/* ══════════════════════════════════════════════════════════════════
   NorthStatus 官网 · 公共样式层
   ------------------------------------------------------------------
   全站唯一的样式源头。四个页面(index / pricing / login / account)
   共用这一份, 改一处四页生效。

   页面专属的样式留在各自 HTML 里(首页的 hero/对比/场景/下载卡、
   价格页的对比表、登录页的表单、账户页的仪表盘), 不往这里塞。

   视觉语言 = ChatGPT 风格单色(黑白灰) + 唯一功能色在线绿 #10A37F。
   铁律: **绿色只给状态**(在线点、在线徽章、对勾)。主操作按钮一律
   单色黑白翻转, 不是绿的。破了这条, 每个真的状态点都变廉价。
   标记 = 18° 前倾平行四边形。字重上限 600, 极简靠克制。
   ══════════════════════════════════════════════════════════════════ */

/* ── 设计 token ─────────────────────────────────────────────────── */
:root{
  color-scheme:light dark;
  --bg:#FFFFFF; --surface:#FAFAFA; --elevated:#F4F4F4;
  --border:#ECECEC; --hair:#EDEDED;
  /* --muted 从 #8E8E8E 提到 #707070:旧值在白底只有 3.28:1、在 elevated 上 2.98:1,
     WCAG AA 要 4.5。而它承载的不只是说明文字, 还有整段「别的机场」对比正文、
     退款说明、登录副标题。我们的用户里有长辈, 这条不能省。
     #707070 = 还能过 4.5 的最浅那档(白底 4.95 / surface 4.74 / elevated 4.50),
     压到这里为止, 再深就伤极简的轻感了。 */
  --text:#0D0D0D; --text-2:#4D4D4D; --muted:#707070; --subtle:#C5C5C5;
  --accent:#0D0D0D; --accent-text:#FFFFFF;
  --online:#10A37F; --online-soft:rgba(16,163,127,.10); --online-line:rgba(16,163,127,.30);
  /* 琥珀从 #D97706 压到 #B45309:旧值白底只有 3.19:1、elevated 上 2.90:1, 不合格。
     (上一轮只补了深色的 --warn/--err, 却漏了浅色 —— 而浅色是默认主题, 是多数人
      实际看到的那一版, 且它的 3.19 比当时修掉的深色 3.33 还差。同一个 token 只修了
      没那么糟的那一半。) 实测 #B45309: 白 5.02 / surface 4.81 / elevated 4.57。
     用在年付卡的「最省心」徽章上, 11.5px/600 是正常文字, 门槛 4.5 不是 3。 */
  --warn:#B45309; --warn-line:rgba(180,83,9,.3);
  --err:#C64545;  --err-line:rgba(198,69,69,.3);
  /* 间距刻度。以前颜色、圆角、缓动都有 token, 唯独间距全靠手打,
     结果同一个分区间距漂出 40/44/48 三个值、页脚漂出 52/34/30。 */
  --sp-1:8px; --sp-2:12px; --sp-3:16px; --sp-4:24px;
  --sp-5:32px; --sp-6:44px; --sp-7:56px; --sp-8:72px;
  /* 字体已真实打包(fonts/fonts.css):拉丁 = Geist, 中文 = MiSans, 数字 = Geist Mono。
     顺序有讲究 —— MiSans 必须排在 -apple-system 之前:Safari 的 -apple-system 自带
     系统级 CJK 回落, 排后面的话中文永远轮不到 MiSans。Geist 在最前抢走拉丁和数字,
     所以拉丁不会被 MiSans 渲染。 */
  --font:"Geist","MiSans",-apple-system,BlinkMacSystemFont,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",system-ui,sans-serif;
  --font-disp:"Geist","MiSans",-apple-system,"PingFang SC",system-ui,sans-serif;
  --font-word:"Geist","MiSans",-apple-system,"PingFang SC",system-ui,sans-serif;
  /* 数字 = 等宽 tabular, 仪表盘质感 */
  --font-num:"Geist Mono",ui-monospace,SFMono-Regular,Menlo,"MiSans","PingFang SC",monospace;
  /* 字号刻度。以前全站散着 39 个字号, 其中六个挤在 .92-.98 之间(差不到 1px),
     一看就是各处手调出来的。收敛成 11 档, 每档一个职责;新写样式从这里取,
     别再手打 font-size 数值。组件级数字展示(1.45/1.5/2.4rem)和标题 clamp() 不进刻度。 */
  --fs-badge:.75rem;    /* 徽章/小标签: 最受欢迎 · 即将上架 · 你的设备 */
  --fs-eyebrow:.76rem;  /* 分区眉题(大写字距那个) */
  --fs-caption:.8rem;   /* 辅助说明: 条款行 · 徽章 pill · 对比栏头 */
  --fs-meta:.86rem;     /* 元信息: 设备副行 · 表单标签 · 页脚横条 */
  --fs-ui:.9rem;        /* 小控件文本: 状态行 · 步骤编号 */
  --fs-small:.94rem;    /* 次级正文: 导航链接 · 列表项 · 套餐描述 */
  --fs-btn:.98rem;      /* 按钮(刻意比正文小一丝, 别合并) */
  --fs-body:1rem;       /* 正文 */
  --fs-body-lg:1.05rem; /* 大正文: 表格金额 · 步骤说明 */
  --fs-lead:1.12rem;    /* 导语/卡片标题 */
  --fs-title:1.3rem;    /* 小节标题(三步的 h3) */
  --wrap:1080px;             /* 账户页会覆盖成 920px(仪表盘窄一些) */
  --r:14px; --r-sm:10px; --r-pill:999px;
  --ease:cubic-bezier(.2,.7,.2,1);
}
/* 深色变体。注意 --warn/--err 以前从来没给过深色值:原来的 --err #C64545
   在深底上只有 3.33:1, 不合格。深色下的红/琥珀必须提亮才够看。 */
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --bg:#212121; --surface:#262626; --elevated:#2E2E2E;
    --border:#3A3A3A; --hair:#333333;
    --text:#ECECEC; --text-2:#B4B4B4; --muted:#959595; --subtle:#6B6B6B;
    --accent:#ECECEC; --accent-text:#0D0D0D;
    --online-soft:rgba(16,163,127,.14); --online-line:rgba(16,163,127,.4);
    --warn:#E8912A; --warn-line:rgba(232,145,42,.35);
    --err:#E8756B;  --err-line:rgba(232,117,107,.35);
  }
}
/* 手动选了主题时, 让 color-scheme 跟着走 —— 否则原生滚动条 / 输入框 / 自动填充
   还按操作系统的深浅渲染:OS 深色但网站被手动切成浅色时, 滚动条会是深的, 对不上。
   没设 data-theme(跟随系统)时保持 :root 上的 light dark 由系统决定。 */
:root[data-theme="light"]{color-scheme:light}
:root[data-theme="dark"]{color-scheme:dark}
:root[data-theme="dark"]{
  --bg:#212121; --surface:#262626; --elevated:#2E2E2E;
  --border:#3A3A3A; --hair:#333333;
  --text:#ECECEC; --text-2:#B4B4B4; --muted:#959595; --subtle:#6B6B6B;
  --accent:#ECECEC; --accent-text:#0D0D0D;
  --online-soft:rgba(16,163,127,.14); --online-line:rgba(16,163,127,.4);
  --warn:#E8912A; --warn-line:rgba(232,145,42,.35);
  --err:#E8756B;  --err-line:rgba(232,117,107,.35);
}

/* ── 基础 ───────────────────────────────────────────────────────── */
*{box-sizing:border-box}
html{scroll-behavior:smooth;scroll-padding-top:80px;-webkit-text-size-adjust:100%}
/* 注意: body 上没有 background/color 的 transition。
   有了它, 主题切换会变成「结构瞬间到位、背景慢慢爬 300ms」的四速动画,
   顶部导航会横着一条颜色不对的带子。切主题就该是干净的一帧。 */
body{margin:0;background:var(--bg);color:var(--text);font-family:var(--font);
  font-size:16px;line-height:1.7;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
h1,h2,h3,h4,p{margin:0}
a{color:inherit;text-decoration:none}
svg{display:block}
/* 单色系统里黑色聚焦框看不见, 这是绿色唯一正当的非状态用法 */
:focus-visible{outline:2px solid var(--online);outline-offset:3px;border-radius:4px}

/* 切主题的那一帧把所有过渡掐掉, 避免 hover 的 transition 被复用成主题动画 */
:root.theme-switching *{transition:none!important}

/* ── 工具 ───────────────────────────────────────────────────────── */
.wrap{width:100%;max-width:var(--wrap);margin:0 auto;padding:0 28px}
.num{font-family:var(--font-num);font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}
.eyebrow{font-size:var(--fs-eyebrow);font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--muted)}
.mk{color:var(--text)}
/* 绿勾 / 绿色状态图标。以前每个 svg 都写死 stroke="#10A37F", 全站 44 处,
   等于这个牌子最宝贝的颜色是靠全文替换在管。现在图标一律 currentColor,
   颜色由这个类给, token 说了算。 */
.ic-ok{color:var(--online)}

/* 在线点 + 呼吸环。四页共用, 别再只给宣传页留环、把仪表盘的真状态点做成死的 */
.dot{width:8px;height:8px;border-radius:50%;background:var(--online);position:relative;flex:0 0 auto}
.dot::after{content:"";position:absolute;inset:-4px;border-radius:50%;border:1.5px solid var(--online);
  animation:ring 2.4s ease-out infinite;opacity:0}
@keyframes ring{0%{transform:scale(.6);opacity:.6}100%{transform:scale(2);opacity:0}}

/* ── 按钮:主操作单色(黑/白翻转), 绿色不参与 ────────────────────── */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;font-family:var(--font);
  font-weight:600;font-size:var(--fs-btn);line-height:1;cursor:pointer;border:1px solid transparent;
  border-radius:var(--r-pill);padding:13px 24px;white-space:nowrap;
  transition:transform .15s var(--ease),opacity .2s,background .2s,border-color .2s,color .2s}
.btn:active{transform:translateY(1px)}
.btn-fill{background:var(--accent);color:var(--accent-text)}
.btn-fill:hover{opacity:.88}
.btn-line{background:transparent;color:var(--text);border-color:var(--border)}
.btn-line:hover{border-color:var(--text)}
.btn-text{padding:13px 4px;color:var(--text)}
.btn-text:hover{color:var(--online)}
.btn-sm{padding:9px 17px;font-size:var(--fs-ui)}
.btn-block{width:100%}
.btn[aria-disabled="true"]{opacity:.45;pointer-events:none}
.arw{width:16px;height:16px}

/* ── 导航 ───────────────────────────────────────────────────────── */
/* saturate() 在单色系统里唯一能作用到的就是绿色(会把它染到导航栏上), 只留 blur */
.nav{position:sticky;top:0;z-index:50;background:color-mix(in srgb,var(--bg) 82%,transparent);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  border-bottom:1px solid var(--hair)}
/* 宽度一律交给 .wrap(用法: <div class="wrap nav-in">), 别在这儿另写 max-width,
   否则导航和正文会各宽各的、logo 和正文左边缘对不齐 */
.nav-in{display:flex;align-items:center;gap:26px;height:62px}
.brand{display:flex;align-items:center;gap:11px}
.brand .mkbox{width:22px;height:22px}
.brand .wm{font-family:var(--font-word);font-weight:600;font-size:var(--fs-lead);letter-spacing:-.028em;color:var(--text)}
.nav-links{display:flex;gap:26px;margin-left:12px}
.nav-links a{color:var(--text-2);font-weight:500;font-size:var(--fs-small);transition:color .18s}
.nav-links a:hover{color:var(--text)}
.nav-links a.cur{color:var(--text);font-weight:600}
.nav-cta{margin-left:auto;display:flex;align-items:center;gap:12px}
/* 语言切换:桌面在导航条上做一个小文字链接, 手机上藏起来、收进汉堡(和登录项同一套路)。
   链接指向对应的另一语言同名页(中文页 → en/ 下同名, 英文页 → 上一级同名)。 */
.nav-lang{display:inline-flex;align-items:center;gap:6px;font-size:var(--fs-small);font-weight:600;
  color:var(--text-2);padding:8px 10px;border-radius:var(--r-pill);transition:color .18s;white-space:nowrap}
.nav-lang:hover{color:var(--text)}
.nav-lang svg{width:15px;height:15px}

.theme-tg{width:38px;height:38px;flex:0 0 auto;border-radius:var(--r-pill);border:1px solid var(--border);background:transparent;
  color:var(--text);cursor:pointer;display:flex;align-items:center;justify-content:center;
  transition:border-color .2s,background .2s}
.theme-tg:hover{border-color:var(--text)}
.theme-tg .sun{display:none}
:root[data-theme="dark"] .theme-tg .sun{display:block}
:root[data-theme="dark"] .theme-tg .moon{display:none}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .theme-tg .sun{display:block}
  :root:not([data-theme="light"]) .theme-tg .moon{display:none}
}
:root[data-theme="light"] .theme-tg .sun{display:none!important}
:root[data-theme="light"] .theme-tg .moon{display:block!important}

/* 汉堡菜单(仅 <=767px 出现) */
.nav-mb{display:none;width:38px;height:38px;flex:0 0 auto;border-radius:var(--r-pill);border:1px solid var(--border);
  background:transparent;color:var(--text);cursor:pointer;align-items:center;justify-content:center}
.nav-mb:hover{border-color:var(--text)}
.nav-mb svg{width:17px;height:17px}
/* 图标跟着 aria-expanded 走, 和主题钮、密码眼睛一样都会换形 */
.nav-mb .ic-close{display:none}
.nav-mb[aria-expanded="true"] .ic-menu{display:none}
.nav-mb[aria-expanded="true"] .ic-close{display:block}
.nav-menu{display:none;border-top:1px solid var(--hair);background:var(--bg)}
.nav-menu.open{display:block}
.nav-menu ul{list-style:none;margin:0;padding:6px 0 10px}
.nav-menu a{display:block;padding:13px 28px;color:var(--text-2);font-weight:500;font-size:var(--fs-body);min-height:44px}
.nav-menu a:active{background:var(--surface);color:var(--text)}
/* 菜单里的登录/退出项:平时藏着(桌面用右上角药丸), 手机上药丸收起时它顶上 */
.nav-menu .m-auth{display:none;border-top:1px solid var(--hair);margin-top:6px;color:var(--text);font-weight:600}
/* 菜单里的语言项:同样平时藏着, 手机上桌面那个小语言链接收起时由它接手 */
.nav-menu .m-lang{display:none}

/* ── 分区节奏 — 极简靠留白 ─────────────────────────────────────── */
.sec{padding:clamp(72px,10vw,120px) 0}
.sec-line{border-top:1px solid var(--hair)}
/* 分区标题与下方内容的间距统一走 token。以前是每处内联 style 手打,
   于是同一种间距在四页里漂成了 40 / 44 / 48 三个值。 */
.lead-head{max-width:680px;margin-bottom:var(--sp-6)}
.lead-head.ctr{margin-left:auto;margin-right:auto;text-align:center}
.lead-head .eyebrow{display:block;margin-bottom:18px}
.lead-head h1{font-family:var(--font-disp);font-size:clamp(2rem,4.6vw,3rem);font-weight:600;
  letter-spacing:-.018em;line-height:1.12;text-wrap:balance}
.lead-head h2{font-family:var(--font-disp);font-size:clamp(1.85rem,3.8vw,2.7rem);font-weight:600;
  letter-spacing:-.014em;line-height:1.18;text-wrap:balance}
.lead-head p{color:var(--text-2);font-size:var(--fs-lead);margin-top:18px;line-height:1.6}

/* ── 套餐卡(首页价格区 + 价格页共用) ──────────────────────────── */
.plans{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;align-items:stretch}
.plan{border:1px solid var(--border);border-radius:var(--r);padding:30px;display:flex;flex-direction:column}
/* 只换颜色不加粗:1.5px 边框会让内容盒偏移 .5px, 这张卡的文字会比邻居差一个物理像素 */
.plan.pop{border-color:var(--online)}
.plan .ptop{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px;min-height:26px}
.plan .name{font-weight:600;font-size:var(--fs-lead)}
/* 徽章文字用中性色, 绿只留给真状态。绿字在这个字号(11.5px)只有 3.20:1, 不过 4.5,
   而且「最受欢迎 / 高价值 / 你的设备 / 即将上架」全用绿, 绿就从信号退化成装饰,
   首屏那个「在线」绿点的说服力跟着被稀释。边框留绿, 徽章还是绿的, 字能读。 */
.plan .flag{font-size:var(--fs-badge);font-weight:600;color:var(--text-2);border:1px solid var(--online-line);
  padding:3px 9px;border-radius:var(--r-pill)}
/* .flag.amber 删掉了:它给「最省心」用 --warn, 而 --warn 正是状态条里 .b-warn
   「那天线路不太好」的故障色。同一屏里同一个橙色, 一边表示故障日、一边表示年付最划算,
   语义直接反了。不能拿故障色夸自己。「最省心」和「最受欢迎」用同一套中性样式。 */
.plan .price{display:flex;align-items:baseline;gap:5px;margin:12px 0 4px}
/* 字重 600 = 系统字重上限。别写 520/540 这种幻觉精度:回落字体会把它们
   吸附到 600, 等 Geist Mono 真打包进来那天, 所有价格和头条数字会突然变细。 */
.plan .price .amt{font-family:var(--font-num);font-variant-numeric:tabular-nums;font-weight:600;
  font-size:2.4rem;letter-spacing:-.02em}
.plan .price .per{color:var(--muted);font-weight:500}
/* 「省 20% / 随时可停」这类卖点行:绿字在 13.8px 只有 3.20:1 过不了 AA,
   且是营销高亮不是状态。改中性近黑加粗, 一样醒目, 绿只留给在线信号。 */
.plan .hl{color:var(--text);font-size:var(--fs-meta);font-weight:600;margin:2px 0 14px}
.plan .desc{color:var(--text-2);font-size:var(--fs-small);min-height:42px;line-height:1.5}
.plan ul{list-style:none;padding:0;margin:20px 0 26px;display:flex;flex-direction:column;gap:12px}
.plan li{display:flex;gap:10px;align-items:flex-start;color:var(--text-2);font-size:var(--fs-small)}
.plan .ic{width:20px;height:20px;flex:0 0 auto;margin-top:1px}
.plan .btn{margin-top:auto}
.price-foot{margin-top:26px;color:var(--muted);font-size:var(--fs-small);text-align:center}

/* ── 兑换码 ─────────────────────────────────────────────────────── */
/* 价格页和账户页是同一个东西, 以前各写了一份(一个自带边框 24/28、
   一个塞在 .card 里 28/30)。现在一个组件, 两处复用:
   独立成块时加 .redeem-box(自带边框), 嵌在卡片里就只用 .redeem。 */
.redeem{display:flex;align-items:center;gap:var(--sp-4);flex-wrap:wrap}
.redeem-box{border:1px solid var(--border);border-radius:var(--r);padding:var(--sp-4) var(--sp-5)}
.redeem .rd-txt{flex:1;min-width:220px}
.redeem .rd-txt h2,.redeem .rd-txt h3{font-size:var(--fs-lead);font-weight:600}
.redeem .rd-txt p{color:var(--muted);font-size:var(--fs-small);margin-top:5px;line-height:1.55}
.rd-form{display:flex;gap:10px;flex-wrap:wrap}
/* 16px 是硬底线：iOS 聚焦字号 < 16px 的输入框就会自动放大整页，
   而且跟屏幕宽度无关，iPad 横屏同样中招，所以不能只在手机断点里改。 */
.rd-input{font-family:var(--font);font-size:16px;padding:12px 18px;border:1px solid var(--border);
  border-radius:var(--r-pill);background:var(--surface);color:var(--text);min-width:210px;
  transition:border-color .2s,background .2s}
.rd-input::placeholder{color:var(--subtle)}
.rd-input:focus{outline:none;border-color:var(--text);background:var(--bg)}

/* ── FAQ — 只留分割线 ──────────────────────────────────────────── */
.faq{max-width:760px;margin:0 auto;border-top:1px solid var(--hair)}
.q{border-bottom:1px solid var(--hair)}
.q summary{list-style:none;cursor:pointer;padding:22px 4px;font-weight:600;font-size:var(--fs-body-lg);
  display:flex;align-items:center;justify-content:space-between;gap:16px}
.q summary::-webkit-details-marker{display:none}
.q .chev{width:18px;height:18px;color:var(--muted);transition:transform .22s var(--ease),color .18s}
/* 全站唯一没有 hover 反馈的可点元素 —— 强化已有的箭头, 不另加装饰 */
.q summary:hover .chev,.q summary:active .chev{color:var(--text)}
.q[open] .chev{transform:rotate(180deg)}
.q .a{padding:0 4px 24px;color:var(--text-2);font-size:var(--fs-body);line-height:1.65;max-width:62ch}

/* ── 收尾卡 ─────────────────────────────────────────────────────── */
/* 曾是黑底反白大板, 太突兀, 改成浅色 elevated 卡 + 细描边。
   按钮就用 .btn-fill(单色), 不要在这儿写绿色:同一页同样四个字,
   hero 里是黑的、底下变绿药丸 = 漂移, 而且它会是全站最大一块饱和色。 */
.final{background:var(--elevated);color:var(--text);border:1px solid var(--border);
  border-radius:calc(var(--r)*1.6);padding:clamp(56px,8vw,88px) 32px;text-align:center;
  position:relative;overflow:hidden}
.final-mk{position:absolute;bottom:-30%;left:-4%;width:min(40vw,360px);color:var(--text);
  opacity:.035;pointer-events:none}
.final h2{position:relative;font-family:var(--font-disp);font-size:clamp(1.95rem,4.2vw,2.95rem);
  font-weight:600;letter-spacing:-.014em;line-height:1.16;text-wrap:balance}
.final p{position:relative;color:var(--text-2);margin-top:16px;font-size:var(--fs-lead)}
.final .btn{position:relative;margin-top:30px}

/* ── 页脚:两种形态 ─────────────────────────────────────────────── */
/* 默认 = 营销页的四列大页脚(首页/价格)。加 .foot-slim = 登录后页面的单行版。
   以前是三个页面各写各的 padding(52/34/30), 现在是一个显式的变体。 */
.foot{border-top:1px solid var(--hair);padding:52px 0 40px}
.foot-grid{display:grid;grid-template-columns:1.7fr 1fr 1fr 1fr;gap:32px}
.foot .brand{margin-bottom:14px}
.foot p{color:var(--muted);font-size:var(--fs-small);max-width:32ch;line-height:1.6}
.foot h4{font-size:var(--fs-caption);letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin-bottom:16px}
.foot ul{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:11px}
.foot ul a{color:var(--text-2);font-size:var(--fs-small);transition:color .18s}
.foot ul a:hover{color:var(--text)}
.foot-bar{display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;
  color:var(--muted);font-size:var(--fs-meta)}
.foot-bar .st{display:flex;align-items:center;gap:8px}
.foot-bar .fl{display:flex;gap:20px}
.foot-bar a{color:var(--muted);transition:color .18s}
.foot-bar a:hover{color:var(--text)}
/* 大页脚里的横条要跟上面的四列分开 */
.foot:not(.foot-slim) .foot-bar{margin-top:38px;padding-top:22px;border-top:1px solid var(--hair)}
.foot-slim{padding:30px 0}

/* ── 进场 ───────────────────────────────────────────────────────── */
/* 进场淡入。【注意选择器上的 html.js 前缀, 那不是装饰】——
   "默认藏起来, 等 JS 来揭幕" 是个危险图式: JS 但凡没跑成, 正文就永远是 opacity:0,
   而且静悄悄的, 看着像页面加载失败。对我们尤其要命 —— 用户天然在恶劣网络上,
   site.js 被拦 / 加载超时 / 老浏览器解析失败 都不是小概率事件。
   所以隐藏态由 <head> 内联脚本挂上 html.js 才生效, 且那段脚本同时起一个 4 秒看门狗,
   site.js 把 IntersectionObserver 装好后才撤。任何一环断掉 —— 脚本没加载、抛异常、
   浏览器太老 —— html.js 都会被摘掉, 正文显形。无 JS 环境则从头到尾就没藏过。

   ⚠️ 这条规则和各页 <head> 里那段内联脚本是【一对】, 改一边必须改另一边:
   CSS 有 html.js 门而脚本不挂 js 类 = 正文永不隐藏(动效没了, 但不致命);
   脚本挂了 js 类而 CSS 没有门 = 看门狗形同虚设(摘掉 js 类也无济于事)。
   后者曾在线上出现过几小时 —— 不是代码错, 是 CDN 把旧 CSS 缓存在了新哈希 URL 上,
   见 stamp-assets.py 里"验证动作本身会污染缓存"那段。 */
/* 视觉隐藏但仍被屏幕阅读器朗读。用于给"只有图标没有文字"的内容补上可读文本 ——
   典型是价格对比表里的对勾: 那些 SVG 是 aria-hidden 的, 不补文本的话 AT 用户读到的
   整行都是空的, 而那张表的全部意义就是说明"你买到什么"。
   不用 display:none / visibility:hidden —— 那两个会把内容从无障碍树里一并摘掉。 */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

html.js .rv{opacity:0;transform:translateY(16px);transition:opacity .5s var(--ease),transform .5s var(--ease)}
html.js .rv.in{opacity:1;transform:none}

/* ── 响应式 ──────────────────────────────────────────────────────
   三个断点各管一件事, 别混:
   880 = 触控。iPad 也是手指, 所以 44px 点击目标和安全区盖到 880。
   767 = 导航。再窄放不下四个链接, 收进汉堡;768 起(iPad 竖屏)真链接回归。
   640 = 堆叠。再窄多列内容喘不过气, 才允许塌成单栏。
   以前只有一个 880 一刀切, iPad 竖屏(768)被当成手机:
   卡片被拉成 712px 宽的单栏, ¥28 孤零零漂在一张巨卡里。 */

/* 触控层(≤880, 含 iPad 竖屏) */
@media (max-width:880px){
  .theme-tg,.nav-mb{width:44px;height:44px}
  .btn-sm{padding:14px 18px}
  .foot ul a,.foot-bar a{display:inline-block;padding:6px 0}
  /* 平板档(768-880)顶部还是真链接, 但纯文字的点击高度只有 ~26px。
     补上下 padding 撑到 48px 手指点得准(≤767 这些链接已收进汉堡, 不受影响)。 */
  .nav-links a{padding:11px 0}
  .wrap{padding-left:max(28px,env(safe-area-inset-left));padding-right:max(28px,env(safe-area-inset-right))}
  .foot{padding-bottom:max(40px,env(safe-area-inset-bottom))}
  .foot-slim{padding-bottom:max(30px,env(safe-area-inset-bottom))}
}

/* 平板档(641-880):保持多列, 只把套餐卡收紧一点让三列站得下 */
@media (min-width:641px) and (max-width:880px){
  .plans{gap:12px}
  .plan{padding:22px 20px}
}

/* 导航层(≤767):四个链接放不下了, 收进汉堡。
   连右上角那颗登录/退出药丸也一起收进去 —— 窄屏(≈360px)下
   brand + 主题钮 + 药丸 + 汉堡四件挤不开, 药丸文字会折成两行、整条导航撑破。
   规则收成一句: 汉堡一出现就由它统管全部导航动作, 顶栏只剩 brand + 主题 + 汉堡。 */
@media (max-width:767px){
  .nav-links{display:none}
  .nav-mb{display:flex}
  .nav-cta>.btn{display:none}
  .nav-lang{display:none}
  .nav-menu .m-auth{display:block}
  .nav-menu .m-lang{display:block}
}

/* 堆叠层(≤640):真手机, 多列塌成单栏 */
@media (max-width:640px){
  .plans{grid-template-columns:1fr}
  .foot-grid{grid-template-columns:1fr 1fr}
  .rd-input{flex:1}
  .rd-form{width:100%}
}

/* 窄手机(≤360, 常见于旧安卓/iPhone SE):28px 两侧留白在这么窄的屏上太奢侈,
   收到 20px 给内容让路, 顺带收紧导航 brand 与右侧控件之间的呼吸位,
   保证最窄的 320px 顶栏也绝不横向溢出。主流手机(375+)不受影响。 */
@media (max-width:360px){
  .wrap{padding-left:max(20px,env(safe-area-inset-left));padding-right:max(20px,env(safe-area-inset-right))}
  .nav-in{gap:16px}
}

/* 尊重系统的「减少动态效果」 */
@media (prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important;scroll-behavior:auto!important}
  html.js .rv{opacity:1;transform:none}   /* 跟上面同权重, 否则这条覆盖不生效 */
}
