/* ================================================================
   QuantDesktop 官网 — 单页静态样式
   Dark-first, zero build step. 风格：深色金融终端。

   调色板来自应用自己的 src/assets/styles/variables.css，站点只在其上
   追加页面级的「氛围」token（底色渐变、发丝线、顶边高光、辉光）。语义色
   （text / accent / up / down）与应用保持同值 —— 改那边要同步这里，
   这是仓库里唯一一处有意重复。

   字体刻意不引 webfont：fonts.googleapis.com 在国内加载不出来，首屏会
   被它拖住。科技感靠**刻意使用等宽栈**传达，而不是靠外部字体。
   ================================================================ */

/* ── Tokens（深色为默认，与应用一致） ── */
:root {
  /* Surfaces — 与应用 variables.css 同值 */
  --surface-0: #0d1117;
  --surface-1: #161b22;
  --surface-2: #1c2333;
  --surface-3: #252d3f;

  /* Page atmosphere — 站点特有。终端感来自“有纵深的底”，不是一块纯色。 */
  --page-top: #0d1117;
  --page-bottom: #05080c;
  --grid-line: rgba(255, 255, 255, 0.028);
  --grid-size: 64px;

  /* Hairlines & sheen — modern-dark 的标志性做法：发丝描边 + 顶边 1px 高光 */
  --hairline: rgba(255, 255, 255, 0.075);
  --hairline-strong: rgba(255, 255, 255, 0.14);
  --sheen: inset 0 1px 0 rgba(255, 255, 255, 0.055);
  --card-fill: linear-gradient(180deg, rgba(255, 255, 255, 0.038), rgba(255, 255, 255, 0.012));
  --card-fill-hover: linear-gradient(180deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.022));
  --band: rgba(255, 255, 255, 0.016);

  /* Text — 与应用同值。--text-3 只用于纯装饰与非文本图形（卡片角标、
     轮播未选中的圆点）：#6e7681 在 #0d1117 上 4.12:1、#8b949e 在纯白上
     3.08:1 —— 够 WCAG 对图形要求的 3:1，但够不上小字号的 4.5:1，
     所以正文级的灰一律用 --text-2。 */
  --text-1: #e6edf3;
  --text-2: #8b949e;
  --text-3: #6e7681;

  /* A 股约定：红涨绿跌。站内只作点缀，不承担语义。 */
  --up: #f85149;
  --down: #3fb950;
  --accent: #58a6ff;
  --accent-dim: rgba(88, 166, 255, 0.12);
  --glow-accent: rgba(88, 166, 255, 0.32);
  --glow-up: rgba(248, 81, 73, 0.22);

  /* 主按钮。深色主题下强调色是亮蓝，标签用近黑；浅色主题下强调色是深蓝，
     标签必须反过来用白 —— 写死深色标签压在 #0969da 上只有 3.68:1。 */
  --btn-accent-a: #6cb2ff;
  --btn-accent-b: #58a6ff;
  --btn-accent-hover-a: #85c0ff;
  --btn-accent-hover-b: #4a9dfa;
  --on-accent: #06101d;

  /* 主标题渐变的末端色。浅色主题下必须把品牌色压得更狠 —— 深蓝在
     白底上比在白字在深底上抢眼得多，同样的比例会变成一根蓝色标题。 */
  --title-grad-end: color-mix(in srgb, var(--text-1) 76%, var(--accent));

  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
    "Microsoft YaHei", "Helvetica Neue", sans-serif;
  --font-mono: "JetBrains Mono", "Cascadia Code", "Consolas", "Menlo", monospace;

  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;

  /* 比一般落地页更收敛的圆角 —— 终端 UI 是方的 */
  --radius-xs: 4px;
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 14px;
  --radius-full: 9999px;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 4px 20px rgba(0, 0, 0, 0.45);
  --shadow-lg: 0 24px 64px rgba(0, 0, 0, 0.55);

  /* 有物理感的缓动，用于入场；微交互用更短的 --transition */
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --transition: 180ms cubic-bezier(0.4, 0, 0.2, 1);

  --nav-height: 64px;
  --container: 1120px;
  --section-y: clamp(64px, 9vw, 112px);
}

[data-theme="light"] {
  --surface-0: #ffffff;
  --surface-1: #f6f8fa;
  --surface-2: #eef1f5;
  --surface-3: #e2e5ea;

  --page-top: #ffffff;
  --page-bottom: #eef2f7;
  --grid-line: rgba(15, 23, 42, 0.045);

  --hairline: rgba(15, 23, 42, 0.1);
  --hairline-strong: rgba(15, 23, 42, 0.2);
  --sheen: inset 0 1px 0 rgba(255, 255, 255, 0.9);
  --card-fill: linear-gradient(180deg, #ffffff, #f8fafc);
  --card-fill-hover: linear-gradient(180deg, #ffffff, #f1f5f9);
  --band: rgba(15, 23, 42, 0.022);

  --text-1: #1f2328;
  --text-2: #656d76;
  --text-3: #8b949e;

  --up: #d1242f;
  --down: #1a7f64;
  --accent: #0969da;
  --accent-dim: rgba(9, 105, 218, 0.09);
  --glow-accent: rgba(9, 105, 218, 0.18);
  --glow-up: rgba(209, 36, 47, 0.12);

  --btn-accent-a: #1a72d0;
  --btn-accent-b: #0969da;
  /* 浅色主题下 hover 要**变深**（深色主题下是变亮）—— 白标签配浅色填充
     只有 3.75:1，方向反了就不达标。 */
  --btn-accent-hover-a: #0f63c4;
  --btn-accent-hover-b: #0753ad;
  --on-accent: #ffffff;

  --title-grad-end: color-mix(in srgb, var(--text-1) 91%, var(--accent));

  --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.07);
  --shadow-md: 0 4px 20px rgba(15, 23, 42, 0.09);
  --shadow-lg: 0 24px 64px rgba(15, 23, 42, 0.13);
}

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-height) + 16px);
  background: var(--page-bottom);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  color: var(--text-1);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}

/* 固定的氛围层：纵向渐变 + 蓝图网格。网格用 mask 从顶部淡出，只在上半屏
   隐约可见 —— 铺满全页会变成噪点。两层都 fixed，页面在它们之上滚动。 */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  background: linear-gradient(180deg, var(--page-top) 0%, var(--page-bottom) 100%);
}

body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image: linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: var(--grid-size) var(--grid-size);
  -webkit-mask-image: radial-gradient(ellipse 130% 70% at 50% 0%, #000 25%, transparent 72%);
  mask-image: radial-gradient(ellipse 130% 70% at 50% 0%, #000 25%, transparent 72%);
}

img {
  max-width: 100%;
  display: block;
}

/* <picture> 只是个格式协商的外壳，不该参与布局 —— 否则它会成为 grid/flex
   的子项，把 .ticker-runway 的 place-items 和 .feature__media--grid 的列宽
   都算错一层。display:contents 让它从盒树里消失，里面的 <img> 回到原来的
   位置，`.xxx img` 这些选择器也照旧命中。 */
picture {
  display: contents;
}

/* UA 默认 margin: 1em 40px 会从每张截图的列宽里悄悄吃掉 80px。 */
figure {
  margin: 0;
}

a {
  color: var(--accent);
  text-decoration: none;
}

h1,
h2,
h3,
h4 {
  margin: 0;
  line-height: 1.25;
  letter-spacing: -0.01em;
}

p {
  margin: 0;
}

ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

button {
  font: inherit;
  cursor: pointer;
}

/* 可见的键盘焦点环 —— 深色底上默认 outline 几乎看不见 */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

.icon {
  width: 1em;
  height: 1em;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex-shrink: 0;
}

/* 数字一律等宽 + 表格数字：价格列不会随刷新抖动，也更像终端 */
.num,
.mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* ── Layout ── */
.container {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 24px;
}

.section {
  position: relative;
  padding: var(--section-y) 0;
}

/* 交替的浅色带用半透明填充 + 发丝分隔，让底层的网格透过来 ——
   不透明色块会把整页的纵深感切断。 */
.section--tint {
  background: var(--band);
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
}

.section__head {
  max-width: 720px;
  margin: 0 auto clamp(40px, 5vw, 64px);
  text-align: center;
}

/* 终端风格的区块标签：[ 02 │ 功能亮点 ] */
.section__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 5px 14px 5px 12px;
  margin-bottom: var(--space-4);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.022);
  box-shadow: var(--sheen);
  color: var(--text-2);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.06em;
}

[data-theme="light"] .section__eyebrow {
  background: rgba(255, 255, 255, 0.75);
}

.section__eyebrow-num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: 0;
  color: var(--accent);
  padding-right: 10px;
  border-right: 1px solid var(--hairline);
}

.section__title {
  font-size: clamp(1.6rem, 3.2vw, 2.2rem);
  font-weight: 700;
}

.section__desc {
  margin-top: var(--space-4);
  color: var(--text-2);
  font-size: 1rem;
}

/* 区块末尾的「查看更多」。首页只放每条内容的摘要，完整版在各自的页面里，
   这个链接就是那条路径。 */
.section__more {
  margin-top: var(--space-6);
  text-align: center;
  font-weight: 600;
}

/* ── Buttons ── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 10px 18px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font-size: 0.94rem;
  font-weight: 600;
  white-space: nowrap;
  transition: transform var(--transition), background var(--transition),
    border-color var(--transition), box-shadow var(--transition), color var(--transition);
}

.btn:hover {
  transform: translateY(-1px);
}

.btn:active {
  transform: translateY(0);
}

.btn--primary {
  background: linear-gradient(180deg, var(--btn-accent-a), var(--btn-accent-b));
  color: var(--on-accent);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25) inset, 0 6px 20px var(--glow-accent);
}

.btn--primary:hover {
  background: linear-gradient(180deg, var(--btn-accent-hover-a), var(--btn-accent-hover-b));
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.3) inset, 0 10px 30px var(--glow-accent);
}

.btn--outline {
  background: var(--card-fill);
  border-color: var(--hairline);
  box-shadow: var(--sheen);
  color: var(--text-1);
}

.btn--outline:hover {
  background: var(--card-fill-hover);
  border-color: var(--hairline-strong);
}

.btn--ghost {
  background: transparent;
  color: var(--text-2);
  border-color: transparent;
  padding: 10px 12px;
}

.btn--ghost:hover {
  color: var(--text-1);
  background: rgba(255, 255, 255, 0.045);
}

[data-theme="light"] .btn--ghost:hover {
  background: rgba(15, 23, 42, 0.05);
}

.btn--lg {
  padding: 14px 26px;
  font-size: 1rem;
  border-radius: var(--radius-md);
}

.btn--sm {
  padding: 7px 14px;
  font-size: 0.875rem;
}

/* ── Nav ── */
.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  height: var(--nav-height);
  display: flex;
  align-items: center;
  border-bottom: 1px solid transparent;
  transition: background var(--transition), border-color var(--transition);
}

.nav.is-scrolled {
  background: color-mix(in srgb, var(--page-top) 78%, transparent);
  backdrop-filter: saturate(180%) blur(16px);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  border-bottom-color: var(--hairline);
}

/* 顶栏下沿一道渐变高光，是「终端窗口」的一个便宜信号 */
.nav.is-scrolled::after {
  content: "";
  position: absolute;
  inset: auto 0 -1px 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--glow-accent), transparent);
}

.nav__inner {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  width: 100%;
}

.nav__brand {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--text-1);
  font-weight: 700;
  font-size: 1.02rem;
  letter-spacing: -0.01em;
}

.nav__brand img {
  width: 28px;
  height: 28px;
  border-radius: 7px;
  box-shadow: 0 0 0 1px var(--hairline);
}

.nav__links {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-left: auto;
}

.nav__link {
  position: relative;
  padding: 8px 12px;
  border-radius: var(--radius-xs);
  color: var(--text-2);
  font-size: 0.92rem;
  font-weight: 500;
  transition: color var(--transition), background var(--transition);
}

.nav__link:hover {
  color: var(--text-1);
  background: rgba(255, 255, 255, 0.045);
}

[data-theme="light"] .nav__link:hover {
  background: rgba(15, 23, 42, 0.05);
}

/* 当前页指示器。所有导航项都带这一条，默认靠 --current 隐掉。 */
.nav__link::after {
  content: "";
  position: absolute;
  /* 左右 12px 正是 .nav__link 的内边距 —— 于是线宽**等于文字宽**。
     按内边距外沿算的话线会比文字宽一截，那看着像一颗带下边框的按钮。 */
  left: 12px;
  right: 12px;
  bottom: 4px;
  height: 2px;
  border-radius: 1px;
  /* 两端渐隐。全站只有两处用渐变线，另一处是顶栏滚动后那条 ::after 发丝线
     （.nav.is-scrolled::after），于是这两条线互相解释。 */
  background: linear-gradient(
    90deg,
    transparent,
    var(--accent) 24%,
    var(--accent) 76%,
    transparent
  );
  /* 用 drop-shadow 而不是 box-shadow：它跟着渐变渲染后的 alpha 走，于是辉光
     只裹在可见的那段线上；box-shadow 会按元素框发一圈方形的光。
     这一下是为了与站点已有的辉光语言对齐 —— 主按钮和回到顶部的进度环都亮着，
     指示器不亮会显得是贴上去的。 */
  filter: drop-shadow(0 0 5px var(--glow-accent));
  opacity: var(--current, 0);
  transition: opacity var(--transition);
}

.nav__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-2);
  font-size: 18px;
  transition: color var(--transition), background var(--transition),
    border-color var(--transition);
}

.icon-btn:hover {
  color: var(--text-1);
  background: rgba(255, 255, 255, 0.045);
  border-color: var(--hairline);
}

[data-theme="light"] .icon-btn:hover {
  background: rgba(15, 23, 42, 0.05);
}

/* 按钮显示的是「切过去会变成什么」，由当前主题决定，不靠 JS 同步类名 */
.theme-toggle .icon-moon {
  display: none;
}

[data-theme="light"] .theme-toggle .icon-sun {
  display: none;
}

[data-theme="light"] .theme-toggle .icon-moon {
  display: block;
}

.nav__burger .icon-close {
  display: none;
}

.nav__burger[aria-expanded="true"] .icon-menu {
  display: none;
}

.nav__burger[aria-expanded="true"] .icon-close {
  display: block;
}

.nav__burger {
  display: none;
}

/* ── Hero ── */
.hero {
  position: relative;
  padding: calc(var(--nav-height) + clamp(48px, 7vw, 84px)) 0 clamp(56px, 8vw, 88px);
  overflow: hidden;
  text-align: center;
}

/* 两团环境光斑（品牌蓝 + 涨红）。用柔和的 radial-gradient 直接画，不加
   filter: blur —— 大面积模糊很贵，而渐变本身就是软的。 */
.hero::before {
  content: "";
  position: absolute;
  inset: -40% 0 auto 50%;
  width: min(1300px, 165vw);
  height: 820px;
  transform: translateX(-50%);
  background: radial-gradient(
      ellipse 42% 55% at 28% 42%,
      var(--glow-up),
      transparent 68%
    ),
    radial-gradient(ellipse 45% 58% at 72% 32%, var(--glow-accent), transparent 66%);
  pointer-events: none;
  z-index: 0;
  animation: hero-drift 22s ease-in-out infinite;
}

@keyframes hero-drift {
  0%,
  100% {
    transform: translateX(-50%) scale(1);
    opacity: 0.85;
  }
  50% {
    transform: translateX(-50%) scale(1.07);
    opacity: 1;
  }
}

.hero > .container {
  position: relative;
  z-index: 1;
}

/* 终端风格的一行规格说明，放在图标之上当 kicker */
.hero__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-bottom: var(--space-8);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-2);
}

.hero__meta i {
  font-style: normal;
  color: var(--hairline-strong);
}

.hero__meta b {
  color: var(--accent);
  font-weight: 700;
}

.hero__icon {
  width: 92px;
  height: 92px;
  border-radius: 22px;
  margin: 0 auto var(--space-6);
  box-shadow: var(--shadow-lg), 0 0 0 1px var(--hairline),
    0 0 60px var(--glow-accent);
}

.hero__title {
  font-size: clamp(2rem, 5.5vw, 3.25rem);
  font-weight: 800;
  letter-spacing: -0.035em;
}

/* 渐变字标。width: max-content 不是排版偏好而是必须的：h1 用了
   background-clip: text 配 color: transparent，渐变只画在元素框内 ——
   字形一旦溢出框，那部分就没有背景可裁，会连同 transparent 一起消失。
   （同一坑在 scripts/og-card.html 里也踩过一次。） */
.hero__wordmark {
  display: block;
  width: max-content;
  margin: 0 auto;
  background: linear-gradient(180deg, var(--text-1) 34%, var(--title-grad-end));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* 品类词进 H1，但不抢字标的位置：这样标题读作
   「QuantDesktop 免费开源的 A 股桌面看盘工具」，而不是只有品牌名。 */
.hero__title-sub {
  display: block;
  margin-top: 10px;
  font-size: clamp(0.95rem, 1.9vw, 1.15rem);
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--text-2);
}

.hero__tagline {
  margin-top: var(--space-4);
  font-size: clamp(1.05rem, 2.2vw, 1.35rem);
  color: var(--text-1);
  font-weight: 500;
}

.hero__tagline em {
  font-style: normal;
  color: var(--accent);
}

.hero__sub {
  margin: var(--space-4) auto 0;
  max-width: 620px;
  color: var(--text-2);
  font-size: 1rem;
}

.hero__cta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3);
  margin-top: var(--space-8);
}

.hero__badges {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2);
  margin-top: var(--space-6);
}

.hero__badges img {
  height: 20px;
  width: auto;
  opacity: 0.9;
}

/* ── Hero 轮播 ──
   一次显示一张，靠 transform 平移。五张截图都是 2057×1466，宽高比一致，
   轨道高度因此在任何一页都相同 —— 切换不会推着下面的内容跳。 */
.carousel {
  position: relative;
  margin-top: clamp(48px, 6vw, 72px);
}

/* 截图下面压一层品牌色的辉光，让「终端窗口」像是亮着的。用渐变本身做柔化，
   不加 filter: blur —— 大面积模糊很贵，而这个光斑是静态的。 */
.carousel::after {
  content: "";
  position: absolute;
  inset: 4% -5% 14%;
  border-radius: 50%;
  background: radial-gradient(ellipse 58% 52% at 50% 56%, var(--glow-accent), transparent 72%);
  z-index: -1;
  pointer-events: none;
}

.carousel__viewport {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  border: 1px solid var(--hairline-strong);
  box-shadow: var(--shadow-lg);
  background: var(--surface-1);
}

.carousel__track {
  display: flex;
  transition: transform 420ms var(--ease-out-expo);
}

.carousel__slide {
  flex: 0 0 100%;
  min-width: 0;
}

/* height:auto 不是可选项：<img> 上的 height 属性会作为定值生效（CSS 里只
   覆盖了 width），漏掉它图片会被拉成原始像素高 —— 1070×1466 而不是
   1070×763。属性本身要留着，它给出宽高比、防切换时的 CLS。 */
.carousel__slide img {
  width: 100%;
  height: auto;
  display: block;
}

/* 左右切换按钮。三条决定：
   1. **始终可见**，不做成 hover 才出现 —— 触摸设备根本没有 hover，而
      「看不出可以点」是轮播最常见的失败。
   2. **跟着主题走。** 早先这里是写死的深色实心圆，理由是「它压的是截图、
      不是页面底色」；那个理由在浅色主题下不成立 —— 一颗黑圆钉在白页面上。
      改用 --surface-1 + --text-1，并保持 92% 不透明度，于是它既属于当前
      主题，又压得住任何一张截图（浅色主题的按钮遇到深色截图也照样读得出）。
   3. **方的，不是圆的。** 全站控件语言是圆角矩形（.btn、各种 chip），
      圆形箭头是这里唯一的例外，也正是它显得突兀的原因。 */
.carousel__nav {
  position: absolute;
  top: 50%;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  padding: 0;
  transform: translateY(-50%);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--surface-1) 92%, transparent);
  backdrop-filter: saturate(160%) blur(12px);
  -webkit-backdrop-filter: saturate(160%) blur(12px);
  box-shadow: var(--sheen), var(--shadow-md);
  color: var(--text-1);
  font-size: 22px;
  transition: background var(--transition), border-color var(--transition),
    color var(--transition), box-shadow var(--transition), transform var(--transition);
}

.carousel__nav:hover {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  box-shadow: var(--sheen), var(--shadow-md), 0 0 22px -6px var(--glow-accent);
}

.carousel__nav:active {
  transform: translateY(-50%) scale(0.96);
}

.carousel__nav--prev {
  left: 14px;
}

.carousel__nav--next {
  right: 14px;
}

.carousel__bar {
  display: grid;
  gap: var(--space-3);
  justify-items: center;
  margin-top: var(--space-5);
}

.carousel__caption {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 10px;
  color: var(--text-2);
  font-size: 0.875rem;
  text-align: center;
}

.carousel__counter {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  color: var(--text-2);
}

.carousel__counter b {
  color: var(--accent);
  font-weight: 700;
}

.carousel__dots {
  display: flex;
  align-items: center;
  justify-content: center;
  /* 相邻触控目标之间至少留 8px */
  gap: var(--space-2);
}

/* 命中区 44×44（触控最小目标），视觉上只是一个 8px 的点 —— 两者分开做，
   才能同时满足「点得到」和「不要一排大圆钮」。选中态拉成胶囊，不靠颜色
   一个维度表意。 */
.carousel__dot {
  position: relative;
  width: 44px;
  height: 44px;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
}

.carousel__dot::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 8px;
  height: 8px;
  margin: -4px 0 0 -4px;
  border-radius: var(--radius-full);
  /* 不是纯装饰：这排点要让人看出「共几张、现在第几张」，属于 UI 组件的
     状态信息，按 WCAG 1.4.11 得够 3:1。#6e7681 在 #0d1117 上 4.12:1、
     在纯白上 3.08:1，两边都过；用 --hairline-strong 只有 1.43:1。 */
  background: var(--text-3);
  transition: width var(--transition), margin var(--transition),
    background var(--transition);
}

.carousel__dot:hover::before {
  background: var(--text-1);
}

.carousel__dot[aria-current="true"]::before {
  width: 24px;
  margin-left: -12px;
  background: var(--accent);
}

/* ── 卡片通用外观 ──
   发丝描边 + 顶边 1px 高光 + 极淡的纵向渐变，是整套「现代深色」的签名。
   全部卡片共用，避免四种卡片各写一遍。 */
.pain,
.highlight,
.underside__item,
.dl__card,
.dl__store,
.faq__item,
.tech__callout {
  position: relative;
  background: var(--card-fill);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  box-shadow: var(--sheen);
}

/* ── Pains ── */
.pains__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-4);
}

.pain {
  padding: var(--space-6);
}

.pain__emoji {
  font-size: 1.5rem;
  line-height: 1;
  margin-bottom: var(--space-4);
}

.pain p {
  color: var(--text-2);
  font-size: 0.94rem;
}

.pains__turn {
  margin-top: var(--space-8);
  text-align: center;
  font-size: clamp(1.05rem, 2.2vw, 1.25rem);
  font-weight: 600;
}

.pains__turn span {
  color: var(--accent);
}

/* ── Highlights ── */
.highlights__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-4);
  counter-reset: hl;
}

.highlight {
  padding: var(--space-6);
  counter-increment: hl;
  transition: border-color var(--transition), transform var(--transition),
    background var(--transition);
}

.highlight:hover {
  border-color: var(--hairline-strong);
  background: var(--card-fill-hover);
  transform: translateY(-2px);
}

.highlight__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.highlight__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: var(--radius-sm);
  background: var(--accent-dim);
  border: 1px solid color-mix(in srgb, var(--accent) 26%, transparent);
  color: var(--accent);
  font-size: 19px;
}

.highlight__title {
  font-size: 1.02rem;
  font-weight: 700;
}

/* 右上角的等宽序号，纯装饰 —— 终端感的来源之一。用 CSS counter 生成，
   免得为了一个装饰数字去改六处 HTML。颜色走 --text-3，但不叠 opacity：
   叠了之后实际对比度会随底色漂移，浅色下基本看不见。 */
.highlight::after {
  content: "0" counter(hl);
  position: absolute;
  right: var(--space-5);
  top: var(--space-5);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  color: var(--text-3);
}

.highlight p {
  color: var(--text-2);
  font-size: 0.92rem;
}

/* ── Feature rows ── */
.feature {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(32px, 5vw, 64px);
  align-items: center;
}

.feature + .feature {
  margin-top: clamp(64px, 8vw, 112px);
}

/* `order` 只把媒体挪进第一个栅格单元，不会改轨道尺寸 —— 不换轨道的话，
   反向行会把截图塞进窄的 5fr 列。 */
.feature--reverse {
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
}

.feature--reverse .feature__media {
  order: -1;
}

.feature__tag {
  display: inline-block;
  padding: 4px 10px;
  border-radius: var(--radius-xs);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--hairline);
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-bottom: var(--space-4);
}

[data-theme="light"] .feature__tag {
  background: rgba(255, 255, 255, 0.7);
}

.feature__tag--hot {
  background: color-mix(in srgb, var(--up) 14%, transparent);
  border-color: color-mix(in srgb, var(--up) 34%, transparent);
  color: var(--up);
}

.feature__title {
  font-size: clamp(1.3rem, 2.6vw, 1.65rem);
  font-weight: 700;
}

.feature__lead {
  margin-top: var(--space-4);
  color: var(--text-2);
  font-size: 0.98rem;
}

.feature__list {
  margin-top: var(--space-5);
  display: grid;
  gap: 10px;
}

.feature__list li {
  display: flex;
  gap: 10px;
  color: var(--text-2);
  font-size: 0.94rem;
  line-height: 1.65;
}

.feature__list .icon {
  width: 16px;
  height: 16px;
  margin-top: 6px;
  color: var(--accent);
  stroke-width: 2.5;
}

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

.feature__media {
  display: grid;
  gap: var(--space-4);
}

.feature__media img {
  width: 100%;
  /* 预留宽高比：这些图是 lazy 的，不预留的话每张加载完都会把下面的内容
     顶下去一次（CLS）。五张功能截图都是 2057×1466。 */
  aspect-ratio: 2057 / 1466;
  border-radius: var(--radius-md);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow-md);
  background: var(--surface-1);
}

/* 两张并排的截图；同一列下方还可以再放一张通栏的 */
.feature__media--pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}

.feature__media figcaption {
  margin-top: 10px;
  color: var(--text-2);
  font-size: 0.82rem;
  text-align: center;
}

/* 行情条截图只有 344×59，按原尺寸嵌在框里，拉伸会糊 */
.ticker-runway {
  display: grid;
  gap: var(--space-4);
  padding: var(--space-6);
  border: 1px dashed var(--hairline-strong);
  border-radius: var(--radius-md);
  background: var(--card-fill);
  box-shadow: var(--sheen);
  place-items: center;
}

.ticker-runway__label {
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.ticker-runway img {
  width: auto;
  max-width: 100%;
  /* 行情条截图是 344×59，不是上面那条 2057:1466 —— 必须关掉继承来的比例 */
  aspect-ratio: auto;
  border: none;
  box-shadow: var(--shadow-md);
  border-radius: 8px;
}

/* ── 表（轮询状态 / 技术栈） ── */
.poll,
.tech__table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--card-fill);
  box-shadow: var(--sheen);
  font-size: 0.94rem;
}

.poll th,
.poll td,
.tech__table th,
.tech__table td {
  padding: 13px 18px;
  text-align: left;
  border-bottom: 1px solid var(--hairline);
}

.poll tbody tr:last-child td,
.tech__table tr:last-child th,
.tech__table tr:last-child td {
  border-bottom: none;
}

.poll thead th {
  background: rgba(255, 255, 255, 0.03);
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

[data-theme="light"] .poll thead th {
  background: rgba(15, 23, 42, 0.03);
}

.poll td:first-child {
  color: var(--text-1);
  font-weight: 600;
  white-space: nowrap;
}

/* 轮询间隔是这张表的重点，给它终端里的高亮色 */
.poll td:nth-child(2) {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--accent);
  white-space: nowrap;
}

.poll td:last-child {
  color: var(--text-2);
}

.underside__grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: var(--space-4);
  margin-top: clamp(32px, 4vw, 48px);
}

.underside__item {
  padding: var(--space-5);
}

.underside__item h4 {
  font-size: 0.95rem;
  font-weight: 700;
  margin-bottom: 6px;
}

.underside__item p {
  color: var(--text-2);
  font-size: 0.86rem;
  line-height: 1.6;
}

/* ── Tech ── */
.tech__table th {
  width: 30%;
  color: var(--text-2);
  font-weight: 600;
  background: rgba(255, 255, 255, 0.02);
}

[data-theme="light"] .tech__table th {
  background: rgba(15, 23, 42, 0.02);
}

.tech__table td {
  font-family: var(--font-mono);
  font-size: 0.89rem;
  color: var(--text-1);
}

.tech__callout {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-6);
  margin-top: var(--space-8);
  padding: var(--space-6);
  text-align: center;
}

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

.tech__size b {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 1.6rem;
  font-weight: 700;
  line-height: 1.2;
}

.tech__size span {
  color: var(--text-2);
  font-size: 0.82rem;
}

/* 「5 MB」对「80 MB+」：赢的那边用品牌色，不用红/绿 —— 那两色在行情
   界面里意味着涨和跌。 */
.tech__size--win b {
  color: var(--accent);
  text-shadow: 0 0 28px var(--glow-accent);
}

.tech__size--lose b {
  color: var(--text-2);
  text-decoration: line-through;
  text-decoration-thickness: 2px;
}

.tech__vs {
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* ── Download ── */
.dl__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-4);
}

.dl__card {
  display: flex;
  flex-direction: column;
  padding: var(--space-6);
  transition: border-color var(--transition), transform var(--transition),
    background var(--transition);
}

.dl__card:hover {
  border-color: var(--hairline-strong);
  background: var(--card-fill-hover);
  transform: translateY(-2px);
}

.dl__card--featured {
  border-color: color-mix(in srgb, var(--accent) 42%, var(--hairline));
  box-shadow: var(--sheen), 0 0 40px -12px var(--glow-accent);
}

.dl__os {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
  font-size: 1.02rem;
}

.dl__os .icon {
  width: 18px;
  height: 18px;
  color: var(--text-2);
}

.dl__pkg {
  margin-top: var(--space-4);
  font-family: var(--font-mono);
  font-size: 0.86rem;
  color: var(--accent);
  word-break: break-all;
}

.dl__size {
  margin-top: var(--space-2);
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: 0.8rem;
}

.dl__note {
  margin-top: var(--space-3);
  color: var(--text-2);
  font-size: 0.86rem;
  flex: 1;
}

.dl__card .btn {
  margin-top: var(--space-5);
  width: 100%;
}

.dl__store {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  margin-top: var(--space-6);
  padding: var(--space-6);
}

.dl__store-text h3 {
  font-size: 1.05rem;
  font-weight: 700;
}

.dl__store-text p {
  margin-top: 6px;
  color: var(--text-2);
  font-size: 0.9rem;
}

.dl__steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-4);
  margin-top: clamp(40px, 5vw, 64px);
  counter-reset: step;
}

.dl__step {
  position: relative;
  padding: var(--space-5) var(--space-5) var(--space-5) 64px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  background: var(--card-fill);
  box-shadow: var(--sheen);
}

.dl__step::before {
  counter-increment: step;
  content: "0" counter(step);
  position: absolute;
  left: var(--space-5);
  top: var(--space-5);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--accent);
  opacity: 0.85;
}

.dl__step h4 {
  font-size: 0.98rem;
  font-weight: 700;
  margin-bottom: 6px;
}

.dl__step p {
  color: var(--text-2);
  font-size: 0.88rem;
}

/* ── FAQ ── */
.faq__list {
  max-width: 820px;
  margin: 0 auto;
  display: grid;
  gap: var(--space-3);
}

.faq__item {
  overflow: hidden;
  transition: border-color var(--transition);
}

.faq__item[open] {
  border-color: var(--hairline-strong);
}

.faq__item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5);
  font-weight: 600;
  font-size: 0.98rem;
  cursor: pointer;
  list-style: none;
  transition: background var(--transition);
}

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

.faq__item summary:hover {
  background: rgba(255, 255, 255, 0.03);
}

[data-theme="light"] .faq__item summary:hover {
  background: rgba(15, 23, 42, 0.03);
}

.faq__item summary::after {
  content: "";
  width: 9px;
  height: 9px;
  border-right: 2px solid var(--text-2);
  border-bottom: 2px solid var(--text-2);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--transition);
  flex-shrink: 0;
}

.faq__item[open] summary::after {
  transform: rotate(-135deg) translate(-2px, -2px);
  border-color: var(--accent);
}

.faq__body {
  padding: 0 var(--space-5) var(--space-5);
  color: var(--text-2);
  font-size: 0.94rem;
}

.faq__body a {
  border-bottom: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
}

/* ── Footer ── */
.footer {
  position: relative;
  border-top: 1px solid var(--hairline);
  background: rgba(0, 0, 0, 0.22);
  /* 底部多留 48px：右下角的回到顶部按钮是 fixed 的，滚到页尾时会压住
     版权行（按钮占据视口底部 24–70px 那一段）。与其在各个断点算容器
     右缘和按钮左缘谁先撞上谁，不如在页脚底部一次性让开。 */
  padding: clamp(48px, 6vw, 72px) 0 calc(var(--space-8) + 48px);
}

[data-theme="light"] .footer {
  background: rgba(15, 23, 42, 0.025);
}

/* 页脚顶边一道渐变线收尾 */
.footer::before {
  content: "";
  position: absolute;
  inset: -1px 0 auto 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--hairline-strong), transparent);
}

.footer__grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1.2fr;
  gap: var(--space-8);
}

.footer__brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
  font-size: 1.02rem;
}

.footer__brand img {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  box-shadow: 0 0 0 1px var(--hairline);
}

.footer__slogan {
  margin-top: var(--space-4);
  color: var(--text-2);
  font-size: 0.9rem;
  max-width: 260px;
}

.footer h4 {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-2);
  margin-bottom: var(--space-4);
}

.footer__links {
  display: grid;
  gap: 10px;
}

.footer__links a {
  color: var(--text-2);
  font-size: 0.9rem;
  transition: color var(--transition);
}

.footer__links a:hover {
  color: var(--accent);
}

/* 源图是一张竖版海报（上方群名、下方有效期），二维码只占约 60% 宽度 ——
   160px 时码本身只剩约 95px，屏幕上不好扫。 */
.footer__qr {
  text-align: center;
}

.footer__qr img {
  width: 180px;
  /* 预留比例的理由不只是 CLS：回到顶部的进度环按 scrollHeight 算，页面高度
     必须在加载前后一致，否则分母会在图片加载完时突然变大。 */
  aspect-ratio: 1146 / 1661;
  margin: 0 auto;
  border-radius: var(--radius-md);
  background: #fff;
  padding: 6px;
  box-shadow: 0 0 0 1px var(--hairline);
}

.footer__qr span {
  display: block;
  margin-top: 10px;
  color: var(--text-2);
  font-size: 0.82rem;
}

.footer__bottom {
  margin-top: clamp(40px, 5vw, 56px);
  padding-top: var(--space-6);
  border-top: 1px solid var(--hairline);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  justify-content: space-between;
  color: var(--text-2);
  font-size: 0.84rem;
}

.footer__bottom p {
  max-width: 640px;
}

/* ── 回到顶部 ──
   fixed 在右下角，滚过 3/4 屏后淡入，外圈一圈滚动进度环。做成
   <a href="#top"> 而不是 <button>：滚动交给片段导航与
   html{scroll-behavior:smooth}，禁用 JS 时它照样能用。顺带避开一个坑 ——
   若它是按钮，「滚到顶就隐藏」意味着点击后按钮在持有焦点时被藏起来，
   焦点会掉到 body；锚点导航则把顺序焦点起点移到目标处。

   形状与轮播箭头一致（圆角矩形），所以右下角这两个悬浮控件是同一套东西。 */
.to-top {
  --lift: 0px;
  --press: 1;
  position: fixed;
  right: 24px;
  bottom: calc(24px + env(safe-area-inset-bottom, 0px));
  z-index: 90;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  /* 位移/缩放/按压合成在一条 transform 上，靠变量切换状态 —— 否则
     .is-visible 的特异性会盖掉 :active 的缩放，按下去没有反馈。 */
  transform: translateY(var(--lift)) scale(var(--press));
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--surface-1) 88%, transparent);
  backdrop-filter: saturate(160%) blur(12px);
  -webkit-backdrop-filter: saturate(160%) blur(12px);
  box-shadow: var(--sheen), var(--shadow-md);
  color: var(--text-1);
  font-size: 17px;
  transition: opacity var(--transition), transform var(--transition),
    visibility var(--transition), color var(--transition),
    border-color var(--transition), box-shadow var(--transition);
}

.to-top:hover {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  box-shadow: var(--sheen), var(--shadow-md), 0 0 24px -6px var(--glow-accent);
}

.to-top:active {
  --press: 0.96;
}

/* 悬浮提示。读 aria-label，所以可见文案与无障碍名称是同一个字符串，不会
   分家；不是 title 属性 —— title 有约 1 秒延迟、样式不可控、触摸设备上根本
   不出现。这里 hover 与键盘 focus 都会出，且零 JS。放在按钮左侧：它在屏幕
   右缘，往右会出界。 */
.to-top::after {
  content: attr(aria-label);
  position: absolute;
  right: calc(100% + 12px);
  top: 50%;
  transform: translateY(-50%) translateX(4px);
  padding: 6px 10px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--surface-2) 96%, transparent);
  box-shadow: var(--shadow-md);
  color: var(--text-1);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--transition), transform var(--transition);
}

/* 指向按钮的小尖角 */
.to-top::before {
  content: "";
  position: absolute;
  right: calc(100% + 7px);
  top: 50%;
  width: 8px;
  height: 8px;
  transform: translateY(-50%) rotate(45deg);
  border-top: 1px solid var(--hairline);
  border-right: 1px solid var(--hairline);
  background: color-mix(in srgb, var(--surface-2) 96%, transparent);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--transition);
}

.to-top:hover::after,
.to-top:focus-visible::after {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
}

.to-top:hover::before,
.to-top:focus-visible::before {
  opacity: 1;
}

/* 进度环。从 12 点方向起画，所以要整体转 -90°。 */
.to-top__ring {
  position: absolute;
  inset: 4px;
  width: calc(100% - 8px);
  height: calc(100% - 8px);
  transform: rotate(-90deg);
  pointer-events: none;
}

.to-top__track,
.to-top__bar {
  fill: none;
  stroke-width: 1.5;
}

.to-top__track {
  stroke: var(--hairline-strong);
}

/* dasharray / dashoffset 由 app.js 按真实周长设置；这里给一个「进度为 0」
   的初值，禁用 JS 时环就是空的，不会画出一段假的进度。 */
.to-top__bar {
  stroke: var(--accent);
  stroke-linecap: round;
  stroke-dasharray: 100.53;
  stroke-dashoffset: 100.53;
}

/* 与 .reveal 同一套门控：<head> 的内联脚本给 <html> 加 .js，只有 JS 真在跑
   时才做「随滚动淡入」；脚本没跑就常显，不会变成一个永远点不到的按钮。 */
.js .to-top {
  --lift: 10px;
  opacity: 0;
  visibility: hidden;
}

.js .to-top.is-visible {
  --lift: 0px;
  opacity: 1;
  visibility: visible;
}

/* ================================================================
   内容页（faq / download / changelog / guide/*）

   这些页面共用首页那套 token 与顶栏页脚，只是版式换成阅读型：一个标题区、
   一条正文列、必要时加卡片网格。顶栏是 fixed 的，而内容页没有 hero 撑高度，
   所以 .page-head 自己让出 nav 的空间。
   ================================================================ */

.page-head {
  padding: calc(var(--nav-height) + clamp(40px, 6vw, 64px)) 0 clamp(28px, 4vw, 40px);
}

.page-head__title {
  font-size: clamp(1.7rem, 3.6vw, 2.4rem);
  font-weight: 700;
  letter-spacing: -0.02em;
}

.page-head__lede {
  margin-top: var(--space-4);
  max-width: 46em;
  color: var(--text-2);
  font-size: 1.02rem;
}

/* 面包屑只出现在 guide/*：那是全站唯一的三级路径。平铺的页面用不到，
   硬加反而是噪音（见 ux 规则的 breadcrumb-web：3+ 层才用）。 */
.crumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: var(--space-5);
  font-family: var(--font-mono);
  font-size: 0.76rem;
  letter-spacing: 0.06em;
  color: var(--text-2);
}

.crumb a { color: var(--text-2); }
.crumb a:hover { color: var(--accent); }
.crumb i { font-style: normal; color: var(--hairline-strong); }

/* 正文列。中文每行 35–45 字最省眼，680px 在 17px 下正好落在这一带 ——
   比首页那种 1072px 的通栏窄得多，那宽度读长文会来回找行首。 */
.prose {
  max-width: 680px;
  font-size: 1rem;
  line-height: 1.8;
  color: var(--text-2);
}

.prose > * + * { margin-top: var(--space-5); }

.prose h2 {
  margin-top: clamp(36px, 5vw, 52px);
  padding-bottom: 10px;
  border-bottom: 1px solid var(--hairline);
  font-size: 1.22rem;
  font-weight: 700;
  color: var(--text-1);
}

.prose h3 {
  margin-top: var(--space-6);
  font-size: 1.02rem;
  font-weight: 700;
  color: var(--text-1);
}

.prose strong { color: var(--text-1); font-weight: 600; }
.prose a { border-bottom: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); }
.prose ul { padding-left: 1.25em; list-style: disc; }
.prose ol { padding-left: 1.5em; list-style: decimal; }
.prose li { margin-top: 8px; }
.prose li::marker { color: var(--text-2); }

.prose code {
  padding: 2px 6px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-xs);
  /* 用 color-mix 而不是写死的白色叠加：浅色主题下 rgba(255,255,255,.04)
     在白底上等于没有 */
  background: color-mix(in srgb, var(--text-1) 7%, transparent);
  font-family: var(--font-mono);
  font-size: 0.86em;
  /* 正文色而不是强调色：强调色在这段正文里是**链接**的颜色，代码再用它就
     分不清哪个能点了。而且强调色压在这层 7% 底色上，浅色主题只有 4.51:1，
     贴着 4.5 的线；正文色是 14:1。等宽字体本身已经把代码和正文分开了。 */
  color: var(--text-1);
  /* 命令不能在中间断行 —— 断成两行的 `chmod` / `+x` 复制出去是错的 */
  white-space: nowrap;
}

/* 提示块。左侧那道竖条是形状不是颜色，去掉颜色也还读得出来。 */
.note {
  padding: var(--space-5);
  border: 1px solid var(--hairline);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
  background: var(--card-fill);
  box-shadow: var(--sheen);
  font-size: 0.94rem;
}

/* 卡片网格：下载页的平台卡、指南索引都用它 */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(258px, 1fr));
  gap: var(--space-4);
}

.card {
  display: block;
  padding: var(--space-6);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  background: var(--card-fill);
  box-shadow: var(--sheen);
  color: inherit;
  transition: border-color var(--transition), background var(--transition),
    transform var(--transition);
}

a.card:hover {
  border-color: var(--hairline-strong);
  background: var(--card-fill-hover);
  transform: translateY(-2px);
}

.card h3 { font-size: 1.02rem; font-weight: 700; color: var(--text-1); }
.card p { margin-top: 8px; color: var(--text-2); font-size: 0.92rem; }

.card__meta {
  display: block;
  margin-top: var(--space-4);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-2);
}

/* ── 更新日志（由 site-assets.mjs 从 CHANGELOG.md 生成） ── */
.release + .release { margin-top: clamp(36px, 4vw, 52px); }

.release__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-3);
  padding-bottom: 10px;
  border-bottom: 1px solid var(--hairline);
}

.release__version {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--accent);
}

.release__date { color: var(--text-2); font-size: 0.85rem; }
.release__section { margin-top: var(--space-5); }

/* 版本号是 h2（层级上对），但分隔线画在 .release__head 上，这里要撤掉
   .prose h2 自带的那条，否则同一条线画两遍 */
.prose .release__version {
  margin-top: 0;
  padding-bottom: 0;
  border-bottom: none;
}

.release__kind {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-2);
}

.release ul { margin-top: 10px; padding-left: 0; list-style: none; }

.release li {
  position: relative;
  padding-left: 18px;
  margin-top: 8px;
  color: var(--text-2);
  font-size: 0.94rem;
}

/* 等宽短横代替默认圆点：与终端的视觉语言一致，也不依赖字体画不画得出圆点 */
.release li::before {
  content: "–";
  position: absolute;
  left: 0;
  font-family: var(--font-mono);
  color: var(--text-3);
}

/* ── 当前页高亮 ──
   **刻意不做「淡色底块 + 通栏下划线」那一套。** 那是模板与生成式工具的默认
   答案；而且两个信号互相打架 —— 底块已经说了「就是这里」，再压一条粗线是
   重复，合起来还会被读成一颗带下边框的按钮。技能库里那条规则的原话也只是
   「Highlight active nav item with color/underline」，没有底块。这里只留
   一个信号：标签提亮 + 一条与文字等宽的渐隐短横。

   状态收进一个 `--current` 变量，颜色与指示器都从它派生 —— 于是「哪个
   data-page 对应哪个导航项」这份清单**只写一遍**。拆成两个选择器块的话，
   两份清单迟早对不上，而症状只是某一页的指示器没出现，没人会发现。

   **不能写进顶栏那段 HTML**：它必须在所有页面逐字节相同，由
   site-assets.mjs 校验。所以状态挂在 <body data-page> 上。

   加新页面时给它一个 data-page 值并在下面登记一行。这里没有 download：
   它的入口是顶栏那颗常驻 CTA 按钮，不是导航项，硬凑一个选择器只会是死代码。 */
body[data-page="home"] .nav__link[href$="index.html#features"],
body[data-page="faq"] .nav__link[href$="faq.html"],
body[data-page="changelog"] .nav__link[href$="changelog.html"],
body[data-page="guide"] .nav__link[href$="guide/"] {
  --current: 1;
  color: var(--text-1);
}

/* ── 入场（需要 app.js 给 <html> 加 .js） ── */
.js .reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 700ms var(--ease-out-expo), transform 700ms var(--ease-out-expo);
}

.js .reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* ── Responsive ── */
@media (max-width: 1024px) {
  .pains__grid,
  .highlights__grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .underside__grid {
    grid-template-columns: repeat(3, 1fr);
  }

  .dl__grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .footer__grid {
    grid-template-columns: 1fr 1fr;
    gap: var(--space-6);
  }
}

@media (max-width: 860px) {
  .nav__links {
    display: none;
    position: absolute;
    top: var(--nav-height);
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    padding: var(--space-3);
    margin: 0;
    background: var(--page-top);
    border-bottom: 1px solid var(--hairline);
    box-shadow: var(--shadow-md);
  }

  .nav__links.is-open {
    display: flex;
  }

  .nav__link {
    padding: 12px 14px;
    font-size: 1rem;
  }

  /* 手机菜单是竖排列表，横向下划线在这里既没有方向感、又会因为
     align-items: stretch 被拉成通栏。改成左侧竖条 —— 竖排列表里用竖条，
     横排里用横线，这是同一个「方向跟着布局走」的规则。 */
  .nav__link::after {
    left: 0;
    right: auto;
    top: 50%;
    bottom: auto;
    width: 2px;
    height: 18px;
    margin-top: -9px;
    border-radius: 0 1px 1px 0;
    background: var(--accent);
  }

  .nav__burger {
    display: inline-flex;
  }

  .feature,
  .feature--reverse {
    grid-template-columns: minmax(0, 1fr);
  }

  /* 单列时文案始终在上，不论图片原本在哪一侧 */
  .feature--reverse .feature__media {
    order: 0;
  }

  .dl__steps {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 620px) {
  .container {
    padding: 0 18px;
  }

  /* 顶栏比页面其余部分更早挤满：品牌名 + GitHub + 主题 + 下载 + 汉堡合计
     要 ~400px，360–390px 的手机没有。去掉 GitHub 文案、收紧间距，图标仍在。 */
  .nav__inner {
    gap: var(--space-3);
  }

  .nav__actions {
    gap: var(--space-1);
  }

  .nav__gh {
    padding: 7px 8px;
  }

  .nav__gh-label {
    display: none;
  }

  .pains__grid,
  .highlights__grid,
  .underside__grid,
  .dl__grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .poll th:nth-child(3),
  .poll td:nth-child(3) {
    display: none;
  }

  .hero__cta .btn {
    width: 100%;
  }

  .feature__media--pair {
    grid-template-columns: minmax(0, 1fr);
  }

  .dl__store {
    flex-direction: column;
    align-items: stretch;
    text-align: center;
  }

  .footer__grid {
    grid-template-columns: 1fr;
  }

  .footer__qr {
    text-align: left;
  }

  .footer__qr img {
    margin: 0;
  }
}

@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;
  }

  .js .reveal {
    opacity: 1;
    transform: none;
  }

  .btn:hover,
  .highlight:hover,
  .dl__card:hover {
    transform: none;
  }

  /* 漂移的光斑对前庭敏感的人不友好，直接停住 */
  .hero::before {
    animation: none;
  }
}
