/* v1.6.7 · 自有 @media 与 Tailwind 断点同一判据:同时看短边。
   手机横屏 844×390 → 移动规则若只按 max-width 判定会全部失效(用户看到的「转手机就变样」)。
   横屏 iframe 也是 844×390,但那是主动要的宽屏视图 → 会真正改变观感的规则用
   html:not(.ls-wide) 排除掉它(纯字号/内距一类无害的不排除,少改一点)。 */
/* ============================================================
   家庭账房 · Private Counting House
   一份起居室里的银行家账册
   ============================================================ */

:root {
  /* — Paper & Ink — */
  --paper:        #F4EFE6;
  --paper-soft:   #EDE6D7;
  --paper-deep:   #E5DCC8;
  --card:         #FFFCF5;
  --card-soft:    #FAF4E6;
  --ink:          #1A1714;   /* on card 17.4:1 */
  --ink-soft:     #5C5147;   /* on card  7.5:1 · AAA */
  /* v1.6 · 对比度修正(visual-spec §1.2 实测):原 #A09486 在 card 上仅 2.90:1 / 在 paper 上 2.59:1,
     连大字号 3:1 都不到,而它承载的恰恰是字号最小的一层(时间/序号/口径/计数/eyebrow)——
     小字 + 低对比 = 双重不可读。改 #706657(card 5.5:1 / paper 4.9:1,双底过 AA)。
     原浅值降级为 --ink-faint,只许画装饰(水印/禁用/占位图形),不许承载信息。 */
  --ink-subtle:   #706657;
  --ink-faint:    #A09486;
  --rule:         #BCAE96;   /* 非文字,but 原 #C9BDA8 仅 1.8:1 偏弱 → 略加深 */
  --rule-soft:    #DBD0BC;

  /* — Accents (used sparingly) — */
  --brass:        #B08642;   /* 仅作底/边/装饰:on card 3.2:1,不可作小字文字 */
  --brass-deep:   #8C6A33;
  /* v1.6 · 铜金作文字专用档(visual-spec §1.3):brass 3.2:1 / brass-deep 在 paper 上 4.34:1 都不过 AA,
     brass-text 5.3:1 / 4.8:1 双底过 AA —— 链接、eyebrow、可点强调文字用它 */
  --brass-text:   #85642F;
  --brass-soft:   #E8D9B6;
  --forest:       #4F6B47;
  --forest-soft:  #C8D5BD;
  --rust:         #9C4A2A;
  --rust-soft:    #E8C8B8;
  --plum:         #5C3A4B;
  --slate:        #3C4A5A;
  --slate-soft:   #C5CDD8;  /* v0.17 · 保险 pill 底色 */

  /* — Sizing — */
  --rule-thin:    0.5px;
  --rule-thick:   1px;

  /* — v1.2.2 · 全局字号档位(issue #7)· 一个变量驱动全站缩放;标准=1 时逐像素等价现状 — */
  --fs-scale:     1;

  /* — Effects — */
  --shadow-paper: 0 1px 0 rgba(26, 23, 20, 0.04), 0 8px 24px -12px rgba(26, 23, 20, 0.08);
  --shadow-deep:  0 2px 0 rgba(26, 23, 20, 0.04), 0 24px 60px -32px rgba(26, 23, 20, 0.18);
}

/* v1.2.2 · 字号档位:大 +15% / 特大 +30%(标准不设 = 用 :root 的 1) */
html[data-fs="lg"] { --fs-scale: 1.15; }
html[data-fs="xl"] { --fs-scale: 1.30; }

* { box-sizing: border-box; }

html, body {
  background: var(--paper);
  color: var(--ink);
  font-family: "Source Serif 4", "Noto Serif SC", Georgia, serif;
  font-feature-settings: "kern" 1, "liga" 1, "calt" 1;
  font-size: calc(15px * var(--fs-scale,1));
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ——— 纸张纹理 ——— */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  background-image:
    radial-gradient(1px 1px at 10% 20%, rgba(176,134,66,0.05) 50%, transparent 50%),
    radial-gradient(1px 1px at 80% 60%, rgba(26,23,20,0.04) 50%, transparent 50%),
    radial-gradient(1px 1px at 30% 80%, rgba(176,134,66,0.04) 50%, transparent 50%),
    radial-gradient(1px 1px at 70% 30%, rgba(26,23,20,0.03) 50%, transparent 50%);
  background-size: 80px 80px, 120px 120px, 100px 100px, 90px 90px;
  background-position: 0 0, 40px 40px, 20px 60px, 60px 20px;
  opacity: 0.6;
  mix-blend-mode: multiply;
}

/* ——— Typography ——— */

.font-display { font-family: "Fraunces", "Noto Serif SC", Georgia, serif; }
.font-serif   { font-family: "Source Serif 4", "Noto Serif SC", Georgia, serif; }
.font-mono    { font-family: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace; font-feature-settings: "tnum" 1, "calt" 1; }

.tnum         { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }
.swsh         { font-feature-settings: "swsh" 1, "ss01" 1; }   /* Fraunces swash + stylistic */

h1, h2, h3, h4 {
  font-family: "Fraunces", "Noto Serif SC", Georgia, serif;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.eyebrow {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: calc(10.5px * var(--fs-scale,1));
  font-weight: 400;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--brass-deep);
}

.eyebrow-ink {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: calc(10.5px * var(--fs-scale,1));
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.dropcap::first-letter {
  font-family: "Fraunces", "Noto Serif SC", Georgia, serif;
  font-weight: 600;
  font-size: 3em;
  line-height: 1;
  float: left;
  padding: 4px 8px 0 0;
  color: var(--brass);
}

/* ——— Components ——— */

.paper-card {
  background: var(--card);
  border: var(--rule-thick) solid var(--rule);
  border-radius: 2px;
  box-shadow: var(--shadow-paper);
  position: relative;
}

.paper-card-soft {
  background: var(--card-soft);
  border: var(--rule-thin) solid var(--rule);
  border-radius: 2px;
}

.envelope {
  background: var(--card);
  border: var(--rule-thick) solid var(--ink);
  border-radius: 0;
  box-shadow:
    4px 4px 0 var(--paper-deep),
    var(--shadow-deep);
}

/* Bracket-cornered cards (账册装饰角) */
.bracket-card {
  position: relative;
  background: var(--card);
  border: 1px solid var(--rule);
  padding: 28px;
}
.bracket-card::before, .bracket-card::after {
  content: "";
  position: absolute;
  width: 14px;
  height: 14px;
  border: 1.5px solid var(--brass);
}
.bracket-card::before { top: -5px; left: -5px; border-right: none; border-bottom: none; }
.bracket-card::after  { bottom: -5px; right: -5px; border-left: none; border-top: none; }

/* Hairline rules (账册中的细线) */
.rule         { border-color: var(--rule); }
.rule-thick   { border-color: var(--ink); }
.rule-x       { border-top: 1px solid var(--rule); }
.rule-y       { border-left: 1px solid var(--rule); }
.rule-double  { border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); padding: 1px 0; }
.rule-triple-bottom { border-bottom: 3px double var(--rule); padding-bottom: 4px; }

/* Buttons */
.btn-ink {
  background: var(--ink);
  color: var(--paper);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: calc(12px * var(--fs-scale,1));
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 12px 20px;
  border: none;
  cursor: pointer;
  transition: all 180ms ease;
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
.btn-ink:hover { background: var(--brass-deep); }

.btn-paper {
  background: transparent;
  color: var(--ink);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: calc(12px * var(--fs-scale,1));
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 11px 19px;
  border: 1px solid var(--ink);
  cursor: pointer;
  transition: all 180ms ease;
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
.btn-paper:hover { background: var(--ink); color: var(--paper); }

.btn-brass {
  background: var(--brass);
  color: var(--paper);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: calc(12px * var(--fs-scale,1));
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 12px 20px;
  border: none;
  cursor: pointer;
  transition: background 180ms ease;
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
.btn-brass:hover { background: var(--brass-deep); }

.btn-ghost {
  background: transparent;
  color: var(--ink-soft);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: calc(11.5px * var(--fs-scale,1));
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 8px 14px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: all 150ms ease;
}
.btn-ghost:hover { color: var(--ink); border-color: var(--rule); }

/* Form */
.field-input {
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--rule);
  padding: 10px 2px;
  font-family: "Source Serif 4", "Noto Serif SC", serif;
  font-size: calc(16px * var(--fs-scale,1));
  color: var(--ink);
  width: 100%;
  outline: none;
  transition: border-color 180ms ease;
}
.field-input:focus { border-bottom: 2px solid var(--brass); padding-bottom: 9px; }

.field-input-num {
  font-family: "JetBrains Mono", monospace;
  font-variant-numeric: tabular-nums;
  font-size: calc(18px * var(--fs-scale,1));
  text-align: right;
  letter-spacing: 0.02em;
}

.field-label {
  font-family: "JetBrains Mono", monospace;
  font-size: calc(10.5px * var(--fs-scale,1));
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  display: block;
  margin-bottom: 6px;
}

/* Pills / Chips / Tags */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border: 1px solid var(--rule);
  background: var(--paper-soft);
  font-family: "JetBrains Mono", monospace;
  font-size: calc(10.5px * var(--fs-scale,1));
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
  border-radius: 1px;
}
.pill-brass { background: var(--brass-soft); border-color: var(--brass); color: var(--brass-deep); }
.pill-forest { background: var(--forest-soft); border-color: var(--forest); color: var(--forest); }
.pill-rust { background: var(--rust-soft); border-color: var(--rust); color: var(--rust); }
.pill-slate { background: var(--slate-soft); border-color: var(--slate); color: var(--slate); } /* v0.17 保险 */
.pill-ink { background: var(--ink); border-color: var(--ink); color: var(--paper); }

/* Number coloring */
.num-pos { color: var(--forest); }
.num-neg { color: var(--rust); }

/* KPI 卡片 */
.kpi-card {
  background: var(--card);
  border: 1px solid var(--rule);
  padding: 24px;
  position: relative;
  transition: border-color 180ms ease;
}
.kpi-card:hover { border-color: var(--ink-soft); }
.kpi-eyebrow {
  font-family: "JetBrains Mono", monospace;
  font-size: calc(10px * var(--fs-scale,1));
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
  display: block;
  margin-bottom: 14px;
}
.kpi-value {
  font-family: "Fraunces", "Noto Serif SC", serif;
  font-feature-settings: "tnum" 1;
  font-size: calc(30px * var(--fs-scale,1));
  font-weight: 500;
  line-height: 1.1;
  color: var(--ink);
  letter-spacing: -0.015em;
}
.kpi-currency { font-size: 0.55em; vertical-align: 0.65em; color: var(--ink-soft); margin-right: 4px; }
.kpi-delta {
  font-family: "JetBrains Mono", monospace;
  font-feature-settings: "tnum" 1;
  font-size: calc(12px * var(--fs-scale,1));
  margin-top: 10px;
}

/* 成员 avatar 颜色(填报页分组 · 按 ownerColorMap index % 5 分配) */
.avatar-0 { background: #2f5d50 !important; } /* forest 深绿 */
.avatar-1 { background: #6b5b8a !important; } /* 紫灰 */
.avatar-2 { background: #3b6998 !important; } /* 蓝灰 */
.avatar-3 { background: #a77b35 !important; } /* 铜金 */
.avatar-4 { background: #4a5568 !important; } /* slate 灰(fallback / 共同) */

/* KPI 口径说明 tooltip · v0.4.13 */
.kpi-info-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
  vertical-align: middle;
}
.kpi-info-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px;
  border: none; color: var(--ink-subtle);
  cursor: pointer; margin-left: 3px; vertical-align: middle;
  transition: color .2s;
  flex-shrink: 0; padding: 0; background: none;
}
.kpi-info-btn:hover { color: var(--brass-deep); }
/* 2026-07-19 · 移动可点性:视觉 14px 的小图标,触摸热区扩到 ~38px(::after 不占布局,只吃点击) */
.kpi-info-btn { position: relative; }
.kpi-info-btn::after, .tap::after {
  content: ''; position: absolute; inset: -12px;
}
.tap { position: relative; }
.kpi-info-panel {
  /* absolute 浮层 · 不撑开 parent card 布局 */
  position: absolute;
  top: calc(100% + 4px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 50;
  padding: 8px 10px;
  background: var(--card); border: 1px solid var(--rule-soft);
  border-left: 3px solid var(--brass); border-radius: 4px;
  font-size: calc(11px * var(--fs-scale,1)); line-height: 1.6; color: var(--ink-soft);
  min-width: 220px; max-width: 320px; width: max-content;
  font-family: "Source Serif 4", "Noto Serif SC", serif;
  box-shadow: 0 4px 12px rgba(26,23,20,.12);
  /* 防 panel 把文字从 uppercase 继承过来 */
  text-transform: none; letter-spacing: normal;
}
/* v0.5.3 · 口径(formula)+ 真实计算数值(calc)双层 */
.kpi-info-formula { display: block; }
.kpi-info-calc {
  display: block;
  margin-top: 7px; padding-top: 7px;
  border-top: 1px dashed var(--rule-soft);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: calc(10.5px * var(--fs-scale,1)); line-height: 1.7;
  color: var(--ink);
  /* 多行分项用 \n 软换行 · 不折叠空白 */
  white-space: pre-line;
  text-transform: none; letter-spacing: normal;
}
/* v0.5.5 · 报表「已关账」朱印章(横排小印 · 单行不换行 · 仅快照态显)*/
.report-seal {
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0; white-space: nowrap;
  color: var(--rust);
  border: 2px solid var(--rust);
  border-radius: 5px;
  background: rgba(156, 74, 42, .05);
  box-shadow: inset 0 0 0 2px rgba(156, 74, 42, .14);
  transform: rotate(-4deg);
  padding: 3px 6px 3px 9px;   /* 右侧略收:letter-spacing 末位补偿 */
  font-family: "Noto Serif SC", serif; font-weight: 700;
  font-size: calc(13px * var(--fs-scale,1)); letter-spacing: 3px; line-height: 1;
  opacity: .92;
}
@media (max-width: 640px), (max-height: 479px) {
  .report-seal { font-size: calc(12px * var(--fs-scale,1)); letter-spacing: 2px; padding: 2px 5px 2px 7px; }
}

/* v0.5.6 · 报表长文目录 · PC 右侧常驻树状大纲 + 手机左上唤醒钮 + 底部 sheet */
/* 布局自管(不依赖 Tailwind lg: · 重页 JIT 不稳)· 窄屏单列+FAB · ≥1024px 双列 */
.toc-cols-main { min-width: 0; }
.toc-rail { display: none; }
@media (min-width: 1024px) and (min-height: 480px) {
  .toc-cols { display: flex; gap: 2rem; align-items: flex-start; }
  .toc-cols-main { flex: 1 1 0%; min-width: 0; }
  /* order:-1 把目录栏放到左列(内容在右)· DOM 仍内容优先(阅读/可访问顺序不变)*/
  .toc-rail { display: block; order: -1; position: sticky; top: 88px; align-self: flex-start; width: 224px; flex-shrink: 0; }
}
.toc-head { font-family:"JetBrains Mono",monospace; font-size: calc(10px * var(--fs-scale,1)); letter-spacing:.18em; text-transform:uppercase; color:var(--ink-subtle); padding:0 0 8px 14px; }
.toc-tree { position: relative; }
.toc-node { display:block; position:relative; text-decoration:none; line-height:1.35;
  font-family:"Source Serif 4","Noto Serif SC",serif; color:var(--ink-soft);
  padding:6px 8px 6px 14px; border-left:2px solid transparent;
  transition:color .15s, border-color .15s, background .15s; }
.toc-node .lbl { font-size: calc(13px * var(--fs-scale,1)); }
.toc-node:hover { color:var(--brass-deep); background:var(--card-soft); }
/* active:aria-current 作样式钩子(a11y)· 朱铜 + 左脊 + 底色 */
.toc-node[aria-current="true"] { color:var(--brass-deep); font-weight:600; border-left-color:var(--brass-deep); background:var(--card-soft); }
.toc-node.ancestor { color:var(--ink); }
/* 子层:缩进 + 竖向引导线 + 横向树枝(支持未来多层嵌套)*/
.toc-children { margin-left:13px; border-left:1.5px solid var(--rule-soft); }
.toc-children > .toc-node { padding-left:16px; }
.toc-children > .toc-node .lbl { font-size: calc(12px * var(--fs-scale,1)); }
.toc-children > .toc-node::before { content:''; position:absolute; left:-1px; top:15px; width:10px; height:1.5px; background:var(--rule-soft); }
.toc-children > .toc-node[aria-current="true"]::before { background:var(--brass-deep); }
/* 手机:左上角唤醒钮(icon-only 小圆钮)+ 底部 sheet · ≥1024px 隐藏(用右栏) */
/* v0.11 · 移动端目录浮钮挪到左下,与隐私浮控(#priv-float, bottom:18px)叠成同一操作区 */
/* v1.6 UED(review A1)· 浮钮从左下改右下 + iOS 安全区:左下是内容起始边,曾压住金额/图例/筛选行 */
.toc-fab { position:fixed; right:14px; bottom:calc(max(18px, env(safe-area-inset-bottom)) + 48px); z-index:9999;
  width:38px; height:38px; border-radius:50%;
  background:var(--ink); color:var(--paper); border:none; box-shadow:0 3px 12px rgba(0,0,0,.22);
  display:inline-flex; align-items:center; justify-content:center; cursor:pointer;
  transition:opacity .25s ease; }
@media (min-width: 1024px) and (min-height: 480px) { .toc-fab { display: none !important; } }
.toc-sheet-mask { position:fixed; inset:0; background:rgba(26,23,20,.4); z-index:70; opacity:0; pointer-events:none; transition:opacity .2s; }
.toc-sheet-mask.open { opacity:1; pointer-events:auto; }
.toc-sheet { position:fixed; left:0; right:0; bottom:0; z-index:80; background:var(--card);
  border-top-left-radius:16px; border-top-right-radius:16px; box-shadow:0 -8px 32px rgba(0,0,0,.22);
  transform:translateY(110%); transition:transform .26s cubic-bezier(.22,1,.36,1);
  padding:8px 6px max(16px, env(safe-area-inset-bottom)); max-height:72vh; overflow:auto; }
.toc-sheet.open { transform:translateY(0); }
.toc-sheet-handle { width:40px; height:4px; border-radius:2px; background:var(--rule); margin:8px auto 4px; }
.toc-sheet-row { display:flex; align-items:center; justify-content:space-between; padding:2px 12px 6px; }
.toc-sheet-row .toc-head { padding:0; }
.toc-sheet-x { width:32px; height:32px; border:none; background:none; color:var(--ink-soft); cursor:pointer; font-size: calc(20px * var(--fs-scale,1)); line-height:1; }
.toc-sheet .toc-node { padding-top:11px; padding-bottom:11px; min-height:44px; box-sizing:border-box; }
.toc-sheet .toc-node .lbl { font-size: calc(15px * var(--fs-scale,1)); }
/* v1.4.x · 目录 sheet 打开时,收起左下角浮钮(隐私眼睛 + 目录浮钮),避免压住 sheet 底部条目 */
body.toc-open #priv-float, body.toc-open .toc-fab { display: none !important; }
/* v1.4.x · 旭日「分析指标 / 看板」横滑行的"还有更多"提示:右缘渐隐 + › 箭头,溢出且未滑到底时出现 */
.lens-hscroll { position: relative; }
.lens-hscroll > .overflow-x-auto { scrollbar-width: none; }
.lens-hscroll > .overflow-x-auto::-webkit-scrollbar { display: none; }
/* v1.6 UED(review A9)· iOS 硬约束:
   ① overscroll-behavior-x:contain —— 横滑到尽头继续拖不再触发 Safari 返回/前进手势(此前会莫名离开页面)
   ② scroll-snap —— 横滑停在完整 pill/卡片边界,不再半个被截断 */
.lens-hscroll > .overflow-x-auto,
.hscroll-x {
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
}
.hscroll-x { overflow-x: auto; scrollbar-width: none; }
.hscroll-x::-webkit-scrollbar { display: none; }
.lens-hscroll > .overflow-x-auto > * > *,
.hscroll-x > * { scroll-snap-align: start; }
/* 内部纵向滚动容器不带动整页(iOS momentum 串联) */
.toc-sheet, .scroll-contain { overscroll-behavior: contain; }
/* 图表容器:长按不弹系统「拷贝图片」菜单(review A9 ⑦) */
.chart-card canvas, canvas[id], .echart-box { -webkit-touch-callout: none; }
.lens-hscroll::after {
  content: '\203A'; position: absolute; top: 0; right: 0; bottom: 5px; width: 34px;
  display: flex; align-items: center; justify-content: flex-end; padding-right: 5px;
  color: var(--brass-deep); font-family: 'JetBrains Mono', monospace; font-size: 18px; font-weight: 700;
  background: linear-gradient(to left, var(--card) 38%, transparent);
  pointer-events: none; opacity: 0; transition: opacity .2s; border-radius: 0 8px 8px 0;
}
.lens-hscroll.more::after { opacity: 1; }
@media (max-width: 640px), (max-height: 479px) {
  .kpi-info-panel {
    /* 手机端:固定到屏幕顶部 · 不跟 button 位置 */
    position: fixed;
    left: 1rem; right: 1rem;
    top: 5rem; bottom: auto; /* nav h-16 + sticky top-1 ≈ 68px · 5rem=80px 避开导航 */
    transform: none;
    min-width: unset; max-width: unset; width: auto;
    font-size: calc(12px * var(--fs-scale,1));
    box-shadow: 0 4px 20px rgba(26,23,20,.18);
    animation: kpi-slide-in .3s ease-out;
  }
}
@keyframes kpi-slide-in {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* 表格 — 账册风 */
.ledger-table {
  width: 100%;
  border-collapse: collapse;
  font-feature-settings: "tnum" 1;
}
.ledger-table thead th {
  font-family: "JetBrains Mono", monospace;
  font-size: calc(10px * var(--fs-scale,1));
  font-weight: 400;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding: 10px 14px;
  text-align: left;
  border-bottom: 1px solid var(--ink);
}
.ledger-table thead th.num { text-align: right; }
/* v0.8 列表排序:可排序列头 + 三态三角指示(CSS 绘制,不用字形/emoji) */
.ledger-table thead th.sortable-th { cursor: pointer; user-select: none; }
.ledger-table thead th.sortable-th:hover { color: var(--ink); }
.ledger-table thead th.sortable-th::after {
  content: ""; display: inline-block; width: 0; height: 0; margin-left: 5px;
  vertical-align: middle; opacity: .28;
  border-left: 3px solid transparent; border-right: 3px solid transparent;
  border-top: 4px solid currentColor;
}
.ledger-table thead th.sortable-th[aria-sort="ascending"]::after {
  border-top: 0; border-bottom: 4px solid var(--brass-deep); opacity: 1;
}
.ledger-table thead th.sortable-th[aria-sort="descending"]::after {
  border-bottom: 0; border-top: 4px solid var(--brass-deep); opacity: 1;
}
.ledger-table tbody td {
  padding: 14px;
  border-bottom: 1px solid var(--rule-soft);
  vertical-align: middle;
  font-size: calc(14.5px * var(--fs-scale,1));
}
/* v1.9.3 · 账户表的数字格一律不折行。
   这两张表最多 17 列、自然宽远超容器,table-layout:auto 会把**能折行的内容压到 min-content**
   再把宽度让给别的列 —— 于是「930.85%」后面那个「累」上标、「-6.00pp」后面的上标、
   「跑输 -87.10pp」都会掉到第二行,行高从 55px 顶到 67~73px;而窄值行不折,同一列有的一行有的两行。
   逐个格补 whitespace-nowrap 是逐点补:下次加个指标列又会漏。这里按「数字格」这个属性一次网住,
   新增 data-mcol 列自动继承。守护 v193-TABLE-NUM-NOWRAP。 */
#dash-list .ledger-table tbody td.num,
#reports-region .ledger-table tbody td.num { white-space: nowrap; }

.ledger-table tbody td.num {
  font-family: "JetBrains Mono", monospace;
  font-variant-numeric: tabular-nums;
  text-align: right;
  letter-spacing: 0.01em;
}
.ledger-table tbody tr:hover td { background: var(--card-soft); }

/* 边栏 */
.side-rule {
  border-left: 1px solid var(--rule);
  padding-left: 24px;
}

/* 序号水印 */
.folio {
  font-family: "Fraunces", serif;
  font-feature-settings: "ss01" 1, "swsh" 1;
  font-style: italic;
  font-size: calc(76px * var(--fs-scale,1));
  line-height: 1;
  color: var(--paper-deep);
  user-select: none;
}

/* 对勾 / 状态符号 */
.tick-done {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px; height: 18px;
  border: 1.5px solid var(--forest);
  background: var(--forest);
  color: var(--paper);
  font-size: calc(11px * var(--fs-scale,1));
  font-weight: 700;
}
.tick-pending {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px; height: 18px;
  border: 1.5px dashed var(--ink-subtle);
  color: var(--ink-subtle);
}

/* 响应处理 */
@media (max-width: 720px), (max-height: 479px) {
  body { font-size: calc(14.5px * var(--fs-scale,1)); }
  /* v0.14.1 UED · 手机 2 列 KPI 卡:24px padding 偏重、挤内容 → 收紧留白节奏,值略降一档更贴合窄卡 */
  .kpi-card { padding: 16px 15px; }
  .kpi-eyebrow { margin-bottom: 10px; }
  .kpi-value { font-size: calc(24px * var(--fs-scale,1)); }
  .kpi-delta { margin-top: 8px; }
}

/* Print-像-账册的微动效 */
@keyframes fade-up {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}
.fade-in        { animation: fade-up 600ms cubic-bezier(0.2, 0.8, 0.2, 1) both; }
.fade-in-delay-1 { animation: fade-up 600ms cubic-bezier(0.2, 0.8, 0.2, 1) both; animation-delay: 100ms; }
.fade-in-delay-2 { animation: fade-up 600ms cubic-bezier(0.2, 0.8, 0.2, 1) both; animation-delay: 200ms; }
.fade-in-delay-3 { animation: fade-up 600ms cubic-bezier(0.2, 0.8, 0.2, 1) both; animation-delay: 300ms; }
.fade-in-delay-4 { animation: fade-up 600ms cubic-bezier(0.2, 0.8, 0.2, 1) both; animation-delay: 400ms; }

/* 账册装饰 — 翻页角 */
.dog-ear {
  position: relative;
}
.dog-ear::after {
  content: "";
  position: absolute;
  top: 0; right: 0;
  width: 24px; height: 24px;
  background: linear-gradient(225deg, var(--paper-deep) 50%, var(--rule-soft) 50%);
  border-left: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}

/* 1px 内边线(账册分栏) */
.col-rule > * + * { border-left: 1px solid var(--rule); padding-left: 24px; }

/* 移动端遮罩(envelope 风格) */
.scrim {
  position: fixed;
  inset: 0;
  background: rgba(26, 23, 20, 0.4);
  backdrop-filter: blur(2px);
  z-index: 50;
}

/* 模态弹层(信函式) */
.envelope-modal {
  background: var(--card);
  border: 1px solid var(--ink);
  box-shadow: 8px 8px 0 var(--paper-deep), var(--shadow-deep);
  position: relative;
}
.envelope-modal::before {
  content: "";
  position: absolute;
  top: -1px; left: 24px; right: 24px;
  height: 4px;
  background: var(--brass);
}

/* 选择 */
::selection {
  background: var(--brass);
  color: var(--paper);
}

/* 链接 */
a {
  color: var(--ink);
  text-decoration-color: var(--rule);
  text-underline-offset: 4px;
  transition: text-decoration-color 200ms ease;
}
a:hover { text-decoration-color: var(--brass); }

a.brass-link {
  color: var(--brass-deep);
  text-decoration-color: var(--brass-soft);
}
a.brass-link:hover { text-decoration-color: var(--brass); }

/* —— Chart palette via CSS vars —— */
.chart-card {
  background: var(--card);
  border: 1px solid var(--rule);
  padding: 24px;
}

/* Sparkline 用 */
.sparkline-pos { color: var(--forest); }
.sparkline-neg { color: var(--rust); }

/* 滚动条 */
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: var(--paper); }
::-webkit-scrollbar-thumb { background: var(--rule); border: 3px solid var(--paper); }
::-webkit-scrollbar-thumb:hover { background: var(--ink-subtle); }

/* — Hamburger summary — 隐藏默认箭头 */
summary { list-style: none; }
summary::-webkit-details-marker { display: none; }
summary::marker { content: ''; }

/* — 填报页 ledger 展开/折叠 文案随状态切换(纯 CSS · 无 JS) — */
details[open]      > summary .lg-when-closed { display: none; }
details:not([open]) > summary .lg-when-open  { display: none; }

/* — v0.7 配置引导 · 折叠式「如何获取」帮助(纯 CSS · 无 JS) — */
.help-fold > summary {
  font-family: "JetBrains Mono", monospace; font-size: calc(11px * var(--fs-scale,1));
  color: var(--brass-deep); cursor: pointer; list-style: none;
  display: inline-flex; align-items: center; gap: 5px; margin-top: 6px;
}
.help-fold > summary::-webkit-details-marker { display: none; }
.help-fold > summary::marker { content: ''; }
.help-fold > summary::before { content: '+'; font-weight: 600; }
.help-fold[open] > summary::before { content: '\2013'; } /* en-dash */
.help-fold .help-body {
  font-size: calc(13px * var(--fs-scale,1)); color: var(--ink-soft); line-height: 1.85;
  margin-top: 8px; padding: 12px 14px;
  background: var(--card-soft); border: 1px solid var(--rule-soft);
}
.help-fold .help-body ol { margin: 0; padding-left: 18px; }
.help-fold .help-body a { color: var(--brass-deep); text-decoration: underline; }

/* ============================================================
   v1.2.2 · 字号档位 · 层2/层5(issue #7)
   层2:6 个写死的 Tailwind arbitrary 字号类(全站 820 处,仅 6 个离散尺寸)
        用 calc×scale 重定义;!important 压 Play CDN 生成的绝对 px
        (仓库既有手法:lens-select .lsel-q 16px !important)。
        标准档 scale=1 → calc(Npx*1)=Npx,与现状逐像素等价。
   ============================================================ */
.text-\[8px\]  { font-size: calc(8px  * var(--fs-scale,1)) !important; }
.text-\[9px\]  { font-size: calc(9px  * var(--fs-scale,1)) !important; }
.text-\[10px\] { font-size: calc(10px * var(--fs-scale,1)) !important; }
.text-\[11px\] { font-size: calc(11px * var(--fs-scale,1)) !important; }
.text-\[12px\] { font-size: calc(12px * var(--fs-scale,1)) !important; }
.text-\[13px\] { font-size: calc(13px * var(--fs-scale,1)) !important; }

/* 层5:移动端输入框 16px 地板(<16px 聚焦触发 iOS 整页放大)。
   只在 大/特大 档生效 → 标准档输入框完全不动,零回归;
   放大档取 max(16px, 14px×scale) 保证既变大又不触发 zoom。 */
@media (max-width: 640px), (max-height: 479px) {
  html[data-fs="lg"] input,  html[data-fs="lg"] select,  html[data-fs="lg"] textarea,
  html[data-fs="xl"] input,  html[data-fs="xl"] select,  html[data-fs="xl"] textarea {
    font-size: max(16px, calc(14px * var(--fs-scale,1))) !important;
  }
}

/* v1.2.2 · 字号控件(nav 下拉 + 移动菜单行)· 高亮 = aria-pressed */
.fs-opt { display:block; width:100%; text-align:left; background:transparent; border:0; cursor:pointer;
  font-family:"JetBrains Mono",monospace; font-size: calc(12px * var(--fs-scale,1)); color:var(--ink-soft);
  padding:7px 14px; white-space:nowrap; letter-spacing:.06em; }
.fs-opt:hover { background:var(--card-soft); color:var(--ink); }
.fs-opt[aria-pressed="true"] { background:var(--ink); color:var(--paper); }
.fs-opt-m { font-family:"JetBrains Mono",monospace; font-size: calc(12px * var(--fs-scale,1)); color:var(--ink-soft);
  border:1px solid var(--rule); background:var(--card); padding:5px 11px; cursor:pointer; letter-spacing:.04em; }
.fs-opt-m[aria-pressed="true"] { background:var(--ink); color:var(--paper); border-color:var(--ink); }
#fs-menu > summary::-webkit-details-marker { display:none; }
#fs-menu > summary::marker { content:''; }

/* v1.3 · 旭日分析指标选择器 */
.sun-m-off { opacity:.42; text-decoration:line-through; cursor:not-allowed; }
#sunMetricPop button { display:block; width:100%; text-align:left; background:none; border:0; cursor:pointer;
  font-family:"JetBrains Mono",monospace; font-size: calc(12px * var(--fs-scale,1)); color:var(--ink-soft);
  padding:6px 14px; white-space:nowrap; }
#sunMetricPop button:hover { background:var(--card-soft); color:var(--ink); }
#sunMetricPop button.on { background:var(--ink); color:var(--paper); }
#sunMetricPop button.off { opacity:.42; text-decoration:line-through; cursor:not-allowed; }

/* ============================================================
   v1.6 · UED review 修复(docs/ued-review-2026-07.md)
   ============================================================ */

/* 补 .pill-mute —— 3 处模板在用(nav 字号钮/隐私钮 · dashboard「本期未填收支」)但此前无定义,
   语义 = 中性/未启用/无数据(spec §6.2 状态标签第 4 档) */
.pill-mute { background: transparent; border-color: var(--rule-soft); color: var(--ink-subtle); }
button.pill-mute:hover, summary.pill-mute:hover { border-color: var(--rule); color: var(--ink-soft); }

/* ---------------------------------------------------------------
   v1.18 · 流水来源微标签(.src-tag)
   为什么不复用 .pill:.pill 是 4px/10px + 10.5px + 大字距 + uppercase,
   给"一个区块一枚"设计的;流水时间线是**每行一枚**,用 .pill 会把行高撑开、
   把本来紧凑的账本读感搞散。另外内容是中文,uppercase 与 0.1em 字距都没意义。
   --------------------------------------------------------------- */
.src-tag {
  display: inline-flex;
  align-items: center;
  padding: 1px 5px;
  border: 1px solid var(--rule-soft);
  background: var(--paper-soft);
  font-family: "JetBrains Mono", monospace;
  font-size: calc(9.5px * var(--fs-scale,1));
  letter-spacing: 0.02em;
  color: var(--ink-subtle);
  border-radius: 1px;
  white-space: nowrap;
  line-height: 1.5;
  /* 定宽:时间线里它是一整列,三种标签(手动填报 50.8 / 来源未记录 60.5 / 自动 · 股价 68.5)
     各按内容宽会让这一列两边都参差。取最宽那个当下限、内容居中,列的左右边缘就都齐了。 */
  min-width: 70px;
  justify-content: center;
}
/* 窄屏放弃定宽 —— 那里本来也排不成列,定宽只会把删除按钮挤到下一行。
   窄屏这一行的参数是在真机上扫出来的(390px · 账户详情 8 月组 78 行):
     类别最小宽 140 + 标签任意宽 → 删除按钮掉行 6 行(这就是我第一版的回归)
     类别最小宽 120 + 标签不定宽 → 掉行 0 · 类别折行 0   ← 采用
     类别最小宽 110 或更小       → 类别被挤上第一行,「估值变动 · 自动(定时)」从中间折断
   所以模板那侧配套写成 min-w-[120px] sm:min-w-[140px]。 */
@media (max-width: 640px) {
  .src-tag { min-width: 0; padding: 1px 4px; }
}
/* 分组配色:自动拉数据=黄铜 · 券商=石板蓝 · 截图导入=森绿 · 手动/系统=中性 */
.src-auto   { background: var(--brass-soft);  border-color: var(--brass);  color: var(--brass-deep); }
.src-broker { background: var(--slate-soft);  border-color: var(--slate);  color: var(--slate); }
.src-import { background: var(--forest-soft); border-color: var(--forest); color: var(--forest); }
.src-manual { background: var(--card-soft);   border-color: var(--rule-soft); color: var(--ink-soft); }
.src-system { background: var(--paper-deep);  border-color: var(--rule);   color: var(--ink-soft); }
/* 历史数据(v1.18 之前)占多数,必须**最不抢视线**:虚线 + 透明底 + 最淡的字 */
.src-unknown { background: transparent; border-style: dashed; border-color: var(--rule-soft); color: var(--ink-faint); }

/* PC 上目录 sheet 与遮罩彻底不参与渲染(此前仅靠 transform 移出视口,仍在合成层里) */
@media (min-width: 1024px) and (min-height: 480px) {
  .toc-sheet, .toc-sheet-mask { display: none !important; }
}

/* review A5 · 1px 发丝网格。
   旧写法 `gap-px bg-rule` 靠容器底色从缝隙透出来画线 —— 格子数不满一行时,空位也透出米灰色,
   形成突兀色块(accounts 9 类型 ÷ 6 列空 3 格 / checkup 5 KPI ÷ 2 列空 1 格)。
   改为:容器白底 + 上左外边线,子项各自画右下线 → 线条一致,空位自然是白底。 */
.grid-hairline { background: var(--card); border-top: 1px solid var(--rule); border-left: 1px solid var(--rule); }
.grid-hairline > * { border-right: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }

/* review B3-4 · 表格窄列里的中文被挤成竖排 → 关键列不换行 */
.ledger-table td.nowrap, .ledger-table th.nowrap { white-space: nowrap; }

/* review B3-3 · 列表行「更多操作」下拉:高频操作留行内,低频收进 ⋯(spec §6.1 行内 ≤3) */
.row-more { position: relative; display: inline-block; vertical-align: middle; }
.row-more > summary {
  list-style: none; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 30px; color: var(--ink-subtle);
  border: 1px solid transparent; transition: color .15s, border-color .15s;
}
.row-more > summary::-webkit-details-marker { display: none; }
.row-more > summary::marker { content: ''; }
.row-more > summary:hover { color: var(--ink); border-color: var(--rule); }
.row-more[open] > summary { color: var(--ink); border-color: var(--rule); }
.row-more-pop {
  position: absolute; right: 0; top: 100%; z-index: 45; min-width: 156px;
  background: var(--card); border: 1px solid var(--ink);
  box-shadow: 4px 4px 0 var(--paper-deep), var(--shadow-deep);
  padding: 4px 0; text-align: left;
}
.row-more-pop > a, .row-more-pop button {
  display: block; width: 100%; text-align: left; background: none; border: 0; cursor: pointer;
  padding: 8px 14px; font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: calc(11px * var(--fs-scale,1)); color: var(--ink-soft); white-space: nowrap;
}
.row-more-pop > a:hover, .row-more-pop button:hover { background: var(--card-soft); color: var(--ink); }
/* 不可逆操作用 rust 描边语义(spec §6.1 danger:有色=要你做决定) */
.row-more-pop .row-more-danger { color: var(--rust); }
.row-more-pop .row-more-danger:hover { background: rgba(156,74,42,.07); color: var(--rust); }

/* review B2-2 · 填报行折叠(移动端 13.9 屏 → 约 3 屏)· summary 满足 40px 触摸高度 */
.entry-fold > summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; gap: 6px;
  min-height: 40px; margin-top: 6px; padding-top: 8px;
  border-top: 1px solid var(--rule-soft);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: calc(11px * var(--fs-scale,1)); letter-spacing: .08em;
  color: var(--brass-text, #85642F);
}
.entry-fold > summary::-webkit-details-marker { display: none; }
.entry-fold > summary::marker { content: ''; }
.entry-fold > summary:hover { color: var(--ink); }
.entry-fold > summary .fold-chev { transition: transform .18s ease; flex-shrink: 0; }
.entry-fold[open] > summary .fold-chev { transform: rotate(180deg); }
.entry-fold[open] > summary .fold-when-closed { display: none; }
.entry-fold:not([open]) > summary .fold-when-open { display: none; }

/* review A4 · 分析页顶部口径控件折叠条(窄屏收起 / PC 恒展开且不显示 summary → 零回归) */
.filter-fold > summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; gap: 7px;
  min-height: 44px; padding: 0 14px; margin-bottom: 4px;
  background: var(--card); border: 1px solid var(--rule);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: calc(11px * var(--fs-scale,1)); letter-spacing: .06em; color: var(--ink-soft);
}
.filter-fold > summary::-webkit-details-marker { display: none; }
.filter-fold > summary::marker { content: ''; }
/* v1.6.1 用户反馈②·箭头方向要符合直觉:收起 = ›(向右,「点开」)· 展开 = ⌄(向下)。
   此前是 ⌄ / ⌃,收起态看不出「这里能点开」。 */
.filter-fold > summary .fold-chev { transition: transform .18s ease; flex-shrink: 0; transform: rotate(-90deg); }
.filter-fold[open] > summary .fold-chev { transform: rotate(0deg); }
.filter-fold[open] > summary .fold-when-closed { display: none; }
.filter-fold:not([open]) > summary .fold-when-open { display: none; }
/* 收起态的行动号召:明确写出点开能干什么,而不是一个「改」字 */
.filter-fold > summary .fold-cta { color: var(--brass-text, #85642F); white-space: nowrap; }
.filter-fold:not([open]) > summary { border-color: var(--brass); background: var(--card-soft); }
@media (min-width: 768px) and (min-height: 480px) { .filter-fold > summary { display: none; } }
/* 横屏 iframe 短边只有 390 但确是宽屏视图 → 把手照旧隐藏 */
@media (min-width: 768px) { html.ls-wide .filter-fold > summary { display: none; } }

/* review B1-6 · KPI 带:窄屏「英雄数字 + 横滑 chip」。
   主 KPI(第一个)近满宽 + 字号升档,其余横滑 —— 五个同等大小的数字等于没有重点。 */
/* v1.6.1 用户反馈③ · 横滑方案退回网格。
   核心指标的要求是「一目了然」—— 横滑意味着有指标藏在屏幕外,得划一下才知道,这与目的相悖。
   改法:保留主次(净资产跨两列 + 大字),但把格子做紧凑(padding / eyebrow / value 全部收一档),
   让 5 个指标在一屏内同时可见。
   !important 必要:Tailwind Play CDN 在 style.css 之后注入,其 .grid-cols-2 同为单类选择器。 */
@media (max-width: 767px), (max-height: 479px) {
  html:not(.ls-wide) .kpi-band { display: grid !important; grid-template-columns: 1fr 1fr !important; }
  html:not(.ls-wide) .kpi-band > * { padding: 11px 12px !important; }
  html:not(.ls-wide) .kpi-band > * .kpi-eyebrow { margin-bottom: 5px; font-size: calc(9.5px * var(--fs-scale,1)); letter-spacing: .12em; }
  html:not(.ls-wide) .kpi-band > * .kpi-value { font-size: calc(19px * var(--fs-scale,1)); line-height: 1.15; }
  html:not(.ls-wide) .kpi-band > * .kpi-delta { margin-top: 4px; font-size: calc(10px * var(--fs-scale,1)); }
  /* 主指标:跨两列 + 字号升档,仍是视觉锚点 */
  html:not(.ls-wide) .kpi-band > *:first-child { grid-column: 1 / -1 !important; padding: 13px 14px !important; }
  /* 其余一律单列 —— 模板里第 5 个 KPI 原本带 col-span-2(那是「5 个平铺、最后一个居中」的老布局),
     现在主指标已占满第一行,第 5 个若还跨列就会让第 4 个旁边空一格。 */
  html:not(.ls-wide) .kpi-band > *:not(:first-child) { grid-column: auto !important; }
  html:not(.ls-wide) .kpi-band > *:first-child .kpi-value { font-size: calc(30px * var(--fs-scale,1)); }
  html:not(.ls-wide) .kpi-band > *:first-child .kpi-delta { font-size: calc(11px * var(--fs-scale,1)); }
}

/* review B3-2 · 类型汇总带:窄屏由多行网格改横滑单行(9 个类型曾占满整个首屏 ~950px) */
@media (max-width: 767px), (max-height: 479px) {
  html:not(.ls-wide) .summary-band {
    display: flex !important; overflow-x: auto;
    overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity; scrollbar-width: none;
  }
  html:not(.ls-wide) .summary-band::-webkit-scrollbar { display: none; }
  html:not(.ls-wide) .summary-band > * { flex: 0 0 44% !important; scroll-snap-align: start; }
}

/* spec §5 · 尊重系统「减少动态效果」偏好 —— 前庭障碍用户会因动画产生生理不适。
   功能性 loader(htmx-indicator / animate-spin)保留,装饰性动画一律停。 */
@media (prefers-reduced-motion: reduce) {
  .fade-in, .fade-in-delay-1, .fade-in-delay-2, .fade-in-delay-3, .fade-in-delay-4 {
    animation: none !important; opacity: 1 !important; transform: none !important;
  }
  #page-overlay, #page-overlay * { animation: none !important; }
  #page-progress::before { animation: none !important; }
  .kpi-info-panel { animation: none !important; }
  .toc-sheet { transition-duration: .01ms !important; }
}

/* review B1-7 · 资产透视三个区块(旭日/排行/交叉表)靠 JS 异步填充,填充前是三个大空白框,
   用户不知道是坏了还是在算 → 给统一的计算中占位。JS 渲染时会覆盖。 */
.lens-skeleton {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  min-height: 120px; height: 100%;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: calc(11px * var(--fs-scale,1)); letter-spacing: .08em; color: var(--ink-subtle);
}

/* review B3-7 · ★ 在 JetBrains Mono 里没有字形,回落后被渲染成点/方块(实测「风险 ······」)。
   星级单独指定有该字形的字体族。 */
.stars {
  font-family: "Noto Serif SC", "Segoe UI Symbol", "Apple Symbols", sans-serif;
  letter-spacing: .04em;
}

/* v1.6.1 的 .rot-* 局部旋转层已删(JS 已无引用)。
   它当年就用对了典范写法 `width:100dvh; height:100vw; transform:translate(100vw,0) rotate(90deg)`,
   只错了一个单位:注释里写「用 dvh 而非 vh,因为 iOS 地址栏收放会改变 vh」—— **正好说反了**。
   vh 是 large viewport(工具栏收起时的高度,恒定),dvh 才是会随工具栏变化的那个。
   用 dvh 当固定尺寸 → 工具栏一收放盒子就变 → 重排。这个误解一路带到 v1.6.6 改成 JS 量 px。 */

/* 触发按钮(仅窄屏出现:桌面本来就宽) */
.landscape-btn { display: none; }
@media (pointer: coarse) { .landscape-btn { display: inline-flex; } }

/* ── v1.6.15 · 整页横屏 · **原地**改断点(不再用 iframe 重载页面)────────────
   历史:v1.6.6–v1.6.14 用同源 iframe 拿"独立 viewport"。有效,但点一下 = 一次完整
   后端渲染 + 12 个脚本重跑(实测 1362ms),而且新文档必然丢滚动位置。
   现在断点由 landscape.js 原地重编译(Play CDN 运行时编译器 · 实测 114ms),
   这里只负责把布局宽度锁成屏幕**长边**,并在设备竖屏时转 90°。

   尺寸用交换后的视口单位(与 v1.6.8 调研的通行写法同一套):
     设备竖屏:width=100vh(长边)· height=100vw(短边)· 转 90°
     设备横屏:width=100vw(长边)· height=100vh(短边)· 不转
   两种情况都是「长边 × 短边」= 同一个物理矩形 → 转手机零重排,且切换由媒体查询完成。
   `max-width: 479px` 是软键盘护栏(竖屏弹键盘会让 orientation 翻成 landscape · SO 8883163)。 */
html.ls-wide { overflow: hidden; }
html.ls-wide > body {
  position: fixed; top: 0; left: 0; margin: 0;
  width: 100vw; height: 100vh;
  /* body 自带 Tailwind `min-h-screen`(min-height:100vh)。不清掉它,height 就被压过去 ——
     实测 body 变成 844×844(应为 844×390),旋转后底部整段跑到屏外,
     连 position:fixed 的退出钮都被算到屏外(rect 3964,730)。 */
  min-height: 0 !important;
  overflow-y: auto; overflow-x: hidden;
  overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  transform-origin: 0 0; transform: none;
}
@media (orientation: portrait) and (max-width: 479px) {
  html.ls-wide > body {
    width: 100vh; height: 100vw;
    transform: translate(100vw, 0) rotate(90deg);
  }
}

/* 退出钮:跟着 body 一起转,位置天然正确。
   内缩量按 iPhone 圆角给足 —— 用户反馈「会被 iPhone 的圆角遮挡导致按不稳」:
   iPhone 的屏幕圆角半径约 44–55pt,贴边 8px 的按钮有一角落在圆角外侧。
   右/上各留 26px,并把 nav 的右侧预留同步加大(见 .nav-inner padding-right)。 */
/* 退出钮由 landscape.js 放进 .nav-actions(随 sticky 导航常驻)。
   不用 position:fixed —— body 被 transform 后 fixed 的包含块变成 body,会跟着内容滚走;
   放进导航行同时解决「被 iPhone 屏幕圆角切到、按不稳」(nav-inner 自带内距)。 */
.ls-exit {
  display: inline-flex; align-items: center; gap: 5px;
  /* v1.6.16 · 用户反馈「经常点击没反应,要点很多次」。
     旧值 min-height:26px —— 旋转后它在屏幕上只有 26px 宽的一条,远低于 iOS HIG 的 44pt
     最小触摸目标,拇指很容易点在边上。加高到 34px,并把整行抬到 44px(见 .nav-inner)。
     touch-action:manipulation 去掉双击缩放的 300ms 等待(等待期内的点击会被吞)。 */
  min-height: 34px; padding: 0 12px; margin-left: 8px; cursor: pointer;
  touch-action: manipulation; -webkit-tap-highlight-color: rgba(26,23,20,.18);
  background: rgba(26,23,20,.88); color: var(--paper); border: none; border-radius: 3px;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: calc(11px * var(--fs-scale,1)); letter-spacing: .1em;
  backdrop-filter: blur(4px);
}
.ls-exit:active { transform: translateY(1px); }

/* ── v1.6.9 · 普通模式:手机横屏时把内容钉在设备坐标系(方案 B,用户选定)──────
   效果 = 就像开了系统的「竖屏方向锁定」,只对本 app 生效:
   转手机时页面在屏幕上**一动不动**,要读还得把手机转回来。

   为什么能做到零重排:
     · body 盒子 = 100vh × 100vw = 短边 × 长边 = **竖屏那个形状**(视口单位在横屏下自动交换)
     · 排版宽度仍是短边 → 与竖屏逐像素相同(断点也已在 v1.6.7 改成看短边)
     · 反向旋转把 OS 的旋转抵消掉 → 内容在设备上的位置不变

   旋转符号必须跟着设备转向走(v1.6.8 记录的正是这个风险):
     screen.orientation.angle 的定义 = viewport 相对自然方向**顺时针**转过的角度,
     要抵消就得转 -angle。angle 90(设备逆时针转)→ -90°;angle 270(设备顺时针转)→ +90°。
     angle 由 landscape.js 读出并挂 html.ori-cw(iOS 16.4+ 有 screen.orientation,
     更老的回落 window.orientation)。判错的表现是内容上下颠倒 —— 一个 class 之差。

   旋转量:绕左上角转 -90° 后盒子落到 y 轴负侧 → 下移一个盒子宽度(100vh);
   转 +90° 后落到 x 轴负侧 → 右移一个盒子高度(100vw)。

   护栏:pointer:coarse 挡 PC 矮窗 · min-width:480 挡竖屏软键盘假横屏(SO 8883163 · 112★)
   · :not(.ls-on) 让主动横屏模式不受影响 · :not(.ls-wide) 让 iframe 内不受影响。

   fixed 浮层(浮钮 / toast)会以被 transform 的 body 为包含块 → 自动跟着一起转,
   位置天然正确,不需要单独校正。 */
@media (pointer: coarse) and (orientation: landscape) and (max-height: 479px) and (min-width: 480px) {
  html:not(.ls-wide) { overflow: hidden; }
  html:not(.ls-wide) > body {
    position: fixed; top: 0; left: 0; margin: 0;
    width: 100vh; height: 100vw;
    overflow-y: auto; overflow-x: hidden;
    overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
    transform-origin: 0 0;
    transform: translate(0, 100vh) rotate(-90deg);
  }
  html.ori-cw:not(.ls-wide) > body {
    transform: translate(100vw, 0) rotate(90deg);
  }
  /* 方案 B 固有代价:body 被 transform 之后,它内部所有 position:fixed 浮层的包含块
     从视口变成了 body 盒子。这些浮层的几何(inset-x-0 / bottom:0 / translateY(110%) 收起态)
     都是按「未旋转的视口」写的,放进旋转容器就会错位 —— 实测目录抽屉会漏进屏内、
     顶部进度条会横向溢出 988px。
     冻结态的语义是「用户误转了手机、马上会转回来」的过渡态,不需要这些浮层 →
     几何脆弱的一律藏掉,只留内容本身 + 两个小圆浮钮(它们随 body 一起转,位置自洽,
     而且方向钮必须留着:用户可能就是想横着拿再点开横屏视图)。 */
  html:not(.ls-wide) #toc-sheet,
  html:not(.ls-wide) .toc-sheet,
  html:not(.ls-wide) .toc-sheet-mask,
  html:not(.ls-wide) .toc-fab,
  html:not(.ls-wide) #page-progress,
  html:not(.ls-wide) #toast-stack { display: none !important; }
}

/* 旋转遮帘(普通模式):iOS 自己的旋转动画抹不掉,盖成纯纸面就看不出在转 */
html.ori-turning > body { background: var(--paper); }
html.ori-turning > body > * { opacity: 0 !important; }

/* 嵌套态(iframe 内)· 不再出现横屏入口,避免套娃 */
html.ls-wide #ori-float, html.ls-wide .landscape-btn { display: none !important; }

/* v1.6.10 · 横屏模式的导航条:加回来,但按 844×390 重排 ——————————————
   v1.6.8 我把它整个藏了,理由是「844 宽放不下、390 高太贵」。用户要求加回来 ——
   这是对的:藏掉能力不是解决排版问题的办法。真正要做的是给横屏一套自己的尺度。

   844 宽的账本(实测):退出钮占 ~112px 必须留出 → 可用 ~700px;
   7 个 tab 压到 10px + 13px 间距 ≈ 268px,加印章 20px ≈ 310px —— 宽度其实很宽裕。
   v1.6.8 之所以折行,不是 tab 太多,是 gap-12(48px)+ gap-7(28px)+ 完整品牌文字
   + 版本徽记 + 字号钮 + 隐私钮 + 账期 pill + 用户名 一起挤的结果。

   390 高才是真正稀缺的:导航从 64px 压到 38px,省下的 26px 直接给内容。
   取舍:品牌只留印章(文字/版本在这个高度里是纯消耗)· 右侧那组整组收起
   (隐私有右下浮钮、字号退出再调),换来 7 个 tab 全部一行放下。 */
html.ls-wide > body > header {
  position: sticky; top: 0;
  /* 横屏态去掉毛玻璃:backdrop-filter 在被 transform 的容器里是 iOS 已知的
     命中测试/合成干扰源,而这里它只是装饰(纸面本来就不透明感强)。 */
  backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
  background: var(--paper) !important;
}
html.ls-wide .nav-inner {
  height: 44px !important;   /* 44 = iOS 最小触摸目标;内含 34px 高的钮 */
  padding-left: 12px !important;
  /* 退出钮已放进 .nav-actions 参与 flex 排,不再需要为它预留右侧空白;
     只留一点内缩避开 iPhone 屏幕圆角(圆角半径约 44–55pt,贴边元素会被切)。 */
  padding-right: 26px !important;
}
html.ls-wide .nav-lead { gap: 18px !important; }
html.ls-wide .nav-brandtext { display: none !important; }
html.ls-wide .nav-inner img { width: 21px !important; height: 21px !important; }
html.ls-wide .nav-tabs {
  gap: 13px !important;
  font-size: calc(10px * var(--fs-scale, 1)) !important;
  letter-spacing: .1em !important;
}
/* 选中态下划线原本用 pb-[18px] 撑到 h-16 的底,压扁后必须重算,否则下划线跑到栏外 */
html.ls-wide .nav-tabs > a { white-space: nowrap !important; padding-bottom: 0 !important; }
html.ls-wide .nav-tabs > a[class*="border-b-2"] { padding-bottom: 4px !important; }
/* 右侧那组默认收起,但**保留隐私钮**并放进导航条 —— 原因见下面的浮钮取舍。 */
html.ls-wide .nav-actions { display: flex !important; gap: 0 !important; }
html.ls-wide .nav-actions > * { display: none !important; }
html.ls-wide .nav-actions > .nav-priv { display: inline-flex !important; min-height: 34px; touch-action: manipulation; }
html.ls-wide .nav-actions > .ls-exit { display: inline-flex !important; }

/* 浮钮取舍:隐私浮钮在 390 高的横屏里会压住内容(实测压住交叉表的「AI 解读当前视图」按钮)。
   横屏导航条里 tab 结束在 335px、退出钮从 726px 开始 —— 中间 390px 全是空的,
   把隐私钮放回导航条既不压内容又更好找。目录钮在横屏无意义(整页就一屏多点)一并收起。 */
html.ls-wide #priv-float { display: none !important; }

/* ── v1.6.13 · 横屏模式下的「本页目录」──────────────────────────────
   v1.6.10 我把目录钮一起藏了,理由是「横屏整页就一屏多点,目录无意义」。
   这个判断错了:横屏高度只有 390,一屏能看的内容反而**更少**,跨节跳转比竖屏更需要。
   交互按横屏的空间特性重排:
     · 入口:不用右下浮钮(390 高里浮钮必压内容)→ 放进导航行,与隐私钮同列
     · 面板:不用底部 sheet(竖屏的做法 —— 横屏里它会盖掉大半屏)
              → 改**右侧侧栏**:横屏宽度富余、高度稀缺,侧栏正好反过来用
     · 点条目跳转后 toc.js 原逻辑自动关闭,无需额外处理 */
/* 目录钮参与导航行的 flex 排列(由 landscape.js 搬进 .nav-actions)——
   不用 position:fixed 摆坐标:那样必须和隐私钮的宽度"保持相等",一变就撞。 */
html.ls-wide .nav-actions > .toc-fab {
  display: inline-flex !important;
  position: static !important;
  min-height: 34px; touch-action: manipulation;
  top: auto; right: auto; bottom: auto; left: auto;
  margin-right: 8px;
  /* 与隔壁隐私钮**同款**:.pill + .pill-mute 的描边样式 ——
     并列同级控件必须同尺度同样式(AGENTS.md 护栏 / visual-spec「并列同类元素」)。
     原来它是 38px 深色实心圆(为右下浮钮设计的),搁在描边 pill 旁边像两个系统的东西。 */
  width: auto; height: auto; border-radius: 0;
  padding: 4px 9px;
  background: transparent;
  border: 1px solid var(--rule-soft);
  color: var(--ink-subtle);
  box-shadow: none;
  opacity: 1;
}
html.ls-wide .nav-actions > .toc-fab svg { width: 14px; height: 14px; }
html.ls-wide .nav-actions > .toc-fab:hover,
html.ls-wide .nav-actions > .toc-fab:active { color: var(--ink-soft); border-color: var(--rule); }
/* top 从 38px(横屏导航栏高)起,不是 0 ——————————————————————————
   `<main>` 带 `relative z-10`,它本身就是一个**层叠上下文**;抽屉在 main 里面,
   所以 `.toc-sheet` 的 z-index:80 永远升不到 z-30 的导航之上(实测抽屉的关闭 ×
   被 nav-inner 压住)。同一个原因也让 v1.6.13 的目录浮钮被隐私钮压住。
   与其去拆 main 的层叠上下文(牵连全站),不如让抽屉从导航条下方开始 ——
   顺带导航在抽屉打开时仍可点,体验反而更好。 */
html.ls-wide .toc-sheet {
  left: auto; right: 0; top: 44px; bottom: 0;
  width: min(320px, 42vw); max-height: none;
  border-radius: 14px 0 0 14px;
  box-shadow: -8px 0 32px rgba(0,0,0,.22);
  transform: translateX(110%);
  padding: 10px 8px 12px;
}
html.ls-wide .toc-sheet.open { transform: translateX(0); }
html.ls-wide .toc-sheet-mask { top: 44px; }   /* 遮罩同样不盖导航条 */
html.ls-wide .toc-sheet-handle { display: none; }
html.ls-wide .toc-sheet .toc-node { padding-top: 9px; padding-bottom: 9px; min-height: 38px; }

/* ── 横屏的垂直节奏:390 高是真正稀缺的资源 ────────────────────────
   实测(交叉表页):header 39 + main 上内边距 30 + 标题块 mt-10(37.5)+ 标题 51
   + 说明段 53 → 首张卡片被推到 **221px = 屏高的 57%**。横屏是为了看表格,
   不是为了看留白。压缩的是间距与标题字号,**不删任何内容**。 */
html.ls-wide main { padding-top: 8px !important; padding-bottom: 14px !important; }
html.ls-wide main .mt-8, html.ls-wide main .mt-10, html.ls-wide main .mt-12 { margin-top: 8px !important; }
html.ls-wide main .mb-8, html.ls-wide main .mb-10, html.ls-wide main .mb-12 { margin-bottom: 10px !important; }
/* 页面大标题降一档(text-2xl 不动:那一档大量用在金额上,压了会伤可读性) */
html.ls-wide main .text-4xl { font-size: calc(24px * var(--fs-scale, 1)) !important; line-height: 1.2 !important; }
html.ls-wide main .text-3xl { font-size: calc(22px * var(--fs-scale, 1)) !important; line-height: 1.2 !important; }
/* 首屏印章动画在嵌套态也跳过(landscape.js 已处理),这里兜底避免遮挡 */
html.ls-wide #page-overlay { display: none !important; }

/* 横屏浮钮:与隐私眼 / 目录钮同列。
   可见性只由「触屏」决定 —— **不能带 max-width**:设备横屏时 viewport 变宽会让按钮消失。 */
#ori-float {
  position: fixed; right: 14px;
  bottom: calc(max(18px, env(safe-area-inset-bottom)) + 96px);
  z-index: 56;
  display: none;
  align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 50%;
  background: var(--card); color: var(--ink-soft);
  border: 1px solid var(--rule); box-shadow: 0 3px 12px rgba(0,0,0,.16);
  cursor: pointer; opacity: .62;
  transition: opacity .25s ease, border-color .18s ease;
}
@media (pointer: coarse) { #ori-float { display: inline-flex; } }
#ori-float:hover, #ori-float:active, #ori-float:focus-visible { opacity: 1; border-color: var(--ink-soft); }
/* 方向图标双态(Tabler device-mobile / device-mobile-rotated · MIT · 同款描边):
   按钮显示**目标状态** —— 竖屏时显示"横屏手机"(点它去横屏),横屏时显示"竖屏手机"。 */
.ori-ico-port { display: none; }
[aria-pressed="true"] .ori-ico-land { display: none; }
[aria-pressed="true"] .ori-ico-port { display: inline; }
#ori-float[aria-pressed="true"] { background: var(--ink); color: var(--paper); border-color: var(--ink); opacity: 1; }
body.is-scrolling #ori-float { opacity: .22; }


/* ── 并列同类图表的公共容器(v1.6.12)────────────────────────────────
   「资产配置」与「按成员分布」是语义同级、并列展示的一对图。它们的容器高度
   原来各写各的 h-[348px]/h-[262px],于是两个环一大一小 —— 用户一眼就看出不对。
   规则(见 docs/visual-spec.md「并列同类图表」):**并列同类图表共用同一个容器 class**,
   任何一侧要改高度都会同时改到另一侧,不可能再单边漂移。 */
.chart-pair-box { height: 336px; }
@media (min-width: 640px) and (min-height: 480px) { .chart-pair-box { height: 380px; } }


/* ── v1.6.16 · 打标页手机端 ─────────────────────────────────────────
   实测 390 宽下:页头两段说明 + 穿透卡 + AI 卡共约 1200px,要滑一整屏才见到第一个
   可操作控件;整页 14054px 高(62 行卡片化),保存钮在最底部。
   做法:说明收成 <details>(PC 全文常显)+ 底部常驻保存条。不删任何信息。 */
.tags-intro > summary { list-style: none; cursor: pointer; }
.tags-intro > summary::-webkit-details-marker { display: none; }
.tags-savebar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 55;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 9px 14px calc(9px + env(safe-area-inset-bottom));
  background: var(--paper); border-top: 1px solid var(--rule);
  box-shadow: 0 -6px 20px rgba(26,23,20,.10);
}
/* 保存条会盖住最后一行 → 给页面补底部留白 */
body:has(.tags-savebar) main { padding-bottom: 76px; }

.tags-todo-toggle {
  display: inline-flex; align-items: center; gap: 7px; margin-bottom: 12px;
  font-size: calc(12px * var(--fs-scale,1)); color: var(--ink-soft); cursor: pointer;
  min-height: 34px; touch-action: manipulation;
}
.tags-todo-toggle input { width: 16px; height: 16px; accent-color: var(--brass-deep); }


/* ── v1.6.17 · 系统浮钮 dock ─────────────────────────────────────────
   三个浮钮(方向 / 本页目录 / 隐藏金额)原来各写死 bottom 偏移,页面缺一个就留空洞
   (打标页没有目录钮 → 中间一个洞,用户反馈④a)。改成 flex 列:有几个排几个。
   z-index 9999 > 首屏遮罩 9998:系统能力不被页面内容的加载进度绑住(反馈①/④b)。 */
/* v1.19.6 · dock 里的「超级 Agent」入口(手机)。
   规格照抄 #ori-float —— 并列同类元素必须同尺寸同样式,不能一个 38 一个 42。
   只在**窄屏**出现:≥768px 上面那个带文字的 .ask-fab 才是主入口,
   两个同时出现就是同一件事给了两个按钮(触屏笔记本会同时命中 coarse 和宽屏)。 */
#ask-float {
  position: fixed; right: 14px;
  bottom: calc(max(18px, env(safe-area-inset-bottom)) + 144px);
  z-index: 56;
  display: none;
  align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 50%;
  background: var(--card); color: var(--brass-deep);
  border: 1px solid var(--rule); box-shadow: 0 3px 12px rgba(0,0,0,.16);
  cursor: pointer; opacity: .72;
  transition: opacity .25s ease, border-color .18s ease;
}
@media (pointer: coarse) { #ask-float { display: inline-flex; } }
/* 这两条隐藏规则必须**带上 #float-dock 前缀**:进 dock 之后有一条
   `#float-dock > #ask-float{display:inline-flex!important}`(两个 id),
   只写 `#ask-float` 或 `body.ask-page #ask-float` 的优先级压不过它,规则会静默失效。
   实测踩过:PC 上和 /ask 页面上按钮照样冒出来。 */
@media (min-width: 768px) {
  #ask-float,
  #float-dock > #ask-float { display: none !important; }
}
#ask-float:hover, #ask-float:active, #ask-float:focus-visible { opacity: 1; border-color: var(--brass); }
body.is-scrolling #ask-float { opacity: .28; }
/* 在超级 Agent 页面上不显示 —— 那里点它等于原地打转,而且这一页左右都有要读的内容
   (v1.19 记过:fixed 浮层在这一页放哪儿都挡) */
body.ask-page #ask-float,
body.ask-page #float-dock > #ask-float { display: none !important; }

#float-dock {
  position: fixed; right: 14px;
  bottom: max(18px, env(safe-area-inset-bottom));
  z-index: 9999;
  display: none;
  flex-direction: column; align-items: center; gap: 10px;
}
@media (pointer: coarse) { #float-dock { display: flex; } }
/* dock 里的按钮交给 flex 排,自己不再定位 */
#float-dock > #ori-float,
#float-dock > .toc-fab,
#float-dock > #ask-float,
#float-dock > #priv-float {
  position: static !important; right: auto !important; bottom: auto !important;
  display: inline-flex !important;
}
/* 目录抽屉打开时只藏隐私眼(它会压住抽屉底部条目),目录钮自身留着当关闭入口 */
body.toc-open #float-dock > #priv-float,
body.toc-open #float-dock > #ask-float { display: none !important; }
html.ls-wide #float-dock { display: none !important; }


/* ── v1.6.17 · 打标页「持仓方向」横条占比示意 ──────────────────────
   加回最初 UED 稿的横条(用户反馈⑤:原来一堆 pill 会换行,方向多了撑成好几行)。
   横条只表达比例,用同一色系按深浅循环 —— 不冒充"维值配色":
   维值配色由旭日那边 JS 的方案色板决定,服务端渲染取不到,这里自造一套只会与旭日不一致。 */
/* 手机端 .tags-table 会卡片化(td 变块级、宽度由内容决定)→ 横条必须显式吃满宽,
   否则 flex:1 拿不到可分配空间,实测塌成 3px。 */
.alloc-head { display: flex; align-items: center; gap: 8px; width: 100%; }
.alloc-bar {
  display: flex; flex: 1 1 auto; min-width: 60px; width: 100%;
  height: 9px; border-radius: 5px; overflow: hidden;
  background: var(--rule-soft);
}
.alloc-seg { display: block; height: 100%; min-width: 2px; }
.alloc-seg.seg-0 { background: #8a6a3a; }
.alloc-seg.seg-1 { background: #a98a5c; }
.alloc-seg.seg-2 { background: #6f7f6a; }
.alloc-seg.seg-3 { background: #93a08e; }
.alloc-seg.seg-4 { background: #6f7a8c; }
.alloc-seg.seg-5 { background: #9aa3b0; }
/* 标签行:不换行,超出横滑(复用 .hscroll-x 的 iOS 护栏:不触发 Safari 返回手势) */
.alloc-pills { display: flex; align-items: center; padding-bottom: 2px; }


/* v1.6.17 · 三个系统浮钮**基础态**就抬到首屏遮罩(9998)之上。
   #float-dock 是 landscape.js(defer)建的,建之前这三个钮还按各自定位渲染 ——
   实测 dashboard 上要到 3.2s 才可点(等 DOMContentLoaded)。抬 z-index 后首屏即可点。 */
#ori-float { z-index: 9999; }


/* v1.6.18 · 明细抽屉打开时闪一下边框 —— 指标放行时表格很高,
   用户点完需要一个"响应了"的确认(否则以为没下钻)。 */
@keyframes drawer-flash { 0%,100% { box-shadow: 0 0 0 0 rgba(176,141,63,0); } 25% { box-shadow: 0 0 0 3px rgba(176,141,63,.55); } }
.drawer-flash { animation: drawer-flash .9s ease-out 1; }
@media (prefers-reduced-motion: reduce) { .drawer-flash { animation: none; } }

/* v1.6.18 · ⑥ 浮钮 dock 右对齐 ——
   隐私态下 #priv-float 会显出文字标签变宽,而 dock 原来是 align-items:center,
   dock 宽度被最宽的那个撑开 → 另外两个居中钮跟着左移(用户反馈:位置偏移)。
   右对齐后每个钮的右缘固定,谁变宽只往左长,其余不动。 */
#float-dock { align-items: flex-end !important; }


/* v1.6.20 · 打标页横屏态:保存条要留着。
   .tags-savebar 带 md:hidden,而横屏模式把 md: 强制打开 → 它会被藏掉;
   但横屏下 62 行表格仍有两千多像素,保存钮还是不该只在最底部。 */
html.ls-wide .tags-savebar { display: flex !important; }


/* v1.6.20 · 打标页横屏态:说明仍保持折叠。
   横屏把 md: 强制打开 → `hidden md:block` 的全文版会现身、`md:hidden` 的折叠版会消失,
   但**横屏的竖向空间(390)比竖屏(844)更紧**,说明全文正是最该收起来的东西。
   横屏要的是"表格铺开",不是"把说明也铺开"。 */
html.ls-wide .tags-intro,
html.ls-wide .tags-note-fold { display: block !important; }
html.ls-wide .tags-intro-full,
html.ls-wide .tags-note-full { display: none !important; }


/* ── v1.6.20 · 打标页横屏态:页头压到最小,让表格进首屏 ─────────────────
   横屏成了这页的**默认工作模式**,而横屏只有 390 竖向像素。
   实测未压缩前:表头在 418px —— 整个首屏被 eyebrow + 大标题 + 两张说明卡占满,
   一行表格都看不到,等于还是干不了活。
   压的是页头与说明卡(它们已折叠成一行),表格本身一点不动。 */
html.ls-wide .tags-head { margin-bottom: 6px !important; }
html.ls-wide .tags-head .eyebrow { display: none !important; }
html.ls-wide .tags-head h1 { font-size: calc(19px * var(--fs-scale, 1)) !important; line-height: 1.2 !important; }
html.ls-wide .tags-head .tags-intro { margin-top: 2px !important; }
html.ls-wide .tags-head > a { font-size: calc(10px * var(--fs-scale, 1)) !important; }
/* 说明卡:内距压薄 + 标题与「这是什么」同一行 */
html.ls-wide .tags-note { padding: 6px 12px !important; margin-bottom: 6px !important; }
html.ls-wide .tags-note .tags-note-fold { display: inline-block !important; margin-top: 0 !important; margin-left: 8px; }
html.ls-wide .tags-note .btn-ink { padding-top: .25rem !important; padding-bottom: .25rem !important; }

/* 券商对接状态条(v1.6.24)· 持仓页标题下,一眼看到本账户 ↔ 富途/老虎的 1:1 关联状况。
   用「左侧竖线 + 细框」而不是 paper-card:它是一条**关联信息**,不是一个内容区块;
   竖线用 brass(已关联)/ ink-subtle(未关联)区分,不靠文字才能读出状态。 */
.link-strip {
  border: 1px solid var(--rule); border-left: 3px solid var(--brass-deep);
  background: var(--card); padding: 12px 16px;
  display: flex; flex-wrap: wrap; align-items: center; column-gap: 20px; row-gap: 8px;
}
.link-strip.is-none { border-left-color: var(--ink-subtle); }
.link-strip .ls-kv { font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: calc(11px * var(--fs-scale,1)); color: var(--ink-soft); }
.link-strip .ls-kv b { color: var(--ink); }
.link-strip .ls-acts { margin-left: auto; display: flex; gap: 8px; }
/* 手机:竖排 + 两个按钮各占一半宽(44px 高满足 iOS 触摸目标 · visual-spec §7.6)*/
@media (max-width: 639px) {
  .link-strip { flex-direction: column; align-items: stretch; row-gap: 4px; }
  .link-strip .ls-acts { margin-left: 0; margin-top: 8px; }
  .link-strip .ls-acts > a { flex: 1; justify-content: center; min-height: 44px; }
}

/* v1.9 · 版本徽记的「有新版」圆点 ————————————————————————————
   绝对定位、不进文档流:徽记只有 9px 高、贴在 logo 下面一行,
   任何进流的元素都会把它和 nav 一起撑歪(验收要求两态几何逐项相同)。
   brass 描边不是红色 —— 这是「有个新版本存在」的事实陈述,不是告警。 */
.ver-badge { text-decoration: none; }
.ver-badge:hover { color: var(--brass-text); text-decoration: none; }
/* v1.9.2 · 原 .ver-dot 用 brass-soft 填色,在 paper 背景上只有约 1.2:1 对比度 —— 用户反馈
   「太弱了,和背景色过于相似」,实测确实等于看不见。换成实心文字标签:
   brass-deep 底 + paper 字 ≈ 4.1:1,而且「NEW」是文字、不需要猜含义。
   参考 WordPress 的 #d63638 实心药丸 + 白字(border-radius:9px / font-size:11px / min-width:18px)
   与 sub2api 的「整个徽记变琥珀 chip + 实心点」。
   刻意不用 rust(红):红色在本项目里是告警语义,而「有新版」是事实陈述不是事故。 */
.ver-new {
  display: inline-block; margin-left: 3px;
  background: var(--brass-deep); color: var(--paper);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 7.5px; line-height: 1; letter-spacing: .1em;
  padding: 2.5px 3.5px 2px; border-radius: 2px;
  vertical-align: 1px; font-weight: 600;
  pointer-events: none;
}
/* 有更新时整个徽记也提一档(sub2api 的做法:chip 本身换色,不只挂个角标) */
.ver-badge.has-upd { color: var(--brass-deep); }
.ver-badge.has-upd:hover .ver-new { background: var(--ink); }

/* ── v1.9.2 · 「有新版」弹窗 ───────────────────────────────────────────── */
.upd-mask {
  position: fixed; inset: 0; background: rgba(26,23,20,.42);
  z-index: 10000; opacity: 0; pointer-events: none; transition: opacity .16s ease;
}
.upd-mask.open { opacity: 1; pointer-events: auto; }
.upd-modal {
  position: fixed; z-index: 10001;
  left: 50%; top: 84px; transform: translateX(-50%);
  width: min(440px, calc(100vw - 28px));
  background: var(--card); border: 1px solid var(--ink);
  box-shadow: 0 14px 40px rgba(33,30,23,.24);
}
.upd-modal[hidden] { display: none; }
/* 弹窗挂在 <footer class="... text-center"> 里 —— 不显式左对齐就会继承居中,
   正文和发布日期全跑到中间(移动端尤其明显)。 */
.upd-modal, .upd-modal * { text-align: left; }
/* 弹窗打开时收掉悬浮件:记账/目录/隐私三个 fab 的 z-index 是 9999,
   跟弹窗同级,会直接压在弹窗上面(移动端弹窗贴底,正好撞在按钮区)。 */
body.upd-open #float-dock,
body.upd-open .toc-fab,
body.upd-open #ori-float,
body.upd-open #priv-float { display: none !important; }
.upd-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 11px 14px; border-bottom: 1px solid var(--rule-soft);
}
.upd-x { background: none; border: 0; cursor: pointer; color: var(--ink-subtle); padding: 2px; line-height: 0; }
.upd-x:hover { color: var(--ink); }
.upd-body { padding: 14px; }
.upd-vers { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.upd-cur { font-family: 'JetBrains Mono', monospace; font-size: 0.94rem; color: var(--ink-soft); }
.upd-new {
  font-family: 'JetBrains Mono', monospace; font-size: 1.06rem; font-weight: 600;
  color: var(--paper); background: var(--brass-deep); padding: 1px 7px; border-radius: 2px;
}
.upd-behind {
  font-family: 'JetBrains Mono', monospace; font-size: 0.56rem; letter-spacing: .08em;
  border: 1px solid var(--brass-deep); color: var(--brass-text);
  background: var(--brass-soft); padding: 2px 6px;
}
.upd-meta { font-family: 'JetBrains Mono', monospace; font-size: 0.63rem; color: var(--ink-subtle); margin-top: 5px; }
.upd-sum { font-size: 0.78rem; color: var(--ink); line-height: 1.8; margin-top: 10px; }
.upd-mig {
  font-family: 'JetBrains Mono', monospace; font-size: 0.66rem; line-height: 1.7;
  margin-top: 11px; padding: 7px 9px; border: 1px dashed var(--rule); color: var(--ink-subtle);
}
.upd-mig.risk { border: 1px solid var(--rust); border-style: solid; color: var(--rust); background: rgba(156,74,42,.06); }
.upd-mig.ok   { border-style: solid; border-color: var(--forest); color: var(--forest); background: rgba(79,107,71,.07); }
.upd-foot {
  display: flex; gap: 9px; flex-wrap: wrap;
  padding: 12px 14px; border-top: 1px solid var(--rule-soft); background: var(--card-soft);
}
.upd-btn { font-size: 0.75rem; }
@media (max-width: 640px) {
  .upd-modal { top: auto; bottom: 0; left: 0; right: 0; transform: none; width: auto; border-bottom: 0; }
  /* 贴底抽屉的按钮行要躲开 iPhone 的 home indicator,否则最后一行按钮压在手势条下面 */
  .upd-foot { padding-bottom: max(12px, env(safe-area-inset-bottom)); }
  .upd-foot .upd-btn { flex: 1; text-align: center; }
}


/* ══════════════════════════════════════════════════════════════════════
   v1.10 · 报表页三区(封板快照)
   一区/二区定格于 asof,三区随 range —— 视觉上必须让用户看出这个分界,
   否则「切范围前两区不动」会被当成页面没反应。
   ════════════════════════════════════════════════════════════════════ */
.zone-head { display: flex; align-items: center; gap: 12px; margin-bottom: 6px; flex-wrap: wrap; }
.zone-no {
  font-family: "JetBrains Mono", monospace; font-size: 1.1rem; line-height: 1;
  color: var(--paper); background: var(--brass-deep); padding: 5px 9px; letter-spacing: 0;
}
.zone-t { font-family: "Fraunces", "Noto Serif SC", serif; font-size: 1.25rem; }
.zone-sub { font-size: 0.72rem; color: var(--ink-subtle); line-height: 1.6; }
.zone-line { height: 2px; background: var(--brass-deep); opacity: .35; margin: 10px 0 18px; }

/* 资产 / 负债 对称条 · 左右同一比例尺 */
.sym-bar { display: flex; align-items: stretch; height: 34px; border: 1px solid var(--ink); margin-top: 14px; }
.sym-a { background: var(--brass-soft); display: flex; align-items: center; justify-content: flex-end; padding-right: 8px; overflow: hidden; }
.sym-l { background: rgba(156,74,42,.16); display: flex; align-items: center; padding-left: 8px; border-left: 2px solid var(--ink); overflow: hidden; }
.sym-a span, .sym-l span { white-space: nowrap; }

/* 瀑布 · 截断轴 + 连接线。月度流量与存量差两个数量级,全量轴下中间段看不见 —— 故必须截断轴。 */
.wf-scroll { overflow-x: auto; overflow-y: visible; -webkit-overflow-scrolling: touch; padding-bottom: 1.6rem; }
.wf { display: flex; align-items: flex-end; height: 220px; margin-top: 12px;
      border-bottom: 1px solid var(--rule); min-width: 460px;
      position: relative;              /* 承载截断斜纹带(::after 贴轴线)*/
      padding-top: 1.5rem;             /* v1.11.1 · 给最高柱子的顶部标签留位置 ——
                                          原来标签定位在柱顶 -1.05rem,最高柱贴着容器上边 → 被裁掉一半 */
      box-sizing: content-box; }       /* 柱高是相对 content box 的百分比,padding 不参与 → 比例不变 */
.wf-col { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; height: 100%; }
.wf-bar { width: 62%; position: relative; min-height: 2px; }
/* 连接线:本段端点水平延伸到下一段起点 —— 没有它就读成普通柱状图,丢掉「分解」语义 */
.wf-bar::after {
  content: ""; position: absolute; top: 0; right: -61.3%; width: 61.3%; height: 1px;
  background: var(--ink-subtle); opacity: .5;
}
.wf-col:last-child .wf-bar::after { display: none; }
.wf-dl {
  /* v1.11.1 · 标签比柱子宽(¥1,234,567 约 178px vs 柱宽 ~127px),溢出的部分会被 DOM 顺序在后的
     柱子背景盖住 —— .wf-bar 没有 z-index 不构成层叠上下文,所以给标签 z-index 就能浮到所有柱子之上。 */
  position: absolute; left: -22%; right: -22%; top: -1.05rem; text-align: center; z-index: 5;
  font-family: "JetBrains Mono", monospace; font-size: 0.62rem; font-weight: 600; white-space: nowrap;
}
.wf-lab { font-family: "JetBrains Mono", monospace; font-size: 0.56rem; color: var(--ink-subtle);
          margin-top: 6px; text-align: center; line-height: 1.35; }

/* 三列对照表 · 封板要精确值,所以用表不用图 */
.cmp-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.cmp-table { width: 100%; border-collapse: collapse; min-width: 620px; }
.cmp-table th {
  font-family: "JetBrains Mono", monospace; font-size: calc(9.5px * var(--fs-scale,1));
  letter-spacing: .14em; color: var(--ink-soft); text-align: right;
  padding: 8px 10px; border-bottom: 1px solid var(--ink); white-space: nowrap;
}
.cmp-table th:first-child { text-align: left; }
.cmp-table td {
  padding: 9px 10px; border-bottom: 1px solid var(--rule-soft); text-align: right;
  font-family: "JetBrains Mono", monospace; font-size: calc(12px * var(--fs-scale,1)); white-space: nowrap;
}
.cmp-table td:first-child {
  text-align: left; font-family: inherit; font-size: calc(13px * var(--fs-scale,1));
  position: sticky; left: 0; background: var(--card); white-space: nowrap;
}

/* 集中度 · 横条 + 阈值线 + 上期幽灵条(没有上期时不画,而不是画成 0) */
.conc-row { margin-bottom: 12px; }
.conc-cap { display: flex; justify-content: space-between; gap: 10px;
            font-family: "JetBrains Mono", monospace; font-size: calc(10px * var(--fs-scale,1)); margin-bottom: 3px; }
.conc-track { position: relative; height: 16px; background: var(--paper-soft); border: 1px solid var(--rule-soft); }
.conc-ghost { position: absolute; top: 0; bottom: 0; background: rgba(140,106,51,.18); }
.conc-fill { position: absolute; top: 0; bottom: 0; background: var(--brass-deep); opacity: .75; }
.conc-thr { position: absolute; top: -3px; bottom: -3px; width: 1px; background: var(--rust); }

/* 流动性分层 · 单条堆叠 */
.stack { display: flex; height: 42px; border: 1px solid var(--ink); margin-top: 10px; }
.stack > div { display: flex; align-items: center; justify-content: center; overflow: hidden;
               font-family: "JetBrains Mono", monospace; font-size: calc(10px * var(--fs-scale,1)); white-space: nowrap; }
.stack-liquid { background: var(--brass-soft); }
.stack-semi { background: rgba(140,106,51,.30); border-left: 1px solid var(--ink); }
.stack-illiquid { background: rgba(33,30,23,.14); border-left: 1px solid var(--ink); }

/* 归因 · 双向条形(零轴居中,正右负左) */
.biv-row { display: grid; grid-template-columns: 1fr 150px 1fr; align-items: center; gap: 8px; margin-bottom: 7px; }
.biv-name { font-size: calc(12px * var(--fs-scale,1)); text-align: center; }
.biv-left { display: flex; justify-content: flex-end; align-items: center; }
.biv-right { display: flex; align-items: center; }
.biv-bar { height: 15px; min-width: 2px; }
.biv-pos { background: rgba(79,107,71,.55); }
.biv-neg { background: rgba(156,74,42,.5); }
.biv-amt { font-family: "JetBrains Mono", monospace; font-size: calc(10px * var(--fs-scale,1));
           padding: 0 5px; white-space: nowrap; }
@media (max-width: 560px) {
  .biv-row { grid-template-columns: 1fr 96px 1fr; gap: 5px; }
  .biv-name { font-size: calc(11px * var(--fs-scale,1)); }
  .zone-t { font-size: 1.1rem; }
}

/* v1.10 · 截断轴的柱底标记。
   瀑布用截断轴是必须的(月度流量与存量差两个数量级),但代价是存量柱的相对高度失真 ——
   实测 beta:期初柱 11% 高、期末柱 87% 高,而两者金额只差 45%,不加提示会被读成「涨了 8 倍」。
   所以轴被截断时在柱底压一道斜纹带(标准 broken-axis 标记),让人一眼知道柱子不是从 0 起。 */
/* v1.11.1 · 斜纹带必须贴在**轴线**(.wf 的底边)上,不能贴滚动容器的底边 ——
   X 轴标签(.wf-lab)是溢出 .wf 之外、落在容器下方的,贴容器底边会**把标签压掉一半**
   (维护者报「大量数字被遮蔽」)。所以改成 .wf::after,相对轴线定位。 */
/* v1.11.1(二改)· 斜纹带只画在**每根柱子内部的底部**,不横贯整宽。
   横贯版(贴 .wf 底边)会压住 X 轴标签 —— .wf-lab 是溢出 .wf 之外的,那条边正好穿过标签中间
   (维护者报「大量数字被遮蔽」,第一次修只解决了顶部标签被裁,这条才是主因)。
   柱底本来就是轴线,画在柱内语义完全一样,而且一个字都不碰。 */
.wf-truncated .wf-bar::before {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 5px;
  background: repeating-linear-gradient(115deg, rgba(244,239,230,.92) 0 3px, rgba(33,30,23,.28) 3px 4px);
  pointer-events: none;
}

/* v1.11.1 · 长文目录的二级条目(报表页三区之下的 9 个子节)。
   统一不编号 + 缩进表达层级 —— 给子节编号(四、五…)会让人以为它们和三个区是同级的。 */
.toc-node.toc-sub { padding-left: 1.15rem; }
.toc-node.toc-sub .lbl { font-size: 0.92em; color: var(--ink-subtle); }
.toc-node.toc-sub[aria-current="true"] .lbl { color: var(--ink); }

/* ===========================================================
   终端命令块(v1.17.1)· 需要用户【照着敲】的命令一律用它
   -----------------------------------------------------------
   以前每处各写各的:更新提示是浅色 <pre>、落地页是黑底 .cmd-block、
   向导页又是另一套内联样式 —— 同一件事(这是要你复制去跑的命令)长三个样,
   而且只有落地页那处能一键复制。统一成一个类 + 一个 fragment。
   =========================================================== */
.term-block{ position:relative; background:#1c1a17; border:1px solid #2a2622; border-radius:6px;
             padding:.85rem 1rem; overflow-x:auto; box-shadow:0 6px 18px -12px rgba(0,0,0,.55); }
/* 不用 <pre>:Thymeleaf 在 <pre> 里会把模板自身的缩进一起渲染出来。
   每行做成独立 block + pre-wrap,既没有多余缩进,长命令(digest)也能折行而不是横向滚动。 */
.term-block .t-code{ font-family:'JetBrains Mono',ui-monospace,monospace; font-size:12.5px;
                     line-height:1.85; color:#d8d2c6; display:block; }
.term-block .t-cmt{ color:#7d766a; }                 /* # 注释 */
/* 悬挂缩进:长命令(digest 那种)折行后,续行要缩进,否则看起来像另起一条命令 */
.term-block .t-line{ display:block; white-space:pre-wrap; word-break:break-all;
                     padding-left:1.5em; text-indent:-1.5em; }
/* 复制按钮浮在右上角,只让【第一行】给它让位 —— 整块留白会白白吃掉移动端本就不多的宽度 */
.term-block .t-line:first-child{ padding-right:3.8rem; }
.term-block .t-line::before{ content:'$ '; color:#8fae86; }   /* 提示符:一眼看出这是要敲的命令 */
.term-block .t-line.t-cmt::before{ content:'  '; }             /* 注释行不加 $,否则复制出来会以为要连 $ 一起敲 */
.term-block .t-copy{ position:absolute; top:.5rem; right:.5rem; font-family:'JetBrains Mono',monospace;
                     font-size:11px; color:#d8d2c6; background:#2a2622; border:1px solid #3a352f;
                     border-radius:4px; padding:.22rem .6rem; cursor:pointer; transition:background .15s,color .15s; }
.term-block .t-copy:hover{ background:var(--brass-deep); color:var(--paper); border-color:var(--brass-deep); }
.term-block .t-copy.ok{ background:var(--forest); color:#fff; border-color:var(--forest); }
@media(max-width:640px){ .term-block pre{ font-size:11.5px; } .term-block .t-copy{ font-size:10px; } }

/* ===========================================================
   凭据配置卡 + 状态标签(v1.17.2)
   -----------------------------------------------------------
   三家 AI 平台原来是三列裸 div,只靠间距分隔 —— 用户看不出"这是三个独立的东西";
   而「已配置 / 未配置」是一行灰色小字,混在 label 里,扫一眼根本分不清哪家配好了。
   =========================================================== */
.cred-card{ background:var(--card-soft); border:1px solid var(--rule-soft); border-radius:6px;
            padding:.9rem 1rem; display:flex; flex-direction:column; }
.cred-card.is-on{ border-color:rgba(79,107,71,.42); background:rgba(79,107,71,.045); }
.cred-card .cred-head{ display:flex; align-items:center; gap:.5rem; flex-wrap:wrap; margin-bottom:.55rem; }
.cred-card .cred-name{ font-weight:600; font-size:13.5px; color:var(--ink); }

/* 状态标签:配没配是这一页最该一眼看清的事,所以给底色 */
.state-tag{ display:inline-flex; align-items:center; gap:.28rem; font-family:'JetBrains Mono',monospace;
            font-size:10px; letter-spacing:.06em; padding:.14rem .5rem; border-radius:3px; white-space:nowrap; }
.state-tag.on{  color:#fff; background:var(--forest); }
.state-tag.off{ color:#fff; background:var(--rust); }
.state-tag svg{ width:11px; height:11px; }

/* 已配置时:掩码值(留头尾几位,方便有多把 key 的人确认当前是哪一把) */
.cred-mask{ font-family:'JetBrains Mono',monospace; font-size:11px; color:var(--ink-soft);
            background:var(--paper); border:1px solid var(--rule-soft); border-radius:4px;
            padding:.3rem .5rem; margin-bottom:.4rem; word-break:break-all; }

/* 卡片里的输入框:placeholder 用等宽小字,和上面那行掩码同一视觉层级 ——
   默认 field-input 的 placeholder 是正文 serif 大字号,和掩码并排时抢走全部注意力 */
.cred-card .field-input{ font-family:'JetBrains Mono',monospace; font-size:12px; }
.cred-card .field-input::placeholder{ font-family:'JetBrains Mono',monospace; font-size:11px; opacity:.75; }

/* 下拉里不可选的平台(还没配 key)*/
select option:disabled{ color:var(--ink-subtle); font-style:italic; }

/* ══════════════════════════════════════════════════════════════════════════
   v1.19 · 超级 Agent
   ──────────────────────────────────────────────────────────────────────────
   结构照 Claude / ChatGPT / Manus 已经收敛的那套规范,视觉仍是账房自己的:
   纸色底、铜色强调、eyebrow 字距。照搬中性灰白会让这一页像从别的产品抄来的 ——
   全站另外十几个页面都是这套语言,单独一页跳出来只会显得突兀。
   ══════════════════════════════════════════════════════════════════════════ */

/* ── 列宽 ──
   768px 是 Claude / ChatGPT 收敛出来的值,对应约 65–72 个西文字符。
   中文更宽,15px 下一行约 40 字 —— 长回答读起来不至于串行。
   之前是 860px + 13.5px,一行奔 60 个汉字,那是文档排版不是对话排版。 */
:root{ --ask-col: 768px; }

.ask-main{ flex:1; min-height:0; width:100%; max-width:calc(var(--ask-col) + 5rem);
           margin:0 auto; display:flex; flex-direction:column; position:relative; z-index:10; }
.ask-shell{ flex:1; min-height:0; display:flex; flex-direction:column; overflow:hidden; }
.ask-panel{ flex:1; min-height:0; display:flex; flex-direction:column; }
.ask-col{ width:100%; max-width:var(--ask-col); margin:0 auto; }

@media (min-width:640px){
  .ask-main{ padding:1.5rem 1rem; }
  .ask-shell{ border:1px solid var(--rule); border-radius:12px; background:var(--paper); }
}

/* ── 顶栏 ── */
.ask-head{ display:flex; align-items:center; gap:.6rem; flex:none;
           padding:.7rem 1rem; border-bottom:1px solid var(--rule); }
.ask-head-brand{ flex:none; color:var(--ink); }
.ask-head-ctx{ flex:none; font-family:'JetBrains Mono',monospace; font-size:10.5px;
               color:var(--ink-subtle); border:1px solid var(--rule-soft);
               border-radius:3px; padding:.1rem .4rem; white-space:nowrap; }
.ask-head-title{ font-size:12.5px; color:var(--ink-soft); overflow:hidden;
                 text-overflow:ellipsis; white-space:nowrap; }
.ask-head-gap{ flex:1; }
/* 窄屏顶栏放不下「+ 新对话」四个字符,flex 会把它压成竖排 —— 只留图标 */
@media (max-width:520px){
  .ask-head{ gap:.45rem; padding:.6rem .8rem; }
  .ask-head .ask-mini{ font-size:0; padding:.3rem; }
  .ask-head .ask-mini svg{ width:15px; height:15px; }
  .ask-head-title{ display:none; }
}

/* ── 消息区 ── */
.ask-msgs{ flex:1; min-height:0; overflow-y:auto; padding:1.1rem 1rem .6rem; }
@media (max-width:520px){
  .ask-msgs{ padding:.9rem .85rem 0; }
  .ask-composer-wrap{ padding:.5rem .85rem .4rem; }
}

/* 用户消息:右对齐 + 一条细下划线,**不用气泡**。
   圆角实心气泡传递的是「随便聊聊」,和这一页要给的「可核对的账」相冲;
   而且 AI 那侧是扁平长文,一边气泡一边文档,自己跟自己打架。 */
.ask-me{ display:flex; justify-content:flex-end; margin:1.4rem 0 1.1rem; }
.ask-me > div{ max-width:82%; text-align:right; font-size:14.5px; line-height:1.7;
               color:var(--ink); white-space:pre-wrap;
               padding-bottom:.45rem; border-bottom:1.5px solid var(--brass); }
.ask-me:first-child{ margin-top:.2rem; }

/* 旁白:换账期 / 上游出错 / 已叫停。刻意弱 —— 它不是答案 */
.ask-note{ display:flex; justify-content:center; margin:1rem 0; }
.ask-note span{ font-size:11.5px; color:var(--ink-subtle); background:var(--card-soft);
                border:1px solid var(--rule-soft); border-radius:999px; padding:.2rem .7rem; }

.ask-turn{ margin-bottom:1.8rem; }

/* ── 工具执行:默认折叠 ──
   Manus 那条规矩:对话线程讲结论,自主执行过程另放。常驻平铺会和正文抢注意力,
   而多数时候用户并不关心它查了哪几个维度 —— 只在数字看着不对时才想看。 */
.ask-acts{ margin-bottom:.7rem; }
.ask-acts summary{ display:inline-flex; align-items:center; gap:.35rem; cursor:pointer;
                   list-style:none; font-size:11.5px; color:var(--ink-subtle);
                   padding:.15rem .5rem .15rem .3rem; border-radius:4px; user-select:none; }
.ask-acts summary::-webkit-details-marker{ display:none; }
.ask-acts summary:hover{ color:var(--ink-soft); background:var(--card-soft); }
.ask-caret{ display:inline-block; transition:transform .15s; font-size:9px; }
.ask-acts[open] .ask-caret{ transform:rotate(90deg); }
.ask-acts-body{ margin:.35rem 0 0 .55rem; padding-left:.7rem;
                border-left:1px solid var(--rule-soft); }
.ask-act{ display:flex; align-items:center; gap:.45rem; font-size:11.5px;
          color:var(--ink-subtle); line-height:1.9; }
.ask-act-ms{ font-family:'JetBrains Mono',monospace; font-size:10px; color:var(--ink-faint); }
.ask-dot{ width:5px; height:5px; border-radius:50%; background:var(--brass); flex:none; }
.ask-dot.bad{ background:var(--rust); }
.ask-dot.run{ animation:ask-pulse 1.1s ease-in-out infinite; }
@keyframes ask-pulse{ 0%,100%{opacity:.28} 50%{opacity:1} }

/* 排队中:脉冲点 + 一句话。**不给假进度条** —— 没有进度可报,画一个是骗人 */
.ask-wait{ display:inline-flex; align-items:center; gap:.45rem;
           font-size:12.5px; color:var(--ink-soft); }
.ask-wait::before{ content:''; width:6px; height:6px; border-radius:50%;
                   background:var(--brass); animation:ask-pulse 1.1s ease-in-out infinite; }

/* ── 正文 ── */
.ask-body{ font-size:15px; line-height:1.78; color:var(--ink); }
.ask-body p{ margin:.55rem 0; }
.ask-body p:first-child{ margin-top:0; }
.ask-body strong{ font-weight:600; }
/* 模型很爱用 "- xxx" 列条目。不认它的话每条会变成一个独立段落 ——
   段间距 .55rem 让三条列表撑得像三段话,而且行首那个裸的短横线很难看。 */
.ask-body ul{ margin:.5rem 0; padding-left:1.05rem; list-style:none; }
.ask-body li{ position:relative; margin:.22rem 0; line-height:1.75; }
.ask-body li::before{ content:''; position:absolute; left:-.85rem; top:.72em;
                      width:4px; height:4px; border-radius:50%; background:var(--brass); }

/* 流式光标:没有它,模型思考的停顿会被读成「已经结束了」。
   Claude 用小方块、ChatGPT 用脉冲点 —— 这里取方块,和等宽数字的调性一致。 */
.ask-caret-live{ display:inline-block; width:.5em; height:1.05em; margin-left:1px;
                 background:var(--ink); vertical-align:-.16em;
                 animation:ask-blink 1s step-end infinite; }
@keyframes ask-blink{ 0%,49%{opacity:1} 50%,100%{opacity:0} }

/* ── 引用卡 ──
   这一版最重要的视觉件。四样缺一不可:指标名、数值、账期与关账状态、点回原页。
   缺任何一样,数字就退回成「一个说不清出处的裸数字」—— 而那正是 v1.18 一整个系列在修的病。 */
/* 连排四张时整体重量偏大,所以内距和行距都收过一轮:
   卡片本身要显眼(它是「这个数有出处」的凭证),但四张叠起来不该盖过正文。 */
.ask-cite{ display:block; margin:.5rem 0; padding:.5rem .7rem; text-decoration:none;
           border:1px solid var(--rule); border-left:2px solid var(--brass);
           border-radius:5px; background:var(--card-soft);
           transition:border-color .15s, background .15s; }
.ask-cite:hover{ border-color:var(--brass); background:var(--card); }
.ask-cite-top{ display:flex; align-items:baseline; justify-content:space-between; gap:.75rem; }
.ask-cite-k{ font-size:12px; color:var(--ink-soft); letter-spacing:.02em; }
.ask-cite-v{ font-family:'JetBrains Mono',monospace; font-size:15px; color:var(--ink);
             font-weight:600; white-space:nowrap; }
.ask-cite-meta{ display:flex; align-items:baseline; justify-content:space-between;
                gap:.75rem; margin-top:.2rem; }
/* 同一组里后面几张贴紧一点 —— 它们是一个整体,不是四件独立的事 */
.ask-cite + .ask-cite{ margin-top:.3rem; }
.ask-cite-per{ font-family:'JetBrains Mono',monospace; font-size:9.5px;
               color:var(--ink-faint); white-space:nowrap; }
.ask-cite-go{ font-size:10px; color:var(--ink-faint); text-align:right; }

/* 行内引用:模型没把标记单独成行时的退路,不至于句子中间插一张卡 */
.ask-chip{ display:inline-flex; align-items:baseline; gap:.25rem; padding:.05rem .3rem;
           margin:0 .1rem; border-bottom:1px solid var(--brass); text-decoration:none;
           font-family:'JetBrains Mono',monospace; font-size:13.5px; color:var(--ink); }
.ask-chip i{ font-style:normal; font-size:9.5px; color:var(--ink-subtle); }

/* ── 追问 chip · FR-424b ──
   点一下就等于把那句话问出来。放在操作行**上面**:它是「接下来做什么」,
   比「复制/重来」更该被先看到。 */
.ask-nexts{ display:flex; flex-wrap:wrap; gap:.4rem; margin-top:.9rem; }
.ask-next{ font-size:12.5px; color:var(--ink); background:var(--paper);
           border:1px solid var(--rule); border-radius:999px; padding:.28rem .7rem;
           cursor:pointer; transition:border-color .15s, background .15s; }
.ask-next:hover{ border-color:var(--brass); background:var(--card-soft); }

/* ── 逐条操作 ──
   桌面上 hover 才浮现(不打扰阅读),手机上常驻(没有 hover 这回事)。 */
.ask-tools-row{ display:flex; gap:.15rem; margin-top:.55rem; margin-left:-.3rem;
                opacity:0; transition:opacity .15s; }
.ask-turn:hover .ask-tools-row, .ask-tools-row:focus-within{ opacity:1; }
@media (hover:none){ .ask-tools-row{ opacity:1; } }

.ask-mini{ display:inline-flex; align-items:center; gap:.28rem; font-size:11.5px;
           color:var(--ink-subtle); background:transparent; border:0; cursor:pointer;
           padding:.2rem .45rem; border-radius:4px; transition:color .15s, background .15s; }
.ask-mini:hover{ color:var(--ink); background:var(--card-soft); }
.ask-mini svg{ width:13px; height:13px; fill:none; stroke:currentColor; stroke-width:1.7;
               stroke-linecap:round; stroke-linejoin:round; }
.ask-mini.ok{ color:var(--forest); }

.ask-icon{ width:26px; height:26px; flex:none; display:inline-flex; align-items:center;
           justify-content:center; border:0; background:transparent; cursor:pointer;
           color:var(--ink-subtle); border-radius:5px; }
.ask-icon:hover{ color:var(--ink); background:var(--card-soft); }
.ask-icon svg{ width:15px; height:15px; fill:none; stroke:currentColor; stroke-width:1.7;
               stroke-linecap:round; stroke-linejoin:round; }

/* ── 空态:输入优先 ──
   Notion AI / Linear AI 那套:一句话 + 几条可点的问题,不上来就摊开历史。
   「空聊天窗」对非技术家庭成员是有压力的 —— 他不知道该问什么。 */
.ask-empty{ padding:2.2rem 0 1rem; }
.ask-empty-eyebrow{ color:var(--ink-soft); margin-bottom:.6rem; }
.ask-empty-lead{ font-family:'Noto Serif SC',serif; font-size:22px; color:var(--ink);
                 margin:0 0 .35rem; }
.ask-empty-sub{ font-size:13.5px; color:var(--ink-soft); line-height:1.7;
                margin:0 0 1.3rem; max-width:34em; }   /* 34em ≈ 30 个汉字:42ch 只放得下 21 个,末行会剩「页核对。」四个孤字 */
/* 窄屏不限宽:42ch 在 390px 上会把「页核对。」挤成孤零零的第二行 */
@media (max-width:520px){ .ask-empty-sub{ max-width:none; } }
.ask-presets{ display:flex; flex-direction:column; gap:.5rem; align-items:flex-start; }
.ask-preset{ text-align:left; font-size:13.5px; color:var(--ink); background:var(--paper);
             border:1px solid var(--rule); border-radius:8px; padding:.5rem .8rem;
             cursor:pointer; max-width:100%;
             transition:border-color .15s, background .15s, transform .15s; }
.ask-preset:hover{ border-color:var(--brass); background:var(--card-soft); transform:translateX(2px); }

.ask-recent{ margin-top:2rem; padding-top:1.2rem; border-top:1px solid var(--rule-soft); }
.ask-recent .eyebrow{ color:var(--ink-subtle); margin-bottom:.5rem; }
.ask-recent-list{ display:flex; flex-wrap:wrap; gap:.35rem; }
.ask-recent-list a{ font-size:12px; color:var(--ink-soft); text-decoration:none;
                    border:1px solid var(--rule); border-radius:999px; padding:.2rem .6rem;
                    max-width:15rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ask-recent-list a:hover{ border-color:var(--brass); color:var(--ink); }

/* ── 未启用 ── */
.ask-blocked{ display:flex; align-items:flex-start; gap:.6rem; margin:1rem;
              padding:.9rem 1rem; border:1px solid var(--rule); border-radius:8px;
              background:var(--card-soft); font-size:13px; line-height:1.7;
              color:var(--ink-soft); }
.ask-blocked svg{ flex:none; margin-top:.25rem; }
.ask-blocked a{ display:inline-block; margin-top:.4rem; color:var(--ink); }

/* ── 输入区 ──
   **必须贴底、不能浮动** —— 盖住最后一条消息是这类界面最常见的手机端 bug。 */
.ask-composer-wrap{ flex:none; border-top:1px solid var(--rule); padding:.6rem 1rem .5rem;
                    background:var(--paper); }
.ask-composer-wrap.is-off{ opacity:.5; pointer-events:none; }
.ask-composer{ display:flex; align-items:flex-end; gap:.5rem;
               border:1px solid var(--rule); border-radius:10px;
               padding:.35rem .35rem .35rem .7rem; background:var(--paper);
               transition:border-color .15s; }
.ask-composer:focus-within{ border-color:var(--brass); }
.ask-composer textarea{ flex:1; resize:none; background:transparent; border:0; outline:none;
                        font-size:14.5px; line-height:1.65; color:var(--ink);
                        padding:.4rem 0; max-height:7rem; font-family:inherit; }
.ask-composer textarea::placeholder{ color:var(--ink-subtle); }
.ask-composer button{ flex:none; width:32px; height:32px; border-radius:8px; border:0;
                      display:inline-flex; align-items:center; justify-content:center;
                      background:var(--ink); color:var(--paper); cursor:pointer;
                      transition:opacity .15s; }
.ask-composer button:disabled{ opacity:.35; cursor:default; }
/* 属性选择器必须写在 display 规则之后,否则 [hidden] 的 display:none 被 inline-flex 盖掉 ——
   实测:停止键和发送键并排出现在输入框右边,一黑一红。 */
.ask-composer button[hidden]{ display:none; }
.ask-composer button svg{ width:16px; height:16px; fill:none; stroke:currentColor;
                          stroke-width:1.9; stroke-linecap:round; stroke-linejoin:round; }
/* 停止键用 rust:它是「中断」,不该和「发送」同色让人误点 */
.ask-composer button[data-ask-stop]{ background:var(--rust); }
.ask-composer button[data-ask-stop] svg{ fill:currentColor; stroke:none; }

.ask-foot{ display:flex; flex-wrap:wrap; align-items:center; gap:.3rem;
           font-size:10.5px; color:var(--ink-subtle); padding:.4rem .2rem .1rem; }
.ask-foot-sep{ opacity:.5; }

/* ── PC 抽屉 ──
   不打断当前页:用户正在看仪表盘时问「这个数怎么来的」,底下那页得留在原地。 */
/* text-align:left 是必须的:抽屉挂在 layout::footer 里,而那个 footer 带 text-center,
   不显式覆盖的话空态标题、说明、「最近」全部继承成居中,和左对齐的按钮列拧着。 */
.ask-drawer{ text-align:left;
             position:fixed; top:0; right:0; bottom:0; width:min(460px,94vw); z-index:45;
             background:var(--paper); border-left:1px solid var(--rule);
             box-shadow:-14px 0 40px rgba(26,23,20,.10);
             transform:translateX(100%); transition:transform .22s ease;
             display:flex; flex-direction:column; }
.ask-drawer.open{ transform:translateX(0); }
.ask-drawer > *{ min-height:0; }
/* 抽屉里列宽由容器决定,不再受 768 限制(它本来就只有 460) */
.ask-drawer .ask-col{ max-width:none; }
.ask-drawer .ask-msgs{ padding-left:.9rem; padding-right:.9rem; }
.ask-drawer .ask-body{ font-size:14px; }

/* 悬浮入口:常驻但不打扰 —— 不主动弹、不推送,只是一直在那儿 */
.ask-fab{ position:fixed; right:20px; bottom:22px; z-index:44; display:inline-flex;
          align-items:center; gap:.4rem; padding:.55rem .85rem; border-radius:999px;
          border:1px solid var(--rule); background:var(--paper); color:var(--ink);
          box-shadow:0 3px 14px rgba(26,23,20,.12); font-size:12.5px; letter-spacing:.06em;
          cursor:pointer; transition:border-color .15s, box-shadow .15s; }
.ask-fab:hover{ border-color:var(--brass); box-shadow:0 5px 20px rgba(26,23,20,.16); }
html.ask-open .ask-fab{ opacity:0; pointer-events:none; }
body.ask-page .ask-fab{ display:none; }

/* 全局浮钮 dock(隐私眼 / 横屏 / 目录)在这一页**藏掉**,隐私切换收进顶栏。
   过程值得记,因为「挪个位置」这个直觉是错的 —— 挪到哪儿都挡:
     · 原位右下 → 压住发送键,而输入框是这一页的主操作;
     · 抬高 96px → 压住引用卡右侧的金额(实测挡掉了「¥1,234,568」的后三位);
     · 再挪到左侧 → 压住引用卡左侧的指标名。
   根因是这一页**内容铺满、左右都有要读的东西**(左指标名、右数值),
   而 position:fixed 的浮层不给内容让位。所以不是找位置,是不该用浮层:
   隐私钮进顶栏(那里本来就有空位),目录钮这一页没有,横屏钮让位。 */
body.ask-page #float-dock{ display:none !important; }

/* 顶栏里的隐私切换 —— 只在触摸设备上出现,和被藏掉的 dock 是同一个条件。
   PC 的导航栏本来就有隐私钮,这里再放一个是重复。 */
.ask-priv{ display:none; }
@media (pointer:coarse){ .ask-priv{ display:inline-flex; } }
html.privacy .ask-priv{ color:var(--ink); background:var(--card-soft); }
/* 手机上不要悬浮球:屏幕小,它会压住底部的表格和按钮。移动端走导航里的整页入口 */
@media (max-width:767px){ .ask-fab{ display:none; } }

/* 隐私模式:只糊**金额**,不糊百分比/月数/条数。
   一刀切的后果实测很难看:饼图上的百分比清清楚楚,正文里同一批百分比却是糊的。
   金额型的值在渲染时挂了 data-priv,直接吃全站那条规则(顺带白得「长按临时查看」)。
   图表 canvas 没法局部糊,所以整块判断:datalabels 里有金额的那些图整张糊。 */
html.privacy .ask-chart[data-priv-chart] canvas{ filter:blur(6px); }

/* 减少动效:光标与脉冲都停掉,但**不隐藏光标** —— 它承载「还在生成」这个信息 */
@media (prefers-reduced-motion:reduce){
  .ask-caret-live, .ask-dot.run, .ask-wait::before{ animation:none; }
}

/* ── 思考过程 · 流式进行中 ────────────────────────────────────────────────
   与历史里那份**同一套 DOM**,只是多一个 .live 态。
   进行中默认展开:用户想看的正是「它在查什么」;跑完了再自动收起 ——
   除非他中途做了查看动作(翻页 / 点击 / 选中 / 停在这一栏上),那说明他在读,
   收起就是把他正在看的东西抢走。 */
.ask-acts.live{ border-left:2px solid var(--brass-soft); padding-left:.6rem; margin-left:-.1rem; }
.ask-acts.live > summary{ color:var(--ink-soft); }
.ask-acts.live .ask-acts-body{ border-left:0; padding-left:0; margin-left:0; }
/* 自动收起时闪一下,让用户知道「它收起来了、还能点开」 */
@keyframes ask-fold{ 0%{ background:var(--brass-soft) } 100%{ background:transparent } }
.ask-acts.folded > summary{ animation:ask-fold 1.1s ease-out; border-radius:4px; }

.ask-act{ padding:.18rem 0; }
.ask-act-head{ display:flex; align-items:center; gap:.45rem; font-size:11.5px; color:var(--ink-soft); }
.ask-act-name{ color:var(--ink-soft); }
.ask-act-args{ margin-left:.95rem; font-family:'JetBrains Mono',monospace; font-size:10px;
               color:var(--ink-faint); line-height:1.6; word-break:break-all; }
.ask-act-sum{ margin-left:.95rem; font-size:11px; color:var(--ink-subtle); line-height:1.6; }
/* 思考里的旁白(模型调工具前说的那句)—— 是句子,不是键值,所以不用等宽 */
.ask-act-say{ margin:.25rem 0 .35rem .95rem; font-size:11.5px; color:var(--ink-subtle);
              line-height:1.7; }

/* ── 富展示:图表与自由 HTML ──────────────────────────────────────────────
   模型能自由发挥的是**形式**,不是数据 —— 图上每个点都来自工具返回的引用值。
   所以这两样在版面上比引用卡轻:引用卡是「凭证」,图是「看个形状」。 */
.ask-chart{ margin:.9rem 0; padding:.7rem .8rem .5rem;
            border:1px solid var(--rule); border-radius:6px; background:var(--card-soft); }
.ask-chart-title{ font-size:12px; color:var(--ink-soft); margin-bottom:.5rem; letter-spacing:.02em; }
.ask-chart-canvas{ position:relative; height:210px; }
@media (max-width:520px){ .ask-chart-canvas{ height:190px; } }

.ask-artifact{ margin:.9rem 0; padding:0; border:1px solid var(--rule); border-radius:6px;
               background:var(--card-soft); overflow:hidden; }
.ask-artifact iframe{ display:block; width:100%; height:180px; border:0; background:transparent;
                      transition:height .18s ease; }
.ask-artifact figcaption{ font-size:10.5px; color:var(--ink-subtle);
                          padding:.3rem .7rem .45rem; border-top:1px solid var(--rule-soft); }
/* 隐私模式:自由 HTML 里的数字我们管不着(它在 iframe 里),整块糊掉最保险 */
html.privacy .ask-artifact iframe{ filter:blur(6px); }

/* ── 「AI 接入」· 百炼托管路线的分步向导 ──────────────────────────────────
   这一段以前只有三个空输入框,而其中两项要去阿里云控制台里翻才拿得到 ——
   「业务空间 ID」这种词对着一个空输入框是问不出来的。
   所以做成分步:谁做哪一步一眼看清,人工那几步各配一段可展开的实操说明
   (默认收起 —— 配过一次的人不需要再看第二遍)。 */
.ask-setup{ border-top:1px solid var(--rule); padding-top:.7rem; }
.ask-setup > summary{ cursor:pointer; font-size:12px; color:var(--ink-soft);
                      list-style:none; user-select:none; padding:.2rem 0; }
.ask-setup > summary::-webkit-details-marker{ display:none; }
.ask-setup > summary::before{ content:'▸'; display:inline-block; font-size:9px;
                              margin-right:.35rem; transition:transform .15s; }
.ask-setup[open] > summary::before{ transform:rotate(90deg); }
.ask-setup > summary:hover{ color:var(--ink); }

.ask-steps{ list-style:none; margin:.9rem 0 0; padding:0; counter-reset:askstep; }
.ask-steps > li{ display:flex; gap:.6rem; padding:.55rem 0;
                 border-top:1px solid var(--rule-soft); counter-increment:askstep; }
.ask-steps > li::before{ content:counter(askstep, decimal); flex:none;
                         width:1.35rem; height:1.35rem; line-height:1.3rem; text-align:center;
                         margin-top:.1rem; border:1px solid var(--rule);
                         border-radius:50%; font-family:'JetBrains Mono',monospace;
                         font-size:10px; color:var(--ink-soft); background:var(--paper); }
.ask-steps > li:first-child{ border-top:0; }
.ask-steps > li > div{ flex:1; min-width:0; }
.ask-steps b{ font-size:13px; color:var(--ink); }
.ask-steps p{ font-size:12px; color:var(--ink-soft); line-height:1.75; margin:.25rem 0 0; }
.ask-steps code{ font-family:'JetBrains Mono',monospace; font-size:11px;
                 background:var(--paper-soft); border:1px solid var(--rule-soft);
                 border-radius:3px; padding:0 .25rem; }

/* 「谁做这一步」—— 分步向导里最该一眼看清的一列:
   用户最怕的不是步骤多,是分不清哪几步要他自己动手 */
.ask-step-who{ flex:none; width:2.4rem; text-align:center; height:1.35rem; line-height:1.35rem;
               font-family:'JetBrains Mono',monospace; font-size:9.5px; letter-spacing:.04em;
               border-radius:3px; color:#fff; background:var(--brass-deep); margin-top:.1rem; }
.ask-step-who.ours{ background:var(--ink-subtle); }

/* 实操说明:默认收起 */
.ask-how{ margin-top:.5rem; }
.ask-how > summary{ display:inline-block; cursor:pointer; list-style:none; user-select:none;
                    font-size:11.5px; color:var(--brass-deep);
                    border-bottom:1px dashed var(--brass); padding-bottom:1px; }
.ask-how > summary::-webkit-details-marker{ display:none; }
.ask-how > summary:hover{ color:var(--ink); border-color:var(--ink-soft); }
.ask-how ol{ margin:.5rem 0 0; padding-left:1.15rem; }
.ask-how li{ font-size:12px; color:var(--ink-soft); line-height:1.8; margin:.2rem 0; }
.ask-how pre{ font-family:'JetBrains Mono',monospace; font-size:11px; line-height:1.6;
              background:var(--paper-soft); border:1px solid var(--rule-soft); border-radius:4px;
              padding:.5rem .6rem; margin:.4rem 0; overflow-x:auto; color:var(--ink-soft); }
.ask-how-note{ margin-top:.5rem !important; padding:.5rem .65rem; border-radius:4px;
               background:var(--card-soft); border-left:2px solid var(--brass);
               font-size:11.5px !important; line-height:1.8 !important; }
.ask-how-note a, .ask-steps a{ color:var(--ink); }

/* 诚实交代:这条路线我们没在真实环境验过。放在输入框**上面** ——
   放下面等于让人填完了才知道 */
.ask-caveat{ margin-top:.9rem; padding:.6rem .75rem; border-left:2px solid var(--rust);
             background:var(--rust-soft, rgba(164,85,47,.05));
             font-size:12px; line-height:1.8; color:var(--ink-soft); }
/* 「万一表单长得不一样」那类补充:比正文更弱,别和主步骤抢 */
.ask-how li.ask-how-alt{ color:var(--ink-subtle); font-size:11.5px; }

/* v1.19.7 · 接入方式的岔路口:百炼在这一步给四个选项,选错了后面全对不上
   (用户实测选了「插件」,被要求逐个填工具描述才发现走错了)。
   做成表格是因为**要对比**——只说「选 X」不够,得让人看见另外三个为什么不是。 */
.ask-how-lead{ margin:.1rem 0 .55rem !important; font-size:12px !important;
               line-height:1.8 !important; color:var(--ink-soft); }
.ask-how-tbl{ width:100%; border-collapse:collapse; margin:.1rem 0 .7rem;
              font-size:11.5px; line-height:1.75; }
.ask-how-tbl td{ border-top:1px solid var(--rule-soft); padding:.4rem .5rem .4rem 0;
                 color:var(--ink-subtle); vertical-align:top; }
.ask-how-tbl td:first-child{ width:11.5rem; color:var(--ink-soft); padding-right:.9rem; white-space:nowrap; }
.ask-how-tbl tr:first-child td{ border-top:0; color:var(--ink-soft); }
.ask-how-tbl tr:first-child td:first-child{ color:var(--brass-deep); }
@media (max-width:640px){
  /* 窄屏两列会挤成一条线,改成上下堆叠 */
  .ask-how-tbl td{ display:block; padding:.15rem 0; border-top:0; }
  .ask-how-tbl td:first-child{ width:auto; padding-top:.5rem; border-top:1px solid var(--rule-soft); }
  .ask-how-tbl tr:first-child td:first-child{ border-top:0; }
}
/* 出处行:比 note 再弱一档,它是给想自己核对的人看的 */
.ask-how-src{ border-left-color:var(--rule) !important; color:var(--ink-subtle); }
