/* ============================================================
   xyn.lgbt · 印刷所
   ------------------------------------------------------------
   白纸、粉蓝白、硬边、留白。灵感是刊物版面而不是仪表盘：
   跨圈大周报本来就是个「刊」，付款页做成一张票根、一页刊头，
   比做成一块发光的玻璃更说得通。

   三条自己定的规矩，前一版就是栽在这上面：

   1. 只有 transform 和 opacity 可以进动画。
      filter / backdrop-filter / box-shadow / background-position
      一律不许动——它们每帧都要重新绘制，正是上一版卡顿的原因。
   2. 除了「正在盯链上」那根 3px 的条，全站没有常驻循环动画。
      动效只在两种时刻出现：用户刚操作完，或者状态真的变了。
   3. 旗面原色只做填充，永远配深色文字。
      #5BCEFA / #F5A9B8 配 #0d2b3a / #3d1622 都在 8:1 以上，
      反过来白底上拿它们写字只有 1.7:1，那条路一开始就是死的。

   CSP 是 style-src 'self'，没有 unsafe-inline —— HTML 里一个 style= 都不能写，
   所有间距都得在这里有个名字。
   ============================================================ */

:root {
  /* 旗面原色。只做填充和色块，不写字 */
  --sky: #5bcefa;
  --rose: #f5a9b8;

  /* 浅到可以铺大面积 */
  --sky-tint: #e9f7fe;
  --rose-tint: #fdf1f4;
  --sky-soft: #bfe9fd;
  --rose-soft: #fbd6de;

  /* 白底上能写字的同色相版本，均 ≥4.8:1 */
  --blue-ink: #0a76ad;
  --rose-ink: #c33c72;

  --ink: #16181d;
  --ink-2: #545b6b;
  --ink-3: #6b7385;
  --line: #e1e7f0;
  --line-2: #cfd7e4;
  --paper: #ffffff;

  --ok: #0a7f5c;
  --warn: #9a5b06;
  --err: #c62a3c;

  --radius: 18px;
  --radius-sm: 12px;

  /* 阴影都是静态的，只在 hover 时整组替换，不做过渡动画 */
  --lift-0: 0 1px 2px rgba(22, 24, 29, .05), 0 12px 26px -20px rgba(22, 24, 29, .2);
  --lift-1: 0 1px 2px rgba(22, 24, 29, .06), 0 20px 38px -24px rgba(22, 24, 29, .26);

  /* 旗子本体。整站复用同一个渐变，尺寸不同就是不同的角色 */
  --flag-v: linear-gradient(180deg,
    var(--sky) 0 20%, var(--rose) 20% 40%, #fff 40% 60%,
    var(--rose) 60% 80%, var(--sky) 80% 100%);

  --ease: cubic-bezier(.2, .8, .25, 1);

  color-scheme: light;
}

/* 伪元素必须一起写。`*` 不匹配 ::before / ::after，
   漏掉它们的话，凡是「定了 width/height 又带 border」的伪元素都会比预期大一圈：
   步骤条的圆圈（18px + 2px 边框 ×2 = 22px）里的数字会偏上、被挤出去，
   票根两侧的缺口圆也会错位。这个坑很隐蔽，因为大部分伪元素没同时用到这两样。 */
*, *::before, *::after { box-sizing: border-box; }

html {
  /* 顶部一层很淡的粉蓝晕染，往下 720px 化到纯白。
     一次画完，不固定、不动画、不模糊——纯粹是张有色的纸。 */
  background: var(--paper)
    linear-gradient(170deg, #eef8fe 0%, #fdf2f6 34%, #ffffff 72%)
    no-repeat top center / 100% 720px;
}

body {
  margin: 0;
  padding: 0;
  background: transparent;
  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro SC", "PingFang SC",
    "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  font-size: 16px;
  line-height: 1.65;
  min-height: 100vh;
  overflow-x: hidden;
}

::selection { background: var(--sky-soft); color: var(--ink); }

a { color: var(--blue-ink); }

:focus-visible {
  outline: 2px solid var(--blue-ink);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ============================================================
   1. 旗子：整站唯一的装饰母题
   同一个五道渐变，四种尺寸，分别当顶栏、刊头横规、小节标记、进度条。
   重复使用同一个形状，页面才像一套东西，而不是一堆效果。
   ============================================================ */

/* ============================================================
   2. 刊头：旗子本身就是报头
   ------------------------------------------------------------
   整页最重要的一个决定。旗面的蓝和粉写不了字（白底上 1.7:1），
   但旗子中间本来就有一条白带——那正好是唯一能放深色字的地方。
   于是不去「解决」这个限制，直接让它当版式：
   四道色带在上下，站名坐进中间那条白带里。

   用五个实心块拼，不用一个百分比渐变：白带的高度跟着标题自己长，
   换个更长的站名也不会把字挤到色带上。
   ============================================================ */

.wrap {
  max-width: 600px;
  margin: 0 auto;
  padding: 34px 20px 88px;
}

.masthead {
  border-radius: 18px;
  overflow: hidden;
  margin-bottom: 18px;
  box-shadow: var(--lift-0);
}
/* 色带要够厚。之前四道各 15px 配一块 90px 的白版，看上去是「白卡片镶了彩边」，
   不是一面旗。四道加起来和白版差不多高，旗子才立得住。 */
.masthead .s { display: block; height: clamp(15px, 3.2vw, 19px); }
.masthead .sky  { background: var(--sky); }
.masthead .rose { background: var(--rose); }

.plate {
  display: flex;
  align-items: center;
  gap: 13px;
  background: var(--paper);
  padding: 15px 20px;
}

.logo {
  flex: none;
  width: 42px; height: 42px;
  display: block;
  border-radius: 12px;
}

h1 {
  font-size: clamp(26px, 6.6vw, 36px);
  font-weight: 800;
  letter-spacing: -.045em;
  line-height: 1.1;
  margin: 0;
  color: var(--ink);
}

.head { margin-bottom: 30px; }
.sub { color: var(--ink-3); font-size: 14px; margin: 0; padding: 0 4px; }
.sub + .sub { margin-top: 2px; font-size: 12.5px; }

/* ============================================================
   3. 面板
   白纸 + 一道细边 + 一层很浅的投影。没有毛玻璃、没有渐变描边。
   ============================================================ */

.card {
  position: relative;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 24px;
  margin-bottom: 16px;
  overflow: hidden;
  box-shadow: var(--lift-0);
}

.card h2 {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-2);
  margin: 0 0 18px;
}
/* 小节标记：报头那面旗的缩影，同一个形状换个尺寸。
   高度给到 22px，五道各 4.4px 才印得清楚——18px 时每道不到 4px，
   落到物理像素上会糊成一团灰。 */
.card h2::before {
  content: "";
  flex: none;
  width: 7px; height: 22px;
  border-radius: 2px;
  background: var(--flag-v);
  box-shadow: inset 0 0 0 1px rgba(22, 24, 29, .08);
}
.card h2::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}

/* 强调面板：赞助位价格那张 */
.card.feature {
  background: linear-gradient(168deg, var(--sky-tint) 0%, var(--rose-tint) 100%);
  border-color: var(--sky-soft);
}

/* ============================================================
   4. 票根
   付款那一段做成撕下来的半张票：一道虚线、两边各咬掉一个圆缺口。
   缺口是 .stub 自己的伪元素，靠 .card 的 overflow:hidden 切成半月形，
   纯静态，零运行时开销。
   ============================================================ */

.stub {
  position: relative;
  margin: 4px -24px 0;
  padding: 28px 24px 0;
  border-top: 2px dashed var(--line-2);
}
.stub::before,
.stub::after {
  content: "";
  position: absolute;
  top: -12px;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: var(--paper);
  border: 1px solid var(--line);
}
.stub::before { left: -12px; }
.stub::after  { right: -12px; }

/* ============================================================
   5. 步骤条（周报页）
   data-step 由 fx.js 写，跟着 .hide 的增减走，不碰业务逻辑。
   ============================================================ */

.steps {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
  list-style: none;
  margin: 0 0 22px;
  padding: 0;
  counter-reset: step;
}
.steps li {
  position: relative;
  text-align: center;
  font-size: 12px;
  color: var(--ink-3);
  padding-top: 28px;
}
/* 连接线：画在圆点后面，左右各伸出半格。
   top 必须正好是圆心（20px 高的圆 → 10px），差一点就会看出来没对齐。 */
.steps li::before {
  content: "";
  position: absolute;
  top: 9px; left: -50%; right: 50%;
  height: 2px;
  background: var(--line);
}
.steps li:first-child::before { display: none; }

/* 数字用 grid 居中，不靠 line-height 凑。
   行高对齐一旦和 border-box 算错就会偏，而偏一两像素在 20px 的圆里非常显眼。 */
.steps li::after {
  counter-increment: step;
  content: counter(step);
  position: absolute;
  top: 0; left: 50%;
  transform: translateX(-50%);
  width: 20px; height: 20px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--paper);
  border: 2px solid var(--line-2);
  color: var(--ink-3);
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  transition: transform .3s var(--ease);
}

/* 已完成：天蓝实心。顺序不能反——已完成写在前面，当前状态才盖得住 */
.steps[data-step="2"] li:nth-child(-n+1)::after,
.steps[data-step="3"] li:nth-child(-n+2)::after,
.steps[data-step="4"] li:nth-child(-n+3)::after {
  content: "✓";
  background: var(--sky);
  border-color: var(--sky);
  color: #0d2b3a;
}
.steps[data-step="2"] li:nth-child(-n+2)::before,
.steps[data-step="3"] li:nth-child(-n+3)::before,
.steps[data-step="4"] li:nth-child(-n+4)::before { background: var(--sky); }

/* 当前：粉色实心，稍微放大一点 */
.steps[data-step="1"] li:nth-child(1),
.steps[data-step="2"] li:nth-child(2),
.steps[data-step="3"] li:nth-child(3),
.steps[data-step="4"] li:nth-child(4) { color: var(--ink); font-weight: 600; }

.steps[data-step="1"] li:nth-child(1)::after,
.steps[data-step="2"] li:nth-child(2)::after,
.steps[data-step="3"] li:nth-child(3)::after,
.steps[data-step="4"] li:nth-child(4)::after {
  background: var(--rose);
  border-color: var(--rose);
  color: #3d1622;
  transform: translateX(-50%) scale(1.15);
}

/* ============================================================
   6. 入场
   一次 380ms 的位移淡入，放完就结束。没有模糊、没有缩放。
   fx.js 没跑起来就完全不藏，无 JS 也能正常看。
   ============================================================ */

html[data-fx="on"] .reveal {
  opacity: 0;
  transform: translateY(14px);
}
html[data-fx="on"] .reveal.in {
  opacity: 1;
  transform: none;
  transition:
    opacity .38s ease var(--d, 0ms),
    transform .5s var(--ease) var(--d, 0ms);
}

/* ============================================================
   7. 胶囊选择器
   ============================================================ */

.chips { display: flex; flex-wrap: wrap; gap: 8px; }

.chip {
  appearance: none;
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--line-2);
  background: var(--paper);
  color: var(--ink-2);
  border-radius: 999px;
  padding: 8px 16px;
  font-size: 14px;
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  transition: transform .18s var(--ease), background-color .16s, border-color .16s, color .16s;
}
.chip:hover { border-color: var(--sky); color: var(--blue-ink); transform: translateY(-1px); }
.chip:active { transform: translateY(0); }

/* 深字压浅底：旗面原色终于能原样出现，对比度还有 8:1 */
.chip[aria-pressed="true"] {
  background: var(--sky);
  border-color: var(--sky);
  color: #0d2b3a;
  font-weight: 700;
  animation: pick .22s var(--ease);
}
.chips.token .chip:hover { border-color: var(--rose); color: var(--rose-ink); }
.chips.token .chip[aria-pressed="true"] {
  background: var(--rose);
  border-color: var(--rose);
  color: #3d1622;
}
@keyframes pick {
  0%   { transform: scale(.94); }
  60%  { transform: scale(1.04); }
  100% { transform: scale(1); }
}

/* ============================================================
   8. 输入
   ============================================================ */

.field { margin-bottom: 18px; }
.field:last-child { margin-bottom: 0; }

label {
  display: block;
  font-size: 13px;
  color: var(--ink-2);
  margin-bottom: 8px;
  font-weight: 600;
}

input[type="text"], input[type="number"], input[type="url"], textarea {
  width: 100%;
  border: 1px solid var(--line-2);
  border-radius: var(--radius-sm);
  padding: 13px 15px;
  font-size: 16px;
  font-family: inherit;
  color: var(--ink);
  background: #fbfcfe;
  outline: none;
  transition: border-color .16s, background-color .16s;
}
input::placeholder, textarea::placeholder { color: #a3abbb; }
input:focus, textarea:focus {
  border-color: var(--blue-ink);
  background: var(--paper);
}
textarea { resize: vertical; min-height: 88px; line-height: 1.6; }

input[type="file"] { font-size: 13px; font-family: inherit; color: var(--ink-3); width: 100%; }
input[type="file"]::file-selector-button {
  font: inherit;
  font-size: 13px;
  margin-right: 12px;
  padding: 9px 16px;
  border-radius: 999px;
  border: 1px solid var(--line-2);
  background: var(--paper);
  color: var(--blue-ink);
  font-weight: 600;
  cursor: pointer;
  transition: border-color .16s, background-color .16s;
}
input[type="file"]::file-selector-button:hover {
  border-color: var(--sky);
  background: var(--sky-tint);
}

/* 金额是这页最重要的一个数，单独放大 */
#amount {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -.02em;
  padding: 14px 16px;
}

/* ============================================================
   9. 按钮
   主按钮就是旗子本身：粉经淡紫到蓝，配深墨字。
   白字在这条渐变上只有 1.8:1，深字有 8.6:1——所以字是深的。
   ============================================================ */

.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  border: 0;
  border-radius: 14px;
  padding: 17px 20px;
  font-size: 16px;
  font-weight: 700;
  font-family: inherit;
  cursor: pointer;
  text-decoration: none;
  color: #16242e;
  background: linear-gradient(97deg, var(--rose) 0%, #dcc0e8 46%, var(--sky) 100%);
  box-shadow: var(--lift-0);
  transition: transform .18s var(--ease);
}
.btn:hover { transform: translateY(-2px); box-shadow: var(--lift-1); }
.btn:active { transform: translateY(0) scale(.995); }
.btn[disabled] { opacity: .45; cursor: not-allowed; transform: none; box-shadow: none; }

.btn.ghost {
  background: var(--paper);
  color: var(--ink-2);
  border: 1px solid var(--line-2);
  font-weight: 600;
  box-shadow: none;
}
.btn.ghost:hover { border-color: var(--sky); color: var(--blue-ink); box-shadow: var(--lift-0); }

.btn.tg {
  background: linear-gradient(97deg, #8fdcfd 0%, var(--sky) 100%);
  color: #0d2b3a;
}

.btn-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.btn-row .btn { font-size: 14px; padding: 13px 14px; }

/* ============================================================
   10. 钱包跳转
   ============================================================ */

.hint { font-size: 12.5px; color: var(--ink-3); text-align: center; margin: 22px 0 12px; }

.wallet-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 9px; }

.wallet {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  padding: 12px 4px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--paper);
  text-decoration: none;
  color: var(--ink-2);
  font-size: 11.5px;
  font-weight: 500;
  line-height: 1.2;
  text-align: center;
  transition: transform .18s var(--ease), border-color .16s, background-color .16s;
}
.wallet:hover { border-color: var(--sky); background: var(--sky-tint); transform: translateY(-3px); }
.wallet:active { transform: translateY(0); }

/* 首字母当图标：不引第三方 logo，省掉授权和外链两件麻烦事 */
.wallet .mark {
  width: 34px; height: 34px;
  border-radius: 11px;
  display: grid; place-items: center;
  font-size: 15px; font-weight: 800;
  color: #16242e;
  background: linear-gradient(140deg, var(--rose), var(--sky));
}

details.more { margin-top: 18px; }
details.more summary {
  font-size: 13px;
  color: var(--ink-2);
  cursor: pointer;
  list-style: none;
  text-align: center;
  padding: 8px;
  border-radius: 10px;
  transition: background-color .16s, color .16s;
}
details.more summary::-webkit-details-marker { display: none; }
details.more summary::after { content: " ↓"; color: var(--ink-3); }
details.more[open] summary::after { content: " ↑"; }
details.more summary:hover { color: var(--blue-ink); background: var(--sky-tint); }

/* ============================================================
   11. 二维码
   ============================================================ */

.qr {
  position: relative;
  display: block;
  width: 216px; height: 216px;
  margin: 0 auto 20px;
  padding: 11px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--lift-0);
}
.qr img, .qr canvas { width: 100%; height: 100%; display: block; image-rendering: pixelated; }

/* 四角取景框，粉蓝各占对角 */
.qr::before {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 18px;
  pointer-events: none;
  background:
    linear-gradient(var(--sky), var(--sky)) 0 0 / 2px 18px no-repeat,
    linear-gradient(var(--sky), var(--sky)) 0 0 / 18px 2px no-repeat,
    linear-gradient(var(--rose), var(--rose)) 100% 0 / 2px 18px no-repeat,
    linear-gradient(var(--rose), var(--rose)) 100% 0 / 18px 2px no-repeat,
    linear-gradient(var(--rose), var(--rose)) 0 100% / 2px 18px no-repeat,
    linear-gradient(var(--rose), var(--rose)) 0 100% / 18px 2px no-repeat,
    linear-gradient(var(--sky), var(--sky)) 100% 100% / 2px 18px no-repeat,
    linear-gradient(var(--sky), var(--sky)) 100% 100% / 18px 2px no-repeat;
}

/* ============================================================
   12. 键值表 / 金额
   ============================================================ */

dl { margin: 0 0 18px; }

.kv {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 14px;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
}
.kv:last-child { border-bottom: 0; }
.kv dt { color: var(--ink-3); font-size: 12.5px; flex: none; margin: 0; }
.kv dd { margin: 0; text-align: right; font-size: 14px; word-break: break-all; }

.mono {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  font-size: 13px;
  letter-spacing: -.01em;
}
.mono.dim { color: var(--ink-3); }

/* 金额**不用**等宽字体。等宽里小数点要占满一格，
   「5.3」会显示成「5 . 3」那样中间裂开，到 62px 就像排版坏了。
   地址和订单号那种要逐字核对的才需要 .mono，展示用的大数字用正文字体 + 等宽数字就够。 */
.amount {
  text-align: center;
  font-size: clamp(42px, 12vw, 58px);
  font-weight: 800;
  letter-spacing: -.03em;
  line-height: 1.05;
  margin: 6px 0;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.amount small {
  font-size: .3em;
  font-weight: 600;
  color: var(--ink-3);
  margin-left: 8px;
  letter-spacing: .02em;
}
/* 数字换了就弹一下。下单后 5.3 变 5.3047，不提示很容易以为没反应。
   只动 transform，不碰 filter。 */
.amount.flash { animation: bump .4s var(--ease); }
@keyframes bump {
  0%   { transform: scale(1.05); }
  100% { transform: scale(1); }
}

.copy {
  appearance: none;
  border: 1px solid var(--line-2);
  background: var(--paper);
  color: var(--blue-ink);
  border-radius: 999px;
  padding: 4px 13px;
  font-size: 12px;
  font-family: inherit;
  font-weight: 600;
  cursor: pointer;
  margin-left: 10px;
  transition: transform .18s var(--ease), border-color .16s, background-color .16s, color .16s;
}
.copy:hover { border-color: var(--sky); background: var(--sky-tint); }
.copy:active { transform: scale(.94); }
.copy.copied {
  border-color: var(--ok);
  color: var(--ok);
  background: #e9f8f2;
}

.timer {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  color: var(--ink-2);
  font-size: 13px;
  padding: 3px 11px;
  border-radius: 999px;
  background: #f4f6fa;
  border: 1px solid var(--line);
  transition: color .2s, background-color .2s, border-color .2s;
}
/* 最后一分钟。名额只留 5 分钟，这个数字得自己跳出来 */
.timer.urgent {
  color: var(--err);
  background: #fdf0f1;
  border-color: #f3c6cc;
  font-weight: 700;
}

/* ============================================================
   13. 提示条 / 状态 / 成功
   ============================================================ */

.note {
  position: relative;
  border-radius: 14px;
  padding: 13px 15px 13px 18px;
  font-size: 13.5px;
  line-height: 1.65;
  margin: 0 0 16px;
  border: 1px solid;
}
.note::before {
  content: "";
  position: absolute;
  left: 0; top: 11px; bottom: 11px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: currentColor;
}
.note.info { background: var(--sky-tint); color: #0a5c85; border-color: var(--sky-soft); }
.note.warn { background: #fff8ec; color: var(--warn); border-color: #f5dcb4; }
.note.err  { background: #fdf0f1; color: var(--err); border-color: #f3c6cc; }
.note.ok   { background: #e9f8f2; color: var(--ok); border-color: #b6e3d1; }
.note.pink { background: var(--rose-tint); color: var(--rose-ink); border-color: var(--rose-soft); }
.note:last-child { margin-bottom: 0; }
.note b { color: var(--ink); }

.status {
  display: flex;
  align-items: center;
  gap: 11px;
  justify-content: center;
  font-size: 14px;
  color: var(--ink-2);
  padding: 4px 0;
}

.spin {
  width: 16px; height: 16px; flex: none;
  border-radius: 50%;
  background: conic-gradient(from 0turn, transparent 0 18%, var(--rose) 52%, var(--blue-ink) 100%);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2.5px), #000 calc(100% - 2.5px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 2.5px), #000 calc(100% - 2.5px));
  animation: spin .9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* 盯链时底边跑一根 3px 的条。
   全站唯一的常驻动画，而且只动 transform——一个 3px 高的盒子平移，
   合成器自己就能处理，不触发任何重绘。 */
.watching::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 38%; height: 3px;
  background: linear-gradient(90deg, var(--sky), var(--rose));
  animation: track 1.7s cubic-bezier(.65, 0, .35, 1) infinite;
}
@keyframes track {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(364%); }
}

.tick {
  position: relative;
  width: 56px; height: 56px;
  margin: 2px auto 16px;
  border-radius: 50%;
  background: var(--sky);
  display: grid; place-items: center;
  color: #0d2b3a;
  font-size: 27px; font-weight: 800;
  animation: pick .34s var(--ease);
}
/* 一圈光环，只放一次。无限脉冲是上一版那种「一直在闪」的来源 */
.tick::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid var(--sky);
  animation: ring .7s var(--ease) forwards;
}
@keyframes ring {
  from { transform: scale(1); opacity: .8; }
  to   { transform: scale(1.75); opacity: 0; }
}

.stock { display: inline-flex; align-items: center; gap: 7px; font-size: 13.5px; color: var(--ink-2); }
.stock b {
  color: var(--rose-ink);
  font-size: 16px;
  font-weight: 800;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
}
.stock.err, .err-text { color: var(--err); }

.hide { display: none !important; }

/* ============================================================
   14. 排版小工具
   CSP 禁掉了内联 style，凡是过去写在 style= 里的间距都得在这里有个名字。
   ============================================================ */

.center   { text-align: center; }
.strong   { font-weight: 700; }
.tiny     { font-size: 12.5px; color: var(--ink-3); }
.lead     { color: var(--ink-2); font-size: 14px; margin: 0 0 16px; }
.lead-sm  { color: var(--ink-2); font-size: 14px; margin: 0 0 12px; }
.mt       { margin-top: 16px; }
.mt-sm    { margin-top: 8px; }
.mb-md    { margin-bottom: 16px; }
.mb-xs    { margin-bottom: 4px; }
.mb0      { margin-bottom: 0; }
.tick + p { margin-top: 0; }
.pay-meta { margin: 0 0 22px; display: flex; align-items: center; justify-content: center; gap: 12px; flex-wrap: wrap; }

.foot {
  text-align: center;
  color: var(--ink-3);
  font-size: 12.5px;
  margin-top: 40px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
  line-height: 1.9;
}
.foot a { color: var(--blue-ink); text-decoration: none; font-weight: 600; }
.foot a:hover { text-decoration: underline; }

/* ============================================================
   15. 窄屏
   ============================================================ */

@media (max-width: 440px) {
  .wrap { padding: 40px 14px 60px; }
  .card { padding: 20px; border-radius: 16px; }
  .stub { margin-left: -20px; margin-right: -20px; padding-left: 20px; padding-right: 20px; }
  .btn-row { grid-template-columns: 1fr; }
  .wallet-grid { gap: 7px; }
  .wallet { font-size: 10.5px; padding: 10px 2px; }
  .wallet .mark { width: 30px; height: 30px; font-size: 13px; }
  .qr { width: 196px; height: 196px; }
  .steps li { font-size: 11px; }
}

/* 触屏上 :hover 点完会赖着不走，抬起来的卡片就卡在那儿 */
@media (hover: none) {
  .chip:hover, .wallet:hover, .btn:hover { transform: none; }
  .btn:hover { box-shadow: var(--lift-0); }
}

/* ============================================================
   16. 减少动态效果
   勾了系统开关的人：全站静止，颜色和层级一点不少。
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .spin { animation: spin 1.2s linear infinite !important; }
  .watching::after, .tick::after { display: none; }
  html[data-fx="on"] .reveal { opacity: 1; transform: none; }
}
