/* 购买页 · 晨雾极光（浅色）· 结算台版。
   复用 tokens-light.css 的全部令牌，这里只写本页独有的结构。
   前缀一律 by-，和官网各段的 hg- / cap- / prc- / dl- 不冲突。

   这一版把「居中窄列表单」改成双栏结算台：左栏三个步骤面板，
   右栏一张贯穿三步的粘性订单摘要卡（玻璃卡 + 渐变 hairline 环）。
   买码页是收钱的地方 —— 动效比首页收敛：
   · 不上任何永续动画（底纹是纯静态渐变，状态药丸的呼吸点用
     静态辉光表达，不用 infinite —— 全站永续动画额度已满）；
   · 入场只做「模糊到清晰」一遍，关键帧显式 to；
   · 摘要卡金额变化时一次性 scale 脉冲（.is-pulse，由 buy.js 重加类触发）；
   · 全部动画包在 no-preference 里，reduce 下 document.getAnimations() 为 0。
   入场关键帧刻意不碰 opacity —— 透明元素不算 LCP 候选，
   这个坑在首页修过一次，交易页不再犯。 */

/* box-sizing 在这套样式表里是按段作用域声明的（site.css 里有
   .hg-nav * / .dl-main * 等），购买页自己的一段写在这里。
   少了它 .by-field input 的 width:100% 加内边距会撑出横向滚动。 */
.by-top, .by-top *, .by-top *::before, .by-top *::after,
.by-main, .by-main *, .by-main *::before, .by-main *::after,
.by-foot, .by-foot * { box-sizing: border-box; }

/* ── 晨雾底纹 ──
   三团柔彩挂在视口四角（fixed，滚动时不跟着跑），色→透明的径向渐变
   本身就够柔，不用 filter: blur。全部收在 70% 就断掉：
   中央内容列上的叠色 ≤ .05，小灰字（--fg-3，5.1:1）不受影响。
   纯静态 —— 交易页不上漂移动画。 */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    radial-gradient(40% 30% at 6% 0%, rgba(126, 186, 233, .30), transparent 70%),
    radial-gradient(38% 28% at 96% 2%, rgba(201, 184, 242, .26), transparent 70%),
    radial-gradient(52% 34% at 50% 104%, rgba(245, 198, 168, .22), transparent 70%);
}

/* ── 页头 ── */
.by-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  max-width: var(--container);
  margin-inline: auto;
  padding: var(--s-5) var(--page-pad);
  border-bottom: 1px solid var(--line-1);
}

.by-brand {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-weight: var(--w-bold);
  color: var(--fg-0);
  text-decoration: none;
}

.by-main {
  max-width: var(--container);
  margin-inline: auto;
  padding: var(--s-10) var(--page-pad) var(--s-24);
}

/* ── 三步进度：圆标 + 连接线 ──
   把「拿到激活码」画成第三步，是因为购买流程里最容易流失的正是
   「付完之后呢」。is-on 是品牌渐变实底圆标，is-done 把序号换成勾、
   身后的连接线点亮成品牌色 —— 走到哪一步一眼可读。 */
.by-steps {
  display: flex;
  align-items: center;
  margin: 0 0 var(--s-10);
  padding: 0;
  list-style: none;
}

.by-step {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex: 1;
  min-width: 0;
  font-size: var(--t-sm);
  color: var(--fg-3);
}

.by-step:last-child { flex: 0 0 auto; }

/* 连接线：跟在每一步后面，占满剩余宽度 */
.by-step::after {
  content: "";
  flex: 1;
  height: 1px;
  margin-inline: var(--s-4);
  background-image: linear-gradient(90deg, var(--line-2), var(--line-1));
}
.by-step:last-child::after { content: none; }
.by-step.is-done::after {
  background-image: linear-gradient(90deg, var(--brand-lift), var(--brand-dim));
}

.by-step__mark {
  position: relative;
  flex: none;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line-2);
  border-radius: var(--r-pill);
  background-color: var(--bg-2);
  box-shadow: var(--edge-top);
  transition:
    border-color     var(--d-hover) var(--e-color),
    background-color var(--d-hover) var(--e-color),
    box-shadow       var(--d-hover) var(--e-out);
}

.by-step__num {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: var(--t-micro);
  color: var(--fg-2);
  transition:
    color   var(--d-hover) var(--e-color),
    opacity var(--d-hover) var(--e-out);
}

.by-step__check {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 12px;
  height: 12px;
  opacity: 0;
  transition: opacity var(--d-hover) var(--e-out);
}
.by-step__check path {
  stroke: var(--brand-lift);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.by-step__txt {
  white-space: nowrap;
  transition: color var(--d-hover) var(--e-color);
}

/* 当前步：品牌渐变实底 + 辉光 */
.by-step.is-on .by-step__mark {
  border-color: transparent;
  background-color: var(--brand);
  background-image: var(--grad-btn);
  box-shadow: var(--edge-top), var(--glow-brand);
}
.by-step.is-on .by-step__num { color: var(--on-accent); }
.by-step.is-on .by-step__txt {
  color: var(--fg-0);
  font-weight: var(--w-bold);
}

/* 完成步：淡蓝底圆标里的勾 */
.by-step.is-done { color: var(--fg-2); }
.by-step.is-done .by-step__mark {
  border-color: rgba(29, 111, 181, .40);
  background-color: var(--brand-dim);
}
.by-step.is-done .by-step__num { opacity: 0; }
.by-step.is-done .by-step__check { opacity: 1; }

/* ── 结算台双栏 ── */
.by-shell {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 380px;
  gap: var(--s-12);
  align-items: start;
}

.by-side {
  position: sticky;
  top: var(--s-6);
}

.by-h1 {
  margin: 0;
  color: var(--fg-0);
  font-size: var(--t-h2);
  line-height: var(--lh-h2);
  letter-spacing: var(--ls-h2);
  font-weight: var(--w-bold);
}

.by-lead {
  /* 同 site.css 里那一段孤字处理：避免末行只剩一两个字。
     购买页原来是「换机需要在后台解 / 绑。」 */
  text-wrap: pretty;
  margin: var(--s-3) 0 var(--s-8);
  max-width: 60ch;
  color: var(--fg-1);
}

/* ── 套餐卡：白玻璃 2×2，和价格页同语汇但更紧凑 ── */
.by-plans {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-4);
}

.by-loading {
  grid-column: 1 / -1;
  color: var(--fg-2);
}

.by-plan {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  min-height: 150px;
  padding: var(--s-5);
  border: 1px solid var(--glass-edge);
  border-radius: var(--r-xl);
  background-image: linear-gradient(150deg, rgba(255, 255, 255, .74), rgba(255, 255, 255, .48));
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  backdrop-filter: blur(14px) saturate(1.2);
  box-shadow: var(--edge-top), var(--shadow-1);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  /* transform 走弹簧曲线：选中/悬停时卡片「被拿起来」的手感 */
  transition:
    transform    var(--d-hover) var(--e-spring),
    border-color var(--d-hover) var(--e-color),
    background-color var(--d-hover) var(--e-color),
    box-shadow   var(--d-hover) var(--e-out);
}

/* 卡片顶部的极光彩线（天蓝→薄紫→蜜桃），照 prc-card 的做法 */
.by-plan::before {
  content: "";
  position: absolute;
  top: 0;
  left: var(--s-4);
  right: var(--s-4);
  height: 1px;
  background-image: var(--grad-line);
  opacity: .8;
  pointer-events: none;
}

/* 悬停/选中时从卡顶洒下来的一层天蓝柔光。
   backdrop-filter 让 .by-plan 自成堆叠上下文，z-index:-1 会压在
   卡片自身背景之上、内容之下，正好。 */
.by-plan::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background-image: radial-gradient(80% 60% at 50% 0%, rgba(126, 186, 233, .20), transparent 72%);
  opacity: 0;
  transition: opacity var(--d-base) var(--e-out);
  pointer-events: none;
}

.by-plan:hover {
  transform: translateY(-3px);
  border-color: rgba(126, 186, 233, .55);
  box-shadow: var(--edge-top), var(--shadow-2), var(--glow-soft);
}
.by-plan:hover::after { opacity: 1; }

/* 按下去先回到地面，松手弹起 —— 弹簧曲线负责回弹 */
.by-plan:active {
  transform: translateY(0) scale(.99);
}

.by-plan.is-on {
  transform: translateY(-3px);
  border-color: var(--brand);
  box-shadow: var(--edge-top), var(--glow-brand), var(--shadow-2);
}
.by-plan.is-on::after {
  opacity: 1;
  background-image: radial-gradient(80% 60% at 50% 0%, rgba(29, 111, 181, .12), transparent 72%);
}

.by-plan:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

/* 推荐档：品牌描边常驻 + 顶部渐变徽章 */
.by-plan.is-rec {
  border-color: rgba(29, 111, 181, .45);
}

.by-rec {
  position: absolute;
  top: calc(var(--s-2) * -1);
  left: var(--s-4);
  padding: 2px var(--s-3);
  border-radius: var(--r-pill);
  background-image: var(--grad-btn);
  color: var(--on-accent);
  font-size: var(--t-micro);
  font-weight: var(--w-bold);
  box-shadow: var(--edge-top), 0 4px 12px -4px rgba(29, 111, 181, .50);
}

/* 选中指示圈：结算页的单选语义画出来，勾在选中时亮起 */
.by-plan-tick {
  position: absolute;
  top: var(--s-4);
  right: var(--s-4);
  width: 22px;
  height: 22px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line-2);
  border-radius: var(--r-pill);
  background-color: var(--bg-2);
  box-shadow: var(--edge-top);
  transition:
    border-color     var(--d-hover) var(--e-color),
    background-color var(--d-hover) var(--e-color),
    box-shadow       var(--d-hover) var(--e-out);
}
.by-plan-tick svg {
  width: 12px;
  height: 12px;
  opacity: 0;
  transition: opacity var(--d-hover) var(--e-out);
}
.by-plan-tick path {
  stroke: var(--on-accent);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.by-plan:hover .by-plan-tick { border-color: rgba(126, 186, 233, .55); }
.by-plan.is-on .by-plan-tick {
  border-color: transparent;
  background-color: var(--brand);
  background-image: var(--grad-btn);
  box-shadow: var(--edge-top), 0 4px 10px -4px rgba(29, 111, 181, .55);
}
.by-plan.is-on .by-plan-tick svg { opacity: 1; }

.by-plan-name {
  font-size: var(--t-body);
  color: var(--fg-1);
}

.by-plan-price {
  display: flex;
  align-items: baseline;
  gap: 2px;
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: var(--t-h2);
  line-height: var(--lh-h2);
  letter-spacing: var(--ls-num);
  font-weight: var(--w-bold);
  color: var(--fg-0);
}

.by-plan-price i {
  font-style: normal;
  font-size: var(--t-sm);
  font-weight: var(--w-normal);
  color: var(--fg-2);
}

.by-plan-term {
  font-size: var(--t-micro);
  letter-spacing: var(--ls-micro);
  color: var(--fg-2);
}

/* 「折合每月」与「省额」层级拉开：折合每月贴着 hairline 分隔，
   数字用 mono 强调；省额是收益绿的一行小字。 */
.by-plan-per {
  margin-top: auto;
  padding-top: var(--s-3);
  border-top: 1px solid var(--line-1);
  font-size: var(--t-micro);
  letter-spacing: var(--ls-micro);
  color: var(--fg-2);
}
.by-plan-per b {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: var(--t-sm);
  font-weight: var(--w-bold);
  letter-spacing: var(--ls-num);
  color: var(--fg-1);
}

.by-plan-save {
  font-size: var(--t-micro);
  letter-spacing: var(--ls-micro);
  color: var(--ok);
}

/* 没有省额行的月卡：折合每月依旧坐在卡底，对齐其余三张 */

/* ── 表单 ── */
.by-form {
  margin-top: var(--s-10);
}

.by-field {
  display: block;
  max-width: 460px;
}

.by-field > span {
  display: block;
  margin-bottom: var(--s-2);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  font-weight: var(--w-bold);
  color: var(--fg-2);
}

.by-field input {
  width: 100%;
  min-height: 44px;
  padding: 0 var(--s-3);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background-color: var(--bg-2);
  box-shadow: var(--edge-top);
  color: var(--fg-0);
  font-family: inherit;
  font-size: var(--t-body);
  transition:
    border-color var(--d-hover) var(--e-color),
    box-shadow   var(--d-hover) var(--e-out);
}

.by-field input::placeholder {
  color: var(--fg-3);
}

.by-field input:focus-visible {
  outline: none;
  border-color: var(--brand);
  box-shadow: var(--edge-top), 0 0 0 3px var(--brand-dim);
}

.by-field small {
  display: block;
  margin-top: var(--s-2);
  font-size: var(--t-micro);
  line-height: var(--lh-micro);
  color: var(--fg-2);
}

/* 主按钮：与首页 hg-btn--solid 同一语汇 —— 强调蓝渐变、
   内侧白高光、品牌辉光、hover 光泽扫过。 */
.by-submit {
  position: relative;
  min-height: 48px;
  margin-top: var(--s-6);
  padding: 0 var(--s-8);
  border: 0;
  border-radius: var(--r-md);
  background-image: var(--grad-btn);
  color: var(--on-accent);
  font-family: inherit;
  font-size: var(--t-lead);
  font-weight: var(--w-bold);
  cursor: pointer;
  overflow: hidden;   /* 光泽扫过要被圆角裁住 */
  box-shadow: var(--edge-top), var(--glow-brand);
  transition:
    transform        var(--d-hover) var(--e-out),
    box-shadow       var(--d-hover) var(--e-out),
    background-color var(--d-hover) var(--e-color),
    color            var(--d-hover) var(--e-color);
}

/* 光泽扫过：一道斜切的白高光。动的是 left（一次性 transition），
   reduce 下 --d-sheen 塌成 1ms，等效瞬移。 */
.by-submit::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: -70%;
  width: 46%;
  background-image: linear-gradient(105deg, transparent, rgba(255, 255, 255, .55) 50%, transparent);
  transform: skewX(-18deg);
  transition: left var(--d-sheen) ease;
  pointer-events: none;
}

.by-submit:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: var(--edge-top), var(--glow-brand), var(--glow-soft);
}
.by-submit:hover:not(:disabled)::before { left: 130%; }
.by-submit:active:not(:disabled) { transform: translateY(0); }

.by-submit:focus-visible {
  outline: none;
  box-shadow: var(--focus);
}

.by-submit:disabled {
  background-image: none;
  background-color: var(--bg-3);
  color: var(--fg-3);
  box-shadow: none;
  cursor: not-allowed;
}
.by-submit:disabled::before { content: none; }

.by-msg {
  margin: var(--s-3) 0 0;
  min-height: 1.5em;
  font-size: var(--t-body);
  color: var(--fg-2);
}

.by-msg.is-error {
  color: var(--bad);
}

.by-msg.is-warn {
  color: var(--fg-1);
}

/* ── 右栏：粘性订单摘要卡 ──
   玻璃卡 + 渐变 hairline 环（照 prc-card 的 mask 技法）+
   顶部天蓝柔光。三步共用这一张卡。 */
.by-card {
  position: relative;
  padding: var(--s-6);
  border: 1px solid transparent;
  border-radius: var(--r-xl);
  background-image: linear-gradient(150deg, rgba(255, 255, 255, .80), rgba(255, 255, 255, .55));
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  backdrop-filter: blur(14px) saturate(1.2);
  box-shadow: var(--edge-top), var(--shadow-1);
}

/* 渐变 hairline 环：mask-composite 抠出的 1px 环，静态 */
.by-card::before {
  content: "";
  position: absolute;
  inset: -1px;
  padding: 1px;
  border-radius: inherit;
  background-image: var(--grad-hair);
  -webkit-mask-image: linear-gradient(var(--fg-0) 0 0), linear-gradient(var(--fg-0) 0 0);
  -webkit-mask-clip: content-box, border-box;
  -webkit-mask-composite: xor;
  mask-image: linear-gradient(var(--fg-0) 0 0), linear-gradient(var(--fg-0) 0 0);
  mask-clip: content-box, border-box;
  mask-composite: exclude;
  pointer-events: none;
}

/* 顶部洒下来的天蓝柔光：backdrop-filter 的堆叠上下文里
   z-index:-1 正好垫在背景之上、内容之下 */
.by-card::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background-image: radial-gradient(90% 55% at 50% 0%, rgba(126, 186, 233, .16), transparent 72%);
  pointer-events: none;
}

.by-card__label {
  margin: 0 0 var(--s-4);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  font-weight: var(--w-bold);
  color: var(--fg-2);
}

/* 引导态：未选套餐时骨架压暗，占位符是「—」。
   不加提示文案 —— 压暗的骨架本身就是「还没选」的信号。 */
.by-card__sel {
  transition: opacity var(--d-base) var(--e-out);
}
.by-card.is-empty .by-card__sel {
  opacity: .45;
}

.by-card__plan {
  margin: 0;
  font-size: var(--t-body);
  color: var(--fg-1);
}

.by-card__price {
  display: flex;
  align-items: baseline;
  gap: 2px;
  margin: var(--s-1) 0 var(--s-4);
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: var(--t-h2);
  line-height: var(--lh-h2);
  letter-spacing: var(--ls-num);
  font-weight: var(--w-bold);
  color: var(--fg-0);
  transform-origin: left center;
}

.by-card__price i {
  font-style: normal;
  font-size: var(--t-h3);
  font-weight: var(--w-normal);
  color: var(--fg-2);
}

/* 摘要行：dt 小灰字、dd 墨字，行间 hairline —— 三步共用
   （步骤二/三由既有 buy.js 填充的 #byPaySummary / #byDoneSummary
   也是这套行结构） */
.by-summary {
  margin: 0;
}

.by-summary > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  padding: var(--s-3) 0;
  border-top: 1px solid var(--line-1);
}

.by-summary dt {
  flex: none;
  font-size: var(--t-micro);
  letter-spacing: var(--ls-label);
  color: var(--fg-2);
}

.by-summary dd {
  margin: 0;
  font-size: var(--t-sm);
  font-weight: var(--w-bold);
  color: var(--fg-0);
  text-align: right;
  overflow-wrap: anywhere;
}

.by-summary code {
  font-family: var(--font-num);
  font-size: var(--t-micro);
  font-weight: var(--w-normal);
  letter-spacing: var(--ls-num);
}

.by-amount {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: var(--t-h3);
}

/* 信任句：品牌点 + 小字，站内既有句子 */
.by-card__trust {
  margin: var(--s-4) 0 0;
  padding: var(--s-4) 0 0;
  border-top: 1px solid var(--line-1);
  list-style: none;
  display: grid;
  gap: var(--s-2);
}

.by-card__trust li {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--t-micro);
  line-height: var(--lh-micro);
  letter-spacing: var(--ls-micro);
  color: var(--fg-2);
}

.by-card__trust li::before {
  content: "";
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: var(--r-pill);
  background-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-dim);
}

/* ── 步骤二：二维码白卡居中 + 状态药丸 ── */
.by-panel--center .by-h1 { text-align: center; }

.by-pay {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-6);
  margin-top: var(--s-8);
  text-align: center;
}

/* 二维码框：实底白卡，不上玻璃 —— 扫码区背后要干干净净。
   （二维码本体是 buy.js 在 canvas 里画的白底深块，浅色页面直接成立。） */
.by-qr-wrap {
  position: relative;
  width: min(320px, 100%);
  padding: var(--s-6);
  border: 1px solid var(--line-1);
  border-radius: var(--r-xl);
  background-color: var(--bg-2);
  box-shadow: var(--edge-top), var(--shadow-2);
  text-align: center;
}

.by-qr-wrap::before {
  content: "";
  position: absolute;
  top: 0;
  left: var(--s-4);
  right: var(--s-4);
  height: 1px;
  background-image: var(--grad-line);
  opacity: .8;
  pointer-events: none;
}

.by-qr-wrap canvas {
  display: block;
  width: 100%;
  height: auto;
  /* 二维码是像素图形，缩放时必须保持硬边 —— 平滑插值会让识别率下降 */
  image-rendering: pixelated;
  /* 二维码出现时淡入，不要「啪」地贴上去 */
  transition: opacity var(--d-base) var(--e-out);
}

.by-qr-hint {
  margin: var(--s-3) 0 0;
  font-size: var(--t-micro);
  color: var(--fg-2);
  overflow-wrap: anywhere;
}

/* 轮询状态药丸：玻璃药丸 + 呼吸点。
   「呼吸」用静态双层辉光表达（点 + 晕圈），不用 infinite 动画 ——
   全站永续动画额度已满，交易页一条也不加。
   buy.js 出错时会把 className 整个改写成 by-poll is-error，
   所以所有样式都挂在这两个类上，不能依赖别的辅助类。 */
.by-poll {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  margin: 0;
  min-height: 40px;
  padding: 0 var(--s-5);
  border: 1px solid var(--line-2);
  border-radius: var(--r-pill);
  background-color: var(--glass);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  box-shadow: var(--edge-top);
  font-size: var(--t-sm);
  color: var(--fg-1);
}

.by-poll::before {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: var(--r-pill);
  background-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-dim), 0 0 12px rgba(29, 111, 181, .55);
}

.by-poll.is-error {
  border-color: rgba(190, 58, 84, .35);
  color: var(--bad);
}

.by-poll.is-error::before {
  background-color: var(--bad);
  box-shadow: 0 0 0 3px var(--bad-dim);
}

.by-link {
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--brand-lift);
  font-family: inherit;
  font-size: var(--t-body);
  text-decoration: underline;
  cursor: pointer;
  transition: color var(--d-hover) var(--e-color);
}

.by-link:hover {
  color: var(--fg-0);
}

/* ── 步骤三：激活码 ──
   等宽 + 加大字号 + user-select:all：这串字符是用户花钱买到的唯一产物，
   它是本页最隆重的一块 —— 品牌描边 + 品牌辉光玻璃卡 + 大号 mono 码 +
   渐变主按钮的「复制」。 */
.by-code-box {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--s-5);
  flex-wrap: wrap;
  margin: var(--s-6) 0 var(--s-8);
  padding: var(--s-8);
  border: 1px solid rgba(29, 111, 181, .45);
  border-radius: var(--r-xl);
  background-image:
    radial-gradient(90% 80% at 50% 0%, var(--brand-ghost), transparent 75%),
    linear-gradient(150deg, rgba(255, 255, 255, .90), rgba(255, 255, 255, .64));
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  backdrop-filter: blur(14px) saturate(1.2);
  box-shadow: var(--edge-top), var(--glow-brand), var(--shadow-2);
}

.by-code-box::before {
  content: "";
  position: absolute;
  top: 0;
  left: var(--s-6);
  right: var(--s-6);
  height: 1px;
  background-image: var(--grad-line);
  pointer-events: none;
}

.by-code {
  flex: 1 1 320px;
  font-family: var(--font-num);
  /* 比 t-h3 再抬 4px：整页只有它配得上超出字阶的字号 */
  font-size: calc(var(--t-h3) + 4px);
  font-weight: var(--w-bold);
  letter-spacing: 0.06em;
  color: var(--fg-0);
  user-select: all;
  overflow-wrap: anywhere;
}

/* 复制是拿码步骤的主动作：品牌渐变主按钮 + 白光泽扫过 */
.by-copy {
  position: relative;
  min-height: 44px;
  padding: 0 var(--s-6);
  border: 0;
  border-radius: var(--r-md);
  background-image: var(--grad-btn);
  color: var(--on-accent);
  font-family: inherit;
  font-size: var(--t-body);
  font-weight: var(--w-bold);
  cursor: pointer;
  overflow: hidden;
  box-shadow: var(--edge-top), var(--glow-brand);
  transition:
    transform        var(--d-hover) var(--e-out),
    filter           var(--d-hover) var(--e-out),
    background-color var(--d-hover) var(--e-color),
    color            var(--d-hover) var(--e-color),
    box-shadow       var(--d-hover) var(--e-out);
}

.by-copy::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: -70%;
  width: 46%;
  background-image: linear-gradient(105deg, transparent, rgba(255, 255, 255, .55) 50%, transparent);
  transform: skewX(-18deg);
  transition: left var(--d-sheen) ease;
  pointer-events: none;
}

/* hover 反馈拉到和「去支付」同级：拿码步骤里最该被点的就是它。
   抬升 + 提亮 + 加深投影，全部只动 transform/filter/阴影。 */
.by-copy:hover {
  transform: translateY(-2px) scale(1.03);
  filter: brightness(1.08) saturate(1.06);
  box-shadow:
    var(--edge-top), var(--glow-brand), var(--glow-soft),
    0 12px 26px -12px rgba(29, 111, 181, .60);
}
.by-copy:hover::before { left: 130%; }
.by-copy:active {
  transform: translateY(0) scale(1);
  filter: none;
}

.by-copy:focus-visible {
  outline: none;
  box-shadow: var(--focus);
}

.by-next {
  margin: var(--s-8) 0 0;
  padding-left: var(--s-6);
  color: var(--fg-1);
}

.by-next li {
  margin-bottom: var(--s-2);
}

.by-legal {
  margin-top: var(--s-8);
  padding-top: var(--s-6);
  border-top: 1px solid var(--line-1);
  font-size: var(--t-micro);
  line-height: var(--lh-micro);
  color: var(--fg-2);
}

.by-foot {
  max-width: var(--container);
  margin-inline: auto;
  padding: var(--s-8) var(--page-pad);
  border-top: 1px solid var(--line-1);
  font-size: var(--t-micro);
  color: var(--fg-2);
}

.by-foot p {
  margin: 0 0 var(--s-1);
}

/* ── 入场：模糊到清晰 ──
   面板切换（选套餐→支付→拿码）时 [hidden] 摘掉、display 回来，
   动画自动重播一次 —— 每一步都有同一套「聚焦」入场；
   右栏摘要卡不在面板里，只在初次加载时入场一遍。
   三条纪律：
   一、不碰 opacity：内容全程可见，无 JS / 旧浏览器下这段动画
       不跑也只是静态但完整；LCP 候选（h1）从第一帧就算数。
   二、显式 to：隐式 to 会去取门控后的值，这坑首页踩过。
   三、整段包在 no-preference 里，reduce 下 getAnimations() 为 0。 */
@media (prefers-reduced-motion: no-preference) {
  .by-panel {
    animation: by-enter var(--d-slow) var(--e-out);
  }
  .by-side .by-card {
    animation: by-enter var(--d-slow) var(--e-out) backwards;
    animation-delay: var(--stagger);
  }
  /* 套餐卡由 buy.js 拉到数据后注入，出现时依次聚焦。
     backwards 只回填 blur/transform，不含 opacity，不挡渲染。 */
  .by-plan {
    animation: by-enter var(--d-slow) var(--e-out) backwards;
  }
  .by-plan:nth-child(2) { animation-delay: var(--stagger); }
  .by-plan:nth-child(3) { animation-delay: calc(var(--stagger) * 2); }
  .by-plan:nth-child(4) { animation-delay: calc(var(--stagger) * 3); }
  @keyframes by-enter {
    from { transform: translateY(10px); filter: blur(8px); }
    to   { transform: translateY(0);    filter: blur(0); }
  }

  /* 摘要卡金额变化：一次轻微 scale 脉冲。
     buy.js 的 pulsePrice 重加 .is-pulse 触发，一次性、非永续。 */
  .by-card__price.is-pulse {
    animation: by-pulse 360ms var(--e-spring);
  }
  @keyframes by-pulse {
    from { transform: scale(1.05); }
    to   { transform: scale(1); }
  }
}

/* ── 响应式 ── */
@media (max-width: 1279px) {
  .by-shell {
    grid-template-columns: minmax(0, 1fr) 336px;
    gap: var(--s-8);
  }
}

@media (max-width: 899px) {
  /* 摘要卡回落到步骤面板下方，不再粘性 */
  .by-shell {
    grid-template-columns: minmax(0, 1fr);
  }
  .by-side {
    position: static;
  }
}

@media (max-width: 599px) {
  .by-plans {
    grid-template-columns: minmax(0, 1fr);
  }
  /* 三步进度保持横排：圆标收小一号，连接线收短 */
  .by-steps {
    margin-bottom: var(--s-8);
  }
  .by-step {
    gap: var(--s-2);
    font-size: var(--t-micro);
  }
  .by-step::after {
    margin-inline: var(--s-2);
  }
  .by-step__mark {
    width: 26px;
    height: 26px;
  }
  .by-code-box {
    padding: var(--s-6);
  }
}
