
/* 系统字体本地声明(handoff fonts.css 同款) */
@font-face{font-family:'PingFang SC';src:local('PingFang SC');font-weight:100 900;font-display:swap}
@font-face{font-family:'HarmonyOS Sans SC';src:local('HarmonyOS Sans SC');font-weight:100 900;font-display:swap}
@font-face{font-family:'MiSans';src:local('MiSans');font-weight:100 900;font-display:swap}
@font-face{font-family:'Microsoft YaHei';src:local('Microsoft YaHei');font-weight:100 900;font-display:swap}
/* ============================================================
   RelaySail 控制台 · 设计系统：Apple Human Interface Guidelines（2025，Liquid Glass 一代）
   与交换台、公开站同一套语言，参照 developer.apple.com/design：

   · 颜色：沿用 08-20 定下的苹果式单色——浅色按钮黑 #1d1d1f，深色云白 #f5f5f7；
     彩色只留给语义和数据。系统色取 HIG 2025 那张表：--ok / --warn / --bad 是
     点、开关、进度条用的鲜艳版，--*-text 是当文字用的那一版（浅色取「提高对比度」
     列，白底上过 4.5:1）。
   · 层级：分组背景 #f5f5f7 上放白卡片（apple.com / iOS 设置的做法）；深色是纯黑底 +
     #1c1c1e 卡片。文字三级：#1d1d1f / #6e6e73 / #86868b。
   · 材质：顶栏、实时条、菜单、弹层是玻璃（半透明 + 模糊 + 提饱和），内容层不用。
   · 形状：按钮和小章一律胶囊，卡片 18px，弹层 26px。
   · 焦点：键盘焦点一圈蓝环（macOS 的 keyboardFocusIndicator）。
   旧令牌名一个都没改（JS 里几十处内联样式引用它们），改的是取值；派生色按
   「名字即算式」整体重算。
   ============================================================ */
:root{
  color-scheme:light;
  /* 旧的 OpenRouter 品牌原色名还有人引用，指到 HIG 里对应的值上 */
  --or-ink:#1d1d1f; --or-cloud:#f5f5f7; --or-grape:#1d1d1f; --or-volt:#f5f5f7;
  --or-coral:#e5501e; --or-royal:#0066cc;

  --bg:#f5f5f7; --surface:#ffffff; --surface-2:#f9f9fb; --surface-3:#f2f2f7;
  --line:#e3e3e8; --line-soft:#ededf0;
  --text:#1d1d1f; --dim:#6e6e73; --faint:#86868b;
  --brand:#1d1d1f; --brand-2:#1d1d1f; --brand-dim:rgba(0,0,0,.05);
  --ok:#34c759; --warn:#ff8d28; --bad:#ff383c;
  --ok-text:#008932; --warn-text:#c55300; --bad-text:#e9152d;
  /* 状态格里「有记录、当天没人调用」那一档。是 --ok 的淡版而不是一个中性灰：
     没人调用不是故障，它该待在绿这一族里，只是不该和真跑过流量的那天一样响。 */
  --ok-quiet:rgba(52,199,89,.34);
  --warn-dim:rgba(255,141,40,.1); --warn-a40:rgba(255,141,40,.4);
  /* 协议色：HIG 系统色「提高对比度」那一列，当文字用也读得清 */
  --ac:#c4561f; --oa:#008575; --gm:#1e6ef4; --im:#b02fc2; --ts:#a16a00;
  --btn-ink:#ffffff; --code-bg:#f5f5f7;
  --input-bg:#ffffff; --input-line:#d2d2d7;
  --card-grad:#ffffff;
  --card-shadow:0 1px 2px rgba(0,0,0,.04),0 2px 8px rgba(0,0,0,.03);
  --scrim:rgba(0,0,0,.24);
  --shadow-1:0 20px 56px rgba(0,0,0,.16),0 2px 8px rgba(0,0,0,.05),0 0 0 .5px rgba(0,0,0,.07);
  --shadow-3:0 10px 30px rgba(0,0,0,.13),0 1px 4px rgba(0,0,0,.05),0 0 0 .5px rgba(0,0,0,.07);
  /* 状态点不发光：光晕三参归零，旧组件里写死的光晕因此自动塌成扁平 */
  --halo-blur:0px; --halo-spread:0px; --halo-alpha:0%;
  /* 一层很淡的墨色：行悬停、展开行、次要按钮悬停都用它 */
  --ctl-on-bg:rgba(0,0,0,.04); --ctl-on-ring:inset 0 0 0 1px var(--line);
  /* 顶栏与实时条：导航层的玻璃 */
  /* 玻璃按台面的颜色调：静止时和页面融成一片，内容滚到底下才看出材质（HIG 的 scroll edge） */
  --rail-bg:rgba(245,245,247,.8); --rail-line:rgba(0,0,0,.08); --rail-hover:rgba(0,0,0,.05);
  --rail-text:#1d1d1f; --rail-dim:#515154; --rail-faint:#86868b;
  --toast-bg:rgba(255,255,255,.86); --toast-text:#1d1d1f; --toast-line:rgba(0,0,0,.08);
  --sans:-apple-system,BlinkMacSystemFont,'SF Pro Text','Helvetica Neue','PingFang SC','Hiragino Sans GB','HarmonyOS Sans SC','MiSans','Segoe UI','Microsoft YaHei',system-ui,sans-serif;
  --disp:-apple-system,BlinkMacSystemFont,'SF Pro Display','Helvetica Neue','PingFang SC','Hiragino Sans GB','HarmonyOS Sans SC','MiSans','Segoe UI','Microsoft YaHei',system-ui,sans-serif;
  --mono:ui-monospace,'SF Mono',SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono',monospace;
  /* 圆角刻度：小章 6 / 控件 8 / 输入 10 / 卡片 18 / 弹层 26 / 胶囊 */
  --r-sm:6px; --r-md:8px; --r-lg:10px; --r-xl:18px; --r-2xl:26px; --r-pill:980px;
  /* 键盘焦点：一圈蓝环 */
  --focus-line:#0071e3; --focus-ring:0 0 0 3px rgba(0,113,227,.3);
  /* HIG 新增：链接蓝、系统填充四级、玻璃、曲线、实心按钮的悬停 / 按下 */
  --link:#0066cc;
  --fill-1:rgba(120,120,128,.2); --fill-2:rgba(120,120,128,.16); --fill-3:rgba(118,118,128,.12); --fill-4:rgba(116,116,128,.08);
  --glass:rgba(250,250,252,.78); --glass-thick:rgba(255,255,255,.92);
  --blur:saturate(180%) blur(20px); --sheen:inset 0 1px 0 rgba(255,255,255,.85);
  --seg-thumb:#ffffff; --seg-thumb-ring:0 3px 8px rgba(0,0,0,.12),0 1px 1px rgba(0,0,0,.04),0 0 0 .5px rgba(0,0,0,.04);
  --btn-hover:#333336; --btn-press:#000000;
  --ease:cubic-bezier(.25,.1,.25,1); --ease-out:cubic-bezier(.22,1,.36,1); --spring:cubic-bezier(.32,.72,0,1);
  /* 派生色：命名即算式，两套主题各算一份。旧名全部保留。 */
  --warn-a40:rgba(255,141,40,.4); --ac-a12:rgba(196,86,31,.12); --bad-a11:rgba(255,56,60,.11);
  --bad-a40:rgba(255,56,60,.4); --bad-a60:rgba(255,56,60,.6); --bad-a9:rgba(255,56,60,.09);
  --bad-ahalo:rgba(255,56,60,0); --bg-a86:rgba(245,245,247,.86); --brand-30-on-line-soft:#afafb1;
  --brand-30-on-surface-3:#b2b2b6; --brand-38-on-line:#98989c; --brand-40-on-line:#949498;
  --brand-5-on-surface:#f4f4f4; --brand-50-on-line:#808084; --brand-55-on-line:#767679;
  --brand-55-on-surface-3:#7d7d80; --brand-62-on-line:#68686b; --brand-80-on-surface-3:#48484a;
  --brand-82-on-surface-3:#434346; --brand-a38:rgba(29,29,31,.38); --brand-a40:rgba(29,29,31,.4);
  --brand-a52:rgba(29,29,31,.52); --brand-a55:rgba(29,29,31,.55); --brand-a60:rgba(29,29,31,.6);
  --brand-ahalo:rgba(29,29,31,0); --brand-ahalohalf:rgba(29,29,31,0); --brandink-55-on-rail-line:#767679;
  --btn-ink-a35:rgba(255,255,255,.35); --faint-a10:rgba(134,134,139,.1); --faint-a16:rgba(134,134,139,.16);
  --faint-a28:rgba(134,134,139,.28); --faint-a30:rgba(134,134,139,.3); --faint-a32:rgba(134,134,139,.32);
  --faint-a38:rgba(134,134,139,.38); --faint-a42:rgba(134,134,139,.42); --faint-a45:rgba(134,134,139,.45);
  --faint-a60:rgba(134,134,139,.6); --gm-a12:rgba(30,110,244,.12); --im-a12:rgba(176,47,194,.12);
  --ts-a12:rgba(161,106,0,.12); --oa-a12:rgba(0,133,117,.12); --ok-a12:rgba(52,199,89,.12);
  --ok-a60:rgba(52,199,89,.6); --ok-ahalo:rgba(52,199,89,0); --surface-3-a50:rgba(242,242,247,.5);
  --text-a16:rgba(29,29,31,.16); --text-a60:rgba(29,29,31,.6); --warn-a12:rgba(255,141,40,.12);
  --warn-ahalo:rgba(255,141,40,0);
}
/* 深色：纯黑底 + 抬升一级的卡片，按钮反成云白底墨字 */
[data-theme=dark]{
  color-scheme:dark;
  --bg:#000000; --surface:#1c1c1e; --surface-2:#232325; --surface-3:#2c2c2e;
  --line:#38383a; --line-soft:#2a2a2c;
  --text:#f5f5f7; --dim:#a1a1a6; --faint:#7c7c80;
  --brand:#f5f5f7; --brand-2:#f5f5f7; --brand-dim:rgba(245,245,247,.1);
  --ok:#30d158; --warn:#ff9230; --bad:#ff4245;
  --ok-text:#30d158; --warn-text:#ff9230; --bad-text:#ff4245;
  --ok-quiet:rgba(48,209,88,.34);
  --warn-dim:rgba(255,146,48,.12); --warn-a40:rgba(255,146,48,.4);
  --ac:#ff9a6b; --oa:#00dac3; --gm:#0091ff; --im:#db34f2; --ts:#ffd600;
  --btn-ink:#1d1d1f; --code-bg:#111113;
  --input-bg:#232325; --input-line:#48484a;
  --card-grad:#1c1c1e;
  --card-shadow:none;
  --scrim:rgba(0,0,0,.5);
  --shadow-1:0 24px 64px rgba(0,0,0,.6),0 0 0 .5px rgba(255,255,255,.1);
  --shadow-3:0 12px 32px rgba(0,0,0,.5),0 0 0 .5px rgba(255,255,255,.1);
  --ctl-on-bg:rgba(255,255,255,.06); --ctl-on-ring:inset 0 0 0 1px var(--line);
  --rail-bg:rgba(0,0,0,.72); --rail-line:rgba(255,255,255,.1); --rail-hover:rgba(255,255,255,.08);
  --rail-text:#f5f5f7; --rail-dim:#a1a1a6; --rail-faint:#7c7c80;
  --toast-bg:rgba(44,44,46,.86); --toast-text:#f5f5f7; --toast-line:rgba(255,255,255,.1);
  --focus-line:#0a84ff; --focus-ring:0 0 0 3px rgba(10,132,255,.5);
  --link:#2997ff;
  --fill-1:rgba(120,120,128,.36); --fill-2:rgba(120,120,128,.32); --fill-3:rgba(118,118,128,.24); --fill-4:rgba(116,116,128,.18);
  --glass:rgba(22,22,23,.72); --glass-thick:rgba(44,44,46,.9);
  --sheen:inset 0 1px 0 rgba(255,255,255,.07);
  --seg-thumb:#636366; --seg-thumb-ring:0 1px 3px rgba(0,0,0,.32);
  --btn-hover:#ffffff; --btn-press:#e3e3e8;
  --warn-a40:rgba(255,146,48,.4); --ac-a12:rgba(255,154,107,.12); --bad-a11:rgba(255,66,69,.11);
  --bad-a40:rgba(255,66,69,.4); --bad-a60:rgba(255,66,69,.6); --bad-a9:rgba(255,66,69,.09);
  --bad-ahalo:rgba(255,66,69,0); --bg-a86:rgba(0,0,0,.86); --brand-30-on-line-soft:#676769;
  --brand-30-on-surface-3:#68686a; --brand-38-on-line:#808082; --brand-40-on-line:#848486;
  --brand-5-on-surface:#272729; --brand-50-on-line:#969698; --brand-55-on-line:#a0a0a2;
  --brand-55-on-surface-3:#9b9b9d; --brand-62-on-line:#adadaf; --brand-80-on-surface-3:#cdcdcf;
  --brand-82-on-surface-3:#d1d1d3; --brand-a38:rgba(245,245,247,.38); --brand-a40:rgba(245,245,247,.4);
  --brand-a52:rgba(245,245,247,.52); --brand-a55:rgba(245,245,247,.55); --brand-a60:rgba(245,245,247,.6);
  --brand-ahalo:rgba(245,245,247,0); --brand-ahalohalf:rgba(245,245,247,0); --brandink-55-on-rail-line:#a0a0a2;
  --btn-ink-a35:rgba(29,29,31,.35); --faint-a10:rgba(124,124,128,.1); --faint-a16:rgba(124,124,128,.16);
  --faint-a28:rgba(124,124,128,.28); --faint-a30:rgba(124,124,128,.3); --faint-a32:rgba(124,124,128,.32);
  --faint-a38:rgba(124,124,128,.38); --faint-a42:rgba(124,124,128,.42); --faint-a45:rgba(124,124,128,.45);
  --faint-a60:rgba(124,124,128,.6); --gm-a12:rgba(0,145,255,.12); --im-a12:rgba(219,52,242,.12);
  --ts-a12:rgba(255,214,0,.12); --oa-a12:rgba(0,218,195,.12); --ok-a12:rgba(48,209,88,.12);
  --ok-a60:rgba(48,209,88,.6); --ok-ahalo:rgba(48,209,88,0); --surface-3-a50:rgba(44,44,46,.5);
  --text-a16:rgba(245,245,247,.16); --text-a60:rgba(245,245,247,.6); --warn-a12:rgba(255,146,48,.12);
  --warn-ahalo:rgba(255,146,48,0);
}
@media (prefers-reduced-motion:no-preference){
  html.theme-fade,html.theme-fade *{transition:background-color .2s ease,color .2s ease,border-color .2s ease}
}
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{background:var(--bg);color:var(--text);font-family:var(--sans);font-size:14px;font-weight:400;
  line-height:1.5;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizeLegibility}
/* 选中文字用系统的淡蓝（macOS selectedTextBackgroundColor） */
::selection{background:rgba(0,122,255,.24)}
a{color:var(--brand-2);text-decoration:none}
a:hover{text-decoration:underline;text-underline-offset:2px}
button{font-family:inherit;cursor:pointer;border:none;font-size:14px;color:inherit}
/* 文本框：白底、发丝边、10px 圆角；聚焦时边变蓝、外面一圈淡蓝环（apple.com 表单） */
input,select{font-family:inherit;font-size:14px;font-weight:400;color:var(--text);background:var(--input-bg);
  border:1px solid var(--input-line);border-radius:var(--r-lg);padding:9px 12px;width:100%;outline:none;
  transition:border-color .16s var(--ease),box-shadow .16s var(--ease)}
input:focus,select:focus{border-color:var(--focus-line);box-shadow:var(--focus-ring)}
/* 下拉框画成 macOS 的弹出按钮：右端一对上下尖角 */
select{-webkit-appearance:none;appearance:none;padding-right:30px;cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 16' fill='none' stroke='%2386868b' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 6l3-3 3 3M2 10l3 3 3-3'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 11px center;background-size:8px 13px}
input[type=checkbox],input[type=radio]{accent-color:var(--brand)}
input[type=checkbox]:focus,input[type=radio]:focus{box-shadow:none}
input[type=checkbox]:focus-visible,input[type=radio]:focus-visible{outline:2px solid var(--focus-line);outline-offset:2px}
input::placeholder{color:var(--faint)}
.mono{font-family:var(--mono)} .hide{display:none!important}
.dim{color:var(--dim)} .faint{color:var(--faint)}
*{scrollbar-width:thin;scrollbar-color:var(--faint-a42) transparent}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--faint-a38);border-radius:6px;border:3px solid transparent;background-clip:content-box}
::-webkit-scrollbar-thumb:hover{background:var(--faint-a60);border:3px solid transparent;background-clip:content-box}

/* ---- 按钮：一律胶囊。实心墨色 = 主操作；灰底 = 次要；危险 = 灰底红字 / 红底白字。
   按下缩到 0.97（HIG 的按压反馈）。边框留一圈透明的，让几种按钮等高。 ---- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;background:var(--brand);color:var(--btn-ink);
  font-weight:500;font-size:14px;letter-spacing:-.005em;border:1px solid transparent;border-radius:var(--r-pill);padding:8px 17px;white-space:nowrap;
  transition:transform .2s var(--spring),background-color .16s var(--ease),color .16s var(--ease),opacity .16s var(--ease)}
.btn:hover{background:var(--btn-hover)}
.btn:active{transform:scale(.97);background:var(--btn-press)}
.btn:focus-visible{outline:2px solid var(--focus-line);outline-offset:2px}
.btn.sm{padding:5px 13px;font-size:13px}
.btn.ghost{background:var(--fill-3);color:var(--text)}
.btn.ghost:hover{background:var(--fill-2)}
.btn.ghost:active{background:var(--fill-1)}
.btn.danger{background:var(--fill-3);color:var(--bad-text)}
.btn.danger:hover{background:var(--bad-a11)}
.btn.solid-bad{background:var(--bad);color:#fff}
.btn.solid-bad:hover{background:var(--bad-text)}
.btn:disabled{opacity:.4;cursor:not-allowed}
.btn:disabled:active{transform:none}
.btn.busy{opacity:.7;pointer-events:none}
.btn.busy::before{content:"";width:13px;height:13px;flex:none;border-radius:50%;
  border:2px solid var(--btn-ink-a35);border-top-color:var(--btn-ink);animation:pspin .7s linear infinite}
.btn.ghost.busy::before,.btn.danger.busy::before{border-color:var(--faint-a38);border-top-color:var(--text)}
@keyframes pspin{to{transform:rotate(360deg)}}
/* app 图标式品牌标（与交换台、公开站同一枚） */
.appmark{display:inline-grid;place-items:center;flex:none;width:28px;height:28px;border-radius:7.5px;
  background:linear-gradient(180deg,#4a4a4f,#1d1d1f);
  box-shadow:inset 0 0 0 .5px rgba(255,255,255,.16),0 1px 2px rgba(0,0,0,.16),0 3px 8px rgba(0,0,0,.1)}
.appmark svg{width:18px;height:18px}

/* 登录卡片曾经也长在这份 HTML 里，2026-08-27 撤掉了：门户只认一个登录入口
   /portal/login。见 showLogin()。 */
.field{margin-bottom:14px}
.field label{display:block;font-size:14px;font-weight:500;color:var(--text);margin-bottom:6px}

/* ---- shell：整幅贴边的导航条 + 一条底线，正文收在中间 ---- */
.wrap{max-width:1360px;margin:0 auto;padding:0 24px 80px}
/* ---- 代客态横幅 -------------------------------------------------------------
   运营以客户身份进门时常驻在最顶上。这个功能最现实的风险不是别人滥用，是操作的人
   忘了自己还在客户账号里，所以它 fixed 在视口顶端、不可关闭、配色和门户主色明显
   不同（门户没有别的地方用这个橙）。
   两条 sticky 要跟着让位：topbar 贴 top:0、实时状态条贴 top:64px，横幅一出现，
   两者各自加上 --imp-h。高度是量出来的而不是写死的——这一条在窄屏上会折行，
   写死的数字会让顶栏压在横幅底下，而那正好是「看不见自己在代客」的那个 bug。 */
#imp-bar{position:fixed;top:0;left:0;right:0;z-index:90;
  padding:13px 0;background:#7c2d12;color:#fff5ed;
  font-size:14px;line-height:1.55;box-shadow:0 1px 0 rgba(0,0,0,.28)}
/* 内容器抄 .wrap 的几何（max-width 1360 + 24px 内边距），横幅左缘才和顶栏里的
   品牌名对齐。少了这一层，色带是通栏的而字是贴着视口走的，两条左边缘差 40px。 */
#imp-bar .imp-in{max-width:1360px;margin:0 auto;padding:0 24px;
  display:flex;align-items:center;justify-content:space-between;gap:12px 20px;flex-wrap:wrap}
#imp-bar .imp-msg{display:flex;align-items:center;gap:10px;flex-wrap:wrap;min-width:0}
#imp-bar b{color:#fff;font-weight:700}
#imp-bar .imp-sep{opacity:.5}
#imp-bar .imp-left{white-space:nowrap;opacity:.85;font-variant-numeric:tabular-nums}
#imp-bar .imp-out{flex:none;border:1px solid rgba(255,255,255,.45);background:transparent;
  color:#fff;border-radius:var(--r-lg);padding:7px 14px;font-size:13px;font-weight:600;
  cursor:pointer;transition:background .15s,border-color .15s}
#imp-bar .imp-out:hover{background:rgba(255,255,255,.14);border-color:rgba(255,255,255,.75)}
body.imp{padding-top:var(--imp-h,0px)}
body.imp .topbar{top:var(--imp-h,0px)}
/* 代客横幅在最上面，顶栏和实时条都要让开它。顶栏高度同样走 --topbar-h：
   窄屏它是两行，写死 64 会让实时条重新压住导航。 */
body.imp .lv{top:calc(var(--imp-h, 0px) + var(--topbar-h, 64px))}
@media (max-width:900px){#imp-bar .imp-in{padding:0 max(14px,env(safe-area-inset-left))}}
/* 顶栏：导航层的玻璃——半透明、模糊、提饱和，正文从它底下滚过去。
   它长在 1360px 的正文列里，宽屏上两侧会露出台面；底色和底线用 border-image 的
   outset 向两侧各铺出去（只画、不占位，不会带出横向滚动条），整条读起来贴满窗口。 */
.topbar{position:sticky;top:0;z-index:30;display:flex;align-items:center;justify-content:space-between;gap:16px;
  height:64px;margin:0 -24px;padding:0 24px;background:none;
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);border:0;
  border-image:linear-gradient(to bottom,var(--rail-bg) calc(100% - 1px),var(--rail-line) 0) fill 0//0 100vmax}
.brand{display:flex;align-items:center;gap:10px;flex:none}
.brand .name{font-family:var(--disp);font-weight:600;font-size:18px;letter-spacing:-.015em;color:var(--rail-text)}
.brand .tag{display:none}
.topbar .right{display:flex;align-items:center;gap:8px;flex:none}
.topbar .btn.ghost{background:transparent;color:var(--rail-dim)}
.topbar .btn.ghost:hover{color:var(--rail-text);background:var(--rail-hover)}

/* ---- 顶栏右侧：问号 + 头像 ------------------------------------------------
   头像是整页唯一一块实心的墨色（主色 + 反白字），和主按钮同一种画法：它是
   「我」的入口，扫一眼右上角就该落在它上面。其余一切保持描边和留白。 */
.help-btn{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;flex:none;
  padding:0;background:transparent;border-radius:50%;color:var(--rail-dim);transition:color .16s var(--ease),background-color .16s var(--ease)}
.help-btn:hover,.help-btn.on{color:var(--rail-text);background:var(--rail-hover)}
.help-btn:focus-visible{outline:2px solid var(--focus-line);outline-offset:2px}
.help-btn svg,.me-item svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;flex:none}
.me{position:relative;flex:none}
.me-btn{display:inline-flex;align-items:center;gap:4px;padding:3px 6px 3px 3px;border-radius:999px;background:transparent;
  color:var(--rail-dim);transition:background .12s,color .12s}
.me-btn:hover,.me-btn[aria-expanded=true]{background:var(--rail-hover);color:var(--rail-text)}
.me-btn:focus-visible{outline:2px solid var(--focus-line);outline-offset:2px}
.me-caret{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;
  transition:transform .18s ease}
.me-btn[aria-expanded=true] .me-caret{transform:rotate(180deg)}
/* 当前在偏好设置 / 邀请好友 / 服务状态：头像外面加一圈，说明这页是从这里进来的 */
.me-btn.on .avatar{box-shadow:0 0 0 2px var(--rail-bg),0 0 0 3.5px var(--brand-50-on-line)}
.avatar{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;flex:none;border-radius:50%;
  background:var(--brand);color:var(--btn-ink);font-size:13px;font-weight:700;line-height:1;letter-spacing:0;
  text-transform:uppercase;user-select:none}
.avatar.lg{width:40px;height:40px;font-size:16px}
/* 头像菜单：macOS 的菜单形制，从右上角弹出来。它长在顶栏里，而顶栏自己是一块
   backdrop-filter 玻璃——嵌套的那一层模糊只能看见顶栏、看不见底下的正文，半透明
   底色会让表格的字原样透上来。所以这一块用实心底，靠投影浮起来。 */
.me-menu{position:absolute;top:calc(100% + 8px);right:0;z-index:40;width:272px;padding:6px;
  background:var(--surface);
  border:1px solid var(--rail-line);border-radius:var(--r-xl);box-shadow:var(--sheen),var(--shadow-1);
  transform-origin:top right;animation:meIn .3s var(--spring)}
.me-menu[hidden]{display:none}
@media (max-width:760px){.me-menu{max-width:calc(100vw - 28px)}}
@keyframes meIn{from{opacity:0;transform:translateY(-4px) scale(.98)}to{opacity:1;transform:none}}
.me-head{display:flex;align-items:center;gap:12px;padding:12px 12px 14px}
.me-id{min-width:0}
.me-name{font-size:14px;font-weight:600;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.me-user{margin-top:3px;font-size:12.5px;color:var(--faint);font-family:var(--mono);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.me-wallet{display:flex;align-items:baseline;justify-content:space-between;gap:12px;width:100%;margin:0 0 4px;
  padding:10px 12px;border:0;border-radius:var(--r-lg);background:var(--fill-4);
  font-size:13px;color:var(--dim);text-align:left;transition:background-color .16s var(--ease)}
.me-wallet b{font-size:15px;font-weight:600;color:var(--text);font-variant-numeric:tabular-nums}
.me-wallet:hover{background:var(--fill-3)}
.me-wallet:focus-visible,.me-item:focus-visible{outline:2px solid var(--focus-line);outline-offset:-2px}
.me-sep{height:1px;margin:6px 6px;background:var(--line)}
.me-item{display:flex;align-items:center;gap:11px;width:100%;padding:8px 12px;border-radius:var(--r-md);
  background:transparent;color:var(--text);font-size:14px;font-weight:400;text-align:left;transition:background-color .1s}
.me-item svg{color:var(--dim)}
.me-item:hover,.me-item:focus-visible{background:var(--fill-3)}
.me-item.on{font-weight:600}
.me-item.on svg{color:var(--text)}
#me-out{color:var(--dim)}

/* ---- 偏好设置：一行一项，左说明右控件 ---- */
.phead{margin-bottom:24px}
/* 设置行是「左边一句话、右边一个控件」：拉满 1400px 宽时两者隔着半个屏幕，
   眼睛要横跨过去才对得上。收在 880px 里，和阅读宽度一致。 */
#v-prefs{max-width:880px}
.prefs{overflow:visible}
.pref{display:flex;align-items:center;justify-content:space-between;gap:24px;padding:18px 22px}
.pref+.pref{border-top:1px solid var(--line)}
.pref-k{min-width:0}
.pref-k b{display:block;font-size:14px;font-weight:600;color:var(--text)}
.pref-k p{margin:4px 0 0;font-size:13px;line-height:1.6;color:var(--faint)}
.pref-v{flex:none;font-size:14px;color:var(--dim);text-align:right;max-width:55%;overflow-wrap:anywhere}
.pref-select{width:auto;min-width:148px;cursor:pointer}
.pw-err{margin:12px 0 0;font-size:13px;line-height:1.6;color:var(--bad-text)}
/* 分段控件：灰色胶囊轨道，选中的那段是一块抬起来的白（深色是灰） */
.seg{display:inline-flex;border:0;border-radius:var(--r-pill);padding:2px;gap:2px;background:var(--fill-3)}
.seg button{padding:6px 14px;border-radius:var(--r-pill);background:transparent;color:var(--text);font-size:13px;font-weight:500;white-space:nowrap;
  transition:background-color .2s var(--ease),box-shadow .2s var(--ease)}
.seg button:hover{background:var(--fill-4)}
.seg button[aria-checked=true]{background:var(--seg-thumb);color:var(--text);font-weight:600;box-shadow:var(--seg-thumb-ring)}
.seg button:focus-visible{outline:2px solid var(--focus-line);outline-offset:1px}
@media (max-width:640px){
  .pref{flex-direction:column;align-items:flex-start;gap:12px;padding:16px 18px}
  .pref-v{max-width:100%;text-align:left}
  .pref-select{width:100%}
}

/* ---- 主导航：顶栏里的一排文字链接，当前页深一档 ---- */
/* min-width:0 不是可选的：弹性项默认按内容撑最小宽，六个标签加起来比手机屏还宽，
   overflow-x 于是永远不生效，溢出的不是这一条而是整个页面（右边一截被切掉）。 */
.tabs{display:flex;align-items:center;gap:2px;overflow-x:auto;scrollbar-width:none;
  flex:1 1 auto;min-width:0;justify-content:flex-end}
.tabs::-webkit-scrollbar{display:none}
/* 页签：胶囊，当前页垫一块浅填充、字加粗一档（macOS 26 工具栏里的页签） */
.tab{display:inline-flex;align-items:center;padding:7px 13px;border-radius:var(--r-pill);color:var(--rail-dim);
  font-weight:500;font-size:14px;letter-spacing:-.005em;background:transparent;white-space:nowrap;transition:color .16s var(--ease),background-color .16s var(--ease)}
.tab:hover{background:var(--rail-hover);color:var(--rail-text)}
.tab.on{color:var(--rail-text);font-weight:600;background:var(--fill-3)}
.tab:focus-visible{outline:2px solid var(--focus-line);outline-offset:-2px}
/* ---- 顶部状态条 --------------------------------------------------------
   跟着导航条一起吸顶，因为它报的是「现在」——滚下去的实时读数没有意义。
   一行之内四个数，所以数值和单位分两档字重：读者扫的是数字，单位只在他停下来
   看某一个数时才需要被读到。窄屏横向滚动而不换行（和 .tabs 同一套办法）：
   两行的顶栏会把每一页的正文都往下推 40px。 */
/* 宽度写成 calc 而不是 100%：它是个 <button>（要的是键盘和读屏都认的语义），
   而按钮按内容定宽，不像块级元素那样自己撑满——不写这一行，整条会缩到文字那么
   长，右边留一截断掉的底线。48px = 两侧各 -24px 的负边距。 */
/* top 不写死：窄屏顶栏会折成两行（导航自己占一行），高度不再是常数。差一像素
   的后果不对称——多了露出一条正文，少了就把导航压在下面点不着（真发生过：
   ≤760px 那一档把顶栏按定高 56px 写死，实时条正好盖住第二行的半截导航，
   而它自己是个按钮，点「密钥」会跳到状态页）。--topbar-h 由 syncTopbarH() 量。 */
.lv{position:sticky;top:var(--topbar-h,64px);z-index:29;display:flex;align-items:center;gap:0 18px;
  margin:0 -24px;padding:0 24px;height:40px;width:calc(100% + 48px);background:none;
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  border:0;border-radius:0;border-image:linear-gradient(to bottom,var(--rail-bg) calc(100% - 1px),var(--rail-line) 0) fill 0//0 100vmax;
  font:inherit;text-align:left;color:var(--dim);cursor:pointer;
  overflow-x:auto;scrollbar-width:none;transition:background .12s}
.lv::-webkit-scrollbar{display:none}
.lv:hover{background:var(--rail-hover)}
.lv:focus-visible{outline:2px solid var(--focus-line);outline-offset:-2px}
.lv-state{display:inline-flex;align-items:center;gap:8px;flex:none;
  font-size:13px;font-weight:600;color:var(--text)}
/* 线路：三条互斥的路，画成一组单选卡。每张卡下面那条「经过哪几站」的小路
   径是这块面板唯一的图形——线路本来就是一个顺序，虚线站表示需要时才经过。 */
.sail-line{padding:24px;margin:24px 0}
.sail-line-head{display:flex;align-items:flex-start;justify-content:space-between;gap:24px;margin-bottom:18px}
.sail-line-head h3{margin:0 0 8px;font-size:16px}
.sail-line-head p{margin:0;max-width:640px;line-height:1.7}
.sail-line-state{flex:none;font-size:13px;color:var(--dim);white-space:nowrap;padding-top:3px}
.sail-routes{display:grid;gap:10px}
.sail-route{display:grid;grid-template-columns:18px 1fr;gap:14px;align-items:start;padding:16px 18px;border:1px solid var(--line);border-radius:var(--r-xl);background:var(--surface-2);cursor:pointer;text-align:left;font:inherit;color:inherit;transition:border-color .15s,background .15s}
.sail-route:hover{border-color:var(--text-a60,var(--faint))}
.sail-route[aria-checked=true]{border-color:var(--brand);background:var(--surface)}
.sail-route:focus-visible{outline:2px solid var(--focus-line);outline-offset:2px}
.sail-route:disabled{opacity:.55;cursor:wait}
.sail-route .dot{width:18px;height:18px;margin-top:1px;border-radius:50%;border:1.5px solid var(--faint);position:relative;box-sizing:border-box}
.sail-route[aria-checked=true] .dot{border-color:var(--brand)}
.sail-route[aria-checked=true] .dot::after{content:"";position:absolute;inset:3px;border-radius:50%;background:var(--brand)}
.sail-route .name{display:flex;align-items:baseline;gap:10px;font-weight:600;font-size:14px;margin-bottom:4px}
.sail-route .name .tag{font-size:12px;font-weight:500;color:var(--faint)}
.sail-route .what{font-size:13px;color:var(--dim);line-height:1.65;margin:0 0 12px}
.sail-path{display:flex;flex-wrap:wrap;align-items:center;row-gap:6px;font-size:12px}
.sail-path .hop{padding:3px 9px;border:1px solid var(--line);border-radius:999px;background:var(--surface);color:var(--dim);white-space:nowrap}
.sail-path .hop.maybe{border-style:dashed;color:var(--faint);background:transparent}
.sail-path i{width:14px;height:1px;background:var(--faint);opacity:.5;flex:none}
.sail-line-note{margin:16px 0 0}
@media(max-width:640px){.sail-line{padding:20px}.sail-line-head{flex-direction:column;gap:8px}.sail-line-state{padding-top:0}.sail-route{padding:14px 14px;gap:12px}}
/* 点用 currentColor 画呼吸环，状态色只在一处设置——三个状态各写一遍环，
   迟早会有一个忘了跟着改。 */
.lv-dot{position:relative;width:8px;height:8px;border-radius:50%;flex:none;
  background:currentColor;color:var(--ok)}
.lv-dot::after{content:'';position:absolute;inset:-4px;border-radius:50%;
  border:1px solid currentColor;opacity:0;animation:lvPing 2.6s ease-out infinite}
@keyframes lvPing{0%{transform:scale(.6);opacity:.5}70%{transform:scale(1.45);opacity:0}100%{opacity:0}}
.lv.degraded .lv-dot{color:var(--warn)} .lv.outage .lv-dot{color:var(--bad)}
.lv.degraded .lv-state{color:var(--warn-text)} .lv.outage .lv-state{color:var(--bad-text)}
/* 线上没有流量时不呼吸：一个对着 0 请求跳动的点，说的是「有事在发生」，
   而那正是此刻唯一不成立的事。 */
.lv.idle .lv-dot::after{display:none}
.lv-metrics{display:flex;align-items:center;gap:0 16px;flex:1 1 auto;min-width:0;white-space:nowrap}
.lv-m{display:inline-flex;align-items:baseline;gap:5px;flex:none}
.lv-m i{font-style:normal;font-size:13px;font-weight:700;color:var(--text);font-variant-numeric:tabular-nums}
.lv-m u{text-decoration:none;font-size:12px;color:var(--faint)}
.lv-m.warn i{color:var(--warn-text)} .lv-m.bad i{color:var(--bad-text)}
.lv-idle{font-size:13px;color:var(--faint)}
.lv-win{margin-left:auto;flex:none;font-size:12px;color:var(--faint);font-variant-numeric:tabular-nums}
/* 页面顶部留白：顶栏（或实时带）下边线到页面第一块内容，和看板同一条规范：16px，掌上 12px。
   见 docs/admin-layout.md。 */
.view{padding-top:16px}
/* ---- 窄屏顶栏：两行 --------------------------------------------------------
   390px 宽时一行装不下品牌加七个页签：页签条会被挤到只剩几个像素，点不到。
   断点下页签独占第二行、整行横滚；第一行只留 logo、问号和头像。
   以前第一行还挤着主题、语言、用户名和退出四件工具，最窄那一档只能把品牌名
   藏掉；它们收进头像菜单之后，320px 也放得下完整的品牌名。
   .lv 吸在顶栏底下，顶栏从 64px 长到约 90px，高度由 syncTopbarH 量出来。 */
@media (max-width:640px){
  .topbar{height:auto;flex-wrap:wrap;align-content:flex-start;row-gap:0;padding:8px 24px 6px}
  .who{display:none}
  .tabs{order:3;flex:1 1 100%;justify-content:flex-start;margin:2px -24px 0;padding:0 24px}
}
@keyframes rise{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
.view.enter>*{animation:rise .3s cubic-bezier(.22,.61,.25,1) both}
/* 首次读数的占位：进页时还空着、等数据来填的区块画成灰色块，页面一进来就是最终的
   骨架，而不是几行标题漂在空白里、数据到了再整页跳一次。go() 读完就撤掉。 */
.view.is-loading div[id]:empty:not(.hide){min-height:72px;margin-bottom:16px;border-radius:18px;background:linear-gradient(90deg,var(--fill-4) 25%,var(--fill-3) 50%,var(--fill-4) 75%);background-size:200% 100%;animation:skel 1.4s ease-in-out infinite}
.view.is-loading #h-greet:empty{min-height:56px}
.view.is-loading #h-cards:empty{min-height:180px}
@keyframes skel{from{background-position:100% 0}to{background-position:-100% 0}}
@media (prefers-reduced-motion:reduce){.view.is-loading div[id]:empty{animation:none}}
.view.enter>*:nth-child(2){animation-delay:40ms}
.view.enter>*:nth-child(3){animation-delay:80ms}
.view.enter>*:nth-child(n+4){animation-delay:120ms}
/* eyebrow 从「全大写小字」改成 OpenRouter 的段落式小标题：句首大写、正常字号 */
.eyebrow{font-size:14px;font-weight:500;letter-spacing:0;text-transform:none;color:var(--dim);margin:0 0 14px}
.sec{margin-bottom:36px}
h1.page{font-family:var(--disp);font-size:30px;font-weight:700;letter-spacing:-.025em;margin:0;line-height:1.2}

/* ---- 数字瓦片 ---- */
.tiles{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:24px}
.tiles.c3{grid-template-columns:repeat(3,1fr)}
.tiles.c2{grid-template-columns:repeat(2,1fr);max-width:720px}
/* 说明句和它解释的那个数字之间要留出一行的呼吸，别贴在控件底下 */
.winnote{font-size:12.5px;color:var(--faint);line-height:1.65;margin:0 0 16px}
.tile{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-xl);padding:18px 20px;box-shadow:var(--card-shadow)}
.tile .k{font-size:12.5px;font-weight:500;letter-spacing:0;text-transform:none;color:var(--dim)}
.tile .v{font-family:var(--disp);font-size:27px;font-weight:700;letter-spacing:-.025em;margin-top:8px;line-height:1.1;font-variant-numeric:tabular-nums}
.tile .sub{font-size:13px;color:var(--dim);margin-top:6px}

/* ---- 表格 ---- */
.panel{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-xl);overflow:auto;box-shadow:var(--card-shadow)}
table{width:100%;border-collapse:collapse;font-size:14px}
th{font-size:12px;font-weight:600;letter-spacing:0;text-transform:none;color:var(--dim);text-align:left;
  padding:11px 16px;border-bottom:1px solid var(--line);background:transparent;white-space:nowrap}
td{padding:12px 16px;border-bottom:1px solid var(--line-soft);vertical-align:middle;font-variant-numeric:tabular-nums}
tr:last-child td{border-bottom:none}
tbody tr:hover{background:var(--ctl-on-bg)}
.panel>table tbody tr:hover td:first-child{box-shadow:none}
td.num,th.num{text-align:right;font-family:var(--mono)}
/* 空态：一枚托盘图标 + 一句话 */
.empty{color:var(--dim);text-align:center;padding:36px 16px!important;font-size:14px}
.empty::before{content:"";display:block;width:30px;height:30px;margin:0 auto 10px;background:var(--faint);opacity:.7;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linejoin='round' stroke-linecap='round'%3E%3Cpath d='M3.5 13.5 6.1 5.6A2.3 2.3 0 0 1 8.3 4h7.4a2.3 2.3 0 0 1 2.2 1.6l2.6 7.9'/%3E%3Cpath d='M3.5 13.5V18a2 2 0 0 0 2 2h13a2 2 0 0 0 2-2v-4.5h-4.8a2.7 2.7 0 0 1-5.4 0z'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linejoin='round' stroke-linecap='round'%3E%3Cpath d='M3.5 13.5 6.1 5.6A2.3 2.3 0 0 1 8.3 4h7.4a2.3 2.3 0 0 1 2.2 1.6l2.6 7.9'/%3E%3Cpath d='M3.5 13.5V18a2 2 0 0 0 2 2h13a2 2 0 0 0 2-2v-4.5h-4.8a2.7 2.7 0 0 1-5.4 0z'/%3E%3C/svg%3E") center/contain no-repeat}
/* 操作列保持真正的表格单元格：display:flex 会把它挤出表格布局，行底线和悬停底色
   都只铺到倒数第二列就断掉。按钮之间的空隙用外边距给。 */
.row-actions{text-align:right;white-space:nowrap}
.row-actions>*+*{margin-left:6px}

/* ---- 徽标 ---- */
.badge{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:500;padding:3px 10px;
  border-radius:var(--r-pill);white-space:nowrap}
.badge.on{color:var(--ok-text);background:var(--ok-a12)}
.badge.open{color:var(--bad-text);background:var(--bad-a11)}
.badge.expired{color:var(--warn-text);background:var(--warn-a12)}
.tag{display:inline-flex;align-items:center;font-size:12px;font-weight:500;padding:2px 9px;
  border-radius:var(--r-pill);white-space:nowrap}
.tag-anthropic{color:var(--ac);background:var(--ac-a12)}
.tag-openai{color:var(--oa);background:var(--oa-a12)}
.tag-gemini{color:var(--gm);background:var(--gm-a12)}
.tag-image{color:var(--im);background:var(--im-a12)}
.tag-typesafe{color:var(--ts);background:var(--ts-a12)}
.ptag{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:500;
  padding:2px 5px 2px 9px;border-radius:var(--r-pill);white-space:nowrap}
.ptag i{font-style:normal;font-weight:400;font-family:var(--mono);font-size:11px;
  padding:1px 6px;border-radius:var(--r-pill);background:var(--surface);opacity:.95}
.ptag.tag-anthropic{color:var(--ac);background:var(--ac-a12)}
.ptag.tag-openai{color:var(--oa);background:var(--oa-a12)}
.ptag.tag-gemini{color:var(--gm);background:var(--gm-a12)}
.ptag.tag-image{color:var(--im);background:var(--im-a12)}
.ptag.tag-typesafe{color:var(--ts);background:var(--ts-a12)}
.lamp{display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--faint);flex:none}
.lamp.ok{background:var(--ok)} .lamp.bad{background:var(--bad)} .lamp.warn{background:var(--warn)}

/* ---- 调用日志 ---- */
.st{display:inline-flex;align-items:center;font-family:var(--mono);font-size:12px;font-weight:500;
  padding:2px 8px;border-radius:var(--r-pill);white-space:nowrap}
.st-ok{color:var(--ok-text);background:var(--ok-a12)}
.st-bad{color:var(--bad-text);background:var(--bad-a11)}
.st-warn{color:var(--warn-text);background:var(--warn-a12)}
tr.lg-row{cursor:pointer}
tr.lg-row>td:first-child::before{content:'›';display:inline-block;width:12px;margin-right:5px;color:var(--faint);
  transition:transform .16s;transform-origin:center}
tr.lg-row.open>td:first-child::before{transform:rotate(90deg);color:var(--text)}
tr.lg-row.open>td{background:var(--ctl-on-bg)}
.lg-det>td{padding:0!important;background:var(--ctl-on-bg);border-bottom:1px solid var(--line)}
.lg-card{padding:6px 18px 18px 34px;display:grid;grid-template-columns:repeat(auto-fit,minmax(148px,1fr));gap:14px 22px}
.lg-card .f{min-width:0}
.lg-card .f .k{font-size:12px;font-weight:500;color:var(--faint)}
.lg-card .f .v{margin-top:3px;font-size:13px;color:var(--text);word-break:break-all}
.lg-card .wide{grid-column:1/-1}
/* 分项账：四路 token 各一行（token × 单价 = 金额），合计与扣费收在最后。
   窄一点、贴着展开卡的网格走，不另起一套间距。 */
.bd-wrap{max-width:600px;margin-top:6px}
.bd-tbl{width:100%;border-collapse:collapse;font-size:13px}
.bd-tbl th,.bd-tbl td{padding:7px 10px;border-bottom:1px solid var(--line-soft);vertical-align:middle}
.bd-tbl th{font-size:11.5px;font-weight:500;color:var(--faint);text-align:left;letter-spacing:.02em}
.bd-tbl th:first-child,.bd-tbl td:first-child{padding-left:0}
.bd-tbl th:last-child,.bd-tbl td:last-child{padding-right:0}
.bd-tbl td.num,.bd-tbl th.num{text-align:right;font-family:var(--mono);font-variant-numeric:tabular-nums}
.bd-tbl tr.sum td{border-bottom:0;padding-top:9px;font-weight:600}
.bd-tbl tr.sum td:first-child{font-weight:500;color:var(--dim)}
.bd-tbl tr.sum+tr.sum td{padding-top:2px}
.bd-note{font-size:12px;color:var(--faint);margin-top:10px;line-height:1.6}
.lg-err{font-family:var(--mono);font-size:12px;line-height:1.6;color:var(--bad-text);background:var(--bad-a11);
  border-radius:var(--r-lg);padding:10px 12px;white-space:pre-wrap;word-break:break-word}
.lg-note{font-size:13px;color:var(--dim)}
.lg-more{display:flex;justify-content:center;margin-top:16px}
@media(max-width:760px){.lg-card{padding-left:18px}}

/* ============================================================================
   模型目录 —— 左侧筛选栏 + 主列表，与 openrouter.ai/models 同构。
   一行是一张贴边的卡：标题、两行描述、一条 by 厂商 · 发布 · 上下文 · 单价 的
   元信息。价格印美元，因为这是全站唯一一个能和别家页面并排读的数字。
   ============================================================================ */
.mdir{display:grid;grid-template-columns:236px minmax(0,1fr);gap:32px;align-items:start}
.mdir-side{position:sticky;top:88px;max-height:calc(100dvh - 108px);overflow-y:auto;padding-right:4px}
.fgrp{border-bottom:1px solid var(--line-soft)}
.fgrp>summary{display:flex;align-items:center;gap:9px;padding:13px 2px;cursor:pointer;list-style:none;
  font-size:14px;font-weight:500;color:var(--text);user-select:none}
.fgrp>summary::-webkit-details-marker{display:none}
.fgrp>summary::after{content:"";margin-left:auto;width:7px;height:7px;border-right:1.5px solid var(--faint);
  border-bottom:1.5px solid var(--faint);transform:rotate(-45deg) translateY(1px);transition:transform .18s}
.fgrp[open]>summary::after{transform:rotate(45deg) translateY(-2px)}
.fgrp>summary:hover{color:var(--text)}
.fgrp>summary svg{width:15px;height:15px;flex:none;fill:none;stroke:var(--faint);stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round}
.fgrp .fbody{padding:2px 0 14px}
.fopt{display:flex;align-items:center;gap:9px;padding:6px 2px;font-size:14px;color:var(--dim);
  cursor:pointer;border-radius:var(--r-md);transition:color .12s}
.fopt:hover{color:var(--text)}
.fopt input{width:15px;height:15px;flex:none;margin:0;padding:0;accent-color:var(--brand);cursor:pointer}
.fopt input:focus-visible{outline:2px solid var(--focus-line);outline-offset:1px}
.fopt.on{color:var(--text);font-weight:500}
.fopt .n{margin-left:auto;font-size:12px;color:var(--faint);font-variant-numeric:tabular-nums}
.fclear{margin:14px 0 0;width:100%;justify-content:center}
/* 主区顶栏：标题 + 视图切换，然后搜索 / 排序，然后模态页签 */
.mdir-head{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;margin:0 0 20px}
.cat-bar{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin:0 0 4px}
.cat-search{flex:1 1 260px;min-width:180px;position:relative}
.cat-search input{width:100%;height:40px;padding:0 12px 0 36px;border-radius:var(--r-lg);
  border:1px solid var(--input-line);background:var(--input-bg);color:var(--text);font-size:14px}
.cat-search::before{content:'';position:absolute;left:13px;top:50%;width:12px;height:12px;transform:translateY(-50%);
  border:1.6px solid var(--faint);border-radius:50%;box-shadow:5px 5px 0 -4.4px var(--faint);pointer-events:none}
.cat-sort{appearance:none;-webkit-appearance:none;flex:0 0 auto;width:auto;height:40px;padding:0 34px 0 13px;
  border-radius:var(--r-lg);border:1px solid var(--input-line);background-color:var(--input-bg);color:var(--text);
  font-size:14px;font-weight:500;
  background-image:linear-gradient(45deg,transparent 50%,var(--faint) 50%),linear-gradient(135deg,var(--faint) 50%,transparent 50%);
  background-position:calc(100% - 18px) 18px,calc(100% - 13px) 18px;background-size:5px 5px,5px 5px;background-repeat:no-repeat}
.cat-count{font-size:13px;color:var(--faint);font-variant-numeric:tabular-nums}
/* 视图切换（列表 / 表格）：一个描边的小分段控件 */
.vsw{display:inline-flex;border:1px solid var(--line);border-radius:var(--r-lg);padding:2px;gap:2px;flex:none}
.vsw button{display:inline-flex;align-items:center;gap:6px;padding:5px 11px;border-radius:var(--r-md);
  font-size:13px;font-weight:500;color:var(--dim);background:transparent}
.vsw button.on{background:var(--ctl-on-bg);color:var(--text)}
.vsw button:focus-visible{outline:2px solid var(--focus-line);outline-offset:1px}
.vsw svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
/* 模态页签：底部一条 2px 实线标出当前项 */
.mtabs{display:flex;align-items:center;gap:4px;overflow-x:auto;scrollbar-width:none;
  border-bottom:1px solid var(--line);margin:16px 0 18px}
.mtabs::-webkit-scrollbar{display:none}
.mtab{display:inline-flex;align-items:center;gap:7px;padding:10px 12px;background:transparent;color:var(--dim);
  font-size:14px;font-weight:500;white-space:nowrap;border-bottom:2px solid transparent;margin-bottom:-1px}
.mtab:hover{color:var(--text)}
.mtab.on{color:var(--text);border-bottom-color:var(--text)}
.mtab .n{font-size:12px;color:var(--faint);font-variant-numeric:tabular-nums}
.mtab.on .n{color:var(--dim)}
.chips{display:flex;flex-wrap:wrap;gap:6px}
.chip{padding:5px 11px;border-radius:999px;border:1px solid var(--line);background:transparent;
  color:var(--dim);font-size:13px;font-weight:500;cursor:pointer;white-space:nowrap}
.chip:hover{color:var(--text);background:var(--ctl-on-bg)}
.chip.on{color:var(--text);background:var(--ctl-on-bg);border-color:var(--faint-a30)}
.chip .n{color:var(--faint);margin-left:5px;font-size:12px}
/* ---- 列表视图的一行 ---- */
.lines{display:flex;flex-direction:column;gap:10px}
.crow{display:block;width:100%;text-align:left;font:inherit;color:inherit;cursor:pointer;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-xl);padding:18px 20px;
  transition:background .12s,border-color .12s}
.crow:hover{background:var(--brand-5-on-surface);border-color:var(--faint-a30)}
.crow:focus-visible{outline:2px solid var(--focus-line);outline-offset:2px}
.crow .chead{display:flex;align-items:flex-start;gap:12px}
.crow .cmodel{display:flex;align-items:center;gap:9px;font-size:20px;font-weight:600;letter-spacing:-.02em;
  line-height:1.3;min-width:0;flex-wrap:wrap}
.crow .cmodel span.nm{overflow:hidden;text-overflow:ellipsis}
.crow .cheat{margin-left:auto;flex:none;display:flex;align-items:center;gap:8px;padding-top:4px}
.crow .cdesc{font-size:14px;line-height:1.55;color:var(--dim);margin-top:8px;display:-webkit-box;
  -webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;max-width:84ch}
.cmeta{display:flex;align-items:center;flex-wrap:wrap;gap:4px 0;margin-top:11px;font-size:14px;color:var(--faint)}
.cmeta>span{display:inline-flex;align-items:center;gap:5px}
.cmeta>span+span::before{content:"";width:1px;height:12px;background:var(--faint-a30);margin:0 11px}
.cmeta b{color:var(--dim);font-weight:500;font-variant-numeric:tabular-nums}
.cmeta .who{padding:0;font-size:inherit;font-weight:450;color:var(--faint);max-width:none}
.ctags{display:flex;align-items:center;gap:7px;margin-top:11px;flex-wrap:wrap}
.cvendor{font-size:12px;letter-spacing:0;text-transform:none;color:var(--faint);font-weight:500}
.cctx{font-family:var(--mono);font-size:12px;color:var(--dim);border:1px solid var(--line);
  border-radius:var(--r-sm);padding:1px 6px;line-height:1.5}
.cmodal{font-size:12px;color:var(--dim);border:1px solid var(--line);border-radius:var(--r-sm);
  padding:1px 6px;line-height:1.5;white-space:nowrap}
/* 一周内发布：名字前一枚圆点。没有光晕——这一版不用发光说话 */
.cnew{width:7px;height:7px;border-radius:50%;background:var(--brand);flex:none}
/* 厂商标记：一枚方形字母牌，站在模型名左边。OpenRouter 那里放的是厂商 logo；
   我们没有那批版权素材，用首字母牌代替——它承担的是同一件事：一眼看出这一行
   是谁家的，而不用先读完名字。颜色按协议家族取，和标签用的是同一套。 */
.vm{display:inline-grid;place-items:center;width:26px;height:26px;flex:none;border-radius:var(--r-md);
  font-size:12px;font-weight:700;letter-spacing:-.02em;line-height:1;font-family:var(--sans);
  background:var(--surface-3);color:var(--dim);text-transform:uppercase}
.vm.v-anthropic{color:var(--ac);background:var(--ac-a12)}
.vm.v-openai{color:var(--oa);background:var(--oa-a12)}
.vm.v-google{color:var(--gm);background:var(--gm-a12)}
.vm.v-xai{color:var(--text);background:var(--faint-a16)}
.vm.v-brand{color:var(--brand-2);background:var(--brand-dim)}
.vm.lg{width:38px;height:38px;font-size:17px;border-radius:var(--r-lg)}
.ctrow .vm{width:22px;height:22px;font-size:11px;border-radius:var(--r-sm)}
.cat-copy{width:32px;height:32px;flex:none;display:grid;place-items:center;border:1px solid var(--line);
  border-radius:var(--r-lg);background:transparent;color:var(--faint);transition:color .12s,background .12s}
.cat-copy:hover{color:var(--text);background:var(--ctl-on-bg)}
.cat-copy:focus-visible{outline:2px solid var(--focus-line);outline-offset:2px}
.cat-copy svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
/* ---- 表格视图：同一批行，压成一张可扫的表 ---- */
.catalog-head,.ctrow{display:grid;grid-template-columns:minmax(220px,1fr) 104px 92px 168px 52px 36px;
  gap:16px;align-items:center}
.catalog-head{padding:0 18px 10px;font-size:12px;font-weight:500;letter-spacing:0;text-transform:none;color:var(--faint)}
.catalog-head span:nth-child(n+2){text-align:right}
.ctrow{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);padding:13px 18px;
  cursor:pointer;text-align:left;width:100%;font:inherit;color:inherit;transition:background .12s,border-color .12s}
.ctrow:hover{background:var(--brand-5-on-surface);border-color:var(--faint-a30)}
.ctrow:focus-visible{outline:2px solid var(--focus-line);outline-offset:2px}
.ctrow .tname{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:600;letter-spacing:-.01em;min-width:0}
.ctrow .tname span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ctrow .tsub{font-family:var(--mono);font-size:12px;color:var(--faint);margin-top:3px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cell{min-height:40px;display:flex;flex-direction:column;justify-content:center;min-width:0}
.cat-spec{text-align:right;font-size:13px;color:var(--dim);font-variant-numeric:tabular-nums}
.cat-spec b{display:block;color:var(--text);font-size:13px;font-weight:500;margin-bottom:2px}
.cat-spec .sub{font-size:12px;color:var(--faint)}
.px{text-align:right;font-variant-numeric:tabular-nums}
.pxline{white-space:nowrap}
.px b{font-size:13px;font-weight:500;font-family:var(--mono)}
.px i{font-style:normal;color:var(--faint);font-weight:400;padding:0 3px}
.px .out{color:var(--dim);font-weight:400}
.px .u{display:block;font-size:12px;color:var(--faint);margin-top:2px}
.px .free{color:var(--faint);font-size:13px}
/* ---- 上新分层 ---- */
.cat-era{display:flex;align-items:baseline;gap:12px;margin:26px 2px 12px}
.cat-era:first-child{margin-top:2px}
.cat-era b{font-size:14px;font-weight:600;letter-spacing:0;color:var(--text);white-space:nowrap}
.cat-era i{flex:1;height:1px;background:var(--line);min-width:16px;transform:translateY(-4px)}
.cat-era em{font-style:normal;font-size:12px;color:var(--faint);font-variant-numeric:tabular-nums}
.cat-era.fresh b{color:var(--brand-2)}
/* 热度：五格条。相对热度，不是调用次数 */
.heat{display:flex;gap:2px;align-items:flex-end;justify-content:flex-end;height:15px}
.heat i{width:4px;border-radius:1px;background:var(--faint-a30)}
.heat i:nth-child(1){height:5px} .heat i:nth-child(2){height:7px}
.heat i:nth-child(3){height:10px} .heat i:nth-child(4){height:12px} .heat i:nth-child(5){height:15px}
.heat i.on{background:var(--brand)}
/* 窄屏上左栏收进一颗「筛选」按钮里。六组筛选摊开在列表上方，读者要先滚过
   一屏才看得见第一个模型——而他们来这一页是来看模型的。 */
.fbtn{display:none}
@media (max-width:1080px){
  .mdir{grid-template-columns:minmax(0,1fr);gap:0}
  .fbtn{display:inline-flex}
  .mdir-side{display:none;position:static;max-height:none;margin:0 0 20px;
    border:1px solid var(--line);border-radius:var(--r-xl);padding:2px 16px}
  .mdir-side.open{display:block}
  .mdir-side .fgrp:last-of-type{border-bottom:none}
}
@media (max-width:760px){
  .catalog-head{display:none}
  .ctrow{grid-template-columns:minmax(0,1fr) auto;gap:10px 14px;padding:14px}
  .ctrow .cell:first-child{grid-column:1/-1}
  .cat-spec,.px{text-align:left}
  .heat{justify-content:flex-start}
  .ctrow .cat-copy{grid-column:2;grid-row:2/4;align-self:center}
  .crow{padding:15px 16px}
  .crow .cmodel{font-size:17px}
}

/* ============================================================================
   模型详情 —— 一个真正的页面，不是弹窗。面包屑、标题行、四张规格卡，
   再往下是左侧小节导航 + 右侧内容，和 openrouter.ai/<vendor>/<model> 同构。
   ============================================================================ */
.mdp-back{display:inline-flex;align-items:center;gap:7px;background:transparent;padding:6px 10px 6px 6px;
  margin-left:-6px;border-radius:var(--r-lg);color:var(--dim);font-size:14px;font-weight:500}
.mdp-back:hover{color:var(--text);background:var(--ctl-on-bg)}
.mdp-back:focus-visible{outline:2px solid var(--focus-line);outline-offset:2px}
.mdp-back svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.mdp-top{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-top:14px}
.mdp-top h1{font-size:30px;font-weight:700;letter-spacing:-.03em;margin:0;line-height:1.2;
  display:flex;align-items:center;gap:11px;flex-wrap:wrap}
.mdp-acts{display:flex;gap:8px;flex-wrap:wrap;flex:none}
.mdp-id{display:inline-flex;align-items:center;gap:8px;margin-top:12px}
.pid{display:inline-flex;align-items:center;font-family:var(--mono);font-size:13px;color:var(--dim);
  border:1px solid var(--line);border-radius:var(--r-md);padding:3px 9px;cursor:pointer;background:transparent}
.pid:hover{color:var(--text);background:var(--ctl-on-bg)}
.mdp-desc{font-size:16px;line-height:1.7;color:var(--text);margin:18px 0 0;max-width:88ch}
/* 四张规格卡：标签小写灰、读数 20px */
.mdl-tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;margin:26px 0 0}
.mdl-tile{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);padding:14px 16px;min-width:0}
.mdl-tile .k{font-size:12px;letter-spacing:.04em;text-transform:uppercase;color:var(--faint);font-weight:500}
.mdl-tile .v{font-size:20px;font-weight:600;letter-spacing:-.02em;margin-top:8px;font-variant-numeric:tabular-nums;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mdl-tile .v small{font-size:13px;font-weight:450;color:var(--dim);margin-left:4px}
.mdl-tile .s{font-size:12px;color:var(--faint);margin-top:5px}
.mdl-tile .mo{display:flex;align-items:center;gap:6px;margin-top:9px}
.mo b{display:inline-grid;place-items:center;width:24px;height:24px;border-radius:var(--r-md);
  font-size:11px;font-weight:600;font-family:var(--mono);background:var(--surface-3);color:var(--dim)}
.mo b.t{color:var(--gm);background:var(--gm-a12)}
.mo b.i{color:var(--ok-text);background:var(--ok-a12)}
.mo b.a{color:var(--im);background:var(--im-a12)}
.mo b.v{color:var(--ac);background:var(--ac-a12)}
.mo b.f{color:var(--warn-text);background:var(--warn-a12)}
.mo .ar{color:var(--faint);font-size:13px;margin:0 2px}
/* 主体：小节导航 + 内容 */
.mdp-body{display:grid;grid-template-columns:190px minmax(0,1fr);gap:34px;align-items:start;margin-top:34px}
.mdp-nav{position:sticky;top:88px;display:flex;flex-direction:column;gap:2px}
.mdp-nav a{display:flex;align-items:center;gap:10px;padding:9px 12px;border-radius:var(--r-lg);
  color:var(--dim);font-size:14px;font-weight:500;text-decoration:none;transition:background .12s,color .12s}
.mdp-nav a:hover{background:var(--ctl-on-bg);color:var(--text);text-decoration:none}
.mdp-nav a.on{background:var(--brand-dim);color:var(--brand-2)}
.mdp-nav svg{width:15px;height:15px;flex:none;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}
.mdl-block{margin-bottom:38px;scroll-margin-top:96px}
.mdl-block:last-child{margin-bottom:0}
.mdl-block h3{display:flex;align-items:center;gap:9px;font-size:20px;font-weight:600;letter-spacing:-.02em;
  color:var(--text);text-transform:none;margin:0 0 8px}
.mdl-block h3 svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round;color:var(--faint)}
.mdl-block .lead{font-size:14px;line-height:1.65;color:var(--dim);margin:0 0 16px;max-width:80ch}
.mtag{display:inline-block;font-size:13px;color:var(--dim);border:1px solid var(--line);
  border-radius:var(--r-md);padding:3px 9px;margin:0 6px 6px 0}
/* 价目表：一行一种 token，右边一个美元读数。圆角要落在外层盒子上——
   table 自己的 border-radius 配 overflow:hidden 在多数浏览器里不生效。 */
.prwrap{border:1px solid var(--line);border-radius:var(--r-xl);overflow:hidden;background:var(--surface)}
.prtab{width:100%;border-collapse:collapse;font-size:14px}
.prtab td{padding:13px 16px;border-bottom:1px solid var(--line-soft)}
.prtab tr:last-child td{border-bottom:none}
.prtab td:first-child{color:var(--dim)}
.prtab td:last-child{text-align:right;font-family:var(--mono);font-weight:500;color:var(--text);white-space:nowrap}
.prtab td .u{color:var(--faint);font-weight:400;margin-left:3px;font-family:var(--sans);font-size:12px}
.prnote{font-size:13px;color:var(--faint);margin:12px 0 0;line-height:1.6}
/* 你的用量 */
.mdl-spark{display:flex;align-items:flex-end;gap:2px;height:64px;border-bottom:1px solid var(--line)}
.mdl-spark span{flex:1;min-width:2px;background:var(--brand-a55);border-radius:2px 2px 0 0}
.mdl-spark span.err{background:var(--bad-a40);min-height:18px}
.mdl-x{display:flex;justify-content:space-between;font-family:var(--mono);font-size:12px;color:var(--faint);margin-top:7px}
.mdl-sum{display:flex;gap:30px;flex-wrap:wrap;margin-top:18px}
.mdl-sum div{font-size:12px;letter-spacing:.04em;text-transform:uppercase;color:var(--faint);font-weight:500}
.mdl-sum b{display:block;font-size:20px;font-weight:600;color:var(--text);margin-top:6px;letter-spacing:-.02em;
  text-transform:none;font-variant-numeric:tabular-nums}
@media (max-width:900px){
  .mdp-body{grid-template-columns:minmax(0,1fr);gap:20px}
  .mdp-nav{position:static;flex-direction:row;overflow-x:auto;scrollbar-width:none;
    border-bottom:1px solid var(--line);padding-bottom:2px}
  .mdp-nav::-webkit-scrollbar{display:none}
  .mdp-nav a{white-space:nowrap;border-radius:0;border-bottom:2px solid transparent;margin-bottom:-2px}
  .mdp-nav a.on{background:transparent;color:var(--text);border-bottom-color:var(--text)}
  .mdp-top h1{font-size:24px}
}

/* ---- token flow bar ---- */
.flow-cell{display:flex;align-items:center;gap:11px;min-width:130px}
.flow{display:flex;height:6px;flex:1;min-width:70px;border-radius:3px;overflow:hidden;background:var(--surface-3)}
.flow>span{display:block;height:100%;min-width:2px}
.flow-in{background:var(--gm)} .flow-out{background:var(--brand)}
.flow-pct{font-family:var(--mono);font-size:12px;color:var(--faint);flex:none;width:52px;text-align:right}

/* ---- 活动热力图 ---- */
.statstrip{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:14px;background:transparent;
  border:none;border-radius:0;overflow:visible}
.statstrip .stat{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-xl);padding:15px 17px;min-width:0}
.stat .k{font-size:12px;font-weight:500;letter-spacing:0;text-transform:none;color:var(--faint);white-space:nowrap}
.stat .v{font-size:22px;font-weight:700;letter-spacing:-.025em;margin-top:8px;line-height:1.1;
  font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.stat .v small{font-size:13px;font-weight:450;color:var(--dim);margin-left:4px}
.stat .v.txt{font-size:16px;font-family:var(--mono);font-weight:500;letter-spacing:0;padding-top:4px}
.statstrip.c3{grid-template-columns:repeat(3,1fr)}
.key-link{background:transparent;padding:0;font-weight:500;color:var(--text);display:inline-flex;align-items:center;gap:7px}
.key-link::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--faint-a45);flex:none;transition:background .12s}
.key-link:hover{color:var(--brand-2)}
.key-link:hover::before{background:var(--brand)}
.key-link:focus-visible{outline:2px solid var(--focus-line);outline-offset:2px;border-radius:var(--r-sm)}
.hm-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-xl);padding:17px 20px 15px;margin-bottom:28px}
.hm-head{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:14px}
.hm-cap{font-size:13px;color:var(--dim)}
.hm-scroll{overflow-x:auto;padding-bottom:3px}
.hm-grid{display:grid;grid-auto-flow:column;grid-template-rows:repeat(7,12px);grid-auto-columns:12px;gap:3px;width:max-content}
.hm-cell{width:12px;height:12px;border-radius:3px;transition:background-color .25s ease}
.hm-cell:hover{box-shadow:inset 0 0 0 1px var(--text-a60)}
.hm-cell.off{visibility:hidden}
.hm-cell.today{box-shadow:inset 0 0 0 1.5px var(--brand)}
.hm-c[data-lv="0"]{background:var(--surface-3)}
.hm-c[data-lv="1"]{background:var(--brand-30-on-surface-3)}
.hm-c[data-lv="2"]{background:var(--brand-55-on-surface-3)}
.hm-c[data-lv="3"]{background:var(--brand-80-on-surface-3)}
.hm-c[data-lv="4"]{background:var(--brand)}
.hm-c[data-lv="b"]{background:var(--brand-82-on-surface-3)}
.hm-months{display:grid;grid-auto-flow:column;grid-auto-columns:12px;grid-template-rows:14px;gap:3px;
  width:max-content;margin-top:5px;font-size:12px;color:var(--faint)}
.hm-months span{grid-row:1;white-space:nowrap}
.hm-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:10px;font-size:12px;color:var(--faint)}
.hm-legend{display:inline-flex;align-items:center;gap:3px}
.hm-legend i{width:10px;height:10px;border-radius:2.5px}

/* ---- 状态页 --------------------------------------------------------------
   间距节奏抄自 .hm-card / .tile：卡片 16-20px 内边距、卡间 12px、区块间 24px。
   颜色只用语义令牌（--ok/--warn/--bad/--or-coral），两套主题自动跟随。 */
.st-banner{display:flex;align-items:center;gap:12px;flex-wrap:wrap;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r-xl);padding:18px 20px;margin-bottom:24px}
.st-banner .st-dot{width:11px;height:11px;border-radius:50%;flex:none}
.st-banner.ok .st-dot{background:var(--ok)}
.st-banner.degraded .st-dot{background:var(--warn)}
.st-banner.outage .st-dot{background:var(--bad)}
.st-banner .st-lead{font-size:16px;font-weight:700;letter-spacing:-.01em}
.st-banner.ok .st-lead{color:var(--ok-text)}
.st-banner.degraded .st-lead{color:var(--warn-text)}
.st-banner.outage .st-lead{color:var(--bad-text)}
.st-banner .st-meta{margin-left:auto;font-size:13px;color:var(--dim);font-variant-numeric:tabular-nums}
/* 一个模型一行，十几行共用一张卡片。上一版是一模型一卡片，卡内七个宽格子：
   格子之所以宽，是因为每格都要写得下一个日期（七格分掉整个卡宽 ≈ 245px/格）。
   日期因此从格子上撑下来，收成列表底下一根共用坐标轴，格子才能瘦。 */
.st-list{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-xl);padding:2px 20px}
.st-row{display:flex;align-items:center;gap:20px;padding:15px 0;border-top:1px solid var(--line-soft)}
.st-row:first-child{border-top:0}
/* 名字在左、条在中、三个读数在右。左右定宽，所以所有行的条左右对齐——
   对齐是这个版式能成立的前提：同一列像素在每一行都是同一天。 */
.st-id{flex:none;width:216px;min-width:0;display:flex;flex-direction:column;gap:3px}
.st-id .st-name{font-family:var(--mono);font-size:13.5px;font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.st-id .st-sub{font-size:11.5px;color:var(--faint);font-variant-numeric:tabular-nums;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* ---- 右边三列：读数区 ------------------------------------------------------
   首字、生成速度、正常运行三个数各占一列，右对齐、列宽固定，所以它们在所有行
   的同一个 x 上——这不是排版洁癖，是这三个数唯一能用的读法：延迟和吞吐单看一
   行没有意义，「81 还是 26」要跟别的模型比才知道好坏。上一版把它们跟请求数串
   在同一条文字流里，`首字 1.34s` 和 `首字 2.50s` 就会因为前面请求数的位数不同
   而落在不同的 x 上，一列数字读下来是锯齿状的，等于没法比。

   两个速度读数用等宽字体、跟模型 id 同一个家族，正常运行率用正文字体加粗：
   **等宽 = 量出来的，正文 = 判出来的**。前两个是测量值，最后一个是我们对这条
   线下的结论，两者不该长得一样。 */
.st-meas{flex:none;display:flex;align-items:center;gap:14px}
.st-m{flex:none;display:flex;flex-direction:column;align-items:flex-end;gap:3px}
.st-m.c-ttfb{width:62px} .st-m.c-tps{width:78px} .st-m.st-fig{width:64px}
.st-m>b{font-family:var(--mono);font-size:12px;font-weight:500;color:var(--dim);
  font-variant-numeric:tabular-nums;white-space:nowrap}
/* 没有读数时留一个破折号而不是空白：定宽的一列里，空白读起来像「这里坏了」，
   破折号读起来像「这次没有数」——后者才是真的（样本不够，见页脚那句）。 */
.st-m>b.st-none{color:var(--faint);font-weight:400}
/* 每格自带的小标题：桌面上由表头统一说一次，所以藏起来；窄屏行会折行、表头对
   不上列，那时候再各说各的。同一份 DOM 两种读法，不用渲染两次。 */
.st-m>u{display:none;text-decoration:none;font-size:11px;color:var(--faint);white-space:nowrap}
/* 正常运行率回正文字体加粗——它是结论，不是读数。颜色留给下面那四条按档位的
   规则去写：在这里写一个 color 会盖掉它们（.st-m>b 只有一个类，输给两个类的
   .st-rate.ok），于是全页的绿/黄/红一起失效。 */
.st-rate{font-family:var(--sans);font-size:14px;font-weight:700}
.st-rate.ok{color:var(--ok-text)} .st-rate.warn{color:var(--warn-text)}
.st-rate.mid{color:var(--or-coral)} .st-rate.bad{color:var(--bad-text)}
/* 表头只盖住右边这三列——左边不写「模型」，因为那一列写的就是模型名，标它一次
   是多余的一件配饰。条那一列也不标：它底下已经有一根共用坐标轴在说话。 */
.st-head{display:flex;align-items:flex-end;gap:20px;padding:15px 0 9px}
.st-head .st-head-pad{flex:none;width:216px}
.st-head .st-head-band{flex:1 1 0;min-width:0}
.st-head .st-m>u{display:block;letter-spacing:.04em}
.st-band{flex:1 1 0;min-width:0;display:flex;align-items:stretch;gap:3px;height:32px}
.st-band i{flex:1 1 0;min-width:0;display:block;border-radius:2px;background:var(--ok-quiet)}
.st-band i.ok{background:var(--ok)} .st-band i.warn{background:var(--warn)}
.st-band i.mid{background:var(--or-coral)} .st-band i.bad{background:var(--bad)}
.st-band i:hover{filter:brightness(1.12);box-shadow:inset 0 0 0 1px var(--text-a60)}
/* 共用坐标轴：左右两个端点 + 中间一句总结，两根细线把它们拉开。
   它对齐到条的那一列（左右的空位和 .st-id / .st-fig 同宽）。 */
.st-axis{display:flex;align-items:center;gap:20px;padding:2px 20px 0;margin-top:10px}
.st-axis .st-axis-pad{flex:none;width:216px}
/* 右垫片 = 读数区整块的宽度（62 + 14 + 78 + 14 + 64），坐标轴才和条的右端对齐。 */
.st-axis .st-axis-pad.r{width:232px}
.st-axis .st-axis-line{flex:1 1 0;min-width:0;display:flex;align-items:center;gap:10px;
  font-size:11.5px;color:var(--faint);white-space:nowrap}
.st-axis .st-axis-line .rule{flex:1 1 0;min-width:8px;height:0;border-top:1px solid var(--line)}
.st-axis em{font-style:normal;color:var(--dim);font-variant-numeric:tabular-nums}
.st-legend{display:flex;align-items:center;gap:16px;flex-wrap:wrap;font-size:12px;color:var(--faint);
  margin:14px 2px}
.st-legend i{width:10px;height:10px;border-radius:3px;display:inline-block;margin-right:5px;vertical-align:-1px}
.st-legend .st-legend-note{margin-left:auto;color:var(--faint)}
@media (max-width:700px){
  .st-banner .st-meta{margin-left:0;flex-basis:100%}
  /* 窄屏上名字和百分比先占一行，条掉到下面独占整宽：
     定宽的名字列在 360px 的屏上会把条挤成一截。 */
  .st-list{padding:2px 14px}
  .st-row{flex-wrap:wrap;gap:8px 12px;padding:13px 0}
  .st-id{flex:1 1 auto;width:auto}
  /* 折行之后列就对不上表头了，所以表头收起来，每个读数各自带上小标题。定宽也
     一起松开——360px 的屏上三个固定列会把名字挤没。 */
  .st-head{display:none}
  .st-meas{gap:16px}
  .st-m{align-items:flex-end}
  .st-m.c-ttfb,.st-m.c-tps,.st-m.st-fig{width:auto}
  .st-m>u{display:block}
  .st-band{flex-basis:100%;order:3;gap:1.5px;height:26px}
  .st-axis{padding:2px 14px 0;gap:0}
  .st-axis .st-axis-pad{display:none}
}
#hm-tip{position:fixed;z-index:50;pointer-events:none;background:var(--toast-bg);color:var(--toast-text);
  border:1px solid var(--toast-line);border-radius:var(--r-lg);padding:8px 11px;
  font-size:13px;line-height:1.55;opacity:0;transition:opacity .12s;box-shadow:var(--shadow-3);white-space:nowrap}
#hm-tip.show{opacity:1}
#hm-tip .tt{font-weight:600}
#hm-tip .td{opacity:.7;font-family:var(--mono);font-size:12px}

/* ---- 分段控件 ---- */
.winsel{display:inline-flex;background:var(--fill-3);border:0;border-radius:var(--r-pill);padding:2px;gap:2px}
.winsel button{padding:6px 14px;border-radius:var(--r-pill);font-size:13px;font-weight:500;color:var(--text);
  background:transparent;transition:background-color .2s var(--ease),box-shadow .2s var(--ease)}
.winsel button:not(.on):hover{background:var(--fill-4)}
.winsel button.on{background:var(--seg-thumb);color:var(--text);font-weight:600;box-shadow:var(--seg-thumb-ring)}
.winsel button:focus-visible{outline:2px solid var(--focus-line);outline-offset:1px}
.bar{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:16px}

/* ---- 文档 / 代码 ---- */
.doc-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-xl);padding:20px 22px;margin-bottom:14px}
.doc-card h3{font-size:16px;font-weight:600;margin:0 0 6px;display:flex;align-items:center;gap:9px;letter-spacing:-.01em}
.doc-card .ep{font-family:var(--mono);font-size:13px;color:var(--dim);margin-bottom:13px;word-break:break-all}
.fmt-list{list-style:none;margin:0;padding:0;display:grid;gap:9px}
.fmt-list li{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.fmt-list code{font-family:var(--mono);font-size:13px;color:var(--dim);word-break:break-all}
pre{position:relative;background:var(--code-bg);border:1px solid var(--line);border-radius:var(--r-xl);
  padding:15px 17px;overflow:auto;font-family:var(--mono);font-size:13px;line-height:1.75;color:var(--dim);margin:0}
pre .cp{position:absolute;top:9px;right:9px;background:var(--glass-thick);-webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);border:1px solid var(--rail-line);
  border-radius:var(--r-pill);color:var(--dim);font-size:12px;font-weight:500;padding:4px 11px;opacity:0;transition:opacity .15s}
pre:hover .cp{opacity:1}
pre .cp:hover{color:var(--text)}
.hint{font-size:13px;color:var(--faint);line-height:1.65}
/* ---- 用量上限 ------------------------------------------------------------
   一条上限一块。输入框下面那条尺子是这组控件存在的理由：今天已用画成进度、
   近两周最重的一天画成一根刻度线，填多少才安全不用猜。间距节奏跟着 .field
   走（块间 14、标签与控件 8、说明 10），不另起一套更挤的数值。 */
.cap-list{display:flex;flex-direction:column;gap:14px}
.cap-row{padding:16px 18px;border:1px solid var(--line);border-radius:var(--r-xl);background:var(--surface-2)}
.cap-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 10px;margin-bottom:10px}
.cap-head b{font-size:14px;font-weight:650}
.cap-head .cap-why{font-size:12.5px;color:var(--faint)}
.cap-in{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.cap-in select{width:auto;min-width:140px;max-width:210px}
.cap-in input{width:96px}
.cap-in .unit{font-size:12.5px;color:var(--faint)}
.cap-meter{position:relative;height:6px;margin-top:14px;border-radius:999px;background:var(--line)}
.cap-meter .fill{position:absolute;left:0;top:0;bottom:0;border-radius:999px;background:var(--brand);transition:width .2s}
.cap-meter.hot .fill{background:var(--warn)}
.cap-meter.full .fill{background:var(--bad)}
.cap-meter.open{background:repeating-linear-gradient(90deg,var(--line) 0 5px,transparent 5px 10px)}
.cap-peak{position:absolute;top:-5px;bottom:-5px;width:2px;background:var(--faint-a45);border-radius:1px}
.cap-foot{display:flex;flex-wrap:wrap;gap:4px 14px;margin-top:10px;font-size:12.5px;color:var(--faint);line-height:1.6}
.cap-foot .now{color:var(--dim)}
/* 表格里的那一格：有上限印数字，没上限印一句能点的话。 */
.cap-cell{font-size:12.5px;color:var(--dim);white-space:nowrap}
.cap-cell.none{color:var(--faint)}
.hint .mono{overflow-wrap:anywhere}

/* ---- 弹窗（新建 Key 等表单仍然用它；模型详情已经不用了） ---- */
/* ---- 协议闸门 --------------------------------------------------------------
   进门前必须读完的那一屏。和 #modal 不共用一套，因为它们的目的相反：弹窗要能
   被关掉，这一屏不能——没有关闭按钮、点遮罩不关、Esc 不关，只有「同意」和
   「退出登录」两个出口。

   三个决定：
   · 进度条不是装饰。文档滚到底之前勾选框是灰的，那条填充是唯一能回答「还有多少
     没读」的东西；没有它，一个禁用的勾选框只会让人以为页面坏了。
   · 红线条款有自己的样式（左边线 + 后果标签）。整份文书里只有两条带它，扫一眼
     版面就知道哪两段会让账号消失。红色在这一屏只出现这两次。
   · 底栏是独立的一块、带自己的上边线和背景。它不跟着正文滚——「我读到哪了」和
     「我要做什么」是两件事，后者必须一直在手边。 */
#agate{position:fixed;inset:0;z-index:60;background:var(--scrim);
  display:flex;align-items:center;justify-content:center;padding:clamp(14px,4vw,44px)}
#agate.hide{display:none}
.agate-panel{width:min(760px,100%);max-height:min(88vh,900px);display:flex;flex-direction:column;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-2xl);
  box-shadow:var(--shadow-1);overflow:hidden}
.agate-head{padding:26px 30px 18px;border-bottom:1px solid var(--line);position:relative}
.agate-top{display:flex;align-items:flex-start;justify-content:space-between;gap:18px}
.agate-head h2{font-size:19px;font-weight:650;letter-spacing:-.01em;margin:0 0 8px;line-height:1.35}
.agate-head p{font-size:13.5px;line-height:1.7;color:var(--dim);margin:0;max-width:52ch}
.agate-ver{flex:0 0 auto;font-family:var(--mono);font-size:11.5px;color:var(--dim);
  background:var(--fill-4);border:0;border-radius:var(--r-pill);padding:4px 10px;white-space:nowrap}
/* 进度轨压在头部下边线上：它量的是下面那块正文，所以它长在两者的交界处。 */
.agate-rail{position:absolute;left:0;right:0;bottom:-1px;height:2px;background:var(--line)}
.agate-rail i{display:block;height:100%;width:0;background:var(--brand);transition:width .12s linear}
.agate-body{overflow-y:auto;overscroll-behavior:contain;padding:26px 30px 30px;-webkit-overflow-scrolling:touch}
.agate-lede{font-size:14px;line-height:1.8;color:var(--dim);margin:0 0 6px}
.agate-lede b{color:var(--text);font-weight:600}
.agate-clause{padding:24px 0;border-top:1px solid var(--line-soft)}
.agate-clause h3{font-size:15.5px;font-weight:650;letter-spacing:-.005em;margin:0 0 12px;line-height:1.45}
.agate-clause p{font-size:14px;line-height:1.85;color:var(--dim);margin:0 0 11px}
.agate-clause p:last-child{margin-bottom:0}
.agate-clause b{color:var(--text);font-weight:600}
.agate-clause.redline{border-left:3px solid var(--bad);padding-left:20px}
.agate-flag{font-size:12px;font-weight:600;letter-spacing:.03em;color:var(--bad-text);margin:0 0 11px}
.agate-flag::before{content:'';display:inline-block;width:6px;height:6px;border-radius:50%;
  background:var(--bad);margin-right:8px;vertical-align:.08em}
.agate-tail{font-size:12.5px;line-height:1.7;color:var(--faint);margin:26px 0 0;padding-top:18px;
  border-top:1px solid var(--line-soft)}
.agate-foot{flex:0 0 auto;border-top:1px solid var(--line);background:var(--surface-2);padding:20px 30px 22px}
.agate-consent{display:flex;align-items:flex-start;gap:11px;font-size:14px;line-height:1.6;color:var(--text);cursor:pointer}
.agate-consent input{width:17px;height:17px;flex:0 0 auto;margin:2px 0 0;padding:0;accent-color:var(--brand);cursor:pointer}
.agate-consent input:disabled{cursor:not-allowed}
.agate-consent.off{color:var(--faint);cursor:not-allowed}
.agate-consent.off input{cursor:not-allowed}
.agate-note{font-size:12.5px;line-height:1.6;color:var(--faint);margin:10px 0 0;padding-left:28px}
.agate-note.bad{color:var(--bad-text)}
.agate-acts{display:flex;justify-content:flex-end;gap:10px;margin-top:20px}
.agate-acts .btn:disabled{opacity:.45;cursor:not-allowed;filter:none}
@media (max-width:640px){
  #agate{padding:0;align-items:stretch}
  .agate-panel{width:100%;max-height:100%;border:0;border-radius:0}
  .agate-head{padding:20px 18px 16px}
  .agate-top{flex-direction:column;gap:10px}
  .agate-body{padding:20px 18px 24px}
  .agate-clause.redline{padding-left:14px}
  .agate-foot{padding:16px 18px 20px}
  .agate-acts{flex-direction:column-reverse}
  .agate-acts .btn{width:100%}
}
@media (prefers-reduced-motion:reduce){.agate-rail i{transition:none}}
/* 弹层打开期间锁住身后的底屏。手指落在弹层里任何一块不滚动的地方，浏览器会顺着
   祖先链找到 body 去滚——弹层纹丝不动，跑的是底屏。body{overflow:hidden} 在
   iOS Safari 上拦不住，只有 position:fixed 拦得住，代价是滚动位置要自己记下来、
   解锁时放回去（见 lockBodyScroll）。 */
body.body-locked{position:fixed;left:0;right:0;width:100%;overflow:hidden}
#scrim{position:fixed;inset:0;background:var(--scrim);z-index:40;opacity:0;pointer-events:none;transition:opacity .18s}
#scrim.show{opacity:1;pointer-events:auto}
#modal{position:fixed;left:50%;top:50%;transform:translate(-50%,-48%) scale(.97);width:min(440px,92vw);
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-2xl);
  z-index:41;padding:26px;opacity:0;pointer-events:none;transition:opacity .2s var(--ease),transform .4s var(--spring);box-shadow:var(--shadow-1);
  /* 内容长过屏幕时自己滚（充值弹窗带上收款码 + 发票四个字段就会）。之前只有
     .wide 有这两行，普通弹窗在手机上会两头被裁掉、按钮够不着。
     iOS 的 100vh 按工具栏收起后的「大视口」算，比可见区高一截——dvh 才是
     当下真实可见高度，支持它的浏览器用第二行覆盖第一行。 */
  max-height:calc(100vh - 32px);max-height:calc(100dvh - 32px);overflow-y:auto}
#modal.show{opacity:1;pointer-events:auto;transform:translate(-50%,-50%) scale(1)}
#modal.wide{width:min(960px,94vw);max-height:90vh;max-height:90dvh;overflow-y:auto}
#modal h3{margin:0 0 18px;font-size:20px;font-weight:600;letter-spacing:-.02em}
#m-foot{display:flex;justify-content:flex-end;gap:9px;margin-top:20px}
/* ---- 充值弹窗：两步 ----
   收款码在第 2 步，因为「实付多少」要等金额和发票勾完才算得出来（企业付费另收
   税点）。码摆在金额上面的那一版，客户扫的是一个当时还没算出来的数。 */
.tp-steps{display:flex;gap:9px;margin:0 0 22px}
.tp-step{display:flex;align-items:center;gap:9px;flex:1;padding:10px 13px;border-radius:var(--r-lg);
  border:1px solid var(--line-soft);background:var(--code-bg);font-size:13px;color:var(--faint)}
.tp-step i{width:20px;height:20px;border-radius:50%;flex:none;display:grid;place-items:center;
  font-style:normal;font-size:11.5px;font-weight:600;background:var(--line);color:var(--dim)}
.tp-step.on{border-color:var(--brand-a55);color:var(--text)}
.tp-step.on i,.tp-step.done i{background:var(--brand);color:var(--btn-ink)}
.tp-lanes{display:flex;gap:8px;margin-bottom:18px}
.tp-check{display:flex;align-items:flex-start;gap:10px;margin:0 0 16px;font-size:13.5px;line-height:1.6;cursor:pointer}
.tp-check input{margin:2px 0 0;width:16px;height:16px;flex:none;padding:0;accent-color:var(--brand);cursor:pointer}
.tp-due{background:var(--code-bg);border:1px solid var(--brand-a55);border-radius:var(--r-lg);
  padding:18px 20px 20px;margin:0 0 16px;text-align:center}
.tp-due .k{font-size:12.5px;color:var(--dim);margin-bottom:7px}
.tp-due .v{font-size:30px;font-weight:650;letter-spacing:-.02em;line-height:1.15}
.tp-due .s{font-size:12.5px;color:var(--faint);margin-top:10px;line-height:1.65}
.tp-pay{background:var(--code-bg);border:1px solid var(--line-soft);border-radius:var(--r-lg);
  padding:18px;margin:0 0 18px}
.tp-pay img{display:block;margin:0 auto;width:min(210px,68%);background:#fff;border-radius:12px;padding:10px}
.tp-pay .info{font-size:13px;color:var(--dim);white-space:pre-wrap;line-height:1.75;margin:14px 0 0;text-align:center}
.tp-bank{font-size:13px;line-height:2.2}
.tp-bank .ln{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.tp-todo{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin:0 0 14px;padding:15px 17px;
  border:1px solid var(--brand-a55);border-radius:var(--r-lg);background:var(--code-bg)}
.tp-todo .m{flex:1;min-width:170px}
.tp-todo .m .h{font-size:13.5px;line-height:1.6;color:var(--dim)}
.tp-todo .m .h b{font-size:16px;color:var(--text)}
.tp-todo .m .s{font-size:12px;color:var(--faint);margin-top:4px}
.tp-todo .acts{display:flex;gap:8px;flex-wrap:wrap}
/* 我的发票：一行一张。和 tp-todo 同一套节奏，但它是历史不是待办，所以边框
   用普通线而不是品牌色 —— 这一块不需要把人的注意力抢过来。 */
.ac-inv{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin:12px 0 0;padding:14px 16px;
  border:1px solid var(--line-soft);border-radius:var(--r-lg);background:var(--code-bg)}
.ac-inv .m{flex:1;min-width:180px}
.ac-inv .m .h{font-size:13.5px;color:var(--text);word-break:break-all}
.ac-inv .m .s{font-size:12px;color:var(--faint);margin-top:4px}
.tp-done{display:flex;align-items:flex-start;gap:14px;background:var(--code-bg);border:1px solid var(--line-soft);
  border-radius:var(--r-lg);padding:18px 20px;margin:0 0 16px}
.tp-done .ic{width:30px;height:30px;border-radius:50%;flex:none;display:grid;place-items:center;
  background:var(--ok);color:var(--btn-ink);font-size:15px;font-weight:700}
.tp-done .h{font-size:15px;font-weight:600;margin:2px 0 6px}
.tp-done .s{font-size:13px;color:var(--dim);line-height:1.7}
.reveal{font-family:var(--mono);font-size:13px;background:var(--code-bg);border:1px solid var(--brand-a55);
  border-radius:var(--r-lg);padding:14px 16px;word-break:break-all;color:var(--text)}

/* ---- toast：反色小条 ---- */
/* 提示：底部居中的一枚玻璃胶囊（HUD） */
#toasts{position:fixed;bottom:24px;left:50%;transform:translateX(-50%);display:flex;flex-direction:column;align-items:center;gap:8px;z-index:60}
.toast{display:flex;align-items:center;gap:10px;background:var(--toast-bg);color:var(--toast-text);
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  border:1px solid var(--toast-line);border-radius:var(--r-pill);padding:10px 18px 10px 15px;font-size:14px;font-weight:500;
  animation:toastin .42s var(--spring) both;box-shadow:var(--shadow-3)}
@keyframes toastin{from{opacity:0;transform:translateY(12px) scale(.96)}to{opacity:1;transform:none}}
.toast::before{content:"";width:7px;height:7px;border-radius:50%;flex:none;background:currentColor;opacity:.5}
.toast.ok::before{background:var(--ok);opacity:1}
.toast.bad::before{background:var(--bad);opacity:1}
.toast.out{animation:sink .22s ease both}
@keyframes sink{to{opacity:0;transform:translateY(8px)}}

/* ---- 确认卡 ---- */
.cfm-scrim{position:fixed;inset:0;background:var(--scrim);z-index:80;opacity:0;pointer-events:none;transition:opacity .16s}
.cfm-scrim.show{opacity:1;pointer-events:auto}
/* 确认框：一块居中的厚玻璃（macOS 26 的提示框），弹出时轻轻放大到位 */
.cfm{position:fixed;left:50%;top:50%;width:min(420px,92vw);z-index:81;
  background:var(--glass-thick);-webkit-backdrop-filter:blur(40px) saturate(180%);backdrop-filter:blur(40px) saturate(180%);
  border:1px solid var(--rail-line);border-radius:var(--r-2xl);padding:24px 24px 20px;
  box-shadow:var(--sheen),var(--shadow-1);opacity:0;pointer-events:none;
  transform:translate(-50%,-50%) scale(1.06);transition:opacity .18s var(--ease),transform .34s var(--spring)}
.cfm.show{opacity:1;pointer-events:auto;transform:translate(-50%,-50%) scale(1)}
.cfm h4{font-size:18px;font-weight:600;letter-spacing:-.02em;margin:0 0 9px;display:flex;align-items:center;gap:9px}
.cfm h4 .lamp{background:var(--warn)}
.cfm.danger h4 .lamp{background:var(--bad)}
.cfm p{margin:0 0 20px;color:var(--dim);font-size:14px;line-height:1.65;white-space:pre-line}
.cfm-foot{display:flex;justify-content:flex-end;gap:10px}
.cfm-foot .btn{flex:1 1 0;min-width:0;justify-content:center}

/* ============ 移动端 ============ */
@media (max-width:760px){
  .wrap{padding:0 max(14px,env(safe-area-inset-right)) 60px max(14px,env(safe-area-inset-left))}
  .topbar{margin:0 -14px;padding:6px 14px;height:auto;min-height:56px;gap:8px}
  .brand{gap:8px;min-width:0}
  .brand .name{font-size:17px}
  .topbar .right{gap:4px;min-width:0}
  .topbar .who{display:none}
  /* 导航在 ≤640px 折到第二行（见上面那一档的 order:3 / flex:1 1 100%），
     它的负边距要跟着这一档的 14px 页边走，否则第一个标签被切掉 10px。 */
  .tabs{gap:0;margin:2px -14px 0;padding:0 14px}
  .tab{padding:8px 9px;font-size:13px}
  /* 吸顶位置跟着量出来的顶栏高度走（--topbar-h），不再按定高推算。 */
  .lv{margin:0 -14px;padding:0 14px;height:38px;gap:0 14px;width:calc(100% + 28px)}
  .lv-metrics{gap:0 14px}
  .lv-win{display:none}
  .view{padding-top:12px}
  h1.page{font-size:20px;letter-spacing:-.02em}
  .eyebrow{font-size:12px;margin:0 0 8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .winnote,.carline{display:none}
  .sec{margin-bottom:22px}
  .tiles,.tiles.c3,.tiles.c2{grid-template-columns:repeat(2,1fr);gap:8px}
  .tile{padding:12px 12px}
  .tile .v{font-size:20px;margin-top:6px}
  .tile .sub{font-size:12px;margin-top:4px}
  .statstrip,.statstrip.c3{grid-template-columns:repeat(2,1fr)}
  .panel{overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain}
  .panel th,.panel td{white-space:nowrap}
  .panel td{max-width:min(72vw,340px);overflow:hidden;text-overflow:ellipsis}
  .panel td.empty{white-space:normal;max-width:none}
  .winsel{max-width:100%;overflow-x:auto;scrollbar-width:none}
  .winsel::-webkit-scrollbar{display:none}
  .winsel button{flex:none;white-space:nowrap}
  .flow-cell{min-width:120px}
  #modal{width:min(440px,calc(100vw - 24px))}
  #modal.wide{left:0;right:0;top:auto;bottom:0;transform:translateY(28px);width:100vw;
    max-height:calc(100dvh - 42px);border-radius:16px 16px 0 0;
    border-left:none;border-right:none;border-bottom:none;
    padding:22px 16px calc(22px + env(safe-area-inset-bottom));overscroll-behavior:contain}
  #modal.wide.show{transform:translateY(0)}
  #toasts{bottom:calc(16px + env(safe-area-inset-bottom));left:14px;right:14px;transform:none;align-items:center}
  .toast{max-width:100%}
  .doc-card{padding:17px 15px}
  .mdp-body{margin-top:24px}
}
/* 这档必须写在上面的双列规则之后；同权重时，后写的单列才能在 400px 生效。 */
@media (max-width:400px){
  .tiles,.tiles.c3,.tiles.c2,.statstrip,.statstrip.c3{grid-template-columns:1fr}
}
@media (pointer:coarse){
  /* 小于 16px 的输入框一被对焦，iOS 就把整页放大，吸顶条和弹层的定位随即错位。
     !important 是有意的：这条要压过每一处按版面调过字号的 id / 类选择器，
     并且让以后新加的输入框自动落在保护里。textarea 原来漏在外面。 */
  input,select,textarea{font-size:16px!important}
  /* 模型页的筛选项：勾选框只有 15px，靠整行 <label> 才按得中，而那一行在触屏上
     只有 33px 高——筛选是要连点好几下的动作，按不中一次就得重来。撑到 40px。 */
  .fopt{padding-top:9px;padding-bottom:9px}
  .btn.sm{padding:8px 13px}
  .help-btn{width:38px;height:38px}
  .winsel button{padding:8px 14px}
  pre .cp{opacity:.9}
}

/* 订阅页的区块间距比全局宽一档：hero 版面需要更大的呼吸。 */
#v-seat .sec{margin-bottom:52px}
/* 购买面板：浅灰底衬白卡（苹果 #f5f5f7 衬 #fff 的层次），货架整体
   收进一块圆角面板里居中——买这件事发生在"一个台面"上，而不是
   散在页面里。实时条也在订阅页收起：收银台上方不报运营数据。 */
body[data-view=seat] .lv{display:none!important}
.shelf{background:var(--surface-2);border-radius:24px;padding:36px 28px 30px}
.shelf h1.page{text-align:center;font-size:36px;letter-spacing:-.04em}
.shelf .eyebrow{text-align:center;margin:12px 0 32px;color:var(--dim)}
.shelf .car-grid{max-width:1020px;margin:0 auto;gap:18px}
.shelf .hint{max-width:1020px;margin:16px auto 0;text-align:center}
/* API 额度不是"第三个档位"——降为档位行下方的一条横向加购行：
   选订阅的时刻不该被另一种付费方式分走注意力。 */
.car.allow{grid-column:1/-1;max-width:1020px;margin:0 auto;flex-direction:row;
  align-items:center;flex-wrap:wrap;gap:6px 22px;padding:20px 24px;box-shadow:none}
.car.allow:hover{transform:none}
.car.allow h3{font-size:17px}
.car.allow .spec{margin:0;flex:1 1 240px;white-space:normal;overflow:visible}
.car.allow .plate{margin:0}
.car.allow .plate .now b{font-size:20px}
.car.allow .held{width:auto;order:9;flex-basis:100%;padding:0}
.car.allow .btn{width:auto;order:10;padding:10px 24px}
@media(max-width:760px){
  #v-seat .sec{margin-bottom:22px}
  .shelf{padding:16px 12px 14px;border-radius:16px}
  .shelf h1.page{font-size:22px}
  .shelf .eyebrow{margin:6px 0 14px;font-size:13px;white-space:normal}
  .car.allow .btn{width:100%}
}
/* ---- 折叠区：说明、命令、排障——内容都在，但默认收起，不抢买家的视线 ---- */
details.fold{border:1px solid var(--line);border-radius:var(--r-xl);background:var(--surface)}
details.fold>summary{display:flex;align-items:center;gap:9px;padding:15px 18px;cursor:pointer;list-style:none;
  font-size:14px;font-weight:500;color:var(--dim);user-select:none}
details.fold>summary::-webkit-details-marker{display:none}
details.fold>summary:hover{color:var(--text)}
details.fold>summary::after{content:"";margin-left:auto;width:7px;height:7px;border-right:1.5px solid var(--faint);
  border-bottom:1.5px solid var(--faint);transform:rotate(-45deg) translateY(1px);transition:transform .18s}
details.fold[open]>summary::after{transform:rotate(45deg) translateY(-2px)}
details.fold[open]>summary{color:var(--text);border-bottom:1px solid var(--line-soft)}
details.fold .fold-body{padding:4px 18px 18px}
/* ---------- 订阅 · 档位卡 ----------
   层次学小米商城（产品名、一行卖点、价格、按钮）；质感学苹果购买页：
   大留白、柔和悬浮阴影、墨色大价格——彩色只出现在「立省」徽标、推荐角标
   和 CTA 三处，别处一律克制。悬浮时卡片轻抬 2px，阴影加深一档。 */
/* minmax(0,1fr)：卖点行不换行，裸 1fr 会被各卡内容的最小宽度撑出
   不等宽的三列（实测 284/336/193）。0 下限强制等分，溢出走省略号。 */
.car-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px}
/* 动效：入场交错升起，悬停轻抬放大，按压回弹——弹簧曲线让「点上去
   卡片放大」有果冻感而不是线性放大。触屏没有 hover，按压反馈照常。 */
@keyframes shelfIn{from{opacity:0;transform:translateY(14px) scale(.985)}to{opacity:1;transform:none}}
.shelf .car{animation:shelfIn .55s cubic-bezier(.22,.61,.25,1) both}
.shelf .car:nth-child(2){animation-delay:.07s}
.shelf .car:nth-child(3){animation-delay:.14s}
.shelf .car:nth-child(4){animation-delay:.21s}
.car{position:relative;display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--line);
  border-radius:16px;padding:28px 26px 24px;box-shadow:var(--shadow-3);
  transition:transform .22s cubic-bezier(.34,1.56,.64,1),box-shadow .2s ease,border-color .2s ease}
@media(hover:hover){.car:hover{transform:translateY(-3px) scale(1.015);box-shadow:var(--shadow-1);border-color:var(--faint-a30)}}
.car:active{transform:scale(1.03)}
.car .btn:active{transform:scale(.97)}
.car.mine{border-color:var(--brand-a52)}
/* 暂未开放的同几何、同阴影，只整体降不透明度——尺寸忽变比缺货更可疑。
   locked 是持有人看别的池：在卖，但换过去要找客服，同一种「看得见、点不了」。 */
.car.full,.car.locked{opacity:.62}
.car.reco{border-color:var(--brand-40-on-line)}
.reco-tag{position:absolute;top:16px;right:16px;font-size:11px;font-weight:600;color:var(--brand-2);
  background:var(--brand-dim);padding:3px 10px;border-radius:999px;letter-spacing:.02em}
.car h3{font-size:19px;font-weight:600;margin:0;letter-spacing:-.02em}
.car .spec{margin:9px 0 0;font-size:13px;color:var(--dim);line-height:1.6;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.plate{margin:16px 0 2px}
.plate .now{display:flex;align-items:baseline;gap:3px;flex-wrap:wrap}
.plate .now .cur{font-size:17px;color:var(--dim);font-weight:500}
.plate .now b{font-size:38px;font-weight:700;letter-spacing:-.03em;font-variant-numeric:tabular-nums;color:var(--text)}
.plate .now .per{font-size:13px;color:var(--faint);margin-left:4px}
.plate .now .was{font-size:13.5px;color:var(--faint);margin-left:10px;font-weight:450}
.plate .now .save{font-style:normal;font-size:11.5px;font-weight:600;color:var(--brand-2);
  background:var(--brand-dim);padding:2px 8px;border-radius:999px;margin-left:8px;transform:translateY(-2px)}
.car .btn{padding:12px 16px;font-weight:600;border-radius:12px;font-size:14.5px}
.car .btn[disabled]{box-shadow:none}
.car .why{font-size:14px;color:var(--dim);margin:6px 0 0;line-height:1.55}
/* margin-top:auto + padding-top：底部那组（余位/持有/按钮）钉在卡片底边，四张卡
   的按钮排成一条线；padding 保证最高的那张卡里它和上文仍有呼吸空间。 */
.car .left{font-size:13px;color:var(--faint);margin:auto 0 13px;padding-top:12px;font-variant-numeric:tabular-nums}
.car .left b{color:var(--text);font-family:var(--mono);font-weight:500}
.car .left.none{color:var(--warn-text)}
.car .btn{width:100%}
/* 主按钮之下的第二个动作（再买一份 / 再续 30 天）。做成一行字而不是并排的
   第二颗按钮：并排会把这一排的比较维度从「三个档位」变成「六个选项」。 */
.car .try{width:100%;margin-top:10px;padding:2px 0;border:0;background:none;cursor:pointer;
  font-family:inherit;font-size:12.5px;color:var(--faint);text-align:center;
  border-radius:var(--r-sm);transition:color .14s}
.car .try b{font-family:var(--mono);font-weight:500;color:var(--dim);transition:color .14s}
.car .try:hover,.car .try:hover b,.car .try:focus-visible,.car .try:focus-visible b{color:var(--brand-2)}
.car .btn[disabled]{background:transparent;color:var(--faint);border:1px solid var(--line);cursor:not-allowed}
.car .held{width:100%;text-align:center;font-size:13px;color:var(--brand-2);font-weight:500;padding:9px 0}
/* 升级报价明细：三行「项目 …… 金额」，最后一行是应付。每行之间留出行距，
   金额用等宽对齐——这四个数客户会自己加一遍，挤在一起他就加不动了。
   现金不够时，建议充值单独放在这张表下面，不进这三行的加减。 */
.upq{display:flex;flex-direction:column;gap:12px;margin:0 0 18px;padding:16px 18px;
  background:var(--surface-2,rgba(127,127,127,.06));border:1px solid var(--line);border-radius:12px}
.upq .r{display:flex;align-items:baseline;justify-content:space-between;gap:16px;font-size:13px;color:var(--dim)}
.upq .r b{font-family:var(--mono);font-variant-numeric:tabular-nums;font-weight:500;color:var(--text)}
.upq .r.off b{color:var(--brand-2)}
.upq .r.pay{margin-top:4px;padding-top:12px;border-top:1px solid var(--line);font-size:14px;color:var(--text)}
.upq .r.pay b{font-size:19px}
.upq:has(+ .upq-next){margin-bottom:12px}
.upq-next{display:flex;flex-direction:column;gap:10px;margin:0 0 16px;padding:16px 18px;
  background:var(--surface-2,rgba(127,127,127,.06));border:1px solid var(--line);border-radius:12px}
.upq-next .r{display:flex;align-items:baseline;justify-content:space-between;gap:16px;font-size:14px;color:var(--text)}
.upq-next b{font-family:var(--mono);font-variant-numeric:tabular-nums;font-weight:500;font-size:19px}
/* 额度卡：同一排货架上的另一种坐法。舱位那格画的是「不占座」这句话本身，
   min-height 对齐排座位的舱位（7+44+7+边框 2），四张卡在一条水平线上。 */
/* 四个档位换四列；中屏折成 2×2，窄屏由下面的通用规则收成一列。 */
.car-grid.four{grid-template-columns:repeat(4,minmax(0,1fr))}
@media (max-width:1080px){.car-grid.four{grid-template-columns:repeat(2,1fr)}}
/* 你的车 */
.ride{display:flex;flex-wrap:wrap;align-items:center;gap:18px;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-xl);padding:18px 20px;margin-bottom:26px}
/* 未订阅态退成大标题上方的一行引题：hero 版面里再放一张虚线卡，
   会在最该安静的地方先吵起来。 */
.ride.off{display:block;border:none;background:transparent;padding:0 0 10px;text-align:center}
.ride.off .who-car .t{font-size:13px;font-weight:600;color:var(--dim)}
.ride.off .who-car .s{font-size:13px;color:var(--faint);margin-top:3px}
/* 座位图。影院选座那套约定：实心座位=有人，描边座位=空着，主色那个是你。
   格子里带一个词，是因为「这辆车上还有没有人」正是客户看不出来的那件事——
   靠深浅两块灰去猜，第二个格子会被当成还没加载出来的占位。 */
.seatmap{flex:0 0 auto;display:flex;gap:8px;padding:9px;border:1px solid var(--line);
  border-radius:var(--r-lg);background:var(--surface-3-a50)}
.seat{width:50px;flex:0 0 50px;height:52px;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:5px;border-radius:var(--r-md);font-size:11px;font-weight:600;letter-spacing:.02em}
.seat .sg{width:19px;height:19px;display:block}
.seat.you{color:var(--brand-2);background:var(--brand-dim);border:1px solid var(--brand-a52)}
.seat.taken{color:var(--dim);background:var(--faint-a16);border:1px solid var(--faint-a30)}
.seat.free{color:var(--faint);background:transparent;border:1px dashed var(--faint-a38)}
/* 车型卡里的座位按格子等分，高度对齐原来的舱位 */
.cabin .seat{flex:1 1 0;width:auto;min-width:0;height:44px;padding:0}
.ride .who-car{flex:1 1 210px;min-width:0}
.ride .who-car .t{font-size:18px;font-weight:600;letter-spacing:-.02em}
.ride .who-car .s{font-size:13px;color:var(--dim);margin-top:5px}
.ride .term{flex:0 0 auto;min-width:172px;text-align:right}
.ride .term .d{font-size:16px;font-weight:600;font-variant-numeric:tabular-nums}
.ride .term .rail{height:4px;border-radius:2px;background:var(--surface-3);margin:9px 0 0;overflow:hidden}
.ride .term .rail i{display:block;height:100%;border-radius:2px;background:var(--brand)}
/* 小时刻度。服务期短于 48 小时时换掉上面那条连续的进度条——按天读，「1 天后到期」
   在整整一天里一动不动，然后跳成 0，而这段时间正是客户最需要知道还剩多少的时候。
   一格一小时，剩下的实心、用掉的留空；和状态页那张固定格数的网格是同一套读法，
   所以不用学。不做秒级跳动：那是在制造焦虑，而这条要回答的是「还剩多少」。 */
.ride .term.hours{min-width:246px}
.ride .term .hrs{display:flex;gap:2px;margin:9px 0 0}
.ride .term .hrs i{flex:1 1 0;height:10px;border-radius:1.5px;background:var(--faint-a16)}
.ride .term .hrs i.on{background:var(--brand)}
.ride .term.soon .hrs i.on{background:var(--warn)}
.ride .term.soon .d{color:var(--warn-text)} .ride .term.soon .rail i{background:var(--warn)}
.ride .acts{flex:0 0 auto;display:flex;gap:8px;flex-wrap:wrap}
.ride .acts{align-items:flex-start}
.ride .mine{flex:1 1 100%;order:9;padding-top:20px;margin-top:2px;border-top:1px solid var(--line)}
/* 没有脚注时最后一条轨道会直接顶到下一块的分隔线上：脚注让出的那段呼吸要补回来，
   否则「删掉一句话」顺手把这一屏挤紧了。 */
.ride .mine.nofoot{padding-bottom:18px}
/* 额度窗口区：照 claude.ai 用量页的版式排（2026-08-26）——窗口名和重置时间摞在
   左栏、细圆角胶囊进度条铺满中栏、右栏一句「已用 N%」；状态（用尽/吃紧/读不到）
   画成一块圆角提示条。信息没有增减，改的只是几何：旧版把窗口名当小节标题、每条
   轨道再带一列小标签，三个窗口读成九行小字，「哪条快满了」反而要逐行找。 */
.mine .mh{font-size:15px;font-weight:600;color:var(--text);margin:0 0 16px}
.qnote{display:flex;align-items:flex-start;gap:10px;border:1px solid var(--line);border-radius:var(--r-xl);
  padding:13px 16px;margin:0 0 18px;font-size:13px;line-height:1.65;color:var(--dim)}
.qnote svg{flex:0 0 auto;width:16px;height:16px;margin-top:3px;color:var(--faint)}
.qnote b{font-weight:600;color:var(--text)}
.qnote.warn{border-color:var(--warn-a40);background:var(--warn-dim)}
.qnote.warn b{color:var(--warn-text)}
.qnote.bad{border-color:var(--bad-a40);background:var(--bad-a9)}
.qnote.bad b{color:var(--bad-text)}
.keys{display:flex;flex-wrap:wrap;gap:6px 16px;margin:0 0 16px;font-size:13px;color:var(--dim)}
.keys .k{display:inline-flex;align-items:center;gap:6px}
.keys .sw{width:13px;height:9px;border-radius:999px;flex:0 0 auto;box-shadow:inset 0 0 0 1px var(--line)}
.keys .sw.veh{background:var(--faint-a60)}
.keys .sw.own{background:var(--brand)}
.keys .sw.lane{background:var(--brand-dim);border-right:2px solid var(--text)}
.keys .sw.over{background:var(--warn)}
.keys .sw.ghost{background:repeating-linear-gradient(115deg,var(--faint-a45) 0 3px,transparent 3px 8px)}
.win{display:grid;grid-template-columns:minmax(130px,200px) minmax(0,1fr);gap:6px 22px;align-items:center;margin-bottom:24px}
.win:last-of-type{margin-bottom:0}
.win .wh{display:flex;flex-direction:column;gap:3px;min-width:0}
.win .wh .nm{font-size:14.5px;font-weight:550;color:var(--text)}
.win .wh em{font-style:normal;font-size:12.5px;color:var(--faint);font-variant-numeric:tabular-nums}
.win .bars{display:flex;flex-direction:column;gap:9px;min-width:0}
.gauge{display:grid;grid-template-columns:30px minmax(90px,1fr) minmax(84px,auto);gap:0 12px;align-items:center}
/* 一个窗口只剩一条轨道（单人车有读数）时不摆「账号」小标签：标签的意义是把上下
   两条轨道对起来，只有一条时它什么都不指。 */
.gauge.lone{grid-template-columns:minmax(90px,1fr) minmax(84px,auto)}
.gauge .tg{font-size:12px;color:var(--faint);font-weight:450;white-space:nowrap}
.gauge .track{position:relative;height:10px;border-radius:999px;background:var(--surface-3);overflow:hidden}
.gauge .track.none{background:transparent;border:1px dashed var(--line)}
.gauge .fill.veh{position:absolute;inset:0 auto 0 0;border-radius:999px;background:var(--faint-a60);
  transition:width .5s cubic-bezier(.2,.8,.3,1)}
/* 唯一的一条就是主角，用主色画——此时图例不渲染，灰色没有可对照的对象。 */
.gauge.lone .fill.veh{background:var(--brand)}
.gauge .lane{position:absolute;inset:0 auto 0 0;background:var(--brand-dim)}
.gauge .fill.own{position:absolute;top:0;bottom:0;left:0;border-radius:999px;background:var(--brand);
  transition:width .5s cubic-bezier(.2,.8,.3,1)}
.gauge .over{position:absolute;top:0;bottom:0;background:var(--warn);
  transition:width .5s cubic-bezier(.2,.8,.3,1),left .5s cubic-bezier(.2,.8,.3,1)}
.gauge .tick{position:absolute;top:0;bottom:0;width:2px;margin-left:-1px;
  background:var(--text);box-shadow:0 0 0 1px var(--surface)}
.gauge .ghost{position:absolute;top:0;bottom:0;opacity:.42;
  background:repeating-linear-gradient(115deg,var(--faint-a45) 0 3px,transparent 3px 8px)}
.gauge .rd{font-size:13px;color:var(--dim);font-variant-numeric:tabular-nums;white-space:nowrap;text-align:right}
.gauge .rd b{font-weight:550;color:var(--text)}
.gauge .rd .sub{color:var(--faint)}
.gauge.own.over .rd b{color:var(--warn-text)}
.gauge.veh.full .fill.veh{background:var(--bad-a60)}
.gauge.veh.full .track{background:var(--bad-a11)}
.win.scoped .wh .nm{color:var(--dim);font-weight:450}
.mine .foot{font-size:13px;color:var(--faint);margin-top:16px;line-height:1.6}
.carline{font-size:13px;color:var(--faint);line-height:1.65;margin:0 0 16px}
@media (max-width:760px){
  .win{grid-template-columns:1fr;gap:8px}
  .gauge{grid-template-columns:auto minmax(0,1fr);gap:4px 10px}
  .gauge .tg{grid-column:1;grid-row:1}
  .gauge .rd{grid-column:2;grid-row:1;text-align:right}
  .gauge .track{grid-column:1/-1;grid-row:2}
  .gauge.lone{grid-template-columns:minmax(0,1fr)}
  .gauge.lone .rd{grid-column:1;grid-row:1}
  .gauge.lone .track{grid-column:1;grid-row:2}
}
.ride.held{border-style:dashed;border-color:var(--warn-a40)}
.ride.held .who-car .t{color:var(--warn-text)}
.ride.ban{border-color:var(--warn-a40);margin-bottom:16px}
.ride.ban .who-car .t{color:var(--warn-text)}
.ride.ban .acts{margin-top:14px}
/* 当前模式徽章。默认（包月中）安静：低饱和描边即可，这是常态不该抢戏；
   「额度顶上」用警示色——它意味着此刻每一次调用都在扣钱，是客户该注意的状态。 */
.ride .modechip{display:inline-block;vertical-align:3px;margin-left:10px;padding:3px 9px;
  border-radius:999px;font-size:11px;font-weight:600;letter-spacing:.03em;
  color:var(--dim);border:1px solid var(--line);background:var(--surface-3-a50)}
.ride .modechip.tu{color:var(--warn-text);border-color:var(--warn-a40);background:transparent}
/* 包月条上的额度余讯：一整行、排在份额与 SLA 之后——它是补充说明，不是主角。 */
.ride .allow-note{flex:1 1 100%;order:11;font-size:12.5px;color:var(--faint);line-height:1.65;
  padding-top:14px;margin-top:2px;border-top:1px solid var(--line-soft)}
.ride .allow-note b{color:var(--text);font-family:var(--mono);font-weight:500}
.ride .allow-note div+div{margin-top:7px}
/* 「额度顶上」自助开关：跟补充说明同级的一行，滑块在左、说明在右。
   触屏上开关比链接好按，说明文字保持 allow-note 的字号和呼吸。 */
.ride .allow-note .tuswitch{display:flex;align-items:center;gap:10px;margin-top:10px}
.swx{position:relative;display:inline-block;width:34px;height:20px;flex:none;cursor:pointer}
.swx input{position:absolute;inset:0;opacity:0;width:100%;height:100%;margin:0;cursor:pointer}
.swx i{display:block;width:100%;height:100%;border-radius:999px;background:var(--surface-3-a50);
  border:1px solid var(--line);transition:background .15s,border-color .15s}
.swx i::after{content:'';position:absolute;top:3px;left:3px;width:14px;height:14px;border-radius:50%;
  background:var(--dim);transition:transform .15s,background .15s}
.swx input:checked+i{background:var(--ok-a12);border-color:var(--ok-a60)}
.swx input:checked+i::after{transform:translateX(14px);background:var(--ok)}
.swx input:disabled+i{opacity:.5}
/* 「我的车」：持有几辆车的人在这里切换此刻开哪一辆。整行、排在份额之前——
   账号打满时这一排就是他要找的东西，不能藏到额度说明后面。一辆车的人不画。
   一行一辆：名字与到期在左、状态或按钮在右；用 allow-note 同一套上边距和分隔线。 */
.ride .garage{flex:1 1 100%;order:8;padding-top:16px;margin-top:2px;border-top:1px solid var(--line)}
.ride .garage .gh{font-size:13px;font-weight:600;color:var(--text);margin:0 0 10px}
.ride .garage .gr{display:flex;align-items:center;gap:14px;padding:10px 0;border-top:1px solid var(--line-soft)}
.ride .garage .gr:first-of-type{border-top:0}
.ride .garage .gn{flex:1 1 auto;min-width:0;font-size:14px;font-weight:500}
.ride .garage .gn .s{display:block;font-size:12px;color:var(--faint);margin-top:3px;font-weight:400}
.ride .garage .gs{flex:none;font-size:12px;font-weight:600;color:var(--brand-2);padding:4px 10px;border-radius:999px;
  border:1px solid var(--brand-a52);background:var(--brand-dim)}
.ride .garage .gf{font-size:12px;color:var(--faint);margin:10px 0 0;line-height:1.6}
.sla{flex:1 1 100%;order:10;padding-top:14px;margin-top:2px;border-top:1px solid var(--line)}
.sla .head{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;font-size:13px;color:var(--faint)}
.sla .head b{font-size:16px;font-weight:600;color:var(--text);font-variant-numeric:tabular-nums}
.sla .head .sep{color:var(--line)}
.sla .live{display:inline-flex;align-items:center;gap:6px;padding:2px 9px;border-radius:999px;
  font-size:12px;font-weight:500;color:var(--warn-text);background:var(--warn-dim)}
.sla .live::before{content:'';width:6px;height:6px;border-radius:50%;background:var(--warn);
  animation:slaPulse 1.6s ease-in-out infinite}
@keyframes slaPulse{0%,100%{opacity:1}50%{opacity:.25}}
.sla .gapfold{margin-top:10px}
.sla .gapfold summary{font-size:13px;color:var(--faint);cursor:pointer;user-select:none;width:fit-content}
.sla .gapfold summary:hover{color:var(--text)}
.sla .gaps{margin-top:10px;display:flex;flex-direction:column;gap:5px}
.sla .gap{display:grid;grid-template-columns:auto 1fr auto;gap:10px;align-items:baseline;
  font-size:13px;color:var(--faint);font-variant-numeric:tabular-nums}
.sla .gap .when{font-family:var(--mono);font-size:12px}
.sla .gap .got{color:var(--brand-2)}
.sla .foot{font-size:13px;color:var(--faint);margin-top:10px;line-height:1.55}
/* ---- 这段时间你开了多少 ---- */
.worth{display:grid;grid-template-columns:minmax(240px,1.15fr) minmax(0,1fr);gap:14px;align-items:stretch}
.worth-hero{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-xl);
  padding:20px 22px;display:flex;flex-direction:column;justify-content:center}
.worth-hero .k{font-size:12px;font-weight:500;letter-spacing:0;text-transform:none;color:var(--faint)}
.worth-hero .v{font-size:38px;font-weight:700;letter-spacing:-.035em;line-height:1.05;margin-top:10px;
  font-variant-numeric:tabular-nums}
.worth-hero .v .cur{font-size:22px;color:var(--dim);margin-right:2px;font-weight:500}
.worth-hero .usd{font-family:var(--mono);font-size:14px;color:var(--dim);margin-top:8px;font-variant-numeric:tabular-nums}
.worth-hero .vs{margin-top:14px;padding-top:13px;border-top:1px solid var(--line);font-size:13px;color:var(--dim);line-height:1.65}
.worth-hero .vs b{color:var(--text);font-family:var(--mono);font-weight:500}
.worth-hero .vs .up{color:var(--ok-text);font-weight:600}
.worth-cells{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;background:transparent;
  border:none;border-radius:0;overflow:visible}
.worth-cells .c{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-xl);padding:14px 16px;min-width:0}
.worth-cells .c .k{font-size:12px;font-weight:500;letter-spacing:0;text-transform:none;
  color:var(--faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.worth-cells .c .v{font-size:20px;font-weight:700;margin-top:8px;line-height:1.15;letter-spacing:-.025em;
  font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.worth-cells .c .v small{font-size:12px;font-weight:450;color:var(--dim);margin-left:3px}
.worth-cells .c .s{font-size:12px;color:var(--faint);margin-top:5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.worth-split{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;margin-top:14px}
.worth-list{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-xl);padding:16px 18px}
.worth-list h4{font-size:14px;font-weight:600;letter-spacing:0;text-transform:none;color:var(--text);margin:0 0 12px}
.wrow{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:5px 10px;align-items:baseline;
  padding:8px 0;border-bottom:1px solid var(--line-soft)}
.wrow:last-child{border-bottom:none;padding-bottom:0}
.wrow .n{font-family:var(--mono);font-size:13px;font-weight:500;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis;min-width:0}
.wrow .n.plain{font-family:var(--sans)}
.wrow .amt{font-family:var(--mono);font-size:13px;font-weight:500;font-variant-numeric:tabular-nums;white-space:nowrap}
.wrow .meter{grid-column:1/-1;height:3px;border-radius:2px;background:var(--surface-3);overflow:hidden}
.wrow .meter i{display:block;height:100%;border-radius:2px;background:var(--brand-a55)}
.wrow .sub{grid-column:1/-1;font-size:12px;color:var(--faint);font-variant-numeric:tabular-nums}
.worth-note{font-size:13px;color:var(--faint);margin:13px 0 0;line-height:1.65}
@media (max-width:820px){
  .worth{grid-template-columns:1fr}
  .worth-split{grid-template-columns:1fr}
}
@media (max-width:430px){
  .worth-cells{grid-template-columns:1fr}
  .worth-hero .v{font-size:32px}
}
/* ---- 订阅 · 订阅说明：一条规矩一句话，双栏摊开 ----
   小方块转 45° 当路牌标——整页唯一一处品牌色小件，其余仍靠发丝线分隔。 */
.rules{margin:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 44px}
/* 分组小标题：两种坐法各一组规矩时才出现。第二组和上一组之间留一段明确的距离，
   让「换话题了」不靠猜。 */
.rules-h{font-size:12px;font-weight:600;color:var(--faint);letter-spacing:.09em;
  text-transform:uppercase;margin:0 0 10px}
.rules+.rules-h{margin-top:26px;padding-top:20px;border-top:1px solid var(--line)}
.rules .rule{padding:13px 0;border-top:1px solid var(--line-soft)}
.rules .rule:nth-child(-n+2){border-top:none;padding-top:2px}
.rules dt{font-size:14px;font-weight:600;color:var(--text);margin:0 0 4px;
  display:flex;align-items:center;gap:9px;letter-spacing:-.01em}
.rules dt::before{content:'';width:6px;height:6px;border-radius:1.5px;background:var(--brand);
  flex:0 0 auto;transform:rotate(45deg)}
.rules dd{margin:0;padding-left:15px;font-size:13px;line-height:1.7;color:var(--dim)}
/* ---- 订阅 · 开始使用三步：一条纵向登车轨 --------------------------------------
   左边是站牌（序号 + 这一步叫什么 + 为什么），右边是能直接复制的终端。终端长得和
   公开站 /carpool 那两块一模一样——深底、标签栏、常亮的复制键——用户从官网过来，
   看到的是同一个东西，而不是换了一身衣服的同一条命令。
   终端在浅色主题里也是深的：它画的是一个终端窗口，不是本页的一张卡片。 */
.board{display:grid;gap:28px}
.bstep{position:relative;display:grid;grid-template-columns:26px minmax(0,264px) minmax(0,1fr);
  column-gap:22px;align-items:start;min-width:0}
.bstep:not(:last-child)::before{content:'';position:absolute;left:13px;top:30px;bottom:-28px;width:1px;
  background:var(--line)}
.bnum{position:relative;z-index:1;display:inline-grid;place-items:center;width:26px;height:26px;border-radius:50%;
  background:var(--brand-dim);border:1px solid var(--brand-a52);
  color:var(--brand-2);font-family:var(--mono);font-size:12px;font-weight:600;font-variant-numeric:tabular-nums}
.bstep .bt{min-width:0;padding-right:6px}
.bstep h4{font-size:15px;font-weight:600;margin:2px 0 7px;letter-spacing:-.01em;line-height:1.45}
.bhint{font-size:13px;color:var(--dim);line-height:1.65;margin:0}
.bhint .mono{overflow-wrap:anywhere;font-size:12px;color:var(--text)}
.board-foot{font-size:13px;color:var(--faint);line-height:1.6;margin:22px 0 0;
  padding-top:14px;border-top:1px solid var(--line-soft)}
/* 终端卡：第 1 步两张（两套系统），第 2、3 步一张——单张卡只占第一格，和上面
   那张 macOS 卡一样宽、一样对齐，右边空着的那格就是留白，不是没填满。 */
.sh-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;align-items:start;min-width:0}
.sh-card{background:#0D1117;border:1px solid #03080a29;border-radius:var(--r-xl);overflow:hidden;
  color:#C9D1D9;min-width:0}
[data-theme=dark] .sh-card{background:#05070B;border-color:#fcfcfe1f}
.sh-bar{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:8px 8px 8px 16px;
  border-bottom:1px solid rgba(255,255,255,.09)}
.sh-bar span{font-family:var(--mono);font-size:11px;color:#8B949E;letter-spacing:.08em;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.sh-cp{flex:0 0 auto;font-family:var(--mono);font-size:11.5px;color:#C9D1D9;background:transparent;
  border:1px solid rgba(255,255,255,.17);border-radius:7px;padding:4px 10px;cursor:pointer;
  transition:color .14s,border-color .14s,background .14s}
.sh-cp:hover{color:#fff;border-color:rgba(255,255,255,.36);background:rgba(255,255,255,.08)}
.sh-cp:focus-visible{outline:2px solid rgba(255,255,255,.55);outline-offset:1px}
.sh-cp.done{color:#3FB950;border-color:#2A6B37}
.sh-card pre{margin:0;padding:15px 16px;background:transparent;border:0;border-radius:0;overflow-x:auto;
  font-family:var(--mono);font-size:12.5px;line-height:1.8;color:#C9D1D9;white-space:pre-wrap;word-break:break-all}
.sh-card .c{color:#6E7681} .sh-card .s{color:#7EE787}
/* ---- 订阅 · 跑起来之后：常用命令与排障并排 ---- */
.after-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;align-items:start}
.after-grid .doc-card{margin-bottom:0}
.cmds .cmd{display:flex;gap:14px;align-items:baseline;padding:10px 0;border-top:1px solid var(--line-soft)}
.cmds .cmd:first-child{border-top:none}
.cmds .cmd code{font-family:var(--mono);font-size:13px;font-weight:500;color:var(--text);
  white-space:nowrap;flex:0 0 118px}
.cmds .cmd span{font-size:13px;color:var(--dim);line-height:1.6;min-width:0}
.faq details{border-top:1px solid var(--line-soft)}
.faq details:first-child{border-top:none}
.faq summary{cursor:pointer;list-style:none;display:flex;align-items:baseline;gap:9px;
  padding:10px 0;font-size:13.5px;font-weight:500;color:var(--text);transition:color .12s}
.faq summary::-webkit-details-marker{display:none}
.faq summary::before{content:'+';font-family:var(--mono);font-size:13px;color:var(--faint);
  flex:0 0 12px;text-align:center}
.faq details[open] summary::before{content:'−';color:var(--brand-2)}
.faq summary:hover{color:var(--brand-2)}
.faq summary:focus-visible{outline:2px solid var(--focus-line);outline-offset:2px;border-radius:var(--r-sm)}
.faq details p{margin:0 0 12px;padding-left:21px;font-size:13px;color:var(--dim);line-height:1.7}
.faq-all{margin:2px 0 0}
.faq-all button{padding:8px 0 2px;background:transparent;font-size:13px;color:var(--dim);
  text-decoration:underline;text-underline-offset:3px;text-decoration-color:var(--faint-a38)}
.faq-all button:hover{color:var(--text);text-decoration-color:currentColor}
.faq-all button:focus-visible{outline:2px solid var(--focus-line);outline-offset:2px;border-radius:var(--r-sm)}
/* 常见问题是一段一段的句子，铺到 1360 就读成一行横幅。阅读宽度收在左对齐的一列里，
   左缘仍和别的页的标题对齐。 */
.faq-page{max-width:720px}
.faq-lead{margin:-2px 0 20px;max-width:62ch;font-size:14px;line-height:1.65;color:var(--dim)}
.faq-search{display:block;max-width:440px;margin:0 0 32px}
.faq-group{margin:0 0 32px}
.faq-group h2{margin:0 0 12px;font-size:13px;font-weight:600;letter-spacing:.01em;color:var(--faint)}
.faq-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-xl);padding:6px 22px 8px}
.faq-card .faq summary{padding:16px 0;font-size:15px;font-weight:600}
.faq-card .faq .faq-body{padding:0 0 18px 21px}
.faq-card .faq .faq-body p{margin:0 0 8px;padding:0;font-size:14px;line-height:1.7;color:var(--dim)}
.faq-card .faq .faq-body p:last-child{margin-bottom:0}
.faq-steps{display:flex;flex-direction:column;gap:18px;margin-top:16px}
.faq-step{display:grid;grid-template-columns:26px minmax(0,1fr);gap:12px;align-items:start}
.faq-card .faq .faq-step h3{margin:1px 0 6px;font-size:14.5px;font-weight:600;letter-spacing:-.01em;line-height:1.45;color:var(--text)}
.faq-step .btn{margin-top:6px}
.faq-card .faq .faq-body .cmds{margin:2px 0 10px}
.faq-card .faq .faq-body .cmds .cmd code{flex:0 0 212px;white-space:normal;overflow-wrap:anywhere}
.faq-card .faq .faq-body .cmds .cmd span{font-size:14px}
.faq-card .faq .faq-body .sh-card{margin:4px 0 10px}
.faq-empty{margin:0;padding:36px 22px;text-align:center;color:var(--faint);font-size:14px;line-height:1.65;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-xl)}
#sail-line{scroll-margin-top:calc(var(--topbar-h, 64px) + 56px)}
@media (max-width:680px){
  .faq-card{padding:4px 16px 6px}
  .faq-step .btn{width:100%}
  .faq-card .faq .faq-body .cmds .cmd{flex-direction:column;gap:4px}
  .faq-card .faq .faq-body .cmds .cmd code{flex-basis:auto}
}
@media (max-width:1000px){
  .sh-grid{grid-template-columns:1fr}
}
@media (max-width:860px){
  .board{gap:24px}
  .bstep{grid-template-columns:26px minmax(0,1fr);row-gap:12px}
  .bstep:not(:last-child)::before{bottom:-24px}
  .bstep .sh-grid{grid-column:2}
  .after-grid{grid-template-columns:1fr}
}
@media (max-width:720px){
  .rules{grid-template-columns:1fr}
  .rules .rule:nth-child(2){border-top:1px solid var(--line-soft);padding-top:13px}
}
/* ---------- 账户 ---------- */
.tile.wide{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px 28px;padding:18px 20px}
.tile.wide .v{font-size:30px}
.tile.wide .sub{margin-top:0;max-width:48ch;text-align:right}
.acct-cols{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:4px 20px;align-items:start}
.acct-cols .doc-card{margin-bottom:0}
#ac-referral .hint{max-width:76ch}
/* 推荐卡 —— 三段，形状刻意各不相同：分享是两个填空框、返佣比例是一把尺子、
   账本是一整块。同一种圆角盒子连排四行，眼睛读不出「这里换话题了」，改版前
   的佣金链就是这么被当成又一排数字瓦片的。

   ⚠️ 内层类名一律带 rbx- 前缀。旧版这里写的是 .rb-node .lv —— 而 .lv 是顶栏
   底下那条 sticky 实时状态条（position:sticky;top:64px;z-index:29;width:100%+48px），
   层级标签当场变成一条横贯整页、盖住所有卡片的白条。这一段里不要再出现
   .lv / .pct / .cnt 这种裸短名。 */
#ac-referral .hint{max-width:76ch}

/* 分享：链接是主角，占大半宽度；推荐码是发不了链接时的备用件，靠在右边。
   按钮紧挨着它复制的那段文字，中间不留一条横跨整卡的空隙。 */
.rbx-share{display:grid;grid-template-columns:minmax(0,2.1fr) minmax(0,1fr);gap:24px 28px}
.rbx-lab{font-size:13px;font-weight:600;color:var(--text);margin:0 0 9px}
.rbx-box{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.rbx-val{flex:1 1 240px;min-width:0;font-family:var(--mono);font-size:13px;line-height:1.55;
  padding:9px 12px;border:1px solid var(--line);border-radius:var(--r-md);
  background:var(--code-bg);color:var(--text);overflow-wrap:anywhere}
.rbx-val.rbx-code{flex:0 1 auto;font-size:15px;letter-spacing:.09em}
.rbx-note{font-size:12.5px;color:var(--faint);line-height:1.65;margin:10px 0 0;max-width:52ch}

/* 段与段之间：一条发丝线 + 26px 的呼吸。整张卡只留两条线（分享之后、统计之前），
   再多就成了栅栏。 */
.rbx-block{margin-top:28px}
.rbx-block.rbx-sep{margin-top:26px;padding-top:26px;border-top:1px solid var(--line)}
.rbx-cap{font-size:13px;font-weight:600;color:var(--text);margin:0 0 18px}

/* 返佣比例 —— 这张卡唯一的高调时刻。品牌标志本身就是「节点 + 连线」，这里把
   同一套几何语言当成解释图用：一条从「你」出发的尺子，离你越远的层级越淡、
   返得越少，「越近返得越多」直接画在距离和墨色里，不再靠箭头和文字各说一遍。
   线在最后一级之后淡出——链到三级为止，那不是省略号。 */
/* 等宽列（「你」也占一列）：三段连线一样长，距离才读得出是「层」而不是随手画的。
   加上限宽——三个比例撑满 1100px 的话，4% 和 1.5% 之间隔着半屏空白，一条尺子
   就散成了三个不相干的数。 */
.rbx-tree{display:grid;gap:0 18px;max-width:640px;
  grid-template-columns:repeat(var(--n,4),minmax(0,1fr))}
.rbx-node{position:relative;min-width:0}
/* 连线画在每个节点自己身上，从本节点的点伸到下一个点为止（右边多出的 20px 正是
   列间距）；最后一级不画。整条线因此严格终止在最后一个点上——用一条横贯容器
   的线加渐变淡出做不到这件事：网格列宽是算出来的，百分比猜不中那个位置。 */
.rbx-node::before{content:'';position:absolute;left:0;right:-20px;top:6px;height:1px;
  background:var(--faint-a28)}
.rbx-node:last-child::before{display:none}
.rbx-dot{display:block;position:relative;z-index:1;width:11px;height:11px;border-radius:50%;
  border:1px solid var(--faint-a45);background:var(--surface)}
.rbx-who{font-size:11.5px;font-weight:600;letter-spacing:.04em;color:var(--faint);margin-top:16px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rbx-rate{font-family:var(--mono);font-size:23px;font-weight:600;letter-spacing:-.02em;line-height:1.1;
  margin-top:8px;font-variant-numeric:tabular-nums;color:var(--text)}
.rbx-people{font-size:12px;color:var(--dim);margin-top:7px}
.rbx-n2 .rbx-rate{color:var(--dim)} .rbx-n3 .rbx-rate{color:var(--faint)}
.rbx-n2 .rbx-dot{border-color:var(--faint-a32)} .rbx-n3 .rbx-dot{border-color:var(--faint-a28)}
.rbx-you{padding-right:6px}
.rbx-you .rbx-dot{border-color:var(--ok);background:var(--ok)}
.rbx-you .rbx-who{color:var(--text)}

/* 账本：一整块，内部用发丝线分栏——三张各自独立的卡片会让「累计 / 已转 / 待结」
   看起来像三件不相干的事，它们其实是同一笔钱的三个去处。 */
.rbx-ledger{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  border:1px solid var(--line);border-radius:var(--r-xl);overflow:hidden;background:var(--surface)}
.rbx-cell{padding:16px 18px;border-left:1px solid var(--line);min-width:0}
.rbx-cell:first-child{border-left:0}
.rbx-k{font-size:12px;font-weight:500;color:var(--faint)}
.rbx-v{font-size:25px;font-weight:700;letter-spacing:-.025em;line-height:1.1;margin-top:9px;
  font-variant-numeric:tabular-nums}
/* 整张卡只有这一处上色。绿在这一页已经是「进账」的意思（下面明细表里的 +¥ 就是
   这个绿），待结算是这里唯一一个还没落袋、但已经属于你的数，值得那一点色。 */
.rbx-due{background:var(--ok-a12)}
.rbx-due .rbx-v{color:var(--ok-text)}
.rbx-bar{height:4px;border-radius:2px;background:var(--faint-a16);margin-top:13px;overflow:hidden}
.rbx-bar i{display:block;height:100%;border-radius:2px;background:var(--ok)}
.rbx-sub{font-size:12.5px;color:var(--dim);margin-top:9px;line-height:1.5}
.rbx-claim{display:flex;flex-wrap:wrap;align-items:center;gap:12px 16px;margin-top:16px}
.rbx-claim .rbx-note{margin:0;flex:1 1 240px}

/* 三个计数降级成一行字。它们是背景信息，不该和钱共用同一种大盒子。 */
.rbx-meta{display:flex;flex-wrap:wrap;gap:10px 30px;margin-top:26px;padding-top:18px;
  border-top:1px solid var(--line);font-size:13px;color:var(--faint)}
.rbx-num{font-family:var(--mono);font-size:15px;font-weight:600;color:var(--text);
  margin:0 5px;font-variant-numeric:tabular-nums}

@media (max-width:760px){
  .rbx-share{grid-template-columns:1fr;gap:22px}
  .rbx-ledger{grid-template-columns:1fr}
  .rbx-cell{border-left:0;border-top:1px solid var(--line)}
  .rbx-cell:first-child{border-top:0}
}
/* 窄屏把尺子立起来：横排三列在手机上每列只剩 90px，比例和人数会各占一行。
   竖着反而更像标志本身——一条主干，节点挂在上面。 */
@media (max-width:640px){
  .rbx-tree{grid-template-columns:1fr;gap:0;padding-left:26px;max-width:none}
  .rbx-node::before{left:-21px;right:auto;top:6px;bottom:-6px;width:1px;height:auto}
  .rbx-node{display:flex;align-items:baseline;gap:12px;padding:12px 0;
    border-bottom:1px solid var(--line-soft)}
  .rbx-node:last-child{border-bottom:0}
  .rbx-dot{position:absolute;left:-26px;top:5px}
  .rbx-who{margin-top:0;flex:1 1 auto}
  .rbx-rate{margin-top:0;font-size:18px}
  /* 人数给一个固定列宽：不给的话每行的「3 人 / 0 人」跟着比例的字宽左右跳，
     三行右缘参差，看起来像没对齐的表格。 */
  .rbx-people{margin-top:0;flex:none;min-width:52px;text-align:right}
  .rbx-you{padding:0 0 12px;border-bottom:1px solid var(--line-soft)}
}
#ac-referral .tiles{max-width:520px}
.set-hint{font-size:12px;color:var(--faint);margin-top:6px;line-height:1.55}
@media (max-width:760px){
  .acct-cols{grid-template-columns:1fr;gap:22px}
  .tile.wide .sub{text-align:left;max-width:none}
  .tile.wide .v{font-size:26px}
  .car-grid,.car-grid.four{grid-template-columns:1fr}
  .ride{gap:13px}
  .ride .term{text-align:left;flex-basis:100%}
  .ride .acts{flex-basis:100%}
  .ride .acts .btn{flex:1}
}

/* ============================================================
   概览 —— 门户的落地页（2026-08-26）
   ------------------------------------------------------------
   此前推开门看到的是「模型」：一个搜索框、一列筛选、一张表。它回答的是
   「有哪些模型」，而人进门时问的是另外三件事——我还有多少能花的、这段时间
   烧掉了多少、下一步该点哪里。三个桶（钱包 ¥ / API 额度 $ / 订阅座位）
   此前各自散在三页上，谁也没在一屏里见过它们的关系。

   这一页把那层关系摆成读得出的顺序：第一张卡是「能花的」，第二张是「烧掉的」，
   第三张是「另一种坐法」。从左读到右就是钱的走向——人民币进来，换成美元额度
   或一辆包月的车，然后按厂商官方价烧掉。

   一条新接口都没加。/portal/api/seat 本来就带着三个桶的全部状态，
   /portal/api/usage/value 本来就带着按天的交付量与扣减额。概览是既有事实的
   重新编排，不是新的查询——所以它也不会给数据库多一份负担。
   ============================================================ */

/* 招呼行。右边的动作从左到右责任递增：翻文档 → 建一把 Key → 现在就开始。
   最后那颗按这个人的状态换文案：还没坐上任何一种坐法的人该去开通，坐上了
   但还没授权设备的人该去装 sail，两样都齐了的人该去看用量。一颗写死的按钮
   对三种人里的两种都是错的。 */
.hgreet{display:flex;align-items:center;justify-content:space-between;gap:14px 20px;flex-wrap:wrap;margin-bottom:24px}
.hgreet h1{font-size:30px;font-weight:700;letter-spacing:-.03em;margin:0;line-height:1.25;min-width:0}
.hg-acts{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.icon-btn{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;flex:none;
  border:1px solid var(--line);border-radius:var(--r-lg);color:var(--dim);background:transparent;
  transition:background .12s ease,color .12s ease}
.icon-btn:hover{background:var(--ctl-on-bg);color:var(--text)}
.icon-btn:focus-visible{outline:2px solid var(--focus-line);outline-offset:2px}
.icon-btn svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}

/* 三张状态卡。数值和它唯一的动作在同一行——把按钮放到卡底会让「$482.30」和
   「充值」中间隔着一句说明，读到数字的人得先跳过一行才找得到能按的东西。 */
.hcards{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-bottom:14px}
.hcard{display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-xl);padding:20px 22px 19px;min-height:158px}
.hc-head{display:flex;align-items:center;gap:7px;margin-bottom:18px}
.hc-k{font-size:14px;font-weight:600;letter-spacing:-.005em}
.hc-i{display:inline-flex;align-items:center;justify-content:center;width:17px;height:17px;flex:none;
  color:var(--faint);border-radius:50%;background:transparent;cursor:help}
.hc-i:hover{color:var(--dim)}
.hc-i svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}
.hc-badge{margin-left:auto;font-size:11.5px;font-weight:500;color:var(--dim);
  background:var(--surface-3);border-radius:999px;padding:3px 9px;white-space:nowrap}
.hc-badge.warn{color:var(--warn-text);background:var(--warn-dim)}
.hc-badge.ok{color:var(--ok-text);background:var(--ok-a12)}
.hc-mid{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-top:auto}
.hc-main{min-width:0}
.hc-v{font-size:32px;font-weight:700;letter-spacing:-.032em;line-height:1.06;
  font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
.hc-v.sm{font-size:22px;letter-spacing:-.02em;line-height:1.25}
.hc-v.none{color:var(--faint);font-weight:600}
.hc-side{flex:none;display:flex;align-items:center}
.hc-foot{margin-top:11px;font-size:13px;color:var(--dim);line-height:1.6}
.hc-foot b{font-weight:600;color:var(--text);font-variant-numeric:tabular-nums}
.hc-foot .sep{color:var(--faint);margin:0 6px}

/* Token 走势。参考页在这里摆的是一条空线加一句「近 7 天没有活动」——空状态
   本身也是一句话，所以这里照着做：没有调用时不画一排 0 高的柱子，直接说
   还没有调用，并把「怎么开始」放在同一行。 */
.hvol{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-xl);
  padding:20px 22px 18px;margin-bottom:38px}
.hv-head{display:flex;align-items:center;gap:7px;margin-bottom:16px}
.hv-body{display:flex;align-items:flex-end;gap:28px;flex-wrap:wrap}
.hv-main{flex:0 0 auto;min-width:150px}
.hv-v{font-size:30px;font-weight:700;letter-spacing:-.03em;line-height:1.06;font-variant-numeric:tabular-nums}
.hv-v.none{font-size:22px;color:var(--faint);font-weight:600}
.hv-sub{margin-top:9px;font-size:13px;color:var(--dim);line-height:1.6}
.hv-sub b{font-weight:600;color:var(--text);font-variant-numeric:tabular-nums}
.hv-side{margin-left:auto;flex:none;align-self:center}
.spark{display:flex;align-items:flex-end;gap:5px;height:62px;flex:1 1 260px;min-width:200px;max-width:520px}
.spark i{flex:1 1 0;min-width:4px;border-radius:3px 3px 1px 1px;background:var(--brand-a40);
  transform-origin:50% 100%;animation:sprout .55s cubic-bezier(.22,.61,.25,1) both}
.spark i.on{background:var(--brand)}
.spark i.zero{background:var(--faint-a28);height:3px!important;border-radius:2px}
@keyframes sprout{from{transform:scaleY(.04)}to{transform:scaleY(1)}}

/* 分节标题。这一页只有两处，所以不需要眉标——标题自己就够重了。 */
.hsec{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin:0 0 15px}
.hsec h2{font-size:17px;font-weight:600;letter-spacing:-.018em;margin:0}
.hsec .more{font-size:13.5px;color:var(--dim);text-decoration:underline;text-underline-offset:3px;
  text-decoration-color:var(--faint-a38);background:transparent}
.hsec .more:hover{color:var(--text);text-decoration-color:currentColor}

/* 模型墙。色块不是装饰：同一个厂商在墙上永远是同一块颜色，扫一眼就知道
   这一排是谁家的。线稿按厂商画，一套笔画（1.6px 圆头），不是从字体里借的字符。 */
.mwall{display:grid;grid-template-columns:repeat(auto-fill,minmax(208px,1fr));gap:14px}
/* 概览上的墙固定四列。auto-fill 会按容器宽度算出五列，而这里只摆四张，
   于是最后一格永远空着；固定列数让这一排每次都是齐的。 */
.mwall.home{grid-template-columns:repeat(4,1fr)}
.mwcard{display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-xl);overflow:hidden;text-align:left;padding:0;font-size:14px;
  transition:border-color .14s ease,transform .14s ease}
.mwcard:hover{border-color:var(--faint-a30);transform:translateY(-2px)}
.mwcard:focus-visible{outline:2px solid var(--focus-line);outline-offset:2px}
/* 色块按比例长高，不按像素钉死：概览上四列的卡有 340 宽，目录里筛过之后可能
   只有 210——同一个高度在两处一个太扁一个太高。上下限是为了别在极端宽度上
   把卡片撑成一张海报或压成一条边。 */
.mwart{aspect-ratio:16/7;min-height:92px;max-height:150px;
  display:flex;align-items:center;justify-content:center;
  background:var(--art);color:var(--art-ink)}
.mwart svg{width:54px;height:54px;fill:none;stroke:currentColor;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round}
/* 六块底色。浅色面用的是低饱和的粉彩，线稿压墨色；深色面把同一个色相压暗、
   线稿翻白——不是把浅色那一组直接调透明度，那样六块会一起塌成同一个灰。 */
.mwart{--art:var(--surface-3);--art-ink:var(--text)}
.mwart.a1{--art:#a9c5ea;--art-ink:#0a1526}
.mwart.a2{--art:#f0a184;--art-ink:#2b1109}
.mwart.a3{--art:#e8e0d1;--art-ink:#22201a}
.mwart.a4{--art:#a8c9bb;--art-ink:#0d211a}
.mwart.a5{--art:#c6b6e6;--art-ink:#1b1230}
.mwart.a6{--art:#e6c98d;--art-ink:#2a2009}
[data-theme=dark] .mwart.a1{--art:#16273d;--art-ink:#bcd4f2}
[data-theme=dark] .mwart.a2{--art:#3a1d13;--art-ink:#f4bda6}
[data-theme=dark] .mwart.a3{--art:#2a2721;--art-ink:#e3dbcb}
[data-theme=dark] .mwart.a4{--art:#122b23;--art-ink:#a9d3c3}
[data-theme=dark] .mwart.a5{--art:#231a3a;--art-ink:#cfc0ee}
[data-theme=dark] .mwart.a6{--art:#332811;--art-ink:#eed3a0}
.mwbody{padding:13px 15px 15px;display:flex;flex-direction:column;gap:10px;flex:1;min-width:0}
.mwname{display:flex;align-items:center;gap:7px;font-size:14.5px;font-weight:600;
  letter-spacing:-.012em;line-height:1.35;min-width:0}
.mwname .nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mwtags{display:flex;flex-wrap:wrap;gap:5px;margin-top:auto;min-width:0}
.mwtags span{font-size:11.5px;font-weight:500;color:var(--dim);background:var(--surface-2);
  border:1px solid var(--line-soft);border-radius:var(--r-sm);padding:3px 7px;line-height:1.4;white-space:nowrap}
.mwtags span.hi{color:var(--text);background:var(--brand-dim);border-color:transparent}

/* 资源架。五张卡，各自指向一件这一页答不了的事。 */
.rshelf{display:grid;grid-template-columns:repeat(auto-fit,minmax(216px,1fr));gap:12px}
.rcard{display:flex;align-items:flex-start;gap:12px;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-xl);padding:16px 18px;text-align:left;transition:border-color .14s ease}
.rcard>span{min-width:0}
.rcard:hover{border-color:var(--faint-a30)}
.rcard:focus-visible{outline:2px solid var(--focus-line);outline-offset:2px}
.rcard>svg{width:18px;height:18px;flex:none;margin-top:2px;color:var(--faint);
  fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.rcard:hover>svg{color:var(--dim)}
.rcard .rt{display:block;font-size:14px;font-weight:600;letter-spacing:-.008em}
.rcard .rs{display:block;font-size:12.5px;color:var(--faint);margin-top:5px;line-height:1.55}

@media (max-width:1040px){
  .hcards{grid-template-columns:repeat(2,1fr)}
  .hcards>.hcard:last-child{grid-column:1/-1}
  .mwall.home{grid-template-columns:repeat(3,1fr)}
}
@media (max-width:820px){
  .mwall.home{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:680px){
  .hgreet{gap:8px;margin-bottom:12px}
  .hgreet h1{font-size:20px;flex:1 1 100%}
  .hg-acts{flex:1 1 100%}
  .hg-acts .btn{flex:1 1 auto}
  .icon-btn{display:none}
  .hcards{grid-template-columns:1fr;gap:8px}
  .hcards>.hcard:last-child{grid-column:auto}
  .hcard{min-height:0;padding:12px 14px 12px}
  .hc-head{margin-bottom:8px}
  .hc-v{font-size:22px}
  .hc-foot{margin-top:6px;font-size:12px;display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden}
  .hvol{padding:17px 18px 16px;margin-bottom:30px}
  .hv-body{gap:18px}
  .hv-main{flex:1 1 100%}
  .hv-side{margin-left:0;flex:1 1 100%;align-self:auto}
  .hv-side .btn{width:100%}
  .spark{flex:1 1 100%;height:48px;gap:4px}
  .mwall{grid-template-columns:repeat(auto-fill,minmax(148px,1fr));gap:10px}
  .mwall.home{grid-template-columns:repeat(2,1fr)}
  .mwart{min-height:78px}
  .mwart svg{width:40px;height:40px}
  .mwbody{padding:11px 12px 13px;gap:8px}
  .mwname{font-size:13.5px}
  .rshelf{grid-template-columns:1fr}
}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* ============================================================
   系统的「降低透明度」「增强对比度」（HIG · Accessibility）
   ------------------------------------------------------------
   玻璃在「降低透明度」下退回实心：开这个设置的人是在说，模糊的背景让他读不清。
   「增强对比度」把分隔线和次级文字各加深一档。「减弱动态效果」在上面已经整页关掉动画。
   ============================================================ */
@media (prefers-reduced-transparency:reduce){
  :root,[data-theme=dark]{--rail-bg:var(--bg);--glass:var(--surface);--glass-thick:var(--surface);--toast-bg:var(--surface)}
  .topbar,.lv,.cfm,.toast,pre .cp{-webkit-backdrop-filter:none!important;backdrop-filter:none!important}
}
@media (prefers-contrast:more){
  :root{--line:#aeaeb2;--line-soft:#c7c7cc;--dim:#3a3a3c;--faint:#545458;--input-line:#8e8e93;--rail-line:rgba(0,0,0,.28);--rail-dim:#1d1d1f}
  [data-theme=dark]{--line:#636366;--line-soft:#48484a;--dim:#d1d1d6;--faint:#aeaeb2;--input-line:#8e8e93;--rail-line:rgba(255,255,255,.3);--rail-dim:#f5f5f7}
}
