/* ═══════════════════════════════════════════════════════════════════════
   糖葫芦 Tanghulu · 官网原型样式表（首页 + 邀请奖励 / 合作共赢子页共用）
   本版形式即主张，两条原创线索：
     ① 左侧竖向「坐标轴导航」把章节当刻度；页面底是近黑蓝 + 星野，不再铺整页网格底纹。
     ② 产品介绍只有一块舞台：右侧目录点一项，左侧舞台就换一块界面，舞台与目录垂直居中对齐。
   气质：深色专业金融工具站——克制、层级清晰、边框优先于阴影，红色只属于品牌 logo。
   零构建、零外链：字体走系统栈，图片只引用本地 assets。
   ═══════════════════════════════════════════════════════════════════════ */

/* ── 设计令牌 ─────────────────────────────────────────────────────── */
:root {
  /* 底色与表面：两层近黑蓝拉开纵深，surface 用白通道叠加而非实色，
     这样任何背景（纯色/画布底纹）之上都能保持同一套层级关系 */
  --bg-0: #010512;
  --bg-1: #06133D;
  --surface-1: rgba(255, 255, 255, .03);
  --surface-2: rgba(255, 255, 255, .055);
  --border: rgba(255, 255, 255, .08);
  --border-strong: rgba(95, 146, 255, .35);

  --text-1: #E9EEF8;
  --text-2: #9FB0CC;
  --text-3: #6B7C99;

  --accent: #5F92FF;
  --accent-soft: rgba(95, 146, 255, .14);
  --candy: #EF4444; /* 品牌红：只属于 logo 本身，页面装饰与交互态一律不取用 */

  /* 与 preview_core.js PALETTE.bg 同值：canvas 拿不到 CSS 变量，两边只能各留一份镜像。
     舞台底色与画布落笔底色对齐后，尺寸重算或首帧未落笔的瞬间不会闪出一块亮底 */
  --stage-bg: #080D1A;

  /* 派生通道：需要自定义透明度的地方从 -rgb 走，避免散落硬编码色值 */
  --bg-0-rgb: 1, 5, 18;
  --bg-1-rgb: 6, 19, 61;
  --accent-rgb: 95, 146, 255;
  --text-3-rgb: 107, 124, 153;
  --ink-rgb: 255, 255, 255;
  --on-accent: #04102B; /* accent 实底上的字色，保证 AA 对比度 */

  --sp-4: 4px;
  --sp-8: 8px;
  --sp-12: 12px;
  --sp-16: 16px;
  --sp-20: 20px;
  --sp-24: 24px;
  --sp-32: 32px;
  --sp-40: 40px;
  --sp-48: 48px;
  --sp-64: 64px;
  --sp-80: 80px;
  --sp-96: 96px;

  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 20px;
  --r-pill: 999px;

  --maxw: 1200px;
  --gutter: var(--sp-24);
  --header-h: 64px;
  --stage-chrome: 36px; /* 舞台顶栏高度：canvas 与实机素材都要 inset 到它之下，只此一处定义 */

  --dur: 180ms;
  --ease: cubic-bezier(.2, .8, .3, 1);

  --font-sans: system-ui, -apple-system, "Segoe UI", "Microsoft YaHei", "PingFang SC", "Noto Sans SC", "Hiragino Sans GB", sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Consolas, monospace;
}

/* ── 全局基座 ─────────────────────────────────────────────────────── */
* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

/* 锚点跳转要避开吸顶头部，多留一口气 */
:where([id]) { scroll-margin-top: calc(var(--header-h) + var(--sp-24)); }

body {
  margin: 0;
  background: var(--bg-0);
  color: var(--text-2);
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* 必须是 clip 不能是 hidden：hidden 会让 body 变成滚动容器，
     吸顶头部的 sticky 就失去参照系、钉不住 */
  overflow-x: clip;
}

img { max-width: 100%; }

/* 显式写出：showcase.js 靠 hidden 属性收放实机截图与录屏，
   任何给这些元素写 display 的规则都会把它作废（见 .stage__media 注释） */
[hidden] { display: none; }

h1, h2, h3 { margin: 0; }

p { margin: 0; }

ul, ol { margin: 0; padding: 0; list-style: none; }

figure { margin: 0; }

a { color: inherit; }

/* 焦点环统一：轮廓自动贴合元素圆角，不额外改形状 */
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ── 通用控件 ─────────────────────────────────────────────────────── */
/* 跳转链接：默认移出视口，键盘聚焦时回到左上角 */
.skip-link {
  position: fixed;
  top: var(--sp-12);
  left: -9999px;
  z-index: 200;
  padding: 10px var(--sp-16);
  border-radius: var(--r-sm);
  background: var(--accent);
  color: var(--on-accent);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
}

.skip-link:focus { left: var(--sp-12); }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-8);
  height: 40px;
  padding: 0 var(--sp-20);
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  font: inherit;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--dur) var(--ease),
              background-color var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease);
}

.btn--primary {
  background: var(--accent);
  color: var(--on-accent);
}

.btn--primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 10px 26px -10px rgba(var(--accent-rgb), .7);
}

.btn--ghost {
  background: transparent;
  border-color: var(--border);
  color: var(--text-1);
}

.btn--ghost:hover {
  border-color: var(--border-strong);
  background: var(--accent-soft);
}

.btn--sm { height: 34px; padding: 0 var(--sp-16); font-size: 13px; }

.btn--lg { height: 48px; padding: 0 28px; font-size: 16px; }

.chip-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-8);
  margin-top: var(--sp-24);
}

.chip {
  padding: 6px 14px;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--surface-1);
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-2);
  transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

.chip:hover {
  border-color: var(--border-strong);
  color: var(--text-1);
}

/* 内容层抬到入场画布之上：.hero-stage 是 z-index:0 的定位元素，
   不给内容层定位，正文就会被它压在下面 */
main,
.site-footer {
  position: relative;
  z-index: 1;
}

/* ── 站点头部与品牌 ───────────────────────────────────────────────── */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  height: var(--header-h);
  background: rgba(var(--bg-0-rgb), .72);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border);
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--sp-32);
  height: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.site-header__actions {
  display: flex;
  align-items: center;
  gap: var(--sp-12);
  margin-left: auto;
}

.brand {
  display: inline-flex;
  align-items: baseline;
  gap: var(--sp-8);
  text-decoration: none;
}

/* logo 自带品牌红，不做任何染色或滤镜；22% 圆角与真机 TanghuluLogo 的 ClipRRect 同比（squircle） */
.brand__mark {
  align-self: center;
  width: 24px;
  height: 24px;
  display: block;
  border-radius: 22%;
}

.brand__mark--sm { width: 18px; height: 18px; }

.brand__word {
  font-size: 17px;
  font-weight: 700;
  line-height: 1;
  color: var(--text-1);
}

.brand__word--sm { font-size: 15px; }

.brand__latin {
  font-size: 12px;
  letter-spacing: .1em;
  line-height: 1;
  color: var(--text-3);
}

.site-nav {
  display: flex;
  align-items: center;
  gap: var(--sp-24);
}

.site-nav__link {
  font-size: 14px;
  color: var(--text-2);
  text-decoration: none;
  transition: color var(--dur) var(--ease);
}

.site-nav__link:hover { color: var(--text-1); }

/* 子页当前态：用一个短下划线而非底色药丸——顶栏是安静区，加底色会把导航变成第二组按钮 */
.site-nav__link.is-current {
  position: relative;
  color: var(--text-1);
}

.site-nav__link.is-current::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -7px;
  height: 2px;
  background: var(--accent);
}

/* 子页返回链接：只做一个方向指示，不做按钮——它是退路不是行动号召 */
.page-nav__back {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--accent);
  text-decoration: none;
  transition: opacity var(--dur) var(--ease);
}

.page-nav__back::before { content: "←"; }

.page-nav__back:hover { opacity: .74; }

/* ── Hero ─────────────────────────────────────────────────────────── */
/* 单列居中：品牌表达整段交给入场时序（奔跑→聚成 Tanghulu→抬升让位文案），
   首屏不再放右侧图腾，也就不需要三列栅格与那层向右淡出的暗幕 */
.hero {
  position: relative;
  z-index: 0;
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-content: center;
  text-align: center;
  min-height: calc(100vh - var(--header-h));
  min-height: calc(100svh - var(--header-h));
  padding: clamp(40px, 5vw, 72px) var(--gutter) clamp(56px, 7vw, 96px);
}

/* 首屏背景极光：流体光晕引擎（aurora_glow.js）逐像素渲染——绿→青→蓝→紫
   无级光雾绕演示窗身后的发散点海带式摆动。容器只负责定位与上下缘收边
   幕罩；亮度包络与构图在引擎里做，不再有 CSS 光片。品牌红不进这层。 */
.hero__aurora {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(
    to bottom,
    transparent 0%,
    #000 14%,
    #000 82%,
    transparent 99%
  );
  mask-image: linear-gradient(
    to bottom,
    transparent 0%,
    #000 14%,
    #000 82%,
    transparent 99%
  );
}

.hero__aurora-cv {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.hero__content {
  position: relative;
  z-index: 2;
  width: min(100%, 1100px);
  min-width: 0;
  margin-inline: auto;
}

/* 首屏唯一一行文案：产品定位当大字标题（原主标题/支持文案/双行动/跨端说明整组撤下，
   叙事让位给下方的真机演示——画面自己会讲） */
.hero__headline {
  margin: 0 auto;
  font-size: clamp(30px, 4.3vw, 62px);
  font-weight: 700;
  letter-spacing: .08em;
  line-height: 1.25;
  color: var(--text-1);
}

/* ── 首屏工作台演示：场景=应用窗本身（1440×900），舞台即窗口剪影 ──
   外圈桌面壳已撤（读作"窗口套窗口"）；上限 1440 = 场景原尺，fit=1 时文字最清晰，
   比例锁死只随视口整体等比。窗后横光已撤——那层会在窗腰铺出一条雾带。 */
.hero__demo {
  position: relative;
  z-index: 1;
  width: 100%;
  margin-top: clamp(30px, 4vw, 52px);
}

.hero__stage {
  position: relative;
  max-width: 1440px;
  margin: 0 auto;
  aspect-ratio: 1440 / 900;
  overflow: hidden;
  border-radius: var(--r-sm);   /* 与窗壳 .lw__win 的 8px 同值：舞台剪影就是窗口本身 */
  background: #05070B;          /* 与顶栏/导航轨同色，缩放亚像素缝不露异色 */
  /* 贴体只留受光描边 + 深度投影；彩色光晕全部交给极光层（均匀 box-shadow 光环显廉价，已撤） */
  box-shadow:
    0 0 0 1px rgba(var(--accent-rgb), .2),
    0 30px 90px -20px rgba(0, 0, 0, .7);
}

.hero__mount {
  position: absolute;
  inset: 0;
}

/* 诚实标注：本组件没有真机底片可对，措辞只敢说"按源码重建"，不说"像素对位" */
.hero__stamp {
  position: absolute;
  right: 12px;
  bottom: 10px;
  z-index: 2;
  padding: 5px 10px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: rgba(var(--bg-0-rgb), .72);
  font-size: 11px;
  line-height: 1.5;
  color: var(--text-3);
}

.hero__acts {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--sp-12);
  max-width: 1560px;
  margin: var(--sp-20) auto 0;
  padding: 0;
  list-style: none;
  text-align: left;
}

/* 坐标轴导航连刻度带章节名占 112px，且只在 >1400px 时显示（见文末响应式）。
   首屏演示是通栏，得自己让开这 112px——其余区块靠 1200 容器宽天然让开 */
@media (min-width: 1401px) {
  .hero__demo { padding-inline: 112px; }
}

@media (max-width: 900px) {
  .hero__acts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ── 首屏图腾：暗处的豹首 ─────────────────────────────────────────── */
/* 掠食者比例的剪影：平顶颅骨、角面收口，宽高约 1.45:1，所以这里不是方框。
   框比剪影再扁一点（1.38）留出上下余量，让眼部溢出的光与耳瓣不被裁掉。
   右缘不再对齐 1200 容器而是贴到 gutter：豹首是背景装置，让它多占 96px 才够大到一眼认得出。
   宽度里的 `100% - 790px` 是给 h1 留的硬净空——标题两行里最长的一行实测 594px，
   加左右留白后 790px 是它的不可侵占带，图腾只能在剩下的空间里取 46% */
.totem {
  position: absolute;
  z-index: 0;
  top: 50%;
  right: var(--gutter);
  width: clamp(300px, min(46%, 100% - 790px), 700px);
  aspect-ratio: 1.38;
  transform: translateY(-50%);
  pointer-events: none;
}

/* 画布铺满图腾框：图腾由 totem.js 用点与线实时绘制，线网本身就是从底色里长出来的，
   既没有"图片边界"要抹，也不需要外圈表盘来把它框住——圆盘反而会把豹首关进一个装饰壳里 */
.totem__canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

/* ── 首屏入场与背景星野：两块画布都铺满视口 ───────────────────────
   星野压在 -1 层（body 底色由根画布承担，负层因此可见）；入场画布留在 0 层，
   与 .hero 同级但 DOM 在前，所以粒子在首屏文案之下、星野之上。
   绽放的粒子云远大于首屏盒子，钉进 .hero 会被它的 overflow:hidden 削出边框，故挂 body。 */
.starfield {
  position: fixed;
  inset: 0;
  z-index: -1;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.hero-stage {
  position: fixed;
  inset: 0;
  z-index: 0;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.hero__wordmark {
  width: min(100%, 1100px);
  height: clamp(150px, 20vw, 240px);
  margin: 0 auto var(--sp-32);
}
/* 字标口径与 GPT 版逐字对齐（font: 900 "Segoe UI" + 同一组 clamp）：
   粒子引擎按这个 DOM 掩码取点，点数预算固定时笔画粒子宽 ∝ √字重系数——
   900 的竖笔是 6 粒子宽，800 只有 5，这就是"字体偏细"的根源，不是引擎参数 */
.hero__wordmark-text {
  display: grid;
  height: 100%;
  place-items: center;
  font: 900 clamp(72px, 14vw, 210px)/1 "Segoe UI", sans-serif;
  color: var(--text-1);
}
@media (max-width: 900px) { .hero__wordmark { height: clamp(130px, 23vw, 180px); } }
@media (max-width: 600px) { .hero__wordmark { height: clamp(110px, 27vw, 150px); } }
@media (max-width: 390px) { .hero__wordmark { height: 104px; } }
/* 入场期间字标由画布粒子承担，DOM 文案退为可读回退；无脚本时保持原样可见 */
.hero.is-intro .hero__wordmark-text {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.hero.is-intro .hero__headline,
.hero.is-intro .hero__demo,
.hero.is-intro .hero__aurora {
  opacity: 0;
  transform: translateY(22px);
}
.hero.is-intro .hero__aurora { transform: none; }
.hero.is-intro.is-intro-done .hero__headline,
.hero.is-intro.is-intro-done .hero__demo,
.hero.is-intro.is-intro-done .hero__aurora {
  opacity: 1;
  transform: none;
  transition: opacity .5s ease, transform .55s cubic-bezier(.2, .7, .2, 1);
}
.hero.is-intro.is-intro-done .hero__demo { transition-delay: .14s; }
.hero.is-intro.is-intro-done .hero__aurora { transition-delay: .08s; }

/* ── 功能演示：左侧舞台固定，右侧目录点击切换 ─────────────────────── */
.showcase {
  border-top: 1px solid var(--border);
  padding: clamp(64px, 8vw, 108px) var(--gutter) clamp(48px, 6vw, 88px);
}

.showcase__head {
  max-width: var(--maxw);
  margin-inline: auto;
  text-align: center;
}

.showcase__head .section__lede { margin-inline: auto; }

.showcase__inner {
  display: grid;
  /* 66% 是硬约束不是审美取舍：workspace 面板在画布宽 < 780px 时不绘制五档盘口，
     而 01 项文案明说了「盘口」——版面必须让画面兑现文案。1200 容器下 66% = 792px，
     扣掉两条 1px 边框仍有 790px 落在阈值之上 */
  grid-template-columns: minmax(0, 66%) minmax(0, 1fr);
  gap: clamp(28px, 3.4vw, 56px);
  /* 目录六项恒比舞台高，默认的 stretch/start 会把舞台顶在上沿——
     两栏垂直居中，视线在"看画面"与"读目录"之间来回时不需要上下找 */
  align-items: center;
  max-width: var(--maxw);
  margin: clamp(36px, 4.4vw, 64px) auto 0;
}

.showcase__stage {
  position: relative;
  overflow: hidden;
  min-width: 0;
  /* 用比例定高而不是视口高度：100svh 会让舞台跟着浏览器工具栏伸缩，
     矮屏上还会把整节顶出屏外，"上下居中"就名存实亡 */
  aspect-ratio: 16 / 10;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--stage-bg);
  box-shadow: 0 30px 80px -50px rgba(var(--bg-0-rgb), .95),
              0 0 110px -54px rgba(var(--accent-rgb), .85);
}

.stage__chrome {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: var(--sp-12);
  height: var(--stage-chrome);
  padding-inline: 14px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
}

.stage__dots {
  display: inline-flex;
  gap: 6px;
}

/* 冷灰圆点：交通灯配色会把"专业工作台"读成玩具窗口 */
.stage__dots > i {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: rgba(var(--text-3-rgb), .45);
}

/* 绝对居中而非 margin:auto：左侧圆点组与右侧药丸宽度悬殊，
   按剩余空间分配会把标题明显推偏；标题文本随目录切换而变，居中点不能跟着漂 */
.stage__title {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  font-size: 13px;
  line-height: 1.4;
  white-space: nowrap;
  color: var(--text-1);
  transition: opacity var(--dur) var(--ease), color var(--dur) var(--ease);
}

/* 宽度由内容自适应：药丸文本在「结构演示 / 实机截图 / 实机演示」之间切换，
   写死宽度会在切换瞬间跳版，而它右缘贴着 margin-left:auto 的边，涨缩不影响任何人 */
.stage__badge {
  margin-left: auto;
  padding: 3px 10px;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--surface-1);
  font-size: 11px;
  line-height: 1.5;
  white-space: nowrap;
  color: var(--text-3);
  transition: color var(--dur) var(--ease);
}

.stage__canvas {
  position: absolute;
  inset: var(--stage-chrome) 0 0 0;
  display: block;
  width: 100%;
  height: calc(100% - var(--stage-chrome));
  cursor: crosshair; /* 画布内有十字线读数，指针形态先把"这里能动"说出来 */
}

.stage__canvas.is-hidden { display: none; }

/* 刻意不写 display：实机素材就位时 showcase.js 只是摘掉 hidden 属性，
   任何 display 声明都会盖掉 hidden，缺素材时这块空壳会顶在画布上 */
/* contain 而不是 cover：真机截图的价格轴与图例就贴在四边，cover 为填满会横向裁掉约 4%，
   右缘的价格刻度首当其冲。截图比例 16:9 与舞台留给素材的 1.73 只差一点，contain 在桌面档
   上下各留约 9px，而截图底色（#070A0D）与舞台底色几乎同色，这条边看不出来 */
.stage__media {
  position: absolute;
  inset: var(--stage-chrome) 0 0 0;
  width: 100%;
  height: calc(100% - var(--stage-chrome));
  object-fit: contain;
}

/* 矢量演示层是真机场景的 1:1 重建，自带底色并按护栏自行定位内部 canvas 与铬层；
   object-fit 只对替换元素有意义，这里是普通容器，写了反而误导 */
.stage__vector {
  object-fit: initial;
  background: #05070B;   /* 与应用窗口外壳同色，缩放留白处不露出异色 */
}

/* 应用窗口：按自然尺寸布局，再整体等比缩小居中；页面组件收到同一个系数自行折算背板 */
.stage__win {
  position: absolute;
  left: 50%;
  top: 50%;
  transform-origin: center center;
}

/* 矢量演示自带真机窗口外壳，舞台这层「三点+标题+描边+底色」就成了第二层窗——
   摘掉边框/圆角/底色，窗口以 16:10 与舞台等比铺满，不留一圈空。
   外发光留着：它落在盒子之外，不构成第二层窗框，反而给窗口托底 */
.showcase__stage.is-bare {
  border: 0;
  border-radius: 0;
  background: none;
}
.showcase__stage.is-bare .stage__chrome { display: none; }
.showcase__stage.is-bare .stage__media { inset: 0; height: 100%; }

/* 纯截图舞台：素材本身就是整幅真机图，舞台不挂仿窗口顶栏——
   canvas 与实机素材直接铺满整幅舞台；挂不挂顶栏由各区块 DOM 自定，
   机制侧 showcase.js 对有无 [data-stage-title] 两种形态通用 */
.showcase__stage.is-chromeless .stage__canvas,
.showcase__stage.is-chromeless .stage__media { inset: 0; height: 100%; }
/* 舞台比例与烘焙底片严格同比对（bake_shots 统一 1600 宽，本批高 892）：
   contain 只有在比率重合时才真正满幅，否则上下各留一条同色带，看着像第二层边框 */
.showcase__stage.is-chromeless { aspect-ratio: 1600 / 892; }

/* 诚实标注跟着搬出来：浮在窗口角上，不再寄居于舞台标题栏 */
.stage__stamp {
  position: absolute;
  right: 12px;
  bottom: 10px;
  z-index: 2;
  padding: 5px 10px;
  border-radius: var(--r-sm);
  background: rgba(var(--bg-0-rgb), .72);
  border: 1px solid var(--border);
  font-size: 11px;
  line-height: 1.4;
  color: var(--text-3);
  white-space: nowrap;
  pointer-events: none;
}

.showcase__list {
  position: relative;
  display: grid;
  gap: var(--sp-8);
  align-content: start;
  min-width: 0;
  /* 滚轮式目录：窗口约三条目高，选中项由 showcase.js 滚到视口正中。
     目录是选择器不是正文列，全部展开会把右列撑得比舞台高出一截，
     两栏上下居中后视线在「看画面」和「读目录」之间没有共同锚点。
     这里的 15rem/6rem 是无脚本兜底与最矮窗口；实际窗口由 showcase.js 按内容
     定高——介绍超过两行的条目展开更高，写死窗口会把邻项标题裁出可视区 */
  height: 15rem;
  padding-block: 6rem;   /* 首尾项也要能滚到正中：上下各留出半屏余量 */
  /* 不开手动滚动：列表只随点击/键盘切换由 JS 滑动定位（hidden 不影响
     程序化 scrollTo），滚轮滚目录会跟舞台换页抢注意力 */
  overflow: hidden;
}

/* 整块可点：标题与介绍都在按钮里，指针不必去瞄一行小字。
   不给边框与底色：选中靠放大 + 变色 + 左缘竖条表达，目录是文字不是卡片 */
.feat {
  position: relative;
  display: block;
  width: 100%;
  padding: 14px var(--sp-16);
  border: 0;             /* 裸 button 的 UA 默认描边必须显式复位，否则每项都带一圈框 */
  background: transparent;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  opacity: .55;
  transform-origin: left center;
  transition: opacity var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}

.feat__body { display: block; }

.feat__title {
  display: block;
  font-size: 17px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--text-2);
  transition: color var(--dur) var(--ease);
}

/* 介绍只跟选中态走：滚轮目录里每项收成一行文字，八段介绍同时铺开
   等于把目录撑回完全展开的老样子，也挤掉了「选中项在正中」的构图 */
.feat__desc {
  display: none;
  margin-top: 3px;
  font-size: 14px;
  line-height: 1.65;
  color: var(--text-3);
  text-wrap: pretty;
}

.feat.is-active .feat__desc { display: block; }

.feat:hover { opacity: 1; }

.feat:hover .feat__title { color: var(--text-1); }

.feat.is-active {
  opacity: 1;
  transform: scale(1.06);
  z-index: 1;   /* 放大后的选中项盖过相邻项时保持在上层 */
}

.feat.is-active .feat__title { color: var(--text-1); }

/* 当前项的 accent 竖条钉在左缘：文字类高亮在暗色里不够果断，
   一根竖条才能在一列文字里一眼认出"现在放的是这一项" */
.feat.is-active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 12px;
  bottom: 12px;
  width: 2px;
  border-radius: var(--r-pill);
  background: var(--accent);
}

/* ── 通用段落文案 ─────────────────────────────────────────────────── */
/* 首屏演示的四幕章节卡（.hero__acts 里）：结构沿用原布局区的章节卡样式 */
.lact {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas: "num title" "num desc";
  gap: 3px var(--sp-12);
  width: 100%;
  padding: var(--sp-16);
  text-align: left;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface-1);
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}

.lact:hover { border-color: var(--border-strong); }
.lact.is-active { border-color: var(--border-strong); background: var(--surface-2); }

.lact__num {
  grid-area: num;
  font-size: 12px;
  line-height: 1.5;
  letter-spacing: .06em;
  color: var(--text-3);
}

.lact.is-active .lact__num { color: var(--accent); }

.lact__title {
  grid-area: title;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--text-1);
}

.lact__desc {
  grid-area: desc;
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-2);
}

@media (max-width: 600px) {
  .hero__acts { grid-template-columns: minmax(0, 1fr); }
}

.section__eyebrow {
  margin-bottom: var(--sp-16);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .16em;
  line-height: 1.4;
  color: var(--accent);
}

.section__title {
  font-size: clamp(26px, 3.2vw, 42px);
  font-weight: 700;
  letter-spacing: -.02em;
  line-height: 1.24;
  color: var(--text-1);
  text-wrap: balance;
}

.section__lede {
  max-width: 46em;
  margin-top: var(--sp-16);
  font-size: clamp(15px, 1.4vw, 18px);
  line-height: 1.75;
  color: var(--text-2);
  text-wrap: pretty; /* 长句居中时避免末行只剩一两个字 */
}

/* ── 档位卡片 ─────────────────────────────────────────────────────── */
/* 四档等权，最高档只挂一个「推荐」角标，不放大也不上浮：读者该按"够不够用"选档，
   而不是被视觉推着选最贵的。原先那条通栏「事实带」已撤——16 窗格与 100,000 根回看
   本来就是这张表里的两行，通栏再报一遍等于同一事实要在两处维护 */
.tiers {
  border-top: 1px solid var(--border);
  padding: clamp(72px, 9vw, 128px) var(--gutter);
}

.tiers__inner {
  max-width: var(--maxw);
  margin-inline: auto;
  text-align: center;
}

/* 权益逐行对齐是这张表的全部意义：同一条权益在四列里必须落在同一高度，
   故四张卡的行文本必须逐字相同、行数也必须相同（含不可用的暗行） */
.tier-cards {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--sp-16);
  margin-top: var(--sp-40);
  text-align: left;
}

.tcard {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: var(--sp-20);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface-1);
}

.tcard--hot {
  border-color: var(--border-strong);
  background: var(--surface-2);
}

/* 角标咬住卡片上沿：浮在卡内会占掉一行高度，四列就对不上行了 */
.tcard__badge {
  position: absolute;
  top: -1px;
  right: var(--sp-16);
  padding: 2px 10px;
  border-radius: 0 0 var(--r-sm) var(--r-sm);
  background: var(--accent);
  color: var(--on-accent);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.6;
}

.tcard__name {
  font-size: 17px;
  font-weight: 700;
  line-height: 1.4;
  color: var(--text-1);
}

/* 计费周期切换：居中一枚胶囊双选，两键拼边共享圆角；
   选中态用品牌蓝实底（与推荐角标同一强调语言） */
.billing {
  display: flex;
  justify-content: center;
  margin-top: var(--sp-32);
}

.billing__opt {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 22px;
  border: 1px solid var(--border);
  background: var(--surface-1);
  font: inherit;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-3);
  cursor: pointer;
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}

.billing__opt:first-child { border-radius: var(--r-pill) 0 0 var(--r-pill); }

.billing__opt + .billing__opt {
  margin-left: -1px;   /* 拼掉公共边，两条边框看起来是一条 */
  border-radius: 0 var(--r-pill) var(--r-pill) 0;
}

.billing__opt.is-active {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--on-accent);
  cursor: default;   /* 已选中再点无动作，指针不该继续暗示可切 */
}

/* 年付折扣角标：currentColor 描边小药丸，随选中态自动反白 */
.billing__off {
  padding: 1px 7px;
  border: 1px solid currentColor;
  border-radius: var(--r-pill);
  font-size: 11px;
  line-height: 1.5;
}

/* 价格行在档名下独立一行：数字用等宽栈与权益行的数值同一套数字语言；
   币符与 /月(/年) 单位小一号压灰，大数字做层级主角。年价与原价由
   interactions.js 从 data-price-month 推导（年=月×12×0.8、原价=月×12） */
.tcard__price {
  margin-top: var(--sp-8);
  font-family: var(--font-mono);
  font-size: 28px;
  font-weight: 700;
  line-height: 1.25;
  color: var(--text-1);
  font-variant-numeric: tabular-nums;
}

.tcard__price small {
  margin-right: 2px;
  font-size: 15px;
  font-weight: 600;
  color: var(--text-3);
}

.tcard__unit {
  margin-left: 4px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-3);
}

/* 年付划线原价：跟在折后年总价后，小一号压灰划线，只在按年且月价>0 时出现 */
.tcard__origin {
  margin-left: 8px;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-3);
  text-decoration: line-through;
}

/* 定位语有一行也有两行，锁最小高度，四张卡的权益列表才从同一条线起排 */
.tcard__tag {
  min-height: 3.4em;
  margin-top: var(--sp-4);
  font-size: 13px;
  line-height: 1.7;
  color: var(--text-3);
  text-wrap: pretty;
}

.tcard__list {
  margin-top: var(--sp-12);
  border-top: 1px solid var(--border);
}

/* 勾号固定占行首一个字宽，数值靠 margin-left:auto 贴到行尾：
   勾号列对齐后，横扫四张卡一眼就能看出哪几行是暗的 */
.tcard__row {
  display: flex;
  align-items: baseline;
  gap: var(--sp-8);
  padding: 7px 0;
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-2);
}

.tcard__row + .tcard__row { border-top: 1px solid rgba(var(--ink-rgb), .045); }

.tcard__row::before {
  content: "✓";
  flex: none;
  width: 1em;
  font-size: 12px;
  color: var(--accent);
}

/* 不含的能力压暗但不删行：位置留着，四列才对得上 */
.tcard__row.is-off { color: rgba(var(--text-3-rgb), .6); }

.tcard__row.is-off::before {
  content: "–";
  color: rgba(var(--text-3-rgb), .6);
}

.tcard__row em {
  margin-left: auto;
  font-family: var(--font-mono);
  font-style: normal;
  font-size: 12px;
  color: var(--text-1);
  font-variant-numeric: tabular-nums; /* 窗格数与回看根数要能跨卡片横着比大小 */
  white-space: nowrap;
}

.tcard__row.is-off em { color: inherit; }

.tiers__foot {
  margin-top: var(--sp-24);
  font-size: 12px;
  line-height: 1.7;
  color: var(--text-3);
}

/* ── 收尾 CTA ─────────────────────────────────────────────────────── */
.final-cta {
  position: relative;
  overflow: hidden;
  padding: clamp(88px, 11vw, 152px) var(--gutter);
  border-top: 1px solid var(--border);
  text-align: center;
}

/* 全站唯一一次使用科技网格图：上下渐隐，只留地平线的暗示 */
.final-cta::before {
  content: "";
  position: absolute;
  inset: 0;
  background: url("assets/bg_grid_tech.png") center bottom / cover no-repeat;
  opacity: .55;
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 38%, #000 80%, transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0%, #000 38%, #000 80%, transparent 100%);
}

.final-cta::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(760px 340px at 50% 8%, var(--accent-soft), transparent 70%);
}

.final-cta__inner {
  position: relative;
  z-index: 1;
  max-width: 720px;
  margin-inline: auto;
}

.final-cta__title {
  font-size: clamp(28px, 3.6vw, 46px);
  font-weight: 700;
  letter-spacing: -.02em;
  line-height: 1.22;
  color: var(--text-1);
  text-wrap: balance;
}

.final-cta__lede {
  margin-top: var(--sp-16);
  font-size: clamp(15px, 1.4vw, 18px);
  line-height: 1.75;
  color: var(--text-2);
  text-wrap: pretty;
}

.final-cta__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-12);
  margin-top: var(--sp-32);
}

/* ═══ 子页面组件（invite.html 邀请奖励 / partner.html 合作共赢 共用） ═══
   两页除下列组件外一律复用首页的令牌与控件，不另起一套色值或字号阶，
   否则子页会读成"另一个站"。子页首屏左对齐，与首页居中的段落头形成层级差 */

/* ── 子页首屏 ─────────────────────────────────────────────────────── */
.subhero {
  position: relative;
  overflow: hidden;
  padding: clamp(72px, 9vw, 120px) var(--gutter);
  border-bottom: 1px solid var(--border);
}

/* 一层极淡的冷光落在标题上方：子页没有图腾，靠这层给首屏一点纵深 */
.subhero::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(680px 280px at 22% 0%, var(--accent-soft), transparent 70%);
}

.subhero__inner {
  position: relative;
  z-index: 1;
  max-width: var(--maxw);
  margin-inline: auto;
}

.subhero__inner .page-nav__back { margin-bottom: var(--sp-24); }

/* ── 子页：流程卡 ─────────────────────────────────────────────────── */
/* auto-fit 让三步与四步共用一套规则：空轨道折叠后，剩下几张就均分整行 */
.steps {
  --step-gap: clamp(16px, 2vw, 28px);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
  gap: var(--step-gap);
  max-width: var(--maxw);
  margin-inline: auto;
}

.step-card {
  position: relative;
  min-width: 0;
  padding: var(--sp-20);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface-1);
}

/* 卡间一根发丝连线，只示意先后顺序：流程感靠这根线给，不靠箭头图形——
   高度对齐序号的光学中心，线才像从上一张的号码里牵出来的 */
.step-card:not(:last-child)::after {
  content: "";
  position: absolute;
  top: calc(var(--sp-20) + 17px);
  right: calc(-1 * var(--step-gap));
  width: var(--step-gap);
  height: 1px;
  background: var(--border);
}

.step-card__num {
  display: block;
  font-family: var(--font-mono);
  font-size: clamp(22px, 2.4vw, 32px);
  font-weight: 600;
  letter-spacing: -.01em;
  line-height: 1.1;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}

.step-card__title {
  display: block;
  margin-top: var(--sp-12);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--text-1);
}

.step-card__desc {
  display: block;
  margin-top: 6px;
  font-size: 13px;
  line-height: 1.7;
  color: var(--text-3);
  text-wrap: pretty;
}

/* ── 子页：规则清单 ───────────────────────────────────────────────── */
.rules {
  max-width: var(--maxw);
  margin-inline: auto;
}

.rule {
  display: grid;
  grid-template-columns: 132px minmax(0, 1fr);
  gap: var(--sp-16);
  padding: 14px 0;
}

/* 分隔线只出现在行与行之间：首尾再各加一条，清单会读成一张封闭的表 */
.rule + .rule { border-top: 1px solid var(--border); }

.rule__k {
  font-size: 13px;
  line-height: 1.7;
  color: var(--text-3);
}

.rule__v {
  font-size: 14px;
  line-height: 1.7;
  color: var(--text-2);
  text-wrap: pretty;
}

/* ── 子页：费率档位表 ─────────────────────────────────────────────── */
/* 四行等权、不给任何一档做高亮：读者按自己的量级对号入座，不该被视觉推着往上看 */
.rate-table {
  /* 与同页 .rules 同宽：两块紧邻出现，宽度不齐会让整段版心看起来是歪的 */
  max-width: var(--maxw);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface-1);
  overflow: hidden;
}

.rate-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-16);
  padding: 12px var(--sp-16);
}

.rate-row + .rate-row { border-top: 1px solid var(--border); }

.rate-row__tier {
  min-width: 0;
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-2);
}

/* 等宽 + 等宽数字 + 右对齐：四档的个位对齐成一列，才能竖着比大小 */
.rate-row__bps {
  flex: none;
  font-family: var(--font-mono);
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-1);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* ── 子页：合规提示 ───────────────────────────────────────────────── */
.notice {
  padding: var(--sp-16) var(--sp-20);
  border-left: 2px solid var(--border-strong);
  border-radius: var(--r-sm);
  background: var(--surface-1);
}

.notice__title {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.6;
  color: var(--text-1);
}

.notice__list {
  margin-top: var(--sp-8);
  font-size: 13px;
  line-height: 1.75;
  color: var(--text-3);
}

/* 短横线而不是圆点：圆点会把风险提示读成一份功能清单 */
.notice__list li {
  position: relative;
  padding-left: 15px;
}

.notice__list li::before {
  content: "–";
  position: absolute;
  left: 0;
}

/* ── 子页：常见问题 ───────────────────────────────────────────────── */
.faq {
  max-width: var(--maxw);
  margin-inline: auto;
}

.faq__item { padding: var(--sp-20) 0; }

.faq__item + .faq__item { border-top: 1px solid var(--border); }

.faq__q {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.6;
  color: var(--text-1);
}

.faq__a {
  max-width: 62em;
  margin-top: 6px;
  font-size: 14px;
  line-height: 1.75;
  color: var(--text-2);
  text-wrap: pretty;
}

/* ── 页脚 ─────────────────────────────────────────────────────────── */
.site-footer { border-top: 1px solid var(--border); }

.site-footer__inner {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 2fr);
  gap: clamp(32px, 5vw, 64px);
  max-width: var(--maxw);
  margin-inline: auto;
  padding: clamp(48px, 6vw, 72px) var(--gutter);
}

.site-footer__brand {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  /* 多行 flex 默认 align-content:stretch，列高被栅格拉高时会把品牌行与标语行撑开一大段空档 */
  align-content: flex-start;
  gap: var(--sp-8);
}

.site-footer__tagline {
  flex-basis: 100%;
  max-width: 26em;
  margin-top: var(--sp-12);
  font-size: 13px;
  line-height: 1.7;
  color: var(--text-3);
}

.site-footer__cols {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-32);
}

.footer-col { min-width: 0; }

.footer-col__title {
  margin-bottom: var(--sp-12);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--text-1);
}

.footer-col__link {
  display: block;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-3);
  text-decoration: none;
  transition: color var(--dur) var(--ease);
}

.footer-col__link + .footer-col__link { margin-top: 10px; }

.footer-col__link:hover { color: var(--text-1); }

/* 法务区与内容网格对齐，分隔线随 1200 容器内缩 */
.site-footer__legal {
  max-width: var(--maxw);
  margin-inline: auto;
  padding: var(--sp-24) var(--gutter) var(--sp-48);
  border-top: 1px solid var(--border);
}

.site-footer__risk {
  max-width: 900px;
  font-size: 12px;
  line-height: 1.7;
  color: var(--text-3);
}

.site-footer__copy {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-8) var(--sp-20);
  margin-top: var(--sp-16);
  font-size: 12px;
  line-height: 1.6;
  color: var(--text-3);
}

/* 法务三链（隐私/协议/客服）落在同域 Flutter 公开页，与 ICP 行同款弱链接 */
.site-footer__law {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-8) var(--sp-20);
  margin-top: var(--sp-16);
  font-size: 12px;
  line-height: 1.6;
  color: var(--text-3);
}

.site-footer__law-link {
  color: inherit;
  text-decoration: none;
  transition: color var(--dur) var(--ease);
}

.site-footer__law-link:hover { color: var(--accent); }

.site-footer__icp {
  color: inherit;
  text-decoration: none;
  transition: color var(--dur) var(--ease);
}

.site-footer__icp:hover { color: var(--accent); }

/* ── 响应式 ≤900px ────────────────────────────────────────────────── */
@media (max-width: 900px) {
  /* 窄屏头部只留品牌与主 CTA */
  .brand__latin,
  .site-nav,
  .btn--ghost.btn--sm { display: none; }

  .hero { padding-block: clamp(32px, 6vw, 56px) clamp(48px, 8vw, 80px); }

  /* 没有并排的余地了：图腾退成居中背景。它本身已被明度衰减压得很暗，
     再叠 .42 的透明度就只剩一团灰雾，故这里只压到 .55，让眉眼带还认得出是一张脸 */
  .totem {
    right: 50%;
    width: min(94%, 620px);
    transform: translate(50%, -48%);
    opacity: .55;
  }

  .hero__content { width: min(100%, 560px); }

  /* 舞台在上、目录在下，与 DOM 顺序一致——先看到画面，再读它是什么 */
  .showcase__inner { grid-template-columns: minmax(0, 1fr); }

  /* 四档降到两列：单列会把 21 行权益拉成一根四段长条，横向比档的能力全丢 */
  .tier-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* 单列后卡片竖着排，横向连线会变成四条悬空的短横 */
  .steps { grid-template-columns: minmax(0, 1fr); }

  .step-card:not(:last-child)::after { display: none; }

  .site-footer__inner { grid-template-columns: minmax(0, 1fr); }

  .site-footer__cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ── 响应式 ≤720px ────────────────────────────────────────────────── */
@media (max-width: 720px) {
  .hero__content {
    width: 100%;
    text-align: center;
  }
}

/* ── 响应式 ≤600px ────────────────────────────────────────────────── */
@media (max-width: 600px) {
  :root { --gutter: var(--sp-16); }

  .tiers { padding-block: var(--sp-64); }

  .tier-cards { grid-template-columns: minmax(0, 1fr); }

  .final-cta { padding-block: var(--sp-80); }

  .subhero { padding-block: var(--sp-64); }

  /* 键列压到 96px：手机上定宽键列再宽，值列就只剩两三个字一行 */
  .rule { grid-template-columns: 96px minmax(0, 1fr); }
}

/* ── 区块进场揭示 ─────────────────────────────────────────────────── */
/* 契约：没有 data-reveal 属性 = 直接可见。interactions.js 只在确定要做动效时才写属性，
   所以脚本没加载、报错或用户偏好减动效时，页面天然停在终态，绝不会留下一屏空白 */
[data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 620ms cubic-bezier(.22, .61, .36, 1),
              transform 620ms cubic-bezier(.22, .61, .36, 1);
}

[data-reveal="in"] {
  opacity: 1;
  transform: none;
}

/* ── 动效降级 ─────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  /* 首屏直出终态：减弱动效下脚本会跳过入场，过渡不该再补演一遍 */
  .hero.is-intro .hero__headline,
  .hero.is-intro .hero__demo {
    opacity: 1;
    transform: none;
  }

  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }

  /* 双保险：脚本若已抢先写入初始态，此处强制归位；
     否则上面把过渡时长清零，元素会永远卡在 opacity:0 */
  [data-reveal],
  [data-reveal="in"] {
    opacity: 1;
    transform: none;
  }
}
