/* Subscription gateway · Control console
   Served with style-src 'self', so every rule must live here:
   no inline style attributes and no <style> blocks in the HTML. */

:root {
  color-scheme: light;
  /* 视觉基线取自 docs/design/v2-现代轻量/设计说明.md。
     变量名保持不变：20 个页面共用这一套 token，换肤只改这里。 */
  --paper: #f6f7f9;
  --surface: #ffffff;
  --ink: #111827;
  --muted: #6b7280;
  --line: #e5e7eb;
  --hair: #eef0f3;
  --teal: #2563eb;
  --teal-hover: #1d4ed8;
  --soft: #eff6ff;
  --ok: #15803d;
  --okbg: #f0fdf4;
  --danger: #b91c1c;
  --amber: #b45309;
  --warnbg: #fffbeb;
  --warnline: #fde68a;
  --badbg: #fef2f2;
  --font: -apple-system, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
  --mono: "SF Mono", ui-monospace, Menlo, Consolas, monospace;
  font-family: var(--font);
  background: var(--paper);
  color: var(--ink);
  font-size: 14px;
  line-height: 1.6;
}
* { box-sizing: border-box; }
body { margin: 0; background: var(--paper); }
a { color: var(--teal); text-decoration-thickness: 1px; text-underline-offset: 4px; }
[hidden] { display: none !important; }

button, input, select, textarea { font: inherit; color: inherit; }
button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  /* 设计稿的 .btn 是 padding:8px 14px（约 37px 高），不是 32px 的紧凑按钮。
     全站统一这一个尺寸，页头按钮才不会显得比稿里小一号。 */
  padding: 8px 14px;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--surface);
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
}
button:hover { background: #fafafa; border-color: #d1d5db; }
button:disabled { opacity: 0.45; cursor: not-allowed; }
button.secondary { background: transparent; }
button.primary { background: var(--teal); border-color: var(--teal); color: #fff; }
button.primary:hover { background: var(--teal-hover); }
button.danger { background: var(--danger); border-color: var(--danger); color: #fff; }
button.ghost { border-color: transparent; background: none; }
button.ghost.danger { color: var(--danger); }
button.ghost.danger:hover { background: var(--badbg); }

input, select, textarea {
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
  padding: 6px 10px;
  font-size: 13px;
  max-width: 100%;
}
input:focus, select:focus, textarea:focus, button:focus-visible, a:focus-visible {
  outline: 2px solid var(--soft);
  outline-offset: 1px;
  border-color: var(--teal);
}
h1, h2, h3, p { margin: 0; }
h1 { font-size: 20px; font-weight: 600; letter-spacing: -0.01em; }
h2 { font-size: 14px; font-weight: 600; }
h3 { font-size: 13px; font-weight: 600; }
.muted, small { color: var(--muted); }
/* 表格里的 ID 用 12.5（与设计稿 .mono 一致）；代码块单独小一号，避免长命令换行更碎。 */
.mono { font-family: var(--mono); font-size: 12.5px; }
code, pre { font-family: var(--mono); font-size: 11.5px; }
pre {
  margin: 0;
  padding: 9px 11px;
  background: var(--paper);
  border: 1px solid var(--hair);
  border-radius: 5px;
  overflow: auto;
  max-height: 320px;
  white-space: pre-wrap;
  word-break: break-all;
}
.toast {
  position: fixed;
  left: 50%;
  bottom: 22px;
  transform: translate(-50%, 12px);
  max-width: min(560px, 92vw);
  padding: 9px 16px;
  border-radius: 7px;
  background: var(--ink);
  color: var(--surface);
  font-size: 12.5px;
  box-shadow: 0 6px 22px rgba(32, 51, 50, 0.22);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.16s, transform 0.16s;
  z-index: 40;
}
.toast.ok { opacity: 1; transform: translate(-50%, 0); }
.toast.bad { opacity: 1; transform: translate(-50%, 0); background: var(--danger); }
.error {
  background: var(--badbg);
  border: 1px solid #fecaca;
  color: var(--danger);
  border-radius: 6px;
  padding: 8px 12px;
  font-size: 12px;
  margin-bottom: 12px;
  overflow-wrap: anywhere;
}
.notice {
  position: relative;
  background: var(--warnbg);
  border: 1px solid var(--warnline);
  color: var(--amber);
  border-radius: 12px;
  padding: 12px 18px 12px 34px;
  font-size: 13px;
  margin-bottom: 16px;
}
/* 与页面级 .banner.warn 用同一个圆点：同样是「注意」，不该长得像两个组件。 */
.notice::before {
  content: "";
  position: absolute;
  left: 18px;
  top: 19px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--amber);
}
.eyebrow { font-size: 10.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); margin-bottom: 4px; }

/* ---------- shell ---------- */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0 28px;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  min-height: 56px;
}
.topbar .row { display: flex; align-items: center; gap: 10px; flex-wrap: nowrap; }
.wordmark { font-size: 14px; font-weight: 600; }
.env {
  font-size: 10px;
  letter-spacing: 0.12em;
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 1px 5px;
}
.topbar select { height: 30px; max-width: 180px; }
/* 顶栏是常驻 chrome，按钮要比页面主按钮轻一号，否则一进页面最抢眼的是「退出」。 */
.topbar button { min-height: 0; height: 30px; padding: 0 10px; font-size: 12.5px; border-radius: 6px; }

.panel { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 16px 18px; margin-bottom: 14px; }
.login { max-width: 420px; margin: 12vh auto; }
.login h1 { margin-bottom: 6px; }
.login > p { margin-bottom: 16px; font-size: 13px; }
.login label { display: block; margin-bottom: 12px; }
.login input { width: 100%; height: 34px; }
.login button { width: 100%; height: 34px; }

.workspace { display: grid; grid-template-columns: 216px minmax(0, 1fr); align-items: start; }
.workspace > aside {
  background: var(--surface);
  border-right: 1px solid var(--line);
  padding: 14px 10px 10px;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: calc(100vh - 56px);
  overflow-y: auto;
}
.workspace > main { padding: 24px 28px 40px; min-width: 0; max-width: 1500px; width: 100%; }

.brand { display: flex; align-items: center; gap: 9px; padding: 6px 10px 14px; }
/* logo：稿里是蓝方块里写 SG，不是两条横线的抽象标记。 */
.brand .mark { width: 28px; height: 28px; border-radius: 8px; background: var(--teal); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 600; flex: none; letter-spacing: 0.02em; }
.brand b { display: block; font-size: 14px; font-weight: 600; line-height: 1.2; }
.brand span { display: block; font-size: 10px; color: var(--muted); letter-spacing: 0.12em; text-transform: uppercase; }

.tenant { margin: 10px 4px 4px; border: 1px solid var(--line); border-radius: 6px; padding: 4px 8px; background: var(--paper); }
.tenant select { border: 0; background: transparent; width: 100%; height: 26px; padding: 0; font-family: var(--mono); font-size: 12px; }

nav#nav { display: block; }
.navgroup { margin-top: 14px; }
.navgroup > p { font-size: 11.5px; letter-spacing: 0.02em; color: var(--muted); margin: 0 0 4px; padding: 0 12px; font-weight: 500; }
.navitem {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  padding: 8px 12px;
  border-radius: 8px;
  font-size: 13px;
  color: var(--muted);
  min-height: 0;
}
.navitem:hover { background: var(--paper); color: var(--ink); }
.navitem[aria-current="page"] { background: var(--soft); color: var(--teal); font-weight: 500; }
.navitem .count { font-size: 11px; color: var(--muted); font-family: var(--mono); }
.navitem[aria-current="page"] .count { color: var(--teal); }

#actor { margin-top: auto; padding: 10px 6px 2px; border-top: 1px solid var(--hair); font-size: 11.5px; color: var(--muted); display: flex; justify-content: space-between; align-items: center; gap: 6px; }
#actor .who { font-family: var(--mono); font-size: 11px; }
#logout { white-space: nowrap; flex-shrink: 0; }

/* ---------- page ---------- */
.pagehead { display: flex; justify-content: space-between; align-items: flex-start; gap: 20px; margin-bottom: 16px; }
.pagehead p { color: var(--muted); font-size: 13px; margin-top: 3px; max-width: 76ch; }
.pagehead .actions { display: flex; gap: 8px; flex: none; }
.pagehead .crumb { font-size: 12px; color: var(--muted); margin: 0 0 6px; }

.filters { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 14px 18px; margin-bottom: 16px; }
.frow { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; }
.field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.field > span { font-size: 12px; color: var(--muted); }
.field input, .field select { height: 32px; min-width: 140px; }
.field.grow input { min-width: 210px; }
.frow .spacer { flex: 1; }
.fresult { font-size: 11.5px; color: var(--muted); padding-bottom: 8px; white-space: nowrap; }
.fbuttons { display: flex; gap: 8px; }

.segbar { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.segbar > span { font-size: 11px; color: var(--muted); flex: none; }

.card { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; overflow: hidden; }
/* 表格标题栏与页脚：设计稿里每张表都有「表名 + 计数」，说明贴在卡内底部。 */
.card > .chd { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 18px; border-bottom: 1px solid var(--hair); }
.card > .chd b { font-size: 14px; font-weight: 600; }
.card > .chd .r { font-size: 12px; color: var(--muted); white-space: nowrap; }
.card > .cfoot { font-size: 12px; color: var(--muted); padding: 10px 18px; border-top: 1px solid var(--hair); background: #fafbfc; }
.card > .cfoot a, .card > .cfoot button { color: var(--teal); }
/* 分页条也在卡内（设计稿的分页属于 panel 的一部分），所以去掉它自己的上外边距与灰底。 */
.card > .cfoot-pager { padding: 12px 18px; background: var(--surface); }
.card > .cfoot-pager .pager { margin-top: 0; }
table { width: 100%; border-collapse: collapse; table-layout: fixed; }
table.fixed { table-layout: fixed; }
.w-60 { width: 60px; } .w-70 { width: 70px; } .w-80 { width: 80px; } .w-90 { width: 90px; }
.w-100 { width: 100px; } .w-110 { width: 110px; } .w-120 { width: 120px; } .w-130 { width: 130px; }
.w-140 { width: 140px; } .w-150 { width: 150px; } .w-160 { width: 160px; } .w-170 { width: 170px; }
.w-180 { width: 180px; } .w-190 { width: 190px; } .w-200 { width: 200px; } .w-210 { width: 210px; }
.w-220 { width: 220px; } .w-230 { width: 230px; } .w-240 { width: 240px; }
.w-auto { width: auto; }
th {
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--muted);
  text-align: left;
  background: #fafafa;
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
th.num, td.num { text-align: right; font-variant-numeric: tabular-nums; }
td { padding: 11px 14px; border-bottom: 1px solid var(--hair); font-size: 13px; vertical-align: middle; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
tbody tr { cursor: pointer; }
tbody tr:nth-of-type(even):not(.static) { background: #fafbfc; }
tbody tr:hover { background: #f6f8fb; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr.static { cursor: default; }
tbody tr.static:hover { background: none; }
td .sub { display: block; font-size: 11px; color: var(--muted); margin-top: 1px; overflow: hidden; text-overflow: ellipsis; }
td .wrap { white-space: normal; }
.rowactions { display: flex; gap: 6px; justify-content: flex-end; }
/* 行内动作 = 设计稿的 .icbtn：小号有边框按钮，hover 变主色。
   稿里操作列没有蓝色实心按钮，所以 primary 在这里也只保留同样外观，
   只用文字深浅区分主次，避免一行里混排实心/描边两种按钮。 */
.rowactions button {
  min-height: 0;
  height: 28px;
  padding: 0 10px;
  font-size: 12px;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--muted);
}
.rowactions button.primary { color: var(--ink); }
.rowactions button.danger { color: var(--danger); }
.rowactions button:hover { border-color: var(--teal); color: var(--teal); background: var(--surface); }
.rowactions button.danger:hover { border-color: var(--danger); color: var(--danger); background: var(--badbg); }

.dot { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.dot::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: #9ca3af; flex: none; }
.dot.ok::before { background: var(--ok); }
.dot.warn::before { background: var(--amber); }
.dot.bad::before { background: var(--danger); }
.dot.idle::before { background: #9ca3af; }

.badge {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 6px;
  font-size: 11.5px;
  font-weight: 500;
  background: #f3f4f6;
  border: 1px solid transparent;
  color: var(--muted);
}
.badge.ok { background: var(--okbg); border-color: transparent; color: var(--ok); }
.badge.warn { background: var(--warnbg); border-color: transparent; color: var(--amber); }
.badge.bad { background: var(--badbg); border-color: transparent; color: var(--danger); }
.badge.mono { font-family: var(--mono); font-size: 11px; }

.empty { padding: 48px 16px; text-align: center; color: var(--muted); font-size: 13px; }
.empty b { display: block; color: var(--ink); font-weight: 500; margin-bottom: 4px; font-size: 13px; }

.pager { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-top: 12px; font-size: 12px; color: var(--muted); }
.pager .pages { display: flex; align-items: center; gap: 6px; }

.metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 14px; margin-bottom: 16px; }
.metric { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px; text-align: left; display: block; width: 100%; }
.metric:hover { background: var(--surface); border-color: var(--teal); }
.metric > span { display: block; font-size: 12px; color: var(--muted); }
.metric strong { display: block; font-size: 24px; font-weight: 600; margin-top: 2px; line-height: 1.3; font-variant-numeric: tabular-nums; }
.metric em { display: block; font-size: 11.5px; color: var(--muted); font-style: normal; margin-top: 2px; }

/* 值班台：稿上是 4 张并排的卡。auto-fit 在宽屏会排出 5 列以上、窄屏又掉成 2 列，
   看起来和设计稿不是同一个页面。 */
.metrics.four { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 1100px) { .metrics.four { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* 指标卡标题行：左标签、右状态点。稿里点色是 inline style，CSP 禁内联，改用 class。 */
.metric .lb { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 12.5px; color: var(--muted); }
.metric .d { width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--line); }
.metric .d.ok { background: var(--ok); }
.metric .d.warn { background: var(--amber); }
.metric .d.bad { background: var(--danger); }
/* 两列并排：稿里「待办事项」与「各产品今日态势」是左右并排，不是上下堆叠。 */
.two { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start; margin-bottom: 16px; }
.two > .card { margin-bottom: 0; }
@media (max-width: 1180px) { .two { grid-template-columns: 1fr; } }
/* 待办行：图标 + 名称/说明 + 计数 + 动作。一条待办就是一件事，
   铺成表格反而要横向找列，还会把「说明」挤成省略号。 */
.todo { display: flex; align-items: center; gap: 12px; padding: 12px 18px; border-bottom: 1px solid var(--hair); }
.todo:last-child { border-bottom: 0; }
.todo .ic { width: 30px; height: 30px; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 14px; flex: none; background: var(--paper); color: var(--muted); }
.todo .ic.warn { background: var(--warnbg); color: var(--amber); }
.todo .ic.bad { background: var(--badbg); color: var(--danger); }
.todo .t { flex: 1; min-width: 0; }
.todo .t b { display: block; font-size: 13px; font-weight: 500; }
/* 只命中直接子级：下面还有一层 <span class="age">，用后代选择器会把它也变成 block，
   一行说明被拆成两行。 */
.todo .t > span { display: block; font-size: 11.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.todo .n { font-weight: 600; font-size: 16px; font-variant-numeric: tabular-nums; min-width: 24px; text-align: right; }
/* 数量为 0 的待办压暗但保留：让人确认「这一类是 0」，而不是以为根本没这一类。 */
.todo.zero .ic, .todo.zero .n { opacity: 0.45; }
.todo.zero .t b { color: var(--muted); font-weight: 400; }
/* 行内动作：稿的 .icbtn，小号描边。不跟着页头主按钮一起放大。 */
.todo button { height: 28px; min-height: 0; padding: 0 10px; font-size: 12px; border-radius: 6px; }

/* 概览条：一张白卡内横向分栏，与设计稿的 .stats 一致。
   与 .metrics 的区别是「同一份数据的多个切片」，不需要每格可点。 */
.stats { display: flex; flex-wrap: wrap; background: var(--surface); border: 1px solid var(--line); border-radius: 12px; margin-bottom: 16px; overflow: hidden; }
.stat { flex: 1 1 148px; padding: 12px 18px; border-right: 1px solid var(--hair); }
.stat:last-child { border-right: 0; }
.stat .k { font-size: 12px; color: var(--muted); }
.stat .v { font-size: 22px; font-weight: 600; line-height: 1.35; font-variant-numeric: tabular-nums; }
.stat .v small { font-size: 12px; color: var(--muted); font-weight: 400; }
.stat .v.ok { color: var(--ok); }
.stat .v.brand { color: var(--teal); }

/* 接入进度条：宽度只能用 class 分档（CSP 禁内联样式），6 步刚好 6 档。 */
.prog { display: flex; align-items: center; gap: 8px; }
.prog .bar { width: 72px; height: 6px; border-radius: 3px; background: var(--line); overflow: hidden; flex: none; }
.prog .bar i { display: block; height: 100%; border-radius: 3px; background: var(--teal); }
.prog .bar i.full { background: var(--ok); }
.prog .bar i.p1 { width: 17%; } .prog .bar i.p2 { width: 33%; } .prog .bar i.p3 { width: 50%; }
.prog .bar i.p4 { width: 67%; } .prog .bar i.p5 { width: 83%; } .prog .bar i.p6 { width: 100%; }
.prog .txt { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }

.banner { display: flex; align-items: flex-start; gap: 12px; background: var(--soft); border-radius: 12px; padding: 12px 18px; font-size: 13px; color: var(--teal); margin-bottom: 16px; }
.banner b { font-weight: 500; }
.banner .pip { width: 6px; height: 6px; border-radius: 50%; background: var(--teal); margin-top: 8px; flex: none; }
.banner.warn { background: var(--warnbg); color: var(--amber); border: 1px solid var(--warnline); }
.banner.warn .pip { background: var(--amber); }
/* 提示条右侧的「去处理 →」：靠右，别和正文挤在一起。 */
.banner .gobtn { margin-left: auto; flex: none; }

/* ---------- shared rows ---------- */
.row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.row > * { min-width: 0; }
.section-title { display: flex; align-items: baseline; gap: 8px; margin: 22px 0 10px; }
.section-title h2 { font-size: 13px; letter-spacing: 0.04em; }
.section-title p { font-size: 11.5px; color: var(--muted); }

.timeline { list-style: none; margin: 0; padding: 0 0 0 16px; border-left: 1px solid var(--line); }
.timeline li { position: relative; padding: 0 0 16px 14px; border: 0; }
.timeline li::before { content: ""; position: absolute; left: -21px; top: 6px; width: 8px; height: 8px; border-radius: 50%; background: var(--line); box-shadow: 0 0 0 3px var(--surface); }
.timeline li.ok::before { background: var(--ok); }
.timeline li.warn::before { background: var(--amber); }
.timeline li.bad::before { background: var(--danger); }
.timeline time { font-size: 11.5px; color: var(--muted); font-family: var(--mono); }
.timeline h3 { margin: 1px 0; font-size: 13px; }
.timeline p { font-size: 12px; color: var(--muted); overflow-wrap: anywhere; }

.kv { display: grid; grid-template-columns: 132px minmax(0, 1fr); gap: 6px 14px; }
.kv dt { color: var(--muted); font-size: 11.5px; }
.kv dd { margin: 0; word-break: break-all; font-size: 12.5px; }

/* ---------- drawer ---------- */
.scrim { position: fixed; inset: 0; background: rgba(32, 51, 50, 0.26); opacity: 0; pointer-events: none; transition: opacity 0.18s; z-index: 20; }
.scrim.show { opacity: 1; pointer-events: auto; }
.drawer {
  position: fixed;
  top: 0;
  right: 0;
  height: 100vh;
  width: min(600px, 94vw);
  background: var(--surface);
  border-left: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  transform: translateX(102%);
  transition: transform 0.2s ease;
  z-index: 21;
}
.drawer.open { transform: translateX(0); }
.dhead { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; padding: 15px 20px 12px; border-bottom: 1px solid var(--hair); }
.dhead h2 { margin-bottom: 2px; }
.dhead p { font-size: 11.5px; color: var(--muted); }
.dbody { padding: 16px 20px; overflow-y: auto; flex: 1; }
.dfoot { border-top: 1px solid var(--hair); padding: 12px 20px; display: flex; justify-content: space-between; align-items: center; gap: 12px; background: var(--surface); }
.dfoot .hint { font-size: 11.5px; color: var(--muted); flex: 1; min-width: 0; }
.dfoot .acts { display: flex; gap: 8px; flex: none; }

.ctx { background: var(--paper); border: 1px solid var(--hair); border-radius: 6px; padding: 11px 13px; margin-bottom: 18px; }
.ctx .grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 16px; }
.ctx .k { font-size: 10.5px; color: var(--muted); letter-spacing: 0.04em; }
.ctx .v { font-size: 12.5px; overflow-wrap: anywhere; }
.ctx .v.mono { font-size: 11.5px; }

.sect { margin-bottom: 20px; }
/* 分区标题统一走 .section-title（页面与抽屉同一个组件），这里只补抽屉里的间距 */
.section-title .opt { font-weight: 400; font-size: 11px; color: var(--muted); margin-left: auto; }
.fgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 11px; }
.fgrid .wide { grid-column: 1 / -1; }
.fgrid label { display: flex; flex-direction: column; gap: 4px; font-size: 11.5px; color: var(--muted); }
.fgrid label > .opt { font-weight: 400; font-size: 11px; }
.fgrid input, .fgrid select, .fgrid textarea { width: 100%; }
.fgrid textarea { min-height: 64px; resize: vertical; }
.fgrid .err { color: var(--danger); font-size: 11px; }
.fgrid .bad, input.bad, select.bad, textarea.bad { border-color: var(--danger); }
.hintline { font-size: 11px; color: var(--muted); }
select.grow-select { flex: 1 1 260px; min-width: 200px; height: 32px; }

.seg { display: flex; border: 1px solid var(--line); border-radius: 5px; overflow: hidden; width: fit-content; }
.seg button { border: 0; border-right: 1px solid var(--line); border-radius: 0; padding: 0 13px; font-size: 12px; color: var(--muted); background: var(--surface); min-height: 0; height: 30px; }
.seg button:last-child { border-right: 0; }
.seg button[aria-pressed="true"] { background: var(--soft); color: var(--teal); font-weight: 500; }
.seg button:disabled { opacity: 0.45; }

.result { display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: 8px; padding: 60px 10px; }
.result .tick { width: 44px; height: 44px; border-radius: 50%; background: var(--soft); position: relative; margin-bottom: 6px; }
.result .tick::after { content: ""; position: absolute; left: 15px; top: 11px; width: 10px; height: 17px; border: 2px solid var(--teal); border-top: 0; border-left: 0; transform: rotate(42deg); }
.result h3 { font-size: 15px; font-weight: 500; }
.result p { color: var(--muted); font-size: 12.5px; max-width: 46ch; line-height: 1.7; }

details > summary { cursor: pointer; font-size: 11.5px; color: var(--teal); margin-bottom: 6px; padding: 3px 0; }

@media (max-width: 1080px) {
  .workspace { grid-template-columns: 1fr; }
  .workspace > aside { position: static; height: auto; border-right: 0; border-bottom: 1px solid var(--line); }
  .metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fgrid, .ctx .grid2 { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}
/* -- 产品接入：摘要卡 + 分区抽屉 ----------------------------------- */
.panelhead { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.panelhead h2 { margin: 0; }
.panelhead p { margin: 3px 0 0; font-size: 11.5px; color: var(--muted); max-width: 62ch; }
.section-title .n { width: 17px; height: 17px; border-radius: 50%; background: var(--soft); color: var(--teal); font-size: 10.5px; display: inline-flex; align-items: center; justify-content: center; font-family: var(--mono); margin-right: 7px; }
.subhead { margin: 18px 0 10px; font-size: 13px; letter-spacing: 0.04em; }
.toolbar { margin-bottom: 14px; }
.formerror {
  color: var(--danger);
  font-size: 12px;
  margin: 0 0 12px;
  padding: 9px 11px;
  background: var(--badbg);
  border: 1px solid #fecaca;
  border-radius: 6px;
  overflow-wrap: anywhere;
}
.formerror b { display: block; font-size: 12.5px; font-weight: 600; }
.formerror .fix { display: block; margin-top: 3px; color: var(--ink); opacity: 0.82; }
.formerror small { display: block; margin-top: 5px; font-size: 11px; color: var(--muted); font-family: var(--mono, monospace); }
.sect > p.sectnote { font-size: 11.5px; color: var(--muted); margin: -4px 0 10px; }
.sect > label { display: flex; flex-direction: column; gap: 4px; font-size: 11.5px; color: var(--muted); }
.sect > label input, .sect > label select, .sect > label textarea { width: 100%; }
.sect > .hintline { margin: 6px 0 0; }
.chips { display: flex; flex-wrap: wrap; gap: 6px; }
/* -- 功能开通：勾选清单（15 项一屏看完，不再一项一次抽屉） --------- */
.fgrid.checks { gap: 6px 12px; }
.fgrid label.check {
  flex-direction: row;
  align-items: flex-start;
  gap: 8px;
  padding: 7px 9px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface);
  color: var(--ink);
  font-size: 12px;
  cursor: pointer;
}
.fgrid label.check:hover { border-color: var(--teal); }
/* -- 折叠区：高级参数 / 可选能力，默认收起，值仍参与提交 ------------ */
details.fold {
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 8px 10px;
  background: var(--surface);
}
details.fold > summary {
  cursor: pointer;
  font-size: 12px;
  color: var(--muted);
  list-style: none;
}
details.fold > summary::-webkit-details-marker { display: none; }
details.fold > summary::before { content: "▸ "; }
details.fold[open] > summary::before { content: "▾ "; }
details.fold > summary:hover { color: var(--ink); }
details.fold .fgrid { margin-top: 10px; }
.fgrid label.check input { width: auto; margin: 3px 0 0; flex: none; }
.fgrid label.check > span { display: flex; flex-direction: column; gap: 1px; }
.fgrid label.check b { font-weight: 600; }
.fgrid label.check em { font-style: normal; color: var(--muted); font-size: 10.5px; font-family: var(--mono); }
/* -- 接入向导：进度点 + 步骤清单 ----------------------------------- */
.steps-dots { display: flex; gap: 4px; margin-top: 8px; }
.steps-dots span { width: 26px; height: 6px; border-radius: 3px; background: var(--hair); }
.steps-dots span.on { background: var(--teal); }
.steps-dots span.bad { background: var(--danger); }
ol.wizard { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
ol.wizard li {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 11px 13px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--surface);
}
ol.wizard li.done { border-color: var(--soft); background: var(--paper); }
/* 当前卡点：整行标红并写明「卡在这里」，不让人自己数哪一步没勾。 */
ol.wizard li.blocked { border-color: #fecaca; background: var(--badbg); }
ol.wizard li.blocked .mark { border-color: var(--danger); color: var(--danger); background: var(--surface); }
ol.wizard li.blocked .wbody b::after { content: " · 卡在这里"; color: var(--danger); font-weight: 500; font-size: 11px; }
ol.wizard li.blocked .wbody p { color: #7f1d1d; }
ol.wizard .mark {
  flex: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid var(--line);
  color: var(--muted);
  font-family: var(--mono);
  font-size: 11px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-top: 1px;
}
ol.wizard li.done .mark { background: var(--soft); border-color: var(--soft); color: var(--teal); }
ol.wizard .wbody { flex: 1; min-width: 0; }
ol.wizard .wbody b { font-size: 13px; }
ol.wizard .wbody p { margin: 2px 0 0; font-size: 11.5px; color: var(--muted); }
ol.wizard li > button { flex: none; }
.price-row { border: 1px solid var(--hair); border-radius: 6px; padding: 10px 12px; margin-bottom: 8px; background: var(--paper); }
.price-row .prow { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.price-row .prow .pnum { width: 18px; font-family: var(--mono); font-size: 11px; color: var(--muted); }
.price-row .prow select { width: auto; min-width: 118px; }
.price-row .prow .sp { flex: 1; }
.price-row .prow button { flex: none; }

/* ==================================================================
   统一组件层
   这一层只放「全站只能有一种写法」的组件。新增页面请复用，不要再
   手搓同类结构 —— 之前详情弹窗与抽屉、两套分区标题、三种空状态
   并存，运营要在不同界面间切换操作习惯。
   ================================================================== */

/* 提示条：info（默认）/ warn / bad 三种语气，标题可省略 */
.banner.bad { background: var(--badbg); color: var(--danger); border: 1px solid #fecaca; }
.banner.bad .pip { background: var(--danger); }
.banner .fix { display: block; margin-top: 3px; }
.banner code { background: var(--surface); border: 1px solid var(--hair); border-radius: 3px; padding: 0 4px; }

/* 分区标题：页面与抽屉同构，抽屉里压缩间距 */
.dbody .section-title { margin: 0 0 9px; }
.dbody .section-title h2 { font-size: 12.5px; }
.sect > .section-title { margin: 0 0 9px; }

/* 空状态：标题 + 一句下一步，禁止只留一行「暂无数据」 */
.empty p { max-width: 48ch; margin: 0 auto; line-height: 1.7; }
.empty .row { justify-content: center; margin-top: 10px; }

/* 当前筛选：把「为什么只有这几行」摆到列表上方 */
.filterchips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: -4px 0 10px; }
.filterchips > .label { font-size: 11px; color: var(--muted); }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 24px;
  height: 24px;
  padding: 0 8px;
  border-radius: 99px;
  border: 1px solid var(--line);
  background: var(--surface);
  font-size: 11.5px;
  color: var(--ink);
}
.chip:hover { border-color: var(--teal); }
.chip b { font-weight: 500; color: var(--muted); }
.chip .x { color: var(--muted); font-family: var(--mono); }
.chip:hover .x { color: var(--danger); }

/* 快速查找：值班台第一入口，粘贴一个号就能到对应列表 */
.quickfind { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 11px 13px; background: var(--surface); border: 1px solid var(--line); border-radius: 12px; margin-bottom: 12px; }
.quickfind > .label { font-size: 12px; font-weight: 500; flex: none; }
.quickfind input { flex: 1 1 280px; height: 32px; min-width: 220px; }
.quickfind .note { flex-basis: 100%; font-size: 11px; color: var(--muted); }

/* 顶栏全局搜索：工作区里它占掉左侧品牌位，右侧留给账号与操作 */
.qfslot { flex: 1; max-width: 460px; }
.quickfind.compact { display: flex; align-items: center; gap: 8px; flex-wrap: nowrap; padding: 0; margin: 0; border: 0; background: transparent; }
.quickfind.compact input { flex: 1; height: 34px; min-width: 0; background: #fafafa; border-radius: 8px; }
.quickfind.compact input:focus { background: #fff; }
.topbar .av { width: 30px; height: 30px; border-radius: 50%; background: var(--soft); color: var(--teal); display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 600; flex: none; }

/* 行内复选：自动刷新等开关 */
.checkline { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--muted); cursor: pointer; }
.checkline input { width: auto; height: auto; margin: 0; }

/* 加载态：只有加载慢到能被看见时才有意义，样式保持克制 */
.loading { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); padding: 10px 0; }
.loading::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--teal); animation: pulse 1s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: 0.25; } 50% { opacity: 1; } }

/* 详情抽屉：ID 旁边直接复制，不再手抄 */
.kv dd .copybtn {
  height: 20px;
  min-height: 0;
  padding: 0 6px;
  margin-left: 6px;
  font-size: 10.5px;
  vertical-align: 1px;
}
.glossary { display: grid; grid-template-columns: 108px minmax(0, 1fr); gap: 7px 12px; margin: 0; }
.glossary dt { font-size: 11.5px; color: var(--ink); }
.glossary dd { margin: 0; font-size: 11.5px; color: var(--muted); overflow-wrap: anywhere; }

/* 提示条里的多行清单：三条铁律要分行读，挤成一段等于没写 */
.banner .rules { margin: 2px 0 0; padding-left: 16px; }
.banner .rules li { margin-top: 2px; }

/* -- 运行健康：值班台顶部四块只读状态（数据来自 GET /v1/runtime） ---- */
.health { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; margin-bottom: 14px; }
.hcard { background: var(--surface); border: 1px solid var(--line); border-left: 3px solid var(--line); border-radius: 12px; padding: 12px 14px; }
.hcard.ok { border-left-color: var(--ok); }
.hcard.warn { border-left-color: var(--amber); background: var(--warnbg); }
.hcard.bad { border-left-color: var(--danger); background: var(--badbg); }
.hcard .hl { display: block; font-size: 11px; color: var(--muted); letter-spacing: 0.04em; }
.hcard strong { display: block; font-size: 14px; font-weight: 500; margin-top: 2px; }
.hcard em { display: block; font-style: normal; font-size: 11px; color: var(--muted); margin-top: 2px; }
.healthfoot { grid-column: 1 / -1; display: flex; justify-content: space-between; align-items: center; gap: 10px; font-size: 11px; color: var(--muted); }

/* 待办年龄：同一列只比较长短，不印绝对时间 */
.age { font-variant-numeric: tabular-nums; color: var(--muted); }
.age.warn { color: var(--amber); }
.age.bad { color: var(--danger); }

/* -- 订单 360：固定头部 + 六个 Tab ---------------------------------- */
.orderhead { background: var(--surface); border: 1px solid var(--line); border-radius: 8px; padding: 13px 15px; margin-bottom: 12px; }
.orderline { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; flex-wrap: wrap; }
.orderline h2 { font-size: 16px; font-weight: 500; }
.orderline p { font-size: 11.5px; color: var(--muted); margin-top: 2px; font-family: var(--mono); overflow-wrap: anywhere; }
.orderfacts { display: flex; gap: 24px; flex-wrap: wrap; }
.orderfacts > div { display: flex; flex-direction: column; gap: 2px; }
.orderfacts span { font-size: 10.5px; color: var(--muted); letter-spacing: 0.04em; }
.orderfacts b { font-size: 13px; font-weight: 500; }
.tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--line); margin: 14px 0 0; flex-wrap: wrap; }
.tabs button { border: 0; border-bottom: 2px solid transparent; border-radius: 0; background: none; color: var(--muted); padding: 0 12px; height: 34px; min-height: 0; }
.tabs button:hover { background: var(--paper); }
.tabs button[aria-selected="true"] { color: var(--teal); border-bottom-color: var(--teal); font-weight: 500; }
.orderpanel { padding-top: 14px; }
.orderpanel .card { margin-bottom: 14px; }

/* 可复制的处置步骤：等宽、保留换行 */
.codeblock { white-space: pre-wrap; background: #f8fafc; border: 1px solid var(--hair); border-radius: 8px; padding: 12px 14px; line-height: 1.8; margin-bottom: 10px; }

/* -- 窄屏：值班台优先，导航压缩成一行 ------------------------------- */
@media (max-width: 1080px) {
  #nav { display: flex; gap: 4px; overflow-x: auto; padding: 6px 0; }
  .navgroup { margin-top: 0; display: flex; align-items: center; gap: 4px; flex: none; }
  .navgroup > p { display: none; }
  .navitem { width: auto; white-space: nowrap; }
}
@media (max-width: 720px) {
  .health { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .card { overflow-x: auto; }
  .card table { min-width: 640px; }
  .pagehead { flex-direction: column; gap: 10px; }
  .pagehead .actions { flex-wrap: wrap; }
  .filters .frow { flex-direction: column; align-items: stretch; }
  .quickfind input { min-width: 0; }
  .orderfacts { gap: 14px; }
  .tabs { overflow-x: auto; flex-wrap: nowrap; }
}

/* -- 角色选择：下拉 + 每个角色能做什么 ------------------------------- */
.rolelist { margin: 2px 0 4px; padding-left: 18px; color: var(--muted); font-size: 12px; line-height: 1.75; }
.rolelist li { margin: 0; }
.rolelist li b { color: var(--muted); font-weight: 600; }
.rolelist li.on { color: var(--ink); }
.rolelist li.on b { color: var(--teal); }

/* -- 变更历史：一条一条列，diff 用「旧 → 新」而不是两段 JSON -------- */
.history { display: flex; flex-direction: column; gap: 10px; }
.hitem { border: 1px solid var(--hair); border-radius: 8px; padding: 10px 12px; background: var(--surface); }
.hline { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.hline b { font-weight: 600; }
.hline .hat { margin-left: auto; color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }
.htag { font-size: 11px; color: var(--teal); background: var(--soft); border-radius: 4px; padding: 1px 6px; }
.hrsn { margin: 4px 0 0; color: var(--muted); font-size: 12px; }
.hdiff { margin-top: 8px; border-top: 1px dashed var(--hair); padding-top: 8px; display: flex; flex-direction: column; gap: 4px; }
.hrow { display: grid; grid-template-columns: 150px 1fr auto 1fr; gap: 8px; align-items: baseline; font-size: 12px; }
.hf { color: var(--muted); }
.hbefore { color: var(--danger); text-decoration: line-through; word-break: break-all; }
.harrow { color: var(--muted); }
.hafter { color: var(--teal); word-break: break-all; }
.hrow.single { grid-template-columns: 150px 1fr; }
.hfoot { margin-top: 8px; }

/* -- 值班台待办：行式列表本身就能收窄（flex 会自动压说明），
   不再需要「桌面表格 / 手机卡片」两套排版。 --------------------------- */
@media (max-width: 560px) {
  .todo { flex-wrap: wrap; }
  .todo .t { flex-basis: calc(100% - 42px); }
  .todo button { margin-left: 42px; }
}
