/* ============================================================
   专业心理测评 · 设计系统 v2（iOS 原生感）
   ------------------------------------------------------------
   ★ 本文件是**设计变量的唯一来源**。`web/views/detail.css` 与任何视图
     都不得重定义本文件里的变量（作业卡 §7.8）。

   语言：iOS 原生分组列表。
     · 灰底页面 + 白卡片；**层次靠底色、留白、字重、hairline，不靠边框。**
     · 大标题（large title）起头，正文用分组内嵌列表（inset grouped list）。
     · **单一强调色 = 系统蓝**，克制使用；文字用 `--accent-text`（对比度达标），
       填充用 `--accent`（iOS 原生观感），两者同色相、已在 docs/设计系统-v2.md 记录对比度。
     · 移动端优先：主操作通栏、触控目标 ≥ 44px、尊重安全区。
     · 所有横向布局的 flex/grid 子项一律 min-width:0 ——
       否则 nowrap 的长文本会把整页撑宽（移动端实测踩过的坑）。
     · prefers-color-scheme / prefers-reduced-motion 均已尊重。

   ★ 兼容铁律（作业卡 §7.9）：**只新增变量、只调数值**；
     不删除、不重命名任何已有类名与变量 —— 并行的视图线正在用它们。

   ★ 2026-09-15 第二阶段收口（执行线 `UIv2-设计系统与共享样式收口`）：
     5 条视图线已全部停手，**唯一一次**对"不删类名"的例外是两个被施工单点名、
     且 grep 全仓证实**零引用**的废弃类（`.is-method__lede` / `.is-crisis-quick`）——
     动作与证据见 `docs/设计系统-v2.md` §7 / §9。
     本次新增两个类：`.is-prose`（卡片内长正文排版）、`.is-input`（文本输入框）；
     并把 `.is-hero__title` 的 30px 档从「只在 `.view--home`」放开到**六个视图同档**。
   ============================================================ */

:root {
  /* ── 中性色 ── */
  --bg: #f2f2f7;
  --bg-raised: #ffffff;
  --surface: #ffffff;
  --surface-2: #f2f2f4;
  --surface-3: #e8e8ed;
  --text: #1d1d1f;
  /* 对比度已实测（docs/设计系统-v2.md §1.4）：
     text-2 #56565a = 白底 7.1:1 / 灰底 6.6:1；text-3 #6e6e73 = 白底 5.1:1 / 灰底 4.7:1。
     两者都 ≥ 4.5:1，因此 `.muted` / `.small` / 徽章正文等**小字也可安全使用**。 */
  --text-2: #56565a;
  --text-3: #6e6e73;
  --muted: #56565a;         /* 兼容别名（指向 text-2） */
  --border: #d8d8dc;
  --border-strong: #c6c6cb;
  --separator: #d8d8dc;
  --separator-opaque: #c6c6cb;

  /* ── 唯一强调色：iOS 系统蓝 ──
     `--accent`        = Apple 系统蓝 #0A84FF（填充用：进度、连续谱、选中态、深色下主按钮底色）
     `--accent-text`   = 同色相的深一档蓝 #0066CC，用于**文字与链接**（白底 5.6:1 / 灰底 5.1:1，
                         白字压在其上的填充也 ≥ 5.1:1）—— 系统蓝直接当正文色只有 3.4:1，不合格。 */
  --accent: #0a84ff;
  --accent-text: #0066cc;
  --accent-bg: #e8f2fd;
  --accent-soft: #e8f2fd;   /* 兼容别名 */
  --accent-border: #b6d8fb; /* 保留（兼容旧引用） */
  --btn-on-accent: #ffffff; /* 强调色填充上的文字色（小字也 ≥ 5.5:1） */

  /* ── 语义色 ── */
  --warn: #8a6512;
  --warn-bg: #fdf7e9;
  --warn-soft: #fdf7e9;     /* 兼容别名 */
  --warn-border: #ecdcb0;   /* 保留（兼容旧引用） */
  --danger: #b3261e;
  --danger-bg: #fdf0ef;
  --danger-soft: #fdf0ef;   /* 兼容别名 */
  --danger-border: #f0c9c6; /* 保留（兼容旧引用） */
  --ok: #1d6b3a;
  --ok-bg: #edf6f0;

  /* ── 圆角阶梯（iOS 近似：10 / 12 / 14 / 18） ── */
  --r-xs: 8px;
  --r-sm: 10px;
  --r: 12px;
  --r-md: 14px;
  --r-lg: 18px;
  --r-full: 999px;
  --radius: 12px;           /* 兼容别名 */
  --radius-sm: 8px;         /* 兼容别名 */

  /* ── 间距阶梯（4pt 网格）
     ★ 排版节奏纪律（2026-09-15）：块与块之间的**纵向**间距只许取本阶梯的值，
       不要再手写 22px / 14px / 10px / 3px 这类网格外数字。
       实测过 14 种块间距，用户看到的「有的挨得紧、有的空得很开」就是它造成的。 */
  --sp-0: 0px;
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 24px; --sp-6: 32px; --sp-7: 48px;
  /* 分组节奏：同组内相邻块 / 卡片之间 / 分组之间。
     比 --sp-3 / --sp-4 / --sp-6 更明确地表达「这三档是一套节奏」，
     数值与阶梯同源，不是新数字。 */
  --rhythm-row: var(--sp-3);      /* 12px：同一块内的相邻行/段 */
  --rhythm-block: var(--sp-4);    /* 16px：卡片之间、小节之间 */
  --rhythm-group: var(--sp-6);    /* 32px：分组（.section）之间 */
  /* 徽章网格的**列宽上限**：≈ 两枚中位徽章的自然宽（95–126px）。
     375px 下 311px 可用宽 ⇒ 正好 2 列（用户要的「不许一枚孤零零换行」）；
     桌面 512px ⇒ 3 列。命名而非裸写，是为了让它可被引用、可被审计。 */
  --badge-col: 8.5rem;
  --space-1: 4px;  --space-2: 8px;  --space-3: 12px; --space-4: 16px;
  --space-5: 24px; --space-6: 32px; /* 兼容别名 */
  --sp-inset: 16px;         /* 分组列表距屏幕边缘的内缩（inset grouped list） */
  --sp-row: 11px;           /* 列表行的纵向内边距，配合 min-height 凑 44px */
  /* 历史遗留：`detail.css` 的 `:root` 块里有同名常量（`--b-` 前缀，B 线局部）。
     本线按作业卡 §7.8「变量只许定义在 styles.css」把它们抄进来一份，
     使 `detail.css` 那个 `:root` 块变成可安全移除的冗余（见 docs/设计系统-v2.md §6）。 */
  --b-edge: 6px;
  --b-tap: 44px;

  /* ── 字体 ── */
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "PingFang SC",
    "Hiragino Sans GB", "Noto Sans SC", "Microsoft YaHei", "Segoe UI", sans-serif;
  --font-num: ui-monospace, "SF Mono", "SFMono-Regular", Menlo, Consolas, monospace;

  /* 字号阶梯（iOS 近似，pt → px 1:1） */
  --fs-largetitle: 30px;    /* 大标题：视图首屏 */
  --fs-title1: 26px;
  --fs-title2: 21px;
  --fs-title3: 19px;
  --fs-headline: 17px;      /* 卡片标题 / 强调正文 */
  --fs-body: 16px;          /* 正文 */
  --fs-callout: 16px;       /* 与正文同档：曾经是 15.5px，全站实测出 15/15.5/16/16.5 四级同名角色 */
  --fs-subhead: 14.5px;
  --fs-footnote: 13px;      /* 依据细节、页脚 */
  --fs-caption: 12px;
  /* 危机页主号码 12356 专用档：**全站唯一大于 30px 的字号**。
     单开一个具名 token 而不是裸写 40px，是为了让「有没有第二处超规格字号」
     变成可 grep 的事实（安全红线要求 12356 必须是首屏绝对主角，见 §3.5）。 */
  --fs-crisis-hero: 40px;
  /* 行高阶梯（★ 2026-09-15 补 --lh-display；此前只有 4 档，实测散出 21 种比值，见设计系统 §1.4 决策表） */
  --lh-display: 1.12;       /* 30px 大标题专用 */
  --lh-tight: 1.2;          /* 40px 级数字/大号强调 */
  --lh-snug: 1.35;          /* 标题族（h1/h2/h3/卡片标题/单行 UI 标签） */
  --lh-normal: 1.47;        /* 正文基准（body 默认）+ 可交互控件 */
  --lh-relaxed: 1.6;        /* 长文段（≥3 行的说明、清单、依据正文） */
  /* 字重阶梯 */
  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semibold: 600;
  /* 字距阶梯 */
  --ls-title: -0.03em;
  --ls-head: -0.02em;
  --ls-body: -0.011em;
  --ls-caps: 0.05em;

  /* ── hairline 分隔线（Retina 上 0.5px；不支持时回落 1px） ── */
  --hairline: 0.5px;
  --hairline-fallback: 1px;

  /* ── 克制阴影：iOS 卡片几乎不用阴影，这里只给浮层用 ── */
  --shadow-none: none;
  --shadow-card: 0 1px 2px rgb(0 0 0 / 4%);
  --shadow-sheet: 0 -1px 24px rgb(0 0 0 / 12%);
  --shadow-pop: 0 8px 28px rgb(0 0 0 / 14%);

  /* ── 动效（prefers-reduced-motion 下统一关闭，见文件末尾） ── */
  --dur-fast: 120ms;
  --dur-mid: 180ms;
  --dur-slow: 250ms;
  --ease: cubic-bezier(0.32, 0.72, 0, 1);   /* iOS 近似的减速曲线 */

  --measure: 38rem;
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #000000;
    --bg-raised: #1c1c1e;
    --surface: #1c1c1e;
    --surface-2: #2c2c2e;
    --surface-3: #3a3a3c;
    --text: #f5f5f7;
    --text-2: #a1a1a6;
    --text-3: #8e8e93;
    --muted: #a1a1a6;
    --border: #38383a;
    --border-strong: #48484a;
    --separator: #38383a;
    --separator-opaque: #48484a;

    --accent: #0a84ff;
    --accent-text: #0a84ff;
    --accent-bg: #10243d;
    --accent-soft: #10243d;
    --accent-border: #1d3d63;
    --btn-on-accent: #14161a;

    --warn: #e0bc6a;
    --warn-bg: #33290f;
    --warn-soft: #33290f;
    --warn-border: #4d3f1a;
    --danger: #ff6b60;
    --danger-bg: #3a1a17;
    --danger-soft: #3a1a17;
    --danger-border: #5c2a25;
    --ok: #6fce93;
    --ok-bg: #16301f;

    --shadow-card: none;
    --shadow-sheet: 0 -1px 24px rgb(0 0 0 / 60%);
    --shadow-pop: 0 8px 28px rgb(0 0 0 / 60%);
  }
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: var(--lh-normal);
  letter-spacing: var(--ls-body);
  font-weight: var(--fw-regular);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-wrap: break-word;
}

/* 链接用 `--accent-text`（可达对比度），不用填充色 `--accent`。 */
a { color: var(--accent-text); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 99;
  background: var(--accent-text); color: var(--btn-on-accent); padding: var(--sp-2) var(--sp-4);
  border-radius: var(--r-sm);
}
.skip-link:focus { left: var(--sp-2); top: var(--sp-2); }

/* ─────────────────────────────────────────── 顶栏 / 页脚 */

.topbar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3);
  padding: calc(var(--safe-t) + 10px) calc(var(--sp-inset) + var(--safe-r)) 10px calc(var(--sp-inset) + var(--safe-l));
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom: var(--hairline) solid var(--separator);
}
.topbar__brand {
  font-size: var(--fs-headline); font-weight: var(--fw-semibold); color: var(--text);
  text-decoration: none; letter-spacing: var(--ls-head);
}
.topbar__brand:hover { text-decoration: none; }
.topbar__nav { display: flex; gap: var(--sp-4); font-size: var(--fs-subhead); flex: 0 0 auto; }
.topbar__nav a { color: var(--text-2); }
.topbar__nav a:hover { color: var(--accent-text); text-decoration: none; }

.footer {
  max-width: var(--measure); margin: var(--sp-6) auto 0;
  padding: var(--sp-5) calc(var(--sp-inset) + var(--safe-r)) calc(var(--sp-7) + var(--safe-b)) calc(var(--sp-inset) + var(--safe-l));
  border-top: var(--hairline) solid var(--separator);
  color: var(--text-3); font-size: var(--fs-footnote); line-height: var(--lh-relaxed);
}
.footer p { margin: 0 0 var(--sp-3); }
.footer strong { color: var(--text-2); font-weight: var(--fw-semibold); }

/* ─────────────────────────────────────────── 视图容器 */

.view {
  max-width: var(--measure);
  margin: 0 auto;
  padding: var(--sp-2) calc(var(--sp-inset) + var(--safe-r)) calc(var(--sp-6) + var(--sp-2)) calc(var(--sp-inset) + var(--safe-l));
}

/* ─────────────────────────────────────────── 排版
   字号/行高/字重一律走变量 —— 视图线不要再写裸 px（除非是 1px 级微调）。
   ★ 2026-09-15「全站排版一致性」线：本节的间距是**全站节奏的锚**。
     此前 `p { margin-bottom: 12px }` 与 `.is-card-head > * + * { margin-top: 2px }`
     并存，实测出 14 种相邻块缝隙（0/1/1.8/2/4/6/8/12/16/24/28/32/44…）；
     现在统一成三档：组内 12、块间 16、分组间 32（见 `--rhythm-*`）。 */

h1 { font-size: var(--fs-title1); line-height: var(--lh-snug); font-weight: var(--fw-semibold); letter-spacing: var(--ls-title); margin: 0 0 var(--sp-3); }
h2 { font-size: var(--fs-title3); line-height: var(--lh-snug); font-weight: var(--fw-semibold); letter-spacing: var(--ls-head); margin: 0 0 var(--sp-2); }
h3 { font-size: var(--fs-headline); line-height: var(--lh-snug); font-weight: var(--fw-semibold); letter-spacing: var(--ls-body); margin: 0 0 var(--sp-2); }
p { margin: 0 0 var(--sp-3); }
p:last-child { margin-bottom: 0; }
ul, ol { margin: 0 0 var(--sp-3); padding-left: 1.25em; }
/* 清单行间不额外加缝：行高的 1.6 已经给了呼吸，再加 margin 会让清单比正文松一档。 */
li { margin-bottom: 0; }

.muted { color: var(--text-2); }
.small { font-size: var(--fs-footnote); line-height: var(--lh-relaxed); }
.strong { font-weight: var(--fw-semibold); }
.center { text-align: center; }
.stack > * + * { margin-top: var(--sp-4); }
.row { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; min-width: 0; }
.row > * { min-width: 0; }
.row--between { justify-content: space-between; }
.row--end { justify-content: flex-end; }

.grid { display: grid; gap: var(--sp-3); }
.grid--2 { grid-template-columns: 1fr; }
.grid--3 { grid-template-columns: 1fr; }
@media (min-width: 700px) {
  .grid--2 { grid-template-columns: 1fr 1fr; }
  .grid--3 { grid-template-columns: repeat(3, 1fr); }
}

/* ─────────────────────────────────────────── 卡片 / 分组内嵌列表
   白卡片浮在灰底上，没有边框也没有阴影 —— 这是整套视觉语言的支点。
   ★ iOS「inset grouped list」：卡片本身承担分组，组与组之间留 22px 以上，
     组名用 `.section__title` 写在小字灰字里、贴在组的上方。 */

.card {
  background: var(--bg-raised);
  border-radius: var(--r-lg);
  padding: var(--sp-4);
  min-width: 0;
  box-shadow: var(--shadow-none);
}
.card + .card { margin-top: var(--rhythm-block); }
.card--warn { background: var(--warn-bg); }
.card__title { margin: 0 0 var(--sp-1); font-size: var(--fs-headline); font-weight: var(--fw-semibold); letter-spacing: var(--ls-head); line-height: var(--lh-snug); }
/* 副标题默认不再自带下边距：iOS 分组卡里，标题与副标题是一个紧凑的头部块，
   与正文之间靠 hairline 或留白分层。保留 margin 会把它和正文推得太开。 */
.card__subtitle { margin: 0; color: var(--text-2); font-size: var(--fs-footnote); line-height: var(--lh-relaxed); }
.card__body { min-width: 0; }
.card__body > *:last-child { margin-bottom: 0; }
.card__footer { margin-top: var(--sp-4); padding-top: var(--sp-3); border-top: var(--hairline) solid var(--separator); }

/* 卡片头部信息块：副标题 / 事实行 / 辅助行之间只留 4px，成为一个整体。 */
.is-card-head { min-width: 0; }
.is-card-head > * + * { margin-top: var(--sp-1); }

/* 事实行：`120 题 · 约 12–15 分钟` 这类硬事实，比依据更显眼、比标题弱。 */
.is-facts {
  margin: 0; color: var(--text); font-size: var(--fs-subhead);
  font-weight: var(--fw-medium); line-height: var(--lh-snug);
  letter-spacing: var(--ls-body); min-width: 0;
}
/* 辅助行：构念 / 时间窗 / 作答顺序等补充事实。 */
.is-meta {
  margin: 0; color: var(--text-2); font-size: var(--fs-footnote);
  line-height: var(--lh-relaxed); min-width: 0;
}

.section { margin: var(--rhythm-group) 0; min-width: 0; }
.section__title {
  font-size: var(--fs-footnote); font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-caps); text-transform: none;
  color: var(--text-2); margin: 0 0 var(--sp-2); padding-left: var(--sp-2);
}
.section__note { color: var(--text-2); font-size: var(--fs-footnote); line-height: var(--lh-relaxed); margin: calc(-1 * var(--sp-1)) 0 var(--sp-3); padding-left: var(--sp-2); }
.section__body { min-width: 0; }
.section__body > *:last-child { margin-bottom: 0; }

/* ─────────────────────────────────────────── 按钮 */

.btn {
  appearance: none; -webkit-appearance: none;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: 44px; padding: 11px 20px;
  font: inherit; font-size: var(--fs-headline); font-weight: var(--fw-medium); letter-spacing: var(--ls-body);
  border-radius: var(--r); border: 0;
  background: var(--surface-2);
  color: var(--text);
  cursor: pointer; text-decoration: none;
  transition: opacity var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
  -webkit-tap-highlight-color: transparent;
  text-align: center;
}
.btn:hover { text-decoration: none; opacity: .88; }
.btn:active { opacity: .72; }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn[disabled], .btn:disabled { opacity: .35; cursor: not-allowed; }

/* 主按钮用 `--accent-text`（#0066CC）而不是系统蓝本身：
   系统蓝配白字只有 3.65:1，达不到正文 4.5:1；深一档蓝是 5.57:1（docs/设计系统-v2.md §1.4）。 */
.btn--primary { background: var(--accent-text); color: #fff; }
.btn--ghost { background: transparent; color: var(--accent-text); padding-inline: 8px; }
.btn--danger { background: var(--danger-bg); color: var(--danger); }
.btn--block { width: 100%; }

/* 手机上主操作通栏，拇指够得着 */
@media (max-width: 699px) {
  .btn--block-mobile,
  .card > .btn--primary,
  .card__body > .btn--primary,
  .is-foot > .btn--primary,
  .is-consent-foot > .btn--primary { width: 100%; }
}

/* ─────────────────────────────────────────── 证据徽章
   无边框、无 emoji —— 图标是内联 SVG（见 components/index.js），随文字颜色。
   ★ 关键：min-width:0 + 允许换行，否则 nowrap 的长授权名会撑宽整页。 */

.is-badge-row, .is-badges {
  /* ★ 2026-09-15：`flex-wrap` → `auto-fill` 网格。
     原因是徽章瘦身后热区靠伪元素外扩，而 flex 的 `row-gap` 与外扩量会互相打架：
     行距 12px 时上下两行的热区重叠 8px，`elementFromPoint` 会把下面那枚的
     顶部若干像素判给上面那枚（实测热区 46 → 37px，跌破 44px 底线）。
     网格把行距与列距分开表达：行距取 `--sp-5`（24px）⇒ 行距 26+24=50px，
     比 `-10px × 2` 的外扩量（20px）还富余 4px，逐像素实测 46px 达标且互不重叠
     （行距取 16px 时实测只有 41px —— 下面那枚的热区把上面那枚的底边 5px 抢走了）。
     列宽上限走 `--badge-col`（8.5rem ＝ 中位徽章的自然宽），长授权名靠 `.pill__label`
     的 ellipsis 收在格子里（不会撑破页面）。 */
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--badge-col)), 1fr));
  gap: var(--sp-5) var(--sp-4);
  margin-bottom: var(--rhythm-block); min-width: 0;
}
.is-badge-row > *, .is-badges > * { min-width: 0; }
/* ★ 徽章不许被栅格拉宽：`.pill` 是 `inline-block`，在 grid 单元格里默认会被
   `1fr` 拉满（实测自然宽 95px 的「文献依据」被拉成 148px，一眼又变成大按钮）。
   `justify-self: start` 把它钉回内容宽，单元格只负责给列宽。 */
.is-badge-row > .pill, .is-badges > .pill { justify-self: start; }

.pill {
  display: inline-block;            /* 收缩到内容宽，不被 block/栅格撑满整行 */
  vertical-align: middle;
  max-width: 100%; min-width: 0;
  background: var(--surface-2);
  border: 0; border-radius: var(--r-full);
  font-size: var(--fs-footnote); line-height: var(--lh-snug);
  /* ★ 徽章瘦身（2026-09-15）：视觉盒交回给内容，热区由 `.pill__summary::after` 撑到 44px。
     不要在 `.pill` 上加 overflow:hidden —— 那会把伪元素热区一起裁掉。 */
  position: relative;
}
.pill[open] { border-radius: var(--r); }
.pill__summary {
  /* ★ 垂直居中（2026-09-15 定稿）：`display: inline-flex` + `align-items: center`，
     padding 上下**对称**（`var(--sp-1)`）。
     试过用「上 3.75 / 下 4」做光学补偿，实测把报告页「局限」从 0.75px 改坏到 1.75px
     ——行盒偏差与中文字形墨迹偏差方向相反，单方向 padding 只能按下葫芦浮起瓢。
     两处会覆盖 `display` 的移动端规则（detail.css）必须一并重申 `align-items: center`。 */
  cursor: pointer; padding: var(--sp-1) var(--sp-3); list-style: none;
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--text-2); min-width: 0; max-width: 100%;
  /* 只允许单行截断，绝不 nowrap 硬撑宽度 */
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pill__summary::-webkit-details-marker { display: none; }
/* ★ 热区外扩（2026-09-15）：视觉高约 26px，`inset: -9px` 把命中区撑回 44px。
   方向只往纵向，横向只外扩 2px —— 一行里几枚徽章之间只隔 `--rhythm-row`，
   横向外扩多了会互相抢点击。实测见 docs/设计系统-v2.md §2.5。 */
.pill__summary::after { content: ''; position: absolute; inset: -10px -2px; }
.pill__summary:hover { color: var(--text); }
.pill__icon { flex: 0 0 auto; display: inline-flex; align-items: center; }
.pill__icon svg { width: 14px; height: 14px; display: block; }
.pill__label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.pill__body {
  padding: var(--sp-1) var(--sp-4) var(--sp-4); max-width: 32rem;
  color: var(--text-2); font-size: var(--fs-footnote); line-height: var(--lh-relaxed);
  overflow-wrap: anywhere;
}
.pill__body p { margin: 0 0 var(--sp-2); }
.pill__body p:last-child { margin-bottom: 0; }
.pill__link { font-size: var(--fs-footnote); display: inline-block; margin-top: var(--sp-0); }

.pill--citation { background: var(--accent-bg); }
.pill--citation .pill__summary { color: var(--accent-text); }
.pill--limitation { background: var(--warn-bg); }
.pill--limitation .pill__summary { color: var(--warn); }

/* ─────────────────────────────────────────── 为什么折叠块 */

.why {
  background: var(--surface-2);
  border-radius: var(--r);
  margin: var(--sp-3) 0;
  overflow: hidden; min-width: 0;
}
.why__q {
  cursor: pointer; padding: 13px 15px; list-style: none;
  font-size: var(--fs-body); font-weight: var(--fw-medium); color: var(--accent-text);
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); min-width: 0;
}
.why__q::-webkit-details-marker { display: none; }
.why__q::after {
  content: ''; flex: 0 0 auto; width: 7px; height: 7px;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translateY(-2px); opacity: .55;
  transition: transform .18s ease;
}
.why[open] .why__q::after { transform: rotate(-135deg) translateY(-2px); }
.why__a { padding: 0 var(--sp-4) var(--sp-4); font-size: var(--fs-body); line-height: var(--lh-relaxed); color: var(--text-2); min-width: 0; }
.why__a > *:last-child { margin-bottom: 0; }
.why__a p { margin: 0 0 var(--sp-3); }
.why__a .strong, .why__a strong { color: var(--text); }
.why__a blockquote {
  margin: var(--sp-3) 0; padding: var(--sp-3) var(--sp-4);
  background: var(--bg-raised); border-radius: var(--r-sm);
  color: var(--text); font-size: var(--fs-callout); line-height: var(--lh-snug);
}
.why__a pre {
  background: var(--bg-raised) !important; border-radius: var(--r-sm);
  font-family: var(--font-num); font-size: var(--fs-caption); line-height: var(--lh-snug);
  max-width: 100%; overflow-x: auto;
}

/* ─────────────────────────────────────────── 连续谱 ★ */

.continuum { margin: var(--sp-5) 0; min-width: 0; }
.continuum__head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-3); margin-bottom: 10px;
}
.continuum__label { font-size: var(--fs-callout); font-weight: var(--fw-semibold); line-height: var(--lh-snug); letter-spacing: var(--ls-body); min-width: 0; }
.continuum__value { font-family: var(--font-num); font-size: var(--fs-headline); color: var(--accent-text); font-weight: var(--fw-medium); line-height: var(--lh-snug); flex: 0 0 auto; }

.continuum__track {
  position: relative; height: 6px; border-radius: var(--r-full);
  background: var(--surface-3);
}
.continuum__band {
  position: absolute; top: 0; bottom: 0;
  background: var(--accent); opacity: .22; border-radius: var(--r-full);
}
.continuum__marker {
  position: absolute; top: -7px; bottom: -7px; width: 3px;
  background: var(--accent); border-radius: 2px; transform: translateX(-1.5px);
}
.continuum__marker::after {
  content: ''; position: absolute; top: -8px; left: 50%;
  width: 13px; height: 13px; border-radius: 50%;
  background: var(--accent); transform: translateX(-50%);
  box-shadow: 0 0 0 3px var(--bg-raised);
}

.continuum__scale {
  display: flex; justify-content: space-between; gap: var(--sp-2);
  margin-top: var(--sp-3); font-size: var(--fs-caption); color: var(--text-3);
}
.continuum__avg { text-align: center; }
.continuum__desc { margin: var(--sp-2) 0 0; font-size: var(--fs-body); line-height: var(--lh-relaxed); color: var(--text-2); }
.continuum__caption { margin-top: var(--sp-1); color: var(--text-3); font-size: var(--fs-footnote); line-height: var(--lh-normal); }
.continuum > .pill { margin-top: var(--sp-2); }

/* ─────────────────────────────────────────── 清单 */

.list { list-style: none; padding: 0; margin: 0; }
.list__item { display: flex; gap: 10px; padding: 7px 0; align-items: flex-start; min-width: 0; }
.list__mark { flex: 0 0 1.15em; font-weight: var(--fw-semibold); font-size: var(--fs-body); line-height: var(--lh-relaxed); }
.list__text { flex: 1 1 auto; min-width: 0; font-size: var(--fs-body); line-height: var(--lh-relaxed); }
.list__note { color: var(--text-3); }
.list--yes .list__mark { color: var(--ok); }
.list--no .list__mark { color: var(--danger); }
.list--plain .list__mark { color: var(--text-3); font-weight: 400; }

/* ─────────────────────────────────────────── 提示条 */

.notice {
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r);
  background: var(--surface-2);
  margin: var(--sp-3) 0;
  font-size: var(--fs-body); line-height: var(--lh-relaxed);
}
.notice--warn { background: var(--warn-bg); color: var(--warn); }
.notice--danger { background: var(--danger-bg); color: var(--danger); }
.notice h3 { color: inherit; }

/* ─────────────────────────────────────────── 键值对 */

.is-kv {
  display: grid; grid-template-columns: auto 1fr;
  gap: 6px var(--sp-4);
  margin: 0 0 var(--sp-3); font-size: var(--fs-subhead); line-height: var(--lh-normal); min-width: 0;
}
.is-kv__k { color: var(--text-3); white-space: nowrap; }
.is-kv__v { margin: 0; min-width: 0; overflow-wrap: anywhere; }

/* ─────────────────────────────────────────── 表格
   滚动容器真的能约束住子元素（移动端实测确认过）。 */

.is-table__wrap {
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  max-width: 100%; margin: var(--sp-3) 0; min-width: 0;
}
.is-table { border-collapse: collapse; width: 100%; font-size: var(--fs-subhead); }
.is-table th, .is-table td {
  text-align: left; padding: 9px 14px 9px 0;
  border-bottom: 0.5px solid var(--separator);
  white-space: nowrap;
}
.is-table th { color: var(--text-3); font-weight: var(--fw-medium); font-size: var(--fs-footnote); }
.is-table td.is-num, .is-table th.is-num {
  font-family: var(--font-num); text-align: right; padding-right: 14px;
}
.is-table tr.is-low td { color: var(--text-2); }

/* ─────────────────────────────────────────── 报告三分区 */

.zone {
  border-radius: var(--r-lg);
  padding: var(--sp-4);
  margin: var(--sp-3) 0;
  background: var(--bg-raised);
  min-width: 0;
}
.zone__tag {
  display: inline-block; font-size: var(--fs-caption); letter-spacing: var(--ls-body);
  padding: 3px 9px; border-radius: var(--r-full); margin-bottom: var(--sp-3);
  background: var(--surface-2); color: var(--text-3);
}

/* ─────────────────────────────────────────── 危机页 */

.crisis { max-width: var(--measure); margin: 0 auto; padding: var(--sp-5) var(--sp-4) var(--sp-6); }
.crisis__numbers { display: grid; gap: var(--sp-3); margin: var(--sp-4) 0; }
.crisis__number {
  display: flex; align-items: center; gap: var(--sp-4);
  padding: var(--sp-4); border-radius: var(--r-lg);
  background: var(--danger-bg); text-decoration: none; color: var(--text);
  min-width: 0;
}
.crisis__number:hover { text-decoration: none; opacity: .9; }
.crisis__number--primary { background: var(--danger); color: #fff; }
.crisis__number--primary .crisis__num,
.crisis__number--primary .crisis__note,
.crisis__number--primary .crisis__name { color: #fff; }
.crisis__num {
  font-family: var(--font-num); font-size: var(--fs-title2); font-weight: var(--fw-semibold);
  color: var(--danger); letter-spacing: -0.02em;
}
.crisis__name { font-weight: var(--fw-semibold); font-size: var(--fs-callout); line-height: var(--lh-snug); }
.crisis__note { color: var(--text-2); font-size: var(--fs-footnote); line-height: var(--lh-normal); }

/* ─────────────────────────────────────────── 答题界面
   选项不用边框盒子：填充色行 + 自绘单选钮，减少视觉噪声。 */

.progress { margin: var(--sp-3) 0 var(--sp-4); min-width: 0; }
.progress__track { height: 4px; border-radius: var(--r-full); background: var(--surface-3); overflow: hidden; }
.progress__bar { height: 100%; background: var(--accent); border-radius: var(--r-full); transition: width .25s ease; }
.progress__text {
  display: flex; justify-content: space-between; gap: var(--sp-3);
  font-size: var(--fs-footnote); line-height: var(--lh-normal); color: var(--text-3); margin-top: var(--sp-2);
}

.qitem { padding: var(--sp-4) 0; border-bottom: 0.5px solid var(--separator); min-width: 0; }
.qitem:last-of-type { border-bottom: 0; }
.qitem__text { font-size: var(--fs-headline); font-weight: var(--fw-medium); line-height: var(--lh-normal); margin-bottom: var(--sp-3); }
.qitem__stem { color: var(--text-2); font-size: var(--fs-subhead); line-height: var(--lh-normal); margin-bottom: var(--sp-3); }
.qitem--crisis { padding-left: var(--sp-3); box-shadow: inset 3px 0 0 var(--warn); }

.options { display: grid; gap: var(--sp-2); }
.option {
  display: flex; align-items: center; gap: var(--sp-3);
  min-height: 52px; padding: 13px var(--sp-4);
  border: 0; border-radius: var(--r);
  background: var(--surface-2); cursor: pointer;
  font-size: var(--fs-callout); min-width: 0;
  transition: background .12s ease;
  -webkit-tap-highlight-color: transparent;
}
.option:hover { background: var(--surface-3); }
.option input { margin: 0; accent-color: var(--accent); width: 20px; height: 20px; flex: 0 0 auto; }
.option:has(input:checked) { background: var(--accent-bg); color: var(--accent); font-weight: 500; }

.pager {
  display: flex; gap: var(--sp-3); justify-content: space-between;
  margin-top: var(--sp-5); padding-bottom: var(--safe-b);
}
.pager__spacer { flex: 1 1 auto; }

.drawer {
  background: var(--bg-raised); border-radius: var(--r-lg);
  padding: var(--sp-4); margin-bottom: var(--sp-4); min-width: 0;
}

/* ============================================================
   视图层
   ------------------------------------------------------------
   由 web/views/*.js 内联使用的 is-* 类。
   与上方同一套变量与语言：**去边框、用填充与留白**。
   ============================================================ */

/* ---------------------------------------------------------- 通用 / 外壳 */

.is-page { max-width: var(--measure); margin: 0 auto; min-width: 0; }

.is-hero { margin-bottom: var(--sp-5); }
.is-hero__title { margin: 0 0 var(--sp-2); }
.is-hero__lede { margin: 0; font-size: var(--fs-callout); line-height: var(--lh-relaxed); color: var(--text-2); max-width: 32rem; }

/* ★ 长正文排版（2026-09-15 第二阶段收口新增）
   语义 = 「一段可读的长文」，与 `.is-hero__lede`（语义是**大标题下的定位语**）不同。
   前导页/方法说明页/报告页原先只能退回裸 `<p>`（16px/1.47），长段落读起来挤。
   用法：容器上挂 `.is-prose`（里面放 `<p>`），或直接挂在单个 `<p>` 上。
   子元素里带自己字号的类（如 `.small`）仍按自己的来。 */
.is-prose {
  font-size: var(--fs-callout);
  line-height: var(--lh-relaxed);
  color: var(--text);
  max-width: var(--measure);
  min-width: 0;
}
.is-prose > * + * { margin-top: var(--sp-3); }
.is-prose > *:first-child { margin-top: 0; }
.is-prose > *:last-child { margin-bottom: 0; }

.is-head { padding-bottom: var(--sp-4); margin-bottom: var(--sp-4); }
.is-head__title { font-size: var(--fs-title2); margin: 0 0 var(--sp-2); }
.is-head__sub { margin: 0; color: var(--text-2); max-width: 36rem; }

.is-h3 { font-size: var(--fs-callout); font-weight: var(--fw-semibold); line-height: var(--lh-snug); margin: 0 0 var(--sp-2); color: var(--text); }

.is-foot {
  display: flex; flex-direction: column; gap: var(--sp-2);
  margin-top: var(--sp-6); padding-bottom: var(--safe-b);
}
.is-badges { margin-bottom: var(--sp-0); }
.is-footnote { margin: var(--sp-5) 0 0; max-width: 34rem; }

/* ★ 文本输入框（2026-09-15 第二阶段收口新增）
   设计系统此前**根本没有输入框类**，报告页的口令框只能用内联 token 兜底。
   `--border` 的既定用途正是「只在必须画盒子时用（选择框、输入框）」（§1.1）。
   字号必须 ≥16px（`--fs-body`）：iOS 上小于 16px 的输入框会触发自动放大。
   留白交还调用方（`margin: 0`），本类只负责"一个输入框长什么样"。 */
.is-input {
  display: block;
  width: 100%;
  min-height: 44px;
  margin: 0;
  padding: 0 14px;
  border: var(--hairline) solid var(--border);
  border-radius: var(--r);
  background: var(--bg-raised);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-body);
  -webkit-appearance: none;
  appearance: none;
}
.is-input::placeholder { color: var(--text-3); opacity: 1; }
.is-input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------------------------------------------------------- intro.js */

.is-pair { display: grid; grid-template-columns: 1fr; gap: var(--sp-3); min-width: 0; }
.is-pair__col { min-width: 0; background: var(--bg-raised); border-radius: var(--r-lg); padding: var(--sp-4); }
.is-pair__ttl { font-size: var(--fs-callout); font-weight: var(--fw-semibold); line-height: var(--lh-snug); margin: 0 0 var(--sp-2); }
.is-pair__col:first-child .is-pair__ttl { color: var(--ok); }
.is-pair__col:last-child .is-pair__ttl { color: var(--danger); }
@media (min-width: 700px) {
  .is-pair { grid-template-columns: 1fr 1fr; gap: var(--sp-4); }
}

.is-stem {
  color: var(--text-2); font-size: var(--fs-subhead); font-style: normal;
  margin: 0 0 var(--sp-3);
}

/* 试做一题：只作预览，禁用态，权重低于答题页的真实选项。 */
/* 试做一题：只作预览，禁用态，权重低于答题页的真实选项。 */
.is-option {
  appearance: none; -webkit-appearance: none;
  display: block; width: 100%; min-height: 48px;
  padding: 13px var(--sp-4);
  font: inherit; font-size: var(--fs-callout); line-height: var(--lh-normal); text-align: left;
  color: var(--text-2); background: var(--surface-2);
  border: 0; border-radius: var(--r); margin-bottom: var(--sp-2);
  cursor: default;
}
/* 灰底 + 灰字本身已经足够弱；再叠一层半透明会让人以为它坏了。 */
.is-option[disabled] { opacity: 1; }

.is-anchor {
  display: grid; grid-template-columns: 1fr; gap: 2px;
  padding: 10px 0; border-bottom: 0.5px solid var(--separator);
  min-width: 0;
}
.is-anchor:last-child { border-bottom: 0; }
.is-anchor__name { display: block; font-weight: var(--fw-medium); font-size: var(--fs-callout); line-height: var(--lh-snug); }
.is-anchor__brief { display: block; color: var(--text-2); font-size: var(--fs-subhead); line-height: var(--lh-normal); }
@media (min-width: 560px) {
  .is-anchor { grid-template-columns: 9rem 1fr; gap: var(--sp-3); align-items: baseline; }
}

/* ---------------------------------------------------------- survey.js */

.is-survey { position: relative; min-width: 0; }
.is-survey__static-tip { margin: var(--sp-4) 0; }

.is-survey__toolbar {
  display: flex; flex-wrap: wrap; justify-content: space-between;
  align-items: flex-start; gap: var(--sp-3);
  padding-bottom: var(--sp-3); margin-bottom: var(--sp-4);
  min-width: 0;
}
.is-survey__toolbar-main { flex: 1 1 14rem; min-width: 0; gap: var(--sp-2); }
.is-survey__toolbar .card__title { margin: 0; }

.is-survey__progress { gap: var(--sp-2); min-width: 0; }
.is-survey__progress-text { color: var(--text-3); }

.is-survey__bar {
  height: 4px; border: 0; border-radius: var(--r-full);
  background: var(--surface-3); overflow: hidden;
}
.is-survey__bar-fill {
  display: block; height: 100%; width: 0;
  background: var(--accent); border-radius: var(--r-full);
  transition: width .25s ease;
}
.is-survey__gap-track { display: none; }

/* 说明与题干：**不再用灰盒子**，改为小字 + 左侧细分隔线，降低视觉噪声。 */
.is-survey__instruction {
  padding: 0 0 0 var(--sp-3);
  border-left: 2px solid var(--surface-3);
  background: transparent;
  color: var(--text-3); font-size: var(--fs-footnote); line-height: var(--lh-normal);
}
.is-survey__instruction > *:last-child { margin-bottom: 0; }
.is-survey__instruction p { margin: 0 0 4px; }

.is-survey__stem {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-headline); font-weight: var(--fw-semibold); letter-spacing: var(--ls-head); line-height: var(--lh-snug);
}
.is-survey__time-window {
  margin: 0 0 var(--sp-3); padding: 0;
  border: 0; background: transparent;
  color: var(--text-3); font-size: var(--fs-footnote); line-height: var(--lh-snug);
}

.is-survey__items { gap: 0; min-width: 0; }

.is-survey__item { padding: var(--sp-4) 0; border-bottom: 0.5px solid var(--separator); min-width: 0; }
.is-survey__item:last-of-type { border-bottom: 0; }

.is-survey__item-head {
  display: grid; grid-template-columns: 1.5em 1fr; gap: 0 var(--sp-2);
  margin-bottom: var(--sp-3); align-items: baseline; min-width: 0;
}
.is-survey__item-index { font-family: var(--font-num); color: var(--text-3); font-size: var(--fs-subhead); }
.is-survey__item-text { min-width: 0; font-size: var(--fs-headline); font-weight: var(--fw-medium); line-height: var(--lh-normal); }

.is-survey__options { display: grid; gap: var(--sp-2); }

/* 整块可点的选项：label 含原生 radio，键盘与读屏都直接可用。 */
.is-survey__option {
  display: flex; align-items: center; gap: var(--sp-3);
  min-height: 52px; padding: 13px var(--sp-4);
  background: var(--surface-2); border: 0; border-radius: var(--r);
  cursor: pointer; font-size: var(--fs-callout); min-width: 0;
  -webkit-tap-highlight-color: transparent;
}
.is-survey__option:hover { background: var(--surface-3); }

/* 选中态：底色 + 实心圆点，形状与颜色双通道，不只靠颜色。 */
.is-survey__option:has(input:checked) { background: var(--accent-bg); }

.is-survey__option-input {
  appearance: none; -webkit-appearance: none;
  flex: 0 0 auto; width: 20px; height: 20px; margin: 0;
  border: 1.5px solid var(--border-strong);
  border-radius: 50%; background: var(--bg-raised); cursor: pointer;
}
.is-survey__option-input:checked {
  border-color: var(--accent);
  background-color: var(--accent);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6.6 12.6l3.6 3.6 7.2-8.3' fill='none' stroke='%23fff' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: center; background-size: 14px 14px;
}
.is-survey__option:has(.is-survey__option-input:focus-visible) {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
.is-survey__option-text { flex: 1 1 auto; min-width: 0; line-height: var(--lh-normal); }
.is-survey__option:has(input:checked) .is-survey__option-text { color: var(--accent); font-weight: 500; }

.is-survey__footer { margin-top: var(--sp-5); padding-bottom: var(--safe-b); }
.is-survey__footer-note {
  display: flex; flex-direction: column; gap: 2px;
  margin-bottom: var(--sp-3); min-height: 1.6em;
  color: var(--text-3); font-size: var(--fs-footnote); line-height: var(--lh-normal);
}
.is-survey__footer-btns { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.is-survey__remaining { display: block; }
.is-survey__gap { display: none; }
@media (min-width: 560px) {
  .is-survey__gap { display: block; flex: 1 1 auto; }
}
@media (max-width: 559px) {
  .is-survey__footer-btns .btn { flex: 1 1 auto; }
  .is-survey__footer-btns .btn--primary { flex: 1 1 100%; order: -1; }
}

/* 量表说明抽屉：遮罩常驻 DOM，靠 .is-open 切换可见性。 */
.is-survey__drawer {
  position: fixed; inset: 0; z-index: 50; display: none;
  background: color-mix(in srgb, var(--text) 42%, transparent);
}
.is-survey__drawer.is-open { display: block; }

.is-survey__drawer-panel {
  display: flex; flex-direction: column;
  width: min(100%, 34rem);
  max-height: 92vh; max-height: 92dvh;
  margin: 4vh auto 0;
  background: var(--bg-raised);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  overflow: hidden;
}
.is-survey__drawer-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); padding: var(--sp-4);
  border-bottom: 0.5px solid var(--separator);
}
.is-survey__drawer-head .card__title { margin: 0; font-size: var(--fs-headline); }
.is-survey__drawer-body {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: var(--sp-4); gap: var(--sp-4);
}
/* 只吃掉**第一个**子块的上边距（抽屉顶部不再多出一段空白）；
   旧写法 `> *` 把每个子块的上边距都清零了 —— 抽屉里「能得到什么」与上一段
   因此贴在一起，只有第一个 section 看得出分段（答题页线报的实测）。 */
.is-survey__drawer-body > *:first-child { margin-top: 0; }
.is-survey__drawer-block { padding: 0; border: 0; }
.is-survey__drawer-block > *:last-child { margin-bottom: 0; }
.is-survey__drawer-foot {
  padding: var(--sp-4); padding-bottom: calc(var(--sp-4) + var(--safe-b));
  border-top: 0.5px solid var(--separator);
}

.is-survey__facts { align-items: baseline; gap: 2px var(--sp-3); margin: 0; min-width: 0; }
.is-survey__fact-label { flex: 0 0 4.5em; color: var(--text-3); }
.is-survey__fact-value { flex: 1 1 auto; min-width: 0; }

/* ---------------------------------------------------------- method.js */

.is-method { max-width: var(--measure); margin-inline: auto; min-width: 0; }
/* `.is-method__lede` 已于 2026-09-15 第二阶段收口时删除：方法说明页改用
   `.is-hero__title` + `.is-hero__lede` 后，它零引用（grep 全仓核实，见
   `docs/设计系统-v2.md` §7）。 */

.is-method__quote {
  margin: var(--sp-3) 0; padding: var(--sp-3) var(--sp-4);
  border-left: 2px solid var(--accent);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  background: var(--accent-bg);
  color: var(--text); font-size: var(--fs-callout); line-height: var(--lh-relaxed);
}

.is-method__stats {
  padding: var(--sp-4); border: 0; border-radius: var(--r);
  background: var(--bg-raised); font-size: var(--fs-callout); line-height: var(--lh-normal);
}
.is-method__status { min-height: 1.6em; margin: var(--sp-2) 0 0; color: var(--text-2); }
.is-method__scroll-hint { margin: var(--sp-2) 0 0; color: var(--text-3); font-size: var(--fs-footnote); }

/* α 完整表：窄屏交给 .is-table__wrap 横向滚动（该容器已实测能正确约束宽内容）。 */
.is-alpha-table { min-width: 40rem; }
.is-alpha-table th[scope='row'] { font-family: var(--font-num); }
.is-alpha-table__num { font-variant-numeric: tabular-nums; }
.is-alpha-table--low { background: transparent; }
.is-alpha-table--low th[scope='row'] { box-shadow: inset 3px 0 0 var(--warn); }
.is-cell--low { color: var(--warn); font-weight: 600; }

.is-flag {
  display: inline-block; padding: 1px 8px;
  border: 0; border-radius: var(--r-full);
  background: var(--warn-bg); color: var(--warn);
  font-size: var(--fs-caption); line-height: var(--lh-normal); white-space: nowrap;
}

/* ---------------------------------------------------------- crisis.js */

.is-crisis-hero {
  margin: var(--sp-4) 0; padding: var(--sp-4);
  border: 0; border-radius: var(--r-lg);
  background: var(--danger-bg);
}
.is-crisis-lead { margin: 0 0 var(--sp-2); font-size: var(--fs-title3); font-weight: var(--fw-semibold); line-height: var(--lh-snug); color: var(--text); }
.is-crisis-sub { margin: 0 0 var(--sp-2); color: var(--text-2); }
.is-crisis-sub:last-child { margin-bottom: 0; }
/* `.is-crisis-quick` 已于 2026-09-15 第二阶段收口时删除：危机页改用
   `.is-hero__lede` 后它零引用（grep 全仓核实，见 docs/设计系统-v2.md §7）。 */

.is-crisis-tel {
  display: flex; flex-direction: column; gap: 3px;
  padding: var(--sp-4); margin-bottom: var(--sp-3);
  border: 0; border-radius: var(--r-lg);
  background: var(--bg-raised); color: var(--text); text-decoration: none;
  min-width: 0;
}
.is-crisis-tel:hover { text-decoration: none; opacity: .92; }
.is-crisis-tel-num {
  font-family: var(--font-num); font-size: var(--fs-title1); font-weight: var(--fw-semibold);
  line-height: var(--lh-tight); color: var(--danger); letter-spacing: var(--ls-head);
}
.is-crisis-tel-name { font-weight: 600; }
.is-crisis-tel-meta { color: var(--text-3); font-size: var(--fs-footnote); line-height: var(--lh-normal); }

.is-crisis-head {
  margin-top: var(--sp-5); padding-top: var(--sp-4);
  border-top: 0.5px solid var(--separator);
  color: var(--text-3); font-size: var(--fs-footnote); line-height: var(--lh-normal);
}

/* ---------------------------------------------------------- consent.js */

.is-consent-foot {
  margin-top: var(--sp-6); padding-top: var(--sp-4);
  border-top: 0.5px solid var(--separator);
}
.is-consent-foot .section__title { margin-top: 0; }
.is-consent-foot .btn { margin-top: var(--sp-2); }

/* ============================================================
   v2.1 补充：手机优先的触控目标、垂直节奏与危机页层级
   ------------------------------------------------------------
   ★ 本节**只新增规则、只调整数值**：不删除、不重命名上方任何
     已存在的类名与 CSS 变量（并行开发的铁律）。
   ============================================================ */

/* ---------------------------------------------------------- 触控目标
   手机上一半的误操作来自「点到旁边」。这里把几处紧凑控件的命中区域
   撑到舒适区，视觉体积基本不变。 */

.skip-link { padding: 9px var(--sp-4); }

/* 顶栏链接：视觉上仍是 23px 高的小字，命中区域扩大到 45px。
   只做纵向外扩，因此不会和相邻链接的横向区域重叠。 */
.topbar__brand, .topbar__nav a { position: relative; }
.topbar__brand::after, .topbar__nav a::after {
  content: ''; position: absolute; inset: -12px -6px;
}

/* 页脚内联链接同理：正文小字不放大，命中区域给足。 */
.footer a { position: relative; }
.footer a::after { content: ''; position: absolute; inset: -12px -4px; }

/* 证据徽章（★ 2026-09-15「徽章瘦身」改口径）
   ------------------------------------------------------------
   旧做法：`min-height: 44px; padding: 11px 13px` —— 把**视觉盒**直接撑到 44px，
   于是四枚徽章在手机上像四个大按钮（用户原话「不需要这么大」）。

   新做法（视觉小 + 热区大）：
   · 视觉盒交回内容：`padding: var(--sp-1) var(--sp-3)` ⇒ 实测高 **25.5px**；
   · 热区由 `.pill__summary::after { inset: -10px -2px }` 撑到
     `25.5 + 20 = 45.5 → 实测 46px`（手机两端 375 / 393 实测，见设计系统 §2.5）；
   · **`.pill__summary` 上不许再写 min-height** —— 写了视觉盒就回去了；
   · **`.pill` 与 `.pill__summary` 都不许加 `overflow: hidden`** —— 那会把
     伪元素热区一起裁掉（旧注释里"无法用伪元素外扩"的前提已不成立：
     单行截断改挂在 `.pill__label` 上，`elementsFromPoint` 才认得到外扩部分）。
   徽章是「可核查」的唯一入口，热区一旦跌破 44px 就没有意义，`tools/shoot.mjs` 会抓。 */
.pill__summary {
  /* 与基础规则逐值一致（padding 对称、垂直居中），否则改一处会被这里盖掉。 */
  padding: var(--sp-1) var(--sp-3);
  min-height: var(--sp-5);
  align-items: center;
}
.pill { border-radius: var(--r-full); }
.pill[open] { border-radius: var(--r); }

/* 徽章展开后的外部依据链接：22px → 44px。 */
.pill__link {
  display: inline-flex; align-items: center;
  min-height: 44px; margin-top: 0;
}

/* ---------------------------------------------------------- 首页证据卡
   卡片底部动作区：与上方依据之间用留白分层，不加线。 */

.is-card-actions {
  display: flex; flex-direction: column; gap: var(--sp-2);
  margin-top: var(--sp-4);
}
.is-card-actions .btn { width: 100%; }

/* 两张证据卡之间的缝，要大于卡片内边距，否则两张卡看起来是贴在一起的。 */
.is-modules { gap: var(--sp-4); }

/* ---------------------------------------------------------- 前导页
   一屏之内必须先回答「多少题、多久、问什么」。 */

.is-head__facts {
  margin: var(--sp-2) 0 var(--sp-3);
  font-size: var(--fs-subhead); font-weight: var(--fw-medium); line-height: var(--lh-snug);
  color: var(--text); letter-spacing: -0.01em;
}

/* 合并后的档案卡内部子块：用留白分层，不加线。 */
.is-sub { margin-top: var(--sp-5); }

/* 维度行：手机上单行排布（名 + 一句说明），比两行堆叠省一半高度。 */
.is-anchor {
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: 2px var(--sp-3);
  padding: 9px 0; border-bottom: 0.5px solid var(--separator);
  min-width: 0;
}
.is-anchor__name { flex: 0 0 auto; }
.is-anchor__brief { flex: 1 1 7rem; min-width: 0; }

/* 底部动作条：5 屏长的页面上，用户不该为了「开始」再多滚 3 屏。
   只在手机上吸底；桌面保持文档式流式布局。 */
@media (max-width: 699px) {
  .is-foot--sticky {
    position: sticky; bottom: 0; z-index: 15;
    display: flex; flex-direction: row; align-items: center;
    gap: var(--sp-2);
    margin: var(--sp-5) calc(-1 * var(--sp-4)) 0;
    padding: var(--sp-3) var(--sp-4) calc(var(--sp-3) + var(--safe-b));
    background: color-mix(in srgb, var(--bg) 86%, transparent);
    backdrop-filter: saturate(180%) blur(20px);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    border-top: 0.5px solid var(--separator);
  }
  .is-foot--sticky .btn--primary { flex: 1 1 auto; width: auto; }
  .is-foot--sticky .btn--ghost { flex: 0 0 auto; }
}

/* ---------------------------------------------------------- 知情同意 */

.is-consent-actions {
  display: flex; flex-direction: column; gap: var(--sp-2);
  margin-top: var(--sp-5);
}
.is-consent-actions .btn--primary { width: 100%; }
.is-consent-actions .btn--ghost { align-self: flex-start; }

/* ★ 2026-09-15 第二阶段收口：让 `.is-consent-actions` 与吸底条**可以同时挂**。
   同意页线实测三种写法，只有下面这种成立（证据在它的报告里）：
     <div class="is-consent-actions is-foot--sticky"> 主按钮 + 次要按钮 </div>
   ——**同一个元素**同时带两个类。
   反例① 两者同时挂但不补这条规则：`.is-consent-actions` 在本文件更靠后、
   同优先级，它的 `flex-direction: column` 会盖掉吸底条的 `row`
   ⇒ 动作条变成 127px 两行堆叠（SE 首屏的 19%）。
   反例② 把吸底条**嵌在** `.is-consent-actions` 里：`position: sticky` 的约束矩形
   是父级内容盒，父级只有 72px 高 ⇒ 吸底彻底失效。
   反例③ 按钮外面再包一层 `.row`：`.is-consent-actions .btn--primary{width:100%}`
   撞上 `.row` 的 `flex-wrap: wrap` ⇒ 次要按钮换行，高度仍 127px。
   只在手机档生效：桌面端 `.is-foot--sticky` 不生效，动作区仍是纵排。 */
@media (max-width: 699px) {
  .is-consent-actions.is-foot--sticky {
    flex-direction: row;
    align-items: center;
  }
  .is-consent-actions.is-foot--sticky .btn--primary {
    flex: 1 1 auto;
    width: auto;
  }
  .is-consent-actions.is-foot--sticky .btn--ghost {
    align-self: auto;
  }
}
/* 同意清单是这一页真正的内容，字号不该小于上面的导语。 */
.is-consent-list .list__item { padding: 9px 0; gap: 8px; }
.is-consent-list .list__mark { flex: 0 0 0.75em; color: var(--text-3); }
.is-consent-list .list__text { font-size: var(--fs-body); line-height: var(--lh-relaxed); }
.is-consent-scale {
  margin: calc(-1 * var(--sp-2)) 0 var(--sp-4);
  color: var(--text-3); font-size: var(--fs-footnote); line-height: var(--lh-normal);
}

/* ---------------------------------------------------------- 危机页
   12356 必须一眼看到、一点即拨。层级靠字号与底色，不靠特效。 */

.is-crisis-hero { background: var(--bg-raised); padding: var(--sp-4); }

.is-crisis-item { min-width: 0; }

.is-crisis-tel--primary {
  background: var(--danger-bg);
  padding: var(--sp-4);
  gap: var(--sp-1);
}
.is-crisis-tel--primary .is-crisis-tel-num {
  font-size: var(--fs-crisis-hero); line-height: 1; letter-spacing: var(--ls-title);
}
.is-crisis-tel--primary .is-crisis-tel-name { font-size: var(--fs-headline); line-height: var(--lh-snug); }
.is-crisis-tel--primary .is-crisis-tel-meta { color: var(--text-2); }

/* 拨号提示条：整张卡已经是 tel: 链接，这条只是把「可以点」说清楚，
   顺带把命中区域做成 44px 高。 */
.is-crisis-tel-hint {
  display: flex; align-items: center; justify-content: center;
  min-height: 44px; margin-top: var(--sp-3);
  border-radius: var(--r);
  background: var(--danger); color: #fff;
  font-size: var(--fs-callout); font-weight: var(--fw-medium); letter-spacing: var(--ls-body);
}
@media (prefers-color-scheme: dark) {
  /* 深色下 --danger 本身很亮，白字对比不足，改为同色系浅底 + 深字。 */
  .is-crisis-tel-hint {
    background: color-mix(in srgb, var(--danger) 20%, var(--bg-raised));
    color: var(--danger);
  }
}

/* 次要渠道（120 / 110）：横向一行，权重明确低于 12356。 */
.is-crisis-secondary { display: grid; gap: var(--sp-2); }
.is-crisis-tel--row {
  flex-direction: row; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--bg-raised);
}
.is-crisis-tel--row .is-crisis-tel-num {
  flex: 0 0 auto; min-width: 3.1em; font-size: var(--fs-title2); line-height: var(--lh-tight);
}
.is-crisis-tel-body {
  display: flex; flex-direction: column; gap: 1px;
  flex: 1 1 auto; min-width: 0;
}
.is-crisis-tel--row .is-crisis-tel-name { font-size: var(--fs-callout); line-height: var(--lh-snug); }
.is-crisis-tel--row .is-crisis-tel-meta { font-size: var(--fs-footnote); line-height: var(--lh-normal); }

/* 地方热线：与 `--row` 同形，机构名长短差很大，说明文字行数因此不一。
   号码若跟着卡片高度垂直居中，一屏内几个号码就会高低不齐；改为顶部对齐 +
   号码自身居中，让号码落在同一水平线上。只新增规则，不动上方任何已有选择器。 */
.is-crisis-tel--local { align-items: flex-start; }
.is-crisis-tel--local .is-crisis-tel-num { align-self: center; }

/* 依据链接移到 tel: 卡片之外 —— 锚点不能嵌套锚点。 */
.is-crisis-src {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 44px; padding: 0 var(--sp-1);
  margin: 0; color: var(--text-3); font-size: var(--fs-footnote); line-height: var(--lh-normal);
}
.is-crisis-item .is-crisis-src { margin-top: 2px; }
.is-crisis-src a { display: inline-flex; align-items: center; min-height: 44px; }

/* 出口按钮组：竖排、通栏，权重低于上面的号码。 */
.is-crisis-actions {
  display: flex; flex-direction: column; gap: var(--sp-2);
  margin-top: var(--sp-3);
}
.is-crisis-actions .btn { width: 100%; }
.is-crisis-actions .btn--ghost { align-self: flex-start; width: auto; }

/* ─────────────────────────────────────────── 无障碍 */

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* 深色模式下 `--accent` 是亮蓝，白字压在上面只有 3.7:1。
   深色由 `--btn-on-accent` 统一派生（近黑文字压亮蓝 = 5.8:1，也正是 iOS 深色主按钮的观感）。 */
@media (prefers-color-scheme: dark) {
  .btn--primary, .skip-link { color: var(--btn-on-accent); }
}

@media (prefers-reduced-motion: reduce) {
  /* 尊重系统「减弱动效」：位移动画完全关闭，颜色过渡压到不可感知。 */
  *, *::before, *::after {
    transition-duration: 0.001ms !important;
    transition-delay: 0ms !important;
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
  }
  .continuum__marker, .continuum__band { transition: none !important; }
  .why__q::after { transition: none !important; }
  html { scroll-behavior: auto; }
}

@media print {
  .topbar, .footer, .btn, .pager { display: none !important; }
  body { background: #fff; }
  .card, .zone, .section { break-inside: avoid; }
}

/* ─────────────────────────────────────────────────────────────
   报告页 ④ 区（AI 解读 / 确定性模板）—— 2026-09-15 AI 接通线新增
   ------------------------------------------------------------------
   只新增 `is-report-ai-*` 前缀的类，**不动上面任何已有类名与变量**
   （并行线仍在使用它们）。这些类是 `web/views/report.js` 第 ④ 区的
   结构契约，见该文件顶部的类名表。
   ───────────────────────────────────────────────────────────── */
.is-report-ai-badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text-2);
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-body);
}
.is-report-ai-note {
  margin: var(--sp-3) 0 0;
  color: var(--text-2);
  font-size: var(--fs-subhead);
  line-height: var(--lh-relaxed);
}
.is-report-ai-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-top: var(--sp-4);
}
/* 触控目标 ≥44px（移动端是主战场；作业卡 §7.7） */
.is-report-ai-btn {
  min-height: 44px;
  padding: 0 var(--sp-5);
}
.is-report-ai-result { margin-top: var(--sp-4); }
.is-report-ai-result > * + * { margin-top: var(--sp-3); }
.is-report-ai-h {
  margin: var(--sp-4) 0 0;
  font-size: var(--fs-callout);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
  color: var(--text);
}
.is-report-ai-warn {
  margin: var(--sp-3) 0 0;
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r);
  background: var(--warn-soft);
  color: var(--text);
  font-size: var(--fs-subhead);
  line-height: var(--lh-relaxed);
}
.is-report-ai-at { margin-top: var(--sp-2); }

/* ============================================================
   v2.2 · iOS 原生感的收敛层
   ------------------------------------------------------------
   ★ 本节**只新增规则、只调整数值**，不删除、不重命名任何类名与变量。
     目的有三个：
       1) 把散落各处的 `0.5px solid` 统一到 `--hairline`（Retina 下的真 hairline）；
       2) 把「当文字用的强调色」统一到 `--accent-text`（`--accent` 只留作填充），
          两者对比度差异见 docs/设计系统-v2.md §1.4；
       3) 补齐大标题（large title）与分组内嵌列表（inset grouped list）的语言。
   ============================================================ */

/* ---------------------------------------------------------- 1. hairline 统一 */

.is-table th, .is-table td,
.qitem,
.is-survey__item,
.is-anchor,
.is-survey__drawer-head,
.is-survey__drawer-foot,
.is-crisis-head,
.is-consent-foot {
  border-bottom-width: var(--hairline);
}
.is-survey__drawer-foot,
.is-crisis-head,
.is-consent-foot { border-top-width: var(--hairline); border-bottom-width: 0; }

/* 同色相邻的列表行：靠 hairline 分隔，绝不加边框盒。 */
.is-survey__item:last-of-type, .qitem:last-of-type { border-bottom-width: 0; }

/* ---------------------------------------------------------- 2. 强调色只当填充 */

/* 当文字用时一律走 `--accent-text`。 */
.continuum__value,
.why__q,
.pill--citation .pill__summary,
.is-survey__option:has(input:checked) .is-survey__option-text,
.option:has(input:checked),
.btn--ghost,
a { color: var(--accent-text); }

/* 当填充用时保持系统蓝 `--accent`。 */
.continuum__band, .continuum__marker, .continuum__marker::after,
.progress__bar, .is-survey__bar-fill,
.is-survey__option-input:checked {
  background-color: var(--accent);
}
.is-survey__option-input:checked { border-color: var(--accent); }

/* 选中行：底色由 `--accent-bg` 派生，形状（实心圆点）与颜色双通道，不只靠颜色。 */
.is-survey__option:has(input:checked), .option:has(input:checked) { background: var(--accent-bg); }

/* ---------------------------------------------------------- 3. 大标题 + 分组内嵌列表 */

/* 大标题：iOS 视图首屏的 large title，左对齐、贴顶、下方留白收紧。
   ★ 2026-09-15 第二阶段收口：30px 档原来只挂在 `.view--home` 下，其余五页
   套了 `.is-hero__title` 却只拿到 `h1` 的 26px —— 4 条视图线都报了这一条。
   现在六个视图同一档（页面身份由 `view--<id>` 决定，见设计系统 §2.1）。 */
.view--home .is-hero { margin-bottom: var(--sp-5); }
.view--home .is-hero__title,
.view--report .is-hero__title,
.view--method .is-hero__title,
.view--intro .is-hero__title,
.view--consent .is-hero__title,
.view--crisis .is-hero__title {
  display: block;
  font-size: var(--fs-largetitle);
  line-height: var(--lh-display);
  font-weight: 700;
  letter-spacing: var(--ls-title);
  margin: 0 0 var(--sp-2);
}
.view--home .is-hero__lede {
  font-size: var(--fs-callout);
  line-height: var(--lh-relaxed);
  color: var(--text-2);
  max-width: 30rem;
  margin: 0;
}

/* 分组内嵌列表：组名（`.section__title`）贴在组上方，组本身是白卡。
   卡与卡之间的缝必须**大于**卡内边距，否则两张卡看起来是贴在一起的。 */
.is-modules { gap: var(--rhythm-block); }
/* 首页两张证据卡内部信息密度高（标题 / 英文副标 / 事实行 / 四枚徽章 / 按钮），
   桌面也保持单列 —— 证据要能一行读完，不是拿来塞满宽屏的。
   只在**首页**收窄栅格，不影响其它视图对 `.grid--2` 的用法。 */
@media (min-width: 700px) {
  .view--home .is-modules { grid-template-columns: 1fr; }
  .view--home .is-modules { max-width: 34rem; }
}
.card + .card { margin-top: var(--rhythm-block); }

/* 卡片头部：标题 + 英文副标 + 事实行 + 辅助行，紧凑成一个块。 */
.is-card-head { min-width: 0; }
.is-card-head .card__title { margin-bottom: var(--sp-1); }

/* 触控目标：分组列表里的行内目标一律 ≥ 44px（作业卡 §7.7）。
   ★ `.pill__summary` **已从这一串里摘掉**（2026-09-15 徽章瘦身）：它自己的 44px
   由 `.pill__summary::after` 的 -10px 外扩提供，视觉盒保持 25.5px。
   若把它留在这一串里，`min-height: 44px` 会重新把视觉盒撑成大按钮 ——
   `tools/shoot.mjs --audit` 量的是**真实热区**，所以摘掉它不会放松判据。 */
.btn, .option, .is-survey__option { min-height: 44px; }

/* ---------------------------------------------------------- 4. 导航行（iOS「跳去另一页」的形态）
   一个带 chevron 的整宽行；权重低于主按钮 —— 主动作只能有一个。 */

.is-nav-row {
  width: 100%;
  justify-content: space-between;
  text-align: left;
  padding-inline: var(--sp-4);
  background: var(--surface-2);
  color: var(--accent-text);
  font-weight: var(--fw-medium);
}
.is-nav-row::after {
  content: '';
  flex: 0 0 auto;
  width: 7px; height: 7px;
  margin-left: var(--sp-2);
  border-right: 1.5px solid var(--text-3);
  border-bottom: 1.5px solid var(--text-3);
  transform: rotate(-45deg);
  transition: transform var(--dur-fast) var(--ease);
}
.is-nav-row:hover::after { transform: rotate(-45deg) translate(1px, -1px); }

/* 列表分组名：iOS 里叫 group label —— 小字、次要色、贴在组的上方（**在卡片外**）。
   放在卡片内部时用来给「卡片里的一段」起标题。 */
.is-group-label {
  margin: 0 0 var(--sp-2);
  padding-left: var(--sp-1);
  color: var(--text-2);
  font-size: var(--fs-footnote);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-caps);
  line-height: var(--lh-snug);
}

/* ---------------------------------------------------------- 5. 触控目标补齐（v2.2 复测发现）
   正文从 17px 收到 16px 之后，顶栏链接的**视觉高度**从 23px 掉到 19px，
   原来 `inset: -12px` 的伪元素热区随之只剩 43px —— 差 1px 就跌出 44px 底线。
   ★ 教训：热区是「视觉高度 + 外扩量」算出来的，**改字号会连带改热区**，
     所以这里同步把外扩量加到 -13px，并保留一条与字号无关的兜底。 */
.topbar__brand::after, .topbar__nav a::after { inset: -13px -6px; }

/* 页脚内联链接改成 inline-flex + min-height：热区是元素本身的盒子，
   不再依赖伪元素外扩，怎么改字号都稳。 */
.footer a {
  display: inline-flex; align-items: center;
  min-height: 44px; margin-block: -12px;
}
.footer a::after { content: none; }

