/* PTC Insight — 唯一样式表（Stage 1.4「壳」）。
   视觉权威：~/.claude-tools/specs/ptc-report-django-DESIGN.md（frontend-council 2026-08-26 主方向=体系派）。

   宪法（违反即打回）：
   1. 深度只标容器，永不标数据——面板/按钮/输入有圆角与投影；表格/行/单元格零圆角零投影零渐变。
   2. 一色一职：navy=文字/结构/主操作，red=未达标语义与限量品牌 CTA，green/amber=达标/临界。
   3. 导航当前项用 navy 淡底 + navy 标记条；不引入第四种点缀色。
   4. 数据区绝对安静。
   5. 零魔法数字，尺寸与颜色一律走 :root token。
   6. 无运行时外链，且零字体请求——门店平板常年弱网/内网。

   ADDENDUM v2（2026-08-26）品牌重映射已生效：字体全 Arial（无 @font-face）、
   cyan 体系整体移除、navy/red/off-white 对齐 PTC Brand Guidelines v2.0。
   token 与 PTC Mobile 自此分叉；布局/断点/组件/动效纪律不变。 */

/* --- Tokens -------------------------------------------------------------- */
:root {
  /* 底 + 面（官方 Off White / White） */
  --bg: #f8f8f8;
  --surface: #ffffff;
  --hairline: rgba(26, 48, 89, 0.09);
  --divider: #d2d2d2;

  /* 中性梯度：真中性，不带蓝调 */
  --n-100: #f8f8f9;
  --n-200: #ededf0;
  --n-400: #d8d8dc;
  --n-500: #aeaeb4;
  --n-600: #8a8a91;
  --n-700: #62626a;
  --n-800: #43434a;

  /* 品牌 + 状态（官方 Navy / Red；green/amber 品牌未定义，沿用功能色原值） */
  --ink: #1a3059;
  /* --action = 应用内交互色，官方 navy 本色；-700/-800 是 hover/active 加深档 */
  --action: #1a3059;
  --action-700: #142647;
  --action-800: #0f1d36;
  --action-100: #e8edf4;
  --ok: #12855a;
  --ok-700: #0c6a47;
  --ok-100: #e8f6ef;
  --warn: #c47a0a;
  --warn-700: #8f5606;
  --warn-100: #fdf3e2;
  /* red 一色两职：达标「未达标」语义 + 无数据页面的限量品牌 CTA */
  --alert: #cc271d;
  --alert-700: #a31f17;
  --alert-100: #fae9e8;

  /* 圆角 */
  --r-panel: 16px;
  --r-key: 11px;
  --r-tag: 6px;
  --r-puck: 999px;

  /* 高度（阴影层） */
  --e1: 0 1px 2px rgba(26, 48, 89, 0.05);
  --e2: 0 1px 2px rgba(26, 48, 89, 0.05), 0 8px 20px -4px rgba(26, 48, 89, 0.14);
  --e3: 0 1px 3px rgba(26, 48, 89, 0.06), 0 14px 32px -8px rgba(26, 48, 89, 0.18),
        0 40px 72px -32px rgba(26, 48, 89, 0.3);

  /* 别名：保留 PTC Mobile 的语义映射，组件代码可直接照搬。
     muted-500/600 刻意映射到更深一档，中性梯度去蓝后浅档对白底不足 4.5:1。 */
  --line: var(--hairline);
  --fill-100: var(--n-100);
  --fill-200: var(--n-200);
  --muted-500: var(--n-600);
  --muted-600: var(--n-700);
  --muted-700: var(--n-700);
  --muted-800: var(--n-800);
  --action-tint: var(--action-100);
  --alert-tint: var(--alert-100);
  --alert-text: var(--alert-700);

  /* 间距 / 尺寸 */
  --pad: 14px;
  --gap: 12px;
  --card-pad: 16px;
  --tap: 44px;
  --btn-lg: 48px;
  --tabbar-h: 58px;
  /* More 菜单卡片最小高度：两行文字 + 上下留白，整卡即拇指区 */
  --menu-card-h: 72px;
  --sidebar-w: 236px;
  --logo-h: 26px;

  /* 字号 */
  --fs-title: 18px;
  --fs-section: 20px;
  --fs-body: 14px;
  --fs-sm: 13px;
  --fs-xs: 12px;
  --fs-kicker: 11px;
  --fs-micro: 10px;

  /* 品牌标题字体即 Arial；正文暂以 Arial 代 FIELDWORK（授权未取得）。零字体请求 */
  --font: Arial, "Helvetica Neue", Helvetica, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --z-header: 20;
  --z-tabbar: 30;
  --z-toast: 50;

  /* ---- 以下为报表场景新增（PTC Mobile 无数据表体系） ---- */

  /* 表格两档行高：紧凑档扫读跨店对比，常规档等于 --tap 供手机点按下钻 */
  --row-h: 36px;
  --row-h-lg: 44px;
  --th-h: 34px;
  --cell-pad-x: 12px;
  --cell-pad-x-lg: 16px;

  /* 顶部状态条 */
  --topbar-h: 56px;
  --topbar-h-sm: 48px;

  /* 行首 4px 状态色条（council 强制的第二重编码） */
  --flag-w: 4px;

  /* 图表容器（Stage 2 用；先定死高宽比，弱网加载才不会撑开又塌陷） */
  --chart-ar: 16 / 9;
  --chart-ar-sm: 4 / 3;
  --chart-h-min: 220px;

  /* 加载态 */
  --skeleton-bg: var(--n-200);
  --spinner-size: 16px;
  --spinner-size-lg: 24px;

  /* 动效：唯一允许的时长常量，组件里禁止写裸毫秒 */
  --t-fast: 120ms;
  --t-ui: 160ms;
  --t-color: 200ms;

  /* 表头 sticky 必须低于 --z-header，否则滚动时表头会盖住状态条 */
  --z-sticky-th: 10;

  /* 排行条形图：高度由「行数 × 行高」在 HTML 里就算死，不靠 JS 撑开 */
  --chart-row-h: 20px;
  --chart-axis-h: 44px;

  /* KPI 卡的大数字（DESIGN.md §7.8） */
  --fs-kpi: 28px;
  /* 首页摘要条/单店视图的主数字：全站唯一比 KPI 更大的一档 */
  --fs-lead-num: 40px;

  /* 首页右侧异常抽屉：桌面固定宽（表格吃剩余宽度），手机变横滑卡宽 */
  --drawer-w: 320px;
  --attn-card-w: 240px;

  /* 长表格容器的高度上限：给了上限，sticky 表头才真的粘得住 */
  --table-max-h: 68vh;
}

/* 壳的断点必须与 token 换档点同一个值，否则会出现「桌面布局 + 手机间距」的中间态 */
@media (min-width: 900px) {
  :root {
    --pad: 28px;
    --gap: 20px;
    --card-pad: 18px;
    --fs-title: 24px;
  }
}

/* --- 基础重置 / 排版 ------------------------------------------------------ */
* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  background-image: radial-gradient(120% 90% at 50% -10%, #ffffff 0%, #fafafa 45%, #f2f2f2 100%);
  background-attachment: fixed;
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  /* 金额、日期、店号全站等宽对齐；表格扫读靠的就是这个 */
  font-variant-numeric: tabular-nums;
}

a { color: var(--action-800); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Arial 无 800：字重上限 700，靠收紧字距补回原本由重字重承担的密度 */
h1, h2, h3 { margin: 0; font-weight: 700; letter-spacing: -0.02em; }

.kicker {
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted-600);
}
.muted { color: var(--muted-700); font-size: var(--fs-sm); }
.note { font-size: var(--fs-kicker); color: var(--muted-700); }
.mono { font-family: var(--font-mono); font-size: var(--fs-sm); }
.stack { display: flex; flex-direction: column; gap: var(--gap); }

/* --- a11y 工具类 --------------------------------------------------------- */
:focus-visible {
  outline: 2px solid var(--action);
  outline-offset: 2px;
}

/* 键盘用户不必 tab 过整条侧栏才能进正文 */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: var(--z-toast);
  padding: 10px 14px;
  background: var(--ink);
  color: #fff;
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.skip-link:focus { left: 0; text-decoration: none; }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* 壳的两套形态共用同一份 DOM，靠这两个类切换，避免重复渲染两遍导航。
   刻意只写「隐藏」不写「显示」：显示态留给元素自己的 display，
   否则会把 .topbar-pagetitle 从 block 改成 flex，text-overflow 省略号就失效了。 */
@media (max-width: 899px) { .desk-only { display: none !important; } }
@media (min-width: 900px) { .mob-only { display: none !important; } }

/* --- 应用壳 -------------------------------------------------------------- */
.shell { display: flex; min-height: 100vh; }

.shell-col {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
}

.sidebar { display: none; }

.app-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--gap);
  width: 100%;
  padding: var(--pad);
  /* Tab Bar 是 sticky 不是 fixed，这里只补一点呼吸位 */
  padding-bottom: calc(var(--pad) + 8px);
}

/* --- 顶部状态条 ---------------------------------------------------------- */
/* 实底不用 backdrop-filter：council 弃用 blur，且它在门店旧安卓 WebView 上掉帧 */
.topbar {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: var(--topbar-h-sm);
  padding: 0 var(--pad);
  padding-top: max(0px, env(safe-area-inset-top));
  background: var(--surface);
  border-bottom: 1px solid var(--hairline);
}

.topbar-scope { display: flex; align-items: center; gap: 10px; }
.topbar-scope select { width: auto; min-width: 168px; }

.topbar-pagetitle {
  min-width: 0;
  margin-right: auto;
  font-size: var(--fs-title);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.topbar-spacer { flex: 1; }

.topbar-stamp {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: none;
  margin: 0;
  font-size: var(--fs-kicker);
  color: var(--muted-700);
  white-space: nowrap;
}
/* 圆点只是加速识别；新鲜度本身由后面的时间文字承载，颜色不是唯一编码 */
.stamp-dot {
  width: 9px;
  height: 9px;
  flex: none;
  background: var(--n-400);
  border-radius: var(--r-puck);
}
.stamp-dot--fresh { background: var(--ok); }
.stamp-dot--stale { background: var(--warn); }

.topbar-user { flex: none; text-align: right; line-height: 1.25; }
.topbar-user-name { font-size: var(--fs-sm); font-weight: 700; }
.topbar-user-role { font-size: var(--fs-kicker); color: var(--muted-700); }

.topbar-logout { display: flex; flex: none; margin: 0; }

/* 手机端图标登出：整块 44×44 才点得中，图标本身 20px */
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--tap);
  min-height: var(--tap);
  padding: 0;
  color: var(--ink);
  background: transparent;
  border: 0;
  cursor: pointer;
  transition: background-color var(--t-color) ease, transform var(--t-ui) ease;
}
.icon-btn:hover { background: var(--fill-100); text-decoration: none; }
.icon-btn:active { transform: scale(0.97); }
.icon-btn svg { width: 20px; height: 20px; }

/* --- 手机底部 Tab Bar ---------------------------------------------------- */
.tabbar {
  position: sticky;
  bottom: 0;
  z-index: var(--z-tabbar);
  display: flex;
  background: var(--surface);
  border-top: 1px solid var(--hairline);
  padding-bottom: env(safe-area-inset-bottom);
}
.tab {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-height: var(--tabbar-h);
  padding: 6px 2px;
  background: var(--surface);
  color: var(--ink);
  border: 0;
  border-top: 3px solid transparent;
  font: inherit;
  transition: transform var(--t-ui) ease, background-color var(--t-color) ease;
}
.tab:hover { text-decoration: none; }
.tab:active { transform: scale(0.97); }
.tab:focus-visible { outline: 2px solid var(--action); outline-offset: -2px; }
.tab-label {
  font-size: var(--fs-kicker);
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
/* 当前项三重编码：3px 顶条（形状）+ 浅青底（颜色）+ aria-current（语义） */
.tab.is-active {
  background: var(--action-100);
  color: var(--action-800);
  border-top-color: var(--action);
}

/* --- 桌面壳 -------------------------------------------------------------- */
@media (min-width: 900px) {
  .tabbar { display: none; }

  .sidebar {
    display: flex;
    flex-direction: column;
    flex: 0 0 var(--sidebar-w);
    width: var(--sidebar-w);
    position: sticky;
    top: 0;
    height: 100vh;
    background: var(--surface);
    /* 方角无影：侧栏是结构不是卡片，只用一条 hairline 与正文分开 */
    box-shadow: 1px 0 0 var(--hairline);
  }

  .sidebar-brand { flex: none; padding: 18px 20px; border-bottom: 1px solid var(--hairline); }
  .sidebar-wordmark {
    display: block;
    font-size: var(--fs-section);
    font-weight: 700;
    letter-spacing: -0.03em;
    line-height: var(--logo-h);
    color: var(--ink);
  }
  .sidebar-brand .kicker { margin-top: 3px; }

  /* 导航能长到 ~19 项 + 6 个分组标签，必须自己滚，品牌位与页脚不跟着走 */
  .sidebar-nav { flex: 1; min-height: 0; overflow-y: auto; padding: 8px 0; }

  .nav-group-label {
    padding: 14px 20px 4px;
    font-size: var(--fs-micro);
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--muted-600);
  }

  .nav-item {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: var(--tap);
    padding: 0 20px;
    border-left: 3px solid transparent;
    color: var(--ink);
    font-size: var(--fs-body);
    font-weight: 400;
    transition: background-color var(--t-color) ease, color var(--t-color) ease;
  }
  /* 导航项不做 scale：整行缩放会让侧栏「抖」，council 的 .97 是给按钮的 */
  .nav-item:hover { background: var(--fill-100); text-decoration: none; }
  .nav-item:active { background: var(--fill-200); }
  /* 内缩描边，否则焦点框会被侧栏边界裁掉 */
  .nav-item:focus-visible { outline: 2px solid var(--action); outline-offset: -2px; }
  .nav-item.is-active {
    background: var(--action-100);
    color: var(--action-800);
    font-weight: 700;
    border-left-color: var(--action);
  }

  .sidebar-foot {
    flex: none;
    margin-top: auto;
    padding: 16px 20px;
    border-top: 1px solid var(--hairline);
  }
  .sidebar-name { font-size: var(--fs-body); font-weight: 700; }
  .sidebar-role { font-size: var(--fs-xs); color: var(--muted-700); }

  .topbar { min-height: var(--topbar-h); }

  /* 跨店对比表列多，不设 1200 硬顶；行长由列宽控制，不去限制表格宽度 */
  .app-main { max-width: 1440px; padding: 28px var(--pad) 40px; }
}

/* --- 面板 ---------------------------------------------------------------- */
.panel {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-panel);
  box-shadow: var(--e2);
  /* 里面的表格是方角，四角由面板自己裁 */
  overflow: hidden;
}
.panel-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 12px var(--card-pad);
  border-bottom: 1px solid var(--hairline);
}
.panel-head .kicker { letter-spacing: 0.1em; color: var(--ink); }
.panel-head-note { font-size: var(--fs-kicker); color: var(--muted-700); }
.panel-head-end { margin-left: auto; }
.panel-body { padding: var(--card-pad); }
/* 表格直贴面板边，不再套一层内距 */
.panel-body--flush { padding: 0; }
.panel-title { font-size: var(--fs-section); font-weight: 700; letter-spacing: -0.02em; }
.panel-sub { margin: 2px 0 0; font-size: var(--fs-xs); color: var(--muted-700); }

/* --- 按钮 ---------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--tap);
  padding: 0 16px;
  font-family: inherit;
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1.2;
  text-align: center;
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--hairline);
  border-radius: var(--r-key);
  box-shadow: var(--e2);
  cursor: pointer;
  /* 逐属性列出，禁止 transition:all——否则 disabled 的 opacity 也会跟着动 */
  transition: transform var(--t-ui) ease, box-shadow var(--t-ui) ease,
              background-color var(--t-color) ease, color var(--t-color) ease;
}
.btn:hover { text-decoration: none; box-shadow: var(--e3); }
/* 按下是「落下去」，不是盖章；.97 与 160ms 是 council 强制值 */
.btn:active { transform: scale(0.97); box-shadow: var(--e1); }
.btn:focus-visible { outline: 2px solid var(--action); outline-offset: 2px; }

/* 应用内唯一主操作：navy 实底白字。平涂无描边无渐变；
   深度只走中性阴影层，不再有有色环境光（navy 已是最深的一档，不需要再发光） */
.btn--primary {
  background: var(--action);
  color: #fff;
  border: 0;
}
.btn--primary:hover { background: var(--action-700); color: #fff; }
.btn--primary:active { background: var(--action-800); color: #fff; transform: scale(0.97); box-shadow: var(--e1); }
/* navy 底上的 navy 描边看不见，改用白色 */
.btn--primary:focus-visible { outline-color: #fff; outline-offset: -4px; }

/* 品牌红 CTA：只允许出现在无数据语义的页面（登录页 Sign in 等），每屏一次。
   数据页面禁止使用——那里的红专属「未达标」 */
.btn--brand {
  background: var(--alert);
  color: #fff;
  border: 0;
}
.btn--brand:hover { background: var(--alert-700); color: #fff; }
.btn--brand:active { background: var(--alert-700); color: #fff; transform: scale(0.97); box-shadow: var(--e1); }
.btn--brand:focus-visible { outline-color: #fff; outline-offset: -4px; }

.btn--secondary { background: var(--surface); color: var(--ink); border-color: var(--hairline); }
.btn--secondary:hover { background: var(--n-100); color: var(--ink); }

/* 红底按钮只给不可逆操作；与 .btn--brand 同色不同语境，不得与达标红表格同屏相邻 */
.btn--danger { background: var(--alert); color: #fff; border-color: transparent; }
.btn--danger:hover { background: var(--alert-700); color: #fff; }

.btn--ghost {
  min-height: 32px;
  padding: 0 8px;
  background: transparent;
  color: var(--action-800);
  border-color: transparent;
  box-shadow: none;
}
.btn--ghost:hover { background: var(--action-100); box-shadow: none; }
.btn--ghost:active { transform: scale(0.97); box-shadow: none; }

.btn--lg { min-height: var(--btn-lg); padding: 0 20px; }
.btn--sm { min-height: 36px; }
.btn--block { display: flex; width: 100%; }
/* 全宽按钮上 .97 的位移观感偏大，降一档 */
.btn--block:active { transform: scale(0.99); }

.btn[disabled], .btn.is-disabled {
  opacity: 0.5;
  cursor: default;
  box-shadow: var(--e1);
  transform: none;
}
.btn[disabled]:hover, .btn.is-disabled:hover { box-shadow: var(--e1); }
.btn[disabled]:active, .btn.is-disabled:active { transform: none; box-shadow: var(--e1); }
.btn--primary[disabled], .btn--primary.is-disabled { box-shadow: var(--e1); }

.btn-row { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; }

/* 提交中不 disabled：保留可聚焦，读屏才读得到 aria-busy；pointer-events 挡重复提交 */
.btn.is-loading { pointer-events: none; }

/* --- 表单 ---------------------------------------------------------------- */
.field { display: block; margin-bottom: 14px; }
.field:last-child { margin-bottom: 0; }
.field-label {
  display: block;
  margin-bottom: 5px;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted-600);
}
.field-note { margin: 5px 0 0; font-size: var(--fs-kicker); color: var(--muted-700); }
.field-error { margin: 5px 0 0; font-size: var(--fs-kicker); font-weight: 700; color: var(--alert-700); }

input[type="text"],
input[type="password"],
input[type="tel"],
input[type="email"],
input[type="date"],
input[type="search"],
select {
  display: block;
  width: 100%;
  min-height: var(--tap);
  padding: 10px 12px;
  font-family: inherit;
  font-size: 16px; /* iOS 下 <16px 聚焦会强制放大页面 */
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-key);
  box-shadow: inset 0 1px 2px rgba(26, 48, 89, 0.04);
  appearance: none;
  -webkit-appearance: none;
  transition: border-color var(--t-color) ease, box-shadow var(--t-ui) ease;
}
select {
  /* appearance:none 去掉了原生箭头，用内联 SVG 补回来（不外链图标） */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238a8a91' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 18px 18px;
  padding-right: 40px;
}
input:hover, select:hover { border-color: var(--n-400); }

/* 全站唯一允许 outline:none 的地方——4px navy 光晕是等效替代，可见性不降 */
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--action);
  box-shadow: 0 0 0 4px rgba(26, 48, 89, 0.35);
}
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: none; }

input:disabled, select:disabled, textarea:disabled {
  background: var(--fill-100);
  color: var(--muted-700);
  cursor: not-allowed;
  box-shadow: none;
}
::placeholder { color: var(--muted-500); }

/* 红边不是唯一编码：必须同时有 .field-error 文字并 aria-describedby 关联 */
.is-invalid { border-color: var(--alert); }

/* --- 数据表 -------------------------------------------------------------- */
/* 横向溢出交给包裹层，表格本身不设 max-width */
.table-scroll { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }

.dtable {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-sm);
}
/* 零圆角零投影零渐变——宪法第 1 条，任何装饰蔓延到这里即打回 */
.dtable th,
.dtable td {
  height: var(--row-h);
  padding: 0 var(--cell-pad-x);
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: middle;
}
.dtable thead th {
  position: sticky;
  top: 0;
  /* 必须低于 --z-header，否则滚动时表头会盖住顶部状态条 */
  z-index: var(--z-sticky-th);
  height: var(--th-h);
  background: var(--n-100);
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted-600);
  border-bottom: 1px solid var(--hairline);
}
/* th 也要写进来：行首是 <th> 的表（排行榜/留客率）末行会剩半截分隔线 */
.dtable tbody tr:last-child td,
.dtable tbody tr:last-child th { border-bottom: 0; }
/* 唯一允许的行反馈：底色。无位移、无投影、无边框变化 */
.dtable tbody tr:hover { background: var(--fill-100); }

.dtable--lg th,
.dtable--lg td { height: var(--row-h-lg); padding: 0 var(--cell-pad-x-lg); }

.dtable .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1; /* 老 WebKit 兜底 */
  white-space: nowrap;
}

/* 手机端横滑时店名列冻结在左侧 */
.dtable .col-sticky {
  position: sticky;
  left: 0;
  background: var(--surface);
}
.dtable thead .col-sticky { background: var(--n-100); z-index: var(--z-sticky-th); }

/* 行首 4px 状态色条：颜色之外还有位置编码，语义仍由同行文字承担 */
.dtable td.flag,
.dtable th.flag {
  /* min-width 是必须的：列多到撑破容器时，auto 表格布局会把没有内容的列压成 0 */
  width: var(--flag-w);
  min-width: var(--flag-w);
  padding: 0;
  background: var(--n-400);
}
.dtable thead th.flag { background: var(--n-400); }
.dtable tr.is-ontrack td.flag { background: var(--ok); }
.dtable tr.is-atrisk td.flag { background: var(--warn); }
.dtable tr.is-behind td.flag { background: var(--alert); }
/* 文字色一律 -700 档，白底 ≥4.5:1 */
.dtable tr.is-ontrack .num--status { color: var(--ok-700); }
.dtable tr.is-atrisk .num--status { color: var(--warn-700); font-weight: 700; }
.dtable tr.is-behind .num--status { color: var(--alert-700); font-weight: 700; }

/* --- 状态标签 ------------------------------------------------------------ */
/* 文案本身就是第二编码，黑白打印/色弱下仍可读 */
.tag {
  display: inline-block;
  padding: 2px 7px;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
  background: var(--n-200);
  color: var(--n-700);
  border: 1px solid var(--n-400);
  border-radius: var(--r-tag);
  box-shadow: none;
}
.tag--ok,
.tag--ontrack { background: var(--ok); color: #fff; border-color: var(--ok); }
.tag--pending,
.tag--atrisk { background: var(--warn-100); color: var(--warn-700); border-color: var(--warn); }
.tag--failed,
.tag--behind { background: var(--alert); color: #fff; border-color: var(--alert); }
.tag--na { background: var(--n-200); color: var(--n-700); border-color: var(--n-400); }

/* --- 加载态 -------------------------------------------------------------- */
/* 只做透明度脉冲：不做位移、不做扫光渐变（扫光是装饰，会侵入数据区） */
.skeleton {
  background: var(--skeleton-bg);
  animation: pulse 1.6s ease-in-out infinite;
}
.skeleton-row { height: var(--row-h); margin-bottom: 1px; }
/* 骨架尺寸与真图一致，加载完才不会跳动 */
.skeleton-chart { aspect-ratio: var(--chart-ar); min-height: var(--chart-h-min); }

.spinner {
  width: var(--spinner-size);
  height: var(--spinner-size);
  flex: none;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: var(--r-puck);
  animation: spin 700ms linear infinite;
}
.spinner--lg { width: var(--spinner-size-lg); height: var(--spinner-size-lg); }

@keyframes spin { to { transform: rotate(360deg); } }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } }

/* --- More 菜单页（Task G，仅手机会走到） --------------------------------- */
/* 一屏能扫完的整页导航：分组标题 + 卡片网格，整卡可点（>72px 拇指区）。
   卡片是容器不是数据，但这里刻意零圆角零投影——它们是入口不是面板，
   靠 1px 边 + 左侧 4px navy 条表达「可点」，与数据区的安静保持一致。 */
.menuhead { margin-bottom: var(--gap); }
.menutitle { font-size: var(--fs-section); font-weight: 700; letter-spacing: -0.02em; }
.menunote { margin: 2px 0 0; font-size: var(--fs-sm); color: var(--muted-700); }
.menunav { display: grid; gap: var(--card-pad); }
.menugroup-title { display: block; margin: 0 0 8px; letter-spacing: 0.1em; color: var(--ink); }
.mgrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--gap); }
.mcard {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  min-height: var(--menu-card-h);
  padding: var(--gap) var(--pad);
  background: var(--surface);
  border: 1px solid var(--hairline);
  /* 左侧 4px 条 = 形状编码，不靠颜色单独承载「这是入口」 */
  border-left: 4px solid var(--action);
  border-radius: 0;
  color: var(--ink);
  transition: background-color var(--t-color) ease;
}
.mcard:hover { background: var(--fill-100); text-decoration: none; }
.mcard:active { background: var(--action-100); }
.mcard:focus-visible { outline: 2px solid var(--action); outline-offset: -2px; }
.mcard.is-active { background: var(--action-100); border-color: var(--action); }
.mcard-name { font-size: var(--fs-body); font-weight: 600; }
.mcard-note { font-size: var(--fs-xs); font-weight: 400; color: var(--muted-700); }

@media (min-width: 600px) {
  .mgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* --- 空态 / 错误态 ------------------------------------------------------- */
/* 无插画、无 emoji；容器高度尽量贴近成功态，避免布局跳动 */
.empty { padding: 32px var(--card-pad); text-align: center; }
.empty-title { font-size: var(--fs-body); font-weight: 700; }
/* 一行说明宽到 140 字符就没人读了，按 65ch 左右收住 */
.empty-note {
  max-width: 62ch;
  margin: 6px auto 0;
  font-size: var(--fs-sm);
  color: var(--muted-700);
}

.alert-note,
.errorbox {
  margin: 14px 0 0;
  padding: 10px 12px;
  background: var(--alert-100);
  color: var(--alert-700);
  border: 1px solid rgba(204, 39, 29, 0.22);
  /* 左侧 4px 实心条 = 颜色之外的第二编码 */
  border-left: 4px solid var(--alert);
  border-radius: var(--r-key);
  font-size: var(--fs-sm);
  font-weight: 700;
}
/* 「去 Portal 改密再来」不是「你错了」，用琥珀不用红 */
.alert-note--warn {
  background: var(--warn-100);
  color: var(--warn-700);
  border-color: rgba(196, 122, 10, 0.25);
  border-left-color: var(--warn);
}

/* --- 登录页 -------------------------------------------------------------- */
.auth {
  min-height: 100dvh; /* dvh 防 iOS 地址栏收起时卡片跳动 */
  display: grid;
  place-items: center;
  padding: var(--pad);
}
.auth-card {
  width: 100%;
  max-width: 380px;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-panel);
  box-shadow: var(--e2);
  padding: 28px 24px;
}
/* 戏在字重对比上，不在装饰上：品牌 800 / 说明 400 */
.auth-brand {
  font-size: 32px;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.05;
  color: var(--ink);
}
.auth-sub {
  margin: 6px 0 0;
  font-size: var(--fs-sm);
  font-weight: 400;
  color: var(--muted-700);
}
.auth-form { margin-top: 20px; }
.auth-submit { margin-top: 18px; }
.auth-foot {
  margin: 18px 0 0;
  font-size: var(--fs-kicker);
  color: var(--muted-700);
  text-align: center;
}

@media (max-width: 419px) {
  .auth-card { max-width: 100%; padding: 24px 18px; }
}

/* --- Target 页：筛选栏 + 双界面切换 -------------------------------------- */
/* 一整行的筛选表单。手机上 .pagebar-lead（界面切换 + 月份）独占第一行，
   其余筛选换到第二行——门店最常改的就是月份 */
.pagebar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 10px 12px;
  margin: 0;
}
.pagebar-lead,
.pagebar-rest {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 10px;
  flex: 1 1 100%;
  min-width: 0;
}

.fsel { display: flex; flex-direction: column; gap: 4px; flex: 1 1 140px; min-width: 0; }
.fsel-label {
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted-600);
}
.fsel select { min-width: 0; }
.fsel-apply { flex: 0 0 auto; }

/* 无 JS 时切换器不渲染：点了没反应比没有更糟。
   .js 由 <head> 里一行脚本打上，脚本迟到也不会造成页面顶部跳动 */
.viewtabs { display: none; }
.js .viewtabs {
  display: inline-flex;
  flex: 0 0 auto;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-key);
  box-shadow: var(--e1);
  overflow: hidden;
}
.viewtab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: var(--tap);
  padding: 0 14px;
  background: var(--surface);
  color: var(--ink);
  border: 0;
  border-bottom: 3px solid transparent;
  font-family: inherit;
  font-size: var(--fs-xs);
  font-weight: 400;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  transition: transform var(--t-ui) ease, background-color var(--t-color) ease,
              color var(--t-color) ease;
}
.viewtab svg { width: 16px; height: 16px; flex: none; }
.viewtab:hover { background: var(--fill-100); }
.viewtab:active { transform: scale(0.97); }
.viewtab:focus-visible { outline: 2px solid var(--action); outline-offset: -2px; }
/* 当前项三重编码：3px 底条（形状）+ navy 淡底（颜色）+ 字重 + aria-selected（语义） */
.viewtab.is-active {
  background: var(--action-100);
  color: var(--action-800);
  font-weight: 700;
  border-bottom-color: var(--action);
}

.view { display: flex; flex-direction: column; gap: var(--gap); }
/* 作者样式的 display 会盖过浏览器默认的 [hidden]，必须显式写回来 */
.view[hidden] { display: none; }
.view:focus { outline: none; }

/* --- Target 页：结论行 + KPI 卡 ------------------------------------------ */
/* 品牌 Voice「结论先行、讲人话」：进页第一眼读到的是判断，不是数字堆 */
.lede {
  margin: 0;
  max-width: 70ch;
  font-size: var(--fs-title);
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.lede strong { font-weight: 700; }

.kpirow { display: grid; grid-template-columns: 1fr; gap: var(--gap); }

/* KPI 卡是唯一允许圆角 + 投影的数据容器（摘要，非明细） */
.kpi {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-panel);
  box-shadow: var(--e2);
  padding: var(--card-pad);
}
.kpi-label {
  margin: 0;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted-600);
}
.kpi-value {
  margin: 6px 0 0;
  font-size: var(--fs-kpi);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.02em;
  /* 大号孤立数字用比例数字：等宽在这个字号下会显得松散 */
  font-variant-numeric: normal;
}
/* 状态做文字色一律 -700 档，白底 ≥4.5:1 */
.kpi-value--ok { color: var(--ok-700); }
.kpi-value--warn { color: var(--warn-700); }
.kpi-value--alert { color: var(--alert-700); }
.kpi-sub { margin: 6px 0 0; font-size: var(--fs-xs); color: var(--muted-700); }

/* 这张卡同时是两张图的图例：色块永远配文字与数量，颜色不单独承载信息 */
.statuslegend {
  display: flex;
  flex-direction: column;
  gap: 5px;
  margin: 8px 0 0;
  padding: 0;
  list-style: none;
  font-size: var(--fs-sm);
}
.statuslegend-item { display: flex; align-items: center; gap: 8px; }
/* 方块不圆角：圆角属于容器，不属于数据编码 */
.statuslegend-swatch { width: 10px; height: 10px; flex: none; }
.statuslegend-swatch--ok { background: var(--ok); }
.statuslegend-swatch--warn { background: var(--warn); }
.statuslegend-swatch--alert { background: var(--alert); }
.statuslegend-count { min-width: 3ch; font-weight: 700; text-align: right; }

/* --- Target 页：图表容器 ------------------------------------------------- */
/* 高度在 HTML 解析阶段就确定（行数 × 行高），ECharts 迟到也不会撑开又塌陷 */
.chart {
  position: relative;
  width: 100%;
  aspect-ratio: var(--chart-ar);
  min-height: var(--chart-h-min);
}
.chart--rank {
  aspect-ratio: auto;
  min-height: 0;
  height: calc(var(--rank-rows, 12) * var(--chart-row-h) + var(--chart-axis-h));
}
.chart-skeleton { width: 100%; height: 100%; }
.chart--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  height: auto;
  min-height: var(--chart-h-min);
  padding: var(--card-pad);
  text-align: center;
  font-size: var(--fs-sm);
  color: var(--muted-700);
}
.chart-note {
  margin: 0;
  padding: 8px var(--card-pad) 12px;
  font-size: var(--fs-kicker);
  color: var(--muted-700);
}

@media (max-width: 899px) {
  .chart { aspect-ratio: var(--chart-ar-sm); }

  /* 手机第一行只放最要紧的两件事：界面切换 + 月份，且必须挤在同一行。
     页签为此收窄内距与字号——手指仍有 44px 高度可点 */
  .pagebar-lead { flex-wrap: nowrap; }
  .pagebar-lead .fsel--month { flex: 1 1 auto; }
  .viewtab { padding: 0 10px; font-size: var(--fs-micro); }
}

/* --- Target 页：明细表 --------------------------------------------------- */
/* sticky 的参照系是 .table-scroll 这个滚动容器（overflow-x 让它成为 scrollport），
   不是视口——所以 top 必须是 0，写 --topbar-h 会把表头往下推一整条状态条的高度。
   表头真正「粘住」靠的是 .table-scroll--sticky 给容器的高度上限（见下） */
.dtable--target thead th {
  top: 0;
  height: auto;
  min-height: var(--th-h);
  max-width: 108px;
  padding: 8px var(--cell-pad-x);
  line-height: 1.3;
  vertical-align: bottom;
}
/* 基线里 .num 是 nowrap（给数字用的），表头必须放开，否则长列名会被裁掉 */
.dtable--target thead th,
.dtable--target thead th.num { white-space: normal; }
/* 数字列不换行，否则金额会被拆成两行读不出来 */
.dtable--target tbody td,
.dtable--target tbody th,
.dtable--target tfoot td,
.dtable--target tfoot th { white-space: nowrap; }

/* 横滑 15 列时，色条与店名一起冻结在左侧 */
.dtable--target td.flag,
.dtable--target th.flag { position: sticky; left: 0; z-index: 1; }
.dtable--target .col-sticky { left: var(--flag-w); }
.dtable--target thead th.flag,
.dtable--target thead .col-sticky { z-index: calc(var(--z-sticky-th) + 1); }
/* 冻结列有自己的底色，行 hover 必须同步，否则整行反馈断在第一列 */
.dtable tbody tr:hover .col-sticky { background: var(--fill-100); }

/* 排序表头：整格可点，方向用箭头（形状）而非只靠颜色。
   用 flex 而非 inline-flex：inline-flex 会按 max-content 撑开，长表头就不换行、互相压字 */
.dtable .th-sort {
  display: flex;
  align-items: baseline;
  gap: 4px;
  color: inherit;
  text-decoration: none;
}
.dtable .th-sort > span:first-child { min-width: 0; }
.dtable .th-sort:hover { text-decoration: underline; }
.dtable th.num .th-sort { justify-content: flex-end; text-align: right; }
.dtable th[aria-sort="ascending"] .th-sort,
.dtable th[aria-sort="descending"] .th-sort { color: var(--ink); }
.th-arrow { font-size: var(--fs-kicker); }

/* Payments 页的两视图切换：GET 链接（无 JS 也要能切），所以不能用 JS-only 的
   .viewtabs 容器；外观复用 .viewtab，只补容器与去掉链接下划线 */
.viewlinks {
  display: inline-flex;
  flex: 0 0 auto;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-key);
  box-shadow: var(--e1);
  overflow: hidden;
}
.viewlinks .viewtab { text-decoration: none; }

/* 缺快照日的整行：文字已经把话说清楚，这里只降对比度，不加装饰 */
.dtable .row-na td { color: var(--muted-600); }

/* Total 行靠分隔线与字重区分，不给底色（底色是状态语义的位置） */
.dtable tfoot .row-total th,
.dtable tfoot .row-total td {
  border-top: 2px solid var(--divider);
  border-bottom: 0;
  font-weight: 700;
}

@media (min-width: 900px) {
  .pagebar-lead { flex: 0 0 auto; }
  .pagebar-rest { flex: 1 1 auto; }
  .fsel { flex: 0 1 180px; }
  .kpirow { grid-template-columns: repeat(3, 1fr); }
  /* 87 行 × 15 列，列名必须一直看得见；手机不开，嵌套纵向滚动会跟页面滚动打架 */
  .table-scroll--sticky { max-height: var(--table-max-h); overflow-y: auto; }
}

/* --- 首页：跨店对比板 ---------------------------------------------------- */
/* 摘要条与单店大卡是「摘要容器」，按 DESIGN §7.8 允许圆角 + 投影；
   它们下面的对比表仍然一格装饰都不给。 */
.summary,
.storehero {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--gap);
  padding: var(--card-pad);
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-panel);
  box-shadow: var(--e2);
}

.summary-id { flex: 1 1 240px; min-width: 0; }
.summary-title { font-size: var(--fs-title); font-weight: 700; letter-spacing: -0.01em; }
.summary-sub { margin: 4px 0 0; font-size: var(--fs-sm); color: var(--muted-700); }
.summary-metric { flex: 0 0 auto; }
.summary-value,
.storehero-value {
  margin: 4px 0 0;
  font-size: var(--fs-lead-num);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.02em;
  /* 大号孤立数字用比例数字：等宽在这个字号下会散架 */
  font-variant-numeric: normal;
}
.summary-note { margin: 4px 0 0; font-size: var(--fs-xs); color: var(--muted-700); }

/* 状态 chip：无 JS 时是静态计数（span），不给手型也不占 44px；
   home.js 把它换成 <button> 之后才升到触控尺寸。 */
.chips { display: flex; flex-wrap: wrap; gap: 8px; flex: 1 1 100%; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 32px;
  padding: 0 10px;
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: var(--r-tag);
  font-family: inherit;
  font-size: var(--fs-xs);
  color: var(--ink);
  transition: background-color var(--t-color) ease, border-color var(--t-color) ease;
}
.chip-count { font-weight: 700; font-variant-numeric: tabular-nums; }
/* 方块不圆角：圆角属于容器，不属于状态编码 */
.chip-dot { width: 9px; height: 9px; flex: none; }
.chip-dot--ok { background: var(--ok); }
.chip-dot--warn { background: var(--warn); }
.chip-dot--alert { background: var(--alert); }

.js .chip { min-height: var(--tap); padding: 0 14px; cursor: pointer; }
.js .chip:hover { background: var(--fill-100); }
.js .chip:active { transform: scale(0.97); transition: transform var(--t-ui) ease; }
/* 选中三重编码：淡底（颜色）+ 双线描边（形状）+ aria-pressed（语义） */
.js .chip.is-on {
  background: var(--action-100);
  border-color: var(--action);
  color: var(--action-800);
  box-shadow: inset 0 0 0 1px var(--action);
}

/* 表在左、抽屉在右；手机把抽屉提到表格上方（见模板注释里的取舍说明） */
.board { display: grid; grid-template-columns: 1fr; gap: var(--gap); }
.board-table { min-width: 0; }

.attn-list { margin: 0; padding: 0; list-style: none; }
.attn-item { --flag-color: var(--n-400); }
.attn-item.is-behind { --flag-color: var(--alert); }
.attn-item.is-atrisk { --flag-color: var(--warn); }
.attn-item + .attn-item { border-top: 1px solid var(--line); }
.attn-link {
  display: block;
  padding: 10px var(--card-pad);
  /* 与表格 4px 状态条同一套编码，语义仍由行内 tag 文字承担 */
  border-left: var(--flag-w) solid var(--flag-color);
  color: var(--ink);
  text-decoration: none;
}
.attn-link:hover { background: var(--fill-100); text-decoration: none; }
.attn-top { display: flex; align-items: center; gap: 8px; }
.attn-name {
  flex: 1 1 auto;
  min-width: 0;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.attn-gap { display: block; margin-top: 2px; font-weight: 700; }
/* 状态做文字色一律 -700 档 */
.attn-item.is-behind .attn-gap { color: var(--alert-700); }
.attn-item.is-atrisk .attn-gap { color: var(--warn-700); }
.attn-sub { display: block; margin-top: 2px; font-size: var(--fs-xs); color: var(--muted-700); }

/* 对比表：整行可点，首列是真链接（无 JS 也能下钻） */
.dtable--home tbody th,
.dtable--home tbody td { white-space: nowrap; }
.dtable--home td.flag,
.dtable--home th.flag { position: sticky; left: 0; z-index: 1; }
.dtable--home .col-sticky { left: var(--flag-w); }
.dtable--home thead th.flag,
.dtable--home thead .col-sticky { z-index: calc(var(--z-sticky-th) + 1); }
.rowlink { color: var(--ink); font-weight: 700; text-decoration: none; }
.rowlink:hover { text-decoration: underline; }
.js .dtable--home tbody tr[data-href] { cursor: pointer; }

.storehero-id { flex: 1 1 240px; min-width: 0; }
.storehero-name { margin: 2px 0 0; font-size: var(--fs-title); }
.storehero-area { margin: 2px 0 0; font-size: var(--fs-sm); color: var(--muted-700); }
.storehero-track { flex: 0 0 auto; }
.storehero-note {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 8px 0 0;
  font-size: var(--fs-xs);
  color: var(--muted-700);
}
.storehero-more { margin: 0; }

@media (max-width: 899px) {
  /* 手机上问题清单必须先被看到；表格在小屏是第二落点 */
  .attn { order: -1; }
  /* 竖着排会把表格挤到屏幕外，改成一条横滑卡片 */
  .attn-list {
    display: flex;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .attn-item { flex: 0 0 var(--attn-card-w); }
  .attn-item + .attn-item { border-top: 0; border-left: 1px solid var(--line); }
  .attn-link {
    height: 100%;
    border-left: 0;
    border-top: var(--flag-w) solid var(--flag-color);
  }
  /* 可点的行在手机上要够得着：紧凑档只给桌面鼠标 */
  .dtable--home tbody th,
  .dtable--home tbody td { height: var(--row-h-lg); }
}

@media (min-width: 900px) {
  .chips { flex: 0 0 auto; margin-left: auto; }
  .board { grid-template-columns: minmax(0, 1fr) var(--drawer-w); align-items: start; }
  /* 抽屉自己滚：40 个落后店竖排会把页面拉到三屏，表格那半边全是空白。
     跟着页面粘住，翻表格时问题清单一直在视野里 */
  .attn {
    position: sticky;
    top: calc(var(--topbar-h) + var(--gap));
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - var(--topbar-h) - var(--gap) * 2);
  }
  .attn-list { overflow-y: auto; }
}

/* --- 我的一屏（/me） ------------------------------------------------------ */
/* 店员手机页：一列卡片、一个锚点数字。桌面不换形态，只是把同一列拆成两栏。 */
.mehead {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 10px var(--gap);
}
.mehead-id { flex: 1 1 220px; min-width: 0; }
.mehead-store { font-size: var(--fs-title); }
.mehead-when { margin: 2px 0 0; font-size: var(--fs-sm); color: var(--muted-700); }
/* 手机上切换器独占一行（select 本身就要 44px 高，挤不进店名那行） */
.meswitch { display: flex; align-items: flex-end; gap: 10px; flex: 1 1 100%; margin: 0; }

.megrid { display: grid; grid-template-columns: 1fr; gap: var(--gap); align-items: start; }
.mecol { display: flex; flex-direction: column; gap: var(--gap); min-width: 0; }

/* 今日金额卡 = 全页唯一锚点：卡里只有一个数字，其余都是它的注脚 */
.mekey {
  padding: 20px var(--card-pad);
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-panel);
  box-shadow: var(--e2);
}
.mekey-value {
  margin: 6px 0 0;
  font-size: var(--fs-lead-num);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.02em;
  /* 大号孤立数字用比例数字：等宽在这个字号下会散架 */
  font-variant-numeric: normal;
}
.mekey-sub { margin: 8px 0 0; font-size: var(--fs-sm); color: var(--muted-700); }
/* 店均是对照组，不是我的成绩：底色把它和我的数字分开 */
.mekey-vs {
  display: inline-block;
  padding: 1px 7px;
  background: var(--fill-200);
  border-radius: var(--r-tag);
  font-size: var(--fs-xs);
  color: var(--muted-700);
  white-space: nowrap;
}

/* 个人份额进度条：纯 CSS，宽度只认模板给的 --pct，>100% 由 min() 收住 */
.prog {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  --prog-color: var(--n-500);
  --prog-text: var(--muted-700);
}
.prog--ok { --prog-color: var(--ok); --prog-text: var(--ok-700); }
.prog--warn { --prog-color: var(--warn); --prog-text: var(--warn-700); }
.prog--alert { --prog-color: var(--alert); --prog-text: var(--alert-700); }
.prog-head { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; }
.prog-value {
  font-size: var(--fs-title);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--prog-text);
}
/* 方角：圆角属于容器，不属于数据编码 */
.prog-track { height: 10px; background: var(--fill-200); overflow: hidden; }
.prog-fill {
  display: block;
  height: 100%;
  width: min(100%, calc(var(--pct, 0) * 1%));
  background: var(--prog-color);
}
.prog-note { margin: 8px 0 0; font-size: var(--fs-xs); color: var(--muted-700); }

/* 排行榜：手机端是主要阅读区，行高一律 44 档 */
.dtable--rank tbody th,
.dtable--rank tbody td { height: var(--row-h-lg); }
.dtable--rank .rank-no { width: 3ch; color: var(--muted-700); }
/* 名字用 th 是为了读屏能把整行念全，但它不是标题，不给加粗 */
.dtable--rank .rank-name { font-weight: 400; }
/* 我那一行三重编码：navy 淡底（颜色）+ 行首色条（位置）+「You」（文字） */
.dtable tbody tr.is-me,
.dtable tbody tr.is-me:hover { background: var(--action-100); }
.dtable tbody tr.is-me th,
.dtable tbody tr.is-me td { font-weight: 700; color: var(--action-800); }
.dtable tbody tr.is-me td.flag { background: var(--action); }
.rank-me {
  /* 模板里已有一个真空格（读屏用），这里只补足视觉间距 */
  margin-left: 3px;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--action-800);
}

.dtable--rate tbody th { font-weight: 400; }

@media (min-width: 900px) {
  /* 桌面：切换器回到店名那一行的右端，宽度够长店名不被截断 */
  .meswitch { flex: 0 0 auto; width: 340px; }
  .megrid { grid-template-columns: minmax(0, 1fr) minmax(0, 420px); }
}

/* --- 行内明细展开（Highlights 子表） -------------------------------------- */
/* 数据区零装饰照旧：只给指示符、缩进与字号差，无圆角无投影无动画 */
.rowdetails { font-size: var(--fs-xs); }
.rowdetails > summary {
  padding: 6px 0;
  color: var(--muted-700);
  font-size: var(--fs-kicker);
  cursor: pointer;
  /* 自绘指示符：原生 marker 在 WebKit/Firefox 形状与缩进都不一样 */
  list-style: none;
}
.rowdetails > summary::-webkit-details-marker { display: none; }
.rowdetails > summary::before { content: "\25B8"; margin-right: 6px; }
.rowdetails[open] > summary::before { content: "\25BE"; }
.rowdetails .dtable {
  width: auto;
  margin: 0 0 8px var(--cell-pad-x);
  font-size: var(--fs-xs);
}
/* 子表表头不该跟着主表粘在滚动容器顶端 */
.rowdetails .dtable thead th { position: static; background: transparent; }

/* --- 分页器 --------------------------------------------------------------- */
.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 16px;
  margin: 0;
  padding: 8px var(--card-pad) 12px;
  font-size: var(--fs-kicker);
  color: var(--muted-700);
}
.pager-current { font-weight: 700; color: var(--ink); }

/* --- reduced-motion ------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  /* 加载反馈是功能性的，不能停——只放慢 */
  .spinner { animation: spin 1.4s linear infinite !important; }
  .skeleton { animation: none; opacity: 0.8; }
}

/* --- 打印 ---------------------------------------------------------------- */
/* 状态好坏在打印件上靠 .tag 文字读出，不依赖颜色 */
@media print {
  .sidebar, .topbar, .tabbar, .btn, .skip-link,
  .pagebar, .chips, #view-charts { display: none !important; }
  /* 打印永远给表格：用户就算停在 Charts 界面，纸上也该是可读的明细 */
  #view-list { display: flex !important; }
  .panel { box-shadow: none; border: 1px solid #999; }
  .app-main { max-width: none; padding: 0; }
}
