/* ============================================================
   抗氧化肽预测 — 玻璃底子 · 靛蓝色调
   主题/语言由 app.js 经 localStorage 持久化（data-theme + html lang）
   ============================================================ */
:root{
  --text:#1c1917; --text-2:#57534e; --text-3:#a8a29e;
  --glass:rgba(255,255,255,.62); --glass-border:rgba(255,255,255,.75);
  --stroke:rgba(28,25,23,.09); --field:rgba(255,255,255,.55);
  --accent:#4338ca; --accent-2:#6366f1; --accent-soft:rgba(67,56,202,.10);
  --accent-rgb:67,56,202;
  --pos:#15803d; --pos-2:#22c55e; --neg:#b91c1c; --neg-soft:rgba(185,28,28,.10);
  --g1:#e0e7ff; --g2:#eef2ff; --g3:#ede9fe; --g4:#f6f5f2;
}
[data-theme="dark"]{
  --text:#ececec; --text-2:#a1a1aa; --text-3:#71717a;
  --glass:rgba(24,26,32,.58); --glass-border:rgba(129,140,248,.16);
  --stroke:rgba(161,161,170,.14); --field:rgba(14,15,19,.5);
  --accent:#818cf8; --accent-2:#a5b4fc; --accent-soft:rgba(129,140,248,.14);
  --accent-rgb:129,140,248;
  --pos:#4ade80; --pos-2:#22c55e; --neg:#f87171; --neg-soft:rgba(248,113,113,.12);
  --g1:#1e1b4b; --g2:#172033; --g3:#2a1f4a; --g4:#0c0d12;
}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{
  min-height:100vh;color:var(--text);
  font-family:"Manrope",system-ui,-apple-system,sans-serif;
  background:
    radial-gradient(820px 560px at 10% -8%,var(--g1),transparent 56%),
    radial-gradient(760px 640px at 96% 6%,var(--g2),transparent 52%),
    radial-gradient(680px 680px at 62% 112%,var(--g3),transparent 56%),
    var(--g4);
  background-attachment:fixed;background-size:160% 160%;
  animation:drift 26s ease-in-out infinite alternate;
  transition:color .4s;-webkit-font-smoothing:antialiased;
}
@keyframes drift{0%{background-position:0% 0%}100%{background-position:100% 100%}}

/* 背景：氨基酸漂流（canvas 由 app.js 驱动，固定铺满视口、置于内容之下、不挡交互）*/
#bg{position:fixed;inset:0;z-index:0;pointer-events:none}
.wrap{max-width:680px;margin:0 auto;padding:28px 22px 80px;position:relative;z-index:1}
.hide{display:none!important}

/* entrance —— 起止态都放进 keyframes（both 填充），基础样式即自然静止态(opacity:1/无位移)。
   这样切换语言时摘掉 .rise 类不会跳动，langSwap 也不会与之抢 animation 属性。 */
.rise{animation:rise .7s cubic-bezier(.2,.8,.2,1) both}
@keyframes rise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}

/* 顶边栏：吸顶玻璃条 —— 平台标识 + 学校 logo + 语言/主题切换 */
.topbar{position:sticky;top:0;z-index:50;background:var(--glass);backdrop-filter:blur(18px) saturate(1.3);-webkit-backdrop-filter:blur(18px) saturate(1.3);border-bottom:1px solid var(--glass-border);box-shadow:0 8px 30px -24px rgba(28,25,23,.5);transition:box-shadow .3s,border-color .3s}
.topbar-inner{max-width:680px;margin:0 auto;padding:11px 22px;display:flex;align-items:center;justify-content:space-between;gap:14px;transition:padding .25s}
/* 滚动后顶栏收薄、阴影加深，更精致 */
.topbar.scrolled .topbar-inner{padding-top:7px;padding-bottom:7px}
.topbar.scrolled{box-shadow:0 12px 30px -18px rgba(28,25,23,.55);border-bottom-color:var(--stroke)}
.topbar.scrolled .mark{width:32px;height:32px}
.brand{display:flex;align-items:center;gap:11px;min-width:0}
.topbar-right{display:flex;align-items:center;gap:12px;flex:none}
.school{display:inline-flex;align-items:center;border-radius:9px;transition:transform .2s}
.school img{height:27px;display:block}
.school:hover{transform:translateY(-1px)}
/* 暗色：给学校 logo 垫一层白色圆角底板（深底上深蓝校名才看得清；官方 logo 不改色） */
[data-theme="dark"] .school{background:#fff;padding:5px 9px;box-shadow:0 4px 14px -6px rgba(0,0,0,.5)}
.tb-divider{width:1px;height:24px;background:var(--stroke);flex:none}
.mark{width:42px;height:42px;border-radius:13px;background:linear-gradient(135deg,var(--accent),var(--accent-2));display:grid;place-items:center;box-shadow:0 10px 24px -8px var(--accent);position:relative;overflow:hidden}
.mark::after{content:"";position:absolute;inset:0;background:linear-gradient(120deg,transparent 30%,rgba(255,255,255,.5) 50%,transparent 70%);transform:translateX(-120%);animation:sheen 5s ease-in-out infinite}
@keyframes sheen{0%,70%{transform:translateX(-120%)}85%,100%{transform:translateX(120%)}}
.mark svg{width:23px;height:23px;position:relative;z-index:1}
.topbar .mark{width:36px;height:36px;border-radius:11px;flex:none;transition:width .25s,height .25s}
.topbar .mark svg{width:20px;height:20px}
.brand-name{font-family:"Sora",sans-serif;font-weight:700;font-size:17px;letter-spacing:-.02em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* 窄屏：藏掉长产品名(留图标)与分隔线，保证 logo + 控件不挤 */
@media(max-width:560px){
  .topbar-inner{padding:9px 16px;gap:10px}
  .brand-name{display:none}
  .school img{height:23px}
  .tb-divider{display:none}
}
.controls{display:flex;gap:8px}
.ctl{border:1px solid var(--glass-border);background:var(--glass);backdrop-filter:blur(14px);color:var(--text-2);border-radius:12px;padding:8px 13px;font-size:13px;cursor:pointer;font-family:"Sora";font-weight:600;transition:.25s}
.ctl:hover{color:var(--accent);transform:translateY(-1px);box-shadow:0 6px 16px -8px var(--accent)}
.ctl:active{transform:translateY(0)}

.tagline{color:var(--text-2);font-size:14.5px;margin:6px 0 7px;max-width:92%}
.subtitle{color:var(--text-3);font-size:13px;line-height:1.5;margin:0 0 18px;max-width:90%}
/* 渐隐细分割线：把 hero 介绍与下方工作区分开，给输入区一个起点 */
.hr{height:1px;border:0;margin:0 0 22px;background:linear-gradient(90deg,transparent,var(--stroke) 18%,var(--stroke) 82%,transparent)}

/* model strip */
.modelstrip{background:var(--glass);backdrop-filter:blur(16px);border:1px solid var(--glass-border);border-radius:16px;padding:13px 16px;margin-bottom:22px;box-shadow:0 14px 40px -22px rgba(28,25,23,.3);transition:opacity .3s}
.ms-top{display:flex;align-items:center;gap:9px;font-size:13px;font-weight:600;color:var(--accent);margin-bottom:9px;flex-wrap:wrap}
.ms-top .dot{width:8px;height:8px;border-radius:50%;background:var(--accent);box-shadow:0 0 0 0 var(--accent);animation:rad 2.2s infinite;flex:none}
.ms-top.warn{color:var(--neg)}
.ms-top.warn .dot{background:var(--neg);animation:none}
@keyframes rad{0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--accent) 55%,transparent)}70%{box-shadow:0 0 0 9px transparent}100%{box-shadow:0 0 0 0 transparent}}
.ms-top .sep{color:var(--text-3);font-weight:400}
.ms-top .ens{color:var(--text-2);font-weight:500}
.ms-models{display:flex;flex-wrap:wrap;gap:6px}
.ms-models .mc{font-size:11px;font-family:"IBM Plex Mono";padding:4px 9px;border-radius:8px;background:var(--accent-soft);color:var(--accent);font-weight:500;transition:.2s;cursor:default;opacity:0;animation:pchip .4s ease forwards}
.ms-models .mc:hover{transform:translateY(-2px)}
@keyframes pchip{to{opacity:1}}

/* tabs */
.tabs{display:flex;gap:4px;background:var(--glass);backdrop-filter:blur(14px);border:1px solid var(--glass-border);padding:5px;border-radius:15px;width:fit-content;margin-bottom:18px;position:relative}
.tab{padding:9px 26px;border:none;background:none;color:var(--text-2);font-size:14px;font-family:"Sora";font-weight:600;cursor:pointer;border-radius:11px;transition:color .25s;position:relative;z-index:1}
.tab.active{color:#fff}
.tab-ind{position:absolute;top:5px;height:calc(100% - 10px);background:linear-gradient(120deg,var(--accent),var(--accent-2));border-radius:11px;transition:transform .4s cubic-bezier(.3,1.3,.4,1),width .4s;z-index:0;box-shadow:0 8px 18px -8px var(--accent)}

/* card */
.card{background:var(--glass);backdrop-filter:blur(22px) saturate(1.3);-webkit-backdrop-filter:blur(22px) saturate(1.3);border:1px solid var(--glass-border);border-radius:22px;padding:24px;box-shadow:0 24px 64px -28px rgba(28,25,23,.4),inset 0 1px 0 rgba(255,255,255,.45)}
.lblrow{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:9px}
label{font-size:13px;color:var(--text-2);font-weight:600}
.counter{font-size:12px;color:var(--text-3);font-family:"IBM Plex Mono"}
.counter.over{color:var(--neg);font-weight:600}
textarea{width:100%;padding:15px;border:1px solid var(--stroke);border-radius:15px;background:var(--field);color:var(--text);font-family:"IBM Plex Mono",monospace;font-size:15px;letter-spacing:.12em;resize:vertical;transition:.25s;min-height:60px}
textarea:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 4px var(--accent-soft)}
textarea.invalid{border-color:var(--neg);box-shadow:0 0 0 4px var(--neg-soft)}
.field-err{color:var(--neg);font-size:12.5px;margin-top:8px;font-weight:500}

/* examples */
.examples{display:flex;gap:7px;margin-top:11px;flex-wrap:wrap;align-items:center}
.examples .ex-lbl{font-size:12px;color:var(--text-3)}
.chip-ex{font-size:11.5px;font-family:"IBM Plex Mono";padding:5px 10px;border-radius:9px;background:var(--field);border:1px solid var(--stroke);color:var(--text-2);cursor:pointer;transition:.2s}
.chip-ex:hover{border-color:var(--accent);color:var(--accent);transform:translateY(-1px)}

/* row + slider + file */
.row{display:flex;align-items:center;gap:18px;margin-top:18px;flex-wrap:wrap}
.thr{display:flex;align-items:center;gap:12px;flex:1;min-width:250px}
.thr-lbl{font-size:13px;color:var(--text-2);font-weight:600;white-space:nowrap}
.thr-range{flex:1;min-width:90px}
.thr-num{width:74px;padding:9px 10px;border:1px solid var(--stroke);border-radius:11px;background:var(--field);color:var(--text);font-family:"IBM Plex Mono",monospace;font-size:15px;font-weight:500;text-align:center;transition:.25s}
.thr-num:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 4px var(--accent-soft)}
input[type=range]{width:100%;-webkit-appearance:none;height:6px;border-radius:6px;background:var(--stroke);cursor:pointer}
input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:19px;height:19px;border-radius:50%;background:linear-gradient(135deg,var(--accent),var(--accent-2));cursor:pointer;border:3px solid #fff;box-shadow:0 2px 8px rgba(0,0,0,.22);transition:transform .15s}
input[type=range]::-webkit-slider-thumb:hover{transform:scale(1.15)}
input[type=range]::-moz-range-thumb{width:16px;height:16px;border-radius:50%;background:var(--accent);border:3px solid #fff;cursor:pointer}
.file-btn{display:inline-flex;align-items:center;gap:6px;padding:10px 16px;border:1px dashed var(--stroke);border-radius:12px;background:var(--field);color:var(--text-2);font-size:13px;font-weight:600;cursor:pointer;transition:.2s}
.file-btn:hover{border-color:var(--accent);color:var(--accent)}

/* button */
.btn{padding:12px 30px;border:none;border-radius:14px;background:linear-gradient(120deg,var(--accent),var(--accent-2));color:#fff;font-size:14px;font-weight:700;font-family:"Sora";cursor:pointer;transition:.25s;box-shadow:0 10px 24px -10px var(--accent);position:relative;white-space:nowrap}
.btn:hover{transform:translateY(-2px);box-shadow:0 16px 32px -12px var(--accent)}
.btn:active{transform:translateY(0)}
.btn:disabled{cursor:default;opacity:.7;transform:none}
.btn .spinner{display:none;width:15px;height:15px;border:2px solid rgba(255,255,255,.4);border-top-color:#fff;border-radius:50%;animation:spin .7s linear infinite;vertical-align:-2px;margin-right:7px}
@keyframes spin{to{transform:rotate(360deg)}}
.btn.loading .spinner{display:inline-block}

/* result */
.result{margin-top:26px;padding-top:24px;border-top:1px solid var(--stroke);animation:reveal .5s ease}
@keyframes reveal{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.result-head{display:flex;gap:24px;align-items:center;flex-wrap:wrap;margin-bottom:22px}
.gauge{position:relative;width:138px;height:138px;flex:none}
.gauge svg{transform:rotate(-90deg)}
.gauge .track{fill:none;stroke:var(--stroke);stroke-width:11}
.gauge .val{fill:none;stroke-width:11;stroke-linecap:round;stroke-dasharray:370;stroke-dashoffset:370;transition:stroke-dashoffset 1.2s cubic-bezier(.2,.8,.2,1)}
.gauge .center{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center}
.gauge .pct{font-family:"Sora";font-weight:700;font-size:29px;letter-spacing:-.02em}
.gauge .pct-lbl{font-size:10px;color:var(--text-3);margin-top:3px;font-weight:600;letter-spacing:.08em;text-transform:uppercase}
.vblock{flex:1;min-width:190px}
.verdict{display:flex;align-items:center;gap:11px;font-family:"Sora";font-size:22px;font-weight:700;margin-bottom:7px;color:var(--pos)}
.verdict.neg{color:var(--neg)}
.verdict .ico{width:32px;height:32px;border-radius:50%;display:grid;place-items:center;font-size:16px;animation:pop .5s cubic-bezier(.3,1.5,.5,1) .3s both;background:color-mix(in srgb,var(--pos) 16%,transparent)}
.verdict.neg .ico{background:color-mix(in srgb,var(--neg) 16%,transparent)}
@keyframes pop{0%{transform:scale(0)}100%{transform:scale(1)}}
.rsub{color:var(--text-2);font-size:13px;margin-bottom:6px}
.conf{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;padding:4px 10px;border-radius:999px;margin-top:2px}
.conf.high{background:color-mix(in srgb,var(--pos) 14%,transparent);color:var(--pos)}
.conf.mid{background:var(--accent-soft);color:var(--accent)}
.conf.low{background:color-mix(in srgb,var(--text-3) 18%,transparent);color:var(--text-2)}
.result-actions{display:flex;gap:8px;margin-top:14px;flex-wrap:wrap}
.mini-btn{font-size:12.5px;font-weight:600;font-family:"Sora";padding:7px 13px;border-radius:10px;border:1px solid var(--stroke);background:var(--field);color:var(--text-2);cursor:pointer;transition:.2s;display:inline-flex;align-items:center;gap:6px}
.mini-btn:hover{border-color:var(--accent);color:var(--accent);transform:translateY(-1px)}

/* per-model breakdown */
.bd-title{font-size:12px;font-weight:600;color:var(--text-3);text-transform:uppercase;letter-spacing:.06em;margin-bottom:12px}
.bd-row{display:grid;grid-template-columns:64px 1fr 56px 22px;align-items:center;gap:12px;margin-bottom:11px;opacity:0;transform:translateX(-10px);animation:slidein .5s ease forwards}
@keyframes slidein{to{opacity:1;transform:none}}
.bd-name{font-family:"IBM Plex Mono";font-size:13px;font-weight:500;color:var(--text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.bd-bar{height:9px;border-radius:999px;background:var(--field);border:1px solid var(--stroke);overflow:hidden;position:relative}
.bd-fill{height:100%;border-radius:999px;width:0;transition:width 1s cubic-bezier(.2,.8,.2,1)}
.bd-fill.pos{background:linear-gradient(90deg,var(--pos-2),var(--pos))}
.bd-fill.neg{background:linear-gradient(90deg,#f87171,var(--neg))}
.bd-tick{position:absolute;top:-2px;bottom:-2px;width:2px;background:var(--text-3);opacity:.5}
.bd-val{font-family:"IBM Plex Mono";font-size:13px;text-align:right;color:var(--text)}
.bd-call{text-align:center;font-size:13px}
.bd-call.y{color:var(--pos)}.bd-call.n{color:var(--neg)}

/* skeleton (loading placeholder) */
.skeleton{display:flex;flex-direction:column;gap:14px}
.sk-head{display:flex;gap:24px;align-items:center}
.sk-circle{width:138px;height:138px;border-radius:50%;flex:none}
.sk-line{height:14px;border-radius:8px}
.sk{background:linear-gradient(100deg,var(--field) 30%,var(--stroke) 50%,var(--field) 70%);background-size:200% 100%;animation:shimmer 1.3s linear infinite}
@keyframes shimmer{to{background-position:-200% 0}}

/* batch summary + histogram */
.batch-summary{display:flex;align-items:baseline;gap:8px;font-size:14px;margin-bottom:6px}
.batch-summary b{font-family:"Sora";font-size:20px;color:var(--accent)}
.hist{display:flex;align-items:flex-end;gap:3px;height:90px;margin:16px 0 6px;padding:0 2px}
.hist-bar{flex:1;background:linear-gradient(180deg,var(--accent-2),var(--accent));border-radius:5px 5px 0 0;min-height:2px;position:relative;transition:height .8s cubic-bezier(.2,.8,.2,1);height:0}
.hist-bar:hover::after{content:attr(data-tip);position:absolute;bottom:100%;left:50%;transform:translateX(-50%);background:var(--text);color:var(--g4);font-size:11px;padding:3px 7px;border-radius:6px;white-space:nowrap;font-family:"IBM Plex Mono";margin-bottom:4px}
.hist-axis{display:flex;justify-content:space-between;font-size:10.5px;color:var(--text-3);font-family:"IBM Plex Mono";margin-bottom:18px}

/* batch table */
.tbl-wrap{overflow-x:auto;margin-top:6px}
table{width:100%;border-collapse:collapse;font-size:13px}
th{text-align:left;color:var(--text-3);font-weight:600;padding:9px 10px;border-bottom:1px solid var(--stroke);font-size:11.5px;text-transform:uppercase;letter-spacing:.04em;cursor:pointer;user-select:none;white-space:nowrap;transition:color .2s}
th:hover{color:var(--accent)}
th .arr{opacity:.45;font-size:10px}
th.sorted .arr{opacity:1;color:var(--accent)}
td{padding:9px 10px;border-bottom:1px solid var(--stroke);font-family:"IBM Plex Mono"}
td.seqcol{font-family:"IBM Plex Mono";word-break:break-all}
tbody tr{transition:background .15s;cursor:help}
tbody tr:hover{background:var(--accent-soft)}
.hover-hint{font-size:11.5px;color:var(--text-3);margin:2px 0 8px;display:flex;align-items:center;gap:5px}

/* per-model hover popover (batch rows) */
.pm-pop{position:fixed;z-index:60;pointer-events:none;min-width:226px;background:var(--glass);backdrop-filter:blur(20px) saturate(1.3);-webkit-backdrop-filter:blur(20px) saturate(1.3);border:1px solid var(--glass-border);border-radius:14px;padding:13px 14px;box-shadow:0 22px 54px -18px rgba(0,0,0,.45);opacity:0;transform:translateY(4px) scale(.98);transition:opacity .14s,transform .14s}
.pm-pop.show{opacity:1;transform:none}
.pm-pop .pm-h{font-size:11px;font-weight:600;color:var(--text-3);text-transform:uppercase;letter-spacing:.05em;margin-bottom:10px;display:flex;justify-content:space-between;gap:12px;align-items:baseline}
.pm-h .pm-seq{color:var(--accent);font-family:"IBM Plex Mono";text-transform:none;letter-spacing:0;font-size:12px;word-break:break-all;text-align:right}
.pm-row{display:grid;grid-template-columns:46px 1fr 40px 14px;align-items:center;gap:8px;margin-bottom:7px}
.pm-row:last-child{margin-bottom:0}
.pm-name{font-family:"IBM Plex Mono";font-size:11.5px;color:var(--text-2)}
.pm-bar{height:7px;border-radius:999px;background:var(--field);border:1px solid var(--stroke);overflow:hidden;position:relative}
.pm-fill{height:100%;border-radius:999px}
.pm-fill.pos{background:linear-gradient(90deg,var(--pos-2),var(--pos))}
.pm-fill.neg{background:linear-gradient(90deg,#f87171,var(--neg))}
.pm-tick{position:absolute;top:-1px;bottom:-1px;width:1.5px;background:var(--text-3);opacity:.5}
.pm-val{font-family:"IBM Plex Mono";font-size:11.5px;text-align:right;color:var(--text)}
.pm-call{font-size:11px;text-align:center}
.pm-call.y{color:var(--pos)}.pm-call.n{color:var(--neg)}
tr:last-child td{border-bottom:none}
.mark-yes{color:var(--pos);font-weight:600}.mark-no{color:var(--neg);font-weight:600}

/* pager */
.pager{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:16px;flex-wrap:wrap}
.pager-size{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--text-2);font-weight:600}
.select-wrap{position:relative;display:inline-flex;align-items:center}
.select-wrap::after{content:"▾";position:absolute;right:11px;top:50%;transform:translateY(-50%);pointer-events:none;color:var(--text-3);font-size:11px;transition:color .2s}
.select-wrap:hover::after{color:var(--accent)}
.pg-select{appearance:none;-webkit-appearance:none;-moz-appearance:none;padding:7px 30px 7px 13px;border:1px solid var(--stroke);border-radius:10px;background:var(--field);color:var(--text);font-family:"Sora",sans-serif;font-size:12.5px;font-weight:600;cursor:pointer;transition:.2s}
.pg-select:hover{border-color:var(--accent)}
.pg-select:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 4px var(--accent-soft)}
.pager-nav{display:flex;align-items:center;gap:8px}
.pager-info{font-family:"IBM Plex Mono",monospace;font-size:12.5px;color:var(--text-2);min-width:52px;text-align:center;display:inline-block}
@keyframes pinfoPop{from{transform:scale(.78);opacity:.5}to{transform:none;opacity:1}}
.pg-btn{width:32px;height:32px;border:1px solid var(--stroke);border-radius:10px;background:var(--field);color:var(--text-2);font-size:17px;cursor:pointer;transition:.2s;display:grid;place-items:center;line-height:1}
.pg-btn:hover:not(:disabled){border-color:var(--accent);color:var(--accent);transform:translateY(-1px);box-shadow:0 6px 14px -8px var(--accent)}
.pg-btn:active:not(:disabled){transform:scale(.9)}
.pg-btn:disabled{opacity:.38;cursor:default}
.mini-btn:active{transform:translateY(0) scale(.96)}

/* batch row entrance — 也是翻页/排序时的动画（方向感知）*/
@keyframes rowinUp{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@keyframes rowinR{from{opacity:0;transform:translateX(16px)}to{opacity:1;transform:none}}
@keyframes rowinL{from{opacity:0;transform:translateX(-16px)}to{opacity:1;transform:none}}
.batch-row{animation:rowinUp .4s cubic-bezier(.2,.8,.2,1) both}
tbody.dir-next .batch-row{animation-name:rowinR}
tbody.dir-prev .batch-row{animation-name:rowinL}

footer{text-align:center;color:var(--text-3);font-size:12px;margin-top:34px;font-weight:500}
.foot-label{font-size:12.5px;color:var(--text-3);margin-bottom:11px}
.foot-admins{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;margin-bottom:15px}
.admin-chip{font-family:"IBM Plex Mono",monospace;font-size:12px;color:var(--text-2);cursor:pointer;padding:5px 12px;border:1px solid var(--stroke);border-radius:999px;background:var(--field);transition:.2s}
.admin-chip:hover{border-color:var(--accent);color:var(--accent);transform:translateY(-1px);box-shadow:0 6px 14px -8px var(--accent)}
.admin-chip.copied{border-color:var(--accent);color:var(--accent);background:var(--accent-soft);box-shadow:none;transform:none}
.foot-meta{color:var(--text-3);font-size:12px}

/* 中英文切换：纯透明度柔和交叉淡入（切换前已在 JS 摘掉 .rise，故二者不再抢 animation）。
   transform:none 为防御性兜底，确保切换期间绝无任何位移。 */
@keyframes langSwap{from{opacity:.25}to{opacity:1}}
.wrap.lang-swapping [data-i18n],.wrap.lang-swapping [data-i18n-ph]{animation:langSwap .45s ease both;transform:none}
/* 切换按钮：极轻的回弹脉冲反馈，不旋转 */
@keyframes langPulse{0%{transform:scale(1)}38%{transform:scale(.93)}100%{transform:scale(1)}}
#lang.lang-anim{animation:langPulse .44s cubic-bezier(.34,1.4,.5,1)}

@media (prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;transition-duration:.01ms!important}}
@media (max-width:560px){
  .wrap{padding:30px 16px 60px}
  .result-head{gap:16px}
  .gauge{width:118px;height:118px}
}
