/* ============================================================
   REACTOR · Base / Reset / Typography / Layout
   ============================================================ */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

body{
  font-family:var(--font-sans);
  font-weight:500; /* 全站基准加粗一档（配套 CDN 已载 500 字重，非合成加粗） */
  color:var(--text); background:var(--bg);
  line-height:1.65; letter-spacing:.01em;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
  min-height:100vh;
  /* texture/light handled by the fixed .bg-field / .bg-dots layers (bg.css) */
}

/* ── 排版层级（统一无衬线）── */
/* text-wrap 新算法（渐进增强，Firefox 自动回退）：
   标题 balance 均衡多行；正文 pretty 优化整段断行、避免孤行词——中英混排尤其受益 */
h1,h2,h3,h4{font-family:var(--font-sans);font-weight:700;line-height:1.12;letter-spacing:-.02em;
  text-wrap:balance}
h1{font-size:clamp(2.5rem,6.4vw,5rem);line-height:1.02}
h2{font-size:clamp(1.6rem,3.4vw,2.4rem);margin:calc(var(--u)*5) 0 calc(var(--u)*2)}
h3{font-size:1.24rem;margin:calc(var(--u)*3) 0 var(--u)}
p{margin:0 0 calc(var(--u)*2);max-width:78ch;text-wrap:pretty}
li{text-wrap:pretty}
/* 课程正文与互动模块等宽(用户裁决:阅读区太窄)——.read 在 article 里吃满容器,
   68ch 的舒适行长上限对 1200px 版心太保守,交互卡是满宽,两者不齐很扎眼 */
.read p,.read li,.callout p{max-width:none}
.read p,.read li{font-family:var(--font-sans);font-size:1.125rem;line-height:1.9}  /* 18px(用户裁决) */
/* 引用：全站同一套无衬线，靠字号/字重/竖线区分，不再换字体 */
.pullquote,blockquote,.cite{font-family:var(--font-sans);font-weight:500}
/* pullquote 恒独占一行:即便作为 <span> 内联嵌在段落中间(如「X 写下:」后接引文),
   也 display:block 断到自己一行,引文与出处各占一行,前后文各自成行 */
.pullquote{display:block;font-size:clamp(1.15rem,2.2vw,1.5rem);line-height:1.6;
  border-left:2px solid var(--accent);padding:calc(var(--u)*.5) 0 calc(var(--u)*.5) calc(var(--u)*2.5);
  margin:calc(var(--u)*2.5) 0;color:var(--text)}
.pullquote .src{display:block;font-family:var(--font-mono);font-size:.7rem;letter-spacing:.1em;
  text-transform:uppercase;color:var(--text-2);margin-top:calc(var(--u)*1.5)}
a{color:var(--accent);text-decoration:none;text-underline-offset:3px}
a:hover{text-decoration:underline}
strong{color:var(--text);font-weight:700}
em{font-style:normal;color:var(--accent);font-weight:600}
code,kbd,.mono{font-family:var(--font-mono)}
:where(code):not(pre code){background:color-mix(in srgb,var(--accent) 12%,transparent);
  padding:.05em .35em;border-radius:var(--radius);font-size:.9em}
/* 节点引用链接:可点跳到该节点;下划虚线示意可点,悬停实底 */
a.node-ref{text-decoration:none;border-bottom:0}
a.node-ref code{cursor:pointer;text-decoration:underline;text-decoration-style:dotted;
  text-underline-offset:2px;transition:background .12s,color .12s}
a.node-ref:hover code{background:var(--accent);color:var(--bg);text-decoration:none}
ul,ol{margin:0 0 calc(var(--u)*2) 1.4em}
li{margin:.3em 0;max-width:74ch}
hr{border:0;height:1px;background:var(--line);margin:calc(var(--u)*4) 0}

/* ── 等宽功能标签（铭牌基因）── */
.label{font-family:var(--font-mono);font-size:.68rem;letter-spacing:.22em;
  text-transform:uppercase;color:var(--text-2)}

/* ── 布局容器 ── */
.wrap{max-width:var(--maxw);margin-inline:auto;padding-inline:clamp(16px,4vw,40px)}
/* 手机:内容吃满宽度,右侧贴边(左距保持,用户裁决) */
/* 手机:两侧 padding 对称相等(用户裁决 2026-07-22),不再为撑满而左右不齐 */
@media (max-width:720px){.wrap{padding-left:16px;padding-right:16px}}
.stack>*+*{margin-top:calc(var(--u)*3)}
.grid{display:grid;gap:calc(var(--u)*3)}
.section{padding-block:calc(var(--u)*8)}
.center{text-align:center}

/* ── 焦点可见性（无障碍）── */
:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
::selection{background:var(--accent);color:var(--bg)}

/* ── 骨架：header / footer ── */
.site-head{position:sticky;top:0;z-index:50;
  display:flex;align-items:center;gap:calc(var(--u)*2);
  padding:calc(var(--u)*1.5) clamp(16px,4vw,40px);
  border-bottom:1px solid var(--line);
  /* 性能红线:全站不用 backdrop-filter(用户裁决,GPU 太贵);玻璃感靠高不透明度近似 */
  background:color-mix(in srgb,var(--bg) 92%,transparent)}
.site-head .brand{font-family:var(--font-sans);font-weight:700;letter-spacing:.02em;
  font-size:1.02rem;color:var(--text);display:flex;align-items:center;gap:calc(var(--u)*1.25)}
.site-head .brand:hover{text-decoration:none;color:var(--text)}
.site-head nav{margin-left:auto;display:flex;gap:calc(var(--u)*2.5);align-items:center}
.site-head nav a{color:var(--text-2);font-family:var(--font-mono);font-size:.72rem;
  letter-spacing:.14em;text-transform:uppercase}
.site-head nav a:hover{color:var(--text)}

.site-foot{border-top:1px solid var(--line);margin-top:calc(var(--u)*10);
  padding:calc(var(--u)*5) 0;color:var(--text-2);font-family:var(--font-mono);font-size:.72rem}
.site-foot .wrap{display:flex;flex-wrap:wrap;gap:calc(var(--u)*2);justify-content:space-between}

img,svg,canvas{max-width:100%;display:block}
.scroll-x{overflow-x:auto}

/* ── 「接下来去哪」推荐:三组候选卡 ── */
.recommend{display:block}
.recommend .rec-title{display:block;margin-bottom:calc(var(--u)*2.5)}
.rec-group{margin-top:calc(var(--u)*3)}
.rec-group[hidden]{display:none}
.rec-glabel{display:block;font-weight:700;font-size:.95rem;color:var(--text);
  margin-bottom:calc(var(--u)*1.5);letter-spacing:.01em}
.rec-items{display:grid;gap:calc(var(--u)*1.5);
  grid-template-columns:repeat(auto-fill,minmax(230px,1fr))}
.rec-item{display:flex;align-items:baseline;gap:calc(var(--u)*1.25);
  padding:calc(var(--u)*1.5) calc(var(--u)*2);
  border:1px solid var(--line);border-left:3px solid var(--_c,var(--accent));
  border-radius:var(--radius-panel);background:var(--card);
  color:var(--text);text-decoration:none;
  transition:border-color .14s,background .14s,transform .14s}
.rec-item[hidden]{display:none}
.rec-item:hover{text-decoration:none;transform:translateY(-1px);
  border-color:var(--_c,var(--accent));background:color-mix(in srgb,var(--_c,var(--accent)) 8%,var(--card))}
.rec-item .rec-id{flex:none;font-family:var(--font-mono);font-weight:700;font-size:.78rem;
  letter-spacing:.06em;color:var(--_c,var(--accent))}
.rec-item .rec-name{font-weight:600;font-size:.98rem;line-height:1.3}
.rec-item[data-branch="red"]   {--_c:var(--branch-red)}
.rec-item[data-branch="blue"]  {--_c:var(--branch-blue)}
.rec-item[data-branch="yellow"]{--_c:var(--branch-yellow)}
.rec-item[data-branch="green"] {--_c:var(--branch-green)}
.rec-item[data-branch="case"],.rec-item[data-branch="converge"]{--_c:var(--text-2)}
