/* ==========================================================================
   达播工作台 — layout.css
   主区域 / 顶栏（面包屑·用户）/ 页面容器
   ========================================================================== */

/* ---- 主区域 ----
   2026-09-19 晚：乐哥拍板**取消「整体悬浮」**，改为「方案A：贴边」（他原话：
   「上面做的那个悬浮菜单还有侧边栏很奇怪，你看下怎么优化，或者不要悬浮？」→ 选 A）。

   上一版是「侧栏 + 内容列各一块 14px 圆角面板，内缩 2~8px 浮在桌面色上」。
   实测两个毛病：
     ① 缝宽不对等（左/中/右 2px、上/下 8px，差 4 倍）→ 读起来像"没对齐"
     ② **滚动后两块面板顶边错开 8px**（侧栏 fixed、内容列随文档流，见 base.css 侧栏注释）
   本版：margin 全部归零、直角、无阴影，左边界贴着侧栏右缘（侧栏自带 1px 分隔线）。

   ⚠️ 为什么保留 `overflow: clip`（即使已经不需要它来裁圆角了）：
     `.topbar` / `.page-tabs-bar` 是**吸顶**的（sticky），而 sticky 需要一个不含滚动容器的祖先链。
     `clip` 只裁剪、**不创建滚动容器**；换成 `hidden` 会创建 → 吸顶在结构上直接失效（实测顶栏跑到 −312）。
     ⇒ 想删这一行前，先用「滚动 320px 后顶栏是否仍在 0」验证。 */
.app-main {
  flex: 1;
  min-width: 0;
  margin-left: var(--sidebar-width);      /* 内容列从侧栏右缘开始（含侧栏那 1px 线） */
  margin-top: 0;
  margin-right: 0;
  margin-bottom: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  background: var(--color-surface);        /* 白：顶栏/标签栏与它同色，连成一块 */
  border-radius: 0;
  overflow: clip;                          /* ⚠️ 见上方注释：只能是 clip，不能是 hidden */
  transition: margin-left var(--motion-base) var(--motion-ease-standard);
}

.app-shell.is-collapsed .app-main {
  margin-left: var(--sidebar-width-icon);
}

/* ---- 顶栏已撤（2026-09-19 结构重排）----
   乐哥：「现在不是有菜单标签了吗，那路径是不是可以不展示」→ 撤掉面包屑那一行，
   标签栏升为第一行。收益实测：内容区顶边 102px → 56px，**多出 46px**。
   依据：全站 24 个页面（14 主 + 10 二级/详情）全部有页面内标题，
   加上侧栏高亮项与分组名，"我在哪"本来就有三层在讲 —— 面包屑是最下面那层重复的。

   ⚠️ 保留 `.topbar` 节点（`display:none`）而不是从 HTML 删掉：
      全站仍有代码查询 `el.topbar`（app.js 的 el 赋值、若干兼容分支），
      删节点会让那些查询变成 null 并在别处抛错。留一个不占高度的空壳最省事。
   ⚠️ 若要恢复面包屑：删掉这里的 display:none，并把 .page-tabs-bar 的 top 改回
      var(--header-height)、品牌区高度改回 calc(header + tabs)（见 base.css），
      同时恢复 app.js 里给 `.breadcrumb__link` 绑跳转的那段。 */
.topbar {
  display: none;
}

/* ⚠️ `.topbar__left` / `.topbar__right` 已随顶栏一起停用（2026-09-19）。
   保留空规则块是为了留痕：这两个类曾是顶栏的左右两半，
   现在它们的内容分别搬去了 `.page-tabs-bar__left` / `__tabs` / `__tools`
   （搜索入口也回到了 `__tools` 里、通知左边）与侧栏的 `#sidebar-footer`。
   若将来恢复顶栏可从这里改回。 */
.topbar__left, .topbar__right { display: none; }

/* 顶栏全局搜索：胶囊浅底，与列表搜索框同风格 */
.global-search {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  height: 36px;
  padding: 0 var(--space-4);
  background: var(--color-bg);
  border-radius: var(--radius-pill);
  min-width: 240px;
  width: 280px;
}
.global-search__icon {
  display: inline-flex;
  flex-shrink: 0;
  color: var(--color-muted);
}
.global-search__input {
  flex: 1;
  min-width: 0;
  border: none;
  background: transparent;
  outline: none;
  font-size: var(--font-size-sm);
  color: var(--color-fg);
}
.global-search__input::placeholder {
  color: var(--color-placeholder);
}
.global-search {
  position: relative;
}
.global-search__panel {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  /* ⚠️⚠️ 面板**必须比输入框宽**，不能用 left:0;right:0（那样只有 280px）。
     实测（原型阶段）：280px 时右侧的「跳转 →」把菜单名挤到 0 宽，
     「提成总览」整行只剩一个图标 —— 看起来像 bug，实际是宽度不够。
     用 max-content 让内容自己撑开；上下限保证不会太窄也不会盖满屏幕。
     max-width 用 100vw 而不是固定 px：否则窄屏（<560px）时会溢出视口。 */
  min-width: 420px;
  width: max-content;
  max-width: min(560px, calc(100vw - 32px));
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);
  max-height: 420px;
  overflow-y: auto;
  z-index: 300;
  padding: var(--space-2);
}
.gs-group__title {
  padding: var(--space-2) var(--space-3) 4px;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-muted);
  letter-spacing: 0.02em;
}
.gs-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  cursor: pointer;
}
.gs-row:hover,
.gs-row.is-active {
  background: var(--color-surface-2);
}
.gs-row__icon {
  display: inline-flex;
  flex-shrink: 0;
  color: var(--color-muted);
}
.gs-row__text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  /* ⚠️ flex:1 不可省 —— 没有它，右侧的「跳转 →」/路径会把这列压到 0 宽，
     菜单名直接消失（见 .global-search__panel 的注释）。 */
  flex: 1;
  min-width: 0;
}
.gs-row__label {
  font-size: var(--font-size-sm);
  color: var(--color-fg);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.gs-row__sub {
  font-size: var(--font-size-xs);
  color: var(--color-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* 功能项目标页面的「跳转 →」提示（功能项与数据项的区别标识） */
.gs-row__go {
  margin-left: auto;
  flex-shrink: 0;
  white-space: nowrap;
  font-size: var(--font-size-xs);
  color: var(--color-accent-text);
  display: inline-flex;
  align-items: center;
  gap: 2px;
}
.gs-empty {
  padding: var(--space-4);
  text-align: center;
  font-size: var(--font-size-sm);
  color: var(--color-muted);
}

/* ---------- 「问 AI」那一行（贴在面板底部，视觉上与前两类结果分开） ---------- */
.gs-ai {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: var(--space-2) calc(var(--space-2) * -1) calc(var(--space-2) * -1);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--color-border-soft);
  background: var(--color-primary-50);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  cursor: pointer;
}
.gs-ai:hover,
.gs-ai.is-active {
  background: var(--color-primary-100);
}
.gs-ai__icon {
  display: inline-flex;
  flex-shrink: 0;
  color: var(--color-primary-500);
}
.gs-ai__ask {
  flex-shrink: 0;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-fg);
}
.gs-ai__q {
  flex: 1;
  min-width: 0;
  font-size: var(--font-size-sm);
  color: var(--color-fg-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.gs-ai__hint {
  margin-left: auto;
  flex-shrink: 0;
  font-size: var(--font-size-xs);
  color: var(--color-meta);
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

/* ---------- AI 回答区 ---------- */
.gs-answer {
  padding: var(--space-3) var(--space-3) var(--space-2);
}
.gs-answer__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-xs);
  color: var(--color-muted);
  margin-bottom: var(--space-2);
}
.gs-answer__spin {
  display: inline-flex;
  animation: gs-spin 1s linear infinite;
}
@keyframes gs-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}
.gs-answer__body {
  font-size: var(--font-size-sm);
  color: var(--color-fg-2);
  line-height: 1.7;
}
.gs-answer__body--dim {
  color: var(--color-muted);
}
/* 数据来源：**每条 AI 回答都必须带**（否则数字无从核对 —— 见用户铁律"必须拿外部基准比"）。
   做成可点链接，点一下跳到那个页面，页面上是多少一眼能核。 */
.gs-answer__src {
  margin-top: var(--space-3);
  padding-top: var(--space-2);
  border-top: 1px dashed var(--color-border);
  font-size: var(--font-size-xs);
  color: var(--color-muted);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.gs-answer__srclink {
  color: var(--color-accent-text);
  text-decoration: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 2px;
}
.gs-answer__srclink:hover {
  text-decoration: underline;
}
.gs-answer__sep {
  color: var(--color-border);
}
.gs-answer__warn {
  margin-top: var(--space-2);
  font-size: var(--font-size-xs);
  color: var(--color-muted);
}

.breadcrumb {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--color-muted);
  min-width: 0;
}

.breadcrumb__sep {
  color: var(--color-meta);
}

.breadcrumb__link {
  color: var(--color-muted);
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  border-radius: var(--radius-sm);
  transition: color var(--motion-fast) var(--motion-ease-standard);
}
.breadcrumb__link:hover {
  color: var(--color-accent-text);
}

.breadcrumb__current {
  color: var(--color-fg);
  font-weight: var(--font-weight-medium);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: none;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-fg-2);
  /* ⚠️ 必须带上 `transform`（2026-09-13 补，ui-ux-pro-max 优先级 7「state-transition」）：
     按下态用了 `transform: scale(0.94)` 做反馈，而这里原来只过渡 background-color/color
     → **缩放会瞬间跳变**（实测确认：规则生效但无过渡）。
     「状态变化要平滑、不能 snap」是动效规范的基本要求。
     时长沿用 --motion-fast(150ms)，落在规范的 150–300ms 区间。 */
  transition: background-color var(--motion-fast) var(--motion-ease-standard),
    color var(--motion-fast) var(--motion-ease-standard),
    transform var(--motion-fast) var(--motion-ease-standard);
}

.icon-btn:hover {
  background: var(--color-surface-2);
  color: var(--color-fg);
}

.icon-btn:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

/* 用户信息 */
.user-chip {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3) var(--space-1) var(--space-1);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background-color var(--motion-fast) var(--motion-ease-standard);
}

.user-chip:hover {
  background: var(--color-surface-2);
}

.user-avatar {
  /* 顶部 1px 补偿中文字面偏上，首字母视觉居中 */
  padding-top: 1px;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-pill);
  background: var(--color-primary-100);
  color: var(--color-accent-text);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  flex-shrink: 0;
}

.user-meta {
  display: flex;
  flex-direction: column;
  line-height: var(--font-line-height-tight);
}

.user-name {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-fg);
}

.user-role {
  font-size: var(--font-size-xs);
  color: var(--color-muted);
}

.user-avatar-img {
  width: 100%;
  height: 100%;
  border-radius: inherit;
  object-fit: cover;
  display: block;
}

/* ---- 个人中心下拉面板 ---- */
.profile-wrap {
  position: relative;
}
.profile-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 260px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-raised);
  overflow: hidden;
  z-index: var(--z-dropdown, 1000);
}
.profile-menu__header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4);
  border-bottom: 1px solid var(--color-border-soft);
}
.profile-avatar {
  width: 44px;
  height: 44px;
  border-radius: var(--radius-pill);
  background: var(--color-primary-100);
  color: var(--color-accent-text);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
  flex-shrink: 0;
  overflow: hidden;
}
.profile-menu__name {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-fg);
}
.profile-menu__sub {
  font-size: var(--font-size-xs);
  color: var(--color-muted);
  margin-top: 2px;
}
.profile-menu__body {
  padding: var(--space-2);
}
.profile-menu__footer {
  padding: var(--space-2);
  border-top: 1px solid var(--color-border-soft);
}
.profile-menu__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: none;
  background: none;
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
  color: var(--color-fg);
  cursor: pointer;
  text-align: left;
}
.profile-menu__item:hover {
  background: var(--color-surface-2);
}
.profile-menu__item--danger {
  color: var(--color-danger);
}
.profile-menu__item--danger:hover {
  background: var(--color-danger-soft, rgba(220, 53, 69, 0.08));
}
.profile-menu__soon {
  margin-left: auto;
  font-size: var(--font-size-xs);
  color: var(--color-muted);
}

/* ---- 通知中心（铃铛 + 下拉） ---- */
.notify-wrap {
  position: relative;
}
.notify-badge {
  position: absolute;
  top: 3px;
  right: 1px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: var(--radius-pill);
  background: var(--color-danger);
  color: #fff;
  font-size: var(--font-size-xs);
  line-height: 16px;
  text-align: center;
  pointer-events: none;
  box-sizing: border-box;
}
.notify-panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 340px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-raised);
  overflow: hidden;
  z-index: var(--z-dropdown, 1000);
}
.notify-panel__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border-soft);
}
.notify-panel__title {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-fg);
}
.notify-panel__readall {
  border: none;
  background: none;
  font-size: var(--font-size-xs);
  color: var(--color-accent-text);
  cursor: pointer;
  padding: 0;
}
.notify-panel__body {
  max-height: 400px;
  overflow-y: auto;
}
.notify-item {
  padding: var(--space-3) var(--space-4);
  cursor: pointer;
  border-bottom: 1px solid var(--color-border-soft);
}
.notify-item:last-child {
  border-bottom: none;
}
.notify-item:hover {
  background: var(--color-surface-2);
}
.notify-item.is-unread {
  background: var(--color-info-soft, rgba(24, 95, 165, 0.05));
}
.notify-item__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.notify-item__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--color-danger);
  flex-shrink: 0;
}
.notify-item:not(.is-unread) .notify-item__dot {
  opacity: 0;
}
.notify-item__title {
  flex: 1;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-fg);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.notify-item__time {
  font-size: var(--font-size-xs);
  color: var(--color-muted);
  flex-shrink: 0;
}
.notify-item__content {
  margin-top: 4px;
  font-size: var(--font-size-xs);
  color: var(--color-muted);
  line-height: 1.5;
}
.notify-empty {
  padding: var(--space-6);
}

/* ---- 主内容 ---- */
.page {
  flex: 1;
  /* 上边距 24（不是 32）—— 2026-09-19 乐哥：「下面有点多留白」。
     实测根因：上 32 ＋ .page-header 的 margin-top 24 = **56px 空档**（5 个页面实测全是 56）。
     那 24 是**标签栏出现之前**定的 —— 当时 .page 顶上直接是顶栏，需要拉开距离；
     现在标签栏已吸顶、且与正文之间有一条分隔线，这 24 就是**重复**的。
     现改法：上 24 ＋ header 的 8 = 32px，与左右 32 的 gutter 对齐成一个方正的角。 */
  padding: var(--space-6) var(--page-padding) var(--page-padding);
  width: 100%;
}

/* ==========================================================================
   多标签页（2026-09-18 乐哥：「能有个达人页面的标签，点击直接切过来，
   内容还是我切换之前维护的那些，丝毫未动」）

   ▸ 两个部件：
     · `.page-tabs-bar` 标签栏 —— 面包屑栏之下、页面之上
     · `.page-stack`    页面栈 —— **所有标签的页面同时存在于 DOM 中**，
       非活动的只是不显示。这是"丝毫未动"的实现基础：
       切标签不做任何重建，筛选条件 / 滚动位置 / 展开的行 / 填一半的表单都原样保留。

   ▸ 为什么"只让活动容器持有 id=page-root"（见 app.js 的 activateTab）：
     全站有 8 处 `document.getElementById('page-root')` 以及大量依赖该 id 的逻辑，
     逐个改成"按标签查找"既繁琐又必漏。改成**活动容器独占该 id**后，
     那些代码一行不改就自动拿到"当前活动页"——这是本次改造能收敛在单文件的关键。

   ---------------------------------------------------------------------------
   ▸ 外观（2026-09-19 乐哥：「有点丑，可以做成 chrome 浏览器标签的样子吗」）
     改成 Chrome 的页签形态。**关键是这一条，不是配色**：
         「激活标签的底色 == 内容区的底色」
       Chrome：窗口顶是深灰槽、内容区是白 ⇒ 激活标签用**白**，白色"流"进内容区，
               视觉上连成一片，标签栏底部的分隔线在激活标签处自然消失。
       我们：内容区是**灰**（--color-bg #F5F6F8）、白的是**卡片** ⇒
             激活标签必须用**灰**，槽要比灰更深一档。
       ⚠️ 我第一版照抄 Chrome 用了白色标签，结果白块浮在灰页面上、比改版前更像
          "一张贴纸"（自测截图一看就露馅）。改对底色后才成立。
       ⚠️ 所以**不要**把 .page-tab.is-active 的 background 改成 --color-surface（白）。

     Chrome 页签的四要素（缺一个就不像）：
       ① 标签从「槽」里升起来：激活的高（36）非激活的矮（32），底部对齐
       ② 激活标签底部**两个凹角**（反圆角），把槽色平滑过渡掉
       ③ 激活标签底边**盖住**分隔线（margin-bottom:-1px + z-index:2）
       ④ 关闭按钮：非激活 hover 才出现、激活常显（降噪；实测 5 个标签 5 个 × 很吵）
   ========================================================================== */
.page-stack {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  width: 100%;
  /* 内容区底色。2026-09-19 晚取消悬浮后**不再需要底部圆角**
     （原先是 `0 0 --radius-frame --radius-frame`，配合外框圆角；外框已改直角）。
     ⇒ 没删掉这个属性、只是把值写清，是为了让"这里曾经有圆角"这件事留个痕，
        免得下一个人看到 .page-stack 和 .app-main 都不圆而以为是漏了。 */
  background: var(--color-bg);
  border-radius: 0;
}
/* 非活动标签的页面：**保留在 DOM 中**，仅不显示（勿改成 display:none 之外的做法，
   也不要移除节点 —— 移除就等于丢失用户没保存的状态） */
.page-stack > .page.is-tab-hidden {
  display: none;
}

/* 标签栏（2026-09-19 第二版）。

   ▸ 乐哥反馈的原话：「标签下面有一条线，另一个是颜色问题，都很突兀」。
     实测出来的两个根因，**都是为上一版改版新造的、全站只此一处的颜色**：
       · 槽底 #E3E6EA —— 全站唯一，比系统里最深的边框（--color-border #E5E8EC）还重
       · 槽底线 #D2D7DD —— 全站唯一，比任何边框都深 → 就是那条"多余的线"
     而系统里**早有一整套 tab 语言**（页面内 `.tabs`：选中＝主色文字＋底部主色下划线，
     选中态用 --color-accent-bg #EDF4FE，全站 10 多处）。窗口标签栏却新造了一套外来语言，
     所以看着"像个外人"。⇒ 本版改成**复用既有语言**，不再引入任何新颜色。

   ▸ 本版做法（方案 1「顶区一体」）：
     面包屑栏与标签栏**同为白**、去掉中间那条线，两行并成一个「顶部区」
     （都在回答"我在哪"）；激活标签 = 全站选中态同款浅蓝胶囊。
     结构性收益：整个页面**只剩一条横向分隔线**（在"顶部区"与正文之间）。

   ▸ ⚠️ 必须配套的两件事（实测出来的，不是可选）：
     ① `.topbar` 的 border-bottom 要**删掉** —— 线挪到这里来。否则两行之间多一条线，
        加上本条的线就是两条（实测现状正是 2 条：topbar 的 + 槽的深线）。
     ② 本栏必须 `position: sticky; top: var(--header-height)`。
        因为 `.topbar` 是粘顶的、本栏原先不粘 —— 实测滚 300px 后本栏跑到 top:-244，
        线随之上移，滚动时"归属"就断了。粘住之后两行**整体吸顶共用一个底边**。
        （实测：祖先链无 overflow 约束，sticky 可用；z-index 取 1099 < topbar 的 1100，
         保证顶栏的全局搜索面板 / 个人中心下拉弹出来时**不会被本栏切掉**。）
   ▸ 2026-09-19 结构重排：面包屑那一行已撤，**本栏升为第一行**（`top: 0`）。
     收益：内容区顶边 102px → 56px。高度沿用 `--tabs-bar-height`，**没有新造尺寸**
     —— 这样 analytics.js 的 `headerHeight()`（读 --header-height 当吸顶高度）无需改动即正确。
     ⚠️ 上面那句里的 56px 是那次重排时的值，之后又调过两次（56→60→52）。
        当前值以 design-tokens 的 `--tabs-bar-height` 为准，**这里不复述具体数字**
        （注释里写死数值会过期，本项目踩过"注释与代码打架"的坑）。
   ▸ 2026-09-20 高度收回：乐哥「最上面的标签，是不是太大，太占位置了」。
     实测依据与最终取值统一写在 design-tokens 的 `--tabs-bar-height` 注释里（只写一处）。
   ▸ 本栏拆成三个并列容器（见 index.html），**动态区与静态区分开**：
       `__left`  移动端菜单开关（静态，从原顶栏搬来）
       `__tabs`  标签（动态，renderTabsBar 每次重建它）
       `__tools` 通知/刷新/关闭（静态，全局委托绑定 → 重建容器也不丢事件）
     ⚠️ 拆分是必须的：原先 `renderTabsBar` 做 `bar.innerHTML = html` 整体重建，
        通知放进去会被每次切页冲掉（事件一并丢失）。
   ========================================================================== */
.page-tabs-bar {
  display: flex;
  align-items: center;
  gap: 0;                             /* 间距交给内部各段自己管，避免空容器仍占 gap */
  height: var(--tabs-bar-height);
  flex: 0 0 auto;
  /* 左内边距 24 —— 好让**标签里的图标**与下方页面标题左边对齐：
     24（栏内边距）+ 8（标签自身内边距）= 32 = --page-padding。实测差 0px。 */
  padding: 0 24px;
  position: sticky;
  top: 0;                             /* ⭐ 第一行：吸在视口顶 */
  z-index: var(--z-sticky);
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);   /* 系统标准线 #E5E8EC */
  /* ⚠️ 横向滚动已下移到 `__tabs` —— 本栏若自己 overflow，会连 `__tools` 一起滚走 */
  overflow: visible;
}
.page-tabs-bar__left {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
}


.page-tabs-bar__tabs {
  display: flex;
  align-items: center;
  /* 标签间距 6（2026-09-19 晚 4 → 6）—— 乐哥反馈顶栏"挤"。
     ⭐ 实测：挤的主因是间距不是高度，4px 让相邻标签几乎贴在一起。 */
  gap: 6px;
  flex: 1 1 auto;
  min-width: 0;                       /* 允许收缩，否则标签把工具组挤出屏幕 */
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;              /* 标签多了横向滚动，但不显示滚动条 */
}
.page-tabs-bar__tabs::-webkit-scrollbar { height: 0; }

.page-tab {
  position: relative;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;             /* 内容在标签内居中 —— 见下方"等宽"的说明 */
  gap: 7px;
  /* 标签高 34（2026-09-20；前一天 36 → 40 的那次已收回，原因见 design-tokens
     里 --tabs-bar-height 的第 ② 次调整：标签 40 比全站所有按钮（36）都大）。
     ⭐ 为什么是 34 而不是更小：栏高 52 − 34 = 18，上下各 9px，
        与「36px 按钮」在「52px 容器」里的留白比例一致；
        再小（如 32）就只剩 10px 内容高给 14px 字号，行高会顶到边。
     ⚠️ 本值必须与 --tabs-bar-height **成对**调：两次历史改版都是两者一起动，
        只改一个会让标签在栏里显得过小或过挤。 */
  height: 34px;
  padding: 0 8px;                      /* 左右各 8：配合栏的 24 让图标落在 32px 线上 */
  border: none;
  /* 胶囊圆角（= --radius-seg，全站分段控件 / Tab 项同款）。
     上一版是「6px 6px 0 0 + 底部两个凹角」的 Chrome 页签形态，本版不再需要两者同值。 */
  border-radius: var(--radius-seg);
  font-size: var(--font-size-sm);
  color: var(--color-muted);
  white-space: nowrap;
  cursor: pointer;
  min-width: 92px;                     /* 防标签挤成一小团 */
  max-width: 200px;                    /* 防长页面名把标签撑得很宽 */
  transition: background var(--motion-fast) var(--motion-ease-standard),
    color var(--motion-fast) var(--motion-ease-standard);
}
/* ⚠️ 标签宽度**由 JS 统一**（app.js 的 equalizeTabWidths），不靠这里的 min-width 撑。
   ────────────────────────────────────────────────────────────────────────────────
   乐哥 2026-09-19：「标签因为文字长度不一样，导致标签长度不一致，看着很奇怪」。
   实测现状：首页 66 / 我的报销 94 / 成本总览 94 / 月度利润明细 122 —— 参差不齐。
   做法：多标签时测出**当前打开这几个**里最宽的自然宽度，全部设成同一个宽度。
     · 为什么不能用 CSS：flex 子项宽度天然由内容决定，"取兄弟节点的最大宽度"
       CSS 没有对应表达 —— `1fr` 是**平分容器**（5 个标签会各撑到 217px，喧宾夺主），
       固定 min-width 又会被更长的名字打破（菜单名从 2 字到 6 字都有）。
     · 为什么加 `justify-content: center`：等宽之后短标签（"首页"只有 66px 的内容）
       若靠左对齐，右侧会空出一大块 —— 与"单标签右边空 26px"是同一个病。
       居中后每个标签的"图标 + 文字"整体居中，长短名视觉重量一致。
       （这条对单标签无影响：那时宽度 = 内容宽，居中与靠左等价。）
     · 单标签不合宽（见 .page-tab--last）—— 只有一个标签时不存在"不一致"，
       且它不显示 ×，贴合内容才不空。 */
.page-tab:hover { background: var(--color-gray-50); color: var(--color-fg); }
.page-tab__label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* 标签左侧的菜单图标 —— 相当于浏览器的 favicon：多个标签并存时靠它快速辨认。
   非激活用次级灰（不抢视线）、激活用主色（与当前页呼应）。 */
.page-tab__ico {
  display: inline-flex;
  flex-shrink: 0;
  color: var(--color-meta);
}
.page-tab.is-active .page-tab__ico { color: var(--color-accent-text); }

/* 激活标签：全站选中态同款浅蓝胶囊 + 主色文字。
   ⚠️ 与上一版的关键区别：
      · 不再「抬高 4px + 与内容区同色 + 盖住分隔线」—— 那是 Chrome 页签的做法，
        要求"激活标签的颜色 == 内容区的颜色"；现在改成胶囊，这条约束不再适用。
      · 颜色取 --color-accent-bg(#EDF4FE) / --color-accent-text(#0064E0)，
        与页面内 `.tabs` 的选中态、以及全站 10 多处的选中态**同一套语言**。
      · 高度与未激活**相同**（32px）：胶囊靠底色区分，不靠体量。 */
.page-tab.is-active {
  background: var(--color-accent-bg);
  color: var(--color-accent-text);
  font-weight: var(--font-weight-medium);
}

.page-tab__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-meta);
  line-height: 1;
  cursor: pointer;
  /* ⚠️⚠️ × **常显**（2026-09-19 乐哥实报「上面的标签页关闭的 x 看不到了」，本轮改）。
     ────────────────────────────────────────────────────────────────────────────
     上一版是"非当前页的标签平时 opacity:0，hover 才出现"（为了降噪）。两个后果：
       ① 乐哥直接反馈「看不到」—— 大多数标签不是当前页，所以大多数标签没有 ×；
       ② ⭐ 更隐蔽的一个：**它占位但不可见**。× 是 flex 子项（16px），
          即使 opacity:0 也照样占 16px 主轴空间 ⇒ 居中算法把它算进去，
          而眼睛看不见它 ⇒ **非激活标签的内容视觉上偏左**。
          实测：「我的报销」标签等宽 117px，可见内容落在 [8, 86]，
          右侧空 31px 里其实藏着 16px 的隐形按钮 —— 看着就像"没对齐"。
          等宽之后这个错位感更明显（短标签"首页"可见内容只有 50px、右侧空 45px）。
     ⇒ 改成常显但**弱化**（opacity .5）：既让人看得见能关、又不像激活态那样抢视线，
        顺带把"隐形占位"这个观感问题一并解决。
     ⚠️ 对比度：.5 的 --color-meta(#8595A4) 在白底上约 1.9:1 —— 作为"可点的次级控件"
        够用（与全站 .icon-btn 的弱化思路一致），hover 时提到 1 并加灰底。 */
  opacity: 0.5;
  transition: opacity var(--motion-fast) var(--motion-ease-standard),
    background var(--motion-fast) var(--motion-ease-standard);
}
.page-tab:hover .page-tab__close { opacity: 1; }
.page-tab.is-active .page-tab__close { opacity: 1; }
.page-tab__close:hover { background: var(--color-gray-300); color: var(--color-fg); }
.page-tab__close svg { display: block; }
/* 最后一个标签（= 全站只剩这一个页面）：不给关闭按钮（关掉就没页面了）——由 app.js 加该类。
   ⚠️⚠️ 同时必须**撤掉 min-width: 92px**（2026-09-19 乐哥实报：
      「只有一个的时候文字也没居中，右边还空了」）。
      多标签时那条 min-width 是"防标签被挤成一小团"的保护，有用；
      但**唯一标签**本来就不显示 ×、宽度只剩 [图标 + 文字]，
      min-width 会把右边撑出一块**没有任何内容的空白** —— 实测：
        「首页」标签 92px、内容 50px ⇒ 右侧空 26px（肉眼就是"文字靠左、右边缺一块"）；
        「我的报销」标签 92px、内容 56px ⇒ 空 20px。
      撤掉后宽度贴合内容，左右留白各 8px，偏心率实测 = 0。 */
.page-tab--last { min-width: 0; }
.page-tab--last .page-tab__close { display: none; }

/* 标签栏右端的固定操作区（刷新 / 关闭全部），永远贴在右边不随标签滚动。
   ⚠️ 底色必须与标签栏一致（现在都是白）。上一版是 --tab-slot-bg，本版该令牌已删除 ——
     若不改这里，var() 解析失败会让底色变透明，横向滚动时露出一块"镂空"。 */
/* 右侧工具组：刷新 / 关闭全部 / 通知 —— 通知**在最右**（乐哥 2026-09-19：「通知按钮能放最右上角好点」）。
   ⚠️ 本组现在是 index.html 里的**静态节点**（原来由 renderTabsBar 生成），
      因为通知放进去后必须扛得住 renderTabsBar 的整体重建。
   ⚠️ 这里**不要**再写 `margin-left: auto`：本组是 `__tabs`（flex:1）之后的兄弟，
      已经被自然推到右侧。曾经踩过一个坑 —— 本组自带 auto、通知组又加一个 auto，
      两个 auto 把剩余空间**对半分**，结果通知停在半空、右边空出 377px（"空白一大片"）。
      现在由 `__tabs` 独占弹性空间，只有一处 auto 语义。 */
.page-tabs-bar__tools {
  display: flex;
  align-items: center;
  /* 工具间距 6（2026-09-19 晚 2 → 6）—— 原 2px 是「挤」最明显的地方：
     刷新 / 关闭 / 搜索 / 通知 四个控件两两只隔 2px，看着像粘在一起。
     ⚠️ 放宽后总宽增加 3×4 = 12px，已实测各视口下标签区余量仍够（见门禁测试）。 */
  gap: 6px;
  flex: 0 0 auto;
  padding-left: 10px;
  background: var(--color-surface);
}
/* 顶栏里的图标按钮：**回归全站基准 36**（2026-09-20）。
   ────────────────────────────────────────────────────────────────────────────
   昨天（09-19 晚）这里是 40，理由只是"跟着顶栏一起加高"。本轮实测发现它其实是个
   **全站孤例**：`.icon-btn` 的基准是 36（layout.css 321 行），100 处在复用，
   只有标签栏把它放大到 40 —— 这正是乐哥说"标签太大、太占位置"的一部分。
   ⇒ 收回 36，与标签栏外的图标按钮同尺寸，不再是孤例。

   ⚠️⚠️ 这条规则（值不管是多少）**必须保留，不许删** —— 它同时是**移动端的闸门**：
       `@media (max-width:768px)` 里有一条 `.icon-btn { width:44px; height:44px }`
       （0,1,0），而本规则是 `.page-tabs-bar .icon-btn`（0,2,0）。
       特异性高的赢、且 **media 查询不改变特异性** ⇒ 本规则在手机上也生效。
       删掉它，手机上标签栏内的这几个按钮会**回落到 44px** ——
       比今天改之前的 40px **还大**，塞进 52px 的栏里只剩 4px 留白（等于没改回）。
       ⇒ 这个坑由 tests/page-tabs.test.js 静态锁住。
   ⚠️⚠️ 用**作用域覆盖**，绝不改全局 `.icon-btn`（见本文件 321 行的 36×36）——
      它被表格行操作、弹窗关闭、列表工具等 **100 处 / 29 个文件**复用
      （`grep -rho icon-btn public/js | wc -l` = 100），改全局会同时撑高那些表格行的
      行高、并让弹窗右上角的关闭按钮变大。
      本项目一贯做法：**改公共类之前先查复用面，用局部覆盖替代全局修改**。 */
.page-tabs-bar .icon-btn { width: 36px; height: 36px; }
/* 通知与「标签操作」之间留一点气口：前者是全站消息、后者是标签的操作，语义不同 */
.page-tabs-bar__tools .notify-wrap {
  margin-left: 6px;
  padding-left: 10px;
  border-left: 1px solid var(--color-border-soft);
}
/* ⚠️⚠️ 这里原本残留着一段**丢了选择器的声明**（`position: sticky; right: 0;
   margin-left: auto; height: 32px; ... }`）—— 那是本规则改版**之前**的旧副本，
   新版（上面 817 行那条）已经把 `margin-left: auto` 去掉了（它会导致通知按钮
   停在半空、右侧空出 377px，见上方 813 行的说明），但旧副本没删干净。

   2026-09-19 修：它不只是"死代码"——**它会把紧接着的下一条规则一起吃掉**：
   CSS 解析器读到孤立的声明时，会一路把它当作下一条规则的「选择器前奏」，
   直到遇到下一个 `{` ⇒ 于是 `.page--narrow { max-width: 1144px }` 被拼进
   这个非法选择器里、**整条规则被丢弃**。
   实测后果：全站 `.page--narrow`（内容区 1080 的窄版二级页）**从来没有生效过**，
   所有靠它限宽的页面都是铺满全宽 1456px。
   ⇒ 教训：删规则时**必须删掉整块（含选择器与花括号）**；
      留半截比留着更危险 —— 它会静默破坏后面一条无关的规则。 */

/* ---- 二级页宽度「两档制」（2026-09-14 乐哥拍板） ----
   背景：二级页此前**三档并存**（内容 1080 / 1392 / 1456），同一个「二级页」身份
   却有三种宽度，看着不像一套东西。现收敛为两档，判据只有一个：
   **页面主体是不是表格**。

   · .page--narrow（内容 1080）—— 无表格的键值 / 表单 / 档案型二级页。
     这类页面铺满全宽（实测内容区 1456px）会把字段拉到两端、视线来回跑，空而散。
   · .page--table（内容 1296）—— 主体是表格的二级页（结算明细 / 提成明细 /
     华大对账明细 / 订单明细）。表格宽度是**列数实打实用掉的**，限到 1080 会出事：
       · 结算明细 10 列表 → 实测**横向滚动 +189px**，末列直接跑出可见区；
       · 订单明细列表   → 实测**表高从 2148px 涨到 4776px**（列被挤得每行折成多行）。
     故两档不是设计偏好，是物理下限。

   ⚠️ 必须连 **标题区一起限宽**（本类加在 .page 上，而非只加在内容容器上）——
      否则标题贴页面最左、内容居中，左边缘不对齐反而更乱。
   ⚠️ 一级列表页 / 看板**不加任何档位类**：它们的宽度同样被列数用掉，须保持全宽。
   ⚠️ 档位归属是**静态声明**（app.js 的 WIDTH_TIER / detail.js 的 KIND.tier），
      不按「当前渲染出几张表」动态判断 —— 否则同一页面换个数据就换宽度，更乱。

   宽度算式：max-width = 内容区 + 左右各 32 的 --page-padding。 */
.page--narrow {
  max-width: 1144px;   /* 内容区 1080 —— 无表格的二级页 */
  margin-left: auto;
  margin-right: auto;
}
.page--table {
  max-width: 1360px;   /* 内容区 1296 —— 主体是表格的二级页 */
  margin-left: auto;
  margin-right: auto;
}

.page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  /* 8（不是 24）—— 与 .page 的 padding-top 24 合成 32px 的上留白。
     原 24 会让两者叠成 56px（见 .page 的注释）。 */
  margin-top: var(--space-2);
  margin-bottom: var(--space-6);
}

.page-title {
  position: relative;
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-semibold);
  letter-spacing: var(--font-letter-spacing-display);
  line-height: var(--font-line-height-tight);
  color: var(--color-fg);
}

/* 页面标题左侧竖条装饰条已移除 —— 国产后台旧范式，TDesign / 微信小店均无此元素。
   若需恢复，取消下面注释即可。
.page-title::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 20px;
  border-radius: 2px;
  background: var(--color-accent);
}
*/

.page-desc {
  margin-top: var(--space-1);
  font-size: var(--font-size-sm);
  color: var(--color-muted);
}

/* 页面标题旁的「数据说明」问号按钮 */
.page-help-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  margin-left: var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: 50%;
  background: transparent;
  color: var(--color-muted);
  cursor: pointer;
  vertical-align: middle;
  transition: color .15s, border-color .15s, background .15s;
}
.page-help-btn:hover {
  color: var(--color-accent);
  border-color: var(--color-accent);
  background: var(--color-surface-2);
}

/* 数据说明弹窗内容 */
.help-section { margin-bottom: var(--space-4); }
.help-section:last-child { margin-bottom: 0; }
.help-label {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-accent-text);
  margin-bottom: var(--space-1);
}
.help-text {
  font-size: var(--font-size-sm);
  color: var(--color-fg-2);
  line-height: 1.6;
}

.page-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
}

/* 页面头部（标题行右侧）的次要按钮：**可见度加强**（2026-09-18 乐哥反馈）
   --------------------------------------------------------------------------
   乐哥原话：「还有个问题，导入导出按钮看着不显眼」。
   原因：`.btn--ghost` 的描边用 `--color-border: #E5E8EC` —— 这是**给卡片留白用的**
   极浅灰，放在同样白色的页面头部里几乎看不见边界，只剩一行灰字悬空；
   而旁边的「新增达人」是蓝底实心 → 主次关系被拉成了「实心按钮 vs 一片文字」。

   ✅ 做法：**只**加强页面头部这一处（`.page-actions` 作用域），不动全局 ghost ——
      全局 `.btn--ghost` 还用在表格操作列（编辑/删除那种图标按钮），
      那些按钮本来就该"轻"（一列里几十个实心描边会非常吵）。
      · 描边提到 `--color-gray-400`（输入框同款，肉眼可辨）
      · 文字用主文字色（不是灰）+ medium 字重
      · hover 转主色（描边 + 文字 + 浅蓝底），与旁边的实心主按钮呼应但不抢主次 */
.page-actions .btn--ghost {
  background: var(--color-surface);
  border-color: var(--color-gray-400);
  color: var(--color-fg);
  font-weight: var(--font-weight-medium);
}

.page-actions .btn--ghost:hover:not(:disabled) {
  border-color: var(--color-accent-text);
  color: var(--color-accent-text);
  background: var(--color-primary-50);
}

/* 桌面端不显示折叠按钮（侧栏固定展开，不支持折叠） */
.sidebar-toggle {
  display: none;
}

/* 响应式：移动端侧栏变抽屉，内容区全屏 */
@media (max-width: 768px) {
  .sidebar-toggle {
    display: inline-flex;
  }
  .sidebar {
    top: 0;
    left: 0;
    bottom: 0;
    width: min(280px, 82vw);
    border-radius: 0 var(--radius-xl) var(--radius-xl) 0;
    transform: translateX(-100%);
    z-index: var(--z-modal);
    transition: transform var(--motion-base) var(--motion-ease-standard);
  }
  .app-shell.sidebar-open .sidebar {
    transform: translateX(0);
  }
  .app-main {
    margin-left: 0;
    padding-right: 0;
    /* 移动端不分「桌面 + 悬浮面板」——内容区全屏，把悬浮相关的四条复位。
       （源顺序在后、特异性相同，所以能覆盖桌面端的规则） */
    margin-top: 0;
    margin-right: 0;
    margin-bottom: 0;
    background: transparent;
    border-radius: 0;
  }
  .sidebar {
    /* 抽屉式：贴左边缘、只圆右侧两角（上面的 .sidebar 块已设，这里补齐悬浮相关的复位） */
    margin: 0;
  }
  .page-stack {
    background: var(--color-bg);
    border-radius: 0;
  }
  .topbar {
    top: 0;
    margin-top: 0;
    border-radius: 0;
    padding: 0 var(--space-4);
  }
  .page {
    padding: var(--space-4);
  }
  .page-header {
    flex-direction: column;
    align-items: stretch;
  }
  .page-actions {
    flex-wrap: wrap;
  }
  .page-actions .btn--lg {
    width: 100%;
  }
  .input,
  .select {
    min-height: 44px;
  }
  .icon-btn {
    width: 44px;
    height: 44px;
  }
  /* ⭐ 顶部标签栏内的图标按钮：移动端**回到 44px**（触摸目标）。
     ────────────────────────────────────────────────────
     ⚠️⚠️ 这条是**必须的**，不是可选的修饰。原因：
       桌面那条 `.page-tabs-bar .icon-btn { 36px }`（特异性 0,2,0）**在手机上也照样生效**
       （media 查询不改变特异性），会把上面这条 `.icon-btn{44}`（0,1,0）盖掉。
       不补本条，手机上的菜单开关 / 刷新 / 关闭 / 搜索 / 通知 全会变成 36px。
     ⭐ 为什么不能只看桌面：菜单开关是**手机上唯一能唤出侧栏的入口**
       （顶栏已撤，见本文件 C4 那条门禁）。36px 命中区偏小：
       Apple HIG 建议 ≥ 44pt、Material 建议 ≥ 48dp。
       （实测过：本轮改动前手机上它是 40px、改后若不补本条会掉到 36px —— 比改前还小。）
     ⭐ 两个场景各自回到既有基准（不是新造一套尺寸）：桌面 36 / 移动端 44。 */
  .page-tabs-bar .icon-btn {
    width: 44px;
    height: 44px;
  }
  /* 栏高在移动端单独加到 56（桌面 52）——
     因为里面装的是 44px 的触摸目标，需要上下各 6px 的留白。
     ⚠️ 必须联动 `--header-height`（分析页目录条的吸顶高度读它），否则手机上目录条会错位。
     ⚠️ 不能把本条写进上面那个公共区域：它只管移动端，而 `--tabs-bar-height` 是全局令牌。 */
  :root {
    --tabs-bar-height: 56px;
    --header-height: 56px;
  }
}

/* 侧栏抽屉遮罩（仅移动端显示） */
.sidebar-backdrop {
  display: none;
}
@media (max-width: 768px) {
  .sidebar-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    background: color-mix(in srgb, var(--color-gray-900) 40%, transparent);
    z-index: calc(var(--z-modal) - 1);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--motion-base) var(--motion-ease-standard);
  }
  .app-shell.sidebar-open .sidebar-backdrop {
    opacity: 1;
    pointer-events: auto;
  }
}

/* ==========================================================================
   侧栏：搜索入口 + 底部「我的」（2026-09-19 结构重排）
   乐哥：「搜索框放在菜单栏里面（位置你给建议）」「右上角我的 → 挪菜单栏最下面」
   ========================================================================== */

/* ==========================================================================
   标签栏右侧：搜索入口（2026-09-19 乐哥：「搜索框要不继续放到右上角，就是通知左边」）
   ─────────────────────────────────────────────────────────────────────────────
   从侧栏搬过来。三件事决定了它的样子：

   ① 宽度 150px（不是历史那种 280px 的完整输入框）——
      这是"标签区空间"与"框的体量"的取舍。实测标签区余量（4 个标签需 484px）：
        视口 1512：280px 宽时余 319 / 150px 宽时余 449
        视口 1280：280px 宽时余  87 / 150px 宽时余 217
        视口 1180：280px 宽时**缺 13px（标签开始横向滚动）** / 150px 宽时余 117
      ⇒ 280px 会在 13 寸笔记本上把标签挤到滚动；150px 在 1280 以上都稳。
      （150 这个数是照"搜索 + 图标 + / 提示"实际需要的宽度定的，不是随手取的。）

   ② 它是一个**入口**、不是输入框（点击弹 640px 居中弹层）——
      原因见 index.html 的注释：问 AI 的长回答需要 640px，下拉面板装不下。

   ③ 位置在**通知左边**、且属于"全局工具"那一组（刷新/关闭是"标签的操作"，
      搜索与通知是"全站的能力"）⇒ 与通知同组、共用一个左侧分隔线。 */
.gs-entry {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 150px;
  /* 高 40（2026-09-19 晚 34 → 40）—— 与标签（40）和顶栏内图标按钮（40）同一体量。
     原来 34 比邻居矮 2~4px，一行里看着"没对齐、没长齐"。 */
  height: 40px;
  padding: 0 var(--space-3);
  flex-shrink: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg);
  color: var(--color-muted);
  font-size: var(--font-size-sm);
  font-family: inherit;
  cursor: pointer;
  transition: border-color var(--motion-fast) var(--motion-ease-standard),
    background var(--motion-fast) var(--motion-ease-standard);
}
.gs-entry:hover { border-color: var(--color-accent-text); background: var(--color-surface); }
.gs-entry__icon { display: flex; flex-shrink: 0; opacity: .75; }
.gs-entry__text { flex: 1; text-align: left; }
/* 快捷键提示（`/`）—— 与侧栏那版同款小键帽，告诉新人这功能有快捷键 */
.gs-entry__kbd {
  flex-shrink: 0;
  font-size: var(--font-size-xs);
  line-height: 16px;
  padding: 0 5px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-meta);
}
/* 这一组（搜索 + 通知）与左边「标签操作」（刷新/关闭）用一条竖线断开，语义不同 */
.gs-entry-wrap {
  display: flex;
  align-items: center;
  margin-left: 6px;
  padding-left: 10px;
  border-left: 1px solid var(--color-border-soft);
}
/* 通知：同组内与搜索留一点气口（分隔线已由 .gs-entry-wrap 提供，这里不再画第二条） */
.page-tabs-bar__tools .notify-wrap {
  margin-left: 6px;
  padding-left: 0;
  border-left: none;
}
/* 窄屏（≤1100px）：搜索入口收成图标，把宽度还给标签。
   实测 1024px 视口下 150px 入口会让标签区缺 39px；收成图标后够用。
   ⚠️ 只隐藏文字与键帽、**不隐藏整个按钮** —— 搜索在窄屏上更该有入口（侧栏入口已撤）。 */
@media (max-width: 1100px) {
  .gs-entry { width: 36px; padding: 0; justify-content: center; }
  .gs-entry__text, .gs-entry__kbd { display: none; }
}
/* 手机端（≤768px）：工具区本来就只有图标，保持图标形态即可；
   侧栏入口已撤，手机上搜索必须还能用 ⇒ 不隐藏。 */

/* 底部「我的」——基础盒模型在 base.css 的 .sidebar__footer（padding/border-top/flex-shrink），
   这里只写**布局变更**部分，避免同一个类在两处重复声明同一批属性。 */

/* ⚠️ 箭头（chevronDown）必须推到最右（2026-09-19 乐哥：「那个箭头太靠左」）。
   原因：`.user-chip` 是 flex，箭头是第 3 个子元素，默认紧跟在名字后面；
   在原顶栏里它靠得近不明显，搬到 240px 宽的侧栏底部、且 chip 被拉成 100% 宽之后，
   箭头停在中间、右边留一大片空 —— 看起来像没对齐。
   ⇒ `margin-left:auto` 把它顶到右边缘，与下方菜单项右缘对齐。
   ⚠️ 只作用于侧栏底部这一个 chip，不动顶栏/其它位置的 .user-chip。 */
.sidebar__footer .user-chip > .nav-icon {
  margin-left: auto;
  flex-shrink: 0;
}
/* 名字区可收缩：名字长时省略，不把箭头挤出容器 */
.sidebar__footer .user-chip > .user-meta {
  min-width: 0;
  overflow: hidden;
}
.sidebar__footer .user-chip .user-name,
.sidebar__footer .user-chip .user-role {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sidebar__footer .user-chip { width: 100%; }
/* ⚠️ 下拉**向上**弹（在底部）：原顶栏里是 `top: calc(100% + 8px)`，
   搬到底部后那样会弹到屏幕外。改为向上、且左对齐铺满侧栏。 */
.sidebar__footer .profile-menu {
  top: auto;
  bottom: calc(100% + 8px);
  left: 0;
  right: auto;
  width: 100%;
  min-width: 208px;
}

/* ==========================================================================
   全站搜索 · 居中弹层
   ========================================================================== */
.gs-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  background: color-mix(in srgb, var(--color-gray-900) 38%, transparent);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 12vh var(--space-4) var(--space-4);
}
.gs-overlay[hidden] { display: none; }
.gs-dialog {
  width: min(640px, 100%);
  max-height: 70vh;
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.gs-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0 var(--space-4);
  height: 52px;
  flex-shrink: 0;
  border-bottom: 1px solid var(--color-border-soft);
}
.gs-head__icon { display: flex; flex-shrink: 0; color: var(--color-muted); }
.gs-head__input {
  flex: 1;
  min-width: 0;
  border: none;
  outline: none;
  background: transparent;
  font-size: var(--font-size-md);
  color: var(--color-fg);
}
.gs-head__input::placeholder { color: var(--color-placeholder); }
.gs-head__close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-muted);
  cursor: pointer;
}
.gs-head__close:hover { background: var(--color-bg); color: var(--color-fg); }
/* 弹层里的结果面板：不再绝对定位（它是弹层的直接内容），铺满并自己滚 */
.gs-dialog .global-search__panel {
  position: static;
  min-width: 0;
  width: 100%;
  max-width: none;
  max-height: none;
  flex: 1 1 auto;
  overflow-y: auto;
  border: none;
  border-radius: 0;
  box-shadow: none;
}
/* 打开时锁住背景滚动，避免弹层后面还能滚 */
body.gs-open { overflow: hidden; }
