/* 前台自助页 —— 「烛河」
   ------------------------------------------------------------------
   四个语义色相：玫瑰（品牌）/ 琥珀（进行中）/ 翡翠（已完成）/ 绯红（错误）。

   ★ 关于"多色是否廉价"（这里原来写反了，据实测数据改正）：
     决定高级与否的不是**色相数量**，而是两条：
       ① 彩度上限。Rosé Pine 六个强调色最高 C=0.156，五个在 0.11 以下；
          Catppuccin 十四个强调色 C 全在 0.024-0.130。而 Tailwind 的
          red-500（C=0.237）那种饱和度压在深底上会"发抖"，那才是廉价。
       ② 明度对齐。Radix 自己的 step 9（实心填充）明度跨度 0.385 —— 它
          放弃了对齐填充色，转而严格对齐 step 11（状态文字）。所以要
          **对齐"状态文字"这一层**，而不是对齐实心填充：前者让四种状态
          看起来是一家人，后者只会让四个按钮长得一模一样。
     本文件四个状态文字色明度跨度 12.1pp，比 Radix 全 31 个色相的
     13.6pp 还紧。

   ★ 上一版为什么"同质化"：强调色 #f0b8a8 和错误色 #e8776b 在 OKLCH 里
     只差 9° —— 15° 以内人眼读作"同一个颜色的深浅"。现在绯红拉到 12.8°
     并把彩度拉开 2.7 倍，靠**彩度差**补上色相差不够的部分。

   动效全部走"光"这一个隐喻，六层：
     ① 极光缓移   背景色团极慢漂移（40s）
     ② 光尘上浮   九颗微粒缓慢升起
     ③ 光心搏动   中央心跳式呼吸（这页唯一的大动作）
     ④ 光环流转   有进度时环上一道亮弧转
     ⑤ 按钮流光   主按钮上一道斜光扫过
     ⑥ 烛河推进   进度条从左推开，带光晕头
   全部在 prefers-reduced-motion 下停掉。

   版面锁 100dvh，两个面板原地互换，不用上下拉。
   ★ 输入框字号硬下限 16px：低于此值 iOS Safari 聚焦会自动放大页面，
     之后 100dvh 的版面就回不去了。要视觉更小就用字距和颜色去弱化。 */

:root {
  /* 底色四层：底 / 次底 / 抬起面 / 描边 / 发丝线
     ★ 浅蓝天空主题：底色为接近白色的浅蓝，层级靠「面色变深 + 蓝色发丝边」表达。 */
  --night:    #edf4fc;   /* 页面底：极浅蓝白 */
  --deep:     #e3eef9;   /* 次底：稍深一点的浅蓝 */
  --raise:    #f7fbff;   /* 抬起面：纯白偏蓝 */
  --edge:     #b9cfe8;   /* 描边：浅蓝 */
  --hair:     rgba(30, 64, 175, .10);

  /* ---- 品牌色：天空蓝 H 217°。变量名沿用（全文 36 处引用），值换蓝 ---- */
  --hot:      #3b82f6;   /* 核心亮：hover / 强调文字 */
  --candle:   #5aa7ff;   /* 主色：按钮填充、LOGO、焦点圈 */
  --ember:    #2563eb;   /* 余晖：按压态、强调描边 */
  --deepgold: #1d4ed8;
  --rose-bg:  rgba(59, 130, 246, .10);   /* 蓝色染色面 */
  --on-rose:  #ffffff;   /* 压在蓝色填充上的字：白字 */

  /* ---- 进行中：琥珀 H 40°。浅底下用深琥珀保证可读 ---- */
  --amber-hi: #b45309;   /* 状态文字 */
  --amber:    #d97706;   /* 实心 / 进度环 */
  --amber-bg: #fdf3e3;
  --on-amber: #ffffff;

  /* ---- 已完成：翡翠 H 160° ---- */
  --jade-hi:  #047857;
  --jade:     #059669;
  --jade-bg:  #e6f7f0;
  --on-jade:  #ffffff;

  /* ---- 错误：绯红 H 2° ---- */
  --wrong:      #dc2626;   /* 校验描边 / 图标 */
  --wrong-hi:   #b91c1c;   /* 错误文字 */
  --err-solid:  #dc2626;   /* 危险按钮填充 */
  --wrong-bg:   #fdecec;

  /* 字色：深蓝 / 次级 / 蓝灰 */
  --ink:      #1e3a5f;
  --ink-2:    #5b7ba6;
  --ash:      #7e97b8;

  --f-ui: -apple-system, BlinkMacSystemFont, "PingFang SC",
          "HarmonyOS Sans SC", "Microsoft YaHei", system-ui, sans-serif;
  --f-data: "SF Mono", ui-monospace, "Cascadia Mono", Menlo, Consolas, monospace;

  --ease: cubic-bezier(.22, .61, .36, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);

  /* 触控下限：iOS 44 / Android 48dp，取 48 两边都满足 */
  --tap: 48px;

  /* 强调色的 RGB 分量：给下面所有 rgba() 用。
     这样换主题只改这一处，不用去 30 多个 rgba() 里逐个替换十六进制。 */
  --rgb-candle: 90, 167, 255;    /* --candle #5aa7ff */
  --rgb-ember:  37, 99, 235;     /* --ember  #2563eb */
  --rgb-hot:    59, 130, 246;    /* --hot    #3b82f6 */
  --rgb-raise:  247, 251, 255;   /* --raise  #f7fbff */
  --rgb-night:  237, 244, 252;   /* --night  #edf4fc */
  --rgb-deepg:  29, 78, 216;     /* --deepgold #1d4ed8 */
  --rgb-wrong:  220, 38, 38;     /* --wrong  #dc2626 */
  --rgb-amber:  217, 119, 6;     /* --amber  #d97706 */
  --rgb-jade:   5, 150, 105;     /* --jade   #059669 */
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
[hidden] { display: none !important; }

html, body { height: 100%; margin: 0; }

body {
  background: var(--night);
  color: var(--ink);
  font: 16px/1.55 var(--f-ui);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* 数字必须等宽：进度会变，不加这条数字跳动时宽度会抖 */
.num { font-variant-numeric: tabular-nums; }

/* ============================ 背景三层 ============================ */

.sky {
  position: fixed; inset: 0; z-index: 0;
  pointer-events: none; overflow: hidden;
}

/* ① 极光：两团色雾极慢漂移。深色模式下阴影几乎失效，所以用"光团"
   而不是投影来制造纵深 */
/* 三团光雾：上方两团用冷蓝（和底色同家族，只提明度不引入色相），
   底部那团用暖玫瑰 —— 冷上暖下，和"黄昏"的光向一致，也让暖强调色
   在页面底部有个呼应，不至于只有按钮一处是暖的。 */
.aurora {
  position: absolute; inset: -25%;
  background:
    radial-gradient(38% 30% at 22% 18%, rgba(147, 197, 253, .50), transparent 70%),
    radial-gradient(32% 26% at 78% 30%, rgba(191, 219, 254, .45), transparent 72%),
    radial-gradient(46% 34% at 50% 88%, rgba(var(--rgb-ember),.16), transparent 70%);
  filter: blur(14px);
  animation: drift 40s var(--ease) infinite alternate;
}
@keyframes drift {
  0%   { transform: translate3d(0,0,0) scale(1); }
  50%  { transform: translate3d(-2.5%, 1.8%, 0) scale(1.06); }
  100% { transform: translate3d(2%, -1.5%, 0) scale(1.02); }
}

/* ② 光尘：九颗微粒缓慢上浮。用 nth-child 各给不同的起点/时长/延迟，
   避免看出周期。每颗都是 2px 的光点 + 微弱光晕 */
.motes { position: absolute; inset: 0; }
.motes i {
  position: absolute; bottom: -12px;
  width: 2px; height: 2px; border-radius: 50%;
  background: var(--candle);
  box-shadow: 0 0 6px 1px rgba(var(--rgb-candle),.55);
  opacity: 0;
  animation: rise linear infinite;
}
@keyframes rise {
  0%   { opacity: 0; transform: translate3d(0, 0, 0) scale(.6); }
  12%  { opacity: .85; }
  70%  { opacity: .5; }
  100% { opacity: 0; transform: translate3d(var(--dx, 10px), -102vh, 0) scale(1.1); }
}
.motes i:nth-child(1) { left: 12%; --dx:  14px; animation-duration: 19s; animation-delay: 0s; }
.motes i:nth-child(2) { left: 26%; --dx: -10px; animation-duration: 24s; animation-delay: 3s; }
.motes i:nth-child(3) { left: 38%; --dx:  18px; animation-duration: 21s; animation-delay: 7s; }
.motes i:nth-child(4) { left: 49%; --dx:  -8px; animation-duration: 27s; animation-delay: 1.5s; }
.motes i:nth-child(5) { left: 60%; --dx:  12px; animation-duration: 22s; animation-delay: 9s; }
.motes i:nth-child(6) { left: 71%; --dx: -16px; animation-duration: 25s; animation-delay: 5s; }
.motes i:nth-child(7) { left: 82%; --dx:   9px; animation-duration: 20s; animation-delay: 12s; }
.motes i:nth-child(8) { left: 91%; --dx: -12px; animation-duration: 28s; animation-delay: 2s; }
.motes i:nth-child(9) { left:  5%; --dx:  16px; animation-duration: 23s; animation-delay: 15s; }

/* ③ 地平线：底部一层烛火烘上来的暖 */
.horizon {
  position: absolute; left: 0; right: 0; bottom: 0; height: 42%;
  background: linear-gradient(to top, rgba(var(--rgb-ember),.13), transparent);
}

/* ============================ 版面 ============================ */

.stage {
  position: relative; z-index: 1;
  min-height: 100dvh;
  display: flex; flex-direction: column;
  /* 不用 space-between：4 个子元素（公告/页眉/主区/页脚）会被分出 3 段空白，
     公告和页眉之间也会被推开。改成靠上排，由 .core 的 auto margin 吃掉
     多余空间 —— 只有一处伸缩，版式可控。 */
  justify-content: flex-start;
  max-width: 460px; margin: 0 auto;
  /* max() 惯用法：有安全区时让位，没有时保底 */
  padding: max(10px, env(safe-area-inset-top)) 20px max(14px, env(safe-area-inset-bottom));
}

/* ---- 公告 ---- */
/* order:-1 + flex:0 0 auto：公告永远在最上面且不参与空间分配。
   不加的话 space-between 会把它和页眉推开一大截。 */
.notice {
  order: -1; flex: 0 0 auto;
  display: flex; align-items: flex-start; gap: 9px;
  margin: 0 0 10px;
  padding: 11px 12px;
  background: var(--raise);
  border: 1px solid var(--hair);
  border-left: 2px solid var(--ember);   /* 单侧强调，比整框彩色克制 */
  border-radius: 9px;
  font-size: 13px; line-height: 1.6;
  color: var(--ink-2);
  animation: notice-in .5s var(--ease-out) both;
}
@keyframes notice-in {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}
.notice-ico { flex: 0 0 auto; color: var(--ember); margin-top: 1px; }
.notice-text { flex: 1 1 auto; min-width: 0; word-break: break-word; }
.notice-x {
  flex: 0 0 auto;
  /* 触控下限：视觉上是个小 ✕，但点击区域撑到 44 */
  width: 44px; height: 44px; margin: -11px -12px -11px 0;
  display: grid; place-items: center;
  background: none; border: 0; padding: 0;
  color: var(--ash); cursor: pointer;
  transition: color .16s var(--ease);
}
.notice-x:active { color: var(--ink); }
@media (hover: hover) and (pointer: fine) {
  .notice-x:hover { color: var(--ink); }
}

/* ---- 页眉 ---- */
.top {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 6px 0 2px;
}
.brand { display: flex; align-items: center; gap: 8px; min-width: 0; }
.brand-mark {
  display: grid; place-items: center;
  width: 27px; height: 27px; border-radius: 8px;
  background: linear-gradient(160deg, rgba(var(--rgb-candle),.16), rgba(var(--rgb-candle),.05));
  border: 1px solid rgba(var(--rgb-candle),.20);
}
.brand-name {
  font-size: 15px; font-weight: 500;
  letter-spacing: .01em; color: var(--ink);
  white-space: nowrap;
}
.brand-name em { font-style: normal; color: var(--candle); }
/* 教程入口。是 <button> 而不是 <a>（它开弹层不导航），所以要把浏览器
   默认按钮样式全清掉，再按文字链的观感重画。 */
.top-link {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: 5px;
  /* 触控下限：视觉是行内文字，但点击区域要够 44 高 */
  min-height: 44px;
  background: none; border: 0; padding: 0 2px;
  font: inherit; font-size: 13px;
  color: var(--ink-2); text-decoration: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  transition: color .16s var(--ease);
}
.top-link svg { flex: 0 0 auto; opacity: .8; transition: opacity .16s var(--ease); }
.top-link:active { color: var(--candle); }
.top-link:active svg { opacity: 1; }
@media (hover: hover) and (pointer: fine) {
  .top-link:hover { color: var(--candle); }
  .top-link:hover svg { opacity: 1; }
}

/* ---- 主区 ---- */
/* 手机屏高差异大（iPhone SE 667 到 Pro Max 932）：
   用 center 会在高屏上把光心和表单之间拉出一片空白，用 flex-start 又会让
   按钮到页脚之间空一大片。所以让 .core 只占内容高度（flex 不伸展），
   由 .stage 的 space-between 把「内容块」整体摆在页眉和页脚之间。 */
.core {
  flex: 0 1 auto;
  display: flex; flex-direction: column; align-items: center;
  justify-content: flex-start;
  gap: 16px;
  padding: 4px 0 10px;
  /* 上下留白 35% / 65%：视觉重心略高于几何中心，看着才"稳"。
     margin:auto 只会 50/50 均分（实测上下各 99px，两头都显空），
     所以上边距给固定的 vh 值，剩下的全归下边的 auto。 */
  margin-top: clamp(6px, 4vh, 34px);
  margin-bottom: auto;
}

/* ============================ 光心 ============================ */

/* 环 116 / 心形 62 ≈ 53%。
   之前是 108/42（39%），环太空、心太小，看着不协调 —— 缩环的时候没把心
   同比放大就会这样。53% 左右是"一圈光裹着一颗心"而不是"一颗小点浮在环里"。 */
.beacon {
  position: relative;
  width: 116px; height: 116px;
  flex: 0 0 auto;
  display: grid; place-items: center;
  /* 上方留白收掉一半：原来 2.5vh 让光心离页眉 122px，显得整体偏下 */
  margin: clamp(2px, 1.2vh, 12px) 0 clamp(2px, 1.2vh, 10px);
}

/* 光晕：搏动的那一层。scale+opacity 一起动，像心跳而不是机械缩放 */
.beacon-halo {
  position: absolute; inset: -18%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(var(--rgb-candle),.30), transparent 68%);
  animation: pulse 3.4s var(--ease) infinite;
}
@keyframes pulse {
  0%, 100% { transform: scale(.94); opacity: .55; }
  45%      { transform: scale(1.06); opacity: .95; }
}

/* 底环：发丝级，只是给光弧一个轨道 */
/* 环用强调色的低透明版，不用 --hair：--hair 是中性白，在这个底色上
   几乎看不见（8% 白 vs #0f1216 只差一点点明度）。带色的边才立得住。 */
.beacon-ring {
  position: absolute; inset: 0;
  border-radius: 50%;
  border: 1px solid rgba(var(--rgb-candle),.22);
  box-shadow: inset 0 0 22px -8px rgba(var(--rgb-candle),.28);
}

/* 进度弧：conic-gradient 走 --p（0~100），JS 只改这一个变量。
   有进度时叠一层慢转的亮弧（spin），静止时不转 */
/* 进度弧：进行中琥珀、送完转翡翠。和下面的烛河同一套语义色，
   所以"这一单到哪了"在光心和进度条上是同一个颜色在说话。 */
.beacon-arc {
  position: absolute; inset: 0;
  border-radius: 50%;
  background: conic-gradient(from -90deg,
    var(--arc, var(--amber)) calc(var(--p, 0) * 1%),
    transparent 0);
  /* 只留一圈：中间挖空 2px 宽的环 */
  mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
  opacity: 0;
  transition: opacity .4s var(--ease);
}
.beacon.has-p .beacon-arc { opacity: 1; }

/* 转动的高光点：只在有进度且未完成时转 */
.beacon.has-p:not(.done)::after {
  content: "";
  position: absolute; inset: -3px;
  border-radius: 50%;
  background: conic-gradient(from -90deg,
    transparent 0 78%, rgba(var(--rgb-hot),.85) 88%, transparent 96%);
  mask: radial-gradient(farthest-side, transparent calc(100% - 4px), #000 calc(100% - 4px));
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 4px), #000 calc(100% - 4px));
  animation: spin 2.6s linear infinite;
}
@keyframes spin { to { transform: rotate(1turn); } }

.beacon-body { position: relative; display: grid; place-items: center; }

.beacon-heart {
  filter: drop-shadow(0 0 10px rgba(var(--rgb-candle),.4));
  transition: opacity .35s var(--ease), transform .35s var(--ease);
}
.beacon.has-p .beacon-heart {
  opacity: 0; transform: scale(.7); position: absolute;
}

/* 数字态 */
.beacon-stat {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  animation: stat-in .45s var(--ease-out) both;
}
@keyframes stat-in {
  from { opacity: 0; transform: scale(.86); }
  to   { opacity: 1; transform: none; }
}
.beacon-num {
  font-family: var(--f-data);
  font-size: 34px; font-weight: 600;
  letter-spacing: -.03em;          /* 大字负字距：字号越大默认字距越显松 */
  line-height: 1;
  color: var(--hot);
  text-shadow: 0 0 16px rgba(var(--rgb-candle),.45);
}
.beacon-num::after { content: "%"; font-size: 15px; margin-left: 1px; color: var(--candle); }
.beacon-unit {
  font-size: 11.5px; color: var(--ash);
  letter-spacing: .04em;           /* 小号短标签正字距 */
  font-variant-numeric: tabular-nums;
}

/* 完成态：环变实、光晕定住、整圈转翡翠 */
.beacon.done { --arc: var(--jade-hi); }
.beacon.done .beacon-halo {
  animation: none; transform: scale(1.04); opacity: .9;
  background: radial-gradient(circle, rgba(var(--rgb-jade),.26), transparent 68%);
}
.beacon.done .beacon-ring {
  border-color: rgba(var(--rgb-jade),.30);
  box-shadow: inset 0 0 22px -8px rgba(var(--rgb-jade),.30);
}
.beacon.done .beacon-num { color: var(--jade-hi); }

/* ============================ 分段切换 ============================ */

.seg {
  position: relative;
  display: grid; grid-template-columns: 1fr 1fr;
  width: 100%;
  padding: 3px;
  background: rgba(var(--rgb-raise),.66);
  border: 1px solid var(--hair);
  border-radius: 11px;
  backdrop-filter: blur(6px);
}
/* 滑块：切 tab 时滑过去，不是硬切 */
.seg-glide {
  position: absolute; top: 3px; bottom: 3px; left: 3px;
  width: calc(50% - 3px);
  border-radius: 8px;
  background: linear-gradient(180deg, rgba(var(--rgb-candle),.16), rgba(var(--rgb-candle),.07));
  border: 1px solid rgba(var(--rgb-candle),.22);
  transition: transform .34s var(--ease-out);
}
.seg[data-at="query"] .seg-glide { transform: translateX(100%); }
.seg button {
  position: relative; z-index: 1;
  min-height: var(--tap);
  background: none; border: 0; padding: 0;
  font: 500 14px/1 var(--f-ui);
  letter-spacing: .02em;
  color: var(--ash);
  cursor: pointer;
  touch-action: manipulation;
  transition: color .28s var(--ease);
}
.seg button[aria-selected="true"] { color: var(--hot); }

/* ============================ 面板 ============================ */

.panel {
  display: none;
  width: 100%;
}
.panel.on {
  display: block;
  animation: panel-in .38s var(--ease-out) both;
}
@keyframes panel-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/* ---- 三步引导 ---- */
.steps {
  display: flex; align-items: center; justify-content: space-between;
  gap: 4px;
  margin: 2px 0 16px; padding: 0;
  list-style: none;
  counter-reset: s;
}
.steps li {
  display: flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--ash);
  letter-spacing: .02em;
}
.steps li + li::before {
  content: ""; width: 14px; height: 1px;
  background: var(--hair); margin-right: 2px;
}
.steps b {
  display: grid; place-items: center;
  width: 18px; height: 18px; border-radius: 50%;
  background: rgba(var(--rgb-candle),.10);
  border: 1px solid rgba(var(--rgb-candle),.22);
  font: 600 10.5px/1 var(--f-data);
  color: var(--candle);
}

/* ---- 输入框 ---- */
/* floating label：靠 :placeholder-shown 反选，所以 placeholder=" " 不能省 */
.field {
  position: relative; display: block;
  margin-bottom: 4px;
}
.field input {
  width: 100%;
  min-height: var(--tap);
  padding: 20px 13px 8px;
  background: rgba(var(--rgb-night),.6);
  border: 1px solid var(--hair);
  border-radius: 10px;
  color: var(--ink);
  /* ★ 16px 是硬下限，低于此值 iOS 聚焦会放大整个页面 */
  font: 400 16px/1.4 var(--f-data);
  letter-spacing: .06em;
  outline: 0;
  transition: border-color .2s var(--ease), background .2s var(--ease);
}
.field input::placeholder { color: transparent; }
.field-label {
  position: absolute; left: 14px; top: 15px;
  font-size: 15px; color: var(--ash);
  letter-spacing: .01em;
  pointer-events: none;
  transform-origin: left top;
  transition: transform .2s var(--ease), color .2s var(--ease);
}
/* 有值或聚焦时上浮缩小 */
.field input:focus + .field-label,
.field input:not(:placeholder-shown) + .field-label {
  transform: translateY(-9px) scale(.76);
  color: var(--ember);
}
.field input:focus { border-color: rgba(var(--rgb-candle),.3); background: rgba(var(--rgb-night),.85); }

/* 聚焦底线：烛光从中心 scaleX 展开。用伪元素叠加而非改 border-width，
   天然无布局跳动 —— 这是关键优点，别改成变边框粗细 */
.field-line {
  position: absolute; left: 10px; right: 10px; bottom: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--candle), transparent);
  transform: scaleX(0);
  transition: transform .34s var(--ease-out);
}
.field input:focus ~ .field-line { transform: scaleX(1); }

/* 错误态：颜色 + 文字双信号（颜色不能是唯一信号） */
.field.bad input { border-color: rgba(var(--rgb-wrong),.55); }
.field.bad .field-label { color: var(--wrong-hi); }
.field-err {
  margin: 0 0 8px; padding-left: 13px;
  /* 用 --wrong-hi 不用 --wrong：小字号要更亮才读得清（9.43:1 vs 4.95:1） */
  font-size: 12px; color: var(--wrong-hi); line-height: 1.5;
  animation: notice-in .26s var(--ease-out) both;
}

/* autofill 覆盖：深色输入框最容易翻车的地方 —— Chrome/Safari 会强制刷上
   浅色底，深色页面上直接白块。浏览器不让改 autofill 背景，标准做法是用
   超大 inset box-shadow 盖掉，并单独设文字色（color 会被覆盖） */
.field input:-webkit-autofill,
.field input:-webkit-autofill:hover,
.field input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--ink);
  -webkit-box-shadow: 0 0 0 100px #ffffff inset;
  caret-color: var(--ink);
  /* 兜底：把背景色过渡拖到极长，让强制色永远来不及呈现 */
  transition: background-color 100000s ease-out 0s;
}

/* ---- 主按钮 ---- */
.go {
  position: relative; overflow: hidden;
  width: 100%; min-height: var(--tap);
  margin-top: 12px;
  display: grid; place-items: center;
  border: 0; border-radius: 11px;
  background: linear-gradient(180deg, #7db8ff, var(--candle) 42%, #3b82f6 100%);
  /* 白字压在蓝按钮上 */
  color: #ffffff;
  font: 600 15px/1 var(--f-ui);
  letter-spacing: .18em; text-indent: .18em;   /* 尾部空隙用 text-indent 抵掉 */
  cursor: pointer;
  user-select: none;
  touch-action: manipulation;                   /* 去掉 300ms 点击延迟 */
  /* 三层：贴边接触影（模糊≈0 保边缘锐度）+ 环境投影（负 spread 收在底下）
     + 双 inset 唇（顶边高光 / 底边压暗）= 1px 的假倒角 */
  box-shadow:
    0 1px 0 rgba(0,0,0,.28),
    0 8px 20px -6px rgba(var(--rgb-ember),.5),
    inset 0 1px 0 rgba(255,248,245,.62),
    inset 0 -1px 0 rgba(var(--rgb-deepg),.42);
  transition: transform .16s var(--ease), box-shadow .16s var(--ease), filter .16s var(--ease);
}
/* 流光：一道斜光每 4.5s 扫过一次 */
.go-sheen {
  position: absolute; top: 0; bottom: 0; left: -60%;
  width: 45%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.42), transparent);
  transform: skewX(-18deg);
  animation: sheen 4.5s var(--ease) infinite;
  pointer-events: none;
}
@keyframes sheen {
  0%, 62% { left: -60%; }
  92%     { left: 118%; }
  100%    { left: 118%; }
}
.go-text { position: relative; z-index: 1; }

/* hover 只在真有指针的设备生效，否则触屏上会"粘住" */
@media (hover: hover) and (pointer: fine) {
  .go:hover:not(:disabled) { transform: translateY(-1px); filter: brightness(1.04); }
}
/* 按下：丢外层只留 inset，从"抬起"翻成"凹陷"。按下快、回弹稍慢 */
.go:active:not(:disabled) {
  transform: translateY(1px);
  box-shadow:
    inset 0 2px 7px rgba(var(--rgb-deepg),.5),
    inset 0 1px 0 rgba(var(--rgb-deepg),.3);
  transition-duration: .1s;
}
.go:disabled {
  cursor: default; filter: saturate(.4) brightness(.72);
  transform: none;
  box-shadow: 0 1px 0 rgba(0,0,0,.2), inset 0 1px 0 rgba(255,248,245,.2);
}
.go:disabled .go-sheen { animation: none; opacity: 0; }

/* ---- 查询结果 ---- */
.detail {
  margin-top: 16px;
  padding: 14px;
  background: rgba(var(--rgb-raise),.55);
  border: 1px solid var(--hair);
  border-radius: 11px;
  animation: panel-in .34s var(--ease-out) both;
}

/* 烛河：一条发丝进度线，和输入框的语言一致，零新增概念。
   进行中走琥珀，送完了整条转翡翠 —— 进度条本身就成了状态指示，
   不用再加第二个控件说"完成了"。 */
.river {
  height: 2px; margin: 0 0 13px;
  background: var(--hair); border-radius: 2px;
  overflow: hidden;
}
.river > i {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, var(--amber), var(--amber-hi));
  box-shadow: 0 0 8px 1px rgba(var(--rgb-amber),.55);
  border-radius: 2px;
  transition: width .7s var(--ease-out),
              background .5s var(--ease), box-shadow .5s var(--ease);
}
.detail.done .river > i {
  background: linear-gradient(90deg, var(--jade), var(--jade-hi));
  box-shadow: 0 0 8px 1px rgba(var(--rgb-jade),.55);
}

.d-row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px;
  padding: 7px 0;
  font-size: 13px;
}
.d-row + .d-row { border-top: 1px solid var(--hair); }
.d-row span { color: var(--ash); letter-spacing: .02em; flex: 0 0 auto; }
.d-row b {
  font-weight: 500; color: var(--ink);
  text-align: right; min-width: 0; word-break: break-all;
}
/* 状态字用语义色。这三个值明度对齐（89.9 / 83.5 / 79.7），
   所以三种状态看起来是一家人，而不是三个不相干的颜色。 */
.d-row b.on   { color: var(--amber-hi); }   /* 赠送中 */
.d-row b.done { color: var(--jade-hi); }    /* 已完成 */
.d-row b.bad  { color: var(--wrong-hi); }   /* 已取消 / 异常 */
.d-row b.uid { font-family: var(--f-data); font-size: 12px; letter-spacing: .02em; }

/* ---- 回执 ---- */
.echo {
  margin-top: 13px; padding: 11px 13px;
  border-radius: 10px;
  border: 1px solid var(--hair);
  border-left: 2px solid var(--ember);
  background: rgba(var(--rgb-raise),.5);
  font-size: 13px; line-height: 1.6; color: var(--ink-2);
  animation: panel-in .3s var(--ease-out) both;
}
.echo.ok  { border-left-color: var(--jade);  background: rgba(var(--rgb-jade),.07); }
.echo.bad { border-left-color: var(--wrong); background: rgba(var(--rgb-wrong),.07);
            color: var(--wrong-hi); }
.echo b { color: var(--candle); font-weight: 500; }

/* ---- 页脚 ---- */
/* 不用 margin-top:auto —— .stage 的 space-between 已经负责把它压到底了，
   再加 auto 会把空白全塞到页脚上方（按钮和页脚之间空一大片）。 */
.foot {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  padding-top: 18px;
  font-size: 12px; color: var(--ash);
}
.foot p { margin: 0; letter-spacing: .02em; }
/* 页脚那句提醒：整句不提亮（会和客服链接抢），只把「务必先留言」标成
   琥珀色。用琥珀不用绯红 —— 这是提醒不是报错，绯红要留给真出错的时候，
   平时就红着的话真报错时客户已经不看了。 */
.foot p.warn em {
  font-style: normal;
  color: var(--amber-hi);
  margin-right: .1em;
}
.foot a {
  color: var(--ink-2); text-decoration: none;
  padding: 10px 2px;
  border-bottom: 1px solid transparent;
  transition: color .16s var(--ease), border-color .16s var(--ease);
}
/* 两个链接并排：购卡 + 客服，中间用 · 分隔 */
.foot-links {
  display: flex; align-items: center; gap: 4px;
  flex: 0 0 auto;
}
.foot-sep { color: var(--ash); opacity: .6; }
.foot a:active { color: var(--candle); border-bottom-color: rgba(var(--rgb-candle),.4); }
@media (hover: hover) and (pointer: fine) {
  .foot a:hover { color: var(--candle); border-bottom-color: rgba(var(--rgb-candle),.4); }
}

/* ---- 轻提示 ---- */
.toasts {
  position: fixed; z-index: 30;
  left: 50%; transform: translateX(-50%);
  bottom: max(18px, calc(env(safe-area-inset-bottom) + 12px));
  display: flex; flex-direction: column-reverse; gap: 8px;
  width: min(calc(100vw - 40px), 420px);
  pointer-events: none;
}
.toast {
  padding: 10px 14px;
  border-radius: 10px;
  background: rgba(var(--rgb-raise),.94);
  border: 1px solid var(--edge);
  border-left: 2px solid var(--ash);
  color: var(--ink);
  font-size: 13px; line-height: 1.5;
  box-shadow: 0 10px 28px -8px rgba(6,8,12,.8);
  backdrop-filter: blur(8px);
  animation: toast-in .26s var(--ease-out) both;
}
.toast.warm { border-left-color: var(--candle); }
.toast.out { animation: toast-out .24s var(--ease) both; }
@keyframes toast-in {
  from { opacity: 0; transform: translateY(10px) scale(.97); }
  to   { opacity: 1; transform: none; }
}
@keyframes toast-out {
  to { opacity: 0; transform: translateY(6px) scale(.98); }
}

/* ============================ 窄屏微调 ============================ */

@media (max-width: 360px) {
  .stage { padding-left: 15px; padding-right: 15px; }
  .beacon { width: 112px; height: 112px; }
  .beacon-num { font-size: 29px; }
  .steps li { font-size: 11px; }
  .steps li + li::before { width: 9px; }
  .go { letter-spacing: .12em; text-indent: .12em; }
}
/* 横屏矮屏（键盘弹出时也接近这个高度）：光心让位给表单 */
@media (max-height: 620px) {
  .core { gap: 12px; justify-content: flex-start; }
  .beacon { width: 92px; height: 92px; }
  .beacon-num { font-size: 25px; }
  .beacon-heart { width: 34px; height: 34px; }
  .steps { margin-bottom: 11px; }
}

/* ============================ 无障碍 ============================ */

/* 只留必要的静态呈现，动的全停。注意不是 display:none —— 布局要保持 */
@media (prefers-reduced-motion: reduce) {
  .aurora, .motes i, .beacon-halo, .go-sheen,
  .beacon.has-p:not(.done)::after {
    animation: none !important;
  }
  .motes { display: none; }
  .go-sheen { opacity: 0; }
  .beacon-halo { opacity: .7; transform: none; }
  .notice, .panel.on, .detail, .echo, .beacon-stat, .toast {
    animation: none !important;
  }
  /* 弹层：位移和缩放全去掉（那才是引起眩晕的部分），只留淡入。
     reduce 不等于"没有动画" —— 保留不动的淡入反而比硬切更好懂，
     因为它仍然传达了"有新东西出现"这个信号。 */
  .tut-card, .tut-mask {
    animation: tut-fade-in .18s linear both !important;
    transform: none !important;
  }
  .tut.closing .tut-card, .tut.closing .tut-mask {
    animation: tut-fade-out .14s linear both !important;
  }
  * { transition-duration: .01ms !important; }
}
@keyframes tut-fade-in  { from { opacity: 0; } to { opacity: 1; } }
@keyframes tut-fade-out { to { opacity: 0; } }

/* 键盘可达性：所有可聚焦元素都要有可见焦点圈 */
.seg button:focus-visible,
.go:focus-visible,
.top-link:focus-visible,
.foot a:focus-visible,
.notice-x:focus-visible {
  outline: 2px solid rgba(var(--rgb-candle),.7);
  outline-offset: 2px;
  border-radius: 8px;
}
.field input:focus-visible { outline: 0; }   /* 输入框用底线表达焦点，不叠 outline */

/* 屏幕阅读器专用：给非视觉用户的文本兜底 */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ============================ 教程弹层 ============================
   动画分两层，这是"高级"的关键：遮罩和卡片各走各的时间线。
     遮罩：透明度 + backdrop blur，.26s 线性偏快 —— 背景该迅速让位
     卡片：从点击点放大浮起，.42s 带回弹曲线 —— 主体要有重量感
   卡片的 transform-origin 由 JS 写成点击按钮的实际位置（--ox/--oy），
   所以它是"从那个按钮长出来的"，不是凭空出现在屏幕中央。
   手机上（≤560px）改成底部抽屉上滑 —— 那才是移动端的原生手势语言。 */

.tut {
  position: fixed; inset: 0; z-index: 300;
  display: grid; place-items: center;
  padding: max(16px, env(safe-area-inset-top)) 16px max(16px, env(safe-area-inset-bottom));
}
.tut-mask {
  position: absolute; inset: 0;
  background: rgba(6, 8, 12, .72);
  -webkit-backdrop-filter: blur(3px) saturate(.9);
  backdrop-filter: blur(3px) saturate(.9);
  animation: tut-mask-in .26s linear both;
}
.tut.closing .tut-mask { animation: tut-mask-out .2s linear both; }
@keyframes tut-mask-in  { from { opacity: 0; } to { opacity: 1; } }
@keyframes tut-mask-out { to { opacity: 0; } }

.tut-card {
  position: relative;
  width: 100%; max-width: 440px;
  max-height: calc(100dvh - 32px);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;      /* 滚到底不要带动后面的页面 */
  background: var(--raise);
  border: 1px solid var(--hair);
  border-radius: 16px;
  /* 三层影：贴边接触影保边缘锐度 + 环境投影（负 spread 收在底下）+ 顶边内高光 */
  box-shadow:
    0 1px 0 rgba(0,0,0,.4),
    0 26px 60px -18px rgba(6,8,12,.9),
    inset 0 1px 0 rgba(255,248,245,.06);
  /* 从点击点长出来：这两个变量由 JS 按按钮位置写入 */
  transform-origin: var(--ox, 50%) var(--oy, 50%);
  animation: tut-card-in .42s var(--ease-out) both;
}
.tut.closing .tut-card { animation: tut-card-out .2s var(--ease) both; }
@keyframes tut-card-in {
  from { opacity: 0; transform: scale(.86) translateY(10px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}
@keyframes tut-card-out {
  to { opacity: 0; transform: scale(.96) translateY(4px); }
}

.tut-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 14px 8px 12px 18px;
}
.tut-title {
  margin: 0; font-size: 15px; font-weight: 600;
  letter-spacing: .01em; color: var(--ink);
}
.tut-x {
  flex: 0 0 auto;
  width: 44px; height: 44px; margin: -6px 0;
  display: grid; place-items: center;
  background: none; border: 0; padding: 0;
  color: var(--ash); cursor: pointer;
  touch-action: manipulation;
  transition: color .16s var(--ease);
}
.tut-x:active { color: var(--ink); }
@media (hover: hover) and (pointer: fine) { .tut-x:hover { color: var(--ink); } }

/* 16:9 先占位再加载：不然视频就绪那一刻会把弹层高度顶一下 */
.tut-video {
  position: relative;
  margin: 0 14px;
  aspect-ratio: 16 / 9;
  border-radius: 11px;
  overflow: hidden;
  background: var(--night);
  border: 1px solid var(--hair);
}
.tut-video video,
.tut-video iframe {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0; display: block;
  object-fit: cover;
  background: #000;
}
.tut-empty {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 5px; color: var(--ash); text-align: center;
}
.tut-empty svg { opacity: .5; margin-bottom: 2px; }
.tut-empty p { margin: 0; font-size: 13px; color: var(--ink-2); }
.tut-empty span { font-size: 11.5px; }

/* 图文步骤：视频看不了也能照着走完 */
/* 底部留白要比顶部大一些（22 vs 14）：视觉上底边留白总显得比实际窄，
   给等量的话看起来还是"贴着"。原来底部是 0 —— 之前有客服链接顶着没露出来，
   链接一去掉最后一步就贴到卡片边上了。
   手机抽屉态下这个值还要再大，见下面 @media 里的覆盖（要让开 Home 横条）。 */
.tut-steps {
  list-style: none; margin: 14px 0 22px; padding: 0 18px;
  display: flex; flex-direction: column; gap: 13px;
}
.tut-steps li { display: flex; align-items: flex-start; gap: 11px; }
.tut-steps b {
  flex: 0 0 auto;
  width: 21px; height: 21px; margin-top: 1px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: rgba(var(--rgb-candle),.12);
  border: 1px solid rgba(var(--rgb-candle),.26);
  font-size: 11.5px; font-weight: 600;
  color: var(--candle);
  font-variant-numeric: tabular-nums;
}
.tut-steps h3 {
  margin: 0 0 2px; font-size: 13.5px; font-weight: 500;
  color: var(--ink); letter-spacing: .01em;
}
.tut-steps p { margin: 0; font-size: 12.5px; line-height: 1.6; color: var(--ash); }
/* 关键地点：提亮到品牌色，不用斜体（中文斜体是伪斜体，糊且难看），
   两侧留 .15em 气口代替空格 —— 直接写空格会在行首行尾留下可见缩进 */
.tut-steps p em {
  font-style: normal;
  color: var(--candle);
  margin: 0 .15em;
}


/* 手机：改成底部抽屉上滑 —— 移动端的原生语言是从边缘推入，不是中心缩放。
   贴底也让拇指刚好能碰到关闭区。 */
@media (max-width: 560px) {
  .tut { place-items: end center; padding: 0; }
  .tut-card {
    max-width: none;
    max-height: 88dvh;
    border-radius: 18px 18px 0 0;
    border-bottom: 0;
    /* 抽屉从下方推入，不用 scale —— 缩放动画在贴边卡片上会显得廉价 */
    transform-origin: 50% 100%;
    animation: tut-sheet-in .4s var(--ease-out) both;
  }
  .tut.closing .tut-card { animation: tut-sheet-out .22s var(--ease) both; }
  /* 抽屉是贴着屏幕底的，最后一步下面要让开 Home 横条 / 手势区，
     否则在全面屏上会被那条横线压住 */
  .tut-steps { margin-bottom: max(26px, calc(env(safe-area-inset-bottom) + 16px)); }
  /* 顶部一道短横线：抽屉的通用暗示，告诉用户这块能往下拨 */
  .tut-head { padding-top: 18px; }
  .tut-head::before {
    content: "";
    position: absolute; top: 7px; left: 50%;
    width: 34px; height: 4px; margin-left: -17px;
    border-radius: 2px;
    background: var(--edge);
  }
}
@keyframes tut-sheet-in {
  from { opacity: .6; transform: translateY(100%); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes tut-sheet-out {
  to { opacity: .5; transform: translateY(100%); }
}

/* 弹层打开时锁背景滚动 */
body.tut-open { overflow: hidden; }
