/* 靠谱数学 · 组件层样式
   纪律：只引 semantic token，零裸色值，零裸字号，零裸间距（八档之外的值视为错）。
   由 scripts/verify-design-system.mjs 看守。 */
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; font-family:var(--font-sans); font-size:var(--type-body);
  line-height:1.65; color:var(--ink);
  background:color-mix(in srgb,var(--lavender) 55%,var(--canvas));
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;display:block}
a{color:inherit}
:focus-visible{outline:3px solid var(--focus); outline-offset:3px; border-radius:var(--space-3xs)}

/* ---- 外框与纸面（frame inset 与 surface padding 分建，总纲 §4.2） ---- */
.frame{max-width:var(--frame-max); margin:0 auto; padding:var(--frame-inset)}
.paper{background:var(--canvas); border-radius:var(--radius-hero); overflow:hidden}
.track{max-width:var(--track-content); margin:0 auto; padding-inline:var(--space-md)}
.track-reading{max-width:var(--track-reading)}
main{padding-block:var(--space-lg) var(--space-xl)}
@media (max-width:70rem){ main{padding-bottom:calc(var(--dock-height) + var(--space-lg))} }

/* ---- 页头（桌面 88px；触控档主导航移交底部坞） ---- */
.site-head{
  display:flex; align-items:center; justify-content:space-between; gap:var(--space-md);
  min-height:88px; max-width:var(--track-content); margin:0 auto;
  padding:var(--space-sm) var(--space-md);
}
.brand{display:flex; align-items:center; gap:var(--space-xs); text-decoration:none}
.brand-mark{
  width:44px; height:44px; flex:0 0 auto; border-radius:var(--radius-inline);
  background:var(--brand); color:var(--surface);
  display:grid; place-items:center; font-weight:800; font-size:1.25rem;
}
.brand-name{display:block; font-weight:800; font-size:1.125rem; letter-spacing:.02em}
.brand-sub{display:block; font-size:var(--type-label); color:var(--ink-muted)}
.navpill{display:flex; gap:var(--space-3xs); background:var(--surface);
  border:1px solid var(--line); border-radius:var(--radius-pill); padding:var(--space-3xs)}
.navpill a{
  display:inline-flex; align-items:center; min-height:var(--tap-link);
  padding:var(--space-2xs) var(--space-sm); border-radius:var(--radius-pill);
  text-decoration:none; font-size:var(--type-supporting); font-weight:500;
  transition:var(--motion-feedback);
}
.navpill a[aria-current="page"]{background:var(--brand); color:var(--surface); font-weight:700}
.head-state{font-size:var(--type-label); color:var(--ink-muted); text-align:right}
@media (max-width:70rem){ .navpill{display:none} .site-head{min-height:68px} }

/* ---- 底部悬浮坞（≤1120px，总纲 §2.3） ---- */
.dock{
  position:fixed; left:50%; transform:translateX(-50%); z-index:30;
  bottom:max(var(--space-xs),env(safe-area-inset-bottom));
  width:min(calc(100vw - var(--space-md) * 2),45rem);
  display:none; grid-template-columns:repeat(4,minmax(0,1fr));
  background:color-mix(in srgb,var(--surface) 93%,transparent);
  -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
  border:1px solid var(--line); border-radius:var(--radius-pill);
  box-shadow:var(--shadow-soft); padding:var(--space-3xs);
}
.dock a{
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:2px;
  min-height:var(--tap); padding:var(--space-2xs) var(--space-3xs);
  border-radius:var(--radius-pill); text-decoration:none;
  font-size:var(--type-label); font-weight:600; color:var(--ink-muted);
  transition:var(--motion-feedback);
}
.dock a[aria-current="page"]{background:var(--lavender); color:var(--brand-strong)}
.dock svg{width:20px; height:20px}
@media (max-width:70rem){ .dock{display:grid} }

/* ---- 胶囊七档（probe-pill 守门） ---- */
.tag{display:inline-flex; align-items:center; gap:var(--space-3xs);
  font-size:.875rem; padding:var(--space-3xs) var(--space-xs);
  border-radius:var(--radius-pill); background:var(--lavender); color:var(--brand-strong); font-weight:600}
.tag-s{font-size:.75rem; padding:2px 10px; border-radius:var(--radius-pill);
  background:var(--lavender); color:var(--brand-strong); font-weight:600; display:inline-flex; align-items:center}
.tag.ok{background:var(--state-correct-face); color:var(--state-correct-ink)}
.tag.warn{background:color-mix(in srgb,var(--sun) 45%,var(--canvas)); color:var(--core-amber-800)}
.tag.lock{background:color-mix(in srgb,var(--ink) 7%,transparent); color:var(--ink-muted)}
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:var(--space-2xs);
  min-height:var(--tap-cta); padding:var(--space-xs) var(--space-md);
  border:none; border-radius:var(--radius-pill); cursor:pointer;
  background:var(--brand); color:var(--surface); font-family:inherit;
  font-size:1.0625rem; font-weight:700; text-decoration:none;
  transition:var(--motion-feedback);
}
.btn:hover{background:var(--brand-strong)}
.btn.chip{min-height:var(--tap); padding:10px var(--space-sm); font-size:.875rem;
  background:var(--surface); color:var(--brand-strong); border:1px solid var(--line-strong); font-weight:600}
.btn.chip:hover{background:var(--lavender); border-color:var(--lavender-deep)}
.btn.on-dark{background:var(--sun); color:var(--ink)}
.btn.on-dark:hover{background:color-mix(in srgb,var(--sun) 82%,var(--surface))}
.btn[disabled]{background:color-mix(in srgb,var(--ink) 10%,transparent); color:var(--ink-muted); cursor:not-allowed}
@media (hover:none){
  .btn:hover{background:var(--brand)}
  .btn.chip:hover{background:var(--surface); border-color:var(--line-strong)}
  .btn.on-dark:hover{background:var(--sun)}
}

/* ---- 通用文字 ---- */
.eyebrow{display:flex; align-items:center; gap:var(--space-2xs);
  font-size:.84rem; font-weight:800; color:var(--brand-strong); letter-spacing:.06em; margin:0 0 var(--space-2xs)}
.eyebrow::before{content:""; width:22px; height:3px; border-radius:var(--radius-pill);
  background:var(--coral); transform:rotate(-1.5deg)}
h1{font-size:var(--type-display); line-height:1.16; margin:0 0 var(--space-sm); font-weight:800; letter-spacing:-.01em}
h2{font-size:var(--type-section-title); line-height:1.22; margin:0 0 var(--space-xs); font-weight:800}
h3{font-size:var(--type-card-title); line-height:1.3; margin:0 0 var(--space-2xs); font-weight:700}
.lead{font-size:var(--type-lead); color:var(--ink-muted); margin:0; max-width:60ch}
.kai{font-family:var(--font-accent)}
.section{margin-top:var(--space-xl)}
.section-head{margin-bottom:var(--space-md)}

/* ---- 卡 ---- */
.card{background:var(--surface); border:1px solid var(--line);
  border-radius:var(--radius-card); padding:var(--pad-card); box-shadow:var(--shadow-soft)}
.cards{display:grid; gap:var(--space-sm)}

/* ---- 行式列表（家族目录语言，总纲 §6.4） ---- */
.rowlist{list-style:none; margin:0; padding:0; background:var(--surface);
  border:1px solid var(--line); border-radius:var(--radius-card); overflow:hidden}
.rowlist>li + li{border-top:1px solid var(--line)}
.rowlink{
  display:grid; grid-template-columns:3.25rem minmax(0,1fr) auto;
  align-items:center; gap:var(--space-sm);
  min-height:var(--tap); padding:var(--space-sm) var(--pad-card);
  text-decoration:none; transition:var(--motion-feedback);
}
a.rowlink:hover{background:var(--hero-soft)}
@media (hover:none){ a.rowlink:hover{background:transparent} }
.rowlink[aria-disabled="true"]{cursor:not-allowed; background:color-mix(in srgb,var(--ink) 3%,transparent)}
.row-no{font-family:var(--font-num); font-variant-numeric:tabular-nums;
  font-size:1.0625rem; font-weight:800; color:var(--brand-strong);
  width:3.25rem; text-align:left}
.rowlink[aria-disabled="true"] .row-no{color:var(--ink-muted)}
.row-body{min-width:0}
.row-title{font-weight:700; font-size:var(--type-body); display:flex; align-items:center;
  gap:var(--space-2xs); flex-wrap:wrap}
.row-meta{font-size:var(--type-supporting); color:var(--ink-muted); margin-top:2px}
.row-tail{display:flex; align-items:center; gap:var(--space-xs); color:var(--ink-muted)}
.chev{width:20px; height:20px; flex:0 0 auto}
.group-head{display:flex; align-items:baseline; gap:var(--space-xs);
  margin:var(--space-lg) 0 var(--space-xs)}
.group-head h3{margin:0}
.group-count{font-size:var(--type-label); color:var(--ink-muted); font-variant-numeric:tabular-nums}

/* ---- 悬挂序号列表（编号内容语言，总纲 §4.4） ---- */
.hanglist{list-style:none; margin:0; padding:0; counter-reset:h}
.hanglist>li{position:relative; padding:var(--space-sm) 0 var(--space-sm) 3.25rem;
  border-bottom:1px solid var(--line)}
.hanglist>li:last-child{border-bottom:none}
.hanglist>li::before{counter-increment:h; content:counter(h);
  position:absolute; left:0; top:var(--space-sm); width:2.25rem; text-align:center;
  font-family:var(--font-num); font-variant-numeric:tabular-nums;
  font-weight:800; color:var(--brand-strong)}

/* ---- 深色叙事面板（唯一深底场景，白名单登记） ---- */
.panel-dark{background:var(--dark-panel); color:var(--surface);
  border-radius:var(--radius-card); padding:clamp(var(--space-md),5vw,var(--space-2xl));
  display:grid; grid-template-columns:minmax(0,1.35fr) minmax(0,1fr); gap:var(--space-lg); align-items:center}
.panel-dark h2{color:var(--surface)}
.panel-dark .lead{color:color-mix(in srgb,var(--surface) 82%,transparent)}
.panel-dark .eyebrow{color:var(--sun)}
@media (max-width:52rem){ .panel-dark{grid-template-columns:minmax(0,1fr)} }

/* ---- 浅底教学图区（Q17：动图区改浅底） ---- */
.figbox{background:var(--surface); border:1px solid var(--line);
  border-radius:var(--radius-panel); padding:var(--space-md)}
/* SVG 的固定样式收进 CSS；每图各自的 max-width 由 app.js 走 CSSOM 设
   （内联 style 属性受 CSP style-src 管，CSSOM 不受）。 */
.figbox svg{width:100%; height:auto; display:block; margin-inline:auto; max-width:640px}
.figcap{font-size:var(--type-label); color:var(--ink-muted); margin:var(--space-xs) 0 0}
.figctrl{display:flex; gap:var(--space-2xs); flex-wrap:wrap; margin-top:var(--space-sm)}

/* ---- 口诀纸条（sun 色彩事件） ---- */
.kou{background:var(--sun); border-radius:var(--radius-panel);
  padding:var(--space-md) var(--pad-card)}
.kou p{margin:0; font-size:var(--type-lead); font-weight:700; line-height:1.7}
.kou .eyebrow{color:var(--core-amber-800)}


/* ---- 收束面板 ---- */
.closing{background:var(--lavender); border-radius:var(--radius-card);
  padding:clamp(var(--space-md),4vw,var(--space-xl)); text-align:center}
.closing h2{margin-bottom:var(--space-2xs)}
.closing .lead{margin:0 auto var(--space-md)}

/* ---- 真实进度（禁虚假起步，总纲 §6.9-5） ---- */
.progress{display:flex; align-items:center; gap:var(--space-sm)}
.progress-text{font-size:var(--type-supporting); font-weight:700;
  font-variant-numeric:tabular-nums; white-space:nowrap}
.bar{flex:1; height:10px; border-radius:var(--radius-pill);
  background:color-mix(in srgb,var(--ink) 8%,transparent); overflow:hidden}
.bar>i{display:block; height:100%; border-radius:var(--radius-pill); background:var(--brand)}

/* ---- 题与选项 ---- */
.qtext{font-size:var(--type-panel-title); font-weight:700; line-height:1.5;
  margin:0 0 var(--space-md)}
.opts{display:grid; gap:var(--space-xs); margin:0; padding:0; list-style:none}
.opt{
  display:grid; grid-template-columns:2rem minmax(0,1fr) auto; align-items:center; gap:var(--space-sm);
  width:100%; min-height:var(--tap); padding:var(--space-xs) var(--space-sm);
  background:var(--surface); border:1px solid var(--line-strong);
  border-radius:var(--radius-inline); cursor:pointer; text-align:left;
  font-family:inherit; font-size:var(--type-body); color:var(--ink);
  transition:var(--motion-feedback);
}
.opt:hover{border-color:var(--brand)}
@media (hover:none){ .opt:hover{border-color:var(--line-strong)} }
.opt .mark{width:2rem; height:2rem; border-radius:var(--radius-pill);
  border:1px solid var(--line-strong); display:grid; place-items:center;
  font-weight:800; font-size:.9375rem; color:var(--ink-muted)}
.opt .verdict{display:flex; align-items:center; gap:var(--space-3xs);
  font-size:var(--type-label); font-weight:700}
.opt.correct{border-color:var(--state-correct-ink); background:var(--state-correct-face)}
.opt.correct .mark{background:var(--state-correct-ink); color:var(--surface); border-color:var(--state-correct-ink)}
.opt.correct .verdict{color:var(--state-correct-ink)}
.opt.wrong{border-color:var(--state-wrong-ink); background:var(--state-wrong-face)}
.opt.wrong .mark{background:var(--state-wrong-ink); color:var(--surface); border-color:var(--state-wrong-ink)}
.opt.wrong .verdict{color:var(--state-wrong-ink)}
.explain{border-left:3px solid var(--brand); background:var(--hero-soft);
  border-radius:0 var(--radius-inline) var(--radius-inline) 0;
  padding:var(--space-sm) var(--space-md); margin-top:var(--space-md)}
.explain p{margin:0}
.explain .eyebrow{margin-bottom:var(--space-3xs)}

/* ---- 面包屑 ---- */
.crumbs{display:flex; flex-wrap:wrap; align-items:center; gap:var(--space-3xs);
  font-size:var(--type-label); color:var(--ink-muted); margin:0 0 var(--space-sm); padding:0; list-style:none}
.crumbs a{min-height:var(--tap-link); display:inline-flex; align-items:center;
  padding-inline:var(--space-3xs); text-decoration:none; color:var(--brand-strong); font-weight:600}
.crumbs li[aria-current]{font-weight:700; color:var(--ink)}

/* ---- 无障碍 ---- */
.sr{position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap}
.skip{position:absolute; min-height:var(--tap); display:inline-flex; align-items:center; left:var(--space-sm); top:-4rem; z-index:40; background:var(--brand);
  color:var(--surface); padding:var(--space-2xs) var(--space-sm); border-radius:var(--radius-pill);
  text-decoration:none; transition:top 180ms cubic-bezier(.2,0,0,1)}
.skip:focus{top:var(--space-sm)}

@media (prefers-reduced-motion:reduce){
  *{animation-duration:.01ms !important; animation-iteration-count:1 !important;
    transition-duration:.01ms !important}
}


/* ---- 年级分组折叠（页高预算修法：只折叠不删内容，用原生 details） ---- */
.ggroup{margin-top:var(--space-lg)}
.gsum{display:flex; align-items:center; gap:var(--space-xs); min-height:var(--tap);
  padding:var(--space-2xs) 0; cursor:pointer; list-style:none;
  transition:var(--motion-feedback)}
.gsum::-webkit-details-marker{display:none}
.gsum h3{margin:0}
.gsum .gmark{width:22px; height:22px; flex:0 0 auto; color:var(--brand-strong);
  transition:transform 180ms cubic-bezier(.2,0,0,1)}
.ggroup[open] .gsum .gmark{transform:rotate(90deg)}
.gsum .spacer{flex:1}

/* ---- 窄档行式列表重排（375 实测：正文列被压到约 140px，三行折行） ---- */
@media (max-width:34rem){
  .rowlink{grid-template-columns:3.25rem minmax(0,1fr); row-gap:var(--space-2xs)}
  .row-tail{grid-column:2; justify-content:flex-start}
  .head-state{font-size:var(--type-label); line-height:1.35}
  .head-state br{display:none}
}

/* ============================================================
   页面级布局（原型稿里在各页 <style> 里的部分，收进唯一样式表）
   ============================================================ */

/* ---- 首页 hero（编辑式，总纲 §6.3 第一式，60/40 不对称） ---- */
.hero{display:grid; grid-template-columns:minmax(0,1.28fr) minmax(0,1fr);
  gap:var(--space-xl); align-items:center; padding-block:var(--space-lg) 0}
.hero h1 > span{display:block}
.hero-act{margin:var(--space-lg) 0 0}
@media (max-width:56rem){ .hero{grid-template-columns:minmax(0,1fr); gap:var(--space-md)} }

/* ---- 续学卡（邀请式，总纲 §6.9-4） ---- */
.resume{display:grid; grid-template-columns:minmax(0,1fr) auto; gap:var(--space-md); align-items:center}
.resume-body p:last-child{margin-bottom:0}
.resume-act{margin:0}
@media (max-width:40rem){
  .resume{grid-template-columns:minmax(0,1fr)}
  .resume-act .btn{width:100%}
}

/* ---- 学段页拱形同台页头（总纲 §6.3 第二式） ---- */
.archhead{display:grid; grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);
  gap:var(--space-xl); align-items:center; padding-block:var(--space-md) 0}
/* 拱形同台（总纲 §6.3 第二式）。用 .art.arch-art 提权重：
   通用的 .art 圆角在文件更后面，同权重时会盖掉拱形。 */
.art.arch-art{border-radius:var(--radius-pill) var(--radius-pill) var(--radius-card) var(--radius-card)}
@media (max-width:56rem){ .archhead{grid-template-columns:minmax(0,1fr); gap:var(--space-md)} }
.ggroup:first-of-type{margin-top:var(--space-md)}

/* ---- 学习页行动区 ---- */
.actbar{display:grid; grid-template-columns:minmax(0,1fr) auto; gap:var(--space-md); align-items:center}
.actbar-btns{display:flex; gap:var(--space-2xs); flex-wrap:wrap}
@media (max-width:44rem){
  .actbar{grid-template-columns:minmax(0,1fr)}
  .actbar-btns .btn{flex:1 1 auto; justify-content:center}
}

/* ---- 练习页（一次一题） ---- */
.quizbar{display:flex; align-items:center; gap:var(--space-md); flex-wrap:wrap; margin-bottom:var(--space-lg)}
.quizbar .progress{flex:1 1 14rem}
.quiznext{margin-top:var(--space-lg); display:flex; justify-content:flex-end; gap:var(--space-2xs)}
.endcard .lead{max-width:none}
.endacts{display:flex; gap:var(--space-2xs); flex-wrap:wrap; margin-top:var(--space-lg)}
@media (max-width:40rem){
  .quiznext{flex-direction:column}
  .quiznext .btn{width:100%}
  .endacts .btn{flex:1 1 auto; justify-content:center}
}

/* ---- 空态（总纲 §8.4：不做假卡片，说清现在没有什么、下一步做什么） ---- */
.empty{display:grid; gap:var(--space-md); justify-items:center; text-align:center;
  padding:var(--space-xl) var(--pad-card)}
.empty .art{width:min(100%,18rem)}
.empty p{margin:0; max-width:44ch}

/* ---- 我的：进度统计 ---- */
.stats{display:grid; grid-template-columns:repeat(auto-fit,minmax(9rem,1fr)); gap:var(--space-sm)}
.stat{background:var(--surface); border:1px solid var(--line); border-radius:var(--radius-panel);
  padding:var(--space-md); text-align:center}
.stat .n{display:block; font-family:var(--font-num); font-variant-numeric:tabular-nums;
  font-size:var(--type-panel-title); font-weight:800; color:var(--brand-strong); line-height:1.1}
.stat .l{display:block; font-size:var(--type-label); color:var(--ink-muted); margin-top:var(--space-3xs)}

/* ---- 里程碑 ---- */
.milestone{display:grid; gap:var(--space-md); justify-items:center; text-align:center}
.milestone .art{width:min(100%,16rem)}

/* ============================================================
   美术资产件与「无图也成立」（总纲 §7.5）
   注册表里没有该图位时 app.js 整个不渲染图，容器加 noart 收成单列，
   不留无职责空白。
   ============================================================ */
/* 图像融入：三层纸面渗色底盘（visual-quality-gates 图像融入分档表，
   不透明插画不许裸矩形直贴）。底层浅紫纸偏移露边，中层暖白纸，
   上层是图本身，配贴纸级投影，读起来是几张纸叠出来的，而不是贴上去的。 */
.art{position:relative; display:block; border-radius:var(--radius-panel);
  isolation:isolate}
.art::before{content:""; position:absolute; inset:0; z-index:-1;
  border-radius:inherit; background:var(--lavender);
  transform:rotate(-1.2deg) translate(-6px,6px)}
.art::after{content:""; position:absolute; inset:0; z-index:-1;
  border-radius:inherit; background:var(--canvas);
  transform:rotate(.6deg) translate(4px,-3px)}
.art img{width:100%; height:100%; object-fit:cover; display:block;
  border-radius:inherit; box-shadow:var(--shadow-soft)}
/* 深色面板里的底盘换成同族深色，别在深底上炸出两块浅紫 */
.panel-dark .art::before{background:color-mix(in srgb,var(--surface) 16%,transparent)}
.panel-dark .art::after{background:color-mix(in srgb,var(--surface) 8%,transparent)}
.panel-dark .art img{box-shadow:var(--shadow-raised)}
@media (prefers-reduced-motion:reduce){
  .art::before, .art::after{transform:none}
}
.hero .art{aspect-ratio:16/10}
.archhead .art, .panel-dark .art{aspect-ratio:4/3}
.empty .art, .milestone .art{aspect-ratio:1/1; margin-inline:auto}
.hero.noart, .archhead.noart{grid-template-columns:minmax(0,1fr)}
.hero.noart > div, .archhead.noart > div{max-width:var(--track-reading)}
.panel-dark.noart{grid-template-columns:minmax(0,1fr)}

/* ---- 选项是 button，需要显式撑满与禁用态 ---- */
.opt{width:100%; font-family:inherit}
.opt:disabled{cursor:default}
.opt .vmark{width:1rem; height:1rem}
.opt.correct .mark .vmark, .opt.wrong .mark .vmark{color:var(--surface)}

/* ---- 未解锁行是 span 不是链接：不给手型、不给悬停 ---- */
/* 未解锁行是 span：悬停效果只给可交互的 a.rowlink，这里不需要任何抵消规则 */
span.rowlink{cursor:default}

/* ---- 结束屏里的叉号图标 ---- */
.row-no .vmark{width:1.375rem; height:1.375rem; color:var(--state-wrong-ink)}

/* ---- 主内容容器获得焦点时不画默认描边（路由后我们主动 focus 它） ---- */
main:focus{outline:none}

/* ============================================================
   动图演示区（Q17：上游把 18 个动图放在深蓝黑底上，本站全部翻成浅底）
   动图脚本用的类名：anim-cap、anim-ctrls、anim-ctrl、btn、btn sm
   ============================================================ */
.figbox svg text{font-family:var(--font-sans)}
.anim-cap{margin:var(--space-sm) 0 0; font-size:var(--type-supporting); color:var(--ink-muted); line-height:1.6}
.anim-ctrls{display:flex; gap:var(--space-2xs); flex-wrap:wrap; margin-top:var(--space-sm)}
.anim-ctrl{display:flex; align-items:center; gap:var(--space-2xs); flex-wrap:wrap}
.figbox .btn, .anim-ctrls .btn{
  min-height:var(--tap); padding:10px var(--space-sm); font-size:.875rem; font-weight:600;
  background:var(--surface); color:var(--brand-strong); border:1px solid var(--line-strong);
}
.figbox .btn:hover, .anim-ctrls .btn:hover{background:var(--lavender); border-color:var(--lavender-deep)}
@media (hover:none){ .figbox .btn:hover, .anim-ctrls .btn:hover{background:var(--surface); border-color:var(--line-strong)} }
.figbox input[type="range"]{accent-color:var(--brand); min-height:var(--tap)}

/* ============================================================
   工具类：替代内联 style 属性。
   目的不是省字，是让 CSP 能收到最严的 style-src 'self'
   （内联 style 属性受 CSP 管，JS 走 CSSOM 设的样式不受管）。
   ============================================================ */
.u-m0{margin:0}
.u-mt-2xs{margin-top:var(--space-2xs)}
.u-mt-sm{margin-top:var(--space-sm)}
.u-mt-md{margin-top:var(--space-md)}
.u-mb-2xs{margin:0 0 var(--space-2xs)}
.u-mb-lg{margin-bottom:var(--space-lg)}
.u-act{margin:var(--space-sm) 0 0}
.u-act-md{margin:var(--space-md) 0 0}
.u-progress-narrow{margin-top:var(--space-md); max-width:26rem}
.u-title-section{font-size:var(--type-section-title)}
