/* ============================================================
   导航门户 · Portal 专属样式
   依赖 style.css 的极光玻璃设计系统（变量 / 玻璃卡片 / 字体）
   本文件在其后引入，含 6 套 [data-theme] 主题覆盖
   ============================================================ */

/* ---------------- 主题切换（多套预设） ----------------
   主题通过 <html data-theme="xxx"> 切换，覆盖基础变量即可。
   aurora = 默认（与 :root 一致，无需重复）。            */
/* ★ 原生下拉弹层可读性（搜索栏引擎切换 / 弹窗内分类·排序·铃声选择）：
   Chromium 的 select 弹出列表底色跟随 color-scheme 渲染 —— 深色主题若不声明
   color-scheme:dark，弹层按浅色画布绘制，配上主题的浅色文字就是「白底白字」，
   5 套深色主题全部踩中（用户实测）。浅色主题反向同理。每个主题块内显式声明。 */
html[data-theme="light"] {
  color-scheme: light;
  --bg: #eef1f7;
  --bg-2: #e3e8f2;
  --surface: rgba(255, 255, 255, .72);
  --surface-2: rgba(255, 255, 255, .86);
  --surface-3: rgba(255, 255, 255, .95);
  --border: rgba(30, 50, 90, .14);
  --border-strong: rgba(47, 107, 255, .55);
  --text: #16203a;
  --text-soft: #39435f;      /* 8.7:1（原 8.1，基本持平） */
  --text-mute: #565f79;      /* 5.6:1 —— 原 #6b748f 仅 4.1:1 不达标 */
  --text-strong: #0d1424;    /* 16.2:1 —— 原为硬编码 #fff，浅色下 1.04:1 完全不可见 */
  --on-accent: #ffffff;      /* 白字压深色渐变；原为深色字 #061226，仅 3.4:1 不达标 */

  /* 基础令牌：极光光球 / hover 底色 / 辉光都从这里派生，缺了会退回 :root 的青紫 */
  --brand: #097688;          /* 主色 · 深青 */
  --brand-2: #2455d8;        /* 辅助色 · 靛蓝 */
  --accent: #6a2fd6;         /* 强调色 · 紫 */

  --cyan: #097688;           /* 4.7:1 —— 原 #0aa6c2 仅 2.6:1 */
  --blue: #2455d8;           /* 5.5:1 —— 原 #2f6bff 仅 4.0:1 */
  --purple: #6a2fd6;         /* 6.2:1 */
  --mint: #0a7353;
  --magenta: #c62828;
  --accent-grad: linear-gradient(120deg, #097688 0%, #2455d8 48%, #6a2fd6 100%);
  /* 首色标提到 .26：避免与 hover 的 color-mix(brand 16%) 撞成同一个底色 */
  --accent-grad-soft: linear-gradient(120deg, rgba(9,118,136,.26), rgba(106,47,214,.20));
  --pop-grad: linear-gradient(120deg, #0a7353, #097688 50%, #6a2fd6);
  --neon: 0 0 14px rgba(47, 107, 255, .28);
  --neon-strong: 0 0 22px rgba(47, 107, 255, .4);

  /* 语义色：浅色底需加深，色相与深色主题保持一致（绿=成功、红=错误） */
  --success: #0a7353;   /* 5.2:1 —— 原借用 --mint #0bbf97 仅 2.1:1 */
  --warning: #8a5a00;   /* 5.2:1 —— 原硬编码 #ffb45a 在浅色下几乎不可读 */
  --error: #c62828;     /* 5.0:1 —— 原借用 --magenta #d6229b 仅 4.1:1 */
  --info: #1a58c8;      /* 5.7:1 */
  --disabled: #7c8598;  /* 3.3:1 */
}
html[data-theme="light"] body::before { opacity: .35; filter: blur(14px) saturate(120%); }
html[data-theme="light"] .site-header,
html[data-theme="light"] .site-footer { background: rgba(255,255,255,.6); }

/* ---------- 素雅大地 ink（浅色纸感 · 低饱和大地 / 米灰 / 墨色）----------
   站里原本 5 套都是深色，此套补上「素雅浅色」：米灰纸底 + 墨色文字 +
   低饱和赭石主色 + 灰褐辅助色，边框低对比，沉稳安静。 */
html[data-theme="ink"] {
  color-scheme: light;
  --bg: #f2efe9;                /* 米灰纸感底 */
  --bg-2: #e7e3d9;
  --surface: rgba(255, 253, 249, .72);
  --surface-2: rgba(255, 253, 249, .86);
  --surface-3: rgba(255, 253, 249, .95);
  --border: rgba(58, 48, 38, .18);          /* 低对比边框 */
  --border-strong: rgba(154, 90, 44, .55);

  --text: #23201b;              /* 墨色正文 14.1:1 */
  --text-soft: #4b463c;         /* 8.2:1 */
  --text-mute: #6a6459;         /* 5.2:1 */
  --text-strong: #14120f;       /* 16.4:1 */
  --on-accent: #ffffff;         /* 白字压赭石渐变，最差 5.4:1 */

  /* 基础令牌：主色赭石 / 辅助灰褐 / 强调墨灰 */
  --brand: #9a5a2c;
  --brand-2: #6f5b41;
  --accent: #4a4740;
  --cyan: var(--brand);
  --blue: var(--brand-2);
  --purple: var(--accent);
  --mint: var(--success);       /* 与 light 一致：mint 承担「已同步 / 已固定」的正向语义 */
  --magenta: var(--error);      /* magenta 承担「离线」的告警语义 */

  --accent-grad: linear-gradient(120deg, var(--brand) 0%, var(--brand-2) 48%, var(--accent) 100%);
  /* 首色标 .30 > hover 的 16%，保证 active 底色明显深于 hover */
  --accent-grad-soft: linear-gradient(120deg, rgba(154, 90, 44, .30), rgba(74, 71, 64, .22));
  --pop-grad: linear-gradient(120deg, var(--brand) 0%, var(--brand-2) 50%, var(--accent) 100%);
  --neon: 0 0 12px rgba(154, 90, 44, .22);
  --neon-strong: 0 0 20px rgba(154, 90, 44, .34);

  /* 语义色：浅底一律加深，色相与深色主题保持一致 */
  --success: #0a7353;   /* 5.1:1 */
  --warning: #8a5a00;   /* 5.1:1 */
  --error: #c62828;     /* 4.9:1 */
  --info: #1a58c8;      /* 5.6:1 */
  --disabled: #7c8598;  /* 3.2:1 */
}
html[data-theme="ink"] body::before { opacity: .35; filter: blur(14px) saturate(120%); }
html[data-theme="ink"] .site-header,
html[data-theme="ink"] .site-footer { background: rgba(255,255,255,.6); }

/* ---------- 清新天青 fresh（浅色 · 柔和浅绿 / 天蓝 / 淡青）----------
   明快通透：浅青白底 + 墨青文字 + 柔和青绿主色 + 天蓝辅助色，边框清淡。 */
html[data-theme="fresh"] {
  color-scheme: light;
  --bg: #f0f7f9;                /* 浅青白底 */
  --bg-2: #e1edf1;
  --surface: rgba(255, 255, 255, .72);
  --surface-2: rgba(255, 255, 255, .86);
  --surface-3: rgba(255, 255, 255, .95);
  --border: rgba(18, 85, 107, .16);         /* 清淡边框 */
  --border-strong: rgba(13, 111, 97, .55);

  --text: #14262b;              /* 墨青正文 14.3:1 */
  --text-soft: #33484f;         /* 8.9:1 */
  --text-mute: #4d656d;         /* 5.8:1 */
  --text-strong: #0b1a1f;       /* 16.5:1 */
  --on-accent: #ffffff;         /* 白字压青绿渐变，最差 6.1:1 */

  /* 基础令牌：主色柔和青绿 / 辅助天蓝 / 强调深青 */
  --brand: #0d6f61;
  --brand-2: #1a5f9e;
  --accent: #12556b;
  --cyan: var(--brand);
  --blue: var(--brand-2);
  --purple: var(--accent);
  --mint: var(--success);
  --magenta: var(--error);

  --accent-grad: linear-gradient(120deg, var(--brand) 0%, var(--brand-2) 48%, var(--accent) 100%);
  /* 首色标 .30 > hover 的 16%，保证 active 底色明显深于 hover */
  --accent-grad-soft: linear-gradient(120deg, rgba(13, 111, 97, .30), rgba(18, 85, 107, .22));
  --pop-grad: linear-gradient(120deg, var(--brand) 0%, var(--brand-2) 50%, var(--accent) 100%);
  --neon: 0 0 12px rgba(13, 111, 97, .22);
  --neon-strong: 0 0 20px rgba(13, 111, 97, .34);

  /* 语义色：浅底加深，色相固定 */
  --success: #0a7353;   /* 5.4:1 */
  --warning: #8a5a00;   /* 5.4:1 */
  --error: #c62828;     /* 5.1:1 */
  --info: #1a58c8;      /* 5.9:1 */
  --disabled: #7c8598;  /* 3.4:1 */
}
html[data-theme="fresh"] body::before { opacity: .35; filter: blur(14px) saturate(120%); }
html[data-theme="fresh"] .site-header,
html[data-theme="fresh"] .site-footer { background: rgba(255,255,255,.6); }

/* 以下 4 套深色主题（cyber / mint / graphite / sunset）有意「不覆盖」
   --success / --warning / --error / --info / --disabled。
   语义色必须保持固定色相：绿=成功、琥珀=警告、红=错误、蓝=信息。
   若随主题漂移，薄荷主题的错误提示会变成浅绿、落日主题的成功提示会变成黄色。 */

html[data-theme="cyber"] {
  color-scheme: dark;
  --bg: #0c0420;
  --bg-2: #120630;
  --surface: rgba(190, 120, 255, .07);
  --surface-2: rgba(190, 120, 255, .11);
  --surface-3: rgba(190, 120, 255, .16);
  --border: rgba(200, 130, 255, .20);
  --border-strong: rgba(255, 90, 216, .6);
  /* 基础令牌（光球 / hover 底色派生源） */
  --brand: #c77bff;
  --brand-2: #ff5ad8;
  --accent: #ff5ad8;
  --cyan: #c77bff;
  --blue: #9b5cff;
  --purple: #ff5ad8;
  --mint: #38ffd0;
  /* --magenta 不在此声明：继承 :root 的 var(--error)，保证「错误 / 删除 / 离线」恒为告警红 */
  --accent-grad: linear-gradient(120deg, #c77bff 0%, #ff5ad8 100%);
  --accent-grad-soft: linear-gradient(120deg, rgba(199,123,255,.22), rgba(255,90,216,.22));
  --pop-grad: linear-gradient(120deg, #38ffd0, #c77bff 50%, #ff5ad8);
  --neon: 0 0 18px rgba(199, 123, 255, .5), 0 0 40px rgba(255, 90, 216, .25);
  --neon-strong: 0 0 26px rgba(255, 90, 216, .6), 0 0 56px rgba(199, 123, 255, .4);
}

html[data-theme="mint"] {
  color-scheme: dark;
  --bg: #04130f;
  --bg-2: #06201a;
  --surface: rgba(56, 255, 208, .06);
  --surface-2: rgba(56, 255, 208, .10);
  --surface-3: rgba(56, 255, 208, .15);
  --border: rgba(56, 255, 208, .20);
  --border-strong: rgba(56, 255, 208, .55);
  /* 基础令牌（光球 / hover 底色派生源） */
  --brand: #38ffd0;
  --brand-2: #1fb6c9;
  --accent: #4be0a8;
  --cyan: #38ffd0;
  --blue: #1fb6c9;
  --purple: #4be0a8;
  --mint: #38ffd0;
  /* --magenta 不在此声明：继承 :root 的 var(--error)。
     原 #7af0c0 浅绿会让错误提示与「已同步」薄荷绿同色系，色盲模拟下无法区分。 */
  --accent-grad: linear-gradient(120deg, #38ffd0 0%, #1fb6c9 100%);
  --accent-grad-soft: linear-gradient(120deg, rgba(56,255,208,.20), rgba(31,182,201,.20));
  --pop-grad: linear-gradient(120deg, #38ffd0, #2af0ff 50%, #7af0c0);
  --neon: 0 0 18px rgba(56, 255, 208, .45), 0 0 40px rgba(31, 182, 201, .22);
  --neon-strong: 0 0 26px rgba(56, 255, 208, .6), 0 0 56px rgba(31, 182, 201, .35);
}

html[data-theme="graphite"] {
  color-scheme: dark;
  --bg: #0e1116;
  --bg-2: #141821;
  --surface: rgba(255, 255, 255, .045);
  --surface-2: rgba(255, 255, 255, .075);
  --surface-3: rgba(255, 255, 255, .11);
  --border: rgba(180, 195, 220, .14);
  --border-strong: rgba(120, 200, 255, .45);
  /* 基础令牌（光球 / hover 底色派生源） */
  --brand: #6fb7d6;
  --brand-2: #6f8fd6;
  --accent: #a890d6;
  --cyan: #6fb7d6;
  --blue: #6f8fd6;
  --purple: #a890d6;
  --mint: #8fd6c0;
  /* --magenta 不在此声明：继承 :root 的 var(--error) */
  --accent-grad: linear-gradient(120deg, #6fb7d6 0%, #a890d6 100%);
  /* 首色标提到 .26，与 hover 的 16% 拉开层级 */
  --accent-grad-soft: linear-gradient(120deg, rgba(120,150,180,.26), rgba(150,160,200,.20));
  --pop-grad: linear-gradient(120deg, #8fd6c0, #6fb7d6 50%, #d690c0);
  --neon: 0 0 14px rgba(150, 180, 220, .3);
  --neon-strong: 0 0 22px rgba(150, 180, 220, .4);
}

html[data-theme="sunset"] {
  color-scheme: dark;
  --bg: #140a14;
  --bg-2: #1d0e18;
  --surface: rgba(255, 170, 90, .07);
  --surface-2: rgba(255, 170, 90, .11);
  --surface-3: rgba(255, 170, 90, .16);
  --border: rgba(255, 170, 90, .20);
  --border-strong: rgba(255, 150, 70, .6);
  /* 基础令牌（光球 / hover 底色派生源） */
  --brand: #ffb45a;
  --brand-2: #ff7e6b;
  --accent: #ff9bd0;
  --cyan: #ffb45a;
  --blue: #ff7e6b;
  --purple: #ff9bd0;
  --mint: #ffd27a;
  /* --magenta 不在此声明：继承 :root 的 var(--error) */
  --accent-grad: linear-gradient(120deg, #ffb45a 0%, #ff7e6b 50%, #ff9bd0 100%);
  --accent-grad-soft: linear-gradient(120deg, rgba(255,180,90,.20), rgba(255,126,107,.20));
  --pop-grad: linear-gradient(120deg, #ffd27a, #ffb45a 50%, #ff9bd0);
  --neon: 0 0 18px rgba(255, 180, 90, .45), 0 0 40px rgba(255, 126, 107, .22);
  --neon-strong: 0 0 26px rgba(255, 150, 70, .6), 0 0 56px rgba(255, 126, 107, .35);
}

/* ---------------- 顶部导航：设置按钮 ---------------- */
.nav-settings {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px; font-size: 14px;
}
.nav-settings svg { width: 18px; height: 18px; }

/* ---------------- 中列整合块（.mid-console）----------------
   搜索 + 天气/时钟 + 我的常用 + 浏览历史 统一收进一块玻璃面板，
   填满中列高度；我的常用 grid 撑满剩余空间，浏览历史固定底部。 */
.mid-console {
  display: flex; flex-direction: column; gap: 8px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 12px 16px; backdrop-filter: blur(12px);
}
/* 大标题 hero：恢复满屏改版前被删的品牌头，置于搜索框上方。
   用 clamp 收紧字号与间距，避免挤占首屏；中列高度不足时整列可滚动。 */
/* hero 收紧：省下首屏约 33px，保证 1366 下「常用 2 行 + 浏览历史」能在一屏内放下 */
/* hero 距中列顶部留白 +20px（用户口径）：原距顶 = .mid-console 的 padding-top 14px，
   目标 34px。本轮 padding-top 收到 12px，于是 hero 自身 margin-top 取 22px（12 + 22 = 34），
   只动 hero 自身外边距，搜索区/天气条/常用等模块的相对位置不受影响。
   ★ 用户口径（宽松轮）：hero 顶距 22 → 28px（heroTop 34 → 40）。 */
.mid-hero { text-align: center; padding: 2px 0 0; margin-top: 28px; }
.mid-hero .brand-line {
  font-family: var(--font-display); font-size: 12px; letter-spacing: 2px;
  line-height: 1.2; color: var(--text-mute); margin-bottom: 4px;
}
.mid-hero h1 {
  font-size: clamp(20px, 2.2vw, 26px); line-height: 1.15; margin: 0 0 4px;
  background: var(--pop-grad);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.mid-hero p.lead { color: var(--text-soft); margin: 0; font-size: 13px; line-height: 1.4; }
/* 搜索栏 ↔ 天气日历条间距：10px → 20px（翻倍轮）→ 30px（宽松轮，再 +50%） */
.mid-top { position: relative; display: flex; flex-direction: column; gap: 30px; }
.mid-freq { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; }
.mid-freq .section-head { margin-bottom: 12px; }
.mid-freq .quick-grid { flex: 1 1 auto; min-height: 0; align-content: start; overflow: auto; gap: 12px; }
/* 中列图标点位紧凑化（仅作用于首页整合块，不动其他页）
   ★ .bm-mono 必须与 .bm-ico 并列：portal.js 的 buildIcon 在 favicon 取不到时
     降级生成 .bm-mono（它是 .bm-ico 的子元素，默认 44px），不一起收会被 overflow:hidden 裁一圈。 */
.mid-console .bm-ico, .mid-console .bm-mono { width: 32px; height: 32px; border-radius: 10px; }
.mid-console .bm-mono { font-size: 16px; }
.mid-console .bm-title { font-size: 12px; }
.mid-freq .bm-card { padding: 9px 8px; gap: 6px; }
.mid-recent .recent-row { gap: 10px; }
.mid-recent .bm-card { padding: 8px 6px; gap: 6px; }
/* ★ 浏览历史：固定最多 8 条（portal.js recentList → visitsList(8)），且永远只占一行。
   用户口径（本轮更新）：**不要整行撑满** —— 卡片不再 flex:1 1 0 等分，
   改成「固定宽度 + 左对齐」：宽屏不再被拉伸成一条横贯全列的色带，窄屏靠 shrink 兜住不溢出。
   flex:0 1 100px = 基准 100px、可缩不可伸 → 既不会被撑开，也永远不会顶出横向滚动条。 */
.mid-recent .recent-row { gap: 8px; justify-content: flex-start; }
.mid-recent .recent-row .bm-card { flex: 0 1 100px; max-width: 100px; min-width: 0; }
.mid-recent .recent-row .bm-card .bm-title {
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mid-recent .recent-row .bm-ico, .mid-recent .recent-row .bm-mono { width: 26px; height: 26px; }
.mid-recent .recent-row .bm-mono { font-size: 13px; }
.mid-recent { flex: 0 0 auto; }
.mid-recent .section-head { margin-bottom: 6px; }
.mid-recent .recent-row { padding-bottom: 0; overflow-x: hidden; }

/* ---------------- 群华自研产品（中列 · 浏览历史正下方）----------------
   一行 5 个胶囊，点击直达；不再占用左列分类卡的高度。 */
.mid-qhprod { flex: 0 0 auto; }
.mid-qhprod .section-head { margin-bottom: 6px; }
.mid-qhprod .section-head h2 { font-size: 16px; line-height: 1.25; }
.qhprod-row {
  display: flex; flex-wrap: nowrap; gap: 10px;
  overflow: hidden; min-width: 0;
}
.qhprod-chip {
  display: flex; align-items: center; gap: 7px; min-width: 0;
  padding: 6px 11px 6px 7px; border-radius: 999px;
  background: var(--surface); border: 1px solid var(--border);
  backdrop-filter: blur(10px); text-decoration: none; color: var(--text-soft);
  font-size: 13px; line-height: 1.2; white-space: nowrap;
  transition: border-color .2s, color .2s;
}
.qhprod-chip:hover { border-color: var(--border-strong); color: var(--text); }
.qhprod-chip .fav { width: 22px; height: 22px; flex: none; }
.qhprod-chip .fav .bm-ico, .qhprod-chip .fav .bm-mono { width: 22px; height: 22px; font-size: 11px; }
.qhprod-chip span:last-child { overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 1180px) {
  .qhprod-row { flex-wrap: wrap; }
}

/* ---------------- 中列紧凑化 v2：标题 + 卡片一起收（目标 -200px 以上）----------------
   作用域 .pg-main .mid-console，只影响首页中列，不污染左列与其他页面。
   ★ 特异性必须 ≥ (0,3,0)：portal.css 的 .pg-main .section-head{margin:0 0 18px}
     与 .mid-freq/.mid-recent .section-head 同为 (0,2,0) 但排在后面，18px 才是赢的那个值。
   ★ 每个缩字号的地方都必须同时写 line-height：body{line-height:1.75} 从未在中列被覆盖，
     只改 font-size 不改 line-height，实际只省得到预期的一半。 */
/* 标题行：「我的常用 / 浏览历史」的 h2 与右侧按钮（＋ 添加站点 / 清空浏览历史）并排同一行。
   h2 与 .head-actions 各自都是块级/独占行，改 flex 两端对齐即可；
   按钮的 margin-top 必须归零，否则在 align-items:center 下会把整行抬高。 */
.pg-main .mid-console .section-head {
  position: relative; display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin: 0 0 8px;
}
.pg-main .mid-console .section-head .kicker {
  font-size: 11px; letter-spacing: 3px; line-height: 1.2; margin-bottom: 4px;
}
.pg-main .mid-console .section-head h2 { font-size: 18px; line-height: 1.25; margin: 0; }
/* 描述文案：视觉隐藏而非 display:none —— 文本仍在 DOM 与无障碍树里（屏幕阅读器/爬虫可取），但不占高度。
   ★ 绝对定位在 flex 容器里依然不参与排布，h2 + 按钮仍是同一行。 */
.pg-main .mid-console .section-head p {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
.pg-main .mid-console .section-head .head-actions { margin-top: 0; flex: none; }
.pg-main .mid-console .btn-mini { padding: 5px 12px; font-size: 12px; line-height: 1.2; }
.pg-main .mid-console .mid-freq  .section-head { margin-bottom: 8px; }
.pg-main .mid-console .mid-recent .section-head { margin-bottom: 6px; }
/* 浏览历史卡片：workbench.css 的 .bm-card.visit-card 是后加载的 (0,2,0)，必须用 (0,5,0) 才压得住。
   ★ min-width 必须归零：原来是 124px，8 张 ×134px 在中列（1366 下 ~730px）放不下，
     会把 .recent-row 顶出横向滚动条；归零后由 flex:1 1 0 等分、标题截断兜底。 */
.pg-main .mid-console .mid-recent .bm-card.visit-card {
  padding: 7px 5px; gap: 6px; min-width: 0; flex: 0 1 100px; max-width: 100px;
}
.pg-main .mid-console .visit-card .v-link { gap: 6px; }
/* + 号卡片的 min-height:96px 因 grid stretch 成为整行地板，不拔掉每行都被抬到 96px */
.pg-main .mid-console .bm-add { min-height: 72px; font-size: 24px; }
.pg-main .mid-console .quick-grid { gap: 12px; }

/* ---------------- 搜索区（已迁入中列，满宽） ---------------- */

.portal-search {
  display: flex; gap: 10px; max-width: none; width: 100%; margin: 0;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 10px;   /* 宽松轮：8 → 10px，搜索胶囊整体略增宽松 */
  backdrop-filter: blur(14px);
  box-shadow: var(--neon);
  transition: border-color .2s, box-shadow .2s;
}
.portal-search:focus-within { border-color: var(--border-strong); box-shadow: var(--neon-strong); }
.ps-engine {
  border: none; background: var(--surface-3); color: var(--text);
  border-radius: 999px; padding: 0 14px; font-size: 14px; cursor: pointer;
  outline: none;
}
.ps-input {
  flex: 1; border: none; background: transparent; color: var(--text);
  font-size: 16px; padding: 10px 14px; outline: none;
}
.ps-input::placeholder { color: var(--text-mute); }

/* ---------------- 信息条（时钟 / 日历 / 天气）----------------
   ★ 本块整体按 0.75 缩放（padding / gap / 字号 / 图标 / 按钮），视觉体积约为改前的 3/4。
     中文文本设 11px 下限（严格 0.75 会落到 9px，低于可读阈值），数字与图标严格取 0.75。
   ★ 宽度：桌面 ≥981px 收为中列内容区 75% 并居中（见满屏媒体查询），≤980px 保持满宽。 */
/* ★ line-height:1.25 是这一块最大的杠杆：body 的 1.75 会继承给所有子项，
   一行即可抵消，配合字号收紧让 1280 下的「换行增高到 132px」回落到单行。
   ★ 用户口径：整条高度再 +20%（实测 50 → ~60px）—— 内边距 5/9 → 8/12（+6px）、
     行高 1.15 → 1.2、时钟 14 → 15px；宽度规则（桌面 75%/上限 720px 居中）不变。 */
/* ★ 用户口径（本轮）：整条高度再 +20%（72 → 86px）—— 上下内边距 16px → 23px
     （内容区实测 38px + 46px padding + 2px border = 86px），行高与字号不变，
      避免放大字号破坏「时间等宽防抖」与单行不换行的既有约束。 */
/* ★ 用户口径（本轮·重设计）：字号整体放大一档 + 取消 75% 居中收窄，内容铺满中列宽度，
     两侧不再留大片空白。竖向 padding 相应收紧（23px → 14px）抵消字号增高，
     整条高度大体维持；space-between 让 时钟 | 天气 | 日历按钮 三段自然分布。
     时间仍锁 tabular-nums + min-width 防抖，单行不换行约束保留。
   ★ 用户口径（最新）：宽度减少 40% → 桌面档改回中列 60% 居中（见满屏媒体查询），
     字号与高度不变。 */
.info-bar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 8px 12px; max-width: none; margin: 0;
  line-height: 1.2;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 14px 18px;
  backdrop-filter: blur(12px);
}
.info-clock { display: flex; align-items: baseline; gap: 10px; }
.info-clock .time {
  font-family: var(--font-display); font-size: 22px; line-height: 1.15; letter-spacing: .5px;
  color: var(--text);
  /* ★ 秒位每秒换字符，比例数字里「1」比「0」窄 → 整条每跳一次就左右抽搐一次。
     tabular-nums 让 0-9 等宽（ch = "0" 的宽度），再用 8ch 槽位（HH:MM:SS 恰好 8 字符）
     锁死最小宽度；万一 --font-display 不支持 tnum，min-width 仍能兜住，双重防抖。 */
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  display: inline-block; min-width: 8ch; text-align: left;
  white-space: nowrap;
}
.info-clock .date { color: var(--text-soft); font-size: 15px; }
.info-weather { display: flex; align-items: center; gap: 14px; }
.wx-now { display: flex; align-items: center; gap: 7px; }
.wx-now .ico { font-size: 22px; }
.wx-now .t { font-family: var(--font-display); font-size: 22px; }
.wx-now .desc { color: var(--text-soft); font-size: 15px; }
.wx-forecast { display: flex; gap: 12px; }
.wx-day { text-align: center; font-size: 14px; line-height: 1.25; color: var(--text-mute); }
.wx-day .top { display: flex; align-items: baseline; justify-content: center; gap: 4px; white-space: nowrap; }
.wx-day .d { color: var(--text-soft); }
.wx-day .r { color: var(--text); font-family: var(--font-display); }
.wx-day .lbl { font-size: 12px; color: var(--text-mute); }
.cal-toggle {
  border: 1px solid var(--border); background: var(--surface-2); color: var(--text);
  border-radius: 999px; padding: 4px 12px; cursor: pointer; font-size: 14px; line-height: 1.2;
  display: inline-flex; align-items: center; gap: 6px;
}
.cal-toggle:hover { border-color: var(--border-strong); }
.cal-toggle svg { display: block; }   /* 尺寸在 HTML 内联给定（16px→12px，3/4） */

.mini-cal {
  position: absolute; left: 50%; transform: translateX(-50%);
  margin-top: 8px; z-index: 50;
  background: var(--surface-3); border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm); padding: 10px; backdrop-filter: blur(18px);
  box-shadow: var(--neon-strong); width: 195px;
}
.mini-cal h4 { text-align: center; margin-bottom: 6px; font-size: 12px; color: var(--text-soft); }
.mini-cal .grid7 { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.mini-cal .grid7 span {
  text-align: center; font-size: 11px; padding: 4px 0; border-radius: 6px; color: var(--text-mute);
}
.mini-cal .grid7 span.wk { color: var(--text-soft); font-weight: 600; }
.mini-cal .grid7 span.today {
  background: var(--accent-grad); color: var(--on-accent); font-weight: 700;
}

/* ---------------- 我的常用 / 最近访问 ---------------- */
.quick-grid {
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
/* ★ 空态提示跨满整行：任何列数（8/6/2 列）下都占满 grid 全宽，
   否则 <p> 只占第 1 格，长文案会被挤成一行两三字的窄竖条（线上 1440 截图实锤）。 */
.quick-grid > .grid-empty-tip {
  grid-column: 1 / -1;
  margin: 0; color: var(--text-mute);
}
.bm-card {
  position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 18px 12px; text-align: center;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); backdrop-filter: blur(12px);
  transition: transform .25s, border-color .25s, box-shadow .25s;
  text-decoration: none; color: var(--text);
}
.bm-card:hover { transform: translateY(-4px); border-color: var(--border-strong); box-shadow: var(--neon); }
.bm-card.dragging { opacity: .4; }
.bm-ico {
  width: 44px; height: 44px; border-radius: 12px; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-2);
}
.bm-ico img { width: 100%; height: 100%; object-fit: contain; }
.bm-mono {
  width: 44px; height: 44px; border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
  font-family: var(--font-display); font-size: 18px; font-weight: 700;
  /* 第四层自制徽标：白色加粗首字 + 顶部内高光；渐变由 JS 按 host 哈希确定性生成 */
  color: #fff;
  text-shadow: 0 1px 1px rgba(0, 0, 0, .22);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .35), 0 1px 2px rgba(0, 0, 0, .22);
}
.bm-title { font-size: 14px; color: var(--text); word-break: break-all; line-height: 1.35; }
.bm-actions {
  position: absolute; top: 6px; right: 6px; display: none; gap: 4px;
}
.bm-card:hover .bm-actions { display: flex; }
.bm-actions button {
  width: 26px; height: 26px; border-radius: 8px; border: 1px solid var(--border);
  background: var(--surface-3); color: var(--text-soft); cursor: pointer; font-size: 13px;
  line-height: 1; display: flex; align-items: center; justify-content: center;
}
.bm-actions button:hover { color: var(--text); border-color: var(--border-strong); }
.bm-card.pinned .bm-actions .pin { color: var(--mint); }
.bm-add {
  border: 1px dashed var(--border-strong); color: var(--text-soft);
  font-size: 28px; cursor: pointer; min-height: 96px;
}
.bm-add:hover { color: var(--text); box-shadow: var(--neon); }

.recent-row {
  display: flex; gap: 12px; overflow-x: auto; padding-bottom: 6px;
  scrollbar-width: thin;
}
.recent-row .bm-card { min-width: 130px; }
.recent-row .bm-ico, .recent-row .bm-mono { width: 34px; height: 34px; }

/* ---------------- 企业办公分类导航 ---------------- */
.cat-grid {
  display: grid; gap: 18px;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}
.cat-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 20px; backdrop-filter: blur(12px);
}
.cat-card h3 {
  font-size: 16px; margin-bottom: 14px; display: flex; align-items: center; gap: 8px;
}
.cat-card h3 .dot {
  width: 10px; height: 10px; border-radius: 50%; background: var(--accent-grad);
  box-shadow: var(--neon);
}
.cat-list { display: grid; gap: 8px; }
.cat-list a {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  border-radius: var(--radius-sm); color: var(--text-soft);
  transition: background .2s, color .2s;
}
.cat-list a:hover { background: var(--surface-2); color: var(--text); }
.cat-list a .fav {
  width: 22px; height: 22px; border-radius: 6px; overflow: hidden; flex: none;
  display: flex; align-items: center; justify-content: center; background: var(--surface-3);
}
.cat-list a .fav img { width: 100%; height: 100%; object-fit: contain; }
.cat-list a .mono-sm {
  width: 22px; height: 22px; border-radius: 6px; flex: none;
  display: flex; align-items: center; justify-content: center;
  /* 与 .bm-mono 一致的白色加粗首字，渐变背景由 JS 内联给出 */
  font-size: 11px; font-weight: 700; color: #fff;
}

/* ---------------- 发现常用 ---------------- */
.discover-strip { display: flex; flex-wrap: wrap; gap: 12px; }
.discover-card {
  display: flex; align-items: center; gap: 10px; padding: 10px 14px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 999px; backdrop-filter: blur(10px); text-decoration: none; color: var(--text-soft);
  transition: border-color .2s, color .2s;
}
.discover-card:hover { border-color: var(--border-strong); color: var(--text); }
.discover-card .bm-mono { width: 30px; height: 30px; border-radius: 9px; font-size: 13px; }
/* 发现条改用 buildIcon 后可能是 img，尺寸与上面的字母徽标保持一致（不改变布局） */
.discover-card img { width: 30px; height: 30px; border-radius: 9px; object-fit: contain; flex: none; }
.discover-card .add {
  width: 22px; height: 22px; border-radius: 50%; border: 1px solid var(--border-strong);
  color: var(--mint); display: flex; align-items: center; justify-content: center; font-size: 15px;
}

/* ---------------- 主题快捷色点 ---------------- */
.theme-dots { display: flex; gap: 10px; justify-content: center; margin-top: 14px; }
.theme-dot {
  width: 24px; height: 24px; border-radius: 50%; cursor: pointer; border: 2px solid transparent;
  transition: transform .15s, border-color .15s;
}
.theme-dot:hover { transform: scale(1.12); }
.theme-dot.active { border-color: var(--text); }

/* ---------------- Modal ---------------- */
.modal {
  position: fixed; inset: 0; z-index: 300; display: none;
  align-items: center; justify-content: center; padding: 20px;
}
.modal.open { display: flex; }
.modal-backdrop { position: absolute; inset: 0; background: rgba(4, 8, 20, .6); backdrop-filter: blur(4px); }
.modal-box {
  position: relative; width: 100%; max-width: 460px; max-height: 86vh; overflow-y: auto;
  background: var(--surface-3); border: 1px solid var(--border-strong);
  border-radius: var(--radius); padding: 26px; backdrop-filter: blur(22px);
  box-shadow: var(--neon-strong);
}
.modal-box h3 { margin-bottom: 16px; }
.modal-box .close {
  position: absolute; top: 14px; right: 16px; background: none; border: none;
  color: var(--text-mute); font-size: 22px; cursor: pointer; line-height: 1;
}
.modal-box .close:hover { color: var(--text); }
.field { margin-bottom: 16px; }
.field label { display: block; font-size: 13px; color: var(--text-soft); margin-bottom: 6px; }
.field input, .field select {
  width: 100%; padding: 11px 13px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--surface); color: var(--text); font-size: 15px;
  outline: none;
}
.field input:focus, .field select:focus { border-color: var(--border-strong); }
.field-row { display: flex; gap: 10px; }
.field-row .btn { flex: none; }
.swatches { display: flex; gap: 10px; flex-wrap: wrap; }
.swatch {
  width: 38px; height: 38px; border-radius: 10px; cursor: pointer; border: 2px solid transparent;
  position: relative;
  transition: transform .15s ease, box-shadow .15s ease;
}
/* hover：此前无任何反馈，补缩放 + 描边 */
.swatch:hover { transform: scale(1.08); box-shadow: var(--neon); }
/* 选中态：浅色主题下 #fff 边框会与浅底同化，改用 --border-strong 保证可见 */
.swatch.active { border-color: var(--border-strong); }
.swatch.active::after { content: "✓"; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #fff; font-size: 16px; text-shadow: 0 1px 3px rgba(0,0,0,.5); }
.sync-status { font-size: 13px; padding: 4px 10px; border-radius: 999px; display: inline-block; }
.sync-status.local { background: rgba(255,255,255,.1); color: var(--text-soft); }
.sync-status.synced { background: color-mix(in srgb, var(--mint) 18%, transparent); color: var(--mint); }
.sync-status.offline { background: color-mix(in srgb, var(--magenta) 16%, transparent); color: var(--magenta); }
.modal-hint { font-size: 12px; color: var(--text-mute); line-height: 1.6; margin-top: 6px; }

/* ---------------- 首屏留白 ----------------
   满屏改版后 .portal-hero 已移除，首页第一块不再是 .section，
   该规则不再命中，故删除（避免误伤其他页面的 .section）。 */

/* ---------------- 响应式 ---------------- */
@media (max-width: 720px) {
  .info-bar { justify-content: center; }
  .quick-grid { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }
  .portal-hero { padding-top: 48px; }
  .ps-engine { max-width: 92px; }
}
@media (max-width: 420px) {
  .quick-grid { grid-template-columns: repeat(2, 1fr); }
}

/* 动效降级 */
@media (prefers-reduced-motion: reduce) {
  .bm-card, .discover-card, .theme-dot { transition: none; }
  .bm-card:hover { transform: none; }
  /* 顶部导航滑入滑出：降级为瞬时显隐（仍可唤出/自动收起，只是没有动画） */
  .site-header, .site-header.nav-visible { transition: none; }
  .nav-fab { transition: none; }
  .nav-fab:hover { transform: none; }
}

/* ---------------- header 登录区 ---------------- */
.nav-auth { display: inline-flex; align-items: center; gap: 8px; }
.nav-auth .biz-ico { width: 16px; height: 16px; }
.nav-login { padding: 8px 16px; }

/* ---------------- 顶栏按钮统一（用户口径：一行排开、大小颜色一致、间距规整） ----------------
   ★ 旧症：窄档（~1181~1279px，或系统 125%/150% 缩放后的有效 CSS 宽度）下 flex 挤压，
     按钮文字在按钮内部折成两行，观感即「按钮显示成两行」。
     根治：按钮禁止收缩 + white-space:nowrap + 统一尺寸；窄档收编「了解群华」。 */
.nav .btn {
  flex: none;
  white-space: nowrap;
  padding: 7px 14px;
  font-size: 13.5px;
  border-radius: 999px;
  line-height: 1.25;
}
/* 颜色统一为同一种描边胶囊（主次只靠 hover 区分，不再 primary/ghost 混排） */
.nav .btn.btn-primary,
.nav .btn.btn-ghost,
.nav .btn.btn-outline {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
  box-shadow: none;
}
.nav .btn.btn-primary:hover,
.nav .btn.btn-ghost:hover,
.nav .btn.btn-outline:hover {
  border-color: var(--border-strong);
  color: var(--text-strong);
  background: color-mix(in srgb, var(--brand) 14%, transparent);
}
.nav .btn.nav-settings svg { width: 15px; height: 15px; }
/* 主题切换器固定最右（DOM 已移到设置按钮之后）：与设置按钮同距、收小一档 */
.nav-themerow { display: flex; align-items: center; gap: 5px; margin: 0 2px 0 10px; flex: none; }
.nav-swatch {
  width: 20px; height: 20px; border-radius: 50%;
  border: 2px solid transparent; cursor: pointer; padding: 0;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.18);
  transition: transform .15s, border-color .15s;
}
.nav-swatch:hover { transform: scale(1.12); }
.nav-swatch.active {
  border-color: var(--text);
  box-shadow: var(--neon);
  transform: scale(1.1);
}
/* 窄档（1181~1439）：收编「了解群华」CTA，其余保持单行（≤1180 走既有移动端布局） */
@media (min-width: 1181px) and (max-width: 1439px) {
  .nav .nav-cta { display: none; }
}

/* ---------------- 操作反馈 toast（全站） ---------------- */
.toast-host {
  position: fixed; top: 22px; left: 50%; transform: translateX(-50%);
  z-index: 9999; display: flex; flex-direction: column; gap: 10px;
  pointer-events: none; width: max-content; max-width: 90vw;
}
.toast {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 18px; border-radius: 14px;
  background: var(--surface-2, rgba(20,28,48,.92));
  border: 1px solid var(--border, rgba(120,160,220,.25));
  box-shadow: 0 12px 40px rgba(0,0,0,.45), var(--neon, 0 0 14px rgba(47,107,255,.25));
  color: var(--text, #eaf0ff); font-size: 14px; font-weight: 500;
  backdrop-filter: blur(10px);
  opacity: 0; transform: translateY(-12px) scale(.96); transition: opacity .3s ease, transform .3s ease;
}
.toast.show { opacity: 1; transform: none; }
.toast .t-ico {
  width: 22px; height: 22px; border-radius: 50%; flex: none;
  display: inline-flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 700;
}
/* 语义色一律走 --success/--warning/--error/--info，不再借用品牌色，
   避免薄荷主题「错误提示显示为绿色」这类色相漂移 */
.toast-success { border-color: var(--success, #45e0a0); }
.toast-success .t-ico { background: color-mix(in srgb, var(--success, #45e0a0) 18%, transparent); color: var(--success, #45e0a0); }
.toast-error { border-color: var(--error, #ff6b5a); }
.toast-error .t-ico { background: color-mix(in srgb, var(--error, #ff6b5a) 18%, transparent); color: var(--error, #ff6b5a); }
.toast-warn { border-color: var(--warning, #ffc857); }
.toast-warn .t-ico { background: color-mix(in srgb, var(--warning, #ffc857) 18%, transparent); color: var(--warning, #ffc857); }
.toast-info { border-color: var(--info, #7ab8ff); }
.toast-info .t-ico { background: color-mix(in srgb, var(--info, #7ab8ff) 18%, transparent); color: var(--info, #7ab8ff); }

/* 闹钟提醒 toast：常驻、可交互（host 默认 pointer-events:none，这里重新开启） */
.toast-alarm { pointer-events: auto; gap: 12px; }
.toast-alarm.toast-need-sound { cursor: pointer; }
.toast-alarm .t-stop {
  margin-left: 4px; flex: none; cursor: pointer;
  padding: 7px 13px; border-radius: 9px; font-size: 13px; font-weight: 600;
  border: 1px solid var(--warning, #ffc857);
  background: color-mix(in srgb, var(--warning, #ffc857) 16%, transparent);
  color: var(--warning, #ffc857);
  transition: background .15s ease;
}
.toast-alarm .t-stop:hover { background: color-mix(in srgb, var(--warning, #ffc857) 30%, transparent); }

/* ---------------- 主题直排顶栏（替代原快捷面板） ----------------
   ★ 色块/行容器样式已统一挪到上方「顶栏按钮统一」段（本轮：主题切换器固定最右）。
   ★ 与顶栏显隐机制无冲突：指针在 header 内不倒计时、header 内 pointerdown 重置兜底。
   ★ ≤1180px 顶栏空间吃紧，隐藏色块，主题切换走设置弹窗里的完整色板（保留）。 */
@media (max-width: 1180px) { .nav-themerow { display: none; } }

/* ============================================================
   首页三列栅格（.page-grid）
   DOM 顺序 = main → side → aside，与窄屏视觉顺序一致（Tab 焦点顺序不跳）；
   桌面用显式 grid-column / grid-row 定位，不用 order 做视觉重排。
   防溢出铁律：轨道一律 minmax(0, Xfr) + 子项 min-width: 0。
   历史事故：Xfr 等价 minmax(auto, Xfr)，其 min-content 下限曾让 390px 视口溢出 105px。
   ============================================================ */
.page-grid {
  display: grid;
  gap: 24px;
  align-items: start;
  /* 左 13 / 中 74 / 右 13：在上一版 16/68/16 基础上，左右两栏各再收 20%（16fr → 12.8fr，
     取整 13fr），省出的宽度全部给中列。轨道仍用 minmax(0,Xfr) 防溢出铁律。 */
  grid-template-columns: minmax(0, 13fr) minmax(0, 74fr) minmax(0, 13fr);
}
.pg-col { min-width: 0; }
.pg-main  { grid-column: 2; grid-row: 1; }
.pg-side  { grid-column: 1; grid-row: 1; }
.pg-aside { grid-column: 3; grid-row: 1; }

/* ⚠️ .section 默认 padding: 86px 0（style.css:523）—— 区块进列后必须中和，否则巨缝。
   注意：#workbench 带 id 选择器，这里压不住，改由 workbench.css 的 .pg-aside > #workbench 处理。 */
.pg-col > .section { padding-top: 0; padding-bottom: 12px; }
.pg-col > .section:last-child { padding-bottom: 0; }

/* 中列「简洁」：两个区块标题从「居中 + 52px 下边距」收紧为「左对齐 + 18px」 */
.pg-main .section-head { text-align: left; max-width: none; margin: 0 0 18px; }
.pg-main .section-head .head-actions { justify-content: flex-start; margin-top: 10px; }

/* ---------------- 左列：紧凑分类列表 ----------------
   作用域限定 .pg-side，只调间距 / 字号 / 截断，不新增颜色、不硬编码色值。
   ★ 本轮按实测溢出（1920/1440/1366 = 295/656/788px）温和收紧一档：
     分类卡内边距、标题间距、链接行高、徽标尺寸，以及最大的一块「发现常用」条。
     口径：不压到极限、不牺牲可读性（分类名 12px、发现条 12px 是下限）。 */
.pg-side .section-head { text-align: left; max-width: none; margin: 0 0 8px; }
.pg-side .section-head h2 { font-size: 16px; }
/* ★ 左列区块描述文案同样是「视觉隐藏」而非删除：它在 230px 宽的窄列里会折成 3~4 行、
   实测吃掉 126px（比一张分类卡还高）。文本仍留在 DOM 与无障碍树里，只是不再占高度。 */
.pg-side .section-head p {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
.pg-side .cat-grid { grid-template-columns: minmax(0, 1fr); gap: 5px; }
.pg-side .cat-card { padding: 9px 9px 7px; }
.pg-side .cat-card h3 { font-size: 13px; margin-bottom: 2px; }
.pg-side .cat-list { gap: 2px 12px; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.pg-side .cat-list a { padding: 2px 6px; font-size: 12px; line-height: 1.3; gap: 6px; min-width: 0; }
/* 窄列里 22px 的徽标会跟文字抢宽度，收到 18px（.fav 容器与其内的 .bm-mono 一起收） */
.pg-side .cat-list .fav { width: 18px; height: 18px; flex: none; }
.pg-side .cat-list .fav .bm-mono, .pg-side .cat-list .fav .bm-ico { width: 18px; height: 18px; font-size: 10px; }
/* 防长站名撑破窄列（如「国家税务总局江苏省电子税务局」）：文字层单行截断。
   光写 ellipsis 不够 —— 栅格轨道与 flex 子项的 min-width 默认都是 auto，
   其 min-content 下限会把 a 顶到 345px（列宽只有 265px，视觉上压到中列）。
   必须三层同时收口：轨道 minmax(0,1fr) + a 的 min-width:0 + span 的 min-width:0。 */
.pg-side .cat-list a span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 发现常用：左列里最大的一块（实测 460~612px）—— 由「胶囊逐行换行」改为两列小网格，
   同名胶囊从单行独占（~34px/个）压到两列并排（~30px/两个），宽度不足时文字截断。 */
.pg-side .discover-inline { margin-top: 4px; padding-top: 6px; }
.pg-side .discover-inline .di-head { margin-bottom: 6px; font-size: 12px; gap: 8px; }
.pg-side .discover-inline .di-head strong { font-size: 13px; }
.pg-side .discover-inline .discover-strip {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 5px 6px;
}
.pg-side .discover-inline .discover-card {
  padding: 4px 8px; gap: 5px; font-size: 12px; line-height: 1.3; min-width: 0;
}
.pg-side .discover-inline .discover-card span:not(.add) {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pg-side .discover-inline .discover-card .bm-mono,
.pg-side .discover-inline .discover-card img { width: 20px; height: 20px; font-size: 10px; border-radius: 6px; }
.pg-side .discover-inline .discover-card .add { width: 16px; height: 16px; font-size: 12px; flex: none; }

/* ---------------- 设置弹窗 · 闹钟声音选择器 ----------------
   不写 min-width: 0 会把 modal-box 顶宽（select 默认 min-content 很宽）。 */
.al-sound-row { align-items: flex-end; }
.al-sound-pick { flex: 1 1 auto; min-width: 0; margin-bottom: 0; }
.al-sound-row select { min-width: 0; width: 100%; }

/* ---------------- 断点阶梯 ---------------- */
@media (max-width: 1180px) {
  .page-grid { grid-template-columns: minmax(0, 32fr) minmax(0, 68fr); }
  .pg-side  { grid-column: 1; grid-row: 1; }
  .pg-main  { grid-column: 2; grid-row: 1; }
  .pg-aside { grid-column: 1 / -1; grid-row: 2; }   /* 工作台跨整行，恢复它擅长的三栏 */
}
@media (max-width: 980px) {
  /* 满屏退化为普通文档流：整页可滚动，列不再内部滚动 */
  body[data-page="home"] { display: block; height: auto; overflow: visible; }
  #pageGrid.page-grid { flex: none; height: auto; min-height: 0; grid-auto-rows: auto; padding: 16px 20px; }
  .page-grid { grid-template-columns: minmax(0, 1fr); }
  /* 三列的显式定位必须全部重置为 auto，否则 grid-row:2 会把 aside 顶到 side 前面 */
  .pg-main, .pg-side, .pg-aside { grid-column: auto; grid-row: auto; }
  .pg-col { display: block; overflow: visible; }
  .mid-console { height: auto; }
  .mid-freq .quick-grid { overflow: visible; }
  .pg-side .cat-grid { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
}

/* ============================================================
   满屏机制（桌面 ≥981px）：首页占满 100dvh，三列撑满高度、列内滚动
   ============================================================ */
@media (min-width: 981px) {
  body[data-page="home"] {
    height: 100vh; height: 100dvh;
    display: flex; flex-direction: column; overflow: hidden;
  }
  #pageGrid.page-grid {
    flex: 1 1 auto; min-height: 0;
    align-items: stretch; grid-auto-rows: minmax(0, 1fr);
    padding: 14px 24px;
  }
  .pg-col {
    display: flex; flex-direction: column;
    min-width: 0; min-height: 0; overflow-y: auto;
  }
  /* ★ P0 修复：原 `flex:1 1 auto; min-height:0` 会把玻璃面板锁成「恰好等于列高」，
     于是唯一可收缩的 .mid-freq 被一路压到 0 —— 「我的常用」卡片不可见且与浏览历史标题重叠。
     改成 shrink:0 让面板按内容生长，溢出交给 .pg-col 的 overflow-y:auto 滚动承接。 */
  .pg-main > .mid-console { flex: 1 0 auto; }
  /* ★ 我的常用：固定列数阶梯（不再是 auto-fill）
     用户口径（本轮更新）：**最多显示三行**（上限 = 列数 × 3，见 portal.js 的 freqCap）。
     auto-fill 会随空余宽度任意加列，既不保证「一行几个」也保证不了行数，所以按中列宽度分档：
       ≥1280px   → 8 列（1366 下中列 ~840px，每格 ~96px；1920 下 ~142px）→ 上限 24 个
       981~1279  → 6 列（每格 ~85px）                                    → 上限 18 个
     ★ 1280~1439 是 8 列不是 7 列：7 列会把 24 个撑成 4 行（超出三行口径），8 列恰好三行。
     ★ 不要再给 .quick-grid 加 min-height:0 / max-height —— 那是上一轮 P0（卡片被压到 0 高）的成因。 */
  .pg-main > .mid-console .mid-freq .quick-grid {
    grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 10px;
    /* ★ 关键：原来是 flex:1 1 auto（portal.css:278），它会吸干 .mid-freq 的剩余高度 ——
       实测容器 296px 而两行卡片只占 178px，卡片下方凭空多出一大块空白。
       改成不伸缩后，容器高度 = 真实内容高度（两行 74+10+74=158px），
       剩余空白交给下面那组 auto margin 做「上下居中」（本轮用户口径）。
       ★ overflow:visible 必须保留（上一轮 P0 修复）：滚动统一交给 .pg-col，避免双层滚动条。 */
    flex: 0 0 auto; overflow: visible;
  }
  @media (min-width: 1280px) {
    .pg-main > .mid-console .mid-freq .quick-grid { grid-template-columns: repeat(8, minmax(0, 1fr)); }
  }
  /* 两行等高：标题一律单行截断（原 word-break:break-all 会让长站名换行，行高参差不齐），
     卡片给固定下限高度，撑出的内容由 .pg-col 的列内滚动承接。 */
  .pg-main .mid-console .mid-freq .quick-grid { grid-auto-rows: minmax(0, auto); }
  .pg-main .mid-console .mid-freq .bm-card { min-height: 74px; }
  .pg-main .mid-console .mid-freq .bm-title {
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; word-break: normal;
  }
  /* 「＋ 添加站点」已移到标题行右侧 */
  .pg-main .mid-console .mid-freq .head-actions { margin-top: 0; }
  .pg-main .mid-console #freqAddBtn[disabled] { opacity: .45; cursor: not-allowed; }

  /* ★ 用户口径（本轮）：我的常用最多三行；内容不满三行时，**在本区域内上下居中**。
     .mid-freq 是 .mid-console 里唯一 flex-grow 的项（flex:1 1 auto），中列剩余高度全归它；
     在它内部用「标题 margin-top:auto + 网格 margin-bottom:auto」把「标题 + 卡片」整组居中 ——
     空白均分在标题上方与末行下方，标题与首行的间距保持不变。
     ★ 必须用 auto margin，不能用 justify-content:center：内容超出容器时 auto margin 会退化为 0，
       justify-content:center 则会把顶部内容推到滚动区之外（滚不上去，够不着）。 */
  .pg-main > .mid-console .mid-freq .section-head { margin-top: auto; }
  .pg-main > .mid-console .mid-freq .quick-grid { margin-bottom: auto; }

  /* 搜索框：占中列内容区 50% 并水平居中，超宽屏最多 480px。
     ★ min-width:320px 兜底 1180 断点区间（中列 68fr→54fr，1200px 时 50% 仅 274px，会把 select/input 挤塌）。
     ★ flex-wrap:nowrap 压住 workbench.css 的 .portal-search{flex-wrap:wrap}，防止半宽下换行增高；
       与 workbench 的 @media(max-width:420px) 视口区间不相交，移动端兜底不受影响。
     ★ 本块位于 min-width:981px 内 → ≤980px 自动还原满宽，无需另写还原规则。 */
  .pg-main .mid-console .portal-search {
    width: 50%; max-width: 480px; min-width: 320px;
    margin-inline: auto; flex-wrap: nowrap;
  }
  .pg-main .mid-console .portal-search .btn { padding: 10px 22px; font-size: 14px; line-height: 1.2; }
  .pg-main .mid-console .ps-input { padding: 9px 12px; font-size: 15px; }
  .pg-main .mid-console .ps-engine { padding: 0 12px; font-size: 13px; }

  /* 天气日历条：用户口径「宽度减少 40%」—— 铺满改回收窄，取中列内容区的 60% 居中，
     两侧留白恢复。三段内容 space-between 分布，超出自动换行（flex-wrap 已开）。
     ★ min-width 560px 兜底窄中列（1180 断点区间中列收窄时 60% 会被压到放不下时钟+天气）。
     ★ 本块在 min-width:981px 内 → ≤980px 自动还原满宽，无需另写还原规则。 */
  .pg-main .mid-console .info-bar {
    width: 60%; max-width: none; min-width: 560px;
    margin-inline: auto; justify-content: space-between;
    /* 收窄到 60% 后三段内容放不满一行（实测需要 ~690px，60% 只有 ~576px），
       会折成两行 → 竖向 padding 由 14px 收到 10px 抵消掉多出来的一行高度，
       整条维持在 ~88px（改前单行 ~86px），不侵占中列预算。 */
    padding: 10px 14px;
  }
  .home-foot { flex: 0 0 auto; }
}

/* ---------------- 首页页脚：关于群华（精简横幅，常驻视口底部）---------------- */
.home-foot {
  border-top: 1px solid var(--border);
  background: var(--surface);
  backdrop-filter: blur(12px);
}
.home-foot .about-banner {
  max-width: var(--maxw, 1280px);
  width: 100%; margin: 0 auto;
  border: none; background: transparent; backdrop-filter: none;
  border-radius: 0; box-shadow: none;
  padding: 12px 24px;
}
/* 页脚常驻登录入口：导航栏收起时（默认状态）仍能一键到达登录页。
   ★ 这是「找不到登录窗口」的兜底路径 —— 导航栏默认 visibility:hidden 且滑出视口，
     不懂这个交互的用户会以为门户根本没有登录。 */
.foot-auth { display: inline-flex; align-items: center; }
.foot-auth-link {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 16px; border-radius: 999px;
  border: 1px solid var(--border-strong);
  background: var(--surface-2); color: var(--text);
  font-size: 14px; line-height: 1.2; white-space: nowrap;
  text-decoration: none; transition: border-color .2s, box-shadow .2s, color .2s;
}
.foot-auth-link:hover { border-color: var(--cyan, #2af0ff); color: var(--cyan, #2af0ff); box-shadow: var(--neon, 0 0 14px rgba(42,240,255,.25)); }
.foot-auth-link::before {
  content: ""; width: 14px; height: 14px; border-radius: 50%;
  background: var(--accent-grad); opacity: .9;
}
@media (max-width: 640px) {
  .page-grid { gap: 18px; }
  .pg-side .cat-grid { grid-template-columns: minmax(0, 1fr); }
}
