/* ============================================================
   420.meme 首页样式
   结构：背景层（像素地址行 / 大字碎片 / 暗色垫底 / 流光光球）
        中央（标签 / 大数字 / 玻璃胶囊进度条 / 按钮）
        弹层（连接钱包 / 查询中 / 结果卡两种）
   颜色变量集中在 :root，改配色只动这里。
   ============================================================ */
:root {
  --bg: #1a1f27;            /* 页面底色：石墨蓝，不是纯黑 */
  --bg-rgb: 26, 31, 39;
  --surface: #232933;       /* 弹层底色 */
  --card: #171c24;   /* 卡片底色比页面更深，光才跳得出来 */          /* 结果卡底色 */
  --text: #f4f6f8;
  --text-70: rgba(255, 255, 255, .7);
  --text-50: rgba(255, 255, 255, .5);
  --line: rgba(255, 255, 255, .2);
  --lime: #9dff5c;          /* 状态点 / 在名单徽章 */
  /* 流光渐变的四个色：薄荷、青、蓝、紫 */
  --g1: #9dff5c; --g2: #5ef2c8; --g3: #6aa6ff; --g4: #c26bff; --g5: #ff6fb1;
  --font: "Manrope", -apple-system, "Helvetica Neue", sans-serif;
  --px: "Silkscreen", "Courier New", monospace;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body { margin: 0; background: var(--bg); color: var(--text); font-family: var(--font); overflow: hidden; -webkit-font-smoothing: antialiased; }
.px { font-family: var(--px); }
button { font-family: inherit; cursor: pointer; }
[hidden] { display: none !important; }

/* ---------- 背景 ----------
   三条原则：
   1) 一个光源，一套色。原来 .orb 用 conic 把五个色全上，还叠 hue-rotate(360deg)
      一直转色相 —— 任何一帧都是随机的浑浊彩虹，和进度条那条液体没有关系。
      现在改成固定色相的三团光，颜色直接取自液体渐变：品牌色只有一套。
   2) 地址墙用 mask 从中心挖空，而不是在上面盖一块暗色椭圆。
      盖暗色会连光一起压掉；挖空才能让焦点区真正干净。
   3) 暗角把视线收回中间。
   ---------------------------------------------------------------- */
.bg { position: fixed; inset: 0; overflow: hidden; pointer-events: none; }

/* 地址墙：中心完全透明，向外才浮现 */
.rows {
  position: absolute; inset: 0;
  -webkit-mask-image: radial-gradient(ellipse 58% 46% at 50% 48%,
                       transparent 0%, transparent 42%, #000 100%);
          mask-image: radial-gradient(ellipse 58% 46% at 50% 48%,
                       transparent 0%, transparent 42%, #000 100%);
}
.rows .row { position: absolute; left: 0; white-space: nowrap; letter-spacing: .14em; color: #fff; line-height: 1; will-change: transform; }
.rows .row.l { animation: driftL linear infinite; }
.rows .row.r { animation: driftR linear infinite; }
@keyframes driftL { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes driftR { from { transform: translateX(-50%); } to { transform: translateX(0); } }

/* 左下角那块巨型描边字：原来 .09 太亮，和地址墙抢。压到几乎是暗示 */
.frag {
  position: absolute; left: -4vw; bottom: -5vh;
  font-size: clamp(150px, 21vw, 300px); line-height: .9;
  color: transparent; -webkit-text-stroke: 1px rgba(255,255,255,.035);
  letter-spacing: -.06em; white-space: nowrap;
}

/* 三团光。位置和色相都固定 —— 它们是这个页面的"打光"，不是装饰动画。
   只让它们极慢地呼吸和位移，不转色相。 */
.orb { position: absolute; inset: 0; }
.orb::before, .orb::after,
.pad {
  content: ''; position: absolute; border-radius: 50%;
  filter: blur(90px); will-change: transform, opacity;
}
/* 青绿 —— 主光，压在进度条上方偏左 */
.orb::before {
  left: 30%; top: 44%; width: min(720px, 86vw); height: min(420px, 48vh);
  transform: translate(-50%, -50%);
  background: radial-gradient(closest-side, rgba(94,242,200,.50), rgba(94,242,200,0) 70%);
  animation: lightA 26s ease-in-out infinite;
}
/* 蓝紫 —— 副光，右侧稍低，制造色温差 */
.orb::after {
  left: 66%; top: 56%; width: min(640px, 80vw); height: min(380px, 44vh);
  transform: translate(-50%, -50%);
  background: radial-gradient(closest-side, rgba(150,130,255,.44), rgba(150,130,255,0) 70%);
  animation: lightB 32s ease-in-out infinite;
}
/* 柠檬绿 —— 最小的一点提亮，只为了让高光区有个暖的落点 */
.pad {
  left: 44%; top: 38%; width: min(420px, 60vw); height: min(240px, 30vh);
  transform: translate(-50%, -50%);
  background: radial-gradient(closest-side, rgba(157,255,92,.26), rgba(157,255,92,0) 70%);
  animation: lightA 34s ease-in-out infinite reverse;
}
@keyframes lightA {
  0%, 100% { transform: translate(-50%, -50%) scale(1);    opacity: .95; }
  50%      { transform: translate(-46%, -54%) scale(1.10); opacity: 1;   }
}
@keyframes lightB {
  0%, 100% { transform: translate(-50%, -50%) scale(1.05); opacity: .85; }
  50%      { transform: translate(-54%, -47%) scale(.95);  opacity: 1;   }
}

/* 暗角：把视线收回中间，同时压住四角的地址墙 */
.bg::after {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(ellipse 75% 65% at 50% 48%,
              transparent 0%, transparent 45%, rgba(8,10,14,.55) 100%);
}

/* 顶部渐隐：品牌所在的那一条必须是干净的 */
.bg::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 22vh;
  background: linear-gradient(180deg, rgba(10,13,18,.92), rgba(10,13,18,0));
  z-index: 1;
}

.topline { position: absolute; z-index: 2; left: 0; right: 0; top: 0; height: 1px; background: linear-gradient(90deg, transparent, rgba(255,255,255,.22), transparent); }

/* ---------- 中央 ----------
   层次只有三级：品牌（最小）→ 标签 → 数字（最大）。
   原来标签和数字之间落差不够，整屏看起来"都差不多大"。
   ---------------------------------------------------------------- */
.center {
  position: relative; z-index: 1; min-height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: clamp(20px, 3vh, 30px); padding: 24px;
}

/* 品牌。原来整个首页一个标识都没有 —— 用户不知道自己在哪个站。 */
.brandmark {
  position: fixed; left: 50%; top: clamp(24px, 4vh, 40px);
  transform: translateX(-50%); z-index: 2;
  font-size: 15px; font-weight: 800; letter-spacing: -.01em; color: #fff;
}
.brandmark span { color: rgba(255,255,255,.45); font-weight: 500; }

.label {
  display: flex; align-items: center; gap: 12px;
  font-size: clamp(10px, 1vw, 12px); font-weight: 700;
  letter-spacing: .34em; color: rgba(255,255,255,.55);
}
/* 两侧短线代替原来的两个点，让这行有"标尺"感而不是装饰 */
.label::before, .label::after {
  content: ''; width: clamp(20px, 4vw, 40px); height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.3));
}
.label::after { background: linear-gradient(90deg, rgba(255,255,255,.3), transparent); }

/* 大数字。尺寸拉开，字距按字号收紧（大字天生显松）。 */
.big { display: flex; align-items: flex-start; line-height: .86; margin: -4px 0 2px; }
.big #percent {
  font-size: clamp(120px, 15vw, 210px); font-weight: 800;
  letter-spacing: -.055em; color: #fff;
  /* 让数字自己发一点光，和背景的光源呼应 */
  text-shadow: 0 0 80px rgba(94,242,200,.22), 0 20px 60px rgba(0,0,0,.5);
}
/* % 跟着数字顶部对齐，不是基线 —— 基线对齐会让它掉到数字中间显得脏 */
.big .pct {
  font-size: clamp(28px, 3.2vw, 46px); font-weight: 300;
  color: rgba(255,255,255,.5); margin-top: .32em; margin-left: .1em;
}

/* 进度条：外壳 + 液体（粘稠边缘 + 流光渐变 + 高光） */
/* 宽度必须扣掉 .center 的左右内边距，否则窄屏上会溢出屏幕。
   原来写的是 92vw，加上 2×24px 内边距就超出视口了。 */
.bar { position: relative; width: min(880px, calc(100vw - 48px)); height: clamp(76px, 8vw, 96px); }
.bar .shell { position: absolute; inset: 0; border-radius: 999px; background: linear-gradient(180deg, rgba(255,255,255,.09), rgba(255,255,255,.035)); border: 1px solid var(--line); box-shadow: inset 0 1px 0 rgba(255,255,255,.28), inset 0 -18px 30px rgba(0,0,0,.35), 0 30px 80px rgba(0,0,0,.45); backdrop-filter: blur(20px); }
/* 初始宽度必须是 0：原来写 42%，页面一打开先闪一下假的 42% 再缩回真实数字。
   clip-path 是给 Safari 的：WebKit 下 overflow:hidden + 圆角裁不住带 filter 的子层（.goo），
   液体会从圆角外壳里漏出来（0% 时左端还剩一截小胶囊）。clip-path 在两家都能真正裁掉。 */
.bar .fill { position: absolute; top: 5px; bottom: 5px; left: 5px; width: 0; border-radius: 999px; overflow: hidden; clip-path: inset(0 round 999px); transition: width 1.2s cubic-bezier(.2,.8,.2,1); }
/* 粘稠边缘：白色形状经 blur+contrast 变成液滴，再用 multiply 把流光渐变印上去 */
.bar .goo { position: absolute; inset: -30px; background: var(--bg); filter: blur(9px) contrast(24); }
.bar .goo .base { position: absolute; left: 0; top: 30px; bottom: 30px; right: 64px; background: #fff; border-radius: 0 40px 40px 0; }
.bar .blob { position: absolute; border-radius: 50%; background: #fff; }
.bar .b1 { right: 30px; top: 22px; width: 88px; height: 88px; animation: blob1 5.5s ease-in-out infinite; }
.bar .b2 { right: 6px; top: 54px; width: 60px; height: 60px; animation: blob2 7s ease-in-out infinite; }
.bar .b3 { right: 48px; top: 70px; width: 48px; height: 48px; animation: blob3 6.2s ease-in-out infinite; }
@keyframes blob1 { 0%, 100% { transform: translate(0,0) scale(1); } 33% { transform: translate(16px,-12px) scale(1.12); } 66% { transform: translate(-8px,10px) scale(.92); } }
@keyframes blob2 { 0%, 100% { transform: translate(0,0) scale(1); } 40% { transform: translate(-18px,8px) scale(1.18); } 70% { transform: translate(12px,-6px) scale(.88); } }
@keyframes blob3 { 0%, 100% { transform: translate(0,0) scale(1); } 50% { transform: translate(22px,4px) scale(1.25); } }
.bar .liquid { position: absolute; inset: 0; mix-blend-mode: multiply; background: linear-gradient(90deg, var(--g1), var(--g2), var(--g3), var(--g4), var(--g1)); background-size: 200% 100%; animation: flow 8s linear infinite; }
@keyframes flow { from { background-position: 0% 50%; } to { background-position: 200% 50%; } }
.bar .overlay { position: absolute; inset: 0; border-radius: 999px; mix-blend-mode: overlay; background: linear-gradient(180deg, rgba(255,255,255,.6) 0%, rgba(255,255,255,.12) 30%, transparent 52%, rgba(0,0,0,.35) 100%); }
.bar .gloss { position: absolute; top: 0; bottom: 0; width: 140px; background: linear-gradient(90deg, transparent, rgba(255,255,255,.5), transparent); animation: gloss 5s ease-in-out infinite; }
@keyframes gloss { from { transform: translateX(-140%) skewX(-18deg); } to { transform: translateX(360%) skewX(-18deg); } }
/* FILLING 原来浮在空管中间，像没放好的文字。
   移到管子下方右端，它就变成了刻度标签 —— 位置本身说明了它在标注什么。 */
.bar .filling {
  position: absolute; right: 4px; top: calc(100% + 14px);
  font-size: 11px; font-weight: 700; letter-spacing: .28em;
  color: rgba(255,255,255,.38);
}

/* 主按钮
   原来它是一枚淡玻璃胶囊 + 一个小绿点，读起来像状态提示而不是"可以点"。
   三处改动：① 给它品牌色的描边光，② 加箭头明示可前进，
   ③ 补 :active —— 按下必须有反馈，而且反馈要在 pointer-down 那一刻，
   不是等 click 结束（见 apple-design §1）。 */
.cta {
  position: relative; display: flex; align-items: center; gap: 12px;
  height: 64px; padding: 0 26px 0 24px; border-radius: 999px;
  border: 1px solid rgba(255,255,255,.18);
  background: linear-gradient(180deg, rgba(255,255,255,.16), rgba(255,255,255,.07));
  backdrop-filter: blur(20px) saturate(160%);
  color: #fff; font-size: 15.5px; font-weight: 700; letter-spacing: .01em;
  box-shadow:
    0 0 0 1px rgba(94,242,200,.14),
    0 18px 50px rgba(0,0,0,.45),
    0 0 60px rgba(94,242,200,.10),
    inset 0 1px 0 rgba(255,255,255,.35);
  transition: transform .18s cubic-bezier(.23,1,.32,1),
              background .18s ease, box-shadow .18s ease;
}
.cta .arw {
  margin-left: 2px; font-size: 17px; line-height: 1;
  color: rgba(255,255,255,.65);
  transition: transform .22s cubic-bezier(.23,1,.32,1), color .18s;
}
@media (hover: hover) and (pointer: fine) {
  .cta:hover {
    background: linear-gradient(180deg, rgba(255,255,255,.22), rgba(255,255,255,.11));
    box-shadow:
      0 0 0 1px rgba(94,242,200,.26),
      0 20px 60px rgba(0,0,0,.5),
      0 0 80px rgba(94,242,200,.18),
      inset 0 1px 0 rgba(255,255,255,.45);
  }
  .cta:hover .arw { transform: translateX(3px); color: #fff; }
}
.cta:active { transform: scale(.975); transition-duration: .1s; }

.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--lime); box-shadow: 0 0 12px var(--lime); animation: blink 1.6s ease-in-out infinite; }
.dot-lg { width: 12px; height: 12px; box-shadow: 0 0 18px var(--lime); }
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }

/* 关掉动画偏好：光和呼吸全停，但保留颜色与层次 */
@media (prefers-reduced-motion: reduce) {
  .rows .row, .orb::before, .orb::after, .pad,
  .bar .blob, .bar .liquid, .bar .gloss, .card, .card-orb, .dot {
    animation: none !important;
  }
  .cta, .cta .arw { transition-duration: .01ms; }
}

/* ---------- 弹层 ---------- */
.backdrop { position: fixed; inset: 0; z-index: 5; background: rgba(14,17,22,.72); backdrop-filter: blur(18px); }
.modal { position: fixed; z-index: 6; left: 50%; top: 50%; transform: translate(-50%, -50%); animation: rise .4s cubic-bezier(.2,.8,.2,1) both; }
@keyframes rise { from { opacity: 0; transform: translate(-50%, -47%) scale(.96); } to { opacity: 1; transform: translate(-50%, -50%) scale(1); } }

.connect { width: min(400px, 92vw); padding: 28px; border-radius: 28px; background: var(--surface); border: 1px solid rgba(255,255,255,.14); box-shadow: 0 40px 120px rgba(0,0,0,.6); display: flex; flex-direction: column; gap: 18px; }
.connect h2 { margin: 0 0 6px; font-size: 22px; font-weight: 800; letter-spacing: -.02em; }
.connect p { margin: 0; font-size: 13px; line-height: 1.5; color: rgba(255,255,255,.62); }
.opts { display: flex; flex-direction: column; gap: 8px; }
.opt { display: flex; align-items: center; justify-content: space-between; height: 56px; padding: 0 18px; border-radius: 16px; border: 1px solid rgba(255,255,255,.12); background: rgba(255,255,255,.07); color: #fff; font-size: 14px; font-weight: 700; transition: background .15s; }
.opt:hover { background: rgba(255,255,255,.12); }
.opt small { font-size: 11px; font-weight: 500; color: var(--text-50); }
.ghost { align-self: center; background: transparent; border: 0; color: var(--text-50); font-size: 13px; font-weight: 500; padding: 8px 12px; }

.checking { display: flex; flex-direction: column; align-items: center; gap: 14px; }
.checking-label { font-size: 14px; font-weight: 700; letter-spacing: .2em; color: rgba(255,255,255,.8); }
.checking-wallet { font-size: 12px; color: var(--text-50); }

/* 结果卡（这也是服务端渲染成 PNG 的同一套样式，尺寸 400×533，输出时放大到 1080×1440） */
.result { display: flex; flex-direction: column; align-items: center; gap: 24px; }
.card { container-type: inline-size; position: relative; width: min(400px, 88vw); aspect-ratio: 3 / 4; border-radius: 32px; overflow: hidden; background: var(--card); box-shadow: 0 50px 140px rgba(0,0,0,.6), 0 0 0 1px rgba(255,255,255,.14); animation: hover 6s ease-in-out infinite; transform-style: preserve-3d; }
@keyframes hover { 0%, 100% { transform: translateY(0) rotateX(0) rotateY(0); } 50% { transform: translateY(-8px) rotateX(2deg) rotateY(-3deg); } }
/* 卡片地址墙：中段挖空。这张卡是用户要截图发 X 的，
   数字压在一片字上就毁了 —— 背景只该在四周出现。 */
.card .wall {
  position: absolute; left: -20px; right: -20px; top: -20px; height: 140%;
  font-size: 24px; line-height: 1.2; letter-spacing: .1em;
  color: rgba(255,255,255,.075); word-break: break-all; overflow: hidden;
  animation: wallUp 40s linear infinite;
  -webkit-mask-image: linear-gradient(180deg, #000 0%, transparent 24%, transparent 62%, #000 82%);
          mask-image: linear-gradient(180deg, #000 0%, transparent 24%, transparent 62%, #000 82%);
}
.card.none .wall { color: rgba(255,255,255,.05); }
@keyframes wallUp { from { transform: translateY(0); } to { transform: translateY(-120px); } }
/* 卡片的光和首页用同一套色：青绿主光 + 蓝紫副光。
   原来是 conic 把五个色全绕一圈再转，出来是糊的彩虹，
   而且和进度条那条液体对不上 —— 同一个品牌不该有两套颜色。 */
.card-orb {
  position: absolute; left: 50%; top: 52%; width: 155%; height: 72%;
  border-radius: 50%; transform: translate(-50%, -50%);
  background:
    radial-gradient(closest-side at 26% 44%, rgba(94,242,200,.95), rgba(94,242,200,0) 70%),
    radial-gradient(closest-side at 74% 38%, rgba(150,120,255,.85), rgba(150,120,255,0) 70%),
    radial-gradient(closest-side at 52% 74%, rgba(157,255,92,.55), rgba(157,255,92,0) 68%);
  filter: blur(46px) saturate(140%); opacity: 1;
  animation: orbSpin 26s ease-in-out infinite;
}
@keyframes orbSpin {
  0%, 100% { transform: translate(-50%, -50%) scale(1)    rotate(0deg); }
  50%      { transform: translate(-53%, -48%) scale(1.08) rotate(8deg); }
}
.card-glow { position: absolute; left: 50%; top: 66%; width: 115%; height: 50%; border-radius: 50%; transform: translate(-50%, -50%); background: radial-gradient(closest-side, rgba(255,255,255,.18), transparent 72%); filter: blur(50px); }
.sheen { position: absolute; top: 0; bottom: 0; width: 45%; background: linear-gradient(90deg, transparent, rgba(255,255,255,.18), transparent); animation: sheen 4s ease-in-out infinite; pointer-events: none; }
.sheen.dim { background: linear-gradient(90deg, transparent, rgba(255,255,255,.08), transparent); }
@keyframes sheen { from { transform: translateX(-160%) skewX(-20deg); } to { transform: translateX(260%) skewX(-20deg); } }
/* 原来 space-between 把数字钉在上三分之一，下半张是死空间。
   改成让中段占据剩余高度并居中 —— 数字落在卡片的视觉重心上。 */
.card-body {
  position: absolute; inset: 0; display: flex; flex-direction: column; padding: 30px 32px;
  /* 可读性基座。光是漂亮，但白字直接泡在亮绿里会变成灰奶色。
     这一层只为文字存在：在内容所在的位置把光压下去一档，
     四角保持通透让光继续跑出去。（apple-design §12 vibrancy） */
  background:
    radial-gradient(120% 58% at 30% 46%, rgba(8,11,16,.62), rgba(8,11,16,0) 72%),
    linear-gradient(180deg, rgba(8,11,16,.45) 0%, rgba(8,11,16,0) 22%,
                            rgba(8,11,16,0) 62%, rgba(8,11,16,.72) 100%);
}
.card-mid { flex: 1; justify-content: center; }
.card-top { display: flex; justify-content: space-between; align-items: center; font-size: 11px; font-weight: 800; letter-spacing: .24em; color: var(--text-70); }
.card-top .muted { opacity: .5; }
.card-mid { display: flex; flex-direction: column; gap: 8px; }
.badge { display: inline-flex; align-self: flex-start; padding: 6px 12px; border-radius: 999px; background: rgba(255,255,255,.1); border: 1px solid rgba(255,255,255,.25); font-size: 11px; font-weight: 700; letter-spacing: .12em; color: rgba(255,255,255,.85); }
.badge.ok { background: rgba(157,255,92,.18); border-color: rgba(157,255,92,.55); color: #d6ffb8; }
.amount {
  /* ★ 字号必须跟着位数走。额度从 2,500 到 350,000 差三位，
     写死字号长的那个一定会切出卡片。用 ch 单位按"能放下几个字符"算。 */
  font-size: min(104px, 22cqw, calc(88vw / 4));
  font-weight: 800; line-height: .92;
  letter-spacing: -.062em; color: #fff;
  text-shadow: 0 0 60px rgba(94,242,200,.25), 0 6px 28px rgba(0,0,0,.6), 0 1px 2px rgba(0,0,0,.5);
}
.unit { font-size: 15px; font-weight: 700; letter-spacing: .3em; color: rgba(255,255,255,.8); }
.headline { font-size: 30px; font-weight: 800; line-height: 1.15; letter-spacing: -.02em; }
.sub { font-size: 13px; font-weight: 500; line-height: 1.6; color: rgba(255,255,255,.65); }
.card-bot { display: flex; justify-content: space-between; align-items: flex-end; }
.card-bot .k { font-size: 10px; font-weight: 800; letter-spacing: .22em; color: rgba(255,255,255,.6); margin-bottom: 4px; }
.card-bot .v { font-size: 13px; }
.brand { font-size: 13px; font-weight: 800; } .brand span { opacity: .6; }
.pop { animation: popIn .5s cubic-bezier(.2,.8,.2,1) both; }
.pop2 { animation: popIn .5s .12s cubic-bezier(.2,.8,.2,1) both; }
.pop3 { animation: popIn .5s .24s cubic-bezier(.2,.8,.2,1) both; }
@keyframes popIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }

.actions { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; }
/* 原来限定在 .actions 里，错误弹层的按钮不在那个容器里就拿不到样式，
   变成浏览器默认的蓝色下划线链接。改成按类名生效。 */
.primary, .secondary {
  display: inline-flex; align-items: center; justify-content: center;
  height: 48px; padding: 0 24px; border-radius: 999px;
  font-size: 14px; text-decoration: none; cursor: pointer;
  transition: transform .16s cubic-bezier(.23,1,.32,1), background .16s, opacity .16s;
}
.primary { border: 0; background: #fff; color: var(--bg); font-weight: 800; }
.secondary { border: 1px solid rgba(255,255,255,.25); background: rgba(255,255,255,.08); color: #fff; font-weight: 700; }
@media (hover: hover) and (pointer: fine) {
  .primary:hover { background: rgba(255,255,255,.88); }
  .secondary:hover { background: rgba(255,255,255,.14); }
}
/* 按下反馈：所有可点的东西都要有，不只是首页那个大按钮 */
.primary:active, .secondary:active, .opt:active, .ghost:active { transform: scale(.97); }
.primary:disabled, .secondary:disabled { opacity: .5; cursor: default; transform: none; }

/* ---------- 手机 ---------- */
@media (max-width: 600px) {
  .center { padding: 20px; gap: clamp(16px, 2.4vh, 24px); }
  .bar { width: calc(100vw - 40px); height: 68px; }
  .bar .filling { right: 2px; font-size: 10px; top: calc(100% + 10px); }
  .bar .goo { inset: -22px; filter: blur(6px) contrast(22); }
  .bar .goo .base { top: 22px; bottom: 22px; right: 34px; }
  .bar .b1 { width: 46px; height: 46px; right: 14px; top: 16px; }
  .bar .b2 { width: 32px; height: 32px; right: 2px; top: 32px; }
  .bar .b3 { display: none; }
  .cta { height: 58px; font-size: 15px; }
  .card-body { padding: 24px; }
}

/* 出错弹层。和其它弹层同一套材质，只是把强调色换成中性的琥珀——
   连不上钱包不是"危险"，用红色会吓人。 */
.errbox {
  width: min(380px, 92vw); padding: 30px 28px 22px; border-radius: 28px;
  background: var(--surface); border: 1px solid rgba(255,255,255,.14);
  box-shadow: 0 40px 120px rgba(0,0,0,.6);
  display: flex; flex-direction: column; align-items: center; gap: 16px; text-align: center;
}
.err-icon {
  width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(255,186,84,.16); border: 1px solid rgba(255,186,84,.4);
  color: #ffce8a; font-size: 20px; font-weight: 800;
}
.errbox p { margin: 0; font-size: 14.5px; line-height: 1.55; color: rgba(255,255,255,.78); }
.errbox .primary { text-decoration: none; }

/* ---------- 认购面板 ---------- */
.buybox {
  width: min(400px, 88vw); padding: 18px; border-radius: 22px;
  background: rgba(255,255,255,.055); border: 1px solid rgba(255,255,255,.12);
  backdrop-filter: blur(20px);
  display: flex; flex-direction: column; gap: 12px;
}
.buybox.off { opacity: .55; pointer-events: none; }
.buyrow label { display: block; font-size: 11px; font-weight: 800; letter-spacing: .2em; color: var(--text-50); margin-bottom: 8px; }
.inputwrap { display: flex; align-items: center; gap: 8px; padding: 0 14px; height: 52px; border-radius: 14px; background: rgba(0,0,0,.28); border: 1px solid rgba(255,255,255,.1); }
.inputwrap:focus-within { border-color: rgba(94,242,200,.5); }
.inputwrap input { flex: 1; min-width: 0; background: none; border: 0; outline: 0; color: #fff; font: inherit; font-size: 20px; font-weight: 700; }
.inputwrap .suffix { font-size: 13px; font-weight: 700; color: var(--text-50); }
.getrow { display: flex; justify-content: space-between; align-items: baseline; font-size: 13px; color: var(--text-50); }
.getrow b { font-size: 18px; font-weight: 800; color: #fff; }
/* 提示行高度固定，出现文字时不会把按钮顶下去 */
.hintrow { min-height: 17px; font-size: 12px; line-height: 1.4; color: rgba(255,186,84,.9); }
.buybtn { width: 100%; height: 52px; font-size: 15px; }

/* 卡片右上角的关闭键。
   原来只有卡片下方一个很淡的 "Close" 文字按钮，实际很难注意到；
   而点遮罩就关又太容易误触。给一个一眼能看到、位置符合直觉的出口。 */
.result { position: fixed; }
.xclose {
  position: absolute; top: -6px; right: -6px; z-index: 2;
  width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(20,24,31,.9); border: 1px solid rgba(255,255,255,.18);
  backdrop-filter: blur(12px);
  color: rgba(255,255,255,.75); font-size: 20px; line-height: 1;
  transition: transform .16s cubic-bezier(.23,1,.32,1), background .16s, color .16s;
}
@media (hover: hover) and (pointer: fine) {
  .xclose:hover { background: rgba(38,44,54,.95); color: #fff; }
}
.xclose:active { transform: scale(.92); }
/* 窄屏：卡片几乎占满视口，×放在外侧会被裁掉，只能挪进卡片里。
   但那个位置正好压着右上角的序号——而序号是用户要截图发 X 的东西，
   所以同时给 .card-top 右边让出位置。 */
@media (max-width: 600px) {
  .xclose { top: 2px; right: 2px; }
  .card-top { padding-right: 38px; }
}

/* 已连接的地址条。放右上角——和左上/居中的品牌分开，
   一眼能看到"我是谁在用这个站"，而不用点开任何东西。 */
.connchip {
  position: fixed; top: clamp(18px, 3vh, 30px); right: clamp(18px, 3vw, 30px); z-index: 3;
  display: flex; align-items: center; gap: 10px;
  padding: 8px 8px 8px 14px; border-radius: 999px;
  background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.14);
  backdrop-filter: blur(20px);
  font-size: 12px; color: rgba(255,255,255,.8);
}
.connchip .dot { width: 6px; height: 6px; animation: none; }
.connchip button {
  border: 0; border-radius: 999px; padding: 5px 11px;
  background: rgba(255,255,255,.1); color: rgba(255,255,255,.7);
  font: inherit; font-size: 11px; font-weight: 700;
  transition: background .16s, color .16s, transform .16s;
}
@media (hover: hover) and (pointer: fine) {
  .connchip button:hover { background: rgba(255,255,255,.18); color: #fff; }
}
.connchip button:active { transform: scale(.94); }
@media (max-width: 600px) {
  .connchip { top: auto; bottom: 16px; right: 50%; transform: translateX(50%); }
}

/* ---------- 转发抽奖：表单弹层 ----------
   沿用 .connect 那套语言（28px 圆角 / --surface 底 / 同一条缓动曲线），
   这是同一个产品里的第二种弹层，不该长得像另一个网站。
   ---------------------------------------------------------------- */
.sheet {
  width: min(420px, 92vw); padding: 28px; border-radius: 28px;
  background: var(--surface); border: 1px solid rgba(255,255,255,.14);
  box-shadow: 0 40px 120px rgba(0,0,0,.6);
  display: flex; flex-direction: column; gap: 18px;
  max-height: 88vh; overflow-y: auto;
}
.sheet.center { align-items: center; text-align: center; }
/* 大字收字距，小字不收 —— 同一个值套所有字号一定有一头是错的 */
.sheet-title { margin: 0; font-size: 22px; font-weight: 800; letter-spacing: -.02em; line-height: 1.15; }
.sheet-lead { margin: 0; font-size: 13.5px; line-height: 1.55; color: rgba(255,255,255,.62); }
.sheet-lead strong { color: var(--text); font-weight: 700; }
.sheet-foot { margin: 0; font-size: 12px; color: var(--text-50); text-align: center; }

.steps { margin: 0; padding: 0 0 0 18px; display: flex; flex-direction: column; gap: 7px; }
.steps li { font-size: 13px; line-height: 1.5; color: rgba(255,255,255,.7); }
.steps li::marker { color: var(--lime); font-weight: 700; }
.steps a { color: var(--lime); text-decoration: none; border-bottom: 1px solid rgba(157,255,92,.35); }
.steps a:hover { border-bottom-color: var(--lime); }

#raffle-form { display: flex; flex-direction: column; gap: 14px; }
.field { display: flex; flex-direction: column; gap: 7px; }
.field-label { font-size: 10.5px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--text-50); }
.field-wrap {
  display: flex; align-items: center; gap: 2px; height: 52px; padding: 0 14px;
  border-radius: 14px; border: 1px solid rgba(255,255,255,.14); background: rgba(255,255,255,.05);
  transition: border-color .16s cubic-bezier(.23,1,.32,1), background .16s;
}
.field-wrap:focus-within { border-color: rgba(157,255,92,.55); background: rgba(255,255,255,.08); }
.field-prefix { color: var(--text-50); font-weight: 700; font-size: 16px; }
.field input {
  flex: 1; min-width: 0; background: transparent; border: 0; outline: none;
  color: #fff; font-family: inherit; font-weight: 600;
  /* 16px 是下限：再小 iOS Safari 会在聚焦时把整页放大 */
  font-size: 16px;
}
.field input::placeholder { color: rgba(255,255,255,.28); font-weight: 500; }
.field-error {
  margin: 0; font-size: 12.5px; line-height: 1.45; color: #ff9aa6;
  animation: errIn .18s cubic-bezier(.23,1,.32,1) both;
}
@keyframes errIn { from { opacity: 0; transform: translateY(-3px); } to { opacity: 1; transform: none; } }
.primary.wide { width: 100%; height: 52px; justify-content: center; }

.tick {
  width: 56px; height: 56px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(157,255,92,.14); border: 1px solid rgba(157,255,92,.4);
  color: var(--lime); font-size: 26px; line-height: 1;
  animation: tickIn .34s cubic-bezier(.2,.8,.2,1) both;
}
@keyframes tickIn { from { opacity: 0; transform: scale(.86); } to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  .tick, .field-error { animation: none; }
}

/* 按钮里的箭头。原来 .arw 只在 .cta 下定义过样式，用到 .primary / .secondary 上
   就变成一个没有间距、没有字号、继承正文色的裸字符——和文字挤在一起。 */
.primary .arw, .secondary .arw {
  margin-left: 7px; font-size: 16px; line-height: 1;
  transition: transform .22s cubic-bezier(.23,1,.32,1);
}
.primary .arw { color: rgba(26,31,39,.5); }
.secondary .arw { color: rgba(255,255,255,.6); }
/* 位移只给真有指针的设备——触屏上 :hover 会粘住 */
@media (hover: hover) and (pointer: fine) {
  .primary:hover .arw, .secondary:hover .arw { transform: translateX(3px); }
}
@media (prefers-reduced-motion: reduce) {
  .primary .arw, .secondary .arw { transition: none; }
}

/* ---------- 打字机注释 ----------
   ghost 与 live 叠在同一格：ghost 是整段隐形文字，负责撑出最终宽高；
   live 在上面逐字出现。这样打字/删除过程中块的尺寸和位置都不动。
   窄屏不换行：字号固定 14px，由 app.js 按屏宽算 zoom 整体缩小。
   不用 vw 算字号，因为浏览器有最小字号（中文 Chrome 12px），小于它会被顶回去而溢出。 */
.typer {
  display: grid; margin: 0; white-space: pre; text-align: left;
  font-size: 14px;
  line-height: 1.75; letter-spacing: .02em;
  color: rgba(255,255,255,.58);
  text-shadow: 0 0 18px rgba(94,242,200,.18);
}
.typer > span { grid-area: 1 / 1; }
.typer .ghost { visibility: hidden; }
.typer .caret {
  display: inline-block; width: .62em; height: 1.1em; margin-left: .08em;
  vertical-align: -.2em; background: var(--g2);
  box-shadow: 0 0 10px rgba(94,242,200,.55);
}
/* 空闲（停留 / 清空等待）时闪；打字删字时常亮，跟真终端一样 */
.typer.idle .caret { animation: caret 1s steps(1) infinite; }
@keyframes caret { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .typer.idle .caret { animation: none; }
}
