/* 接入层管理台与用户门户 · 样式
   依据《管理后台页面设计规范》：中性灰阶 + 一个主色（延续旧版的青绿）；层次靠细边框与明暗，
   阴影只给浮层；颜色、圆角、间距、动效时长全部变量化；深浅色跟随系统，不做切换按钮。 */
:root{
  color-scheme:light dark;
  --bg:#fafafa; --surface:#ffffff; --sunken:#f4f4f5; --raised:#ffffff;
  --text:#18181b; --text2:#52525b; --muted:#71717a; --faint:#a1a1aa;
  --border:#e4e4e7; --border2:#d4d4d8;
  --accent:#0b7f74; --accent-hover:#096b62; --accent-ink:#ffffff; --accent-soft:#e3f3f0; --accent-text:#0a6a61;
  --ok:#15803d; --ok-soft:#e7f5ec; --warn:#a16207; --warn-soft:#fbf3dc; --err:#b91c1c; --err-soft:#fdecec;
  --info:#1d4ed8; --info-soft:#e8effd; --neutral-soft:#f0f0f1;
  --r-s:6px; --r-m:8px; --r-l:12px;
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px; --s6:32px;
  --shadow-pop:0 8px 28px rgba(24,24,27,.14),0 1px 3px rgba(24,24,27,.08);
  --t-fast:110ms; --t:180ms; --t-slow:260ms; --ease:cubic-bezier(.2,.7,.2,1);
  --side-w:224px; --rail-w:56px; --top-h:52px;
  --sans:system-ui,-apple-system,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei","Noto Sans CJK SC",sans-serif;
  --mono:ui-monospace,"SF Mono","Cascadia Mono",Menlo,Consolas,"Liberation Mono",monospace;
}
@media (prefers-color-scheme:dark){
  :root{
    --bg:#0b0b0d; --surface:#131316; --sunken:#0f0f12; --raised:#1b1b1f;
    --text:#ededef; --text2:#b4b4bb; --muted:#8e8e98; --faint:#63636c;
    --border:#26262b; --border2:#34343b;
    --accent:#2bbfa9; --accent-hover:#3bd0ba; --accent-ink:#04221e; --accent-soft:#11302c; --accent-text:#4fd6c2;
    --ok:#4ade80; --ok-soft:#12291b; --warn:#eab54a; --warn-soft:#2c2410; --err:#f87171; --err-soft:#321616;
    --info:#7aa7ff; --info-soft:#151f38; --neutral-soft:#1f1f24;
    --shadow-pop:0 0 0 1px var(--border2),0 12px 32px rgba(0,0,0,.5);
  }
}

/* ---------- reset ---------- */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}
body{margin:0;background:var(--bg);color:var(--text);font:14px/1.6 var(--sans);font-variant-numeric:tabular-nums}
h1,h2,h3,p{margin:0}
a{color:var(--accent-text);text-decoration:none}
button,input,select,textarea{font:inherit;color:inherit;margin:0}
button{background:none;border:0;padding:0;cursor:pointer}
:focus{outline:none}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--r-s)}
::selection{background:var(--accent-soft)}
*{scrollbar-width:thin;scrollbar-color:var(--border2) transparent}
::-webkit-scrollbar{width:8px;height:8px}
::-webkit-scrollbar-thumb{background:var(--border2);border-radius:8px}
input:-webkit-autofill,input:-webkit-autofill:focus{-webkit-text-fill-color:var(--text);box-shadow:0 0 0 1000px var(--surface) inset;caret-color:var(--text)}
input[type=number]{-moz-appearance:textfield;appearance:textfield}
input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}
input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}
.mono{font-family:var(--mono);font-size:.93em}
.muted{color:var(--muted)} .small{font-size:12px} .nowrap{white-space:nowrap} .hidden{display:none!important}
.num{text-align:right;white-space:nowrap}
.clip{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.clip2{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.pre{white-space:pre-wrap;overflow-wrap:anywhere}

/* ---------- 外壳：侧栏 + 顶栏 + 内容区 ---------- */
.app{display:grid;grid-template-columns:var(--side-w) minmax(0,1fr);height:100dvh;transition:grid-template-columns var(--t) var(--ease)}
.app.rail{grid-template-columns:var(--rail-w) minmax(0,1fr)}
.side{display:flex;flex-direction:column;min-height:0;background:var(--surface);border-right:1px solid var(--border);overflow:hidden}
.side-brand{display:flex;align-items:center;gap:10px;height:var(--top-h);padding:0 16px;flex:none;min-width:0}
.side-brand .mark{width:22px;height:22px;border-radius:6px;background:var(--accent);flex:none;display:grid;place-items:center;color:var(--accent-ink);font-weight:700;font-size:12px}
.side-brand b{font-size:14px;font-weight:600}
.side-brand .role{font-size:11px;color:var(--muted);border:1px solid var(--border);border-radius:99px;padding:0 7px;flex:none}
.side-nav{flex:1;overflow-y:auto;padding:8px;display:flex;flex-direction:column;gap:2px}
.side-nav a{display:flex;align-items:center;gap:10px;height:34px;padding:0 10px;border-radius:var(--r-m);color:var(--text2);white-space:nowrap;transition:background var(--t-fast),color var(--t-fast)}
.side-nav a svg{flex:none;color:var(--muted)}
.side-nav a.on{background:var(--accent-soft);color:var(--accent-text);font-weight:600}
.side-nav a.on svg{color:var(--accent-text)}
.side-nav a:active{transform:scale(.985)}
.side-foot{padding:8px;border-top:1px solid var(--border);display:flex;flex-direction:column;gap:2px;flex:none}
.side-foot button,.side-foot a{display:flex;align-items:center;gap:10px;height:34px;padding:0 10px;border-radius:var(--r-m);color:var(--text2);white-space:nowrap;width:100%}
.side-foot svg{flex:none;color:var(--muted)}
.app.rail .side-brand b,.app.rail .side-brand .role,.app.rail .side-nav a span,.app.rail .side-foot span{display:none}
.app.rail .side-brand{padding:0;justify-content:center}
.app.rail .side-nav a,.app.rail .side-foot button,.app.rail .side-foot a{justify-content:center;padding:0}
.main{display:flex;flex-direction:column;min-width:0;min-height:0}
.top{display:flex;align-items:center;gap:var(--s3);height:var(--top-h);padding:0 var(--s5) 0 var(--s3);border-bottom:1px solid var(--border);background:var(--surface);flex:none}
.top h1{font-size:15px;font-weight:600;flex:1;min-width:0}
.top .top-r{display:flex;align-items:center;gap:var(--s2);flex:none}
.content{flex:1;overflow-y:auto;padding:var(--s5);padding-bottom:calc(var(--s6) + env(safe-area-inset-bottom))}
.view{display:flex;flex-direction:column;gap:var(--s4);animation:fade var(--t) var(--ease)}
.view.stale{opacity:.55;transition:opacity var(--t)}
.narrow{max-width:760px}
.scrim{display:none}
@keyframes fade{from{opacity:0}to{opacity:1}}
@media (hover:hover){
  .side-nav a:hover,.side-foot button:hover,.side-foot a:hover{background:var(--sunken);color:var(--text)}
}
@media (max-width:1100px) and (min-width:761px){
  .app{grid-template-columns:var(--rail-w) minmax(0,1fr)}
  .app .side-brand b,.app .side-brand .role,.app .side-nav a span,.app .side-foot span{display:none}
  .app .side-brand{padding:0;justify-content:center}
  .app .side-nav a,.app .side-foot button,.app .side-foot a{justify-content:center;padding:0}
  .top .collapse{display:none}
}
@media (max-width:760px){
  .app,.app.rail{grid-template-columns:minmax(0,1fr)}
  .side{position:fixed;inset:0 auto 0 0;width:min(280px,82vw);z-index:60;transform:translateX(-102%);transition:transform var(--t-slow) var(--ease);padding-top:env(safe-area-inset-top)}
  .app.drawer .side{transform:none}
  .app.rail .side-brand b,.app.rail .side-brand .role,.app.rail .side-nav a span,.app.rail .side-foot span{display:initial}
  .app.rail .side-nav a,.app.rail .side-foot button,.app.rail .side-foot a{justify-content:flex-start;padding:0 10px}
  .app.rail .side-brand{padding:0 16px;justify-content:flex-start}
  .side-nav a,.side-foot button,.side-foot a{height:42px}
  .scrim{display:block;position:fixed;inset:0;background:rgba(0,0,0,.4);z-index:55;opacity:0;pointer-events:none;transition:opacity var(--t)}
  .app.drawer .scrim{opacity:1;pointer-events:auto}
  .top{height:46px;padding:0 var(--s3);padding-top:env(safe-area-inset-top);box-sizing:content-box}
  .top .collapse{display:none}
  .content{padding:var(--s3);padding-bottom:calc(var(--s6) + env(safe-area-inset-bottom))}
  .desk{display:none!important}
}
@media (min-width:761px){.menu-btn,.mob{display:none!important}}

/* ---------- 工具条 / 栅格 / 卡片 ---------- */
.bar{display:flex;align-items:center;gap:var(--s2);flex-wrap:wrap}
.bar .grow{flex:1;min-width:0}
.bar.sticky{position:sticky;top:calc(-1 * var(--s5));z-index:5;background:var(--bg);padding:var(--s2) 0;margin:calc(-1 * var(--s2)) 0}
.row{display:flex;align-items:center;gap:var(--s2);flex-wrap:wrap;min-width:0}
.spread{justify-content:space-between}
.stack{display:flex;flex-direction:column;gap:var(--s4);min-width:0}
.stack.tight{gap:var(--s2)}
.grid{display:grid;gap:var(--s4)}
.grid.c2{grid-template-columns:repeat(auto-fit,minmax(min(100%,420px),1fr))}
.grid.c3{grid-template-columns:repeat(auto-fit,minmax(min(100%,220px),1fr))}
.grid.c4{grid-template-columns:repeat(auto-fit,minmax(min(100%,180px),1fr))}
.grid.auto{grid-template-columns:repeat(auto-fill,minmax(min(100%,320px),1fr))}
.grid.f2{grid-template-columns:repeat(auto-fit,minmax(min(100%,240px),1fr));gap:var(--s3) var(--s4)}
.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-l);padding:var(--s4);min-width:0}
.card.flush{padding:0;overflow:hidden}
.card h3{font-size:13px;font-weight:600;margin-bottom:var(--s3);display:flex;align-items:center;gap:var(--s2);flex-wrap:wrap}
.card h3 .sub{font-weight:400;color:var(--muted);font-size:12px}
.card.flush>h3{padding:var(--s3) var(--s4);margin:0;border-bottom:1px solid var(--border)}
.sec-h{font-size:13px;font-weight:600;color:var(--text2);display:flex;align-items:center;gap:var(--s2);margin-top:var(--s2)}
.sec-h .sub{font-weight:400;color:var(--muted);font-size:12px}
.stat{display:flex;flex-direction:column;gap:2px;min-width:0}
.stat .v{font-size:24px;font-weight:600;letter-spacing:-.01em;line-height:1.25}
.stat .v .cur{font-size:14px;color:var(--muted);font-weight:400;margin-right:2px}
.stat .k{font-size:12px;color:var(--muted)}
.chip{display:inline-flex;align-items:center;gap:6px;padding:2px 9px;border-radius:99px;background:var(--sunken);border:1px solid var(--border);font-size:12px;color:var(--text2);white-space:nowrap}
.chip b{color:var(--text);font-weight:600}
.banner{display:flex;gap:var(--s3);align-items:flex-start;padding:var(--s3) var(--s4);border-radius:var(--r-l);border:1px solid var(--border);background:var(--surface);font-size:13px}
.banner.warn{background:var(--warn-soft);border-color:transparent;color:var(--text)}
.banner.info{background:var(--info-soft);border-color:transparent}
.banner.err{background:var(--err-soft);border-color:transparent}
.banner svg{flex:none;margin-top:2px}
.banner .grow{flex:1;min-width:0}

/* ---------- 按钮 ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:32px;padding:0 12px;border-radius:var(--r-m);border:1px solid var(--border2);background:var(--surface);color:var(--text);font-size:13px;font-weight:500;white-space:nowrap;position:relative;transition:background var(--t-fast),border-color var(--t-fast),transform var(--t-fast),color var(--t-fast);user-select:none}
.btn:active:not(:disabled){transform:scale(.97);background:var(--sunken)}
.btn:disabled{opacity:.5;cursor:not-allowed}
.btn.primary{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);font-weight:600}
.btn.primary:active:not(:disabled){background:var(--accent-hover)}
.btn.danger{color:var(--err);border-color:color-mix(in srgb,var(--err) 40%,var(--border))}
.btn.danger.solid{background:var(--err);border-color:var(--err);color:#fff}
.btn.ghost{border-color:transparent;background:transparent;color:var(--text2)}
.btn.sm{height:26px;padding:0 9px;font-size:12px;border-radius:var(--r-s)}
.btn.icon{width:32px;padding:0}
.btn.icon.sm{width:26px}
.btn.busy{color:transparent!important;pointer-events:none}
.btn.busy::after{content:"";position:absolute;width:14px;height:14px;border-radius:50%;border:2px solid var(--muted);border-top-color:transparent;animation:spin .7s linear infinite}
.btn.primary.busy::after,.btn.danger.solid.busy::after{border-color:var(--accent-ink);border-top-color:transparent}
.btn.done{color:var(--ok)}
@keyframes spin{to{transform:rotate(360deg)}}
@media (hover:hover){
  .btn:hover:not(:disabled){background:var(--sunken);border-color:var(--border2)}
  .btn.primary:hover:not(:disabled){background:var(--accent-hover);border-color:var(--accent-hover)}
  .btn.danger:hover:not(:disabled){background:var(--err-soft)}
  .btn.danger.solid:hover:not(:disabled){background:var(--err);filter:brightness(.93)}
  .btn.ghost:hover:not(:disabled){background:var(--sunken);color:var(--text)}
}
.seg{display:inline-flex;padding:2px;border-radius:var(--r-m);background:var(--sunken);border:1px solid var(--border)}
.seg button{height:26px;padding:0 12px;border-radius:var(--r-s);font-size:12.5px;color:var(--muted);transition:background var(--t-fast),color var(--t-fast)}
.seg button.on{background:var(--surface);color:var(--text);font-weight:600;box-shadow:0 0 0 1px var(--border)}

/* ---------- 表单 ---------- */
.field{display:flex;flex-direction:column;gap:5px;min-width:0}
.field>label,.label{font-size:12.5px;font-weight:500;color:var(--text2)}
.hint{font-size:12px;color:var(--muted);line-height:1.55}
.field .err-text{font-size:12px;color:var(--err)}
.input,textarea.input{width:100%;min-height:32px;padding:5px 10px;border-radius:var(--r-m);border:1px solid var(--border2);background:var(--surface);transition:border-color var(--t-fast),box-shadow var(--t-fast)}
.input::placeholder{color:var(--faint)}
.input:focus,.sel:focus-visible{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft);outline:none}
.input.bad{border-color:var(--err)}
textarea.input{resize:vertical;line-height:1.55;min-height:60px}
.input[type=date]{min-width:136px;width:auto}
.sel{display:inline-flex;align-items:center;justify-content:space-between;gap:8px;height:32px;padding:0 8px 0 10px;border-radius:var(--r-m);border:1px solid var(--border2);background:var(--surface);min-width:120px;max-width:100%;text-align:left;transition:border-color var(--t-fast),box-shadow var(--t-fast)}
.sel>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.sel>svg{flex:none;color:var(--muted);transition:transform var(--t)}
.sel[aria-expanded=true]>svg{transform:rotate(180deg)}
.sel.block{display:flex;width:100%}
.sel .ph{color:var(--faint)}
.check{display:inline-flex;align-items:center;gap:8px;cursor:pointer;user-select:none;min-height:24px}
.check input{position:absolute;opacity:0;width:0;height:0}
.check .box{width:16px;height:16px;border-radius:4px;border:1.5px solid var(--border2);background:var(--surface);flex:none;display:grid;place-items:center;transition:background var(--t-fast),border-color var(--t-fast),transform var(--t-fast)}
.check .box::after{content:"";width:8px;height:4px;border-left:2px solid var(--accent-ink);border-bottom:2px solid var(--accent-ink);transform:rotate(-45deg) translate(1px,-1px) scale(0);transition:transform var(--t-fast)}
.check input:checked+.box{background:var(--accent);border-color:var(--accent)}
.check input:checked+.box::after{transform:rotate(-45deg) translate(1px,-1px) scale(1)}
.check input:focus-visible+.box{outline:2px solid var(--accent);outline-offset:2px}
.check:active .box{transform:scale(.9)}
.switch{display:inline-flex;align-items:center;gap:8px;cursor:pointer;user-select:none;font-size:12.5px;color:var(--text2)}
.switch input{position:absolute;opacity:0;width:0;height:0}
.switch .track{width:30px;height:18px;border-radius:99px;background:var(--border2);position:relative;flex:none;transition:background var(--t)}
.switch .track::after{content:"";position:absolute;top:2px;left:2px;width:14px;height:14px;border-radius:50%;background:#fff;transition:transform var(--t) var(--ease);box-shadow:0 1px 2px rgba(0,0,0,.25)}
.switch input:checked+.track{background:var(--accent)}
.switch input:checked+.track::after{transform:translateX(12px)}
.switch input:focus-visible+.track{outline:2px solid var(--accent);outline-offset:2px}
@media (max-width:760px){
  .input,textarea.input,.sel{font-size:16px;min-height:40px}
  .sel{height:40px}
  .btn{height:38px;padding:0 14px}
  .btn.sm{height:32px}
  .btn.icon{width:38px} .btn.icon.sm{width:32px}
}

/* ---------- 徽标：浅底 + 彩色文字 + 圆点，不只靠颜色 ---------- */
.badge{display:inline-flex;align-items:center;gap:5px;height:20px;padding:0 8px;border-radius:99px;font-size:12px;font-weight:500;white-space:nowrap;background:var(--neutral-soft);color:var(--text2)}
.badge::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor;opacity:.85}
.badge.plain::before{display:none}
.badge.ok{background:var(--ok-soft);color:var(--ok)}
.badge.warn{background:var(--warn-soft);color:var(--warn)}
.badge.err{background:var(--err-soft);color:var(--err)}
.badge.info{background:var(--info-soft);color:var(--info)}
.badge.acc{background:var(--accent-soft);color:var(--accent-text)}

/* ---------- 表格；容器变窄时自动变成卡片列表 ---------- */
.tbl-wrap{container-type:inline-size;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-l);overflow:hidden}
.card.flush .tbl-wrap{border:0;border-radius:0}
.tbl-scroll{overflow-x:auto}
table.tbl{width:100%;border-collapse:collapse;font-size:13px}
.tbl th{text-align:left;font-weight:500;font-size:12px;color:var(--muted);padding:8px 12px;border-bottom:1px solid var(--border);white-space:nowrap;background:var(--sunken)}
.tbl td{padding:9px 12px;border-bottom:1px solid var(--border);vertical-align:middle;max-width:360px}
.tbl tr:last-child>td{border-bottom:0}
.tbl th.num,.tbl td.num{text-align:right}
.tbl tr.click{cursor:pointer}
.tbl tr.grp>td{background:var(--sunken);font-weight:600;font-size:12.5px;padding:6px 12px}
.tbl tr.flash>td{animation:flash 1.2s var(--ease)}
.tbl td.c-act{text-align:right;white-space:nowrap;width:1%}
.tbl tr.detail>td{background:var(--sunken);padding:12px 16px;max-width:none}
.tbl .t2{font-size:12px;color:var(--muted)}
@keyframes flash{from{background:var(--accent-soft)}to{background:transparent}}
@media (hover:hover){.tbl tr.click:hover>td{background:var(--sunken)}}
.acts{display:inline-flex;align-items:center;gap:4px;justify-content:flex-end}
@container (max-width:680px){
  .tbl thead{display:none}
  .tbl,.tbl tbody{display:block}
  .tbl tr{display:flex;flex-wrap:wrap;align-items:center;gap:3px 12px;padding:12px 14px;border-bottom:1px solid var(--border);position:relative}
  .tbl tr:last-child{border-bottom:0}
  .tbl td{padding:0;border:0;max-width:100%;min-width:0;font-size:12.5px;color:var(--text2)}
  .tbl td[data-l]::before{content:attr(data-l) " ";color:var(--muted)}
  .tbl td.c-title{flex:1 1 100%;padding-right:44px;font-size:14px;color:var(--text)}
  .tbl td.c-x{display:none}
  .tbl td.c-act{position:absolute;top:8px;right:8px;width:auto}
  .tbl td.c-act .act-inline{display:none}
  .tbl td.c-act .act-more{display:inline-flex!important}
  .tbl tr.grp{padding:6px 14px;background:var(--sunken)}
  .tbl tr.grp>td{padding:0;background:none}
  .tbl tr.detail{background:var(--sunken)}
  .tbl tr.detail>td{flex:1 1 100%;padding:0;background:none}
  .tbl tr.empty-row{display:block}
}
.pager{display:flex;align-items:center;justify-content:flex-end;gap:var(--s2);font-size:12.5px;color:var(--muted)}
.empty{display:flex;flex-direction:column;align-items:center;gap:var(--s2);padding:40px 16px;color:var(--muted);text-align:center}
.empty b{color:var(--text);font-weight:600;font-size:14px}
.kv{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:4px 16px;font-size:12.5px}
.kv .k{color:var(--muted)} .kv .v{overflow-wrap:anywhere}
pre.code{margin:0;padding:12px 14px;border-radius:var(--r-m);background:var(--sunken);border:1px solid var(--border);font:12.5px/1.6 var(--mono);overflow:auto;max-height:420px;white-space:pre-wrap;overflow-wrap:anywhere}
.code-wrap{position:relative}
.code-wrap .copy{position:absolute;top:6px;right:6px}
.idc{display:inline-flex;align-items:center;gap:2px;max-width:100%}

/* ---------- 骨架屏 ---------- */
.skel{border-radius:var(--r-s);background:linear-gradient(90deg,var(--sunken) 25%,var(--border) 50%,var(--sunken) 75%);background-size:200% 100%;animation:shimmer 1.3s linear infinite;height:14px}
.skel.row-h{height:38px;border-radius:var(--r-m)}
.skel.card-h{height:120px;border-radius:var(--r-l)}
@keyframes shimmer{to{background-position:-200% 0}}

/* ---------- 浮层：弹窗 / 下拉 / 菜单 / 提示 ---------- */
.mask{position:fixed;inset:0;z-index:80;background:rgba(0,0,0,.42);display:grid;place-items:center;padding:var(--s4);animation:fade var(--t)}
.mask.out{opacity:0;transition:opacity var(--t-fast)}
.modal{width:min(520px,100%);max-height:min(88dvh,900px);display:flex;flex-direction:column;background:var(--raised);border-radius:var(--r-l);box-shadow:var(--shadow-pop);animation:pop var(--t) var(--ease)}
.modal.wide{width:min(860px,100%)}
.modal-h{display:flex;align-items:center;gap:var(--s3);padding:var(--s3) var(--s3) var(--s3) var(--s4);border-bottom:1px solid var(--border);flex:none}
.modal-h b{flex:1;font-size:14px;font-weight:600;min-width:0}
.modal-b{padding:var(--s4);overflow-y:auto;flex:1;display:flex;flex-direction:column;gap:var(--s4)}
.modal-f{display:flex;justify-content:flex-end;gap:var(--s2);padding:var(--s3) var(--s4);border-top:1px solid var(--border);flex:none}
@keyframes pop{from{opacity:0;transform:translateY(6px) scale(.985)}to{opacity:1;transform:none}}
@keyframes sheet{from{transform:translateY(100%)}to{transform:none}}
.pop{position:fixed;z-index:90;min-width:160px;max-width:min(420px,92vw);max-height:min(360px,60dvh);overflow-y:auto;background:var(--raised);border-radius:var(--r-m);box-shadow:var(--shadow-pop);padding:4px;animation:pop var(--t-fast) var(--ease)}
.pop-mask{position:fixed;inset:0;z-index:89}
.pop .opt{display:flex;align-items:center;gap:8px;width:100%;min-height:32px;padding:5px 10px;border-radius:var(--r-s);text-align:left;font-size:13px;color:var(--text)}
.pop .opt .t{flex:1;min-width:0}
.pop .opt .t small{display:block;color:var(--muted);font-size:11.5px}
.pop .opt.on{font-weight:600}
.pop .opt.on::after{content:"✓";color:var(--accent-text);flex:none}
.pop .opt.hl{background:var(--sunken)}
.pop .opt.danger{color:var(--err)}
.pop .opt:disabled{opacity:.45}
.pop .search{position:sticky;top:-4px;margin:-4px -4px 4px;padding:6px;background:var(--raised);border-bottom:1px solid var(--border)}
.pop .none{padding:14px;text-align:center;color:var(--muted);font-size:12.5px}
#toasts{position:fixed;z-index:120;right:var(--s4);bottom:calc(var(--s4) + env(safe-area-inset-bottom));display:flex;flex-direction:column;gap:var(--s2);align-items:flex-end;pointer-events:none}
.toast{pointer-events:auto;display:flex;align-items:center;gap:var(--s3);max-width:min(440px,92vw);padding:9px 14px;border-radius:var(--r-m);background:var(--text);color:var(--bg);font-size:13px;box-shadow:var(--shadow-pop);animation:pop var(--t) var(--ease)}
.toast.err{background:var(--err);color:#fff}
.toast button{color:inherit;font-weight:600;text-decoration:underline;text-underline-offset:2px;flex:none}
.toast.out{opacity:0;transform:translateY(6px);transition:opacity var(--t-fast),transform var(--t-fast)}
.tip{position:absolute;z-index:20;pointer-events:none;max-width:260px;padding:8px 10px;border-radius:var(--r-m);background:var(--raised);box-shadow:var(--shadow-pop);font-size:12.5px}
@media (max-width:760px){
  .mask{place-items:end center;padding:0}
  .modal,.modal.wide{width:100%;max-height:92dvh;border-radius:var(--r-l) var(--r-l) 0 0;animation:sheet var(--t-slow) var(--ease);padding-bottom:env(safe-area-inset-bottom)}
  .pop{left:0!important;right:0;top:auto!important;bottom:0;max-width:none;width:100%!important;max-height:70dvh;border-radius:var(--r-l) var(--r-l) 0 0;padding:8px 8px calc(8px + env(safe-area-inset-bottom));animation:sheet var(--t-slow) var(--ease)}
  .pop .opt{min-height:44px;font-size:15px}
  .pop-mask{background:rgba(0,0,0,.42)}
  #toasts{left:var(--s3);right:var(--s3);align-items:stretch}
}

/* ---------- 模型卡 / 公告 / 图表 ---------- */
.mcard{display:flex;flex-direction:column;gap:var(--s3)}
.mcard .mname{display:flex;align-items:center;gap:6px;min-width:0}
.mcard .mname b{font-family:var(--mono);font-size:13.5px;overflow-wrap:anywhere}
.mcard .notes{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:4px 12px;font-size:12.5px}
.mcard .notes .nk{color:var(--muted)} .mcard .notes .nv{white-space:pre-wrap;overflow-wrap:anywhere}
.ann{padding:var(--s3) 0;border-top:1px solid var(--border)}
.ann:first-of-type{border-top:0;padding-top:0}
.ann .d{font-size:12px;color:var(--muted)}
.ann .c{white-space:pre-wrap;overflow-wrap:anywhere}
.chart{position:relative;overflow-x:auto}
.chart svg{display:block;width:100%;height:auto;min-width:420px}
.chart .bar{fill:var(--accent)} .chart .bar-val{font-size:10.5px;fill:var(--text2)}
.chart .ax{font-size:10.5px;fill:var(--muted)} .chart .ax-t{font-size:11px;fill:var(--muted)}
.chart .gridline{stroke:var(--border);stroke-width:1} .chart .divline{stroke:var(--border2);stroke-dasharray:3 3}
.chart .pt{fill:var(--accent);stroke:var(--surface);stroke-width:1.5;cursor:pointer}
.chart .pt.free{fill:var(--info)}
.chart .pt-label{font-size:10.5px;fill:var(--text2);font-family:var(--mono)}
.chart .leader{stroke:var(--border2);stroke-width:1}
.vars{display:flex;flex-wrap:wrap;gap:6px}
.vars button{font:12px var(--mono);padding:2px 8px;border-radius:var(--r-s);background:var(--sunken);border:1px solid var(--border);color:var(--text2)}
.vars button:disabled{opacity:.4;cursor:not-allowed}
.preview{padding:8px 10px;border-radius:var(--r-m);background:var(--sunken);font-size:12.5px;white-space:pre-wrap;overflow-wrap:anywhere;min-height:34px}
.steps{counter-reset:s;display:flex;flex-direction:column;gap:6px;font-size:13px;color:var(--text2)}
.steps>div{counter-increment:s;display:flex;gap:10px}
.steps>div::before{content:counter(s);flex:none;width:20px;height:20px;border-radius:50%;background:var(--sunken);border:1px solid var(--border);display:grid;place-items:center;font-size:11px;color:var(--muted)}

/* ---------- 登录 ---------- */
.login{min-height:100dvh;display:grid;place-items:center;padding:var(--s4)}
.login-card{width:min(360px,100%);display:flex;flex-direction:column;gap:var(--s4);background:var(--surface);border:1px solid var(--border);border-radius:var(--r-l);padding:var(--s5)}
.login-card .mark{width:28px;height:28px;border-radius:8px;background:var(--accent)}
.login-card h1{font-size:17px;font-weight:600}
.login-err{color:var(--err);font-size:12.5px;min-height:18px}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;transition-duration:.01ms!important}
  .view,.mask,.toast{animation:fade 120ms!important}
  .skel{animation:none}
}
