/* ============================================================================
   GENXFF —— 站点样式
   设计令牌与视觉规格沿用 lcms2yield-web（Apple 风格，浅色），
   组件层按 GENXFF 的页面重写（见文件后半「GENXFF 组件」）。

   不引入 Tailwind Play CDN：§4.6 把令牌以原生 CSS 给出，§3 的目标是
   「无构建步骤、不需要 Node」。单文件 CSS 同样满足该目标，且没有
   渲染阻塞脚本、没有首屏无样式闪烁、不依赖外部 CDN 可达性
   （本站用户在海外，cdn.tailwindcss.com 的可达性不可控）。
   ========================================================================== */

:root {
  /* --- 品牌色：直接取自 logo 的实际像素 ------------------------------------
     logo（generator/static/generator/img/brand/xtalpi-logo-primary.png）的渐变走向是
     左下深蓝 → 中部天蓝 → 右上青绿 → 右上角亮绿点。下面五个色标就是
     在该图上采样得到的，不是另配的。

     ⚠️ 对比度分两类用途，不可混用：
       蓝段 #2837fa(6.96:1) / #3f5ce5(5.42:1)  ——  可承载白字
       青绿段 #4699c5(3.17) / #35c3ae(2.19) / #00ff90(1.34)
                                             ——  只能做描边、色块、装饰条，
                                                 其上绝对不要放文字
     这也是下面 --grad-cta 只取蓝段、--grad-brand 才用全色域的原因。 */
  --brand-blue:   #2837fa;
  --brand-indigo: #3f5ce5;
  --brand-azure:  #4699c5;
  --brand-teal:   #35c3ae;
  --brand-green:  #00ff90;

  /* 全色域装饰渐变：只用于不承载文字的地方（顶部细条、标题前的小色条、
     卡片顶边、logo 光晕）。"不显得单调"主要靠它。 */
  --grad-brand: linear-gradient(100deg,
                  var(--brand-blue) 0%,
                  var(--brand-indigo) 28%,
                  var(--brand-azure) 56%,
                  var(--brand-teal) 80%,
                  var(--brand-green) 100%);

  /* CTA 渐变：刻意只在蓝段内走，两端白字分别 6.96:1 / 5.42:1，
     整条渐变上任意一点都高于 4.5:1。 */
  --grad-cta:       linear-gradient(135deg, #2837fa 0%, #3f5ce5 100%);
  --grad-cta-hover: linear-gradient(135deg, #1d29ff 0%, #3348d8 100%);

  /* 极淡背景洗色（3%）。实测正文 15.5:1、次要文字 4.84:1，仍达标。
     再浓就会把 --text-muted 压到 4.5 以下，不要加。 */
  --grad-wash: linear-gradient(135deg,
                 rgba(40, 55, 250, .03) 0%,
                 rgba(53, 195, 174, .03) 100%);

  /* --- 颜色（§4.6） ------------------------------------------------------ */
  --bg:           #ffffff;
  --bg-alt:       #fbfbfd;              /* Apple 招牌浅灰，用于交替分区 */
  --text:         #1d1d1f;              /* 近黑，标题与正文 */
  --text-muted:   #6e6e73;              /* 次要文字，白底 5.07:1 */

  /* §4.6 原定 accent 为 Apple 蓝 #0071e3（白底 4.70:1）。既然已经拿 logo
     定了品牌蓝，链接与焦点环改用 logo 自己的蓝，整站和图标同源，
     且对比度从 4.70 提到 7.01，更稳。 */
  --accent:       #2d3bf0;              /* 白底 7.01:1 */
  --accent-hover: #1d29ff;              /* 白底 7.46:1 */

  --text-2:       #48484d;              /* 浅色底块上的次要文字：灰底 8.12:1，
                                           --text-muted 在这些底上只剩 4.5 上下 */

  --border:       rgba(0, 0, 0, .08);   /* 仅用于分隔线等装饰，不用于控件边界 */
  --danger:       #b3261e;              /* 白底 6.54:1，用于表单错误 */
  --danger-bg:    #fdf2f1;
  /* 徽章底是 10% 的本色叠在白底上（合成 #e8f2ed）。
     原 #1a7f4b 在白底 5.02:1 合格，但在徽章底上只有 4.39:1 —— 徽章文字
     只有 13px，必须按正文档位满足 4.5:1，故压深一档。 */
  --ok:           #177142;              /* 白底 6.04:1，徽章底 5.28:1 */
  --ok-bg:        #eaf5ef;              /* --ok 在其上 5.41:1 */
  --warn:         #8a5300;              /* 只做图标与小字，--warn-bg 上 5.90:1 */
  --warn-bg:      #fff6e5;

  /* 品牌蓝的浅色铺底：图标底块、选中态、提示框。--accent 在 --tint 上 6.25:1。
     --tint-2 更淡，只用于大面积的悬停/选中底色。 */
  --tint:         #f0f1ff;
  --tint-2:       #f7f8ff;

  /* 深色代码块 / 终端。文字 #e8ebf7 15.0:1、注释 #8f98c2 6.33:1、
     提示符（品牌青）8.14:1、YAML 键 #8ab4ff 8.55:1。 */
  --ink:          #0f1533;
  --ink-bar:      #191e3b;

  /* 控件边界（输入框等）受 WCAG 1.4.11 非文字对比度约束，需 ≥3:1。
     §4.6 的「不用重边框」是针对卡片说的，卡片靠底色与阴影分层、本来就
     没有边框；但输入框的边框是用户识别「这里可以输入」的唯一视觉线索，
     淡到 rgba(0,0,0,.16)（#d6d6d6，仅 1.45:1）就不合格了。
     这里取刚过线并留余量的值。 */
  --field-border:       rgba(0, 0, 0, .42);   /* ≈#949494，3.03:1 */
  --field-border-hover: rgba(0, 0, 0, .58);   /* 更深，hover 有明确反馈 */

  /* --- 圆角（§4.6） ------------------------------------------------------ */
  --radius:       18px;
  --radius-lg:    28px;
  --radius-sm:    12px;                 /* 输入框等小元素，18px 过圆 */
  --radius-pill:  980px;                /* Apple 胶囊按钮 */

  /* --- 布局 ------------------------------------------------------------- */
  /* lcms2yield 用 980px；本站的介绍页首屏、工具页、手册都是两栏，980 下
     首屏左栏只剩约 490px，连两颗主按钮都并排不下，所以放宽到 1120。
     长段落另由 .lead 等自身的 max-width 控制行宽，不靠版心。 */
  --maxw:         1120px;
  /* 顶栏实际高度 = nav__inner 的 min-height 52px + 上下 padding 8px×2 + 1px 边框。
     表格的 sticky 表头要减掉这个高度，否则会滑到半透明顶栏底下。 */
  --nav-h:        69px;

  /* --- 间距（density 4/10 = standard） ---------------------------------- */
  --space-1:  4px;
  --space-2:  8px;
  --space-3:  16px;
  --space-4:  24px;
  --space-5:  32px;
  --space-6:  48px;
  --space-7:  64px;

  /* --- 字体（§4.6：系统字体栈，不引入 webfont） ------------------------
     下面的栈分两段：前半段管拉丁字母（各平台原生 UI 字体），后半段管中文。
     中文必须排在拉丁之后 —— 中文字体自带拉丁字形，排前面会把拉丁顶掉。

     中文回退：macOS PingFang → Windows 雅黑 → Linux Noto。

     ⚠️ Linux 上一定要写 "Noto Sans CJK SC" 这个族名。发行版装的 fonts-noto-cjk
     给出的族名就是它，而 "Noto Sans SC"（Google Fonts 的叫法）在 Linux 上根本
     不存在 —— fc-match 会落回 DejaVu Sans，而那字体没有任何中文字形。此前
     Linux 上中文没出问题纯属侥幸：Debian/Ubuntu 在 fontconfig 里把
     "Microsoft YaHei" 别名到了 Noto Sans CJK SC
     （/etc/fonts/conf.d/65-nonlatin.conf），换个发行版就未必有这条别名。

     等宽那组同理带上 CJK 等宽字体：BibTeX 的作者名可能是中文，否则会落到
     fontconfig 的自动兜底。 */
  --font-sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
               "SF Pro Text", "SF Pro Display", "Helvetica Neue",
               "PingFang SC", "Microsoft YaHei UI", "Microsoft YaHei",
               "Noto Sans CJK SC", "Noto Sans SC", "Source Han Sans SC",
               "WenQuanYi Micro Hei", "WenQuanYi Zen Hei", "Droid Sans Fallback",
               sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
               "Liberation Mono", "Noto Sans Mono CJK SC",
               "WenQuanYi Zen Hei Mono", monospace;

  /* --- 阴影（§4.6：极淡，不用重边框） ---------------------------------- */
  --shadow:    0 1px 2px rgba(16, 24, 40, .04), 0 2px 12px rgba(16, 24, 40, .04);
  --shadow-md: 0 1px 2px rgba(16, 24, 40, .05), 0 6px 24px rgba(16, 24, 40, .08);
  --shadow-lg: 0 2px 6px rgba(16, 24, 40, .04), 0 24px 48px -16px rgba(16, 24, 40, .16);

  /* --- 动效（§4.6：微妙即可，不做弹跳或大幅位移） ---------------------- */
  --t: .2s ease;
}

/* ============================================================================
   基础
   ========================================================================== */

*,
*::before,
*::after { box-sizing: border-box; }

/* 浏览器对 [hidden] 的 display:none 是 UA 样式，优先级低于任何作者样式：
   一个 <button class="btn" hidden> 会被 .btn 的 display:inline-flex 顶出来。
   本站多处用 hidden 属性切换显隐（提交中的提示、3D 视图的「完成」按钮等），
   必须在这里强制兜住。 */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;       /* 不禁用缩放，只阻止横屏自动放大 */
  scroll-behavior: smooth;
}

/*
  顶栏是 sticky 的，跳转到锚点时目标会停在顶栏底下被挡住。
  站内这些跳转都依赖它：提交后跳 #results、错误汇总跳到出错字段、
  历史页空状态跳 /#predict、注册页跳页脚 #privacy。
*/
[id] { scroll-margin-top: calc(var(--nav-h) + var(--space-3)); }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);        /* 见 :root 里 --font-sans 的说明 */
  font-size: 17px;                      /* §4.6：正文 17px 而非 16px */
  line-height: 1.47;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* 正文里的等宽字体（文件名、版本号、数值），见 :root 的 --font-mono */
code, pre, .mono, .num {
  font-family: var(--font-mono);
}

img, svg { max-width: 100%; }
img { height: auto; }

/* ============================================================================
   排版（§4.6 字号表）
   大标题带负字距，是 Apple 观感的关键细节。
   字号用 clamp 收口，56px 在 375px 宽的屏上会溢出。
   ========================================================================== */

h1, h2, h3 {
  margin: 0;
  font-weight: 600;
  letter-spacing: -.02em;
}

.h-hero {                               /* Hero 标题 56px / 1.05 */
  font-size: clamp(34px, 7.2vw, 56px);
  line-height: 1.05;
}

.h-section {                            /* 区块标题 H2 40px / 1.1 */
  font-size: clamp(26px, 5vw, 40px);
  line-height: 1.1;
}

.h-sub {                                /* 小标题 H3 24px / 1.2 */
  font-size: clamp(20px, 3vw, 24px);
  line-height: 1.2;
  letter-spacing: -.01em;
}

p { margin: 0 0 var(--space-3); }
p:last-child { margin-bottom: 0; }

/* 页头里标题与紧跟的导语之间留一档；标题自身 margin 为 0 */
h1 + .lead,
h1 + .muted { margin-top: var(--space-3); }

.lead {
  max-width: 42em;                       /* 版心放宽到 1120 后，整行铺开会超过 100 字符 */
  font-size: clamp(18px, 2.4vw, 21px);
  line-height: 1.4;
  color: var(--text-muted);
  letter-spacing: -.01em;
}

/* 不做两端对齐：本站正文是英文，两栏布局里行宽较短，justify 会拉出词间大空隙。 */

.muted {                                /* 辅助文字 14px / 1.4 */
  font-size: 14px;
  line-height: 1.4;
  color: var(--text-muted);
}

a {
  color: var(--accent);
  text-decoration: none;
  transition: color var(--t);
}
a:hover { color: var(--accent-hover); }
/* 正文内链接保留下划线 —— 不能只靠颜色区分链接。
   独立成行的链接（.text-link、按钮）不在此列，它们靠位置与图标识别。 */
.lead a, .body-lg a, .muted a, figcaption a, .footer a, .callout a, .step a,
.tips a, .checklist a, .field__help a, .manual p a, .opts a, .contact a {
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ============================================================================
   焦点可见性（优先级 1：绝不移除焦点环）
   用 :focus-visible，鼠标点击不出现、键盘操作一定出现。
   ========================================================================== */

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
/* 不支持 :focus-visible 的老浏览器仍保留默认焦点环 */
:is(a, button, input, textarea, select, [tabindex]):focus:not(:focus-visible) {
  outline: none;
}

/* 跳转到主内容 —— 键盘用户第一个可聚焦元素 */
.skip-link {
  position: absolute;
  left: var(--space-3);
  top: -100px;
  z-index: 100;
  padding: 10px var(--space-3);
  background: var(--bg);
  color: var(--accent);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
  transition: top var(--t);
}
.skip-link:focus { top: var(--space-3); }

/* ============================================================================
   布局
   §4.6：内容最大宽度 980px 居中，区块上下留白 80–120px
   ========================================================================== */

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--space-4);        /* 每个断点都留 ≥16px 侧边距 */
}

.section {
  position: relative;
  padding-block: clamp(var(--space-6), 9vw, 112px);
}
.section--tight { padding-block: clamp(var(--space-5), 6vw, var(--space-7)); }

/* 交替分区：在 §4.6 的 --bg-alt 之上再叠一层 3% 的品牌洗色。
   纯 #fbfbfd 大面积铺开偏灰，加这一层后蓝→青有极轻微的冷暖变化。
   浓度卡在 3%：实测再往上 --text-muted 会跌破 4.5:1。 */
.section--alt {
  background-color: var(--bg-alt);
  background-image: var(--grad-wash);
}

/* 标题前的小色条。承担「不单调」的主要观感，又完全不碰文字对比度。 */
.accent-rule {
  display: block;
  width: 52px;
  height: 4px;
  margin-bottom: var(--space-4);
  border-radius: 99px;
  background: var(--grad-brand);
}

/* Hero 背后的品牌光晕。两团极淡的 logo 蓝/青径向渐变，给首屏一点
   色彩纵深，又不至于让标题区变成一块死白。
   浓度取 5%：光晕最浓处正好压在 .lead 这类 --text-muted 文字下面，
   实测 5% 时仍有 4.67:1；7% 会掉到 4.52:1，贴着 4.5 的线太险。 */
.hero {
  position: relative;
  isolation: isolate;
}
.hero::before {
  content: "";
  position: absolute;
  z-index: -1;
  /* 左右不外扩：伪元素超出版面会撑出横向滚动条（宽屏上正好多出 5% 的宽度） */
  inset: -10% 0 auto;
  height: 520px;
  pointer-events: none;
  background:
    radial-gradient(42% 55% at 12% 0%,  rgba(40, 55, 250, .05) 0%, transparent 70%),
    radial-gradient(38% 50% at 88% 12%, rgba(53, 195, 174, .05) 0%, transparent 72%);
}


/* ============================================================================
   顶部导航（§4.1 第 0 项：浅色半透明）
   ========================================================================== */

.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255, 255, 255, .82);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--border);
}
/* 顶部 3px 品牌渐变细条。整站第一眼的颜色来源，成本极低、
   不承载任何文字，所以可以放心用全色域渐变。 */
.nav::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 3px;
  background: var(--grad-brand);
}
/* 不支持 backdrop-filter 时退回不透明底，避免文字压在内容上 */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .nav { background: var(--bg); }
}

.nav__inner {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 52px;
  padding-block: var(--space-2);
}

/* 官方横版 logo + 产品名（base.html）。
   logo 高 28px 时，图内字标的大写高度（画布 312 中占 116–266 行，即 48%）≈ 13.5px，
   与 19px 的 "XFF" 大写高度一致。
   对齐按基线：flex 的 baseline 对 <img> 取其下外边距边缘，而字标基线在画布底边
   往上 46/312 处，所以用等量的负 margin-bottom 把图片「基线」提到字标基线上。 */
.brand {
  display: inline-flex;
  align-items: baseline;
  gap: .5em;
  color: var(--text);
  font-size: 19px;
  letter-spacing: -.02em;
  white-space: nowrap;
}
.brand:hover { color: var(--text); }

.brand__logo {
  --logo-h: 28px;
  display: block;
  width: auto;
  height: var(--logo-h);
  flex: 0 0 auto;
  margin-bottom: calc(var(--logo-h) * -46 / 312);
}

.brand__sep  { color: #c7c7cc; font-weight: 300; }
.brand__app  { font-weight: 500; }

.nav__spacer { flex: 1 1 auto; }


.nav__links {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* 导航项与退出按钮尺寸一致，均满足 44px 最小可点区域 */
/* 退出是 <button>（必须走 POST），与 <a> 导航项共用这个类，
   所以要显式重置按钮的默认边框/底色/字体 —— button 不会继承 body 的字体。 */
.nav__link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--space-3);
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 15px;
  line-height: 1.2;
  text-align: center;
  cursor: pointer;
  transition: background var(--t), color var(--t);
}
.nav__link:hover { background: rgba(0, 0, 0, .05); color: var(--text); }
.nav__link[aria-current="page"] { color: var(--accent); font-weight: 500; }

.nav__user {
  max-width: 24ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-muted);
  font-size: 15px;
}

/* 窄屏：邮箱让位给导航项 */
@media (max-width: 560px) {
  .nav__user { display: none; }
  .nav__link { padding-inline: var(--space-2); }
  .brand { font-size: 17px; }
  .brand__logo { --logo-h: 25px; }       /* 字标大写高度随 17px 文字同比缩小 */
}

/* 手机宽度：品牌 + 4 个导航项一行放不下（约 460px 对 342px 可用宽度），
   导航项换到第二行，整行左对齐；再窄也只在这一行内横向滚动，不撑破页面。

   order: 1 把 <nav> 排到最后 —— 它就是靠这个被挤到第二行的。本站现在只有
   英文、没有语言切换控件，看着可有可无；一旦加上第二种语言（见 CLAUDE.md
   「语言」），少了它语言切换会跟着掉到第三行，顶栏变成三行。

   顶栏随之变高，--nav-h 跟着改，锚点跳转与吸顶元素才不会被它挡住。 */
@media (max-width: 640px) {
  :root { --nav-h: 85px; }               /* 实测两行顶栏的高度（390px 下量的） */
  .nav__inner { flex-wrap: wrap; row-gap: 0; padding-bottom: 0; }
  .nav nav {
    order: 1;
    flex: 1 1 100%;
    margin-inline: calc(-1 * var(--space-2));
    overflow-x: auto;
    scrollbar-width: none;
  }
  .nav nav::-webkit-scrollbar { display: none; }
  .nav__links { flex-wrap: nowrap; }
  .nav__link { white-space: nowrap; }
}

/* ----------------------------------------------------------------------------
   语言切换（分段控件）
   -------------------------------------------------------------------------- */

.langsw {
  display: inline-flex;
  flex: 0 0 auto;
  margin-left: var(--space-2);
  padding: 2px;
  border-radius: var(--radius-pill);
  background: rgba(0, 0, 0, .05);
}

.langsw__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 导航里空间有限，按钮做到 30px 高、38px 宽；为满足 44×44 的最小
     可点区域，用 ::after 把命中区域向外扩到 44px，视觉尺寸不变。 */
  position: relative;
  min-width: 38px;
  height: 30px;
  padding-inline: 9px;
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-muted);
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  transition: background var(--t), color var(--t);
}
.langsw__btn::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  min-width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
}
.langsw__btn:hover { color: var(--text); }

/* 当前语言：白底 + 阴影，做成被"抬起"的那一段 */
.langsw__btn[aria-current="true"] {
  background: var(--bg);
  color: var(--text);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .1);
  cursor: default;
}

@media (max-width: 560px) {
  .langsw { margin-left: var(--space-1); }
  .langsw__btn { min-width: 34px; padding-inline: 6px; }
}

/* ============================================================================
   按钮（§4.6：Apple 蓝胶囊形，白字，hover 提亮）
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 44px;                      /* 优先级 2：最小 44×44 */
  padding: 11px var(--space-4);
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  /* background-color 是兜底：forced-colors 模式会丢弃 background-image，
     渐变消失后仍是一块合规的纯色按钮，不会变成透明。 */
  background-color: var(--brand-blue);
  background-image: var(--grad-cta);
  color: #fff;
  font: inherit;
  font-size: 17px;
  font-weight: 400;
  line-height: 1.2;
  text-align: center;
  cursor: pointer;
  /* 主按钮带一层品牌蓝的投影，在白底上有「浮起」的层次；次要按钮不带 */
  box-shadow: 0 6px 16px -8px rgba(40, 55, 250, .65);
  transition: background-image var(--t), background-color var(--t),
              color var(--t), border-color var(--t), opacity var(--t),
              box-shadow var(--t);
}
.btn:hover {
  background-color: var(--accent-hover);
  background-image: var(--grad-cta-hover);
  color: #fff;
  box-shadow: 0 8px 20px -8px rgba(40, 55, 250, .75);
}
.btn .icon { flex: 0 0 auto; }
.btn:active { opacity: .88; }

.btn--secondary {
  /* 简写同时清掉 background-image，次要按钮不带渐变 —— 页面上只有
     主 CTA 用渐变，否则到处都是彩色反而更吵。 */
  background: transparent;
  /* 次要按钮的边框也是控件边界，同样受 1.4.11 约束（≥3:1） */
  border-color: var(--field-border);
  color: var(--accent);
  box-shadow: none;
}
.btn--secondary:hover {
  background: rgba(0, 0, 0, .04);
  border-color: var(--field-border-hover);
  color: var(--accent-hover);
  box-shadow: none;
}

.btn--block { width: 100%; }
.btn--lg { min-height: 50px; padding: 13px 26px; font-weight: 500; }
/* 小号按钮视觉 36px，命中区域用 ::after 扑到 44px（与语言切换同一做法） */
.btn--sm { position: relative; min-height: 36px; padding: 7px 14px; font-size: 14px; }
.btn--sm::after { content: ""; position: absolute; inset: -4px 0; }

.btn[disabled],
.btn[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: .55;
}
.btn[disabled]:hover,
.btn[aria-disabled="true"]:hover {
  background-image: var(--grad-cta);     /* 禁用态不响应 hover */
}

/* 提交中的转圈。reduced-motion 下换成静态点，见文件末尾。 */
.btn__spinner {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  border: 2px solid rgba(255, 255, 255, .45);
  border-top-color: #fff;
  border-radius: 50%;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.btn-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

/* ============================================================================
   卡片（§4.6：白底、圆角、极淡阴影，不用重边框）
   ========================================================================== */

.card {
  position: relative;
  background: var(--bg);
  border-radius: var(--radius-lg);
  /* 一圈极淡的描边：在 --bg-alt 分区上，只靠阴影的白卡片边缘会糊掉 */
  box-shadow: 0 0 0 1px rgba(16, 24, 40, .04), var(--shadow);
  padding: clamp(var(--space-4), 4vw, var(--space-6));
}

/* 卡片顶边的品牌渐变条。只给页面上最主要的那张卡片（表单、结果）用，
   每张卡都加就失去重点了。overflow:hidden 让色条跟着圆角走。 */
.card--accent { overflow: hidden; }
.card--accent::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 4px;
  background: var(--grad-brand);
}

/* ============================================================================
   表单（优先级 8：可见 label、错误贴着字段、帮助文字）
   ========================================================================== */

.field { margin-bottom: var(--space-4); }
.field:last-of-type { margin-bottom: 0; }

.field__label {
  display: block;
  margin-bottom: var(--space-2);
  font-size: 15px;
  font-weight: 500;
}
.field__req {
  margin-left: .25em;
  color: var(--text-muted);
  font-weight: 400;
}

/* 用元素选择器给 Django 渲染出的原生控件上样式，
   这样 forms.py 不必为了外观往 widget 里塞 class。 */
.field input[type="text"],
.field input[type="email"],
.field input[type="password"],
.field input[type="number"],
.field textarea,
.field select {
  display: block;
  width: 100%;
  min-height: 44px;
  padding: 11px 14px;
  border: 1px solid var(--field-border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--text);
  font: inherit;
  font-size: 17px;                       /* ≥16px，iOS 聚焦时才不会自动放大 */
  transition: border-color var(--t), box-shadow var(--t);
}
.field textarea {
  min-height: 160px;
  line-height: 1.5;
  resize: vertical;
  font-family: var(--font-mono);
  font-size: 15px;
}
/* placeholder 属于要读的内容，按正文档位满足 4.5:1。
   #a1a1a6 只有 2.57:1，换成 #767676（4.54:1）。
   label 与 help_text 始终可见，placeholder 不承担 label 职责。 */
.field input::placeholder,
.field textarea::placeholder { color: #767676; opacity: 1; }

.field input:hover,
.field textarea:hover { border-color: var(--field-border-hover); }

.field input:focus,
.field textarea:focus,
.field select:focus {
  /* 焦点环用 box-shadow 画，观感比 outline 柔和。
     但强制高对比模式（Windows 高对比 / forced-colors）会直接丢弃 box-shadow，
     焦点就彻底不可见了 —— 所以留一圈 transparent 的 outline：
     正常模式下看不见，forced-colors 下会被系统换成可见的高亮色。 */
  outline: 2px solid transparent;
  outline-offset: 2px;
  border-color: var(--accent);
  box-shadow: 0 0 0 4px rgba(0, 113, 227, .16);
}

/* 出错字段：边框 + 文案双通道，不只靠颜色 */
.field input[aria-invalid="true"],
.field textarea[aria-invalid="true"] {
  border-color: var(--danger);
}
.field input[aria-invalid="true"]:focus,
.field textarea[aria-invalid="true"]:focus {
  box-shadow: 0 0 0 4px rgba(179, 38, 30, .14);
}

.field__help {
  margin: var(--space-2) 0 0;
  color: var(--text-muted);
  font-size: 14px;
  line-height: 1.4;
}
/* Django 的密码规则 help_text 是一段 <ul> */
.field__help ul { margin: var(--space-1) 0 0; padding-left: 1.25em; }
.field__help li { margin-top: 2px; }

.field__error {
  display: flex;
  gap: .4em;
  margin: var(--space-2) 0 0;
  color: var(--danger);
  font-size: 14px;
  line-height: 1.4;
  font-weight: 500;
}
.field__error svg { flex: 0 0 auto; margin-top: 2px; }

/* 顶部错误汇总：可聚焦，每条链到对应字段 */
.alert {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
  background: var(--danger-bg);
  color: var(--danger);
  font-size: 15px;
  line-height: 1.45;
}
.alert svg { flex: 0 0 auto; margin-top: 2px; }
.alert h2 {
  margin: 0 0 var(--space-1);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0;
}
.alert ul { margin: var(--space-1) 0 0; padding-left: 1.1em; }
.alert li + li { margin-top: 2px; }
.alert a { color: var(--danger); text-decoration: underline; text-underline-offset: 2px; }
.alert--info {
  background: var(--bg-alt);
  color: var(--text);
  border: 1px solid var(--border);
}

/* ============================================================================
   表格与徽章
   ========================================================================== */

/* 可横向滚动的容器必须可聚焦（模板里带 tabindex="0"），否则纯键盘用户滚不动 */
.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border-radius: var(--radius);
  background: var(--bg);
  box-shadow: 0 0 0 1px var(--border);
}
.table-scroll:focus-visible { outline-offset: 0; }

.table {
  width: 100%;
  min-width: 480px;
  border-collapse: collapse;
  font-size: 15px;
}
.table caption {
  padding: var(--space-3) var(--space-3) var(--space-2);
  color: var(--text-muted);
  font-size: 14px;
  text-align: left;
}
.table th,
.table td {
  padding: 12px var(--space-3);
  text-align: left;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
.table thead th {
  /* 不用 position:sticky：.table-scroll 设了 overflow-x:auto，容器自己成了
     滚动根，sticky 永远不触发。表头靠 --bg-alt 底色与正文区分即可。 */
  background: var(--bg-alt);
  color: var(--text-muted);
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
}
.table tbody th { font-family: var(--font-mono); font-weight: 600; font-size: 14px; }
.table tbody tr:last-child > * { border-bottom: 0; }
.table td code { margin-right: 6px; }
.table--compact th,
.table--compact td { padding-block: 10px; }

.badge {
  display: inline-flex;
  align-items: center;
  gap: .35em;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
}
.badge--ok    { background: var(--ok-bg);     color: var(--ok); }
.badge--fail  { background: var(--danger-bg); color: var(--danger); }
.badge--brand { background: var(--tint);      color: var(--accent); }

/* 页面顶部的一次性提示 */

/* 页面顶部的一次性提示 */
.flash { padding-top: var(--space-4); }
.flash .alert { margin: 0; }

/* ============================================================================
   按钮行与文字链接
   ========================================================================== */

.cta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-5);
}

/* 「完整介绍 →」这类独立文字链接：比正文略重，末尾的箭头悬停时右移。
   箭头有两种写法：登录 / 注册页的 <span>→</span>，其余页面的 {% icon "arrow-right" %} */
.text-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 500;
}
.text-link span,
.text-link .icon { display: inline-block; flex: 0 0 auto; transition: transform var(--t); }
.text-link:hover span,
.text-link:hover .icon:last-child:not(:first-child) { transform: translateX(2px); }

/* ============================================================================
   页脚（§12：说明收集了什么、用途、如何要求删除）
   ========================================================================== */

.footer {
  padding-block: var(--space-6);
  border-top: 1px solid var(--border);
  background: var(--bg-alt);
  color: var(--text-muted);
  font-size: 13px;
  line-height: 1.6;
}
.footer h2 {
  margin: 0 0 var(--space-2);
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0;
}
/* 左栏是「参考」（页脚里唯一有正文的一栏），右栏是「隐私 + 版权」——
   隐私只剩一句说明加一个链接，所以主要宽度给左栏。比例曾经反过来过
   （隐私摘要在左边的时候），别不加判断地调换。 */
.footer__cols {
  display: grid;
  gap: var(--space-5) var(--space-6);
  grid-template-columns: 1fr;              /* 移动端单栏堆叠 */
}
@media (min-width: 768px) {
  .footer__cols {
    grid-template-columns: 1.5fr 1fr;
  }
}

/* 两栏要「一样长」：各栏都撑满行高，多出来的那点高度均摊到内部间距上，
   而不是在短的那一栏下方留一块空白（栏底参差就是这么来的）。
   两栏都写 space-between：内容哪天谁变长了，另一栏自动吸收差值。 */
.footer__ref,
.footer__aside {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.footer__aside {
  gap: 20px;                               /* 隐私块与版权行之间，原 32px，右栏偏高 */
}
.footer__bottom {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding-top: var(--space-3);             /* 原 var(--space-4)，同上 */
  border-top: 1px solid var(--border);
}
.footer__bottom p { margin: 0; }
.footer p { margin-bottom: var(--space-2); }
/* 每栏最后一行不留尾距：两栏靠 space-between 撑成等高，最后那块若还带 8px 下边距，
   两栏的文字底线就差这 8px，看着仍然是「不一样长」。必须写在这条之后。 */
.footer p:last-child { margin-bottom: 0; }

/* ============================================================================
   认证页（登录 / 注册）
   ========================================================================== */

.auth {
  display: grid;
  gap: clamp(var(--space-5), 5vw, var(--space-7));
  align-items: start;
  grid-template-columns: 1fr;
}
@media (min-width: 900px) {
  .auth { grid-template-columns: 1fr 1fr; }
}
.auth__form { max-width: 420px; width: 100%; }
.auth__aside { min-width: 0; }

/* ============================================================================
   其它
   ========================================================================== */

/* ============================================================================
   其它
   ========================================================================== */

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ============================================================================
   确认弹窗（base.html 的 #confirm-dialog，由 app.js 驱动）
   居中卡片：大圆角、柔和阴影、毛玻璃遮罩，与站点卡片同一语言。
   ========================================================================== */

.dialog {
  width: min(400px, calc(100vw - 2 * var(--space-4)));
  max-width: none;
  margin: auto;
  padding: 0;                             /* 点击目标为 <dialog> 本身 = 点在遮罩上，见 app.js */
  border: 0;
  border-radius: var(--radius-lg);
  background: var(--bg);
  color: var(--text);
  box-shadow: 0 24px 64px rgba(0, 0, 0, .18), 0 2px 8px rgba(0, 0, 0, .08);
  overflow: visible;
}
.dialog::backdrop {
  background: rgba(29, 29, 31, .32);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
/* 打开时锁住页面滚动 */
html:has(.dialog[open]) { overflow: hidden; }

.dialog[open] { animation: dialog-in .2s cubic-bezier(.2, .8, .2, 1); }
.dialog[open]::backdrop { animation: backdrop-in .2s ease-out; }
@keyframes dialog-in {
  from { opacity: 0; transform: translateY(8px) scale(.97); }
}
@keyframes backdrop-in {
  from { opacity: 0; }
}

.dialog__panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: var(--space-5) var(--space-5) var(--space-4);
  text-align: center;
}

/* 只有危险操作才显示警示图标 */
.dialog__icon {
  display: none;
  width: 48px;
  height: 48px;
  margin-bottom: var(--space-3);
  border-radius: 50%;
  align-items: center;
  justify-content: center;
}
.dialog--danger .dialog__icon {
  display: inline-flex;
  background: var(--danger-bg);
  color: var(--danger);                    /* 图标对其底色 5.96:1 */
}

.dialog__title {
  margin: 0;
  font-size: 19px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -.01em;
}
.dialog__detail {
  margin: var(--space-2) 0 0;
  color: var(--text-muted);
  font-size: 15px;
  line-height: 1.45;
  font-variant-numeric: tabular-nums;
}

/* 两个按钮等宽并排；窄屏上下排，确认在上 */
.dialog__actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2);
  width: 100%;
  margin-top: var(--space-5);
}
.dialog__actions .btn { width: 100%; }
@media (max-width: 360px) {
  .dialog__actions { grid-template-columns: 1fr; }
  .dialog__actions [data-dialog-ok] { order: -1; }
}

/* 危险操作：确认按钮红色实心。白字 6.54:1，hover 8.71:1 */
.dialog--danger [data-dialog-ok] {
  background-color: var(--danger);
  background-image: none;
}
/* 必须同时清掉 background-image：.btn:hover 会叠一层蓝色渐变，盖在红色上 */
.dialog--danger [data-dialog-ok]:hover { background-color: #921d17; background-image: none; }

@media (forced-colors: active) {
  .dialog { border: 1px solid CanvasText; }
}

/* ============================================================================
   GENXFF 组件
   以下为本站页面专用的组件。令牌全部复用上面的 :root，不另起颜色。
   顺序：通用小件 → 介绍页 → 工具页 → license → 手册 → 错误页
   ========================================================================== */

/* --- 分区变体 ------------------------------------------------------------ */
/* 内页页头：比介绍页的大分区紧凑，标题下面紧跟内容 */
.section--head {
  padding-block: clamp(var(--space-5), 6vw, 72px) clamp(var(--space-4), 3vw, var(--space-5));
}
/* 紧跟页头的内容区：顶部不再留白，否则页头与内容之间像断开了 */
.section--flush-top {
  padding-top: 0;
  padding-bottom: clamp(var(--space-6), 8vw, 96px);
}

/* 区块标题上方的小标签。不做全大写（中文无大小写，且会改掉 GENXFF / AMBER
   这类专有名词的写法），只靠颜色与字重区分。 */
.eyebrow {
  margin: 0 0 var(--space-2);
  color: var(--accent);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: .01em;
}
.eyebrow + .h-section,
.eyebrow + .h-hero { margin-top: 0; }

.body-lg {
  margin-top: var(--space-3);
  color: var(--text-muted);
  font-size: 17px;
  line-height: 1.6;
}

.note { margin-top: var(--space-4); max-width: 760px; }
.mono { font-family: var(--font-mono); }

/* 行内代码（正文里的 -c bcc、.chg 等）：淡品牌底，与正文区分但不抢眼 */
.body-lg code,
.format__desc code,
.manual p code,
.manual li code,
.opts dd code,
.callout code {
  padding: 1px 6px;
  border-radius: 6px;
  background: var(--tint);
  color: #1f2a8a;                        /* --tint 上 10.9:1 */
  font-size: .88em;
}

.cta-row--tight { margin-top: var(--space-4); }

/* --- 标签条（chips） ------------------------------------------------------ */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 28px;
  padding: 3px 12px;
  border-radius: var(--radius-pill);
  background: var(--tint);
  color: var(--accent);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.2;
}
.chips--muted .chip {
  background: rgba(0, 0, 0, .05);
  color: var(--text-2);
  font-weight: 500;
}
.chips--muted .chip a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.chips--muted { margin-top: var(--space-4); }

/* --- 提示框（callout） ---------------------------------------------------
   与 .alert 的分工：.alert 是表单出错（红），.callout 是说明 / 提醒 / 成功，
   正文一律用 --text，靠底色和图标区分语气 —— 不让颜色单独承载含义。 */
.callout {
  display: flex;
  gap: var(--space-3);
  padding: 14px 18px;
  border-radius: var(--radius-sm);
  background: var(--tint);
  color: var(--text);
  font-size: 15px;
  line-height: 1.5;
}
.callout > .icon { flex: 0 0 auto; margin-top: 1px; color: var(--accent); }
.callout p { margin: 0; }
.callout p + p { margin-top: var(--space-1); }
.callout--warn { background: var(--warn-bg); }
.callout--warn > .icon { color: var(--warn); }
.callout--ok { background: var(--ok-bg); }
.callout--ok > .icon { color: var(--ok); }
.callout--lg { padding: 20px 24px; font-size: 16px; }
.callout__title { font-weight: 600; }

/* ============================================================================
   介绍页
   ========================================================================== */

.hero--home { padding-block: clamp(56px, 8vw, 104px); }

.hero__grid {
  display: grid;
  gap: clamp(var(--space-5), 5vw, var(--space-7));
  align-items: center;
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 900px) {
  .hero__grid { grid-template-columns: minmax(0, 1.12fr) minmax(0, .88fr); }
}
.hero__text .lead { margin-top: var(--space-4); max-width: 34em; }
/* 介绍页 hero 的三层结构，一层一种形式，不再混用大小按钮：
     1. .cta-row        动作 —— 主按钮 + 次要按钮，同为 --lg 高
     2. .hero-links     资料 —— 一行文字链接，都带 16px 图标
     3. .hero__account  账号提示 —— 一行次要文字
   同一层内尺寸与形式一致，层与层之间靠字号和间距拉开，不靠多种按钮样式。 */
.hero-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-5);
  margin: var(--space-4) 0 0;
  padding: 0;
  list-style: none;
}
.hero-links li { display: flex; }
/* 链接后的期刊说明：比链接文字小一号、用次要色，跟着链接走但不读作链接的一部分 */
.hero-links .meta {
  margin-left: .45em;
  color: var(--text-muted);
  font-size: 13px;
  font-weight: 400;
}

.hero__account {
  margin: var(--space-3) 0 0;
  font-size: 15px;
}

/* 「服务器给出哪些参数」卡片 */
.ffcard {
  position: relative;
  overflow: hidden;
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  background: var(--bg);
  box-shadow: 0 0 0 1px rgba(16, 24, 40, .05), var(--shadow-lg);
}
.ffcard::before {                          /* 顶边品牌渐变条，同 .card--accent */
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 4px;
  background: var(--grad-brand);
}
.ffcard__title {
  margin-bottom: var(--space-3);
  color: var(--text-muted);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0;
}
.terms {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.term {
  display: flex;
  flex-direction: column;
  padding: 14px 14px 12px;
  border-radius: var(--radius);
  background: var(--bg-alt);
  background-image: var(--grad-wash);
}
.term__glyph {
  width: 64px;
  height: 40px;
  margin-bottom: var(--space-2);
  overflow: visible;
}
.term__name { font-size: 16px; font-weight: 600; letter-spacing: -.01em; }
.term__desc { color: var(--text-muted); font-size: 14px; }

/* 示意图的笔触：原子白底品牌蓝描边，键灰色，能量项本身用品牌青高亮 */
.g-atom   { fill: #fff; stroke: var(--brand-blue); stroke-width: 2.5; }
.g-bond   { fill: none; stroke: #9aa1b5; stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
.g-spring { fill: none; stroke: var(--brand-azure); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
.g-accent { fill: none; stroke: var(--brand-teal); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
.g-axis   { fill: none; stroke: #c4c8d4; stroke-width: 1.5; stroke-dasharray: 3 4; }

.ffcard__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) 12px;
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border);
}
.ffcard__label { color: var(--text-muted); font-size: 14px; }

/* --- 三步流程 ------------------------------------------------------------ */
.steps {
  display: grid;
  gap: 20px;
  grid-template-columns: minmax(0, 1fr);
  margin: var(--space-5) 0 0;
  padding: 0;
  list-style: none;
  counter-reset: step;
}
@media (min-width: 760px) {
  .steps { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.step {
  position: relative;
  padding: 28px 24px 24px;
  border-radius: var(--radius-lg);
  background: var(--bg);
  box-shadow: 0 0 0 1px rgba(16, 24, 40, .04), var(--shadow);
  counter-increment: step;
}
/* 右上角的大号序号，纯装饰：<ol> 本身已经给读屏报了序号。
   「/ ""」是 CSS 生成内容的替代文本写法，让读屏跳过它；不认这种写法的
   浏览器会丢掉第二条声明，退回第一条。 */
.step::after {
  content: counter(step, decimal-leading-zero);
  content: counter(step, decimal-leading-zero) / "";
  position: absolute;
  top: 18px;
  right: 22px;
  color: rgba(40, 55, 250, .1);
  font-size: 44px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.04em;
}
.step__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin-bottom: var(--space-3);
  border-radius: 12px;
  background: var(--tint);
  color: var(--accent);
}
.step__title {
  margin-bottom: var(--space-2);
  font-size: 19px;
  line-height: 1.3;
  letter-spacing: -.01em;
}
.step p { color: var(--text-muted); font-size: 16px; line-height: 1.55; }

/* --- 左说明 / 右内容的两栏 ------------------------------------------------ */
.split {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 900px) {
  .split {
    grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr);
    gap: var(--space-7);
    align-items: start;
  }
}
.split__intro .callout { margin-top: var(--space-4); }

/* --- 电荷文件格式卡片 ------------------------------------------------------ */
.formats {
  display: grid;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}
.format {
  padding: 18px 20px;
  border-radius: var(--radius);
  background: var(--bg);
  box-shadow: 0 0 0 1px var(--border), var(--shadow);
}
.format__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}
.format__name { font-size: 17px; letter-spacing: -.01em; }
.format__dl {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 0 14px;
  border-radius: var(--radius-pill);
  background: var(--tint);
  font-size: 14px;
  font-weight: 600;
  transition: background var(--t);
  position: relative;
}
.format__dl::after { content: ""; position: absolute; inset: -4px 0; }
.format__dl:hover { background: #e4e7ff; }
.format__desc { margin: 6px 0 0; color: var(--text-muted); font-size: 15px; line-height: 1.5; }

/* 小段示例（电荷文件内容） */
.snippet {
  margin: 12px 0 0;
  padding: 10px 14px;
  overflow-x: auto;
  border-radius: 10px;
  background: var(--bg-alt);
  box-shadow: inset 0 0 0 1px var(--border);
  color: var(--text);
  font-size: 13.5px;
  line-height: 1.55;
}

/* --- 版本时间线 ----------------------------------------------------------- */
.releases {
  position: relative;
  display: grid;
  gap: var(--space-3);
  margin: var(--space-5) 0 0;
  padding: 0;
  list-style: none;
}
.releases::before {                        /* 竖线，装饰 */
  content: "";
  position: absolute;
  top: 18px;
  bottom: 18px;
  left: 7px;
  width: 2px;
  border-radius: 2px;
  background: linear-gradient(var(--brand-indigo), var(--brand-teal));
  opacity: .35;
}
.release {
  position: relative;
  margin-left: 32px;
  padding: 20px 24px;
  border-radius: var(--radius);
  background: var(--bg);
  box-shadow: 0 0 0 1px rgba(16, 24, 40, .04), var(--shadow);
}
.release::before {                         /* 时间线上的节点 */
  content: "";
  position: absolute;
  top: 26px;
  left: -32px;
  width: 16px;
  height: 16px;
  border: 3px solid var(--brand-indigo);
  border-radius: 50%;
  background: var(--bg);
}
.release__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) 12px;
  margin-bottom: var(--space-2);
}
.release__ver { font-size: 20px; font-weight: 600; letter-spacing: -.01em; }
.release__date { margin-left: auto; color: var(--text-muted); font-size: 14px; }
.release p { color: var(--text-muted); }

.structs {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: var(--space-3) 0 0;
  padding: 0;
  list-style: none;
}
.structs li {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 104px;
  height: 84px;
  border-radius: 12px;
  background: #fff;
  box-shadow: inset 0 0 0 1px var(--border);
}
/* 原图只有 40–70px，不放大插值（会糊），按原尺寸居中放在画框里 */
.structs img { width: auto; height: auto; }

/* --- 命令行下载 ----------------------------------------------------------- */
.cli {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: minmax(0, 1fr);
  align-items: center;
}
@media (min-width: 900px) {
  .cli { grid-template-columns: minmax(0, 1fr) minmax(0, .95fr); gap: var(--space-6); }
}
.cli .cta-row { margin-top: var(--space-4); }
.cli .cta-row + .muted { margin-top: var(--space-4); }

.terminal {
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--ink);
  box-shadow: 0 24px 48px -16px rgba(15, 21, 51, .45);
}
.terminal__bar {
  display: flex;
  gap: 6px;
  padding: 12px 14px;
  background: var(--ink-bar);
}
.terminal__bar span {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .2);
}
.terminal__body {
  margin: 0;
  padding: 18px 20px 22px;
  overflow-x: auto;
  color: #e8ebf7;
  font-size: 14px;
  line-height: 1.7;
  white-space: pre;
}
.t-comment { color: #8f98c2; }
.t-prompt  { color: var(--brand-teal); user-select: none; }

/* --- 关于晶泰科技（介绍页最后一段） -----------------------------------------
   与 lcms2yield-web 的同名类一致：宽屏「logo + 标题」在左、正文在右，窄屏上下排。 */
.company {
  display: grid;
  gap: var(--space-4) clamp(var(--space-5), 6vw, var(--space-7));
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 860px) {
  .company { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); align-items: start; }
}
.company__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
@media (min-width: 860px) {
  .company__head { flex-direction: column; align-items: flex-start; }
}
/* 标题与官网链接同组：窄屏下 .company__head 是横排，链接若作为它的第三个子项，
   logo + 标题 + 链接会挤在同一行。 */
.company__title {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
}
.company__logo {
  display: block;                          /* 挂在 <a> 上，width 要生效须非 inline */
  width: 150px;                            /* 992×312 等比，约 47px 高 */
  flex: 0 0 auto;
}
.company__logo img { display: block; width: 100%; height: auto; }
/* 独立链接（不在正文里），靠强调色 + 外链图标区分，不常驻下划线；
   悬停补下划线，给鼠标用户一个「这是链接」的确认。 */
.company__site {
  display: inline-flex;
  align-items: center;
  gap: .3em;
  font-size: 15px;
}
.company__site:hover { text-decoration: underline; text-underline-offset: 2px; }
.company__body p {
  color: var(--text-muted);
  font-size: 17px;
  line-height: 1.6;
}
.company__body p + p { margin-top: var(--space-3); }

/* --- 参考文献 ------------------------------------------------------------- */
.refs { margin: var(--space-4) 0 0; padding: 0; list-style: none; }
.ref {
  padding: 20px 24px;
  border-radius: var(--radius);
  background: var(--bg);
  box-shadow: 0 0 0 1px rgba(16, 24, 40, .04), var(--shadow);
}
.ref__text { font-size: 15px; line-height: 1.6; }
.ref__text cite { font-style: italic; }
.ref__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: 14px;
}
.contact {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-4);
  color: var(--text-muted);
  font-size: 15px;
}

/* ============================================================================
   工具页（generate.html）
   宽屏：左表单、右结果面板吸顶；窄屏上下排。
   ========================================================================== */

.tool {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}
@media (min-width: 960px) {
  .tool { grid-template-columns: minmax(0, 1fr) 360px; gap: var(--space-5); }
  .tool__aside { position: sticky; top: calc(var(--nav-h) + var(--space-4)); }
}
.tool__form { padding: clamp(var(--space-4), 4vw, 40px); }
.tool__form > .alert { margin-bottom: var(--space-4); }

/* 表单分步：fieldset 承担分组语义，legend 当步骤标题 */
.block { min-width: 0; margin: 0; padding: 0; border: 0; }
.block + .block {
  margin-top: 36px;
  padding-top: var(--space-5);
  border-top: 1px solid var(--border);
}
/* legend 默认嵌在 fieldset 的上边框里：.block + .block 的分隔线会被它截断，
   上方还会多出一截空白。浮动的 legend 不再是「渲染出的 legend」，按普通块排，
   后面的元素 clear 掉即可。 */
.block__title {
  float: left;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 20px;
  padding: 0;
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -.01em;
}
.block__title + * { clear: both; }
.block__num {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background-color: var(--brand-blue);
  background-image: var(--grad-cta);
  color: #fff;
  font-size: 15px;
  font-weight: 600;
}

.seg-field { min-width: 0; margin: 0; padding: 0; border: 0; }
.seg-field + .seg-field { margin-top: var(--space-4); }
legend.field__label { padding: 0; }

/* --- 分段控件（单选） -----------------------------------------------------
   原生 radio 透明地铺满每一段：点击、方向键切换、读屏的「单选按钮 1/2」
   全由浏览器提供，样式只画在后面的 span 上。 */
.seg {
  display: grid;
  grid-auto-columns: minmax(0, 1fr);
  grid-auto-flow: column;
  gap: 4px;
  padding: 4px;
  border-radius: 14px;
  background: rgba(0, 0, 0, .05);
}
.seg--fit { display: inline-grid; grid-auto-columns: auto; }
.seg__opt { position: relative; display: block; cursor: pointer; }
.seg__opt input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.seg__label {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: 8px 16px;
  border-radius: 10px;
  color: var(--text-2);
  font-size: 15px;
  font-weight: 500;
  line-height: 1.2;
  text-align: center;
  transition: background var(--t), color var(--t), box-shadow var(--t);
}
.seg__opt:hover .seg__label { color: var(--text); }
/* 手机上每段只有约 145px，「图标 + Upload files」按默认内边距会折成两行 */
@media (max-width: 480px) {
  .seg__label { padding-inline: 10px; white-space: nowrap; }
}
.seg__opt input:checked + .seg__label {
  background: var(--bg);
  color: var(--text);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .12), 0 1px 1px rgba(0, 0, 0, .04);
}
.seg__opt input:checked + .seg__label .icon { color: var(--accent); }
/* 链接版分段控件（隐私政策的中英文切换，见 _privacy_switch.html）：
   选项是 <a> 而不是 <label>+<input>，当前项用 aria-current 标，视觉与选中态一致。 */
.seg__opt[aria-current="true"] .seg__label {
  background: var(--bg);
  color: var(--text);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .12), 0 1px 1px rgba(0, 0, 0, .04);
  cursor: default;                       /* 当前语言，点它只是重载本页 */
}
.seg__opt input:focus-visible + .seg__label { outline: 2px solid var(--accent); outline-offset: 2px; }
.seg__meta {
  padding: 1px 8px;
  border-radius: var(--radius-pill);
  background: var(--tint);
  color: var(--accent);
  font-size: 12px;
  font-weight: 600;
}

/* --- 格式卡片（单选） ------------------------------------------------------ */
.choices {
  display: grid;
  gap: 12px;
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 600px) {
  .choices { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.choice { position: relative; display: block; cursor: pointer; }
.choice input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.choice__body {
  display: flex;
  flex-direction: column;
  gap: 10px;
  height: 100%;
  padding: 14px 16px;
  border: 1.5px solid rgba(0, 0, 0, .14);
  border-radius: var(--radius-sm);
  background: var(--bg);
  transition: border-color var(--t), background var(--t), box-shadow var(--t);
}
.choice:hover .choice__body { border-color: rgba(0, 0, 0, .32); }
.choice input:checked + .choice__body {
  border-color: var(--accent);
  background: var(--tint-2);
  box-shadow: 0 0 0 3px rgba(45, 59, 240, .12);
}
.choice input:focus-visible + .choice__body { outline: 2px solid var(--accent); outline-offset: 2px; }
.choice__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}
.choice__title { font-size: 16px; font-weight: 600; letter-spacing: .01em; }
/* 选中标记：未选时是一个空心圈（≥3:1 的控件边界，满足 1.4.11），
   选中时填成品牌渐变 + 白色对勾。卡片边框本身不承担「这是可选项」的提示。 */
.choice__check {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border: 1.5px solid var(--field-border);
  border-radius: 50%;
  color: transparent;
  transition: background var(--t), border-color var(--t), color var(--t);
}
.choice input:checked + .choice__body .choice__check {
  border-color: transparent;
  background-color: var(--brand-blue);
  background-image: var(--grad-cta);
  color: #fff;
}
.choice__files { display: flex; flex-wrap: wrap; gap: 4px; }
.choice__files code {
  padding: 2px 7px;
  border-radius: 6px;
  background: rgba(0, 0, 0, .05);
  color: #3a3a3f;                        /* 灰底 10.1:1 */
  font-size: 12.5px;
}

/* --- 文件拖放区 -----------------------------------------------------------
   原生 file input 透明铺满整块（z-index 在上），点击与拖放都直接落到它身上，
   不需要 JS 处理 drop 事件。下面的文字只是视觉，pointer-events 关掉。 */
.field__labelrow {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px var(--space-2);
  margin-bottom: var(--space-2);
}
.field__labelrow .field__label { margin-bottom: 0; }
.field__tag {
  padding: 2px 9px;
  border-radius: var(--radius-pill);
  background: rgba(0, 0, 0, .05);
  color: var(--text-2);
  font-size: 12.5px;
  font-weight: 600;
}
.field__tag.is-required { background: var(--warn-bg); color: var(--warn); }

.dropzone {
  position: relative;
  border: 1.5px dashed var(--field-border);
  border-radius: var(--radius);
  background: var(--bg-alt);
  transition: border-color var(--t), background var(--t);
}
.dropzone input[type="file"] {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}
.dropzone__empty,
.dropzone__chosen { pointer-events: none; }
.dropzone:hover,
.dropzone.is-dragover { border-color: var(--accent); background: var(--tint-2); }
.dropzone.is-dragover { border-style: solid; }
/* 焦点在透明的 input 上，环要画在外框上 */
.dropzone:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }
.dropzone.has-file { border-style: solid; border-color: rgba(0, 0, 0, .16); background: var(--bg); }
.dropzone.has-file:hover { border-color: var(--accent); }
.dropzone.is-invalid { border-color: var(--danger); background: var(--danger-bg); }

.dropzone__empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 22px 16px;
  text-align: center;
}
.dropzone__icon {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: var(--tint);
  color: var(--accent);
}
.dropzone__icon--file { width: 38px; height: 38px; border-radius: 10px; }
.dropzone__text { font-size: 15px; }
.dropzone__text strong { color: var(--accent); font-weight: 600; }
.dropzone__hint { color: var(--text-muted); font-family: var(--font-mono); font-size: 13px; }
.dropzone__chosen {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
}
.dropzone__name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: 500;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dropzone__size {
  color: var(--text-muted);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.dropzone__change { color: var(--accent); font-size: 14px; font-weight: 500; }

.field__help--note { color: var(--warn); font-weight: 500; }

.tool__submit {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 20px;
  margin-top: 36px;
  padding-top: 28px;
  border-top: 1px solid var(--border);
}
.tool__submit .muted { margin: 0; }

/* --- 结果面板 -------------------------------------------------------------
   三态：空 / 运行中（.is-busy，app.js 在提交时加）/ 有结果。
   .is-stale：有结果后用户又改了输入，结果对应的是上一次的参数。 */
.result { padding: var(--space-4); }
.result__busy {
  display: none;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-5) var(--space-2);
  text-align: center;
}
.result.is-busy .result__busy { display: flex; }
.result.is-busy .result__content { display: none; }
.result__spinner {
  width: 40px;
  height: 40px;
  margin-bottom: var(--space-2);
  border: 3px solid var(--tint);
  border-top-color: var(--brand-blue);
  border-radius: 50%;
  animation: spin .8s linear infinite;
}
.result__busy-title { margin: 0; font-size: 17px; font-weight: 600; }

.result__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) 12px;
  margin-bottom: 12px;
}
.result__head .muted { margin: 0; }
.result__title {
  margin-bottom: var(--space-3);
  font-size: 21px;
  line-height: 1.25;
  letter-spacing: -.01em;
}
/* 标题只在加载后被程序聚焦（让窄屏滚到结果处），不是可操作控件，不画焦点环 */
.result__title:focus { outline: none; }

.kv {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 6px var(--space-3);
  margin: 0 0 var(--space-3);
  font-size: 14px;
}
.kv dt { color: var(--text-muted); }
.kv dd { margin: 0; overflow-wrap: anywhere; }

.filelist {
  margin: 0 0 var(--space-3);
  padding: 4px 12px;
  border-radius: var(--radius-sm);
  background: var(--bg-alt);
  box-shadow: inset 0 0 0 1px var(--border);
  list-style: none;
}
.filelist li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  font-size: 14px;
}
.filelist li + li { border-top: 1px solid var(--border); }
.filelist .icon { flex: 0 0 auto; color: var(--accent); }
.filelist code { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.filelist__size {
  color: var(--text-muted);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.result__file {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin-top: 10px;
  overflow-wrap: anywhere;
}
.result__stale {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  margin-top: var(--space-3);
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  background: var(--warn-bg);
  font-size: 14px;
  line-height: 1.45;
}
.result__stale .icon { flex: 0 0 auto; margin-top: 1px; color: var(--warn); }
.result.is-stale .result__content > :not(.result__stale) { opacity: .5; transition: opacity var(--t); }

.checklist { margin: 12px 0 0; padding-left: 1.2em; color: var(--text-muted); font-size: 15px; }
.checklist li + li { margin-top: 6px; }

.preview { margin: 0 0 var(--space-3); }
.preview img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-sm);
  background: #fff;
  box-shadow: inset 0 0 0 1px var(--border);
}

.empty { padding: var(--space-3) var(--space-2) var(--space-4); text-align: center; }
.empty__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  margin-bottom: 12px;
  border-radius: 16px;
  background: var(--tint);
  color: var(--accent);
}
.empty__title {
  margin-bottom: 6px;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -.01em;
}
.tips {
  display: grid;
  gap: 12px;
  margin: 0;
  padding: var(--space-3) 0 0;
  border-top: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 14px;
  line-height: 1.45;
  list-style: none;
}
.tips li { display: flex; align-items: flex-start; gap: 10px; }
.tips .icon { flex: 0 0 auto; margin-top: 1px; color: var(--accent); }

/* --- 单选 / 复选（_field.html 渲染的 RadioSelect，以及 license 的同意框） --- */
.field > div[id] {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.field > div[id] > div > label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--text);
  font-size: 16px;
  cursor: pointer;
}
.field input[type="radio"],
.field input[type="checkbox"] {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--accent);
  cursor: pointer;
}

.checkline {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}
.checkline input[type="checkbox"] {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin-top: 2px;                       /* 与首行文字对齐 */
  accent-color: var(--accent);
  cursor: pointer;
}
.checkline label { cursor: pointer; font-size: 16px; line-height: 1.45; }

/* ============================================================================
   license（同意 / 预览）
   ========================================================================== */

.licence {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}
@media (min-width: 900px) {
  .licence { grid-template-columns: minmax(0, 1fr) 320px; }
  .accept { position: sticky; top: calc(var(--nav-h) + var(--space-4)); }
}
.docframe { margin: 0; }
.docframe iframe {
  display: block;
  width: 100%;
  height: min(76vh, 760px);
  border: 0;
  border-radius: var(--radius);
  background: var(--bg-alt);
  box-shadow: 0 0 0 1px var(--border), var(--shadow);
}
.docframe figcaption {
  margin-top: var(--space-3);
  color: var(--text-muted);
  font-size: 14px;
  line-height: 1.5;
}

.accept {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-3);
  padding: var(--space-4);
}
.accept p { margin: 0; }
.accept .btn { width: 100%; }
.accept__form { display: flex; flex-direction: column; gap: 20px; }
.accept__done { display: flex; align-items: flex-start; gap: 12px; }
.accept__icon { flex: 0 0 auto; color: var(--ok); }

.next-steps {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: minmax(0, 1fr);
  margin: var(--space-4) 0 var(--space-5);
}
@media (min-width: 640px) {
  .next-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.next-step {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 20px 22px;
  color: var(--text);
  transition: box-shadow var(--t), transform var(--t);
}
.next-step:hover { color: var(--text); box-shadow: 0 0 0 1px rgba(45, 59, 240, .2), var(--shadow-md); transform: translateY(-1px); }
.next-step__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  margin-bottom: var(--space-2);
  border-radius: 12px;
  background: var(--tint);
  color: var(--accent);
}
.next-step__title { font-weight: 600; }
.next-step .muted { font-size: 14px; }

/* ============================================================================
   用户手册
   ========================================================================== */

.docs {
  /* 列宽用 minmax(0, 1fr)：1fr 的下限是 auto，代码块里不换行的长行会把列撑破屏幕 */
  display: grid;
  gap: var(--space-5);
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}
@media (min-width: 960px) {
  .docs { grid-template-columns: 220px minmax(0, 1fr); gap: 56px; }
  .toc { position: sticky; top: calc(var(--nav-h) + var(--space-4)); }
}

.toc {
  padding: var(--space-3);
  border-radius: var(--radius);
  background: var(--bg-alt);
  font-size: 14px;
}
@media (min-width: 960px) {
  .toc { padding: 0; background: none; }
}
.toc__title { margin-bottom: var(--space-2); padding-inline: 10px; color: var(--text); font-weight: 600; }
.toc ol { margin: 0; padding: 0; list-style: none; }
.toc ol ol { margin: 2px 0 6px 12px; padding-left: 4px; border-left: 1px solid var(--border); }
.toc a {
  display: flex;
  align-items: center;
  min-height: 36px;
  padding: 4px 10px;
  border-radius: 8px;
  color: var(--text-muted);
  transition: background var(--t), color var(--t);
}
.toc a:hover { background: rgba(0, 0, 0, .04); color: var(--text); }
.toc a[aria-current] { background: var(--tint); color: var(--accent); font-weight: 500; }
@media (max-width: 959px) {
  .toc a { min-height: 44px; }           /* 窄屏是触屏，命中区域按 44px */
}

.manual { max-width: 760px; }
.manual > .callout { margin-bottom: var(--space-5); }
.manual .callout p { margin-top: 0; color: var(--text); font-size: 15px; }
.manual h2 {
  margin-top: var(--space-7);
  padding-top: var(--space-5);
  border-top: 1px solid var(--border);
  font-size: clamp(24px, 3.4vw, 30px);
  line-height: 1.2;
}
.manual > .callout + h2 { margin-top: 0; padding-top: 0; border-top: 0; }
.manual h3 {
  margin-top: var(--space-6);
  font-size: clamp(19px, 2.4vw, 22px);
  line-height: 1.25;
}
.manual h3 code { font-size: .92em; }
.manual p {
  margin-top: var(--space-3);
  color: var(--text-muted);
  font-size: 17px;
  line-height: 1.6;
}
.manual strong { color: var(--text); }
.manual .table-scroll { margin-top: var(--space-4); }

/* 代码块：深色，带文件名 + 复制按钮的标题栏 */
.code {
  margin-top: var(--space-3);
  overflow: hidden;
  border-radius: var(--radius-sm);
  background: var(--ink);
}
.code__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: 4px 6px 4px 16px;
  background: var(--ink-bar);
}
.code__name { color: #aab2d5; font-family: var(--font-mono); font-size: 13px; }
.code__copy {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 0 10px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: #c9cfe8;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
  transition: background var(--t), color var(--t);
}
.code__copy::after { content: ""; position: absolute; inset: -4px 0; }
.code__copy:hover { background: rgba(255, 255, 255, .08); color: #fff; }
.code__copy:focus-visible { outline-color: #8ab4ff; }
.code pre {
  margin: 0;
  padding: 16px 18px 18px;
  overflow-x: auto;
  color: #e8ebf7;
  font-size: 13.5px;
  line-height: 1.65;
  tab-size: 4;
}
.y-key { color: #8ab4ff; }
.y-com { color: #8f98c2; }

/* 配置项说明 */
.opts { margin: var(--space-3) 0 0; }
.opts dt { margin-top: 20px; }
.opts dt:first-child { margin-top: 0; }
.opts dt code {
  padding: 2px 8px;
  border-radius: 6px;
  background: rgba(0, 0, 0, .05);
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
}
.opts dd {
  margin: 8px 0 0;
  color: var(--text-muted);
  font-size: 16px;
  line-height: 1.6;
}
.opts dd p { margin: 0; font-size: 16px; }
.opts__list { margin: var(--space-2) 0 0; padding-left: 1.3em; }
.opts__list li + li { margin-top: 12px; }
.opts__list .snippet { max-width: 240px; }

/* ============================================================================
   隐私政策（privacy.html / _privacy_zh.html / _privacy_en.html）
   版式照抄用户手册的「目录 + 正文」两栏，正文的排版参数按法律文本调：
     - 行宽与手册一致（760px），但字号收到 16px、行高放到 1.75 —— 条款长、
       段多，手册那种 17px/1.6 连读起来太挤；
     - 正文色用 --text-2 而不是 --text-muted：法律文本要长时间读，
       #6e6e73 在 16px 的密度下偏浅（--text-2 白底 8.9:1）；
     - 章节之间用分隔线而不是纯留白，方便一眼看出条款边界。
   ========================================================================== */

.policy { max-width: 760px; }

.policy h2 {
  margin-top: var(--space-7);
  padding-top: var(--space-5);
  border-top: 1px solid var(--border);
  font-size: clamp(22px, 3vw, 26px);
  line-height: 1.3;
}
.policy h3 {
  margin-top: var(--space-5);
  font-size: clamp(17px, 2.2vw, 19px);
  line-height: 1.4;
}
.policy p {
  margin-top: var(--space-3);
  color: var(--text-2);
  font-size: 16px;
  line-height: 1.75;
}
.policy ol,
.policy ul {
  margin: var(--space-3) 0 0;
  padding-left: 1.6em;
  color: var(--text-2);
  font-size: 16px;
  line-height: 1.75;
}
.policy li + li { margin-top: var(--space-2); }
.policy ul { list-style: disc; }        /* 原件里是「•」开头的条目 */
.policy strong { color: var(--text); }
.policy a {                              /* 正文内链接保留下划线，不只靠颜色区分 */
  text-decoration: underline;
  text-underline-offset: 2px;
  overflow-wrap: anywhere;               /* 邮箱地址在窄屏上不撑破列 */
}

/* 联系信息块（第九节）：与正文分开，别再混在段落里 */
.policy__contact {
  margin-top: var(--space-4);
  padding: 18px 22px;
  border-radius: var(--radius);
  background: var(--bg-alt);
  box-shadow: inset 0 0 0 1px var(--border);
}
.policy__contact p {
  margin: 0;
  color: var(--text);
  font-size: 16px;
  line-height: 1.7;
}
.policy__contact p + p { margin-top: 4px; }

/* ============================================================================
   错误页（404 / 500）
   ========================================================================== */

.errorpage {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.errorpage .lead { max-width: 560px; margin-top: var(--space-3); }
.errorpage .cta-row { justify-content: center; }
.errorpage__logo { width: 140px; margin-bottom: var(--space-5); }
/* 大号状态码用品牌渐变填字，纯装饰（aria-hidden）—— 不承载需要读出的文字 */
.errorpage__code {
  margin-bottom: var(--space-2);
  background: var(--grad-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-size: clamp(72px, 16vw, 128px);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.04em;
}

/* ----------------------------------------------------------------------------
   prefers-reduced-motion：去掉所有非必要动效，但保留状态可见性
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  /* 转圈停下后不能变成一个看不出含义的缺口圆环，改成完整圆环 ——
     旁边的文案（「Generating…」「Running genxff…」）已经表达了状态 */
  .btn__spinner {
    animation: none !important;
    border-color: rgba(255, 255, 255, .7);
  }
  .result__spinner {
    animation: none !important;
    border-color: var(--brand-indigo);
  }
  .next-step:hover,
  .btn:hover { transform: none; }
}

/* ----------------------------------------------------------------------------
   forced-colors（Windows 高对比模式等）
   系统会接管颜色、并丢弃 box-shadow 与半透明背景。这里把那些只靠
   阴影/底色表达的边界补回成实线，保证卡片、按钮、徽章、选项仍有轮廓。
   -------------------------------------------------------------------------- */
@media (forced-colors: active) {
  .card,
  .table-scroll,
  .badge,
  .chip,
  .step,
  .format,
  .release,
  .ref,
  .ffcard,
  .term,
  .code,
  .terminal,
  .callout,
  .filelist {
    border: 1px solid CanvasText;
  }
  .btn { border-color: ButtonBorder; }
  .nav { background: Canvas; }          /* 半透明失效，回落到实底 */
  /* 所有装饰渐变在此模式下都会被系统抹掉。它们本来就只是装饰，
     不承载任何信息，所以直接隐藏，避免留下一条莫名其妙的实色块。 */
  .nav::before,
  .card--accent::before,
  .ffcard::before,
  .hero::before,
  .accent-rule,
  .releases::before { display: none; }
  .errorpage__code { background: none; color: CanvasText; }
  .field input:focus-visible,
  .field textarea:focus-visible,
  .field select:focus-visible {
    outline: 2px solid Highlight;
    outline-offset: 2px;
  }
  /* 分段控件与格式卡片的「选中」原本靠底色/边框色表达，这里换成系统高亮色 */
  .seg__opt input:checked + .seg__label,
  .seg__opt[aria-current="true"] .seg__label,
  .choice input:checked + .choice__body {
    outline: 2px solid Highlight;
    outline-offset: -2px;
  }
  .dropzone { border-color: CanvasText; }
}

/* ----------------------------------------------------------------------------
   打印：去掉导航、页脚和交互元素
   -------------------------------------------------------------------------- */
@media print {
  .nav, .footer, .skip-link, .btn, .code__copy, .toc, .cta-row { display: none !important; }
  body { font-size: 12pt; }
  .section { padding-block: 0; }
  .card { box-shadow: none; border: 1px solid #ddd; }
  .table-scroll { overflow: visible; }
  .table { min-width: 0; }
  .code, .terminal { background: #fff; border: 1px solid #ddd; }
  .code pre, .terminal__body, .y-key, .y-com, .t-comment, .t-prompt { color: #000; }
}
