/* ===========================================================================
   视觉基线 · 单源（票 08 §6 定案）
   方向：Ethereal Glass（暗）｜ 底：石墨 #12161C ｜ 主光：去饱和青 #4FB5A8
   规则：两色系统（主光 + 中性灰）；无外投影、无实心边框；层次靠半透明叠加 + 内高光
   =========================================================================== */
:root{
  /* 表面层次：半透明白叠加在石墨底上 */
  --void:#12161C;
  --veil:rgba(255,255,255,.038);
  --panel:rgba(255,255,255,.058);
  --panel-2:rgba(255,255,255,.075);

  /* 发丝线：只用于分割 */
  --hair:rgba(255,255,255,.075);
  --hair-strong:rgba(255,255,255,.15);

  /* 文字三阶 */
  --ink:#EDF1F4; --ink-soft:#A4AEBA; --ink-mute:#6A7280;

  /* 主光（唯一强调） */
  --beam:#4FB5A8; --hair-beam:rgba(79,181,168,.34); --beam-wash:rgba(79,181,168,.078);
  --beam-on:#04140F;

  /* 语义：与主光同源 */
  --signal:var(--beam);

  /* 间距阶 */
  --gut:28px;
  --sp-2:8px; --sp-3:12px; --sp-4:18px; --sp-5:28px; --sp-6:44px; --sp-7:72px; --sp-8:112px;

  /* 圆角阶 */
  --r-1:12px; --r-2:20px; --r-3:28px;

  --sans:"PingFang SC","Microsoft YaHei",system-ui,-apple-system,"Segoe UI",sans-serif;
  --mono:"JetBrains Mono",Consolas,"SF Mono",Menlo,monospace;
  --ease:cubic-bezier(.32,.72,0,1);
}

*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0;background:var(--void);color:var(--ink);
  font:400 15.5px/1.85 var(--sans);-webkit-font-smoothing:antialiased;
}
/* 材质：径向柔光 + 顶部环境光 + 全屏噪点（fixed 层，不参与滚动重绘） */
body::before{
  content:"";position:fixed;inset:0;pointer-events:none;z-index:0;
  background:
    radial-gradient(1020px 700px at 13% 0%, rgba(79,181,168,.125), transparent 58%),
    radial-gradient(840px 580px at 92% 22%, rgba(96,140,196,.095), transparent 60%),
    radial-gradient(920px 780px at 46% 102%, rgba(79,181,168,.085), transparent 62%),
    linear-gradient(180deg, rgba(255,255,255,.028), transparent 44%);
}
body::after{
  content:"";position:fixed;inset:0;pointer-events:none;z-index:0;opacity:.034;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='150' height='150'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/></filter><rect width='150' height='150' filter='url(%23n)'/></svg>");
}
.wrap{position:relative;z-index:2;max-width:1080px;margin:0 auto;padding:0 var(--gut) 140px}

/* ---------- 顶栏 ---------- */
.bar{position:sticky;top:0;z-index:20;
  background:color-mix(in srgb, var(--void) 76%, transparent);
  backdrop-filter:blur(18px);border-bottom:1px solid var(--hair)}
.bar-in{max-width:1080px;margin:0 auto;padding:13px var(--gut);display:flex;
  align-items:center;gap:var(--sp-4);font-size:11px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--ink-mute)}
.bar .topic{color:var(--beam)}
.bar .sep{opacity:.4}
/* 宿主站名：把这一页接回宿主根。挂载后指向 `/`；脱离宿主单独打开时该链接落回本站首页 */
.bar .lg{color:var(--ink-soft);font-weight:500;letter-spacing:-.01em;text-transform:none;font-size:12.5px}
.bar .lg b{color:var(--beam)}
/* 顶栏里的课题名做成回链：从任何一页都能一步回到课题入口 */
.bar a{color:inherit;text-decoration:none;border-bottom:1px solid transparent;
  transition:border-color .35s var(--ease)}
.bar a:hover{border-bottom-color:var(--hair-strong)}
.bar .ttl{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  letter-spacing:.06em;text-transform:none;font-size:12.5px;color:var(--ink-soft)}
.bar .pg{white-space:nowrap}

/* ---------- 课头（T1 系列位置） ---------- */
.head{padding:var(--sp-8) 0 var(--sp-7);animation:rise .85s var(--ease) both}
@keyframes rise{from{opacity:0;transform:translateY(28px);filter:blur(8px)}
                to{opacity:1;transform:none;filter:blur(0)}}
.kicker{font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-mute);
  margin-bottom:var(--sp-5)}
.kicker b{color:var(--beam);font-weight:500;letter-spacing:.06em}
h1{font-size:68px;line-height:1.08;margin:0 0 var(--sp-5);font-weight:580;
  letter-spacing:-.022em;max-width:17ch}
.meta{display:flex;flex-wrap:wrap;gap:var(--sp-3) var(--sp-6);font-size:11px;
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink-mute)}
.meta b{color:var(--ink-soft);font-weight:500;letter-spacing:.03em;text-transform:none;font-size:13px}

/* ---------- 课首骨架（T2 只声明一次） ---------- */
.spine{margin:var(--sp-7) 0 0;padding-top:var(--sp-5);border-top:1px solid var(--hair)}
.spine-h{font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-mute);
  margin-bottom:var(--sp-3)}
.spine-q{color:var(--ink-soft);margin:0 0 var(--sp-6);max-width:64ch;font-size:16.5px;line-height:1.75}
.spine-q b{color:var(--beam);font-weight:500}
.track{display:grid;gap:var(--sp-3);position:relative;overflow:hidden}
.track.two{grid-template-columns:repeat(2,minmax(0,1fr))}
.track.three{grid-template-columns:repeat(3,minmax(0,1fr))}
.track.four{grid-template-columns:repeat(4,minmax(0,1fr))}
@media (max-width:760px){.track.four{grid-template-columns:repeat(2,minmax(0,1fr))}}
.scan{position:absolute;top:0;left:0;height:1px;width:34%;opacity:.5;
  background:linear-gradient(90deg,transparent,var(--beam),transparent);
  animation:scan 7.5s var(--ease) infinite}
@keyframes scan{0%{transform:translateX(-40%);opacity:0}18%{opacity:.55}
  82%{opacity:.55}100%{transform:translateX(330%);opacity:0}}
.node{padding:var(--sp-4) var(--sp-2) 0;border-top:1px solid var(--hair-strong);
  transition:border-color .7s var(--ease)}
.node .n{font-size:11px;letter-spacing:.14em;color:var(--ink-mute);transition:color .7s var(--ease)}
.node .t{margin-top:var(--sp-2);font-size:14.5px;color:var(--ink-mute);transition:color .7s var(--ease)}
.node.on{border-top-color:var(--beam)}
.node.on .n{color:var(--beam)} .node.on .t{color:var(--ink)}
.node.done{border-top-color:var(--hair-beam)} .node.done .t{color:var(--ink-soft)}

/* ---------- 段落 ---------- */
.sec{padding-top:var(--sp-8);margin-top:var(--sp-8);border-top:1px solid var(--hair)}
.sec-h{display:flex;align-items:baseline;gap:var(--sp-4);margin-bottom:var(--sp-3);flex-wrap:wrap}
.sec-h .sn{font-size:13px;font-weight:500;color:var(--beam);letter-spacing:.06em;
  font-variant-numeric:tabular-nums}
h2{font-size:27px;margin:0;font-weight:560;letter-spacing:-.012em}
.bridge{color:var(--ink-mute);font-size:13.5px;margin:0 0 var(--sp-4)}
.bridge b{color:var(--ink-soft);font-weight:500}
.motiv{color:var(--ink-soft);margin:0 0 var(--sp-6);max-width:66ch;font-size:17px;line-height:1.8}
.motiv b{color:var(--ink);font-weight:500}

/* ---------- 件号与件体（三件套统一语言） ---------- */
.piece{margin:0 0 var(--sp-6)}
.piece-tag{display:flex;align-items:center;gap:var(--sp-3);margin-bottom:var(--sp-4);
  font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-mute)}
.piece-tag .idx{color:var(--beam);letter-spacing:.14em}
.schema{background:var(--veil);border-radius:var(--r-2);padding:var(--sp-5);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.055)}
.schema svg{display:block;width:100%;height:auto}
.s-cap{color:var(--ink-mute);font-size:13px;margin-top:var(--sp-4);line-height:1.8}
.s-cap b{color:var(--ink-soft);font-weight:500}
.s-cap code{font-family:var(--mono);font-size:12px;color:var(--ink-soft)}

/* ---------- 件二：画布与面板 ---------- */
.lab{display:grid;grid-template-columns:minmax(0,1.5fr) minmax(0,1fr);gap:var(--sp-5);align-items:start}
@media (max-width:900px){.lab{grid-template-columns:minmax(0,1fr)}}
.stage{position:relative;background:color-mix(in srgb, var(--void) 52%, #000);
  border-radius:var(--r-1);overflow:hidden;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06);animation:stagein 1.1s var(--ease) both}
@keyframes stagein{from{opacity:0;transform:scale(.982);filter:blur(12px)}
                   to{opacity:1;transform:none;filter:blur(0)}}
.stage canvas{display:block;width:100%;aspect-ratio:4/3}
.panel{background:var(--veil);border-radius:var(--r-1);padding:var(--sp-4);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.055)}
.panel-h{font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-mute);
  margin:0 0 var(--sp-4)}
.ctl{margin-bottom:var(--sp-4)}
.ctl:last-child{margin-bottom:0}
.ctl label{display:flex;justify-content:space-between;align-items:baseline;font-size:13.5px;
  color:var(--ink-soft);margin-bottom:9px}
.ctl label span{font:500 13px var(--mono);color:var(--beam);font-variant-numeric:tabular-nums}
input[type=range]{width:100%;height:2px;-webkit-appearance:none;appearance:none;
  background:var(--hair-strong);border-radius:2px;outline:none}
input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:13px;height:13px;
  border-radius:50%;background:var(--beam);cursor:pointer;
  transition:transform .35s var(--ease),box-shadow .35s var(--ease);
  box-shadow:0 0 0 3px rgba(79,181,168,.14)}
input[type=range]::-webkit-slider-thumb:hover{transform:scale(1.18)}
input[type=range]::-moz-range-thumb{width:13px;height:13px;border:0;border-radius:50%;
  background:var(--beam);cursor:pointer}
input[type=range]:focus-visible{box-shadow:0 0 0 2px var(--hair-beam)}
.code{margin:0;background:rgba(255,255,255,.028);border-radius:var(--r-1);padding:var(--sp-4);
  overflow-x:auto;font:12.5px/1.8 var(--mono);color:#B6C2D0;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05)}
.code .k{color:#8FB6E8} .code .add{color:var(--signal)} .code .cm{color:var(--ink-mute)}
.code2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-4)}
@media (max-width:820px){.code2{grid-template-columns:minmax(0,1fr)}}

/* ---------- 观察块（定点观察） ---------- */
.obs{display:flex;gap:var(--sp-4);margin:var(--sp-5) 0 0;padding:var(--sp-5);
  background:var(--beam-wash);border-radius:var(--r-1)}
.obs .tag{flex:0 0 auto;font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--beam);padding-top:3px}
.obs p{margin:0;font-size:15px;color:#C6D2DC;line-height:1.8}
.obs b{color:var(--ink);font-weight:500}
.obs em{color:var(--beam);font-style:normal}

/* ---------- 件三：数值表（无外框，靠留白 + 行发丝） ---------- */
.tables{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--sp-6)}
@media (max-width:820px){.tables{grid-template-columns:minmax(0,1fr)}}
table{width:100%;border-collapse:collapse;font:12.5px var(--mono)}
caption{caption-side:top;text-align:left;padding:0 0 var(--sp-4);color:var(--ink-mute);
  font:400 11px/1.6 var(--sans);letter-spacing:.14em;text-transform:uppercase}
caption b{color:var(--ink-soft);font-weight:500;letter-spacing:.02em;text-transform:none;font-size:13px}
th,td{padding:9px 0;text-align:right;font-variant-numeric:tabular-nums}
th{color:var(--ink-mute);font-weight:400;font-size:11px;letter-spacing:.1em;
  border-bottom:1px solid var(--hair-strong)}
td{color:var(--ink);border-bottom:1px solid var(--hair)}
td:first-child,th:first-child{text-align:left;color:var(--ink-mute)}
.t-clip td{color:var(--ink)} .t-col td{color:var(--ink-soft)}
.flip{animation:nf .18s var(--ease)}
@keyframes nf{from{opacity:.15;transform:translateY(-4px)}to{opacity:1;transform:none}}

/* ---------- 收益块（T6 诚实收益） ---------- */
.gain{display:flex;gap:var(--sp-4);margin:var(--sp-6) 0 0;padding:var(--sp-5);
  background:var(--beam-wash);border-left:2px solid var(--beam);border-radius:0 var(--r-1) var(--r-1) 0}
.gain .tag{flex:0 0 auto;font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--beam);padding-top:3px}
.gain p{margin:0;font-size:15px;color:#C6D2DC;line-height:1.8}
.gain b{color:var(--beam);font-weight:500}

/* ---------- 保真度角标（两色 + 形状） ---------- */
.badge{display:inline-flex;align-items:center;gap:7px;font:400 11px var(--sans);
  letter-spacing:.12em;text-transform:uppercase;color:var(--ink-soft);white-space:nowrap}
.badge::before{content:"";width:6px;height:6px;border-radius:1px;
  border:1px solid currentColor;background:transparent;flex:0 0 auto}
.badge.real{color:var(--beam)} .badge.real::before{background:currentColor}
.badge.approx::before{transform:rotate(45deg);border-radius:0}

/* ---------- 段落占位（未实现的段落） ---------- */
.stub{margin-top:var(--sp-8);padding-top:var(--sp-6);border-top:1px solid var(--hair)}
.stub-h{font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-mute);
  margin-bottom:var(--sp-5)}
.stub-i{display:flex;align-items:baseline;gap:var(--sp-5);padding:var(--sp-5) 0;
  border-bottom:1px solid var(--hair);flex-wrap:wrap}
.stub-i .rn{font-size:13px;font-weight:500;color:var(--ink-mute);letter-spacing:.06em;
  font-variant-numeric:tabular-nums;white-space:nowrap}
.stub-i .rt{color:var(--ink-soft);font-size:15.5px}
.stub-i .delta{color:var(--ink-mute);font-size:12.5px;letter-spacing:.02em}
.stub-i .ra{margin-left:auto;display:flex;gap:var(--sp-5);align-items:center;
  font-size:12px;letter-spacing:.08em;color:var(--ink-mute)}

/* ---------- 课末（T8/T9） ---------- */
.next{margin-top:var(--sp-7);padding-top:var(--sp-6);border-top:1px solid var(--hair);
  display:flex;justify-content:space-between;gap:var(--sp-5);flex-wrap:wrap}
.next .lbl{display:block;font-size:11px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--ink-mute);margin-bottom:var(--sp-2)}
.next a{color:var(--beam);text-decoration:none;font-size:16px;transition:opacity .5s var(--ease)}
.next a:hover{opacity:.72}

/* ---------- 课题入口页 ---------- */
.topic-head{padding:var(--sp-8) 0 var(--sp-6);animation:rise .85s var(--ease) both}
.topic-head .kicker{margin-bottom:var(--sp-5)}
.topic-head h1{font-size:60px;max-width:20ch}
.topic-model{color:var(--ink-soft);font-size:17px;line-height:1.8;max-width:64ch;margin:0 0 var(--sp-4)}
.topic-model b{color:var(--beam);font-weight:500}
.lessons{display:grid;gap:0;margin-top:var(--sp-7)}
.lesson-row{display:grid;grid-template-columns:64px minmax(0,1fr) auto;gap:var(--sp-5);
  align-items:baseline;padding:var(--sp-6) 0;border-top:1px solid var(--hair);
  text-decoration:none;color:inherit;transition:background .5s var(--ease)}
.lesson-row:hover{background:var(--veil)}
.lesson-row .ix{font:500 13px var(--mono);color:var(--beam);letter-spacing:.06em}
.lesson-row h3{margin:0 0 var(--sp-2);font-size:22px;font-weight:560;letter-spacing:-.01em}
.lesson-row .desc{color:var(--ink-mute);font-size:14px;margin:0}
.lesson-row .desc b{color:var(--ink-soft);font-weight:500}
.lesson-row .side{display:flex;flex-direction:column;gap:var(--sp-2);align-items:flex-end;
  font-size:12px;letter-spacing:.08em;color:var(--ink-mute);white-space:nowrap}
.lesson-row[aria-disabled="true"]{opacity:.5;pointer-events:none}
.appendix{margin-top:var(--sp-7);padding-top:var(--sp-6);border-top:1px solid var(--hair)}
.appendix h3{font-size:16px;margin:0 0 var(--sp-3);font-weight:500;color:var(--ink-soft)}
.appendix p{color:var(--ink-mute);font-size:14px;margin:0}

/* ---------- 件一：示意图内部图元（含代码写在流程框里） ---------- */
.schema svg .lbl{fill:var(--ink-soft);font:600 15px var(--mono)}
.schema svg .sub{fill:var(--ink-mute);font:11.5px var(--mono);letter-spacing:.06em}
.schema svg .cellL{fill:rgba(79,181,168,.12);stroke:rgba(79,181,168,.44)}
.schema svg .cellL.hot{stroke:var(--beam);stroke-width:1.4}
.schema svg .cellR{fill:var(--panel);stroke:var(--hair-strong)}
.schema svg .cellR.hot{stroke:var(--beam);stroke-width:1.4}
.schema svg .cellR.cut{stroke:var(--beam);stroke-dasharray:3 3}
.schema svg .cellR.new{stroke:var(--beam);stroke-dasharray:3 3;fill:rgba(79,181,168,.10)}
.schema svg .numL{fill:#9CCFBE;font:12.5px var(--mono)}
.schema svg .numR,.schema svg .num{fill:var(--ink);font:12.5px var(--mono)}
.schema svg .shader{fill:rgba(255,255,255,.045);stroke:var(--hair-strong)}
.schema svg .shader-h{fill:rgba(255,255,255,.075);stroke:var(--hair-strong)}
.schema svg .shader-t{fill:var(--ink);font:500 14.5px var(--mono);letter-spacing:.04em}
.schema svg .code{fill:#93A3B5;font:12px var(--mono)}
.schema svg .wire{stroke:rgba(255,255,255,.20);stroke-width:1.3;fill:none;
  stroke-linecap:round;stroke-linejoin:round}
.schema svg .pkt{fill:var(--beam)}

/* ---------- 课题分组（站首页：唯一入口，课群列表就在同一页） ----------
   分组标题与课行的"名称"列对齐：课行那个 64px 序号列不在分组行上显示，
   分组行改用等宽左内边距顶齐第二列。分组靠"更大的字号 + 一条通栏细线 + 更多上间距"
   区分，不靠缩进或左边框。 */
.tgroup{margin-top:var(--sp-8)}
.tgroup:first-of-type{margin-top:var(--sp-6)}
.tg-head{display:grid;grid-template-columns:minmax(0,1fr) auto;
  gap:var(--sp-5);align-items:center;
  padding-left:calc(64px + var(--sp-5));
  padding-bottom:var(--sp-4);border-bottom:1px solid var(--hair-strong)}
.tg-head h2{margin:0;font-size:21px;font-weight:540;letter-spacing:-.01em;color:var(--ink)}
.tg-head .side{display:flex;flex-direction:column;gap:var(--sp-2);
  align-items:flex-end;font-size:11.5px;color:var(--ink-mute)}
.tg-spine{margin:var(--sp-4) 0 0;padding-left:calc(64px + var(--sp-5));
  font-size:13.5px;line-height:1.75;color:var(--ink-mute);max-width:78ch}
.tg-list{margin-top:var(--sp-4)}
.tg-list .lesson-row{border-top:1px solid var(--hair)}
.tg-list .lesson-row:first-child{border-top:0}
.tg-list .lesson-row h3{font-size:16.5px;font-weight:500;margin:0}
.tg-list .lesson-row[aria-disabled="true"]{opacity:.45}
.tg-app{margin:var(--sp-4) 0 0;padding-left:calc(64px + var(--sp-5));
  font-size:12.5px;line-height:1.7;color:var(--ink-mute);opacity:.78}

/* ---------- 分段按钮（多档切换） ---------- */
.seg{display:flex;gap:6px;flex-wrap:wrap}
.seg button{font:400 12.5px var(--sans);color:var(--ink-soft);background:var(--panel-2);
  border:1px solid var(--hair-strong);border-radius:999px;padding:5px 13px;cursor:pointer;
  transition:color .35s var(--ease),border-color .35s var(--ease),background .35s var(--ease)}
.seg button.on{color:var(--beam);border-color:var(--hair-beam);background:var(--beam-wash)}
.hint{color:var(--ink-mute);font-size:12.5px;line-height:1.75;margin:var(--sp-4) 0 0}

/* ---------- 鼠标探针（2.2：十字线 + 色块） ---------- */
.cross{position:absolute;width:15px;height:15px;margin:-8px 0 0 -8px;border-radius:50%;
  border:1px solid rgba(255,255,255,.8);pointer-events:none;display:none;
  box-shadow:0 0 0 2px rgba(0,0,0,.45)}
.cross::after{content:"";position:absolute;left:50%;top:50%;width:3px;height:3px;
  margin:-1.5px 0 0 -1.5px;border-radius:50%;background:rgba(255,255,255,.92)}
.chip{display:inline-block;width:26px;height:12px;border-radius:3px;vertical-align:-1px;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.22);margin-right:6px}

/* ---------- 运行时自检面板 ----------
   2026-09-29：按用户要求**不再展示**给读者（它原本是给我自己的反馈回路）。
   节点仍留在 DOM 里、诊断管线照常写入，所以将来要排查只需把下面这行 display:none 去掉。 */
.diag{display:none;margin:var(--sp-5) 0 0;background:rgba(255,255,255,.03);
  border:1px solid var(--hair);border-radius:var(--r-1);padding:var(--sp-4)}
.diag-h{display:flex;justify-content:space-between;gap:var(--sp-3);flex-wrap:wrap;
  font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-mute);
  margin-bottom:var(--sp-3)}
.diag-h b{color:var(--beam);font-weight:500;letter-spacing:.04em;text-transform:none;font-size:12.5px}
.diag pre{margin:0;font:12px/1.7 var(--mono);color:var(--ink-soft);white-space:pre-wrap;
  max-height:200px;overflow:auto}

/* ---------- 视口框（1.4：把视口画在画布上） ---------- */
.vp-box{position:absolute;border:1px solid var(--hair-beam);border-radius:4px;
  pointer-events:none;background:rgba(79,181,168,.045)}
.vp-tag{position:absolute;font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--beam);pointer-events:none;background:rgba(3,3,4,.72);padding:1px 6px;border-radius:4px}

/* ---------- 双窗格对照（裁剪前 / 裁剪后） ---------- */
.pane-lbl{position:absolute;top:10px;font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-mute);pointer-events:none;white-space:nowrap}
.pane-lbl.left{left:14px}
.pane-lbl.right{right:14px}
.pane-div{position:absolute;top:8%;bottom:8%;left:50%;width:1px;
  background:var(--hair-strong);pointer-events:none}

/* ---------- 探针（件三的运行时渲染体） ---------- */
.probe-row{display:flex;justify-content:space-between;gap:var(--sp-3);padding:6px 0;
  border-bottom:1px solid var(--hair);font-size:12.5px;color:var(--ink-mute)}
.probe-row:last-child{border-bottom:0}
.probe-row b{font:500 12.5px var(--mono);color:var(--ink);font-variant-numeric:tabular-nums}

/* ---------- 画布状态条 ----------
   ★ 它是**角标**，不是面板，更不是一条膜（2026-09-30 修）。
   原来这里只有 `right/bottom` 两个定位 + 一条 `linear-gradient(transparent, rgba(3,3,4,.86))` 的底 ——
   短句（「启动中…」）时看着就是右下角一行小字，可句子一长（降档档要报绘制读数），
   盒子就横着长成**一整条**：实测手机档 390×844 —— 状态条 344×49，占画布**宽 97%、高 22%**，
   且那条渐变在底部已到 0.86 的不透明度，等于给画面底部盖了一块近不透明的暗板
   （读者的话是「活例底部有留白，像是表面罩住了暗板」）。三条一起修：
     ① `max-width` 限宽 + `text-align:right`：句子再长也只在右下角长高，不横贯画面；
     ② 底改成 `.fb-tag` 同一套配方（半透明 + 内描边 + 圆角），读起来是角标而不是「罩在上面的膜」；
     ③ `pointer-events:none`：它是**覆盖在画布上的兄弟元素**，默认会吃掉画面底部那一条的
        pointerdown —— 拖视角时从那里按下没反应，等于画面底部有一条死区。
   ⚠ 失败面板（`.status.err` / `.err-gpu` / `.err-cpu`）也命中 `.status`，
     所以下面那组选择器里必须把 `max-width` 与 `pointer-events` **显式还原**
     （面板要铺满 `inset:0`、要能滚，被限宽就废了）。 */
.status{position:absolute;right:10px;bottom:9px;max-width:min(calc(100% - 20px),18em);
  text-align:right;font:11px/1.55 var(--mono);color:var(--ink-mute);letter-spacing:.05em;
  padding:3px 8px;border-radius:5px;background:rgba(3,3,4,.72);
  box-shadow:inset 0 0 0 1px var(--hair);pointer-events:none}

/* ---------- 失败态：装置不可用（未提供 WebGPU / 适配器创建失败 / 管线校验失败） ----------
   这一档不能是一条 11px 的角标。设备不支持时，读者看到的是一整块黑，
   而黑和「跑起来了但画面是黑的」看起来一模一样 —— 必须给一块能把「为什么」读完的板子。
   （2026-09-29：手机上就是这么翻车的，验收前只测了桌面宽度。）

   两个类名分属两条路，规则完全等价：
     · `.err-gpu` —— GPU 报错面板。GPU 路径只写它，绝不 remove 它。
     · `.err-cpu` —— CPU 降档面板。只有 CPU 兜底分支才允许 remove 它。
   两条路面板互不越界，改一条不会碰到另一条。写成同一组选择器，避免两份声明日后各漂各的。 */
.status.err,.err-gpu,.err-cpu{position:absolute;inset:0;display:flex;flex-direction:column;
  justify-content:center;align-items:stretch;gap:var(--sp-4);
  text-align:left;padding:var(--sp-5);overflow:auto;
  /* 显式还原：面板必须铺满 inset:0 且可滚，不能被上面 .status 的限宽与 pointer-events:none 带偏 */
  max-width:none;pointer-events:auto;
  background:color-mix(in srgb, var(--void) 90%, #000);
  color:var(--ink-soft);font:400 13.5px/1.85 var(--sans);letter-spacing:0;
  white-space:pre-wrap}
/* ⚠⚠ 2026-09-29 必须保留这一行 —— 它修的是"hidden 属性被 CSS 压过"这个根坑。
   `.status.err{display:flex}` 的特异性(0,2,0) 高于浏览器默认的 `[hidden]{display:none}`(0,1,0)，
   所以只要面板的类里静态带着 `err`，`hidden` 就形同虚设：**面板在每一页加载时就可见并盖住画面**。
   PC 走 GPU 路径、没有任何代码去清它 → 所有课页都显示「本段活例未能运行」；
   手机走降档路径、会清面板 → 手机正常。这就是"手机好了 PC 全坏"的真正成因。
   这一行让 hidden 永远赢，从根上堵死这一类错误。 */
.status[hidden],.err-gpu[hidden],.err-cpu[hidden]{display:none!important}

/* 页内抛出的那句话是照桌面写的（"请用 Chrome / Edge 113+ 打开"）——
   在手机上读会被误导，所以面板末尾统一补一句指向设备要求。要求只在 `.diag-note` 里存一份。 */
.status.err::after,.err-gpu::after,.err-cpu::after{content:"本段活例未能运行；同一页的示意图与数值表照常可读。";
  color:var(--ink-mute);font:400 12.5px/1.75 var(--sans)}

/* 移动端软光栅的降档角标。只对移动端启用（桌面走 WebGPU，不会出现这一档）。 */
.fb-tag{position:absolute;left:10px;top:9px;z-index:3;font:11px/1.5 var(--mono);letter-spacing:.04em;
  color:var(--ink-soft);padding:3px 8px;border-radius:4px;max-width:calc(100% - 20px);
  background:rgba(3,3,4,.78);box-shadow:inset 0 0 0 1px var(--hair-strong)}

/* 自检面板顶部的固定说明：设备要先满足这些，活例才跑得起来 */
.diag-note{color:var(--ink-mute);font-size:12px;line-height:1.75;margin:0 0 var(--sp-3)}
.diag-note b{color:var(--ink-soft);font-weight:500}

/* ---------- 窄屏（手机） ----------
   2026-09-29 之前这一档是空的：整站在桌面宽度下验收，手机上既没适配也没测过。
   手机上必须改三件事：字阶降下来、课行从三列折成两行、滑块热区放大（13px 的拇指在手指下太小）。 */
@media (max-width:640px){
  .wrap{padding:0 18px 96px}
  .bar-in{padding:11px 18px;gap:var(--sp-3);font-size:10px;letter-spacing:.12em}
  .bar .ttl{font-size:12px;letter-spacing:.02em}
  .bar .lg{font-size:12px}
  h1{font-size:34px;line-height:1.16;letter-spacing:-.02em;max-width:none}
  .topic-head h1{font-size:30px;max-width:none}
  .head{padding:var(--sp-7) 0 var(--sp-6)}
  .topic-head{padding:var(--sp-7) 0 var(--sp-5)}
  .sec{padding-top:var(--sp-7);margin-top:var(--sp-7)}
  .tgroup{margin-top:var(--sp-7)}
  h2{font-size:22px}
  .motiv{font-size:15.5px}
  .spine-q{font-size:15px}
  .kicker{font-size:10px;letter-spacing:.14em}
  .track.two,.track.three,.track.four{grid-template-columns:minmax(0,1fr)}
  /* 课行：三列（序号 | 名称 | 右侧信息）在窄屏挤不下 —— 右侧信息折到名称下方 */
  .lesson-row{grid-template-columns:auto minmax(0,1fr);gap:var(--sp-2) var(--sp-3);
    align-items:start;padding:var(--sp-5) 0}
  .lesson-row h3{font-size:19px}
  .lesson-row .side{grid-column:2;flex-direction:row;flex-wrap:wrap;gap:var(--sp-3);
    align-items:center;white-space:normal}
  /* 分组行：去掉那 64px 的顶齐缩进，标题独占一行 */
  .tg-head{grid-template-columns:minmax(0,1fr);padding-left:0;gap:var(--sp-2)}
  .tg-head .side{flex-direction:row;flex-wrap:wrap;align-items:flex-start;gap:var(--sp-3)}
  .tg-spine,.tg-app{padding-left:0}
  .tg-list .lesson-row h3{font-size:15.5px}
  /* 滑块热区：拇指 13px 在手指下点不准 */
  input[type=range]{height:4px}
  input[type=range]::-webkit-slider-thumb{width:24px;height:24px}
  input[type=range]::-moz-range-thumb{width:24px;height:24px}
  .seg button{padding:8px 15px;font-size:13px}
  .piece-tag{font-size:10px;letter-spacing:.14em}
  /* 件二画布上的叠加标签：窄屏一行放不下「描述 + 读数」两条 nowrap 标签，会撞在一起。
     给它们限宽并允许折行，把带 id 的读数列（#valNN，右对齐、由 JS 回写）错到下一行；
     分屏字样（如「裁剪前 / 裁剪后」，无 id）仍贴边一行。桌面档（>640px）不动。 */
  .pane-lbl{white-space:normal;max-width:calc(100% - 28px)}
  .pane-lbl.right[id]{top:28px;text-align:right}
  /* 数据流示意图（件一）在手机上撑满视口宽。
     原先它跟着 .wrap 的左右内边距一起被裁窄，而 `.schema svg{width:100%}` 是**等比**缩放的 ——
     宽度少一点，整张图（含图里的 12–15px 标注）就一起缩小，手机上小到读不清。
     用 calc(50% - 50vw) 撑到满宽，不依赖具体内边距数值；两侧再留 14px 免得贴边。
     刻意不加横向滚动容器：整图等比缩放是选定行为，放大靠抢回被内边距吃掉的那点宽度。 */
  .schema{margin-left:calc(50% - 50vw);margin-right:calc(50% - 50vw);
    padding-left:14px;padding-right:14px}
  .obs,.gain{padding:var(--sp-4);gap:var(--sp-3)}
  .obs p,.gain p{font-size:14.5px}
  .status.err,.err-gpu,.err-cpu{font-size:13px;padding:var(--sp-4)}
  table{font-size:12px}
  .diag pre{max-height:160px}
}

/* ---------- 无障碍 ---------- */
:focus-visible{outline:2px solid var(--beam);outline-offset:3px;border-radius:4px}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important}
}
