/* ═══════════════════════════════════════════════════════════════════════════
   case.css — 案例详情页（2026-08 内容包重建版）

   与旧 case-detail.css 的关系：这是**替代品**，不是补丁。五页迁完之前两份
   并存，旧页面继续引用旧文件，新页面只引用这一份。迁完可以删旧的。

   为什么重写而不是改：新内容包多了四类旧骨架没有的模块（冻结轨、可变列
   读数、逐句打标的证据板、折叠分析师卡），而且读数格从写死三列变成每案
   不同列数。在旧文件上加这些会到处是例外。

   沿用的设计语言（这部分一个字没动）：
     · 底 = --paper + 6px 点阵；深浅带交替
     · 字 = Azeret Mono 当 display 与小标签，Lexend 当正文
     · 朱色 --case-accent 只当指示灯：数据值、激活态、结果、冻结点
     · 全部 1px --rule 线框拼贴，**无圆角、无阴影、无辉光**

   ⚠️ 辉光（box-shadow: 0 0 Npx accent）是保留的设计，别再删。
   但**加辉光就必须同时给它腾出净距**，否则它会糊在旁边的字上。

   实测衰减（12px 模糊、朱色 65%、浅底）自方块边缘向外：
     0px Δ33 · 4px Δ17 · 8px Δ6 · 11px Δ3 · **12px Δ1（完全看不见）**
   所以规矩是：**净距 ≥ 模糊半径 + 4px 余量**。
   现行取值：`.track-end{gap:16px}`、`.mast-case-status{gap:16px}`
   （原来是 10px / 9px，都不够，字上有一层可见的橙雾）。
   冻结标记向下到日期有 17px，14px 模糊够用，不用改。

   量法在自检清单里：拿同样的尺寸/模糊/颜色单独渲一个方块，
   逐像素扫到色差 Δ≤1 为止。不要靠「blur/2」这类推算，不准。

   ⚠️ 文字**没有**深浅层级可用。tokens.css 是刻意把 --g5..--g9 全部映射到
   --on 的（源文件注释：「⚠ 原『最弱文字』→ 与正文同色」）。所以
   `--text` / `--text-2` / `--text-mute` / `--text-faint` **算出来是同一个
   #2B2D31**，写哪个都一样，全是死代码。
   全站只有四级明度：--off 纸 / --dim 淡（线） / --fill 中 / --on 全。
   要让某段文字**真的**变浅，唯一的选择是 `--fill`（#6D747E，对纸面
   约 3.5:1，30px 以上的大字过 WCAG）。其余层级请用**字号和字重**做，
   这是这套系统的本意 —— 颜色留给结构，不用来分文字主次。
   ═════════════════════════════════════════════════════════════════════════ */

:root{
  --case-accent:#C96342;
  --case-accent-wash:#E8B7A7;
  --case-pad:clamp(20px,3.4vw,52px);
  --case-max:1480px;
  /* 版块上下留白。hero 与 .sec-case 共用 --case-bot —— 页面上每一次
     「浅底结束 → 深色带开始」都必须是同一个数，hero 也不例外（它只是
     上边不一样：masthead 已经给了空间，所以 --case-top 不管 hero）。
     窄屏在 720 断点处只改这两个变量，不要再去各处写 padding。
     ⚠️ 别用 --sec-top/--sec-bot 这两个名字：landing.css 的 .sec 已经占了，
     值还不一样（96/104），且 .split-rule--params 与 .product-globe 拿它们
     算负外边距。案例页同时 link 了 landing.css，撞名会串。 */
  /* 问号方块。--q-size 是唯一的旋钮，方框的网格列、方块尺寸、字形大小
     都从它推出来。⚠️ 两个约束：
       ① --q-size ÷ --q-pitch 必须整除，否则方块边缘会切出半个点
          （现在 108÷4.5=24、窄屏 54÷4.5=12，都整）
       ② 字形高固定取 0.74×，这是 54/40 那一版定下来的比例 */
  --q-size:108px;
  --q-pitch:4.5px;
  --q-dot:.87px;
  --lede-gap:44px;
  --hero-art-w:clamp(280px,40vw,620px);
  --hero-art-rise:80px;
  --case-top:104px;
  --case-bot:110px;
}

*{box-sizing:border-box;margin:0;padding:0;}
html{scroll-behavior:smooth;background-color:var(--paper);background-image:var(--grid);background-size:var(--grid-size);}
body{min-width:320px;background:transparent;color:var(--text);font-family:var(--font-body);font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased;}
button,input{font:inherit;color:inherit;}
img{max-width:100%;}
ol,ul{list-style:none;}

/* 案例页共用滚动条。页面和确实需要滚动的内部数据容器使用同一套直角、
   低对比度外观；案例专属 CSS 不再重复定义。滚动条只负责外观，不能拿来
   掩盖页面横向溢出。 */
*{scrollbar-width:thin;scrollbar-color:var(--fill) var(--paper);}
*::-webkit-scrollbar{width:10px;height:10px;}
*::-webkit-scrollbar-track{background:var(--paper);}
*::-webkit-scrollbar-thumb{min-width:30px;min-height:30px;border:2px solid var(--paper);border-radius:0;background:var(--fill);}
*::-webkit-scrollbar-thumb:hover{background:var(--case-accent);}
*::-webkit-scrollbar-corner{background:var(--paper);}

.mono{font-family:var(--font-mono);font-weight:var(--label-weight);font-variant-numeric:tabular-nums;}
.section-label{font-size:10px;line-height:1.2;letter-spacing:.17em;text-transform:uppercase;}
.shell{max-width:var(--case-max);margin:0 auto;padding:0 var(--case-pad);}
.status-dot{width:7px;height:7px;background:var(--case-accent);box-shadow:0 0 12px color-mix(in srgb,var(--case-accent) 70%,transparent);}

/* Shared section entrance. Case-specific scripts only toggle is-revealed; the
   motion language belongs to the page system, not to an individual case. */
.case-scroll-reveal{opacity:1;transform:none;}
.is-enhanced .case-scroll-reveal{opacity:0;transform:translate3d(0,28px,0);transition:opacity .72s ease-out,transform .86s cubic-bezier(.2,.7,.2,1);will-change:opacity,transform;}
.is-enhanced .case-scroll-reveal.is-revealed{opacity:1;transform:translate3d(0,0,0);}

/* 视觉隐藏但留给读屏与无 JS —— 全站硬规矩：可见性不依赖脚本 */
.sr{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;}

/* ── 顶部导航 ────────────────────────────────────────────────────────────
   ⚠️ 下面四条是从 case-detail.css 原样搬过来的，一个值都没改。
   坑：`.mast` 主体在 landing.css 里，但**左栏这四条只在案例页样式表里**。
   换样式表时如果只搬了标记没搬这几条，导航左栏会掉回默认字号 ——
   已经踩过一次。改这里之前先确认 landing.css 里确实没有同名规则。   */
.mast-case{display:flex;flex-direction:column;align-items:flex-start;gap:8px;}
.mast-case-no{font-family:var(--font-display);font-size:clamp(26px,2.6vw,36px);
  font-weight:200;line-height:1.1;letter-spacing:var(--disp-tracking-md);
  color:var(--text);margin:0;}
.mast-case-status{display:flex;align-items:center;gap:16px;margin:0;
  font-size:9px;letter-spacing:.15em;text-transform:uppercase;color:var(--text-mute);}
.mast-case-back{display:inline-flex;align-items:center;gap:10px;
  font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--text);border-bottom:2px solid transparent;padding-bottom:2px;}
.mast-case-back:hover{border-bottom-color:var(--ac-base);}

/* ── HERO ──────────────────────────────────────────────────────────────── */
.case-hero{max-width:var(--case-max);margin:0 auto;padding:52px var(--case-pad) var(--case-bot);}
/* kicker：一行点分隔，不加方框 —— 参考页就是这么写的
   （Indonesia · Fiscal policy · Resolved case）。
   分隔点用 ::before 生成，不写进标记：它是排版符号不是内容，
   以后加减标签不用手动挪点。 */
.case-chips{display:flex;flex-wrap:wrap;align-items:baseline;gap:0 11px;margin-bottom:30px;
  font-size:9px;letter-spacing:.15em;text-transform:uppercase;}
.case-chips span{display:inline-flex;align-items:baseline;gap:11px;}
.case-chips span + span::before{content:"·";color:var(--fill);letter-spacing:0;}
.case-chips span.is-freeze{color:var(--case-accent);}
.case-hero h1{max-width:19ch;font-family:var(--font-display);font-size:clamp(34px,4.4vw,64px);font-weight:250;letter-spacing:var(--disp-tracking-md);line-height:1.05;}
/* .case-sub 已删：hero 导语改用 .case-question.is-lede（框 + 表头）。 */

/* 逐字问题 —— 这是审计对象，所以给它一个被引用的样子，不当正文排 */
/* ⚠️ 不要给这类文本块加「单边加粗彩色竖条」（border-left:3px solid accent）。
   那是最典型的模板腔，一眼假。这一页的框语言只有一种：四边 1px。
   要让一块内容显得「被引用」，靠它上面那行 mono 小标签，不靠一条竖杠。 */
/* 右上角一个实心问号方块。内容在左，标记在右。 */
.case-question{margin-top:34px;padding:22px 26px;border:1px solid var(--rule);background:var(--paper);
  display:grid;grid-template-columns:minmax(0,1fr) var(--q-size);gap:20px;align-items:start;}
/* 只作用于表头那个 span。写成 `.case-question span` 会连右上角的问号方块
   一起套中，而且 (0,1,1) 还压得过 .q-mark 的 (0,1,0) —— 踩过一次：
   问号被强制成 8px + display:block，缩在方块左上角。 */
.case-question > div > span{display:block;margin-bottom:11px;font-size:8px;letter-spacing:.16em;text-transform:uppercase;}
.case-question p{max-width:96ch;font-size:14px;font-weight:300;line-height:1.7;}
/* 术语注释。只出现在 hero 那一版，**不要**加到审计条那一版：那一段的
   全部价值就是「登记在案、一个字都没动」，在框里补一句我们写的解释会
   稀释这个断言。读者在 hero 已经看过一次了。
   不加分隔线：这一页的框语言是四边 1px，框内再切一道横线会多出一层
   层级；靠 --fill 的色差 + mono 的引导词已经够读成脚注。
   术语用 mono 起头，跟 .brier-note b 同一个手法（本页第二处脚注体）。
   ⚠️ 选择器必须写成 `.case-question p.q-gloss`(0,2,1)。只写 `.q-gloss`
   是 (0,1,0)，压不过上面的 `.case-question p` (0,1,1)，字号会被拉回 14px
   —— 跟 .q-mark 当初被 `.case-question span` 压中是同一个坑，已踩两次。 */
.case-question p.q-gloss{margin-top:18px;max-width:96ch;font-size:11px;
  font-weight:300;line-height:1.55;color:var(--fill);}
.case-question p.q-gloss b{font-family:var(--font-mono);
  font-weight:var(--label-weight);font-size:10px;letter-spacing:.06em;}
/* hero 里那一版跟审计条里那版**样式完全相同**（14px / padding 22px 26px /
   96ch），只有上间距不一样。用户点名要「当时一样的样式」，别再给它单独
   放大字号。 */
.case-question.is-lede{margin-top:var(--lede-gap);}

/* 问号方块。两件事：
   ① 底是**点阵**，不是实心 —— 借的就是全站页面底那套语汇，只是点色从
      --dim 换成 --fill。它是弱装饰，隐约可见即可。
      2026-08-12 整体放大一倍：方块 54→108，字形 40→80，点距 3.375→4.5。
      点距为什么不跟着翻倍：6.75px 试过，点太大，问号的形直接碎掉（那一版
      像粗网点海报，跟这页别的东西不是一个精度）。4.5 是「点还看得出是点、
      形又没散」的折中。108 ÷ 4.5 = 24 整除。
   ② 问号是 Science Gothic 的 ? 字形**转成的轮廓**，不是字体，也不是手绘。
      页面没有、也不会加载这个字体 —— 只有这一个字符，取它的轮廓贴进
      HTML 就够了，比为一个装饰拉一整份字体划算得多。
        字体：Science Gothic v1.035（OFL-1.1，Google Fonts）
        实例：wght 600 · wdth 130 · CTRS 0 · slnt 0
        轮廓：fontTools 取 'question' 字形，y 轴翻转后按外框归一到
              高 24 单位 → viewBox "0 0 21.15 24"，坐标保留两位小数
      要换粗细/宽度就重跑这套参数重新导出，不要手动去改 d 里的数字。
      注意它是**填充**图形（fill），不是描边 —— 别再给它加 stroke-width。
   颜色是 --paper，跟框底同色，所以它不是画上去的，是把点**擦掉**的一块
   空白，问号以负形浮现。--paper 在深色带跟着变深，两带同一个效果。

   ⚠️ 点距与字形尺寸是**一对**：形靠擦点显影，笔画要跨过好几个点距才连得
   起来。实测 4.5px 点距下这个形就开始碎，6px 基本没了。
   ⚠️ 字重也参与这对关系：擦掉的面积越大，装饰就越不「弱」。实测 wght 600
      的墨量约是上一版手绘描边的 1.8 倍，已经是「看得出是问号、又还没变成
      一坨」的上限附近；再往 800/900 走，碗里的空当会被点填死。 */
.q-mark{width:var(--q-size);height:var(--q-size);align-self:center;
  display:grid;place-items:center;background-color:transparent;
  background-image:radial-gradient(circle at center,
    var(--fill) var(--q-dot),transparent calc(var(--q-dot) + .16px));
  background-size:var(--q-pitch) var(--q-pitch);}
/* 宽度让字形自己定（21.15 : 24），锁死宽高会把它压扁。 */
.q-mark svg{height:calc(var(--q-size) * .74);width:auto;display:block;
  fill:var(--paper);stroke:none;}

/* ── 时间轨 ─────────────────────────────────────────────────────────────
   一条实线，五个刻度，冻结点是唯一的朱色标记。
   2026-08-12 之前这里是「冻结轨」：冻结点左侧实线、右侧虚线，外加一个
   带删除线的幽灵标记（法定生效日）。整套撤掉了 —— 用户直接问「这个是
   什么意思」，就是它没说清楚的证据；补图例要多一行字，不如让时间轴只做
   时间轴。「冻结之后的事没进包」这句在页尾审计条里已经有了。 */
.rail-wrap{margin-top:52px;border:1px solid var(--edge);background:var(--paper);}
.rail-head{display:flex;flex-wrap:wrap;gap:18px;justify-content:space-between;padding:14px 22px;border-bottom:1px solid var(--rule);font-size:8px;letter-spacing:.14em;text-transform:uppercase;}
.rail-head b{color:var(--case-accent);font-weight:var(--label-weight);}
.rail{--rail-pad:22px;--rail-dot:9px;
  position:relative;padding:74px var(--rail-pad) 34px;
  display:grid;grid-template-columns:repeat(var(--steps,5),minmax(0,1fr));gap:18px;}
/* 线是**一整条**，不再是每一步各画一段。
   两端各缩进 padding + 半个标记 = 26.5px，左右到大边框的距离由构造保证
   相等，不靠人去对。以前分段画是为了在冻结点切换实线/虚线，那个需求没了。
   旧写法还留了个 bug：`:last-child` 被幽灵标记那个 li 占着，所以末段连线
   一直画到框外，右端顶死在边框上（左端 28px、右端 0px）。
   y = 50px = padding-top 74 - 24，跟标记中心对齐。 */
.rail::before{content:"";position:absolute;top:50px;height:0;
  left:calc(var(--rail-pad) + var(--rail-dot) / 2);
  right:calc(var(--rail-pad) + var(--rail-dot) / 2);
  border-top:1px solid var(--on);}
.rail-step{position:relative;padding-top:0;}
/* ⚠️ 必须写成 `> i`。刻度点是 .rail-step 的**直接子元素**；步骤的正文段落
   里也可能出现行内元素（冻结那一步的 p 里就放了 logo），松散的
   `.rail-step i` 会把它们一起套成 9px 绝对定位的小方块。
   同类坑本页已经踩过两次（.case-question span 压中 .q-mark、
   .q-gloss 被 .case-question p 压中）。 */
.rail-step > i{position:absolute;left:0;top:-28px;
  width:var(--rail-dot);height:var(--rail-dot);
  border:1px solid var(--on);background:var(--paper);}
.rail-step.is-freeze > i{width:13px;height:13px;top:-30px;left:-2px;border:0;background:var(--case-accent);box-shadow:0 0 14px color-mix(in srgb,var(--case-accent) 70%,transparent);}
/* is-after 原来把冻结后的标记与文字压淡一档。虚线体系撤掉后这个区分没有
   任何图例支撑，一并取消 —— 整条轨上唯一的区分就是朱色冻结点，而它自己
   带着 "1 NOV 2021 · FREEZE" 那行字，不用猜。class 留在标记里当钩子。 */
.rail-step time{display:block;font-family:var(--font-mono);font-weight:var(--label-weight);font-size:9px;letter-spacing:.11em;text-transform:uppercase;font-variant-numeric:tabular-nums;}
.rail-step p{max-width:30ch;margin-top:9px;font-size:12px;font-weight:300;line-height:1.5;}
/* 冻结点会闪。周期与节奏跟误差格右下角那个方块**完全一致**（1.1s、
   steps(1,end)、55% 处切换），一页上两处闪烁必须同频，否则读起来是两套
   系统各闪各的。两者都从加载起算，所以相位也是对齐的。
   ⚠️ 但**不能直接套 tile-caret**：那组关键帧灭到 opacity 0。误差格那个
   方块在角上，灭掉没关系；这个方块是**轨道上的一个刻度**，灭到 0 会在
   五个刻度里留一个洞，看起来像少画了一个点。实测过，很明显。
   所以低位停在 .35：方块始终在，只是从「亮着」变成「暗着」。 */
@keyframes rail-pulse{0%,55%{opacity:1}55.01%,100%{opacity:.35}}
.rail-step.is-freeze > i{animation:rail-pulse 1.1s steps(1,end) infinite;}
@media (prefers-reduced-motion:reduce){
  .rail-step.is-freeze > i{animation:none;}
}
/* Yarrow 标记。**内联 SVG**，不是 <img>、也不是 CSS mask。三条路都试过：
     · <img src="assets/yarrow_l.svg">：源文件里路径写死 fill="white"，
       深色带没问题，搬到浅色带就消失了。
     · CSS mask + 外链 SVG：颜色对，但 **file:// 下不渲染**（Chromium 把
       本地文件当跨源，遮罩取不到）。双击打开 HTML 时 logo 是一片空白 ——
       实测过，这是我们撤掉它的直接原因，评审是直接开文件看的。
     · 内联：两个问题都没有。代价是图形数据复制进了页面。
   ⚠️ 源文件仍是 assets/yarrow_l.svg（2026-08-12 取），**改了 logo 要手动
   同步这里**。同步时记得把 path 上的 fill="white" 去掉 —— 表现属性会压过
   继承来的 fill:currentColor，留着的话两带自适应就失效了。 */
.yl{display:inline-block;width:1.25em;height:1.25em;
  margin-right:.5em;vertical-align:-.26em;
  fill:currentColor;}
.rail-step.is-freeze time{color:var(--case-accent);}
.rail-step.is-freeze p{font-weight:400;}
/* 时间轴不再有收口句（图例已撤）。.rail 的下内边距从 26 提到 34，
   补上原来那条 sec-cap 分隔线带来的呼吸。 */

/* ── 读数格 ──────────────────────────────────────────────────────────────
   旧版写死三列。新内容包每案的格子数与内容都不同（B 要塞市场价，
   D 要同时放 raw 与 published 两个误差），所以列数走 --tiles。 */
.readout{position:relative;margin-top:34px;border:1px solid var(--edge);display:grid;grid-template-columns:repeat(var(--tiles,4),minmax(0,1fr));background:var(--paper);}
.tile{min-height:150px;padding:20px 24px 22px;border-right:1px solid var(--rule);display:flex;flex-direction:column;justify-content:space-between;gap:14px;}
.tile:last-child{border-right:0;}
.tile-label{font-size:9px;line-height:1;letter-spacing:.16em;text-transform:uppercase;}
.tile-val{font-family:var(--font-display);font-size:clamp(30px,3.1vw,46px);font-weight:250;letter-spacing:var(--disp-tracking-md);line-height:1;}
.tile-val sup{font-size:.4em;letter-spacing:0;margin-left:3px;vertical-align:baseline;}
/* 注脚行用 --fill。⚠️ 别写 --text-2，它算出来等于 --text（见文件头）。
   代价说明白：#6D747E 对纸面 3.57:1，11px 不过 WCAG AA 的 4.5:1。
   这是「把注脚压弱」这个意图自带的代价，不是失误 —— 这一行说的事
   在别处另有交代（Brier 那句解释就在读数格正下方）。 */
.tile-note{font-size:11px;font-weight:300;line-height:1.45;color:var(--fill);}
/* 朱色只留给「我们的判断」这一格。结果格与外行格都回普通深色 ——
   四格里同时三处朱色，指示灯就不是指示灯了。 */
.tile.is-ours .tile-val{color:var(--case-accent);}
.tile.is-market .tile-val{color:var(--text-2);}
.tile.is-result .tile-val{color:var(--text);}
/* 「外行会给的答案」那一格。它是被我们否掉的答案，不该抢色。
   这格的值是一句话不是数字，字号要小一档，否则挤出格子。 */
.tile.is-naive .tile-val{font-size:clamp(22px,2.1vw,30px);color:var(--text);}

/* 误差格 —— 这一页的落点：前三格铺垫，这一格给分数。
   标记它的方式是**点阵底 + 右下角一个会闪的方块**，不是实心色块。

   为什么不实心：一大片饱和朱色（hero 里三百多 × 一百五）在这套版面里
   太吵，而且朱色在全站是「指示灯」—— 指示灯不该有巴掌那么大。
   点阵把同样的朱色摊薄到约 12.6% 的覆盖率（πr²/节距²），一眼看得出
   这格不一样，但不抢。

   节距刻意取 6px，跟页面底的那层栅格（tokens.css 的 --grid，6px / r0.6）
   同一个节奏，只是点更大更热 —— 读起来是「同一张纸，通了电」，
   不是「贴了一块别的材质」。⚠️ 改节距就失去这层关系，要改请连
   --grid-size 一起想。

   格子里的字**全部走朱色**，靠色相跟旁边三格的深灰分开，而不是靠底色块。
   点降到 30% 之后已经不吃字了，所以之前给小字垫的那层纸色通道撤掉了
   （2026-08-12）—— 那层是为 100% 不透明的点做的补丁，点变淡就没必要，
   留着反而多两条横杠。

   两带自适应：--case-accent 在 .sec-dark 里会重映成 #E08059，
   所以这一格搬到深色带不用另写规则。
   ⚠️ 对比度的账在这里记一笔，都是「刻意压弱」不是疏漏：
     朱色对纸面 2.97:1；注脚再乘 0.7 后约 2.14:1。
     这一格的信息在正下方 .brier-note 那句里是重复交代过的。 */
/* --err-dot 是点的颜色，唯一的调节旋钮。10%：点心实际落在
   rgb(219,211,211)，覆盖率 12.6% × 0.1 ≈ 1.3% 的等效墨量 —— 比页面底
   那层栅格（6px / r0.6，3.1%）还轻一半。已经是「余光才看得到」的量级，
   再往下就等于没有了。
   ⚠️ 用 color-mix 而不是写死 rgb()：这样 .sec-dark 里 --case-accent
   换成 #E08059 时会跟着走，两带不用各写一遍。 */
.tile.is-error{position:relative;overflow:hidden;
  --err-dot:color-mix(in srgb,var(--case-accent) 10%,transparent);
  background-color:transparent;
  background-image:radial-gradient(circle at center,var(--err-dot) 1.2px,transparent 1.32px);
  background-size:6px 6px;}
.tile.is-error .tile-label,
.tile.is-error .tile-val,
.tile.is-error .tile-note{color:var(--case-accent);}
.tile.is-error .tile-note{opacity:.7;}

/* 右下角的方块 —— 旧版就有，这次让它闪。
   为什么是它、不是「整块底色呼吸」或「数字后跟光标」：
     · 底色呼吸要让品牌朱色每两秒变一轮，而且动的是一大片；
     · 数字后的光标会跟着滚入递增一起动，两个动作打架。
   这个方块本来就在，是这一格的固有标记，让它闪不引入新元素。
   动效面积 10×10，是三种里最小的。 */
.tile.is-error::after{content:"";position:absolute;right:0;bottom:0;
  width:10px;height:10px;background:var(--case-accent);
  animation:tile-caret 1.1s steps(1,end) infinite;}
@keyframes tile-caret{0%,55%{opacity:1}55.01%,100%{opacity:0}}
@media (prefers-reduced-motion:reduce){
  .tile.is-error::after{animation:none;}
}

/* Brier 解释行 —— 内容包硬要求：每次出现 error/Brier 都要带一句 */
.brier-note{margin-top:0;padding:13px 24px;border:1px solid var(--rule);border-top:0;background:color-mix(in srgb,var(--on) 3%,transparent);font-size:11px;font-weight:300;line-height:1.55;color:var(--text-2);}
.brier-note b{font-family:var(--font-mono);font-weight:var(--label-weight);font-size:10px;letter-spacing:.06em;color:var(--text);}

/* commit 闸门与揭晓对比条已删除（2026-08-10）：那是自创交互，按内容包
   的模块顺序回正时一并撤掉。文档里确实有一条「commit-then-reveal 滑条」
   的互动建议，但它指向的原型 docs/brief/case_carbontax_reference.html
   我们手上没有，等拿到再谈。 */

/* ── 通用区块头 ─────────────────────────────────────────────────────────── */
.sec-case{max-width:var(--case-max);margin:0 auto;padding:var(--case-top) var(--case-pad) var(--case-bot);}
.sec-dark .sec-case{max-width:var(--case-max);margin:0 auto;}
.block-head{display:grid;grid-template-columns:7fr 5fr;column-gap:24px;align-items:end;margin-bottom:52px;}
.block-head .section-label{grid-column:1/-1;}
.block-head h2{grid-column:1;margin-top:18px;max-width:24ch;font-family:var(--font-display);font-size:clamp(24px,2.3vw,34px);font-weight:300;letter-spacing:var(--disp-tracking-md);line-height:1.16;}
.block-head .head-note{grid-column:2;text-align:right;font-size:12px;font-weight:300;line-height:1.6;color:var(--text-2);}
/* head-note 是可选的：没有它时 h2 独占左列，右列自然空着，不用额外规则 */
.head-note.has-sad{position:relative;}
.hard-sad{position:absolute;right:0;bottom:calc(100% + 14px);width:72px;height:72px;display:grid;place-items:center;background-image:radial-gradient(circle at center,var(--case-accent) var(--q-dot),transparent calc(var(--q-dot) + .16px));background-size:var(--q-pitch) var(--q-pitch);}
.hard-sad svg{display:block;width:100%;height:100%;}
.hard-sad rect{fill:var(--paper);}
.hard-sad path{fill:none;stroke:var(--paper);stroke-width:9;stroke-linecap:square;}

/* 01 那一节的导语也走这个右列位（2026-08-12）。改之前它是全页唯一一个
   把导语单独占一行的小节，跟 02～05 不是一套。
   对齐跟兄弟 head-note 一致 —— 右对齐。（我一度改成左对齐，理由是这段有
   6 行、参差左缘影响阅读；用户否掉了：整列右缘对齐这件事在这个版面里更
   重要。别再改回来。）
   只有一处跟兄弟不同：**顶对齐**。默认 align-items:end 是给「短图注贴着
   h2 底」设计的，这里导语比 h2 高，贴底会让 h2 孤零零地沉在下面。
   ⚠️ align-items 写在 .block-head.has-lede 上，别改全局 —— 02～05 的
   短图注依赖底对齐。 */
.block-head.has-lede{align-items:start;}
.block-head.has-lede h2{margin-top:0;}
.head-note.is-pair{display:flex;flex-direction:column;gap:16px;}
/* 13px / 250：比兄弟 head-note（12/300）大半档、轻一档 —— 它是小节导语，
   不是图注。250 需要 Lexend 的字重区间放到 200，见 case-01.html 的字体
   link（原来是 300..500，300 是地板，写 250 会被夹回 300）。 */
.head-note.is-pair p{font-size:13px;font-weight:250;line-height:1.7;}

/* ── 证据板 ──────────────────────────────────────────────────────────────
   冻结证据是逐字不可改的一整段（anchor sha 按原文算）。这里只做两件事：
   在句号处断行、给每句挂一个标签。**一个字符都没动**，拼回去仍是原文。
   标签分类沿用产品自己在 D 案原文里用的 [OFFICIAL]/[PRESS]/[PRECEDENT]，
   拿不准的句子留空不打标。 */
/* 证据筛选按钮已删除：同上，自创交互。逐句拆行 + 标签是内容包点名要的，
   保留；.ev-line 的 is-dim / is-hit 两个态也一并去掉了。 */
/* 曾经这里是 border-top:0 —— 因为上面紧贴着 .ev-toolbar 筛选按钮条，
   由它那条底边充当封顶。按钮删掉后这个盒子就少了一条边。
   ⚠️ 规律：凡是写 border-top:0 的盒子，都在赌「上面有个元素紧贴着」。
   删那个元素之前，先回来把这条边补上。 */
.ev-body{border:1px solid var(--rule);background:var(--paper);}
.ev-line{display:grid;grid-template-columns:138px minmax(0,1fr);
  border-bottom:1px solid var(--hair);}
.ev-line:last-child{border-bottom:0;}
/* 左栏原来 118px 里只有一个 22px 图标加一个词，大半是空的。现在装三样：
   序号 / 图标 / 类别。跨两行，跟右边的图＋正文对齐。
   （曾经还有第四样「方向标 ↓SLIPS / ↕BOTH」，2026-08-12 按用户要求撤掉，
   理由是保持简洁。判断依据留在 git 历史里，要恢复看那一版。） */
.ev-kind{grid-column:1;grid-row:1 / span 2;
  padding:19px 16px;border-right:1px solid var(--hair);
  display:flex;flex-direction:column;align-items:flex-start;gap:10px;}
.ev-kind b{font-family:var(--font-mono);font-weight:var(--label-weight);font-size:8px;letter-spacing:.13em;text-transform:uppercase;color:var(--text-mute);}
/* 序号：给这块一个可以指认的坐标（「第 03 条」），也让五行不再是一团。 */
.ev-no{font-size:9px !important;letter-spacing:.1em !important;color:var(--fill) !important;
  font-variant-numeric:tabular-nums;}

/* 每条证据配一张小图，**放在正文上方**。
   素材全部取自这句话本身（数字、机构名、因果关系），没有引入任何新事实 ——
   这一节是逐字不可改的，图只能是原文的另一种画法，不能是补充说明。
   ⚠️ 别画成「像数据但不是数据」的东西。第 05 条最早画的是一条能源价格
   走势曲线，形状是我编的 —— 在一个主打可审计的页面上放一条假曲线，
   性质不对。改成了因果链（价格↑ → 加成本的政策 → 推迟），它是原文
   直接说的关系，不假装是序列数据。 */
/* margin-top 18 不是随手写的：左栏序号 01 的字冠顶落在行顶 +21px
   （.ev-kind 的 padding-top 19 + 9px 字的内部留白），图里首行标签的基线
   在 viewBox 的 y=10，所以 18 + 10 - 字冠高 ≈ 21，两边字冠顶对齐。
   ⚠️ 改 .ev-kind 的 padding-top、改 .ev-no 的字号、或者改图里首行标签的
   基线 y，这三样任何一个动了，这个 18 都要跟着重算。
   五张图的首行标签基线已经统一到 y=10，别再各画各的。 */
.evfig{grid-column:2;grid-row:1;width:520px;max-width:calc(100% - 48px);height:auto;
  margin:18px 24px 0;overflow:visible;font-family:var(--font-mono);}
.evfig text{fill:var(--text);font-size:8.5px;letter-spacing:.02em;}
.evfig .l{font-size:7px;letter-spacing:.13em;fill:var(--fill);}
.evfig .v{font-size:9px;}
.evfig .hot{fill:var(--case-accent);}
.evfig .bar{fill:var(--fill);}
.evfig .bar.hot{fill:var(--case-accent);}
.evfig .box{fill:none;stroke:var(--fill);stroke-width:1;}
.evfig .box.fill{fill:var(--fill);stroke:none;}
.evfig .box.wide{stroke:var(--rule);}
.evfig .box.wide.hot{stroke:var(--case-accent);fill:none;}
.evfig .ln,.evfig .ax,.evfig .arw,.evfig .tick{fill:none;stroke:var(--fill);stroke-width:1;
  stroke-linecap:square;stroke-linejoin:miter;}
.evfig .ln{stroke:var(--text);}
.evfig .dash{stroke-dasharray:4 4;stroke:var(--fill);}
.evfig .arw.hot{stroke:var(--case-accent);}

/* 正文铺满整格，不设 max-width。
   量过：1440 下这一格净宽 1156px，一行约 155 字符 —— 比常规上限（90～100）
   长得多。这里可以接受，理由是**每条只有 2～3 行**：长行的代价是回到左边缘
   时找不着下一行，行数少就不构成问题；而右边空着 375px 反而一眼就是错的。
   ⚠️ 如果以后某一条被替换成长段落（超过 5 行），这条要重新评估。
   ⚠️ viewBox 的宽度必须跟 .evfig 的 CSS 宽度相等（现在都是 520），否则
   SVG 里的文字会跟着缩放比例一起变大变小 —— 图不是位图，别直接拉 100%。 */
.ev-line > p{grid-column:2;grid-row:2;
  padding:12px 24px 20px;font-size:14px;font-weight:300;line-height:1.72;}
/* 金额与日期改用 display 字体 + 等宽数字。**只加标记，不改一个字符** ——
   哈希算的是文本内容，标记不参与。规则就一条：钱和日期，别的不标，
   标多了就没有节奏了。 */
.ev-line .num{font-family:var(--font-display);font-weight:400;font-size:.92em;
  font-variant-numeric:tabular-nums;letter-spacing:.01em;}
.ev-line[data-tag=official] .ev-kind b{color:var(--text);}
/* 先例那一类给一点朱色 —— 它是这一案真正起作用的证据。
   只染文字不染图标：22px 的彩色描边看着像渲染故障，而且图标统一中灰
   才读得出「这是一层系统」。 */
.ev-line[data-tag=precedent] .ev-kind b{color:var(--case-accent);}

/* ── 分析师面板 ──────────────────────────────────────────────────────────
   MECHANISM 原文每人 60–100 词，比旧内容长两三倍，一次只显示一张会让人
   看不到全貌。所以改成「全部平铺 + 原生 <details> 折叠」：
   折叠态 = 模型 + 概率 + 文档自带的那句斜体摘要；展开 = 逐字原文。
   用原生 details 是为了无 JS 时折叠仍然可用。 */
.panel-meta{display:flex;flex-wrap:wrap;gap:0;border:1px solid var(--edge);background:var(--paper);}
.panel-meta div{flex:1 1 150px;min-height:78px;padding:15px 20px;border-right:1px solid var(--rule);display:flex;flex-direction:column;justify-content:space-between;}
.panel-meta div:last-child{border-right:0;}
.panel-meta span{font-family:var(--font-mono);font-weight:var(--label-weight);font-size:8px;letter-spacing:.13em;text-transform:uppercase;color:var(--text-mute);}
.panel-meta strong{font-family:var(--font-display);font-size:19px;font-weight:300;letter-spacing:var(--disp-tracking-md);font-variant-numeric:tabular-nums;}
.panel-indep{padding:15px 20px;border:1px solid var(--rule);border-top:0;background:color-mix(in srgb,var(--on) 3%,transparent);font-size:12px;font-weight:300;line-height:1.6;max-width:none;color:var(--text-2);}

/* 点阵图：一条轴，六个点，中位线。轴永远 0–1，不放大 —— 放大会让
   「分歧有多大」失真，而分歧本身是内容。 */
/* 它跟上面隔着 42px，是个独立的盒子，必须四边俱全。
   （早先误抄了 border-top:0，从第一版起顶边就一直缺着。） */
/* 图例移进框内、放在图表上方（2026-08-12）。原来它是 .dots 之后的一条
   独立横条，读者要看完图再往下找形状对照，眼睛来回跑。
   长的那句说明**没有跟着上去**：它是一条注意事项（两次跑不足以给模型
   排名），放在图前面会挡着人看图，留在框底当脚注。
   上内边距因此从 56 降到 22 —— 那 56 里有 34 是留给中位线标签
   （.dots-median b 的 top:-16px 加 .dots-field 的 top:-14px）的净空，
   现在图例本身就占了这个高度，标签有地方待。 */
.dots{position:relative;margin-top:42px;padding:22px 22px 0;border:1px solid var(--rule);background:var(--paper);}
/* 场地左右各留 22px：0.00 与 1.00 的标记线才不会跟容器边框糊在一起，
   否则「真值线」看起来像是面板的边，而不是图上的一个位置。 */
.dots-field{position:relative;height:120px;margin:0 22px;border-left:1px solid var(--hair);border-right:1px solid var(--hair);background:repeating-linear-gradient(90deg,var(--hair) 0,var(--hair) 1px,transparent 1px,transparent 10%);}
.dot{position:absolute;left:var(--p);top:50%;width:15px;height:15px;transform:translate(-50%,-50%);border:2px solid var(--on);border-radius:50%;background:var(--paper);}
.dot.m-haiku{border-radius:50%;}
.dot.m-sonnet{border-radius:0;}
.dot.m-gpt{border-radius:0;transform:translate(-50%,-50%) rotate(45deg);}
.dot.is-excluded{border-style:dashed;border-color:var(--fill);background:transparent;}
.dot b{position:absolute;left:50%;bottom:22px;transform:translateX(-50%);font-family:var(--font-mono);font-weight:var(--label-weight);font-size:9px;white-space:nowrap;color:var(--text-2);}
.dot.m-gpt b{transform:translateX(-50%) rotate(-45deg);}
/* 相邻两点常常只差两三个百分点，标签会叠。交错上下排，不用挪点。 */
.dot.lbl-down b{bottom:auto;top:22px;}
.dot.m-gpt.lbl-down b{transform:translateX(-50%) rotate(-45deg);}
.dots-median{position:absolute;left:var(--m);top:-14px;bottom:-1px;border-left:1px solid var(--case-accent);}
.dots-median b{position:absolute;left:8px;top:-16px;white-space:nowrap;font-family:var(--font-mono);font-weight:var(--label-weight);font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:var(--case-accent);}
/* 真值标记。放上去之后，每个点到它的水平距离就是那个分析师的误差 ——
   Brier 从一个抽象数字变成图上量得出来的长度。 */
.dots-truth{position:absolute;left:var(--t);top:-14px;bottom:-1px;border-left:2px solid var(--on);}
.dots-truth b{position:absolute;left:8px;bottom:-1px;white-space:nowrap;font-family:var(--font-mono);font-weight:var(--label-weight);font-size:9px;letter-spacing:.1em;text-transform:uppercase;}
.dots-axis{display:flex;justify-content:space-between;margin:0 22px;padding:12px 0 18px;font-family:var(--font-mono);font-weight:var(--label-weight);font-size:8px;letter-spacing:.1em;color:var(--text-mute);}
/* 窄屏取值行。为什么需要它：点上的标签是绝对定位在点的 x 上的，而六个点
   全挤在 0.08–0.30 那一小段，场地一窄标签就必然互相压字（实测 900px 起
   "A4 0.25" 和 "A3 0.30" 压 17px，390px 有三对压）。交错上下排只能撑到
   两行，救不了。所以窄屏干脆把标签从图里拿出来单排一行。 */
.dots-values{display:none;}
.dots-values i{display:inline-block;width:9px;height:9px;margin-right:7px;border:1.5px solid var(--on);vertical-align:-1px;}
.dots-values i.m-haiku{border-radius:50%;}
.dots-values i.m-gpt{transform:rotate(45deg);}

.dots-key{display:flex;flex-wrap:wrap;gap:22px;margin:0 22px 40px;
  font-family:var(--font-mono);font-weight:var(--label-weight);font-size:8px;
  letter-spacing:.12em;text-transform:uppercase;color:var(--text-mute);}
.dots-key i{display:inline-block;width:9px;height:9px;margin-right:7px;border:1.5px solid var(--on);vertical-align:-1px;}
.dots-key i.m-haiku{border-radius:50%;}
.dots-key i.m-gpt{transform:rotate(45deg);}
/* 框底的注意事项。跟 .sec-cap 同一档字，但留在框内 —— 它说的是这张图
   怎么读，不是这一节的小结。 */
.dots-note{margin:0 22px;padding:14px 0 16px;border-top:1px solid var(--hair);
  font-size:11px;font-weight:300;line-height:1.55;color:var(--fill);}

/* 分析师卡 */
.cards{margin-top:34px;border:1px solid var(--rule);background:var(--paper);}
.card{border-bottom:1px solid var(--hair);}
.card:last-child{border-bottom:0;}
.card > summary{list-style:none;padding:22px 26px;display:grid;grid-template-columns:78px 64px minmax(0,1fr) 26px;align-items:center;gap:20px;cursor:pointer;}
.card > summary::-webkit-details-marker{display:none;}
.card > summary:hover{background:color-mix(in srgb,var(--on) 4%,transparent);}
.card-id{font-family:var(--font-mono);font-weight:var(--label-weight);font-size:9px;letter-spacing:.12em;text-transform:uppercase;color:var(--text-mute);}
.card-p{font-family:var(--font-display);font-size:26px;font-weight:250;letter-spacing:var(--disp-tracking-md);line-height:1;font-variant-numeric:tabular-nums;color:var(--case-accent);}
.card-digest{font-size:14px;font-weight:300;line-height:1.5;}
.card-digest em{font-style:italic;}
.card-model{display:block;margin-top:6px;font-family:var(--font-mono);font-weight:var(--label-weight);font-size:8px;letter-spacing:.12em;text-transform:uppercase;color:var(--text-mute);}
.card-chev{justify-self:end;width:11px;height:11px;border-right:1px solid var(--fill);border-bottom:1px solid var(--fill);transform:rotate(45deg) translate(-3px,-3px);transition:transform .16s ease;}
.card[open] .card-chev{transform:rotate(225deg) translate(-3px,-3px);}
/* 正文左边距要对齐折叠态那句摘要（78 + 20 + 64），不是对齐概率数字，
   否则展开时视线要横向跳一次。 */
.card-body{padding:4px 26px 30px;display:grid;grid-template-columns:162px minmax(0,1fr);gap:20px;}
.card-body > div{grid-column:2;}
.card-verbatim span{display:block;margin-bottom:9px;font-family:var(--font-mono);font-weight:var(--label-weight);font-size:8px;letter-spacing:.14em;text-transform:uppercase;color:var(--text-mute);}
.card-verbatim p{max-width:84ch;font-size:13px;font-weight:300;line-height:1.75;}
.card-est{margin-top:20px;padding-top:18px;border-top:1px solid var(--hair);}
.card.is-excluded .card-p{font-family:var(--font-mono);font-size:11px;letter-spacing:.13em;text-transform:uppercase;color:var(--fill);}
.card.is-excluded .card-digest{color:var(--text-mute);}

/* ── 双轨图（A 案主视觉）─────────────────────────────────────────────────
   同一部法律分出两个工具：增值税跑在既有机制上准时到；碳税那条轨
   **物理上缺一段** —— 缺的那段就是从来没被造出来的实施细则。 */
.tracks{margin-top:44px;border:1px solid var(--edge);background:var(--paper);}
.tracks-src{padding:22px 26px;border-bottom:1px solid var(--rule);}
.tracks-src span{font-family:var(--font-mono);font-weight:var(--label-weight);font-size:8px;letter-spacing:.14em;text-transform:uppercase;color:var(--text-mute);}
.tracks-src strong{display:block;margin-top:8px;font-family:var(--font-display);font-size:20px;font-weight:300;letter-spacing:var(--disp-tracking-md);}
.track{position:relative;padding:30px 26px 34px;border-bottom:1px solid var(--hair);}
.track:last-child{border-bottom:0;}
.track-name{display:flex;flex-wrap:wrap;align-items:baseline;gap:14px;}
.track-name strong{font-family:var(--font-display);font-size:17px;font-weight:350;letter-spacing:var(--disp-tracking-md);}
.track-name span{font-family:var(--font-mono);font-weight:var(--label-weight);font-size:8px;letter-spacing:.13em;text-transform:uppercase;color:var(--text-mute);}
/* ⚠️ 这条线曾经是 `::before` 绝对定位 + `right:118px` —— 一个猜出来的
   魔法数字，猜的是「右边那个标签有多宽」。它猜错了：标签块实测 138px，
   于是线穿过终点方块一直顶到文字跟前；换上真字体（Azeret Mono 比回退
   等宽字体宽）标签块变成 159px，线直接插进文字 41px。

   现在线是 flex 里一个 `flex:1` 的元素，长度 = 剩下多少空间。
   标签多长、换什么字体、换成哪国语言，都不用再改这里。
   **别再往回写成百分比或固定 px。** */
.track-line{position:relative;min-height:46px;margin-top:22px;display:flex;align-items:center;gap:0;}
.track-rule{flex:1 1 auto;min-width:24px;height:0;border-top:2px solid var(--on);}
.track-rule.is-dashed{border-top:2px dashed var(--dim);}
/* 终点标记紧贴线尾（方块就是这条线的终点），文字再往后 10px —— 线永远
   碰不到字 */
.track-end{flex:none;display:flex;align-items:center;gap:16px;font-family:var(--font-mono);font-weight:var(--label-weight);font-size:9px;letter-spacing:.12em;text-transform:uppercase;}
.track-ok .track-end{color:var(--case-accent);}
.track-broken .track-end{color:var(--text-mute);}
.track-end i{flex:none;width:11px;height:11px;}
.track-ok .track-end i{background:var(--case-accent);box-shadow:0 0 12px color-mix(in srgb,var(--case-accent) 65%,transparent);}
.track-broken .track-end i{border:1px dashed var(--fill);border-radius:50%;}

/* 缺口标记 —— 静态，不可点。缺的那几样东西直接列在下面，不藏起来。
   同样改成 flex 项：宽度由内容决定，两侧留 16px 让它跟线断开。 */
.gap-mark{flex:none;margin:0 16px;padding:9px 14px;border:1px dashed var(--case-accent);background:var(--paper);color:var(--case-accent);font-size:8px;letter-spacing:.11em;text-transform:uppercase;line-height:1.4;text-align:center;}
.gap-list{margin-top:20px;border:1px solid var(--hair);}
.gap-list li{padding:13px 18px;border-bottom:1px solid var(--hair);font-size:12px;font-weight:300;line-height:1.5;}
.gap-list li:last-child{border-bottom:0;}
.gap-list li b{font-family:var(--font-mono);font-weight:var(--label-weight);font-size:8px;letter-spacing:.13em;text-transform:uppercase;color:var(--text-mute);margin-right:12px;}
.tracks-foot{padding:18px 26px;border-top:1px solid var(--rule);max-width:88ch;font-size:13px;font-weight:300;line-height:1.7;}

/* ── Calibration lab ─────────────────────────────────────────────────────
   参考页 case_carbontax_reference.html 的 "05 · Calibration lab"。
   位置、文案、误差算式照抄，只把配色换成本站的令牌。

   本站不给它编号：PDF 的内容模块是 01–05，这一节不在那份清单里，
   跟审计条一样属于「装置」。给它编号会让人以为它也是内容包定的。

   ⚠️ 无 JS 时整块不显示（下面的 display:none）。这不违反「可见性不依赖
   脚本」——它是一个练习，不是一段内容；里面出现的结果与面板误差在页面
   别处都已经写着。露出一个点不动的滑条才是真的坏。 */
.calib{display:none;}
.is-enhanced .calib{display:grid;grid-template-columns:1fr 1fr;gap:44px;align-items:start;}
.calib-copy h2{max-width:18ch;font-family:var(--font-display);font-size:clamp(24px,2.3vw,34px);font-weight:300;letter-spacing:var(--disp-tracking-md);line-height:1.16;}
.calib-copy p{max-width:48ch;margin-top:20px;font-size:14px;font-weight:300;line-height:1.7;}
.calib-copy .calib-rule{margin-top:16px;font-size:11.5px;line-height:1.6;color:var(--text-mute);}

.calib-widget{border:1px solid var(--edge);background:var(--paper);padding:24px 26px 26px;}
.calib-row{display:flex;align-items:baseline;justify-content:space-between;gap:20px;margin-bottom:14px;}
.calib-row span,.calib-row label{font-size:9px;letter-spacing:.15em;text-transform:uppercase;color:var(--text-mute);}
.calib-big{font-family:var(--font-display);font-size:36px;font-weight:250;letter-spacing:var(--disp-tracking-md);line-height:1;font-variant-numeric:tabular-nums;color:var(--case-accent);}

.calib-widget input[type=range]{width:100%;-webkit-appearance:none;appearance:none;height:26px;background:transparent;cursor:pointer;}
.calib-widget input[type=range]::-webkit-slider-runnable-track{height:1px;background:var(--on);}
.calib-widget input[type=range]::-moz-range-track{height:1px;background:var(--on);}
.calib-widget input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:15px;height:15px;margin-top:-7px;border:0;border-radius:50%;background:var(--case-accent);box-shadow:0 0 12px color-mix(in srgb,var(--case-accent) 65%,transparent);}
.calib-widget input[type=range]::-moz-range-thumb{width:15px;height:15px;border:0;border-radius:50%;background:var(--case-accent);}
.calib-widget input[type=range]:focus-visible{outline:2px solid var(--case-accent);outline-offset:6px;}
.calib-widget input[type=range]:disabled{cursor:default;}
.calib-widget input[type=range]:disabled::-webkit-slider-thumb{background:var(--fill);box-shadow:none;}
.calib-widget input[type=range]:disabled::-moz-range-thumb{background:var(--fill);}
.calib-scale{display:flex;justify-content:space-between;margin-top:2px;font-size:8px;letter-spacing:.1em;text-transform:uppercase;color:var(--text-mute);}

.calib-lock{margin-top:18px;width:100%;min-height:46px;border:1px solid var(--on);background:var(--on);color:var(--off);font-family:var(--font-mono);font-weight:var(--label-weight);font-size:9px;letter-spacing:.16em;text-transform:uppercase;cursor:pointer;}
.calib-lock:hover:not(:disabled){background:var(--case-accent);border-color:var(--case-accent);color:#fff;}
.calib-lock:disabled{background:transparent;color:var(--text-mute);border-color:var(--rule);cursor:default;}

.calib-reveal{display:none;margin-top:20px;padding-top:16px;border-top:1px solid var(--rule);}
.calib-reveal.is-on{display:block;}
.calib-reveal dl{display:grid;gap:0;}
.calib-reveal div{display:flex;align-items:baseline;justify-content:space-between;gap:18px;padding:9px 0;border-bottom:1px solid var(--hair);}
.calib-reveal div:last-of-type{border-bottom:0;}
.calib-reveal dt{font-size:9px;letter-spacing:.13em;text-transform:uppercase;color:var(--text-mute);}
.calib-reveal dd{font-family:var(--font-display);font-size:14px;font-variant-numeric:tabular-nums;text-align:right;}
.calib-reveal .is-you dd{color:var(--text);}
.calib-reveal .is-us dd{color:var(--case-accent);}
.calib-verdict{margin-top:14px;max-width:46ch;font-size:12.5px;font-weight:300;line-height:1.6;color:var(--text-2);}

/* Dot-matrix calibration console used by the public probability exercises.
   It is gated by the matrix child so older/reference sliders keep their own
   interaction treatment. */
.calib-terminal:has(.calib-matrix){--calib-pos:50%;position:relative;border:1px solid var(--rule);background:color-mix(in srgb,var(--on) 2%,transparent);}
.calib-widget:has(.calib-matrix){border-color:var(--rule);}
.calib-widget:has(.calib-matrix) .calib-big{min-width:4ch;text-align:right;font-size:42px;font-weight:500;background-image:radial-gradient(circle at center,var(--case-accent) .9px,transparent 1.12px);background-size:3px 3px;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;}
.calib-terminal:has(.calib-matrix) .calib-terminal-head{display:flex;justify-content:space-between;gap:18px;padding:8px 11px;border-bottom:1px solid var(--hair);font-size:7px;line-height:1.2;letter-spacing:.13em;text-transform:uppercase;color:var(--fill);}
.calib-terminal:has(.calib-matrix) .calib-terminal-head span:last-child{color:var(--case-accent);}
.calib-matrix{position:relative;overflow:hidden;height:74px;background-image:radial-gradient(circle at center,color-mix(in srgb,var(--fill) 58%,transparent) 1.15px,transparent 1.35px);background-size:7px 7px;}
.calib-matrix::before{content:"";position:absolute;inset:0 auto 0 0;width:var(--calib-pos);background-image:radial-gradient(circle at center,var(--case-accent) 1.15px,transparent 1.35px);background-size:7px 7px;}
.calib-scan{position:absolute;z-index:1;left:clamp(16px,var(--calib-pos),calc(100% - 16px));top:0;bottom:0;width:1px;background:var(--case-accent);box-shadow:0 0 13px color-mix(in srgb,var(--case-accent) 72%,transparent);transform:translateX(-50%);animation:case-calib-scan-pulse 2.8s ease-in-out infinite;}
.calib-scan::after{content:"↔";position:absolute;left:50%;top:50%;display:grid;place-items:center;width:32px;height:22px;background:var(--case-accent);color:var(--paper);font-family:var(--font-mono);font-size:11px;line-height:1;transform:translate(-50%,-50%);}
@keyframes case-calib-scan-pulse{0%,100%{box-shadow:0 0 6px color-mix(in srgb,var(--case-accent) 48%,transparent)}50%{box-shadow:0 0 18px color-mix(in srgb,var(--case-accent) 88%,transparent)}}
.calib-terminal:has(.calib-matrix) input[type=range]{position:absolute;z-index:2;inset:27px 0 0;width:100%;height:74px;margin:0;-webkit-appearance:none;appearance:none;opacity:0;cursor:ew-resize;}
.calib-terminal:has(.calib-matrix) input[type=range]::-webkit-slider-runnable-track{height:74px;background:transparent;}
.calib-terminal:has(.calib-matrix) input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:32px;height:74px;margin-top:0;background:transparent;box-shadow:none;}
.calib-terminal:has(.calib-matrix) input[type=range]::-moz-range-track{height:74px;background:transparent;}
.calib-terminal:has(.calib-matrix) input[type=range]::-moz-range-thumb{width:32px;height:74px;border:0;background:transparent;}
.calib-terminal:has(.calib-matrix):focus-within{outline:0;box-shadow:inset 0 0 0 2px var(--case-accent);}
.calib-terminal:has(.calib-matrix):hover:not(.is-locked) .calib-scan::after{color:#fff;}
.calib-terminal:has(.calib-matrix).is-locked .calib-terminal-head span:last-child{color:var(--fill);}
.calib-terminal:has(.calib-matrix).is-locked .calib-matrix::before{filter:saturate(.35);opacity:.72;}
.calib-terminal:has(.calib-matrix).is-locked .calib-scan{animation:none;background:var(--fill);box-shadow:none;}
.calib-terminal:has(.calib-matrix).is-locked .calib-scan::after{content:"■";background:var(--fill);color:var(--paper);}
.calib-terminal:has(.calib-matrix).is-locked input[type=range]{cursor:default;}
.calib-reset{display:block;width:100%;min-height:46px;margin-top:18px;border:1px solid var(--on);background:var(--on);color:var(--off);font-family:var(--font-mono);font-weight:var(--label-weight);font-size:9px;line-height:1.2;letter-spacing:.16em;text-transform:uppercase;cursor:pointer;}
.calib-reset:hover{border-color:var(--case-accent);background:var(--case-accent);color:#fff;}
.calib-reset:focus-visible{outline:2px solid var(--case-accent);outline-offset:5px;}

/* ── 图标层 ──────────────────────────────────────────────────────────────
   规格原样沿用旧版通过的设计（旧 case-detail.css 的 .audit-icon）：
   22×22、stroke-width 1.45、**方头端点 + 直角接合**、只描边不填充、中灰。
   方头直角是关键 —— 圆头会立刻变成通用图标库的样子，跟这套全是直角
   1px 线框的版面对不上。

   ⚠️ 我第一版重建时把这一层整个丢了（旧页面审计条本来就有六个），
   是漏搬不是设计决定。加新页记得带上。 */
.ico{width:22px;height:22px;flex:none;color:var(--fill);fill:none;stroke:currentColor;stroke-width:1.45;stroke-linecap:square;stroke-linejoin:miter;}

/* 审计条：钉在每格右上角，跟旧版位置一致 */
.audit-grid > div{position:relative;}
.audit-ico{position:absolute;right:22px;top:20px;}

/* ── 每节的收口句 ────────────────────────────────────────────────────────
   参考页 case_carbontax_reference.html 每个模块末尾都有一条 caption，把
   这一节的意义钉住。这一层我第一版整个漏了 —— 没有它，点阵图只是六个点
   的位置；有了它，那张图才在说「分歧是关于多不可能，不是关于是否」。

   ⚠️ 参考页那些 caption 的英文**不在 PDF 里**（参考页比 PDF 早，已被修正）。
   所以位置照参考页补，句子只用 PDF 里已经有的事实重组，不引入新论断。
   这几句仍属「我们写的」，要交工程/产品过目 —— 页面上用 .sec-cap 标着，
   grep 这个类名就能找齐。 */
.sec-cap{margin-top:18px;max-width:92ch;font-size:11.5px;font-weight:300;line-height:1.65;color:var(--text-mute);}
.sec-cap b{font-weight:var(--label-weight);font-family:var(--font-mono);font-size:10.5px;letter-spacing:.04em;color:var(--text-2);}

/* 「主张 + 它的历史战绩」成对写法，也是参考页的模式（Historical record: …）。
   这两行的字句是冻结证据原句的**精确片段**，不是复述。 */
.track-record{margin-top:16px;padding-top:12px;border-top:1px solid var(--hair);font-size:11.5px;font-weight:300;line-height:1.6;color:var(--text-2);}
.track-record b{display:block;margin-bottom:6px;font-size:8px;letter-spacing:.14em;text-transform:uppercase;color:var(--text-mute);}

/* ── 为什么难 ───────────────────────────────────────────────────────────── */
.hard-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(272px,1fr));border:1px solid var(--rule);background:var(--paper);}
.hard-grid article{padding:30px 26px 34px;border-right:1px solid var(--hair);}
.hard-grid article:last-child{border-right:0;}
.hard-grid h3{max-width:20ch;font-family:var(--font-display);font-size:17px;font-weight:350;letter-spacing:var(--disp-tracking-md);line-height:1.3;}
.hard-grid p{margin-top:16px;max-width:44ch;font-size:13px;font-weight:300;line-height:1.7;}

/* Rich explanatory cards. :has(.hard-copy) keeps the older text-only cards
   on Case 1 on their original compact layout. */
.hard-grid:has(.hard-copy) article{position:relative;isolation:isolate;overflow:hidden;display:grid;grid-template-rows:subgrid;grid-row:span 2;}
.hard-grid:has(.hard-copy) h3::before{content:"";display:inline-block;width:7px;height:7px;margin-right:11px;vertical-align:.08em;background:var(--fill);transition:background-color .18s ease,box-shadow .18s ease;}
.hard-grid:has(.hard-copy) article:hover h3::before{background:var(--case-accent);box-shadow:0 0 8px color-mix(in srgb,var(--case-accent) 55%,transparent);animation:case-hard-marker-pulse 1.1s steps(1,end) infinite;}
@keyframes case-hard-marker-pulse{0%,55%{opacity:1}55.01%,100%{opacity:.22}}
.hard-copy{position:relative;isolation:isolate;overflow:hidden;min-height:220px;margin:-30px -26px 0;padding:30px 26px 20px;}
.hard-copy::before{content:"";position:absolute;z-index:0;inset:0;background-image:radial-gradient(circle at center,var(--fill) var(--q-dot),transparent calc(var(--q-dot) + .16px));background-size:var(--q-pitch) var(--q-pitch);opacity:.42;animation:case-hard-dots-drift 9s linear infinite;transition:opacity .3s ease;}
.hard-copy > *{position:relative;z-index:2;}
.hard-copy h3,.hard-copy p{transition:opacity .3s ease;}
@keyframes case-hard-dots-drift{to{background-position:var(--q-pitch) var(--q-pitch)}}
@media (hover:hover) and (pointer:fine){
  .hard-copy h3,.hard-copy p{opacity:.68;}
  .hard-grid article:hover .hard-copy h3,.hard-grid article:hover .hard-copy p{opacity:1;}
  .hard-grid article:hover .hard-copy::before{opacity:.14;animation-play-state:paused;}
}
.hard-visual{margin-top:0;padding-top:28px;}
.hard-visual figcaption{display:flex;align-items:center;gap:10px;margin-bottom:12px;font-size:7px;line-height:1.2;letter-spacing:.14em;text-transform:uppercase;color:var(--fill);}
.hard-visual figcaption::after{content:"";width:36px;border-top:1px solid var(--case-accent);opacity:.7;}
.hard-row{display:grid;grid-template-columns:minmax(64px,.8fr) minmax(0,1.15fr) minmax(0,1.3fr);align-items:center;gap:10px;min-height:52px;margin-top:7px;padding:11px 12px;background:color-mix(in srgb,var(--on) 2%,transparent);}
.hard-row:first-of-type{margin-top:0;}
.hard-row strong{font-family:var(--font-display);font-size:11px;font-weight:350;letter-spacing:var(--disp-tracking-md);}
.hard-row > span{font-size:8px;line-height:1.45;letter-spacing:.1em;text-transform:uppercase;color:var(--fill);}
.hard-row > b{display:flex;align-items:center;gap:12px;font-size:8px;line-height:1.45;letter-spacing:.08em;text-transform:uppercase;}
.hard-row > b i{flex:none;width:7px;height:7px;}
.hard-row.is-context > b{color:var(--fill);}
.hard-row.is-context > b i{background:var(--fill);}
.hard-row.is-accent > b{color:var(--case-accent);}
.hard-row.is-accent > b i{background:var(--case-accent);box-shadow:0 0 8px color-mix(in srgb,var(--case-accent) 60%,transparent);}

/* ── 结果 ───────────────────────────────────────────────────────────────── */
.resolution{border:1px solid var(--edge);background:var(--paper);padding:34px 32px;}
.resolution p{max-width:74ch;font-size:16px;font-weight:300;line-height:1.75;}
.resolution p + p{margin-top:16px;}
.resolution b{font-weight:400;color:var(--case-accent);}

/* Scored verdict component. The structural gate preserves the text-only
   resolution used by the withdrawn Case 1 reference page. */
.resolution:has(.res-verdict){display:grid;grid-template-columns:minmax(0,1.45fr) minmax(300px,.55fr);padding:0;border-color:var(--rule);}
.res-verdict{padding:38px 42px 40px 32px;}
.res-kicker{font-size:9px;line-height:1.2;letter-spacing:.15em;text-transform:uppercase;color:var(--case-accent);}
.res-answer{display:flex;align-items:flex-end;gap:28px;margin-top:12px;}
.res-answer strong{font-family:var(--font-display);font-size:clamp(58px,7vw,96px);font-weight:200;letter-spacing:var(--disp-tracking-md);line-height:.9;color:var(--case-accent);}
.res-answer span{padding-bottom:4px;font-size:9px;line-height:1.55;letter-spacing:.1em;text-transform:uppercase;color:var(--fill);}
.resolution:has(.res-verdict) .res-copy{max-width:72ch;margin-top:30px;font-size:15px;font-weight:300;line-height:1.75;}
.res-final{display:flex;align-items:center;gap:14px;margin-top:22px;font-size:10px;line-height:1.4;letter-spacing:.1em;text-transform:uppercase;}
.res-final i{flex:none;width:8px;height:8px;background:var(--case-accent);box-shadow:0 0 10px color-mix(in srgb,var(--case-accent) 55%,transparent);}
.res-score{display:flex;flex-direction:column;justify-content:center;padding:38px 32px 40px 42px;border-left:1px solid color-mix(in srgb,var(--rule) 62%,transparent);background:color-mix(in srgb,var(--on) 2%,transparent);}
.res-score figcaption{font-size:9px;line-height:1.2;letter-spacing:.15em;text-transform:uppercase;color:var(--fill);}
.res-score > strong{margin-top:16px;font-family:var(--font-display);font-size:clamp(50px,5.2vw,76px);font-weight:220;letter-spacing:var(--disp-tracking-md);line-height:1;color:var(--case-accent);}
.res-equation{margin-top:10px;font-size:9px;line-height:1.2;letter-spacing:.08em;color:var(--fill);}
.res-scale{margin-top:34px;}
.res-track{position:relative;height:1px;background:var(--fill);}
.res-track span{position:absolute;left:0;top:0;width:18.4%;height:1px;background:var(--case-accent);}
.res-yarrow{position:absolute;left:18.4%;top:50%;width:18px;height:18px;padding:2px;overflow:visible;background:var(--case-accent);transform:translate(-50%,-50%);animation:case-res-yarrow-pulse 3.6s ease-in-out infinite;}
.res-yarrow::after{content:"";position:absolute;inset:3px;background:var(--on);-webkit-mask:url("yarrow_l.svg") center/contain no-repeat;mask:url("yarrow_l.svg") center/contain no-repeat;}
@keyframes case-res-yarrow-pulse{0%,100%{box-shadow:0 0 6px color-mix(in srgb,var(--case-accent) 48%,transparent)}50%{box-shadow:0 0 16px color-mix(in srgb,var(--case-accent) 90%,transparent)}}
.res-scale > p{display:flex;justify-content:space-between;margin-top:22px;font-size:8px;line-height:1.2;letter-spacing:.08em;text-transform:uppercase;color:var(--fill);}
.res-note{max-width:40ch;margin-top:24px;font-size:11px;font-weight:300;line-height:1.6;color:var(--fill);}

/* Mandatory honesty box: the left storage object and right disclosure share
   one recognizable shell across every public case. */
.honesty-box{display:grid;grid-template-columns:minmax(170px,.28fr) minmax(0,1fr);gap:30px;padding:26px;border:1px solid var(--case-accent);background:color-mix(in srgb,var(--case-accent) 6%,var(--paper));}
.honesty-mark{display:flex;width:max-content;flex-direction:column;align-items:flex-start;}
.honesty-mark > p{margin-top:0;font-size:8px;line-height:1.5;letter-spacing:.15em;text-transform:uppercase;color:var(--case-accent);white-space:nowrap;}
.honesty-canvas{display:block;width:69px;height:54px;margin-top:18px;align-self:center;pointer-events:none;}
.honesty-body h3{max-width:45ch;font-family:var(--font-display);font-size:18px;font-weight:350;line-height:1.35;letter-spacing:var(--disp-tracking-md);}
.honesty-body > p{max-width:92ch;margin-top:10px;font-size:12px;font-weight:300;line-height:1.7;color:var(--fill);}

/* ── 审计条 ─────────────────────────────────────────────────────────────── */
/* 固定三列，不用 auto-fit。六项配 auto-fit 会排成 5+1，第二行拖着一格
   空白但边框还在，看着像坏了。三列刚好两行满。 */
.audit-lead{max-width:96ch;margin-bottom:28px;font-size:14px;font-weight:300;line-height:1.7;color:var(--text-2);}
.audit-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));border:1px solid var(--rule);background:var(--paper);}
.audit-grid > div{padding:22px 24px;border-right:1px solid var(--hair);border-bottom:1px solid var(--hair);}
.audit-grid > div:nth-child(3n){border-right:0;}
.audit-grid > div:nth-last-child(-n+3){border-bottom:0;}
.audit-grid dt{font-family:var(--font-mono);font-weight:var(--label-weight);font-size:8px;letter-spacing:.14em;text-transform:uppercase;color:var(--text-mute);}
.audit-grid dd{margin-top:10px;font-size:13px;font-weight:300;line-height:1.5;word-break:break-word;}
.audit-grid code{font-family:var(--font-mono);font-size:12px;letter-spacing:.01em;}
.audit-say{margin-top:0;padding:20px 24px;border:1px solid var(--rule);border-top:0;max-width:none;font-size:13px;font-weight:300;line-height:1.7;color:var(--text-2);}

/* Expandable public verification receipt. Individual cases supply only their
   own fields and source links; the interaction and hierarchy stay consistent. */
.audit-question{display:grid;grid-template-columns:minmax(170px,.28fr) minmax(0,1fr);gap:30px;margin-top:20px;padding:22px 26px;border:1px solid var(--rule);background:var(--paper);}
.audit-question > p{font-size:8px;line-height:1.4;letter-spacing:.15em;text-transform:uppercase;color:var(--fill);}
.audit-question blockquote{max-width:96ch;font-size:13px;font-weight:300;line-height:1.7;}
.audit-receipt{margin-top:20px;border:1px solid var(--rule);background:var(--paper);}
.audit-receipt summary{display:grid;grid-template-columns:minmax(150px,.28fr) minmax(0,1fr) auto;align-items:center;gap:30px;padding:18px 26px;cursor:pointer;list-style:none;}
.audit-receipt summary::-webkit-details-marker{display:none;}
.audit-receipt summary span{font-size:8px;line-height:1.2;letter-spacing:.15em;text-transform:uppercase;color:var(--fill);}
.audit-receipt summary b{font-size:12px;font-weight:300;line-height:1.5;}
.audit-receipt summary::after{content:"+";display:grid;place-items:center;width:22px;height:22px;border:1px solid var(--fill);font-family:var(--font-mono);font-size:14px;font-weight:300;line-height:1;color:var(--fill);}
.audit-receipt[open] summary::after{content:"−";border-color:var(--case-accent);color:var(--case-accent);}
.audit-receipt summary:hover::after{border-color:var(--case-accent);color:var(--case-accent);}
.audit-receipt dl{border-top:1px solid var(--rule);}
.audit-receipt dl > div{display:grid;grid-template-columns:minmax(140px,.28fr) minmax(260px,.72fr) minmax(220px,.7fr);gap:30px;align-items:baseline;padding:15px 26px;border-bottom:1px solid var(--hair);}
.audit-receipt dl > div:last-child{border-bottom:0;}
.audit-receipt dt{font-size:8px;letter-spacing:.14em;text-transform:uppercase;color:var(--fill);}
.audit-receipt dd{min-width:0;word-break:break-word;}
.audit-receipt code{font-family:var(--font-mono);font-size:11px;letter-spacing:.01em;}
.audit-receipt dl p{font-size:10.5px;font-weight:300;line-height:1.5;color:var(--fill);}
.audit-receipt dd a{color:inherit;text-decoration:none;}
.audit-request{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:28px;padding:22px 26px;border-top:1px solid var(--rule);}
.audit-request > div{display:grid;grid-template-columns:minmax(140px,.28fr) minmax(0,1fr);align-items:baseline;gap:30px;}
.audit-request > div > span{font-size:8px;line-height:1.2;letter-spacing:.15em;text-transform:uppercase;color:var(--fill);}
.audit-request p{font-size:11.5px;font-weight:300;line-height:1.55;color:var(--text-mute);}
.audit-request-btn{display:flex;align-items:center;justify-content:space-between;gap:34px;min-width:250px;min-height:46px;padding:0 18px;border:1px solid var(--on);background:var(--on);color:var(--off);font-size:9px;font-weight:var(--label-weight);letter-spacing:.15em;text-transform:uppercase;text-decoration:none;transition:background-color .16s ease,border-color .16s ease,color .16s ease;}
.audit-request-btn:hover{border-color:var(--case-accent);background:var(--case-accent);color:#fff;}
.audit-request-btn:focus-visible{outline:2px solid var(--case-accent);outline-offset:4px;}
.audit-request-btn span{font-size:14px;line-height:1;}

/* ── 页脚 ───────────────────────────────────────────────────────────────── */
footer.foot.sec-dark{position:relative;border-top:0;}
footer.foot.sec-dark::before{content:"";position:absolute;z-index:1;left:0;right:0;top:0;height:1px;
  background:var(--rule);pointer-events:none;}
.foot-shell{max-width:var(--case-max);margin:0 auto;padding:0 var(--case-pad);}

/* ── 深色带里的局部反色 ──────────────────────────────────────────────────
   tokens.css 的 .sec-dark 已经整层重映了 --paper/--on/--dim/--text 等，
   所以这里基本不用再写。只有朱色在暗底上要提亮一档，否则对比不够。 */
.sec-dark{--case-accent:#E08059;background-color:var(--paper);background-image:var(--grid);background-size:var(--grid-size);}

/* ── 断点 ───────────────────────────────────────────────────────────────── */
@media (max-width:900px){
  .mast-case{gap:12px;}
}
/* 点阵图的断点比版面断点宽：六个点挤在 0.08–0.30 那一小段，实测 1180px
   就开始压字了，1080 才切换来不及。这个阈值是量出来的不是猜的 —— 改了
   点的取值范围（别的案例）要重新量。 */
@media (max-width:1320px){
  .dot b{display:none;}
  .dots-values{display:flex;flex-wrap:wrap;gap:10px 22px;margin:0 22px;padding:0 0 18px;font-size:9px;letter-spacing:.08em;color:var(--text-2);}
}
@media (max-width:1080px){
  .block-head{grid-template-columns:1fr;}
  .block-head h2,.block-head .head-note{grid-column:1;}
  /* 窄屏 head-note 掉到 h2 下面变成整行段落，右对齐会让左边缘参差难读，回到左对齐 */
  .block-head .head-note{margin-top:18px;text-align:left;}
  /* 单列之后 has-lede 的顶对齐没意义了，h2 要把上间距要回来（宽屏那条
     margin-top:0 是为了跟右列导语的首行对齐，单列下会让 h2 贴住小标签）。 */
  .block-head.has-lede h2{margin-top:18px;}
  .readout{grid-template-columns:repeat(2,minmax(0,1fr));}
  .tile:nth-child(2n){border-right:0;}
  .tile:nth-child(-n+2){border-bottom:1px solid var(--rule);}
  .audit-grid{grid-template-columns:repeat(2,minmax(0,1fr));}
  .audit-grid > div:nth-child(3n){border-right:1px solid var(--hair);}
  .audit-grid > div:nth-child(2n){border-right:0;}
  .audit-grid > div:nth-last-child(-n+3){border-bottom:1px solid var(--hair);}
  .audit-grid > div:nth-last-child(-n+2){border-bottom:0;}
  /* 窄屏改成竖轨：连线从「每步向右」变成「每步向下」，虚实规则不变 */
  .rail{grid-template-columns:1fr;padding:26px 22px;gap:0;}
  /* 竖排：横线关掉，改由每一步自己的左边框接成一条竖线 */
  .rail::before{display:none;}
  .rail-step{padding:18px 0 18px 26px;border-left:1px solid var(--on);}
  .rail-step i{left:-5px;top:22px;}
  .rail-step.is-freeze i{left:-7px;top:20px;}
  .is-enhanced .calib{grid-template-columns:1fr;gap:30px;}
  .card > summary{grid-template-columns:64px 56px minmax(0,1fr);gap:14px;}
  .card-chev{display:none;}
  .card-body{grid-template-columns:1fr;}
  .card-body > div{grid-column:1;}
}
@media (max-width:820px){
  .audit-question{grid-template-columns:1fr;gap:12px;padding:20px;}
  .audit-receipt summary{grid-template-columns:minmax(0,1fr) auto;gap:8px 18px;padding:17px 20px;}
  .audit-receipt summary span,.audit-receipt summary b{grid-column:1;}
  .audit-receipt summary::after{grid-column:2;grid-row:1/3;}
  .audit-receipt dl > div{grid-template-columns:1fr;gap:5px;padding:15px 20px;}
  .audit-request{grid-template-columns:1fr;gap:16px;padding:20px;}
  .audit-request > div{grid-template-columns:1fr;gap:7px;}
  .audit-request-btn{width:100%;min-width:0;}
}
@media (max-width:720px){
  .case-hero{padding-top:34px;}
  /* 窄屏方块回到 54px：320px 视口下若还是 108，文字列只剩 98px，没法读。
     54 ÷ 4.5 = 12，仍然整除。 */
  :root{--q-size:54px;}
  .readout{grid-template-columns:1fr;}
  .tile{border-right:0;border-bottom:1px solid var(--rule);}
  .tile:last-child{border-bottom:0;}
  :root{--case-top:70px;--case-bot:76px;}
  /* 单列：把宽屏那套显式网格定位全部解开，否则 grid-column:2 会凭空
     造出第二列，图和正文会被甩到一个不存在的栏里。 */
  .ev-line{grid-template-columns:1fr;}
  .ev-kind{grid-column:1;grid-row:auto;
    flex-direction:row;align-items:center;gap:12px;border-right:0;border-bottom:1px solid var(--hair);padding-bottom:12px;}
  .evfig{grid-column:1;grid-row:auto;margin:18px 22px 0;}
  .ev-line > p{grid-column:1;grid-row:auto;}
  /* 窄屏：线太短没有意义，改成竖排 —— 标记与标签各占一行 */
  .track-line{flex-wrap:wrap;align-items:flex-start;gap:12px;}
  .track-rule{display:none;}
  .gap-mark{margin:0;width:100%;}
  .track-end{width:100%;}
  .audit-grid{grid-template-columns:1fr;}
  .audit-grid > div{border-right:0;}
  .audit-grid > div:nth-child(3n){border-right:0;}
  .audit-grid > div:nth-last-child(-n+3),.audit-grid > div:nth-last-child(-n+2){border-bottom:1px solid var(--hair);}
  .audit-grid > div:last-child{border-bottom:0;}
  .hard-copy::before,.hard-sad{display:none;}
  .resolution:has(.res-verdict){grid-template-columns:1fr;}
  .res-verdict{padding:30px 20px;}
  .res-score{padding:30px 20px;border-left:0;border-top:1px solid var(--rule);background:transparent;}
  .honesty-box{grid-template-columns:1fr;gap:14px;padding:22px 20px;}
  .honesty-canvas{display:none;}
  .honesty-mark{width:auto;}
}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto;}
  *{transition-duration:.01ms !important;}
  .case-scroll-reveal{opacity:1;transform:none;transition:none;}
  .hard-copy::before,.hard-grid article:hover h3::before,.res-yarrow,.calib-scan{animation:none !important;}
  .hard-copy::before{opacity:.14;}
  .hard-copy h3,.hard-copy p{opacity:1 !important;}
}

/* ── hero 配图 ──────────────────────────────────────────────────────────
   Case 01 使用 assets/case1_in.png；C / E / F / G / H 使用
   assets/cover_article_*.png。图片均为约 2.04:1 的透明 PNG，且是**纯装饰**，
   所以有一条硬约束：

     加了它，hero 的高度和标题的折行都不许变。

   做法是把 img 绝对定位 —— 脱离文档流之后它不参与行高计算，行高只由
   h1（含 --lede-gap）决定，图再按 max-height 往里缩。
     .hero-art        默认 align-self:stretch → 撑满整行，当定位上下文
     img{bottom:0}    → 底边落在行底，也就是 question 方框的上边线
     max-height / max-width 两个方向同时封顶，谁先到谁生效，比例不变
   --hero-art-rise 是允许图往**上**长出标题行的量。往上长不影响任何东西
   （绝对定位），所以可以给它一点余量让画面不至于太小；往下一寸都不能动，
   那是方框的边。

   ⚠️ 别把 img 改回静态定位「顺手省一层」：图一高就会顶开行高，标题被推
   着重排。量过：620px 宽的静态图会把 h1 从「The tax that was / already law」
   挤成「The tax that / was already law」。
   ⚠️ .hero-top + .case-question.is-lede{margin-top:0} 是配套的：那 44px
   空隙搬到了 h1 的 margin-bottom 上，两处不能同时留。
   Case 01 的图右侧有 114/1672 ≈ 6.8% 的纯透明边，所以墨迹离方框右缘还有一小段。
   想让它齐边，正确做法是裁 PNG 的透明边，不要在 CSS 里写偏移量补。 */
.hero-top{display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,var(--hero-art-w));
  column-gap:clamp(24px,3.2vw,56px);}
.hero-top h1{margin-bottom:var(--lede-gap);}
.hero-art{position:relative;margin:0;}
.hero-art img{position:absolute;right:0;bottom:0;
  max-width:100%;max-height:calc(100% + var(--hero-art-rise));
  width:auto;height:auto;}
.hero-top + .case-question.is-lede{margin-top:0;}
/* 窄屏：列一没了图就没地方站，直接不显示 —— 装饰，不承载信息。 */
@media (max-width:900px){
  .hero-top{grid-template-columns:1fr;}
  .hero-art{display:none;}
}
