/* 标题字体：Caprasimo（Organic 的唯一 display voice）。
 *
 * 值得先说清楚它盖到哪、盖不到哪。Caprasimo 是纯拉丁字形，没有任何中日韩覆盖，
 * 而本站 34 条 <h*> 标题**全部含中文**——所以它一条标题都盖不到。
 *
 * 设计稿自己也没往中文标题上套：官网四页的中文小标题一律是正文栈 + 字重 700，
 * Caprasimo 只出现在三类东西上，全是纯拉丁：
 *   · 英文短句（"One menu bar." / "Pay for what you use." / "Almost there."）
 *   · 大数字（安装体积、占用率、模块数、套餐价、应付总额）
 *   · 品牌名 MacToolbox
 * 对应到本站就是 .display / .stat-num / .plan-amount /
 * .module-total-price / .summary-total strong / .brand 这六处，别往别处套。
 *
 * 结论：中文标题像不像设计稿，由字重与字号决定，与这个字体文件无关。
 *
 */
/* 自托管，不走 Google Fonts。
 *
 * 三个理由，按重要性排：
 *   1. README 写着「零运行时依赖」。挂一个第三方 CDN 就不成立了，
 *      而且它挂了本站的标题字就没了。
 *   2. @import 是串行的——浏览器要先拿到 style.css 才发现它，多一次往返；
 *      README 又写着「首屏速度直接影响转化」。自托管同域，走同一个连接。
 *   3. 这是个卖东西的站。Google Fonts 会把访客 IP 交给第三方，
 *      欧盟那边有过判例，能避就避。
 *
 * 按 unicode-range 切两片是照搬 Google 的做法，不是多余：绝大多数访客
 * 只会命中 latin 那 20 KB，latin-ext 那 2 KB 根本不会被下载。
 *
 * 授权：SIL OFL 1.1，全文在 assets/fonts/OFL.txt——OFL 要求随字体分发，
 * 删掉那个文件就违反授权了。 */
@font-face {
  font-family: 'Caprasimo';
  font-style: normal;
  font-weight: 400;
  /* swap：字体没到之前先用系统字显示，别让标题空着。
     这几处都是数字与品牌名，回退时布局只会轻微变宽，不会塌 */
  font-display: swap;
  src: url('fonts/caprasimo-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Caprasimo';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/caprasimo-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

/* MacToolbox 官网样式
 *
 * 设计取向：这是给技术用户看的工具类软件官网，克制比华丽重要。
 * 层次靠间距与字重建立，不靠色彩堆砌；不用渐变背景、不用装饰性动效。
 * 暗色为主色调——系统工具的用户大多常年开着暗色模式。
 */

:root {
  /* 原生控件（滚动条、勾选框、下拉）跟着一起变色，否则暗色页面里会插进白色部件 */
  color-scheme: dark;

  /* Organic 暗色。取值与 MacToolbox 的 SurfacePalette/TextPalette、
   * windows-client 的 DesignTokens.cs 同源——改一处要改三处，
   * Scripts/verify-design-tokens.sh 会逐值比对。 */
  --bg: #211b13;
  --bg-alt: #2a241a;
  --surface: #2a241a;
  --surface-hover: #37301f;

  /* border 分两级：装饰性分隔线用 --border，
   * 输入框、按钮这类「边框就是控件边界」的地方用 --border-strong。
   * 后者按 WCAG 1.4.11 需要对背景 ≥3:1，前者不需要，混用会让整页噪声变大。 */
  --border: #463d28;
  /* 控件边界按 WCAG 1.4.11 要对背景 ≥3:1。暗色下 neutral-500 恰好 3.23，
   * 但 bg / bg-alt / surface 三种底都要过，留一档余量取 600（4.90）。 */
  --border-strong: #a99d87;

  --text: #f1e8d6;
  --text-muted: #c9bfae;
  --text-dim: #a99d87;

  /* 强调色分两槽，这是 Organic 逼出来的区分。
   *
   * 设计系统自己写明："The accent-to-ground pair is tuned to at least 3:1 —
   * enough for icons, large text and interface chrome, not for body copy."
   * 也就是说 terracotta 本身只够画图标和界面构件，撑不起正文级的文字。
   * 实测亮色 #c67139 在奶油底上是 3.30:1，配白字 3.61、配深墨 4.60，
   * 而 hover 态一变就掉到 3.70——两头都够不着 4.5。
   *
   * 所以：--accent 管图形（3:1），--accent-text 管文字与链接（4.5:1），
   * 走斜坡上更深/更浅的那一档。混用是这套配色最容易犯的错。 */
  --accent: #e09659;
  --accent-hover: #eeab72;
  --accent-text: #ffc89d;
  --accent-dim: rgba(224, 150, 89, 0.14);
  /* 第二个声音：sage。设计系统要求把它当真正的第二 voice，不是高光 */
  --accent-2: #a3b284;

  /* 铺在强调色实底上的文字（主按钮）。暗色 terracotta 偏亮，
   * 白字在它上头只有 2.42:1、hover 更掉到 1.96——必须用深色字，实测 7.05 / 8.70。
   * 亮色那边正好相反，见下面的覆盖块。 */
  /* 暗色的主按钮底就用 terracotta 本色：深色字在它上头 7.05:1，够。
   * 亮色那边不行，见覆盖块里的 --accent-solid。 */
  --accent-solid: #e09659;
  --accent-solid-hover: #eeab72;
  --on-accent: #211b13;

  --success: #dce9c2;
  /* 「注意但还没出错」独立成槽。缺了它，接近阈值、降级运行这类状态
   * 只能借 danger 红，语义比实际严重一档 */
  --warn: #ffdfc4;
  /* Organic 只有 terracotta 与 sage 两支色，没有 danger。
   * 这一支是补的——「注意」和「出错」必须分得开。 */
  --danger: #ff6961;

  /* 层次分两套机制，不能共用一组阴影：
   * 暗色下黑影打在深底上等于没有，靠「更亮一档的面」--surface-raised 抬起；
   * 亮色下 --surface 与 --bg 同为纯白，只有阴影能把卡片和页面分开。 */
  --surface-raised: #332b1d;
  /* 暖调阴影。中性黑影打在深棕底上会显脏，抽走 Organic 的暖意 */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.30);
  --shadow-md: 0 3px 10px rgba(0, 0, 0, 0.45);
  --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.60);

  --wrap: 1100px;
  --wrap-narrow: 760px;
  /* Organic 的性格是圆。设计稿里 border-radius:999px 出现 54 次、
   * 圆形 31 次，所以整体比原来大一档，并且补一个 --radius-pill。 */
  --radius: 12px;
  --radius-sm: 8px;
  --radius-lg: 20px;
  --radius-pill: 999px;

  /* 统一动效尺度。缓动收尾慢、起步快，接近 macOS 原生控件的手感 */
  --dur: 0.18s;
  --ease: cubic-bezier(0.32, 0.72, 0, 1);

  /* 标题栈。Caprasimo 只有拉丁字形，中文自动落到后面的系统栈 */
  --font-heading: "Caprasimo", var(--font);

  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue",
    "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
}

/* 亮色模式：不是简单反色，浅色下对比度需要单独调。
 * 每个语义色都要在这里重新给值——漏一个就会把暗色值搬到白底上，
 * 曾经 --success / --danger 就是这么掉到 2.5:1 的。 */
@media (prefers-color-scheme: light) {
  :root {
    color-scheme: light;

    /* Organic 亮色：奶油底 + 赤陶点缀。三端同源，见 :root 里的说明。 */
    --bg: #f5ead8;
    --bg-alt: #ebddc5;
    --surface: #f9f4ed;
    --surface-hover: #eee7db;
    --border: #dcd3c4;
    /* 同理，亮色下 500 只有 2.15，要到 600 才够（3.21） */
    --border-strong: #82796a;
    --text: #201e1d;
    --text-muted: #474238;
    --text-dim: #645c50;

    /* 图形用的 terracotta（3:1）与文字用的深档（4.5:1）分开——
       理由见 :root 里那段。这里 --accent 是品牌本色，
       --accent-text 走 accent-700，实测在奶油底上 5.72:1。 */
    --accent: #c67139;
    --accent-hover: #b2622d;
    --accent-text: #8c491a;
    --accent-dim: rgba(198, 113, 57, 0.10);
    --accent-2: #7a8a5e;

    /* 亮色的主按钮底不能用 --accent 本色：白字在 #c67139 上只有 3.61:1，
       换深墨也只有 4.60、hover 掉到 3.70，两头都不够。
       所以按钮底走 accent-700，白字在它上头是 6.81:1。 */
    --accent-solid: #8c491a;
    --accent-solid-hover: #643312;
    --on-accent: #ffffff;

    /* warning 走 terracotta 深档、success 走 sage 深档，danger 是补的第三支。
       三端逐字同源，改一处就要改三处：windows-client 的 DesignTokens.cs、
       MacToolbox 的 StatusPalette、本文件。 */
    --success: #3d472b;
    --warn: #643312;
    --danger: #bc2d0e;

    --surface-raised: #f9f4ed;
    /* Organic 的阴影带暖调（ink #2e2b25），不是中性黑——
       中性黑影打在奶油底上会显灰，把整页的暖意抽走 */
    --shadow-sm: 0 1px 2px rgba(46, 43, 37, 0.14);
    --shadow-md: 0 3px 10px rgba(46, 43, 37, 0.16);
    --shadow-lg: 0 12px 32px rgba(46, 43, 37, 0.22);
  }

  /* 亮色 --surface 与 --surface-raised 同色，示意面板用 hover 档拉开层次 */
  .showcase-panel { background: var(--surface-hover); }
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

html { scroll-behavior: smooth; }

/* 导航是 sticky 的，锚点滚过去时标题会被它压在下面。
 * 60px 导航 + 一点呼吸；窄屏导航折成两行，另给更大的值。 */
:where(section[id], [id]:target) { scroll-margin-top: 84px; }

@media (max-width: 860px) {
  :where(section[id], [id]:target) { scroll-margin-top: 116px; }
}

/* 保留 0.01ms 而不是直接 none：完全去掉过渡会让依赖 transitionend 的逻辑永远等不到回调 */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  /* 悬停位移也一并去掉。它只有 1-2px，但对前庭敏感的人来说
   * 「鼠标扫过一整片卡片时整页都在跳」仍然难受，而这层反馈
   * 本来就由边框和阴影同时承担，去掉不丢信息。 */
  .feature-card:hover, .plan:hover, .btn:active { transform: none; }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 24px; }
.wrap.narrow { max-width: var(--wrap-narrow); }
.center { text-align: center; }
.muted { color: var(--text-muted); }
.small { font-size: 14px; }

/* text-wrap: balance 让标题自己找断点，比手写 <br> 可靠——
 * 手写换行在窄屏上会断在莫名其妙的位置 */
/* 中文标题**刻意不用** Caprasimo，也不用字重 400。
 *
 * 这一点我先做错过一次，值得写下来。`_ds/styles.css` 里写的是
 * `h1..h4 { font-family: Caprasimo; font-weight: 400 }`，照抄就会把
 * 全站中文标题变成 400 字重的系统字——又细又散。
 *
 * 但设计稿**自己没这么干**：官网四页的中文小标题一律是
 * `clamp(26px,3vw,34px)` + 字重 700 + 正文栈（模块卡名更是 0.82em/700），
 * Caprasimo 只出现在英文短句、大数字和 "MacToolbox" 上——见下面 .display。
 * 原因不难想：Caprasimo 没有中日韩字形，中文拿不到它自带的重量，
 * 那份重量只能靠字重补回来。
 *
 * 所以这里保持正文栈 + 粗体，字号按设计稿的 clamp 上限对齐。 */
h1, h2, h3 {
  line-height: 1.25;
  letter-spacing: -0.01em;
  margin: 0 0 16px;
  text-wrap: balance;
}
h1 { font-size: clamp(32px, 5vw, 52px); font-weight: 700; letter-spacing: -0.02em; }
h2 { font-size: clamp(26px, 3vw, 34px); font-weight: 700; }
h3 { font-size: 17px; font-weight: 600; }

/* Organic 的 display voice 只用在这三类上，与设计稿一致：
 *   · 英文短句（"One menu bar." "Pay for what you use."）
 *   · 大数字（安装体积、占用率、模块数、价格、应付总额）
 *   · 品牌名 MacToolbox
 * 中文一个字都不经过它——Caprasimo 没有中日韩字形，落过去只会回退。
 *
 * font-synthesis-weight: none 不能省：Caprasimo 只有 400 一档，
 * 浏览器遇到更粗的请求会自己把字形横向拉胖，那比不加粗更难看。 */
.display {
  font-family: var(--font-heading);
  font-weight: 400;
  font-synthesis-weight: none;
  letter-spacing: -0.015em;
}
p { margin: 0 0 16px; text-wrap: pretty; }
/* 链接是文字：走 --accent-text（4.5:1）而不是 --accent（图形档 3:1）。
 * 亮色 terracotta 本色在奶油底上只有 3.30:1，当链接会看不清。 */
a { color: var(--accent-text); text-decoration: none; }
a:hover { color: var(--accent-solid-hover); }

/* 键盘可达性：焦点环必须清晰可见 */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* 只给读屏的文字。切换计费周期与币种时整页价格会变，
 * 那是纯视觉变化，得有一句话告诉听的人结果变成什么了。
 * 不用 display:none / visibility:hidden——那两个会把内容从无障碍树里摘掉。 */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* 跳到主内容：键盘与读屏用户不必每页先 Tab 过整条导航 */
.skip-link {
  position: absolute;
  left: 12px;
  top: -60px;
  z-index: 100;
  padding: 10px 16px;
  background: var(--accent-solid);
  color: var(--on-accent);
  font-size: 14px;
  font-weight: 550;
  border-radius: var(--radius-sm);
  transition: top 0.15s;
}

.skip-link:focus { top: 12px; color: var(--on-accent); }

/* ── 导航 ───────────────────────────────── */

.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
}

.nav-inner {
  display: flex;
  align-items: center;
  gap: 28px;
  height: 60px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  color: var(--text);
  /* 品牌名走 display voice。就地声明而不是靠上面的 .display —— 那条在本规则
     之前，font-weight 会被这里覆盖掉一半，留下 Caprasimo 被请求成 650 的怪状态 */
  font-family: var(--font-heading);
  font-weight: 400;
  font-synthesis-weight: none;
  font-size: 17px;
  letter-spacing: -0.01em;
}

.brand-mark {
  width: 18px;
  height: 18px;
  border-radius: 5px;
  background: var(--accent);
  /* 一个简单的几何标记，避免用 emoji 充当 logo */
  box-shadow: inset 0 0 0 3px var(--bg);
}

.nav-links { display: flex; gap: 22px; font-size: 14px; }
.nav-links a { color: var(--text-muted); }
.nav-links a:hover { color: var(--text); }
.nav-actions { margin-left: auto; display: flex; gap: 10px; align-items: center; }

/* 窄屏不藏导航，改成第二行横滑。
 * 之前这里直接 display:none，手机用户既进不去功能锚点，
 * 也点不到定价页——而 pricing 页被一并藏掉的那个按钮是货币切换。 */
@media (max-width: 860px) {
  .nav-inner {
    height: auto;
    flex-wrap: wrap;
    gap: 10px 16px;
    padding-top: 10px;
    padding-bottom: 8px;
  }

  .nav-links {
    order: 3;
    width: 100%;
    gap: 20px;
    overflow-x: auto;
    align-self: stretch;
    margin-top: 2px;
    padding-top: 8px;
    padding-bottom: 2px;
    border-top: 1px solid var(--border);
    scroll-padding-inline: 4px;
    scrollbar-width: none;
  }

  .nav-links::-webkit-scrollbar { display: none; }
  .nav-links a { white-space: nowrap; }
}

/* ── 按钮 ───────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 8px 16px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font-size: 14px;
  font-weight: 550;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease),
    color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
  white-space: nowrap;
}

/* 按下时下沉 1px 给一点实体感。幅度必须小：
 * 大位移在按钮密集的页面里会让整块界面看着在抖 */
.btn:active { transform: translateY(1px); }

.btn-lg { padding: 12px 24px; font-size: 15px; }
.btn-sm { padding: 7px 11px; font-size: 13px; }

.btn:disabled,
.btn[aria-disabled="true"],
.btn[data-state="unavailable"] {
  opacity: 0.58;
  cursor: not-allowed;
  box-shadow: none;
}

/* 实底按钮的底走 --accent-solid：--accent 本色撑不起 4.5:1 的标签，
   亮色下白字在它上头只有 3.61:1。见令牌块里的说明。 */
.btn-primary { background: var(--accent-solid); color: var(--on-accent); box-shadow: var(--shadow-sm); }
.btn-primary:hover {
  /* 亮色 --accent-hover 铺白字只有 4.49:1，差 0.01 掉出 AA。
   * hover 与 :active 统一走 --accent-solid-hover（verify-contrast 检的也是它）。 */
  background: var(--accent-solid-hover);
  color: var(--on-accent);
  box-shadow: var(--shadow-md);
}

/* background 必须显式写透明：<button> 带 UA 默认的 buttonface 底色，
 * 不覆盖的话「切换为 USD」「联系我们」这两个 button 会比同样挂着
 * btn-ghost 的 <a> 亮一档，同一个类渲染出两种样子。 */
.btn-ghost { background: transparent; border-color: var(--border-strong); color: var(--text); }
.btn-ghost:hover { background: var(--surface-hover); border-color: var(--accent); color: var(--text); }

/* ── Hero ───────────────────────────────── */

.hero { padding: 88px 0 72px; }

.platform-switch {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  margin-bottom: 18px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
}

.platform-switch button {
  border: 0;
  background: transparent;
  color: var(--text-muted);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 7px 16px;
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

.platform-switch button[aria-pressed="true"] {
  background: var(--accent-solid);
  color: var(--on-accent);
}

.platform-switch button:hover:not([aria-pressed="true"]) {
  background: var(--surface-hover);
  color: var(--text);
}

.eyebrow {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--accent-text);
  background: var(--accent-dim);
  padding: 4px 10px;
  border-radius: 999px;
  margin-bottom: 20px;
}

/* 主标题按分句断行，各宽度一律一句一行。
 *
 * 中文没有词边界，浏览器只会按字符塞满再折，"工具箱"这种词照拆不误。
 * 逐字量过三个宽度：430px 以上一句一行正好各占一行；390px 下第二句仍会
 * 再折一次，但第一句"一个菜单栏工具箱，"完整——比交给 text-wrap: balance
 * 均分成"一个菜单栏工具 / 箱，顶掉六个各 / 收各钱的订阅。"强得多。
 *
 * 用 span 而不是 <br class="...">：<br> 的换行是固有行为，
 * 靠 display 开关它并非各浏览器都可靠。 */
.title-clause { display: block; }

/* 中文没有词边界，浏览器逐字塞满就折，390px 下第二句会被断成
 * 「顶掉六个各收 / 各钱的订阅」——把「各收各钱」这个并列结构劈成两半。
 *
 * 只锁后半句还不够：那样它又改从「顶掉六 / 个各收各钱…」断，反而拆了「六个」。
 * 两个词组都锁上，整句就只剩它们之间这一个合法断点。
 * 代价是窄屏下第一行偏短，但比把词劈开强。 */
.phrase { white-space: nowrap; }

.lede {
  font-size: clamp(16px, 2vw, 18px);
  color: var(--text-muted);
  max-width: 640px;
  margin-bottom: 32px;
}

.lede strong { color: var(--text); font-weight: 600; }

.hero-actions { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.hero-actions.center { justify-content: center; }
.hero-note { font-size: 13px; color: var(--text-dim); margin: 0 0 6px; }

/* ── 首屏产品示意 ───────────────────────── */

/* 菜单栏与面板是纯 CSS 画的，不用截图。
 * 位图每次改版都要重拍、还得出 @2x/@3x 三套；而首屏只需要让人一眼明白
 * 「这东西长在菜单栏里」。里面的数字是摆设，整块对读屏隐藏。 */
/* 整块当成一小片屏幕来画：顶上一条菜单栏，下面是桌面。
 * 面板只占右边一块，左边那片留白就是桌面本身——把它框起来，
 * 空白才读得出「这是桌面」，而不是「这里漏排了东西」。 */
.showcase {
  display: grid;
  max-width: 880px;
  margin-top: 44px;
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}

.showcase-bar {
  display: flex;
  align-items: center;
  gap: 18px;
  height: 38px;
  padding: 0 14px;
  background: var(--surface-raised);
  border-bottom: 1px solid var(--border);
  font-size: 12px;
  color: var(--text-muted);
  overflow: hidden;
}

.showcase-logo {
  width: 12px;
  height: 12px;
  flex: none;
  border-radius: 3px;
  /* 菜单栏是 --surface-raised：--text-dim 在那档面上掉出 AA，改走控件边界色 */
  background: var(--border-strong);
}

.showcase-menus { display: flex; gap: 15px; white-space: nowrap; }
.showcase-menus b { color: var(--text); font-weight: 600; }

.showcase-status {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--bg-alt);
  font-family: var(--font-mono);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}

.chip b { color: var(--text); font-weight: 600; }

.chip-accent {
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  background: var(--accent-dim);
}

.chip-accent b { color: var(--accent-text); }

/* 一个缓慢呼吸的点，表示数据在实时刷新。
 * 全局的 prefers-reduced-motion 规则会把它定格，不必单独再写一遍。 */
.chip-live::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--success);
  animation: chip-breathe 2.6s ease-in-out infinite;
}

@keyframes chip-breathe {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}

/* 不用 --text-dim：它在 --surface-raised 这档面上只有 4.32:1，掉出 AA */
.showcase-clock { font-size: 11px; color: var(--text-muted); }

/* 面板贴着右上角垂下来，位置对应菜单栏图标——菜单栏应用就是这么展开的。
 * 外层 overflow:hidden 会裁掉大范围模糊，所以这里只用中号阴影。 */
.showcase-panel {
  justify-self: end;
  width: min(330px, 100%);
  margin: 10px 14px 22px;
  padding: 14px 16px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--shadow-md);
}

.showcase-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding-bottom: 10px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--border);
}

.showcase-head b { font-size: 13px; font-weight: 650; }

.showcase-tag {
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--accent-dim);
  color: var(--accent-text);
  font-size: 11px;
}

.metric {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 0;
  font-size: 12px;
}

.metric-label { width: 32px; color: var(--text-muted); }

.metric-value {
  width: 46px;
  font-family: var(--font-mono);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

/* 迷你趋势条：高度由内联 style 给，和后台概览里的 .bar 同一套做法 */
.spark {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 16px;
  margin-left: auto;
}

/* 首帧高度用 class 写 --h，避免 HTML 内联 style 撞上 style-src。
 * 演示脚本仍可能在运行时改 --h；那条线由 CSP 另案处理。 */
.spark i {
  width: 3px;
  height: var(--h, 50%);
  border-radius: 1px;
  background: var(--accent);
  opacity: 0.45;
}
.spark-h-26 { --h: 26%; }
.spark-h-30 { --h: 30%; }
.spark-h-32 { --h: 32%; }
.spark-h-34 { --h: 34%; }
.spark-h-36 { --h: 36%; }
.spark-h-38 { --h: 38%; }
.spark-h-41 { --h: 41%; }
.spark-h-44 { --h: 44%; }
.spark-h-47 { --h: 47%; }
.spark-h-48 { --h: 48%; }
.spark-h-52 { --h: 52%; }
.spark-h-54 { --h: 54%; }
.spark-h-55 { --h: 55%; }
.spark-h-57 { --h: 57%; }
.spark-h-58 { --h: 58%; }
.spark-h-60 { --h: 60%; }
.spark-h-62 { --h: 62%; }
.spark-h-63 { --h: 63%; }

.spark i:last-child { opacity: 1; }

.showcase-foot {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  font-size: 12px;
  color: var(--text-muted);
}

.showcase-foot b { color: var(--success); font-weight: 600; }

/* Windows 版用底部任务栏 + 左侧主窗口。品牌不变，系统外壳不冒充 Mac。 */
.platform-windows .showcase-bar {
  order: 2;
  border-top: 1px solid var(--border);
  border-bottom: 0;
}

.platform-windows .showcase-panel {
  order: 1;
  justify-self: start;
  width: min(390px, 100%);
  margin: 22px 14px 10px;
}

.platform-windows .showcase-logo {
  position: relative;
  border-radius: 1px;
  background: var(--accent);
}

.platform-windows .showcase-logo::before,
.platform-windows .showcase-logo::after {
  content: "";
  position: absolute;
  background: var(--surface-raised);
}

.platform-windows .showcase-logo::before {
  inset: 0 5px;
}

.platform-windows .showcase-logo::after {
  inset: 5px 0;
}

/* 窄屏放不下整条菜单栏：先丢掉最不重要的信息，
 * 而不是整块缩放——缩到 9px 的字谁也看不清 */
/* 721–860px 菜单栏恢复 clock/optional，但 bar 仍 overflow:hidden，
 * Windows「托盘 运行中」会把时钟硬切掉。先藏时钟，720 以下再藏菜单。 */
@media (max-width: 860px) {
  .showcase-clock { display: none; }
}

@media (max-width: 720px) {
  .showcase { margin-top: 36px; }
  .showcase-bar { gap: 10px; padding-inline: 12px; }
  .showcase-status { gap: 5px; min-width: 0; }
  .showcase-menus, .showcase-clock, .chip-optional { display: none; }
  .showcase-panel { justify-self: stretch; width: auto; }
  .platform-windows .showcase-panel { justify-self: stretch; width: auto; }
}

.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 1px;
  margin-top: 56px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}

.stat {
  background: var(--bg);
  padding: 20px 18px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  transition: background-color var(--dur) var(--ease);
}

/* 不用 transform：这排卡片靠 1px 网格间隙拼出分隔线，
 * 一位移就会在缝里露出底色 */
.stat:hover { background: var(--surface); }

/* 大数字是 Organic 用 display voice 的第二类：设计稿里 6.3 MB / <1.5% / 14
   都走 Caprasimo，字号 38~56px。数字是纯拉丁，所以这里它真的生效
   （中文标题那边不生效，见上面 h1/h2/h3 的说明）。

   原来是等宽栈 + 600 字重；换成 Caprasimo 之后 tabular-nums 仍然留着——
   四个统计并排，数字宽度不一致会让基线看起来在抖。 */
.stat-num {
  font-family: var(--font-heading);
  font-weight: 400;
  font-synthesis-weight: none;
  font-size: clamp(26px, 3.4vw, 32px);
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.stat-label { font-size: 13px; color: var(--text-dim); }

/* ── 区块 ───────────────────────────────── */

.section { padding: 72px 0; border-top: 1px solid var(--border); }
.section-alt { background: var(--bg-alt); }
.section-lede { color: var(--text-muted); max-width: 620px; margin-bottom: 40px; }
.center .section-lede { margin-left: auto; margin-right: auto; }

/* ── 功能卡片 ───────────────────────────── */

.feature-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 16px;
  /* 入场/悬停的轻微 scale 不应把整页撑出横向滚动条。 */
  overflow: clip;
  padding: 3px;
  margin: -3px;
}

.feature-card {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 22px;
  box-shadow: var(--shadow-sm);
}

/* 亮色下 --surface 与 --bg 同为纯白，卡片全靠这层阴影才浮得起来。
 * 位移只放在 prefers-reduced-motion: no-preference，避免和全局 0.01ms 规则各写一份。 */
.feature-card:hover {
  border-color: var(--border-strong);
  box-shadow: var(--shadow-md);
}

.feature-card.highlight { border-color: color-mix(in srgb, var(--accent) 40%, var(--border)); }
.feature-card.highlight:hover { border-color: var(--border-strong); }

.feature-card h3 {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  row-gap: 4px;
  margin-bottom: 10px;
}

.feature-card h3 .badge {
  flex-shrink: 0;
  margin-left: auto;
}

/* 「开发中」原先缀在 feature-meta 那行小字的尾巴上，扫过十四张卡
 * 根本分不出哪些现在就能用。提成标题旁的独立标记。 */
.badge {
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  background: var(--bg-alt);
  color: var(--text-dim);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0;
  white-space: nowrap;
}
.feature-card p { font-size: 14px; color: var(--text-muted); margin-bottom: 0; }
.feature-card p + p { margin-top: 12px; }
.feature-card strong { color: var(--text); font-weight: 600; }

.feature-meta {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-dim) !important;
  margin-top: auto;
  padding-top: 12px;
}

/* ── 对比表 ─────────────────────────────── */

/* 横向滚动区要能用键盘滚：配套 HTML 上的 tabindex="0" + role="region" */
.compare-wrap { overflow-x: auto; margin-bottom: 48px; }
.scroll-hint {
  margin: 0 0 10px;
  color: var(--text-muted);
  font-size: 13px;
}
.scroll-hint:not([hidden]) {
  margin: 0 0 12px;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-alt);
}

.compare-wrap:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius);
}

.compare {
  width: 100%;
  border-collapse: collapse;
  font-size: 15px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}

.compare caption {
  caption-side: bottom;
  padding-top: 12px;
  font-size: 13px;
  color: var(--text-dim);
  text-align: left;
}

.compare th, .compare td { padding: 12px 18px; text-align: left; }
.compare thead th {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-dim);
  border-bottom: 1px solid var(--border);
}
.compare tbody tr { border-bottom: 1px solid var(--border); }
.compare tbody td { color: var(--text-muted); }
.compare tbody td:first-child { color: var(--text); }
.compare th.num,
.compare td.num {
  width: 1%;
  white-space: nowrap;
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
.compare tfoot td { font-weight: 600; border-top: 1px solid var(--border); }
.compare .highlight-row td {
  background: var(--accent-dim);
  color: var(--text);
}
.compare .highlight-row .num { color: var(--accent-text); font-size: 17px; }

/* 省下多少是整张表唯一要让人记住的数字，给它最重的视觉分量 */
.compare .saving-row td {
  background: color-mix(in srgb, var(--success) 12%, transparent);
  border-top: 1px solid color-mix(in srgb, var(--success) 28%, transparent);
  font-weight: 500;
}

.compare .saving-row .num {
  color: var(--success);
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.compare-points {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 28px;
}
.compare-points p { font-size: 14px; color: var(--text-muted); margin-bottom: 0; }

#compare .wrap[data-platforms="windows"] .compare-points > div {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 22px;
  box-shadow: var(--shadow-sm);
}

#compare .wrap[data-platforms="windows"] .compare-points h3 {
  margin-bottom: 10px;
}

/* ── 原则 ───────────────────────────────── */

.principle-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 28px;
  margin-top: 24px;
}
.principle h3 { color: var(--text); margin-bottom: 8px; }
.principle p { font-size: 14px; color: var(--text-muted); margin-bottom: 0; }

/* ── FAQ ────────────────────────────────── */

details {
  border-bottom: 1px solid var(--border);
  padding: 4px 0;
}

summary {
  cursor: pointer;
  padding: 16px 28px 16px 0;
  font-weight: 550;
  list-style: none;
  position: relative;
  transition: color var(--dur) var(--ease);
}

summary:hover { color: var(--accent-text); }
summary:hover::after { border-color: var(--accent-text); }

summary::-webkit-details-marker { display: none; }

summary::after {
  content: "";
  position: absolute;
  right: 6px;
  top: 50%;
  width: 8px;
  height: 8px;
  border-right: 1.5px solid var(--text-dim);
  border-bottom: 1.5px solid var(--text-dim);
  transform: translateY(-50%) rotate(45deg);
  transition: transform var(--dur) var(--ease);
}

details[open] summary::after { transform: translateY(-50%) rotate(225deg); }

details p {
  font-size: 15px;
  color: var(--text-muted);
  padding-bottom: 16px;
  margin: 0;
  max-width: 68ch;
}

details strong { color: var(--text); font-weight: 600; }

/* ── 定价 ───────────────────────────────── */

.billing-toggle {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  margin-bottom: 12px;
}

.billing-toggle button {
  border: 0;
  background: transparent;
  color: var(--text-muted);
  font-family: inherit;
  font-size: 14px;
  font-weight: 550;
  padding: 7px 18px;
  border-radius: 999px;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

.billing-toggle button:hover:not([aria-pressed="true"]) {
  color: var(--text);
  background: var(--surface-hover);
}

.billing-toggle button[aria-pressed="true"] {
  background: var(--accent-solid);
  color: var(--on-accent);
}

.save-hint {
  font-size: 13px;
  color: var(--success);
  min-height: 20px;
  margin-bottom: 28px;
}

.plan-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px;
  align-items: stretch;
  padding-top: 10px;
}

.plan {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 26px 24px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  height: 100%;
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur) var(--ease), border-color var(--dur) var(--ease),
    box-shadow var(--dur) var(--ease);
}

.plan:hover {
  transform: translateY(-2px);
  border-color: var(--border-strong);
  box-shadow: var(--shadow-md);
}

/* 主推方案本来就该比旁边两张更"近"一层 */
.plan.featured {
  z-index: 1;
  border-color: var(--accent);
  border-width: 2px;
  padding: 25px 23px;
  background: color-mix(in srgb, var(--accent-dim) 50%, var(--surface));
  box-shadow: var(--shadow-lg);
  position: relative;
}

.plan.featured:hover { border-color: var(--accent); box-shadow: var(--shadow-lg); }

.plan-badge {
  position: absolute;
  top: -10px;
  left: 24px;
  background: var(--accent-solid);
  color: var(--on-accent);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 3px 10px;
  border-radius: 999px;
}

.plan-name { font-size: 17px; font-weight: 650; margin: 0; }
.plan-desc { font-size: 14px; color: var(--text-muted); margin: 0; min-height: 42px; }

/* 等宽数字：切换月付/年付时价格不会因为字宽变化而左右抖动 */
.plan-price {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* 套餐价走 display voice（设计稿是 40px Caprasimo）。
   父级 .plan-price 的 font-family: var(--font-mono) 被这里覆盖——
   等宽是为了切月付/年付时不抖，而 tabular-nums 已经单独保证了这一点，
   不需要真的用等宽字族。 */
.plan-amount {
  font-family: var(--font-heading);
  font-weight: 400;
  font-synthesis-weight: none;
  font-size: clamp(30px, 4vw, 40px);
  letter-spacing: -0.02em;
}
.plan-period { font-size: 14px; color: var(--text-dim); }

.plan-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 9px; }

.plan-list li {
  font-size: 14px;
  color: var(--text-muted);
  padding-left: 22px;
  position: relative;
}

.plan-list li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 8px;
  width: 9px;
  height: 5px;
  border-left: 1.5px solid var(--accent);
  border-bottom: 1.5px solid var(--accent);
  transform: rotate(-45deg);
}

/* 对勾表示「含」，未含的项必须换一种形状。
 * 早先只是把对勾调淡，读起来像「含，但不重要」，正好反了。 */
.plan-list li.off { color: var(--text-dim); }

.plan-list li.off::before {
  top: 11px;
  width: 10px;
  height: 0;
  border-left: 0;
  border-bottom: 1.5px solid var(--text-dim);
  transform: none;
}

.plan .btn { width: 100%; margin-top: auto; }

/* 单模块选购 */
.module-picker {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: 26px 24px;
}

.module-picker-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.module-picker-toolbar p { margin: 0; }
.module-picker-actions { display: flex; gap: 8px; flex-wrap: wrap; }

.module-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
  gap: 8px;
  margin: 0 0 20px;
}

.module-option {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 14px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: 14px;
  transition: border-color 0.15s, background-color 0.15s;
}

.module-option:hover { background: var(--surface-hover); }

/* hover 与选中两种态的底色都比 --surface 亮，--text-dim 在它们上头都掉出 AA：
 * hover 是 4.27:1，选中态（半透明 --accent-dim 叠在 --surface 上）更低到 3.84:1。
 * 选中态尤其要紧——那是持续状态，用户勾完模块就一直看着这个价格标签。
 *
 * 提升一档而不是去调全局令牌：--text-dim 在其它表面上都达标，
 * 为这两个态动全局，会牵连三端所有用到它的地方。 */
.module-option:hover .module-tag,
.module-option:has(input:checked) .module-tag { color: var(--text-muted); }

.module-option input { accent-color: var(--accent); margin: 0; }

/* 选中态不只靠颜色：勾选框本身已是形状信号，配色只作强化 */
.module-option:has(input:checked) { border-color: var(--accent); background: var(--accent-dim); }

/* 禁用态曾经用 opacity:.45 整体压暗，实测把文字压到 2.9:1。
 * 改成显式的降级配色，暗淡但仍然读得清。 */
.module-option:has(input:disabled) {
  cursor: not-allowed;
  border-color: var(--border);
  background: var(--bg-alt);
  color: var(--text-dim);
}

.module-option:has(input:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.module-tag {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-dim);
}

.module-total {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
  flex-wrap: wrap;
}

.module-total-price {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 400;
  font-synthesis-weight: none;
  font-size: clamp(24px, 3vw, 32px);
  font-variant-numeric: tabular-nums;
}

/* ── 页脚 ───────────────────────────────── */

.footer { border-top: 1px solid var(--border); padding: 40px 0; }
.footer-inner { display: flex; gap: 28px; align-items: center; flex-wrap: wrap; }
.footer .brand { font-size: 15px; margin: 0 0 2px; }
.footer p { margin: 0; font-size: 14px; }
.footer-links { display: flex; gap: 20px; font-size: 14px; margin-left: auto; }
.footer-links a { color: var(--text-muted); }
.footer-links a:hover { color: var(--text); }

@media (max-width: 720px) {
  .footer { padding: 32px 0; }
  .footer-inner {
    flex-direction: column;
    align-items: flex-start;
    gap: 18px;
  }
  .footer-links {
    margin-left: 0;
    flex-wrap: wrap;
    gap: 10px 16px;
    width: 100%;
  }
}

/* ── 通用 ───────────────────────────────── */

.note {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
  padding: 16px 18px;
  font-size: 14px;
  color: var(--text-muted);
  margin: 28px 0;
}

.note strong { color: var(--text); }

.note.note-policy {
  border-left-color: var(--border-strong);
  background: var(--bg-alt);
}

/* ── 内联反馈 ───────────────────────────── */

/* 替代 alert()：原生弹窗会阻塞页面、无法样式化，在手机上尤其突兀。
 * 挂 role="status" 后读屏用户也能听到，alert() 反而做不到这点。 */
.inline-alert {
  margin: 12px 0 0;
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  background: var(--accent-dim);
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
  color: var(--text);
}

.inline-alert:empty {
  display: none;
}

.inline-alert.warn {
  background: color-mix(in srgb, var(--danger) 10%, transparent);
  border-color: color-mix(in srgb, var(--danger) 35%, transparent);
}

/* ── 工具类 ─────────────────────────────── */

/* 这些原本都是写在标签 style 属性里的魔法值，收敛到这里便于统一调整 */
.hero-tight { padding-bottom: 48px; }
.hero-tighter { padding-bottom: 32px; }
.section-plans { padding-bottom: 64px; }
.wrap.checkout { max-width: 820px; }
.page-title { font-size: clamp(26px, 3.5vw, 34px); }
.page-title-md { font-size: clamp(28px, 4vw, 40px); }
.box-title { font-size: 18px; margin-bottom: 18px; }
.box-title.tight { margin-bottom: 6px; }
.plan-meta { min-height: auto; font-size: 13px; }
.btn-block { width: 100%; }
.total-note { margin: 8px 0 18px; }
.total-note:empty { margin: 0; min-height: 0; }
.note-spaced { margin-top: 32px; }
.module-total-label { margin: 0; font-size: 14px; color: var(--text-muted); }
.module-total-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }

@media (max-width: 640px) {
  .hero { padding: 56px 0 48px; }
  .section { padding: 52px 0; }

  /* 收紧而不是藏掉：定价页那个 btn-ghost 是货币切换，藏了就没法切 USD */
  .nav-actions { gap: 8px; }
  .nav-actions .btn { padding: 7px 12px; font-size: 13px; }

  /* 三列对比表在 390px 下本来要横滑才看得全。
   * 收紧字号与内边距让它整张放得进去，比加一个「可以左右滑」的提示实在。 */
  .compare { font-size: 14px; }
  .compare th, .compare td { padding: 10px 11px; }
  .compare .highlight-row .num { font-size: 15px; }
  .compare .saving-row .num { font-size: 19px; }
  .module-picker-toolbar { align-items: flex-start; flex-direction: column; }

  #download .hero-actions {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
  }
  #download .hero-actions .btn {
    width: 100%;
    white-space: normal;
  }

  .module-total {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }
  .module-total-actions {
    width: 100%;
    flex-direction: column;
    align-items: stretch;
  }
  .module-total-actions .btn { width: 100%; }
}

@media (max-width: 360px) {
  .feature-grid,
  .principle-grid,
  .compare-points,
  .plan-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .feature-card,
  .plan { min-width: 0; }

  .hero-actions {
    flex-direction: column;
    align-items: stretch;
  }
  .hero-actions .btn { width: 100%; }
}

@media (max-width: 330px) {
  .hero h1 { font-size: 30px; }
}

/* ── Windows 高对比模式 ─────────────────── */

/* 高对比模式会把所有背景色换成系统调色板，凡是「只靠底色表达状态」的地方
 * 到那儿就全部长得一样了。这里给它们补上不会被抹掉的形状信号。
 * 只补状态，不用 forced-color-adjust 强行保留品牌色——那等于把用户
 * 特意打开的辅助功能又关回去。 */
@media (forced-colors: active) {
  /* 底色被接管后，skip-link 会变成一块和页面同色的方块 */
  .skip-link { border: 1px solid; }

  /* 计费周期原本只靠一块蓝底表示「当前选的是哪个」，
   * 高对比下月付 / 年付 / 买断三个按钮会一模一样 */
  .billing-toggle button[aria-pressed="true"] {
    outline: 2px solid Highlight;
    outline-offset: -2px;
  }

  .platform-switch button[aria-pressed="true"] {
    outline: 2px solid Highlight;
    outline-offset: -2px;
  }

  /* 主推方案的强调边框会和普通卡片同色 */
  .plan.featured { outline: 2px solid Highlight; outline-offset: -1px; }

  .pay-option:has(input:checked) {
    outline: 2px solid Highlight;
    outline-offset: -2px;
  }

  /* 主按钮与次按钮都会退化成系统按钮色，靠边框拉开主次 */
  .btn-primary { border-color: currentColor; }
}

/* ── 结账页 ───────────────────────────────── */

.checkout-grid {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 24px;
  align-items: start;
  margin-top: 28px;
}

.checkout-box {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: 22px 24px;
}

.checkout-main .checkout-box + .checkout-box {
  margin-top: 18px;
}

.checkout-side .sticky {
  position: sticky;
  top: 88px;
  max-height: calc(100dvh - 96px);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.checkout-actions {
  display: grid;
  gap: 10px;
}

.payment-qr {
  display: block;
  width: min(240px, 100%);
  height: auto;
  margin: 16px auto;
  padding: 8px;
  border-radius: 12px;
  background: #fff;
}

.qr-actions {
  display: grid;
  gap: 10px;
  margin-top: 16px;
}

.legal-copy h2 {
  margin-top: 48px;
  font-size: clamp(20px, 2.4vw, 24px);
  font-weight: 600;
  letter-spacing: -0.015em;
  scroll-margin-top: 88px;
}

.legal-copy h2:first-of-type { margin-top: 32px; }

.legal-copy h2:not(:first-of-type) {
  padding-top: 24px;
  border-top: 1px solid color-mix(in srgb, var(--border) 65%, transparent);
}

.legal-copy > p {
  max-width: 640px;
  line-height: 1.75;
}

.legal-copy > .inline-alert { max-width: 640px; }

.legal-updated {
  display: block;
  margin-bottom: 10px;
  font-size: 13px;
  color: var(--text-dim);
  letter-spacing: 0.01em;
}

.legal-copy .legal-contact {
  margin-top: 12px;
  padding: 16px 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.legal-copy .legal-contact dt {
  font-size: 13px;
  color: var(--text-dim);
}

.legal-copy .legal-contact dd {
  font-size: 16px;
  text-align: start;
  font-variant-numeric: normal;
}

/* 订单摘要：左标签右值，值靠右便于扫读金额与数量 */
.summary {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 10px 16px;
  margin: 0;
}

.summary dt {
  color: var(--text-muted);
  font-size: 14px;
}

.summary dd {
  margin: 0;
  font-size: 14px;
  text-align: right;
  overflow-wrap: anywhere;
  font-variant-numeric: tabular-nums;
}

.summary .saving {
  color: var(--success);
}

.summary-total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}

/* 应付总额：结账页最该被看见的数字，设计稿给的是 38px Caprasimo */
.summary-total strong {
  font-family: var(--font-heading);
  font-weight: 400;
  font-synthesis-weight: none;
  font-size: clamp(28px, 3.6vw, 38px);
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

/* 付款方式：整块可点，不要只让那个小圆点能点 */
.pay-grid {
  display: grid;
  gap: 10px;
}

.pay-option {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.pay-option:hover {
  background: var(--surface-hover);
}

/* 同 .module-option：hover 与选中两种底色都更亮，12px 的付款说明必须跟着提升一档 */
.pay-option:hover .pay-note,
.pay-option:has(input:checked) .pay-note { color: var(--text-muted); }

.pay-option:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-dim);
}

.pay-option:has(input:checked) .pay-name {
  font-weight: 600;
}

/* 键盘用户需要看得见焦点落在哪张卡上 */
.pay-option:has(input:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.pay-option input {
  accent-color: var(--accent);
  width: 16px;
  height: 16px;
  flex: none;
}

.pay-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.pay-name {
  font-size: 14px;
  font-weight: 500;
}

.pay-note {
  font-size: 12px;
  color: var(--text-dim);
}

.field-label {
  display: block;
  margin-bottom: 7px;
  font-size: 14px;
  font-weight: 550;
}

.field {
  width: 100%;
  padding: 12px 14px;
  font: inherit;
  font-size: 15px;
  color: var(--text);
  background: var(--bg-alt);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
}

.field:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent);
}

.field[aria-invalid="true"] { border-color: var(--danger); }

/* 错误提示不能只靠红色传达——前面那个「!」是给色觉障碍用户的第二重信号 */
.field-error {
  min-height: 18px;
  margin: 6px 0 0;
  font-size: 13px;
  color: var(--danger);
}

.field-error:not(:empty)::before {
  content: "! ";
  font-weight: 700;
}

.assurance {
  margin: 20px 0 0;
  padding: 18px 0 0;
  border-top: 1px solid var(--border);
  list-style: none;
  display: grid;
  gap: 8px;
}

.assurance li {
  font-size: 13px;
  color: var(--text-muted);
  padding-left: 18px;
  position: relative;
}

.assurance li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 7px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--success);
}

.order-no {
  font-family: var(--font-mono);
  font-size: 15px;
  margin: 4px 0 0;
  overflow-wrap: anywhere;
}

.lede code,
#order-no {
  font-family: var(--font-mono);
  font-size: 0.94em;
  letter-spacing: 0.02em;
}

#result .summary dt:first-of-type + dd {
  font-family: var(--font-mono);
  letter-spacing: 0.02em;
}

#lookup-form #order-hint { margin: 6px 0 0; }
#lookup-form .btn-block { margin-top: 16px; }

@media (min-width: 641px) {
  #lookup-form .btn-block {
    width: auto;
    min-width: 9.5em;
  }
}

#result:not(:empty) { margin-top: 24px; }

@media (max-width: 860px) {
  .checkout-grid {
    grid-template-columns: 1fr;
  }
  .checkout-side .sticky {
    position: static;
  }
}

/* ── 动效 ─────────────────────────────────
 *
 * Organic 的性格是软、圆、有点顽皮，所以动效走"长出来 / 陷下去"，
 * 不走位移滑动——圆形元素滑动会显得它在飘，缩放才像它自己在动。
 *
 * 三条自我约束：
 *   1. **纯 CSS，不加 JS。** README 写着「零构建、零运行时依赖」，
 *      为了几个入场动画引一个 IntersectionObserver 不值得。
 *   2. **渐进增强。** 滚动驱动动画（animation-timeline）用 @supports 包住，
 *      不支持的浏览器看到的就是现在这个静态页面——不退化、不闪、不空白。
 *      这一点很重要：入场动画最常见的坏法是"JS 没跑起来，内容永远是透明的"。
 *   3. **prefers-reduced-motion 一律让路。** 文件上方那个 media query 已经
 *      把 transition/animation 时长压到 0.01ms，这里再显式关掉入场动画的
 *      初始透明度——只压时长的话，元素会卡在动画第一帧，也就是不可见。
 */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* 区块进入视口时淡入并轻微上浮。
       只给 section 级，不给每张卡片——十四个模块卡逐个飘进来会像广告页。 */
    main > section {
      animation: rise-in linear both;
      animation-timeline: view();
      /* 区块刚露头 15% 时开始，进到 60% 时演完。
         起点不取 0% 是有理由的：从刚露一条边就开始的话，用户往下滚到
         能看清它的时候动画早演完了，等于白做。 */
      animation-range: entry 15% entry 60%;
    }

    @keyframes rise-in {
      from { opacity: 0; transform: translateY(14px) scale(0.995); }
      to   { opacity: 1; transform: none; }
    }
  }
}

/* 卡片悬停：原来只有 translateY(-2px)。Organic 的圆角配一点点放大更贴它的性格，
   幅度刻意压到 1.008——再大就会把相邻卡片的边距挤得看起来不齐。 */
@media (prefers-reduced-motion: no-preference) {
  .feature-card, .plan {
    transition: transform var(--dur) var(--ease), border-color var(--dur) var(--ease),
                box-shadow var(--dur) var(--ease), background-color var(--dur) var(--ease);
  }
  .feature-card:hover { transform: translateY(-2px); }
  .plan:hover { transform: translateY(-2px) scale(1.006); }
}

/* 打印主要用于保存订单/条款；导航、购买动作和装饰不应抢占纸面。 */
@media print {
  :root {
    color-scheme: light;
    --bg: #fff;
    --bg-alt: #fff;
    --surface: #fff;
    --surface-hover: #fff;
    --surface-raised: #fff;
    --text: #111;
    --text-muted: #333;
    --text-dim: #555;
    --border: #bbb;
    --border-strong: #777;
  }

  .nav,
  .footer,
  .skip-link,
  .hero-actions,
  .billing-toggle,
  .platform-switch,
  .module-picker-actions,
  .qr-actions,
  [data-buy],
  [data-sales],
  #submit,
  #cancel-submit,
  #lookup-submit { display: none !important; }

  body { background: #fff; color: #111; }
  /* 四步列表的滚动驱动入场同样要关：打印没有滚动，
     带 both 填充的动画会把条目冻在透明第一帧 */
  main > section, .flow-list > li { animation: none !important; }
  .hero, .section, .section-plans { padding-block: 20px; }
  .legal-copy h2:not(:first-of-type) { border-top-color: #ccc; }
  .plan, .checkout-box, .module-picker, .note {
    break-inside: avoid;
    box-shadow: none;
  }
  a[href]::after {
    content: " (" attr(href) ")";
    font-size: 0.8em;
    overflow-wrap: anywhere;
  }
}

/* 主按钮按下去"陷"一下。设计系统要求按下态取强调色斜坡再深一档，
   位移只是补充手感，颜色才是主信道。 */
.btn-primary:active { background: var(--accent-solid-hover); }

/* 大数字变化时的过渡。价格切月付/年付、模块合计改动都会走这里——
   数字本身没法做逐位滚动（那需要 JS），但颜色与轻微缩放能提示"这里变了"。 */
@media (prefers-reduced-motion: no-preference) {
  .plan-amount, .module-total-price, .summary-total strong {
    transition: color var(--dur) var(--ease), transform var(--dur) var(--ease);
  }
}

/* ── 四步流程 ───────────────────────────────
 *
 * 编号与标签走等宽，正文走站内 h3 / --text-muted。
 * 分隔用 1px --border，不铺底色卡片——和 .stat-row / .principle-grid
 * 一样，层次靠间距与字重，不靠色块。 */

.flow-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.flow-list > li {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr);
  gap: 20px;
  padding: 22px 0;
}

.flow-list > li + li { border-top: 1px solid var(--border); }

.flow-index {
  font-family: var(--font-mono);
  font-size: 20px;
  font-weight: 700;
  line-height: 1.2;
  color: var(--accent-text);
  align-self: start;
  /* 对齐右侧 h3，而不是 DOWNLOAD 标签行 */
  margin-top: calc(11px * 1.2 + 6px + 2px);
}

.flow-list h3 { margin-bottom: 8px; }

.flow-list p {
  color: var(--text-muted);
  max-width: 60ch;
  margin-bottom: 0;
}

.flow-tag {
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1.2;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  margin: 0 0 6px;
}

/* ── 定价页信任条 ───────────────────────────
 * 三列克制陈述，不加底色。格子间只留 1px 分隔线。 */

.trust-strip {
  list-style: none;
  margin: 0 0 40px;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.trust-strip > li { padding: 0 22px; }
.trust-strip > li:first-child { padding-left: 0; }
.trust-strip > li:last-child { padding-right: 0; }
.trust-strip > li + li { border-left: 1px solid var(--border); }

.trust-strip strong {
  display: block;
  color: var(--text);
  font-weight: 650;
  margin-bottom: 6px;
}

.trust-strip span {
  display: block;
  color: var(--text-muted);
  font-size: 14px;
  line-height: 1.5;
}

@media (max-width: 720px) {
  .principle-grid {
    grid-template-columns: 1fr;
    gap: 24px;
  }

  .flow-list > li {
    grid-template-columns: 44px minmax(0, 1fr);
    gap: 16px;
  }
  .flow-index { font-size: 18px; }

  .trust-strip { grid-template-columns: 1fr; margin-bottom: 44px; }
  .trust-strip > li {
    padding-block: 20px;
  }
  .trust-strip > li:first-child { padding-top: 0; }
  .trust-strip > li:last-child { padding-bottom: 0; }
  .trust-strip > li + li {
    border-left: 0;
    border-top: 1px solid var(--border-strong);
  }
}

@media (max-width: 860px) {
  .legal-copy h2 { scroll-margin-top: 120px; }
}

/* ── Hero 演示动效 ─────────────────────────
 *
 * 柱高与读数高亮只在用户接受动效时过渡。
 * 事件行叠在面板上：按更紧的 --surface-raised 对比度来守，
 * 不用 --text-dim（那档在 raised 面上掉出 AA）。 */

@media (prefers-reduced-motion: no-preference) {
  .spark i { transition: height 0.6s ease; }
  .metric-value { transition: color var(--dur) var(--ease); }
}

.metric-value.is-fresh { color: var(--accent-text); }

.showcase-event {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 8px 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-muted);
}

.showcase-event time {
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}

.showcase-event span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 四步入场单独开一块：不改上方 section 级 rise-in。
 * 不支持 view() 的浏览器看不到 animation，列表保持静态可见；
 * reduced-motion 被 no-preference 挡在外面，不会卡在透明第一帧。 */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .flow-list > li {
      animation: rise-in linear both;
      animation-timeline: view();
      animation-range: entry 12% entry 58%;
    }
    .flow-list > li:nth-child(2) { animation-range: entry 18% entry 64%; }
    .flow-list > li:nth-child(3) { animation-range: entry 24% entry 70%; }
    .flow-list > li:nth-child(4) { animation-range: entry 30% entry 76%; }
  }
}
