/* ============================================================================
   猫猫雨电竞 · 经营管理后台

   来源：docs/kook-bot/design/console.css（三轮评审定稿）。搬运时做了三件事，
   除此之外逐字未改 —— 这样以后拿设计稿 diff 一眼能看出哪些是落地改的：

     1. 丢掉 §0 画布外壳（.doc / .frame / .note）与 §15 里的设计稿专用类
        （.sw-* 色板、.ts-* 字阶、.frame--*、*--demo、.shell--tall/xtall）。
        §15 的标题写着「设计稿专用」，但它其实是后两份稿子追加的产品样式和
        画布样式混在一起 —— 逐条挑过，产品的留下了。
     2. 补 @font-face。评审稿从 Google Fonts 引 Geist，生产不行（CSP
        default-src 'self'），字体文件从 payment 项目复用。
     3. 末尾加 §16：画布用的是固定高度（.shell 860px、.login 820px），
        真页面要跟着视口走。只在这里覆盖，不去改上面的行。
   ========================================================================== */

@font-face {
  font-family: 'Geist';
  src: url('../fonts/geist-latin.woff2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Geist Mono';
  src: url('../fonts/geist-mono-latin.woff2') format('woff2');
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
}

/* ── §1 基础 ─────────────────────────────────────────────────────────────── */
:root{
  /* 表面（四级，靠明度差分层，不用投影） */
  --surface-sunken:#131417;   /* 侧栏 */
  --surface-page:#17181B;     /* 页面底 */
  --surface-panel:#1D1F23;    /* 卡片 / 面板 */
  --surface-overlay:#26282D;  /* 模态 / 抽屉 / 下拉 */
  --surface-raise:#212327;    /* 面板内的次级块（表头条、内嵌块） */
  /* 线 */
  --line-faint:#24262B;       /* 表格行线，比常规还淡一档 */
  --line:#2C2F35;             /* 常规分隔线 */
  --line-strong:#3E434C;      /* 悬停边框、图表准星 */
  --grid-line:rgba(255,255,255,.05);
  --row-hover:rgba(255,255,255,.025);
  /* 文字（四级） */
  --text-title:#EDEEF0;
  --text-body:#C6CAD1;
  --text-muted:#8B9099;
  --text-faint:#62666E;
  /* 主色 —— 杏橙 amber。避开兄弟项目的 emerald / periwinkle，
     且它不会被误读成「成功」（那是绿色的活） */
  --primary:#D69A55;
  --primary-hover:#E5AD6C;
  --primary-soft:rgba(214,154,85,.13);
  --primary-softer:rgba(214,154,85,.07);
  --primary-ink:#241705;
  /* 五个状态语义 */
  --st-todo:#D69A55;   --st-todo-soft:rgba(214,154,85,.13);
  --st-ok:#4FB784;     --st-ok-soft:rgba(79,183,132,.13);
  --st-decide:#5B9CD8; --st-decide-soft:rgba(91,156,216,.13);
  --st-alert:#E0685F;  --st-alert-soft:rgba(224,104,95,.13);
  --st-done:#7C818B;   --st-done-soft:rgba(255,255,255,.055);
  /* 限次折扣：会耗尽的资源，既不是「正常」也不是「要你行动」 */
  --st-limited:#D9B44A; --st-limited-soft:rgba(217,180,74,.1); --st-limited-line:rgba(217,180,74,.34);
  /* 中性进行中：五语义都不适用时的显式表达（见设计稿注释） */
  --st-idle:#C6CAD1;   --st-idle-soft:rgba(255,255,255,.055);
  /* 几何 */
  --r-ctl:8px; --r-modal:10px; --r-sm:5px; --r-pill:999px;
  --sidebar-w:224px; --topbar-h:46px; --content-max:1320px;
  --shadow-overlay:0 16px 40px -12px rgba(0,0,0,.6),0 4px 12px -4px rgba(0,0,0,.5);
  /* 字体：Geist 排最前只接管拉丁与数字，汉字自然落到系统中文字体 */
  --font:'Geist',-apple-system,BlinkMacSystemFont,'PingFang SC','HarmonyOS Sans SC','Microsoft YaHei','Noto Sans CJK SC',sans-serif;
  --font-mono:'Geist Mono',ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  background:var(--surface-page);color:var(--text-body);
  font-family:var(--font);font-size:14px;line-height:1.65;
  -webkit-font-smoothing:antialiased;
  font-variant-numeric:tabular-nums;
}
a{color:var(--primary);text-decoration:none}
a:hover{color:var(--primary-hover);text-decoration:underline}
::selection{background:var(--primary-soft);color:var(--text-title)}
:focus-visible{outline:2px solid var(--primary);outline-offset:2px;border-radius:4px}

.lat{font-family:var(--font-mono);letter-spacing:-.01em}
.num{font-variant-numeric:tabular-nums}
.mono{font-family:var(--font-mono);font-size:12px;letter-spacing:0}
.nowrap{white-space:nowrap}
.t-title{color:var(--text-title)}
.t-body{color:var(--text-body)}
.t-muted{color:var(--text-muted)}
.t-faint{color:var(--text-faint)}

/* 金额：着色是语义不是装饰 */
.amt{font-variant-numeric:tabular-nums;white-space:nowrap}
.amt--in{color:var(--st-ok)}
.amt--out{color:var(--text-body)}
.amt--neg{color:var(--st-alert)}
.amt--big{font-size:22px;font-weight:600;color:var(--text-title);letter-spacing:-.01em}

/* ── §2 外壳 ─────────────────────────────────────────────────────────────── */
.shell{display:grid;grid-template-columns:var(--sidebar-w) 1fr;min-height:860px;background:var(--surface-page)}
.sidebar{background:var(--surface-sunken);border-right:1px solid var(--line);display:flex;flex-direction:column;min-height:0}
.brand{height:var(--topbar-h);display:flex;align-items:center;gap:9px;padding:0 16px;border-bottom:1px solid var(--line);flex:0 0 auto}
.brand-mark{width:22px;height:22px;border-radius:6px;background:var(--primary-soft);display:flex;align-items:center;justify-content:center;color:var(--primary);flex:0 0 22px}
.brand-name{font-size:13.5px;font-weight:600;color:var(--text-title)}
.nav{padding:10px 10px 20px;overflow-y:auto;flex:1 1 auto}
.nav-group{margin-top:14px}
.nav-group:first-child{margin-top:0}
.nav-group-label{font-size:11px;color:var(--text-faint);padding:0 8px 6px;font-weight:500}
.nav-item{display:flex;align-items:center;gap:9px;padding:6px 8px;border-radius:6px;color:var(--text-muted);font-size:13px;cursor:pointer;line-height:1.5}
.nav-item:hover{background:rgba(255,255,255,.04);color:var(--text-body)}
.nav-item .ico{flex:0 0 15px;height:15px;color:currentColor;opacity:.8}
.nav-item .lbl{flex:1 1 auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.nav-item.is-active{background:var(--primary-soft);color:var(--primary)}
.nav-item.is-active .ico{opacity:1}
.nav-count{font-family:var(--font-mono);font-size:10.5px;font-weight:500;min-width:18px;height:16px;padding:0 5px;border-radius:var(--r-pill);background:var(--primary);color:var(--primary-ink);display:inline-flex;align-items:center;justify-content:center}
.nav-count--quiet{background:rgba(255,255,255,.09);color:var(--text-muted)}
.nav-count--alert{background:var(--st-alert);color:#2A0906}
.sidebar-foot{padding:12px 16px;border-top:1px solid var(--line);font-size:11px;color:var(--text-faint);line-height:1.6;text-align:center}

.topbar{height:var(--topbar-h);border-bottom:1px solid var(--line);display:flex;align-items:center;gap:14px;padding:0 18px;background:var(--surface-page);position:relative;z-index:2}
.crumbs{display:flex;align-items:center;gap:7px;font-size:13px;color:var(--text-muted);flex:1 1 auto;min-width:0}
.crumbs b{color:var(--text-title);font-weight:600}
.crumbs .sep{color:var(--text-faint)}
.env{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:600;padding:2px 8px;border-radius:var(--r-sm);letter-spacing:.02em}
.env--dev{background:rgba(224,104,95,.14);color:var(--st-alert);border:1px solid rgba(224,104,95,.32)}
.env--prod{background:rgba(255,255,255,.055);color:var(--text-muted);border:1px solid var(--line)}
.env .dot{width:5px;height:5px;border-radius:50%;background:currentColor}
.who{display:flex;align-items:center;gap:8px;padding:3px 4px 3px 3px;border-radius:var(--r-pill);cursor:pointer}
.who:hover{background:rgba(255,255,255,.045)}
.who .av{width:24px;height:24px;border-radius:50%;flex:0 0 24px;object-fit:cover;background:var(--surface-overlay)}
.who .nm{font-size:13px;color:var(--text-body)}
.who .rl{font-size:11px;color:var(--text-faint)}

.main{display:flex;flex-direction:column;min-width:0;background:var(--surface-page)}
.scroll{flex:1 1 auto;overflow:auto;min-height:0}
.content{max-width:var(--content-max);margin:0 auto;padding:20px 24px 56px;display:flex;flex-direction:column;gap:18px}
.page-head{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}
.page-head h1{margin:0;font-size:18px;font-weight:600;color:var(--text-title);line-height:1.5}
.page-head .sub{margin:2px 0 0;font-size:12px;color:var(--text-muted)}
.page-head .grow{flex:1 1 auto}
.head-actions{display:flex;gap:8px;align-items:center}

/* 全局告警横幅 */
.banner{display:flex;align-items:flex-start;gap:11px;padding:11px 14px;border-radius:var(--r-ctl);border:1px solid rgba(224,104,95,.35);background:rgba(224,104,95,.1);color:var(--text-body);font-size:13px;line-height:1.65}
.banner--quota{border-color:rgba(214,154,85,.4);background:rgba(214,154,85,.1)}
.banner .ico{flex:0 0 16px;margin-top:2px;color:var(--st-alert)}
.banner--quota .ico{color:var(--primary)}
.banner .bd{flex:1 1 auto;min-width:0}
.banner .bd b{color:var(--text-title);font-weight:600}
.banner .bd .sub{display:block;color:var(--text-muted);font-size:12px;margin-top:2px}
.banner .x{flex:0 0 auto;background:none;border:0;color:var(--text-faint);cursor:pointer;padding:2px;border-radius:4px;font-family:inherit;font-size:12px}
.banner .locked{flex:0 0 auto;display:inline-flex;align-items:center;gap:5px;font-size:11px;color:var(--text-faint);white-space:nowrap}
.banner .x:hover{color:var(--text-body);background:rgba(255,255,255,.06)}

/* ── §3 面板 ─────────────────────────────────────────────────────────────── */
.panel{background:var(--surface-panel);border:1px solid var(--line);border-radius:var(--r-ctl);overflow:hidden}
.panel-head{display:flex;align-items:center;gap:10px;padding:11px 14px;border-bottom:1px solid var(--line)}
.panel-head h2,.panel-head h3{margin:0;font-size:14px;font-weight:600;color:var(--text-title);line-height:1.5}
.panel-head .sub{font-size:12px;color:var(--text-muted)}
.panel-head .grow{flex:1 1 auto}
.panel-body{padding:14px}
.panel-body--tight{padding:0}
.panel-foot{padding:10px 14px;border-top:1px solid var(--line);display:flex;align-items:center;gap:10px}
.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px;align-items:start}
.grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;align-items:start}
.grid-4{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;align-items:start}
.grid-side{display:grid;grid-template-columns:1fr 380px;gap:16px;align-items:start}
.stack{display:flex;flex-direction:column;gap:16px}
.stack--sm{gap:10px}
.row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.row--between{justify-content:space-between}
.row--tight{gap:6px}

/* ── §4 表格 ─────────────────────────────────────────────────────────────── */
.table-scroll{overflow-x:auto}
.table{width:100%;border-collapse:collapse}
.table.wide{min-width:1020px}
.table th{
  font-size:12px;font-weight:500;color:var(--text-faint);text-align:left;
  padding:9px 14px;white-space:nowrap;border-bottom:1px solid var(--line);
  background:var(--surface-raise);line-height:1.5;
}
.table th.lat{font-family:var(--font-mono);font-size:11px;letter-spacing:.02em}
.table th.r,.table td.r{text-align:right}
.table td{
  font-size:13px;padding:12px 14px;white-space:nowrap;
  border-top:1px solid var(--line-faint);color:var(--text-body);line-height:1.5;vertical-align:middle;
}
.table tbody tr:first-child td{border-top:0}
.table tbody tr:hover{background:var(--row-hover)}
.table tbody tr.is-clickable{cursor:pointer}
.table tbody tr.is-selected{background:var(--primary-softer)}
.table td .sub{display:block;font-size:11.5px;color:var(--text-faint);margin-top:2px;line-height:1.45}
.table td .sub.t-alert-sub{color:var(--st-alert)}
.table td .sub.t-ok-sub{color:var(--st-ok)}
.table td.r .amt{display:block}
.table--fixedact th:last-child,.table--fixedact td:last-child{
  position:sticky;right:0;background:var(--surface-panel);
  box-shadow:-12px 0 12px -12px rgba(0,0,0,.9);
}
.table--fixedact th:last-child{background:var(--surface-raise)}
.table--fixedact tbody tr:hover td:last-child{background:#212327}
.cell-2{display:flex;flex-direction:column;gap:2px}
.cell-who{display:flex;align-items:center;gap:8px}
.cell-who .av{width:22px;height:22px;border-radius:50%;flex:0 0 22px;object-fit:cover;background:var(--surface-overlay)}
.cell-who .nm{font-size:13px;color:var(--text-body)}
.cell-who .id{font-family:var(--font-mono);font-size:11px;color:var(--text-faint)}

/* 分页 */
.pager{display:flex;align-items:center;gap:10px;padding:10px 14px;border-top:1px solid var(--line)}
.pager .range{font-size:12px;color:var(--text-muted);flex:1 1 auto}
.pager .ind{font-family:var(--font-mono);font-size:12px;color:var(--text-body);min-width:48px;text-align:center;font-variant-numeric:tabular-nums}

/* 表格三种非正常状态 */
.tstate{padding:52px 24px;display:flex;flex-direction:column;align-items:center;gap:10px;text-align:center}
.tstate .art{opacity:.6;color:var(--text-faint)}
.tstate h4{margin:0;font-size:14px;font-weight:600;color:var(--text-body)}
.tstate p{margin:0;font-size:13px;color:var(--text-muted);max-width:44ch;line-height:1.7}
.tstate--fail{background:rgba(224,104,95,.05);border-top:1px solid rgba(224,104,95,.2);padding:34px 24px}
.tstate--fail .art{color:var(--st-alert);opacity:.8}
.tstate--fail h4{color:var(--st-alert)}
.sk{height:11px;border-radius:4px;background:linear-gradient(90deg,rgba(255,255,255,.05),rgba(255,255,255,.085),rgba(255,255,255,.05));background-size:220% 100%;animation:skshine 1.5s linear infinite}
@keyframes skshine{0%{background-position:120% 0}100%{background-position:-120% 0}}
.sk--w40{width:40%}.sk--w60{width:60%}.sk--w80{width:80%}.sk--w100{width:100%}.sk--w28{width:28%}

/* ── §5 徽章 ─────────────────────────────────────────────────────────────── */
.badge{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;font-weight:500;padding:2px 8px;border-radius:var(--r-sm);white-space:nowrap;line-height:1.6;border:1px solid transparent}
.badge .dot{width:5px;height:5px;border-radius:50%;background:currentColor;flex:0 0 5px}
.badge--todo{background:var(--st-todo-soft);color:var(--st-todo);border-color:rgba(214,154,85,.24)}
.badge--ok{background:var(--st-ok-soft);color:var(--st-ok);border-color:rgba(79,183,132,.24)}
.badge--decide{background:var(--st-decide-soft);color:var(--st-decide);border-color:rgba(91,156,216,.24)}
.badge--alert{background:var(--st-alert-soft);color:var(--st-alert);border-color:rgba(224,104,95,.26)}
.badge--done{background:var(--st-done-soft);color:var(--st-done);border-color:var(--line)}
.badge--idle{background:var(--st-idle-soft);color:var(--st-idle);border-color:var(--line)}
.badge--live .dot{animation:pulse 1.6s ease-in-out infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.25}}
.badge--sm{font-size:11px;padding:1px 6px}

/* 双维状态：受理维度用「细杠 + 小字」挂在进度徽章前，两者不抢 */
.dual{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
.dual .intake{display:inline-flex;align-items:center;gap:4px;font-size:11px;padding:1px 6px;border-radius:var(--r-sm);border:1px dashed transparent;line-height:1.6}
.dual .intake--pending{color:var(--st-todo);border-color:rgba(214,154,85,.42)}
.dual .intake--approved{color:var(--text-faint);border-color:var(--line)}
.dual .intake--rejected{color:var(--st-alert);border-color:rgba(224,104,95,.5);background:rgba(224,104,95,.08)}
.dual .arrow{color:var(--text-faint);font-size:10px}

/* 角色 */
.rolepill{display:inline-flex;align-items:center;font-size:11px;font-weight:500;padding:1px 7px;border-radius:var(--r-pill);border:1px solid var(--line);background:rgba(255,255,255,.045);color:var(--text-muted);white-space:nowrap}
.rolepill--owner{color:var(--primary);border-color:rgba(214,154,85,.3);background:var(--primary-softer)}
.rolepill--finance{color:var(--st-decide);border-color:rgba(91,156,216,.3);background:rgba(91,156,216,.07)}
.rolepill--agent{color:var(--st-ok);border-color:rgba(79,183,132,.3);background:rgba(79,183,132,.07)}

/* 会员等级：VIP / VIP限次折扣 / SVIP永久折扣 是三类东西，不是 12 个渐变 */
.lv{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;font-weight:600;padding:2px 8px;border-radius:var(--r-sm);white-space:nowrap;border:1px solid;line-height:1.6}
.lv .tier{font-family:var(--font-mono);font-size:11px;letter-spacing:.02em}
.lv--plain{color:var(--text-muted);border-color:var(--line);background:rgba(255,255,255,.045)}
.lv--limited{color:var(--st-limited);border-color:var(--st-limited-line);background:var(--st-limited-soft)}
.lv--perm{color:var(--primary);border-color:rgba(214,154,85,.42);background:linear-gradient(180deg,rgba(214,154,85,.18),rgba(214,154,85,.09))}
.lv-quota{display:inline-flex;align-items:center;font-family:var(--font-mono);font-size:10.5px;padding:0 4px;border-radius:3px;background:rgba(0,0,0,.28);color:currentColor}

/* ── §6 按钮 ─────────────────────────────────────────────────────────────── */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  font-family:inherit;font-size:13px;font-weight:500;line-height:1;
  padding:0 13px;height:32px;border-radius:6px;border:1px solid transparent;
  cursor:pointer;white-space:nowrap;transition:background .12s,border-color .12s,color .12s;
}
.btn .ico{flex:0 0 14px}
.btn--sm{height:26px;font-size:12px;padding:0 9px;border-radius:5px;gap:5px}
.btn--lg{height:38px;font-size:14px;padding:0 18px}
.btn--block{width:100%}
.btn--primary{background:var(--primary);color:var(--primary-ink);font-weight:600}
.btn--primary:hover{background:var(--primary-hover)}
.btn--primary:active{background:#C88C48}
.btn--secondary{background:rgba(255,255,255,.055);color:var(--text-body);border-color:var(--line)}
.btn--secondary:hover{background:rgba(255,255,255,.085);border-color:var(--line-strong);color:var(--text-title)}
.btn--secondary:active{background:rgba(255,255,255,.03)}
.btn--danger{background:rgba(224,104,95,.14);color:var(--st-alert);border-color:rgba(224,104,95,.36)}
.btn--danger:hover{background:var(--st-alert);color:#2A0906;border-color:var(--st-alert)}
.btn--ghost{background:transparent;color:var(--text-muted)}
.btn--ghost:hover{background:rgba(255,255,255,.055);color:var(--text-body)}
.btn:disabled,.btn.is-disabled{opacity:.4;cursor:not-allowed}
.btn:disabled:hover,.btn.is-disabled:hover{background:inherit}
.btn--primary:disabled:hover{background:var(--primary)}
.btn.is-loading{color:transparent;position:relative;pointer-events:none}
.btn.is-loading::after{content:"";position:absolute;width:13px;height:13px;border-radius:50%;border:2px solid rgba(0,0,0,.25);border-top-color:rgba(0,0,0,.75);animation:spin .7s linear infinite}
.btn--secondary.is-loading::after,.btn--ghost.is-loading::after,.btn--danger.is-loading::after{border-color:rgba(255,255,255,.2);border-top-color:var(--text-body)}
@keyframes spin{to{transform:rotate(360deg)}}
.btn-focus-demo{outline:2px solid var(--primary);outline-offset:2px}
.btngroup{display:inline-flex;border:1px solid var(--line);border-radius:6px;overflow:hidden}
.btngroup .btn{border-radius:0;border:0;border-right:1px solid var(--line);height:30px}
.btngroup .btn:last-child{border-right:0}
.btngroup .btn.is-on{background:var(--primary-soft);color:var(--primary)}
.iconbtn{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:6px;border:1px solid var(--line);background:rgba(255,255,255,.04);color:var(--text-muted);cursor:pointer;padding:0}
.iconbtn:hover{color:var(--text-title);border-color:var(--line-strong);background:rgba(255,255,255,.07)}
.iconbtn:disabled{opacity:.35;cursor:not-allowed}

/* ── §7 表单 ─────────────────────────────────────────────────────────────── */
.field{display:flex;flex-direction:column;gap:6px;min-width:0}
.field > label{font-size:13px;color:var(--text-body);font-weight:500;display:flex;align-items:center;gap:6px}
.field .req{color:var(--st-alert)}
.field .hint{font-size:11.5px;color:var(--text-faint);line-height:1.6}
.field .err{font-size:11.5px;color:var(--st-alert);display:flex;align-items:center;gap:5px;line-height:1.6}
.input,.select,.textarea{
  font-family:inherit;font-size:13px;color:var(--text-title);line-height:1.5;
  background:var(--surface-page);border:1px solid var(--line);border-radius:6px;
  padding:0 11px;height:32px;width:100%;
}
.textarea{height:auto;padding:8px 11px;resize:vertical;min-height:72px;line-height:1.65}
.input::placeholder,.textarea::placeholder{color:var(--text-faint)}
.input:hover,.select:hover{border-color:var(--line-strong)}
.input:focus,.select:focus,.textarea:focus{outline:0;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-softer)}
.input:disabled,.select:disabled{opacity:.45;cursor:not-allowed;background:rgba(255,255,255,.02)}
.input.is-error,.select.is-error{border-color:var(--st-alert)}
.input.is-error:focus{box-shadow:0 0 0 3px rgba(224,104,95,.14)}
.select{appearance:none;padding-right:28px;background-image:linear-gradient(45deg,transparent 50%,#8B9099 50%),linear-gradient(135deg,#8B9099 50%,transparent 50%);background-position:calc(100% - 15px) 14px,calc(100% - 10px) 14px;background-size:5px 5px,5px 5px;background-repeat:no-repeat}
.input-mono{font-family:var(--font-mono);font-size:12.5px}
.input-wrap{position:relative;display:flex;align-items:center}
.input-wrap .pre{position:absolute;left:11px;font-size:13px;color:var(--text-muted);pointer-events:none}
.input-wrap .suf{position:absolute;right:11px;font-size:12px;color:var(--text-faint);pointer-events:none}
.input-wrap .input{padding-left:26px;text-align:right;padding-right:52px;font-family:var(--font-mono);font-size:14px}
.daterange{display:flex;align-items:center;gap:0;border:1px solid var(--line);border-radius:6px;background:var(--surface-page);height:32px;overflow:hidden}
.daterange:focus-within{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-softer)}
.daterange .input{border:0;box-shadow:none;background:transparent;text-align:center;font-family:var(--font-mono);font-size:12.5px}
.daterange .tilde{color:var(--text-faint);flex:0 0 auto;font-size:12px}
.checkbox{display:inline-flex;align-items:flex-start;gap:8px;font-size:13px;color:var(--text-body);cursor:pointer;line-height:1.6}
.checkbox .box{width:15px;height:15px;flex:0 0 15px;border-radius:4px;border:1px solid var(--line-strong);background:var(--surface-page);margin-top:3px;display:flex;align-items:center;justify-content:center;color:transparent}
.checkbox.is-on .box{background:var(--primary);border-color:var(--primary);color:var(--primary-ink)}
.radiorow{display:flex;gap:0;border:1px solid var(--line);border-radius:6px;overflow:hidden;width:fit-content}
.radiorow .opt{padding:0 14px;height:32px;display:flex;align-items:center;font-size:13px;color:var(--text-muted);cursor:pointer;border-right:1px solid var(--line);white-space:nowrap}
.radiorow .opt:last-child{border-right:0}
.radiorow .opt:hover{background:rgba(255,255,255,.045);color:var(--text-body)}
.radiorow .opt.is-on{background:var(--primary-soft);color:var(--primary);font-weight:500}
.radiorow .opt.is-off{opacity:.35;cursor:not-allowed}
.filters{display:flex;gap:10px;align-items:flex-end;flex-wrap:wrap}
.filters .field{min-width:0}
.f-w120{width:120px}.f-w140{width:140px}.f-w160{width:160px}.f-w180{width:180px}.f-w200{width:200px}.f-w240{width:240px}.f-w280{width:280px}

/* 文件上传（凭证） */
.upload{border:1px dashed var(--line-strong);border-radius:var(--r-ctl);padding:22px;display:flex;flex-direction:column;align-items:center;gap:8px;text-align:center;background:rgba(255,255,255,.015);cursor:pointer}
.upload:hover{border-color:var(--primary);background:var(--primary-softer)}
.upload .ico{color:var(--text-faint)}
.upload .t{font-size:13px;color:var(--text-body)}
.upload .s{font-size:11.5px;color:var(--text-faint)}
.upload.is-error{border-color:var(--st-alert);background:rgba(224,104,95,.05)}
.proof{display:flex;align-items:center;gap:11px;border:1px solid var(--line);border-radius:var(--r-ctl);padding:9px 11px;background:var(--surface-page)}
.proof .thumb{width:44px;height:44px;flex:0 0 44px;border-radius:6px;border:1px solid var(--line);overflow:hidden;background:var(--surface-overlay)}
.proof .meta{flex:1 1 auto;min-width:0}
.proof .meta .n{font-size:12.5px;color:var(--text-body);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.proof .meta .s{font-size:11px;color:var(--text-faint);font-family:var(--font-mono)}

/* 成员搜索选择器（三千多名 KOOK 成员里搜人） */
.picker{position:relative;width:340px}
.picker-input{display:flex;align-items:center;gap:8px;border:1px solid var(--line-strong);border-radius:6px;background:var(--surface-page);height:32px;padding:0 10px}
/* 光晕跟真实焦点走。原来是无条件常亮的，意图是「这一步该你填」，但一个没
   有焦点却长得像有焦点的输入框，是在骗用户键盘会去哪 —— 提现页把它和另外
   两个普通输入框竖着摆在一起之后，第一次就有人对着它打字打进了金额框。
   常亮的主色边框保留在 :focus-within 上，静息态退回普通描边 */
.picker-input:focus-within{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-softer)}
.picker-input .ico{color:var(--text-faint);flex:0 0 14px}
.picker-input input{flex:1 1 auto;background:none;border:0;outline:0;color:var(--text-title);font-family:inherit;font-size:13px;min-width:0}
.picker-menu{margin-top:4px;background:var(--surface-overlay);border:1px solid var(--line-strong);border-radius:var(--r-ctl);box-shadow:var(--shadow-overlay);overflow:hidden}
.picker-status{padding:7px 11px;font-size:11.5px;color:var(--text-faint);border-bottom:1px solid var(--line);display:flex;align-items:center;gap:6px}
.picker-opt{display:flex;align-items:center;gap:9px;padding:7px 11px;cursor:pointer}
.picker-opt .av{width:26px;height:26px;border-radius:50%;flex:0 0 26px;object-fit:cover;background:var(--surface-panel)}
.picker-opt .nm{font-size:13px;color:var(--text-body);flex:1 1 auto;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.picker-opt .id{font-family:var(--font-mono);font-size:11px;color:var(--text-faint)}
.picker-opt.is-cursor{background:var(--primary-soft)}
.picker-opt.is-cursor .nm{color:var(--text-title)}
.picker-foot{padding:6px 11px;border-top:1px solid var(--line);font-size:11px;color:var(--text-faint);display:flex;gap:12px}
.kbd{font-family:var(--font-mono);font-size:10px;border:1px solid var(--line-strong);border-bottom-width:2px;border-radius:3px;padding:0 4px;color:var(--text-muted);background:rgba(255,255,255,.04)}

/* ── §8 浮层 ─────────────────────────────────────────────────────────────── */
.drawer{width:600px;background:var(--surface-overlay);border-left:1px solid var(--line-strong);box-shadow:var(--shadow-overlay);display:flex;flex-direction:column;min-height:0}
.drawer-head{padding:13px 16px;border-bottom:1px solid var(--line);display:flex;align-items:flex-start;gap:12px}
.drawer-head .t{flex:1 1 auto;min-width:0}
.drawer-head h2{margin:0;font-size:14px;font-weight:600;color:var(--text-title);display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.drawer-head .sub{font-size:11.5px;color:var(--text-faint);margin-top:3px;font-family:var(--font-mono)}
.drawer-body{flex:1 1 auto;overflow:auto;padding:16px;display:flex;flex-direction:column;gap:16px;min-height:0}
.drawer-body > *{flex:0 0 auto}
.drawer-foot{padding:12px 16px;border-top:1px solid var(--line);background:var(--surface-overlay)}
.dsec{border:1px solid var(--line);border-radius:var(--r-ctl);background:var(--surface-panel);overflow:hidden}
.dsec-head{padding:9px 13px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:8px;background:var(--surface-raise)}
.dsec-head h3{margin:0;font-size:13px;font-weight:600;color:var(--text-title)}
.dsec-head .n{font-family:var(--font-mono);font-size:11px;color:var(--text-faint)}
.dsec-head .grow{flex:1 1 auto}
.dsec-body{padding:13px}

.modal-scrim{background:rgba(8,9,11,.66);padding:60px 24px;display:flex;justify-content:center;align-items:flex-start}
.modal{width:460px;background:var(--surface-overlay);border:1px solid var(--line-strong);border-radius:var(--r-modal);box-shadow:var(--shadow-overlay);overflow:hidden}
.modal-head{padding:15px 18px 0}
.modal-head h2{margin:0;font-size:15px;font-weight:600;color:var(--text-title)}
.modal-head p{margin:6px 0 0;font-size:13px;color:var(--text-muted);line-height:1.7}
.modal-body{padding:14px 18px}
.modal-foot{padding:12px 18px;display:flex;gap:8px;justify-content:flex-end;border-top:1px solid var(--line);margin-top:4px}
.confirm-list{border:1px solid var(--line);border-radius:var(--r-ctl);background:var(--surface-page);overflow:hidden}
.confirm-list .r{display:flex;align-items:center;gap:12px;padding:9px 12px;border-top:1px solid var(--line-faint);font-size:13px}
.confirm-list .r:first-child{border-top:0}
.confirm-list .k{color:var(--text-faint);font-size:12px;flex:0 0 72px}
.confirm-list .v{color:var(--text-title);flex:1 1 auto;min-width:0}

.toast{display:flex;align-items:flex-start;gap:10px;background:var(--surface-overlay);border:1px solid var(--line-strong);border-radius:var(--r-ctl);box-shadow:var(--shadow-overlay);padding:11px 13px;width:344px}
.toast .ico{flex:0 0 16px;margin-top:1px}
.toast--ok .ico{color:var(--st-ok)}
.toast--fail .ico{color:var(--st-alert)}
.toast--warn .ico{color:var(--primary)}
.toast .bd{flex:1 1 auto;min-width:0}
.toast .bd b{display:block;font-size:13px;font-weight:600;color:var(--text-title)}
.toast .bd span{display:block;font-size:12px;color:var(--text-muted);margin-top:2px;line-height:1.6}

/* ── §9 时间线 ───────────────────────────────────────────────────────────── */
.timeline{display:flex;flex-direction:column}
.tl{display:grid;grid-template-columns:78px 15px 1fr;gap:0 10px;padding-bottom:14px;position:relative}
.tl:last-child{padding-bottom:0}
.tl .when{font-family:var(--font-mono);font-size:11px;color:var(--text-faint);text-align:right;padding-top:1px;white-space:nowrap}
.tl .rail{display:flex;flex-direction:column;align-items:center}
.tl .node{width:9px;height:9px;border-radius:50%;background:var(--surface-panel);border:2px solid var(--st-done);margin-top:4px;flex:0 0 auto}
.tl .line{width:1px;flex:1 1 auto;background:var(--line);margin-top:3px}
.tl:last-child .line{display:none}
.tl.is-ok .node{border-color:var(--st-ok)}
.tl.is-alert .node{border-color:var(--st-alert)}
.tl.is-now .node{border-color:var(--primary);background:var(--primary)}
.tl .what{padding-bottom:2px;min-width:0}
.tl .what .h{font-size:13px;color:var(--text-body);display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.tl .what .h b{color:var(--text-title);font-weight:600}
.tl .what .r{font-size:11.5px;color:var(--text-faint);margin-top:2px;line-height:1.65;white-space:normal}
.by{display:inline-flex;align-items:center;font-size:10.5px;padding:0 5px;border-radius:3px;background:rgba(255,255,255,.055);color:var(--text-muted);white-space:nowrap}
.by--sys{color:var(--text-faint)}
.by--boss{color:var(--st-decide);background:rgba(91,156,216,.1)}
.by--mate{color:var(--st-ok);background:rgba(79,183,132,.1)}
.by--staff{color:var(--primary);background:var(--primary-softer)}

/* ── §10 金额构成展开块 ─────────────────────────────────────────────────── */
.calc{border:1px solid var(--line);border-radius:var(--r-ctl);background:var(--surface-page);overflow:hidden}
.calc-sum{display:flex;align-items:center;gap:10px;padding:10px 13px;cursor:pointer;list-style:none}
.calc-sum::-webkit-details-marker{display:none}
.calc-sum .caret{color:var(--text-faint);font-size:9px;transition:transform .15s;flex:0 0 auto}
.calc[open] .calc-sum .caret{transform:rotate(90deg)}
.calc-sum .t{flex:1 1 auto;font-size:13px;color:var(--text-body)}
.calc-sum .t b{color:var(--text-title);font-weight:600}
.calc-sum .v{font-size:15px;font-weight:600;color:var(--text-title);font-variant-numeric:tabular-nums}
.calc-steps{border-top:1px solid var(--line);padding:4px 0 6px;background:rgba(0,0,0,.16)}
.cstep{display:grid;grid-template-columns:1fr auto;gap:14px;padding:5px 13px 5px 30px;font-size:12.5px;color:var(--text-muted);position:relative;line-height:1.7}
.cstep::before{content:"";position:absolute;left:19px;top:14px;width:4px;height:4px;border-radius:50%;background:var(--line-strong)}
.cstep .n{font-variant-numeric:tabular-nums;color:var(--text-body);white-space:nowrap}
.cstep--minus .n{color:var(--st-ok)}
.cstep--plus .n{color:var(--text-body)}
.cstep--neg .n{color:var(--st-alert)}
.cstep--note{color:var(--text-faint);font-size:11.5px}
.cstep--total{border-top:1px solid var(--line);margin-top:4px;padding-top:9px;padding-bottom:9px;color:var(--text-title);font-weight:600;font-size:13px}
.cstep--total::before{display:none}
.cstep--total .n{color:var(--primary);font-size:15px;font-weight:600}

/* ── §11 单值卡 / 图表 ──────────────────────────────────────────────────── */
.kpi{background:var(--surface-panel);border:1px solid var(--line);border-radius:var(--r-ctl);padding:13px 15px;display:flex;flex-direction:column;gap:3px;min-width:0}
.kpi .k{font-size:12px;color:var(--text-muted);white-space:nowrap}
.kpi .v{font-family:var(--font-mono);font-size:25px;font-weight:600;color:var(--text-title);letter-spacing:-.02em;font-variant-numeric:tabular-nums;line-height:1.25}
.kpi .d{font-size:11.5px;display:flex;align-items:center;gap:4px;color:var(--text-faint);min-height:19px}
.kpi .d.up{color:var(--st-ok)}
.kpi .d.down{color:var(--st-alert)}
.chart{position:relative}
.chart-tip{position:absolute;min-width:194px;background:var(--surface-overlay);border:1px solid var(--line-strong);border-radius:var(--r-ctl);box-shadow:var(--shadow-overlay);padding:9px 11px}
.chart-tip .when{font-size:12px;font-weight:600;color:var(--text-title);margin-bottom:6px}
.chart-tip .r{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--text-muted);padding:2px 0}
.chart-tip .r .cw{width:10px;height:2px;border-radius:2px;flex:0 0 10px;display:inline-block}
.chart-tip .r .nm{flex:1 1 auto}
.chart-tip .r .n{font-family:var(--font-mono);font-size:12px;color:var(--text-title);font-variant-numeric:tabular-nums}
.tip-a{left:636px;top:16px}
.swb-a{background:#D69A55}.swb-b{background:#5B9CD8}.swb-n{background:#62666E}
.legend{display:flex;justify-content:center;gap:22px;font-size:11px;color:var(--text-muted);padding-top:10px;flex-wrap:wrap}
.legend .i{display:flex;align-items:center;gap:6px}
.legend .i .cw{width:10px;height:2px;border-radius:2px;display:inline-block}
.legend .i b{color:var(--text-body);font-weight:500;font-family:var(--font-mono);font-size:11px}
.axis{display:flex;justify-content:space-between;font-family:var(--font-mono);font-size:10.5px;color:var(--text-faint);padding:6px 0 0}

/* 横向排行条 */
.rank{display:flex;flex-direction:column;gap:0}
.rankrow{display:grid;grid-template-columns:196px 1fr 104px;gap:12px;align-items:center;padding:6px 0}
.rankrow .who{display:flex;align-items:center;gap:7px;min-width:0;padding:0;border-radius:0;cursor:default}
.rankrow .who:hover{background:none}
.rankrow .who .av{width:20px;height:20px;flex:0 0 20px;border-radius:50%;object-fit:cover;background:var(--surface-overlay)}
.rankrow .who .nm{font-size:12.5px;color:var(--text-body);white-space:normal;overflow:visible;text-overflow:clip;line-height:1.4}
.rankbar{height:7px;border-radius:4px;background:rgba(255,255,255,.045);overflow:hidden}
.rankbar .fill{height:100%;border-radius:4px;background:linear-gradient(90deg,var(--primary),rgba(214,154,85,.28))}
.rankrow .n{font-family:var(--font-mono);font-size:12.5px;color:var(--text-body);text-align:right;font-variant-numeric:tabular-nums}
.w100{width:100%}.w92{width:92%}.w83{width:83%}.w76{width:76%}.w64{width:64%}.w58{width:58%}.w51{width:51%}.w44{width:44%}.w37{width:37%}.w31{width:31%}.w26{width:26%}.w18{width:18%}.w12{width:12%}

/* ── §12 价格矩阵 ───────────────────────────────────────────────────────── */
.matrix{border-collapse:separate;border-spacing:0;width:auto}
.matrix th,.matrix td{border:1px solid var(--line-faint);padding:0;height:42px;min-width:104px;text-align:center;white-space:nowrap}
.matrix thead th{background:var(--surface-raise);font-size:12px;font-weight:500;color:var(--text-muted);padding:0 14px;border-color:var(--line)}
.matrix tbody th{background:var(--surface-raise);font-size:13px;font-weight:500;color:var(--text-body);text-align:left;padding:0 14px;min-width:96px;border-color:var(--line)}
.matrix thead th:first-child{background:var(--surface-panel)}
.cellbtn{width:100%;height:100%;border:0;background:none;font-family:var(--font-mono);font-size:14px;color:var(--text-title);cursor:pointer;font-variant-numeric:tabular-nums;display:flex;align-items:center;justify-content:center;gap:2px;padding:0}
.cellbtn .cur{font-size:11px;color:var(--text-faint);font-family:var(--font)}
.cellbtn:hover{background:var(--primary-softer);box-shadow:inset 0 0 0 1px var(--primary)}
.cell-empty .cellbtn{color:var(--text-faint);font-size:16px;font-weight:300}
.cell-empty{background:repeating-linear-gradient(135deg,transparent,transparent 5px,rgba(255,255,255,.022) 5px,rgba(255,255,255,.022) 10px)}
.cell-na{background:rgba(224,104,95,.05)}
.cell-na .cellbtn{color:rgba(224,104,95,.72);font-size:13px}
.cell-edit{box-shadow:inset 0 0 0 2px var(--primary);background:var(--surface-page);position:relative}
.cell-edit input{width:100%;height:100%;border:0;background:none;outline:0;text-align:center;font-family:var(--font-mono);font-size:14px;color:var(--text-title)}
.cellmenu{background:var(--surface-overlay);border:1px solid var(--line-strong);border-radius:var(--r-ctl);box-shadow:var(--shadow-overlay);padding:4px;width:168px}
.cellmenu .mi{display:flex;align-items:center;gap:8px;padding:6px 9px;border-radius:5px;font-size:12.5px;color:var(--text-body);cursor:pointer}
.cellmenu .mi:hover{background:rgba(255,255,255,.06)}
.cellmenu .mi.is-danger{color:var(--st-alert)}
.matrix-note{display:flex;align-items:center;gap:8px;padding:9px 13px;border-radius:var(--r-ctl);background:var(--primary-softer);border:1px solid rgba(214,154,85,.26);font-size:12.5px;color:var(--text-body)}
.matrix-note .ico{color:var(--primary);flex:0 0 15px}
.legend-cells{display:flex;gap:16px;flex-wrap:wrap;font-size:12px;color:var(--text-muted)}
.legend-cells .i{display:flex;align-items:center;gap:7px}
.legend-cells .box{width:30px;height:20px;border:1px solid var(--line);border-radius:4px}

/* ── §13 杂项 ───────────────────────────────────────────────────────────── */
.kv{display:grid;grid-template-columns:auto 1fr;gap:8px 16px;font-size:13px;align-items:baseline}
.kv dt{color:var(--text-faint);font-size:12px;white-space:nowrap}
.kv dd{margin:0;color:var(--text-body)}
.deflist{display:flex;flex-direction:column;gap:0}
.deflist .r{display:flex;align-items:baseline;justify-content:space-between;gap:16px;padding:8px 0;border-top:1px solid var(--line-faint);font-size:13px}
.deflist .r:first-child{border-top:0}
.deflist .r .k{color:var(--text-muted);font-size:12.5px}
.deflist .r .v{color:var(--text-title);text-align:right}
.bigav{width:56px;height:56px;border-radius:50%;flex:0 0 56px;object-fit:cover;background:var(--surface-overlay);border:1px solid var(--line)}
.progress{height:5px;border-radius:3px;background:rgba(255,255,255,.06);overflow:hidden}
.progress .fill{height:100%;background:var(--primary);border-radius:3px}
.tabs{display:flex;gap:2px;border-bottom:1px solid var(--line)}
.tab{padding:8px 12px;font-size:13px;color:var(--text-muted);cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px;white-space:nowrap}
.tab:hover{color:var(--text-body)}
.tab.is-on{color:var(--text-title);border-bottom-color:var(--primary);font-weight:500}
.voucher{display:flex;align-items:center;gap:11px;padding:9px 11px;border:1px solid var(--line);border-radius:var(--r-ctl);background:var(--surface-page)}
.voucher .face{font-family:var(--font-mono);font-size:16px;font-weight:600;color:var(--primary);flex:0 0 auto;min-width:62px}
.voucher.is-used,.voucher.is-expired{opacity:.5}
.voucher.is-used .face,.voucher.is-expired .face{color:var(--text-muted)}
.voucher .m{flex:1 1 auto;min-width:0}
.voucher .m .a{font-size:12.5px;color:var(--text-body)}
.voucher .m .b{font-size:11px;color:var(--text-faint);font-family:var(--font-mono)}
.frozen{display:flex;align-items:baseline;gap:8px;padding:9px 11px;border-radius:var(--r-ctl);background:rgba(91,156,216,.07);border:1px solid rgba(91,156,216,.22)}
.frozen .k{font-size:12px;color:var(--st-decide);white-space:nowrap}
.frozen .v{font-family:var(--font-mono);font-size:16px;font-weight:600;color:var(--st-decide);font-variant-numeric:tabular-nums}
.frozen .why{font-size:11.5px;color:var(--text-muted);flex:1 1 100%;line-height:1.6}
.hr{height:1px;background:var(--line);border:0;margin:0}
.hr--faint{background:var(--line-faint)}

/* 登录页 */
.login{min-height:820px;display:flex;align-items:center;justify-content:center;background:var(--surface-page);padding:40px}
.login-card{width:372px;display:flex;flex-direction:column;gap:20px}
.login-brand{display:flex;flex-direction:column;gap:9px;align-items:flex-start}
.login-brand .mk{width:34px;height:34px;border-radius:9px;background:var(--primary-soft);color:var(--primary);display:flex;align-items:center;justify-content:center}
.login-brand h1{margin:0;font-size:18px;font-weight:600;color:var(--text-title)}
.login-brand p{margin:0;font-size:12.5px;color:var(--text-muted)}
.login-box{background:var(--surface-panel);border:1px solid var(--line);border-radius:var(--r-ctl);padding:20px;display:flex;flex-direction:column;gap:14px}
.login-foot{font-size:11px;color:var(--text-faint);text-align:center;line-height:1.7}
.lockout{display:flex;flex-direction:column;gap:6px;padding:11px 13px;border-radius:var(--r-ctl);background:rgba(224,104,95,.09);border:1px solid rgba(224,104,95,.3)}
.lockout .h{display:flex;align-items:center;gap:7px;font-size:13px;font-weight:600;color:var(--st-alert)}
.lockout .b{font-size:12.5px;color:var(--text-body);line-height:1.7}
.lockout .c{font-family:var(--font-mono);font-size:20px;font-weight:600;color:var(--st-alert);font-variant-numeric:tabular-nums;letter-spacing:.02em}

/* 工作台待办卡 */
.todo{background:var(--surface-panel);border:1px solid var(--line);border-radius:var(--r-ctl);display:flex;flex-direction:column;overflow:hidden;min-width:0}
.todo-head{display:flex;align-items:center;gap:9px;padding:11px 13px 9px}
.todo-head .n{font-family:var(--font-mono);font-size:24px;font-weight:600;color:var(--text-title);line-height:1;font-variant-numeric:tabular-nums}
.todo-head .t{flex:1 1 auto;min-width:0}
/* display:block —— 原来这两行只是靠「装不下就换行」才叠成两行的，卡片一宽
   就会并成一行读作「待审核订单受理维度 pending」；overflow 是因为 nowrap 不
   收边，一句长一点的副标题（「接单 10 分钟没打点，或超时 10 分钟没结束」）
   会直接淌出卡片。两条都是浏览器里看出来的 */
.todo-head .t .a{display:block;font-size:13px;font-weight:600;color:var(--text-body);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.todo-head .t .b{display:block;font-size:11px;color:var(--text-faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.todo.is-urgent{border-color:rgba(214,154,85,.34)}
.todo.is-urgent .todo-head .n{color:var(--primary)}
.todo.is-alert{border-color:rgba(224,104,95,.3)}
.todo.is-alert .todo-head .n{color:var(--st-alert)}
.todo.is-clear .todo-head .n{color:var(--text-faint)}
.todo-list{border-top:1px solid var(--line-faint);display:flex;flex-direction:column}
.todo-item{display:flex;align-items:center;gap:9px;padding:7px 13px;border-top:1px solid var(--line-faint);font-size:12.5px;cursor:pointer;min-width:0}
.todo-item:first-child{border-top:0}
.todo-item:hover{background:var(--row-hover)}
/* 产品侧加的：画布上每一行都点得进去，但整行卡的「合计」那一行没有去处，
   而一个有手型光标、有 hover、点了什么都不发生的行，读起来是坏的 */
.todo-item.is-static{cursor:default}
.todo-item.is-static:hover{background:transparent}
.todo-item .id{font-family:var(--font-mono);font-size:11px;color:var(--text-faint);flex:0 0 auto}
.todo-item .m{flex:1 1 auto;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--text-body)}
.todo-item .ago{font-family:var(--font-mono);font-size:10.5px;color:var(--text-faint);flex:0 0 auto}
.todo-more{padding:7px 13px;border-top:1px solid var(--line-faint);font-size:11.5px;color:var(--text-muted);cursor:pointer;display:flex;align-items:center;justify-content:space-between}
.todo-more:hover{background:var(--row-hover);color:var(--text-body)}
.todo-empty{padding:14px 13px;border-top:1px solid var(--line-faint);font-size:12px;color:var(--text-faint);display:flex;align-items:center;gap:7px}

/* 加款日报 */
.daily-flag{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:500;padding:1px 7px;border-radius:var(--r-sm);background:var(--st-alert-soft);color:var(--st-alert);border:1px solid rgba(224,104,95,.28);white-space:nowrap}
.daily-flag--warn{background:var(--primary-soft);color:var(--primary);border-color:rgba(214,154,85,.28)}
.agentbar{display:grid;grid-template-columns:110px 1fr 130px;gap:12px;align-items:center;padding:7px 0;border-top:1px solid var(--line-faint)}
.agentbar:first-child{border-top:0}
.agentbar .nm{font-size:13px;color:var(--text-body);display:flex;align-items:center;gap:7px;min-width:0}
.agentbar .nm .av{width:20px;height:20px;border-radius:50%;flex:0 0 20px;object-fit:cover;background:var(--surface-overlay)}
.agentbar .amt{text-align:right;font-family:var(--font-mono);font-size:13px}
.agentbar .cnt{font-size:11px;color:var(--text-faint);font-family:var(--font-mono)}
.stackbar{height:8px;border-radius:4px;background:rgba(255,255,255,.045);overflow:hidden;display:flex}
.stackbar .seg{height:100%}
.seg--a{background:var(--primary)}
.seg--b{background:rgba(214,154,85,.55)}
.seg--c{background:rgba(214,154,85,.3)}
.proof-thumb{width:34px;height:24px;border-radius:4px;border:1px solid var(--line);object-fit:cover;background:var(--surface-overlay);display:block}
.avg-cmp{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.avg-cmp .big{font-family:var(--font-mono);font-size:28px;font-weight:600;color:var(--text-title);letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.spark{display:flex;align-items:flex-end;gap:4px;height:44px}
.sparkwrap{width:156px;flex:0 0 156px}
.spark .b{width:16px;border-radius:3px 3px 0 0;background:rgba(255,255,255,.09)}
.spark .b.is-today{background:var(--primary)}
.spark .b.is-avg{background:rgba(255,255,255,.16)}
.h44{height:44px}.h38{height:38px}.h30{height:30px}.h26{height:26px}.h22{height:22px}.h19{height:19px}.h16{height:16px}.h13{height:13px}.h11{height:11px}

/* ── §14 图标 / 图表画布 / 工作台栅格 ───────────────────────────────────── */
.sprite{position:absolute;width:0;height:0;overflow:hidden;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.sprite symbol{fill:none;stroke:currentColor}
.ico{width:15px;height:15px;flex:0 0 auto;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;display:block}
.ico--14{width:14px;height:14px}
.ico--16{width:16px;height:16px}
.ico--18{width:18px;height:18px}
.ico--20{width:20px;height:20px}
.ico--44{width:44px;height:44px;stroke-width:1.1}
.chartsvg{display:block;width:100%;height:190px}
.todo-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;align-items:start}
.todo--wide{grid-column:span 4}
.todo--wide .todo-list{display:grid;grid-template-columns:1fr 1fr}
.todo--wide .todo-item:nth-child(2){border-top:0}
.todo--wide .todo-item:nth-child(even){border-left:1px solid var(--line-faint)}
.hole{border:1px dashed rgba(224,104,95,.4);border-radius:var(--r-ctl);background:repeating-linear-gradient(135deg,transparent,transparent 6px,rgba(224,104,95,.05) 6px,rgba(224,104,95,.05) 12px);display:flex;align-items:center;justify-content:center;text-align:center;padding:16px;font-size:11.5px;color:rgba(224,104,95,.75);line-height:1.6;min-height:104px}

/* 头像：无外链图片，用底色 + 首字 */
.av{display:inline-flex;align-items:center;justify-content:center;font-size:10px;font-weight:600;color:rgba(255,255,255,.78);background:#34373D;letter-spacing:0;line-height:1;overflow:hidden;font-family:var(--font)}
.bigav{display:inline-flex;align-items:center;justify-content:center;font-size:20px;font-weight:600;color:rgba(255,255,255,.8)}
.av--a{background:#4A3B57}.av--b{background:#2F4A46}.av--c{background:#503B33}.av--d{background:#334458}.av--e{background:#4C3A3A}.av--f{background:#3B4A34}.av--g{background:#453F30}.av--h{background:#38394F}
/* 凭证缩略图占位 */
.thumbimg{width:100%;height:100%;display:block;background:repeating-linear-gradient(135deg,#2A2D33,#2A2D33 4px,#32353C 4px,#32353C 8px)}

/* ── §15 里属于产品的那些（画布专用的已剔除）─────────────────────────── */
.nav-sep{height:1px;background:var(--line);margin:14px 8px 12px}
.foot-note{padding:14px 24px 0;font-size:11px;color:var(--text-faint);text-align:center}
.workarea{position:relative;flex:1 1 auto;display:flex;min-height:0;overflow:hidden}
.workarea > .scroll{flex:1 1 auto}
.drawer-scrim{position:absolute;top:0;right:0;bottom:0;left:0;background:rgba(8,9,11,.5);z-index:2}
.drawer-mount{position:absolute;top:0;right:0;bottom:0;display:flex;z-index:3}
.main{overflow:hidden}
.sticky-side{position:sticky;top:0}
.est{border:1px solid rgba(214,154,85,.3);background:linear-gradient(180deg,rgba(214,154,85,.07),transparent 120px);border-radius:var(--r-ctl);overflow:hidden}
.est-head{padding:11px 14px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:8px}
.est-head h3{margin:0;font-size:13px;font-weight:600;color:var(--text-title)}
.est-head .tagsrv{font-size:10.5px;font-family:var(--font-mono);color:var(--primary);border:1px solid rgba(214,154,85,.34);border-radius:3px;padding:0 5px;white-space:nowrap}
.est-body{padding:14px}
.est-total{display:flex;align-items:baseline;justify-content:space-between;gap:12px;padding-bottom:10px}
.est-total .k{font-size:12px;color:var(--text-muted)}
.est-total .v{font-family:var(--font-mono);font-size:26px;font-weight:600;color:var(--text-title);letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.balcheck{display:flex;flex-direction:column;gap:6px;padding:10px 12px;border-radius:var(--r-ctl);border:1px solid;font-size:12.5px;line-height:1.65}
.balcheck--ok{border-color:rgba(79,183,132,.28);background:rgba(79,183,132,.07);color:var(--text-body)}
.balcheck--bad{border-color:rgba(224,104,95,.34);background:rgba(224,104,95,.08);color:var(--text-body)}
.balcheck .h{display:flex;align-items:center;gap:7px;font-weight:600;font-size:13px}
.balcheck--ok .h{color:var(--st-ok)}
.balcheck--bad .h{color:var(--st-alert)}
.balcheck .gap{font-family:var(--font-mono);font-variant-numeric:tabular-nums}
.slotrow{display:grid;grid-template-columns:1fr auto;gap:8px 14px;padding:9px 0;border-top:1px solid var(--line-faint);font-size:12.5px}
.slotrow:first-child{border-top:0}
.slotrow .who{display:flex;align-items:center;gap:7px;padding:0;cursor:default}
.slotrow .who:hover{background:none}
.slotrow .times{font-family:var(--font-mono);font-size:12px;color:var(--text-muted);white-space:nowrap}
.slotrow .meta{grid-column:1 / -1;font-size:11.5px;color:var(--text-faint);line-height:1.6}
.actgrid{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.actitem{display:flex;flex-direction:column;gap:3px}
.actitem .why{font-size:11px;color:var(--text-faint);line-height:1.55}
.limitcard{border:1px solid rgba(91,156,216,.28);background:rgba(91,156,216,.06);border-radius:var(--r-ctl);padding:11px 13px;display:flex;flex-direction:column;gap:8px}
.limitcard .h{font-size:13px;font-weight:600;color:var(--st-decide);display:flex;align-items:center;gap:7px}
.limitcard .o{display:flex;align-items:center;gap:9px;font-size:12.5px;padding:6px 9px;border-radius:6px;background:rgba(0,0,0,.2)}
.limitcard .o .mono{flex:0 0 auto}
.limitcard .o .m{flex:1 1 auto;min-width:0;color:var(--text-body)}
.step-h{display:flex;align-items:center;gap:9px;margin-bottom:2px}
.step-n{width:19px;height:19px;flex:0 0 19px;border-radius:50%;background:var(--primary-soft);color:var(--primary);font-family:var(--font-mono);font-size:11px;display:flex;align-items:center;justify-content:center;font-weight:600}
.step-h h3{margin:0;font-size:13px;font-weight:600;color:var(--text-title)}
.step-h .s{font-size:11.5px;color:var(--text-faint)}
.profile-head{display:flex;gap:16px;align-items:flex-start;padding:16px}
.profile-head .id{display:flex;flex-direction:column;gap:5px;min-width:0}
.profile-head h2{margin:0;font-size:18px;font-weight:600;color:var(--text-title);display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.profile-head .kook{font-family:var(--font-mono);font-size:12px;color:var(--text-faint)}
.lvnext{display:flex;flex-direction:column;gap:5px;min-width:260px}
.lvnext .t{display:flex;justify-content:space-between;font-size:11.5px;color:var(--text-muted)}
.lvnext .t b{color:var(--text-body);font-family:var(--font-mono);font-variant-numeric:tabular-nums}
.moneyrow{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);border-top:1px solid var(--line)}
.moneyrow .c{background:var(--surface-panel);padding:13px 16px;display:flex;flex-direction:column;gap:3px}
.moneyrow .c .k{font-size:12px;color:var(--text-muted)}
.moneyrow .c .v{font-family:var(--font-mono);font-size:20px;font-weight:600;letter-spacing:-.01em;font-variant-numeric:tabular-nums;color:var(--text-title)}
.moneyrow .c .s{font-size:11px;color:var(--text-faint);line-height:1.55}
.moneyrow .c--frozen .v{color:var(--st-decide)}
/* 三格：稿子第四格是代金券，会员域没做之前不画它 —— 少一格，其余三格摊开，
   不留一块空着的位置（空格子读作「这里是 0」） */
.moneyrow--3{grid-template-columns:repeat(3,1fr)}
.matrix-wrap{padding:14px;overflow-x:auto}
.dayhead{display:grid;grid-template-columns:1fr auto;gap:16px;align-items:center}
.flagbox{display:flex;flex-direction:column;gap:8px}
.flagline{display:flex;align-items:flex-start;gap:9px;padding:9px 11px;border-radius:var(--r-ctl);border:1px solid rgba(224,104,95,.26);background:rgba(224,104,95,.06);font-size:12.5px;line-height:1.65;color:var(--text-body)}
.flagline .ico{flex:0 0 15px;margin-top:2px;color:var(--st-alert)}
.flagline b{color:var(--text-title);font-weight:600}
.flagline--warn{border-color:rgba(214,154,85,.26);background:rgba(214,154,85,.06)}
.flagline--warn .ico{color:var(--primary)}
tr.is-flagged td{background:rgba(224,104,95,.05)}
tr.is-flagged:hover td{background:rgba(224,104,95,.08)}

/* ── §16 落地调整（设计稿里没有，因为画布不需要）────────────────────── */
/* 画布上外壳是一张固定高度的图；真页面要占满视口，内容区自己滚 */
.shell{min-height:100vh;height:100vh}
.login{min-height:100vh}
/* 设计稿里没有「先藏起来、由 JS 打开」的块，所以没人碰过这条。
   浏览器给 [hidden] 的是 display:none，但那是 UA 样式表里的规则，
   .lockout{display:flex} 这种类选择器优先级更高，直接把它盖掉 ——
   结果是锁定框和错误提示在正常登录页上一直露着 */
[hidden]{display:none !important}
/* 页头右边那排控件要一样高。稿子把 .iconbtn 画成 30、.btn--sm 26、.input 32，
   三个值分开看都对 —— 但画布上这三样从没出现在同一行里，日报页的「‹ 日期 ›
   导出」正是三样并排，于是一行里出现三个高度。统一到 32（.input / .btn 的
   默认高），顺带让各页页头的按钮互相也一样高 */
.head-actions .iconbtn{width:32px;height:32px}
.head-actions .btn--sm{height:32px;font-size:13px;padding:0 13px;border-radius:6px}
.head-actions .btn--sm .ico{flex:0 0 14px}

/* 顶栏不许被压扁。它是 .main 这个纵向 flex 容器的子项，默认 flex-shrink:1，
   于是内容一多就被挤矮 —— 实测价格配置页上它只剩 36.3px 而不是 --topbar-h
   的 46px。表现是：顶栏底下那条线跟侧栏 .brand 底下那条对不齐，而且**只在
   内容够长的页面上对不齐**（工作台内容短，看着是好的），所以很容易被当成
   某一页自己的毛病。.brand 早就写了 flex:0 0 auto，这里补上同一条 */
.topbar{flex:0 0 auto}
/* 侧栏里还没做的页面：画出来但明显点不动。藏起来会让人以为功能没规划，
   画成正常项则会让人点了没反应 —— 两种都比压暗更糟 */
.nav-item.is-soon{opacity:.42;cursor:default}
.nav-item.is-soon:hover{background:none;color:var(--text-muted)}
/* 侧栏 <a> 继承了 a{color:var(--primary)}，导航项的颜色得由 .nav-item 说了算 */
a.nav-item,a.nav-item:hover{text-decoration:none}
a.nav-item{color:var(--text-muted)}
a.nav-item:hover{color:var(--text-body)}
a.nav-item.is-active,a.nav-item.is-active:hover{color:var(--primary)}
/* 稿子里 .grow 是「把右边那堆推过去」的通用件，但只给三个父级定义了规则
   （.page-head / .panel-head / .dsec-head）—— 画布上其它几处凑巧不靠它对齐，
   所以缺了也看不出来。抽屉页脚要靠它把「停用」推到右边，补一条全局的；
   上面三条留着不动，删了会让稿子 diff 多出三行噪音 */
.grow{flex:1 1 auto}
/* .panel-head 有 .sub，.dsec-head 没有 —— 稿子在抽屉小节标题上用的是 §0 的
   .ts-11 字阶类，那一批是画布专用、搬运时整批丢掉的 */
.dsec-head .sub{font-size:11.5px;color:var(--text-faint)}
/* 抽屉：画布上它是一张贴着右边画好的图，真页面要从右边滑进来。
   .workarea 是定位参照（外壳 fragment 里），遮罩只盖内容区 */
.drawer-mount{animation:drawer-in .16s ease}
@keyframes drawer-in{
  from{transform:translateX(16px);opacity:.4}
  to{transform:none;opacity:1}
}
/* 表格里的操作列：按钮之间别换行，一行 26px 高的两个按钮撑不破行高 */
.table td .row--tight{flex-wrap:nowrap}
/* 成员选择器：稿子里这张菜单只画了 4 行，真搜起来一次回 30 个人。不封高度
   它会把抽屉里下面的表单整个顶出屏幕 —— 所以行单独一列自己滚，搜索结果计数
   和键盘提示钉在上下两头不动（跟 §17 的 .dd-menu 同一套做法）*/
.picker-menu{display:flex;flex-direction:column;max-height:288px}
.picker-menu .picker-status,.picker-menu .picker-foot{flex:0 0 auto}
.picker-list{overflow-y:auto;min-height:0}
/* 二次确认弹层：稿子给了 .modal-scrim 的底色和内边距，但没给定位 ——
   画布上它是画在框里的一张图，不需要浮起来。跟抽屉同一套：相对 .workarea
   绝对定位，只盖内容区，层级压在抽屉之上（加款页确认时抽屉不开，但两者将来
   会在同一个页面上，先把顺序定下来） */
.modal-scrim{position:absolute;top:0;right:0;bottom:0;left:0;z-index:4}
/* 稿子 §0 的字阶类，搬运时整批当成画布专用丢掉了；加款页这两处要用：
   确认弹层里念金额的那一行，和选中老板那张卡的名字 */
/* .ts-11 也在这批里，而价格配置页、加款日报、建单页和订单抽屉一共用了它
   十来处 —— 缺这一条时它们不会报错，只是按父级字号渲染，比预期大 2px，
   看起来像「这几行字有点挤」而不像样式没生效 */
.ts-11{font-size:11px;color:var(--text-muted)}
.ts-12{font-size:12px;font-weight:500;color:var(--text-faint);line-height:1.5}
.ts-14b{font-size:14px;font-weight:600;color:var(--text-title);line-height:1.5}
/* 凭证缩略图是个按钮：点开看原图。稿子把它画成静态方块 */
button.proof-thumb{padding:0;cursor:pointer}
button.proof-thumb:hover{border-color:var(--primary)}
/* 原图弹层里的那张图。得是类不是 style=""：CSP 没有 unsafe-inline，
   内联样式属性一样被挡（11 §7），而被挡的表现是图片按原始像素铺出去 */
.proof-full{max-width:100%;display:block;border-radius:var(--r-sm);border:1px solid var(--line)}

/* 拖文件进上传框时的高亮。稿子只画了 .upload 的静止态和 .is-error（凭证还
   没传、提交被锁住的那个红态），没画拖拽中 —— 画布上没法拖。第一版落地图省
   事把 is-error 拿来当拖拽态用了，语义正好反：拖文件进来是正常操作，画成红
   的是错的。这一条跟 :hover 同一个视觉 */
.upload.is-over{border-color:var(--primary);background:var(--primary-softer)}

/* 稿子的 .modal 是 460px（二次确认那种）。改价历史是一张四列的表，
   460 里塞不下，加一档宽的 */
.modal--wide{width:680px}
.modal--wide .modal-body{max-height:52vh;overflow-y:auto}

/* 画布把 .cellmenu 画在一个示意面板里（03 §3 右下角那格），所以它只有长相
   没有定位 —— 真页面上它得跟着被点的格子浮出来。这里只补定位，长相一个字
   不动 */
.cellmenu{position:absolute;z-index:5}

/* 高矮不齐的卡片排两列。稿子的 .grid-2 是真网格，**行高由该行最高的一张决定**
   —— 会员配置那 12 张面板一条到三条权益不等，矮的那张底下就空出一大块。
   改成分栏流：面板按高度自己往下码，break-inside 保证一张不会被拆到两栏。
   代价是顺序从「一行两个」变成「先走完左栏再走右栏」，而一把梯子本来就该
   这么读 */
.cols-2{column-count:2;column-gap:16px}
.cols-2 > *{break-inside:avoid;margin-bottom:16px}

/* 两列定义表的左栏不折行。稿子的 .deflist 每一行都是短标签配短值，而会员权益
   那一栏的值是一整句「赠技术陪 1 小时 + 娱乐陪 1 小时（不要可折成 …）」——
   space-between 会把「人工权益」四个字挤成两行 */
.deflist .r .k{white-space:nowrap}

/* 待办卡做成链接。稿子画的是一张 div —— 画布上没有「点了会去哪」这件事，而
   一张写着「3 件事等着办」的卡片点不动是说不通的。跟 §16 里 .nav-item 那条
   同一个原因：<a> 会继承 a{color:var(--primary)}，得让 .todo 自己说了算 */
a.todo,a.todo:hover{text-decoration:none;color:inherit}
a.todo:hover{border-color:var(--line-strong)}

/* 竖着排的单选组。稿子的 .radiorow 是一条横向分段控件（width:fit-content、
   不换行），画布上单选出现的地方都只有两三个短选项。券不一样：一位老板名下
   可能有七八张，每一行还带着面额、事由和券号 —— 横着排一定溢出。
   **这一条是必须的，不是好看**：.opt 里那个真 <input type=radio> 靠
   `.radiorow .opt input` 那条规则铺满整格并透明化（§17），容器没有 .radiorow
   的话它就以系统原生单选钮的样子露出来，正是 §17 整节要消灭的东西 */
.radiorow--v{flex-direction:column;width:auto}
.radiorow--v .opt{height:auto;min-height:34px;padding:7px 11px;border-right:0;
  border-bottom:1px solid var(--line);white-space:normal}
.radiorow--v .opt:last-child{border-bottom:0}

/* 进度条的宽度。CSP 没有 unsafe-inline，宽度不能写在 style= 上（11 §7），
   而 §11 那把 .w* 是排行榜用的 13 个不等距展示值 —— 「还差多少到下一级」要的
   是一把等距的尺，5% 一档，够细也够短 */
.p0{width:0}.p5{width:5%}.p10{width:10%}.p15{width:15%}.p20{width:20%}
.p25{width:25%}.p30{width:30%}.p35{width:35%}.p40{width:40%}.p45{width:45%}
.p50{width:50%}.p55{width:55%}.p60{width:60%}.p65{width:65%}.p70{width:70%}
.p75{width:75%}.p80{width:80%}.p85{width:85%}.p90{width:90%}.p95{width:95%}
.p100{width:100%}

/* 定义表左栏里的那半句解释。稿子的 .deflist 每一行都是短标签配短值，所以 §16
   上面那条给 .k 加了 nowrap —— 而报表页「促销成本」那四行每一行都得带自己的
   判据（「这笔钱是陪玩出的，不是店里的成本」那种），不带的话四个数字会被当成
   同一类东西加起来。只在 .k 里的 .sub 上把 nowrap 收回来 */
.deflist .r .k .sub{
  display:block;white-space:normal;
  font-size:11.5px;color:var(--text-faint);line-height:1.55;margin-top:2px;max-width:52ch;
}
/* 带解释的行不再是一行两端对齐，值要跟标签的首行对齐 */
.deflist .r:has(.k .sub){align-items:flex-start}

/* 表格的合计行。稿子里一张带合计的表都没有 —— 而账务页那张账户余额表的最后
   一行是**整套账本的验收标准**：全部账户加总必须是 ￥0.00（06 §3）。它得比
   数据行重，又不能重到看起来像另一个表头，所以：上面一条实线断开，底色跟表头
   同一档，字用正文色 */
.table tfoot td{
  border-top:1px solid var(--line);
  background:var(--surface-raise);
  font-size:13px;font-weight:600;color:var(--text-title);
  padding:11px 14px;white-space:nowrap;
}
.table tfoot td .sub{font-weight:400}
/* 操作列钉死的那张表（加款日报），最后一格的底色由 .table--fixedact 说了算，
   优先级比上面那条高 —— 不补这一句，合计行末尾会露出一块跟本行不同的底 */
.table--fixedact tfoot td:last-child{background:var(--surface-raise)}

/* Toast 摞在哪儿。稿子把三个变体并排摆在一块面板里 —— 画布只需要交代长相，
   不需要交代它从哪儿冒出来（跟上面 .cellmenu 一样的情况）。这里只补容器，
   .toast 本身一个字不动。

   层级压过 .dd-menu 的 200：下拉开着的时候点保存是很常见的一串动作，而
   「保存失败」被那张菜单盖住就等于没弹。容器本身 pointer-events:none，
   不然右下角那一块屏幕会在没有 Toast 的时候也点不动 */
.toast-stack{
  position:fixed;right:20px;bottom:20px;z-index:300;
  display:flex;flex-direction:column;gap:10px;pointer-events:none;
}
.toast-stack .toast{pointer-events:auto;animation:toast-in .16s ease}
@keyframes toast-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
/* .toast .ico 那条（16px + margin-top:1px）是给左边那个状态图标写的，可它比
   §6 的 .btn .ico 靠后，于是也套到了右边关闭按钮里那个 14px 的叉上 */
.toast .btn .ico{flex:0 0 14px;margin-top:0}

/* 审计详情弹层。二次确认那种弹层只放一句话，这一个放的是一整行审计 ——
   User-Agent 一行两百个字符是常事，details 的形状又因动作而异，两样都不能截。
   .modal-scrim 是 position:absolute（§8 上面那条注释），不跟着页面滚，所以高度
   必须由弹层自己收住，不然超出视口的那一截谁也够不着 */
.modal--wide{width:560px}
.modal--wide .modal-body{max-height:min(64vh,520px);overflow:auto}

/* details 原样摆出来：这一列每个动作的形状都不同，而它在屏幕上的身份是证据，
   不是一句话。break-all 是给 proof_key 那种一长串不带空格的值留的 */
.jsonbox{
  margin:0;padding:11px 12px;border:1px solid var(--line);border-radius:var(--r-ctl);
  background:var(--surface-page);font-family:var(--font-mono);font-size:11.5px;
  line-height:1.7;color:var(--text-body);white-space:pre-wrap;word-break:break-all;
  max-height:220px;overflow:auto;
}

/* ══ §17 不用系统自带的控件 ═══════════════════════════════════════════════
   设计稿画的是控件「关着」的样子。浏览器和操作系统画的是它们「打开」的
   样子 —— 滚动条、<select> 弹出的列表、复选框的对勾、number 的上下箭头、
   Chrome 自动填充的那层底色。这几样一律是浅色系统外观，在一个 #17181B 的
   后台上每次出现都是一道白。gateway 的处理是同一条：一样都不用原生的
   （gateway-manager/static/css/base.css + components/dropdown.js）。

   这一节把那条策略搬过来，配色换成本项目的 token。
   ══════════════════════════════════════════════════════════════════════ */

/* ── 滚动条 ──────────────────────────────────────────────────────────────
   全局而不是给一个 .scroll 类：模态、抽屉、下拉菜单、表格、侧栏，任何一处
   将来长出滚动条都得是这一套，而「记得加那个类」是一定会忘的。
   本项目全部表面都是深色，所以浅色轨道 + 半透明滑块到处都成立 */
*{scrollbar-width:thin;scrollbar-color:var(--line-strong) transparent}
::-webkit-scrollbar{width:8px;height:8px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--line);border-radius:8px}
::-webkit-scrollbar-thumb:hover{background:var(--line-strong)}
::-webkit-scrollbar-corner{background:transparent}

/* ── 下拉：永远不用 <select> ──────────────────────────────────────────────
   §7 里那个 .select 是设计稿画的，它只管得住「关着」的那半 —— 点开之后
   弹出来的列表是操作系统画的，深色后台上会是一块白底蓝高亮，而且没有任何
   CSS 管得着。所以产品侧用 .dd-trigger + JS 生成的 .dd-menu
   （static/js/components/dropdown.js），.select 留着只为对齐设计稿。

   触发器长得跟 .input 一模一样（同高、同圆角、同边框），这样一行表单里
   输入框和下拉挨着不会差半个像素 */
.dd-trigger{
  display:inline-flex;align-items:center;justify-content:space-between;gap:8px;
  height:32px;padding:0 11px;
  font-family:inherit;font-size:13px;line-height:1.5;color:var(--text-title);
  background:var(--surface-page);border:1px solid var(--line);border-radius:6px;
  cursor:pointer;white-space:nowrap;
}
.dd-trigger:hover{border-color:var(--line-strong)}
.dd-trigger:disabled{opacity:.45;cursor:not-allowed}
.dd-trigger .ico{color:var(--text-muted);flex:0 0 auto;opacity:.85}
/* 整行宽的表单控件用这个；筛选条上的下拉保持内容宽度 */
.dd-trigger--block{width:100%}
/* inline-block：dropdown.js 会量出最宽的一项写死 min-width，让控件不随
   选中项忽宽忽窄；而 <button> 默认居中，得显式左对齐 */
.dd-value{display:inline-block;text-align:left;overflow:hidden;text-overflow:ellipsis}

.dd-menu{
  position:fixed;z-index:200;max-height:300px;
  display:flex;flex-direction:column;overflow:hidden;
  background:var(--surface-overlay);border:1px solid var(--line);
  border-radius:var(--r-ctl);box-shadow:var(--shadow-overlay);
  animation:dd-pop .13s ease;
}
/* 会滚的是列表这一半，搜索行钉在上面不动 */
.dd-list{overflow-y:auto;min-height:0;padding:5px}
.dd-search{flex:0 0 auto;padding:6px;border-bottom:1px solid var(--line)}
.dd-search input{
  width:100%;height:28px;padding:0 9px;
  font-family:inherit;font-size:12.5px;color:var(--text-title);
  background:var(--surface-page);border:1px solid var(--line);border-radius:var(--r-sm);
  outline:0;
}
.dd-search input::placeholder{color:var(--text-faint)}
.dd-search input:focus{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-softer)}
/* 输入类控件自己画了焦点（主色描边 + 柔光），§1 的全局 :focus-visible 再套一圈
   2px outline 就成了双环 —— 打开可搜索下拉时最明显，因为那个框是脚本聚焦的。
   按钮、链接、导航项没有自绘焦点，那圈 outline 是它们唯一的可达性提示，留着 */
.input:focus-visible,.select:focus-visible,.textarea:focus-visible,
.dd-search input:focus-visible{outline:none}
.dd-option{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:7px 10px;border-radius:6px;font-size:13px;color:var(--text-body);cursor:pointer;
  /* 不换行：菜单按最宽的一项撑开，宽到顶了才由下面的 ellipsis 接手 */
  white-space:nowrap;
}
.dd-option .dd-label{overflow:hidden;text-overflow:ellipsis;min-width:0}
.dd-option:hover{background:rgba(255,255,255,.045);color:var(--text-title)}
.dd-option .tick{color:var(--primary);opacity:0;flex:0 0 auto}
.dd-option.is-selected{color:var(--primary)}
.dd-option.is-selected .tick{opacity:1}
.dd-empty{padding:8px 10px;font-size:12.5px;color:var(--text-faint)}
/* 搜索过滤靠 [hidden]，而 .dd-option 是 display:flex —— 这一条由 §16 的
   [hidden]{display:none !important} 兜住了，别把那条删了 */
@keyframes dd-pop{
  from{opacity:0;transform:translateY(6px) scale(.98)}
  to{opacity:1;transform:none}
}

/* ── 复选框 / 单选：真 input，外观自己画 ─────────────────────────────────
   设计稿里是 .box + .is-on 两个 class（画布上没有真表单，只能这么摆）。
   产品侧用真的 <input>：键盘能到达、能被 form 提交、屏幕阅读器认得，
   而 appearance:none 之后系统一笔都画不上去。对勾是两条边框转 45°，
   不用 data: URI —— CSP 是 default-src 'self' */
.checkbox input[type=checkbox]{
  appearance:none;
  width:15px;height:15px;flex:0 0 15px;margin:3px 0 0;padding:0;
  border-radius:4px;border:1px solid var(--line-strong);background:var(--surface-page);
  cursor:pointer;position:relative;transition:background .12s,border-color .12s;
}
.checkbox input[type=checkbox]:checked{background:var(--primary);border-color:var(--primary)}
.checkbox input[type=checkbox]:checked::after{
  content:"";position:absolute;left:4.5px;top:1.5px;width:3.5px;height:7.5px;
  border:solid var(--primary-ink);border-width:0 2px 2px 0;transform:rotate(45deg);
}
.checkbox input[type=checkbox]:disabled{opacity:.45;cursor:not-allowed}
.checkbox:has(input:disabled){opacity:.6;cursor:not-allowed}

/* 分段单选：真 radio 铺满整格并透明，视觉全交给 .opt */
.radiorow .opt{position:relative}
.radiorow .opt input[type=radio]{
  position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer;
}
.radiorow .opt:has(input:checked){background:var(--primary-soft);color:var(--primary);font-weight:500}
.radiorow .opt:has(input:disabled){opacity:.35;cursor:not-allowed}
.radiorow .opt:has(input:disabled) input{cursor:not-allowed}

/* ── 剩下两处系统外观 ────────────────────────────────────────────────────
   金额、时长都会用 type=number，而那对上下箭头是系统画的，跟 32px 的输入框
   高度也对不上。用 text 又拿不到数字键盘和校验，所以留 number、去箭头 */
input[type=number]{appearance:textfield}
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button{appearance:none;margin:0}

/* Chrome 自动填充会把输入框刷成浅黄/浅蓝，且 background 改不动 —— 只能用
   一层足够厚的 inset 阴影盖掉。登录页每次记住密码都会撞上 */
.input:-webkit-autofill,
.input:-webkit-autofill:hover,
.input:-webkit-autofill:focus{
  -webkit-text-fill-color:var(--text-title);
  -webkit-box-shadow:0 0 0 40px var(--surface-page) inset;
  caret-color:var(--text-title);
}
