/* DJB 控制台 · Aurora Signal 页面层（W3 / web-console 所有）。
   范围：templates/{auth,consumer,node,pay,errors}/*.html 用到的类。
   约定（UI-BASELINE-2026-11-01 §1 圆角/间距 + design/15 配色）：
   - 圆角：卡片 12 / 控件 8 / 弹层 14；间距 8 的倍数；内容宽 1280；
   - 控制台正文 14px，字阶 12/13/14/16/20/24/32/44；
   - 中文按钮最小 40px 高，主按钮 44px；输入框 44px；
   - 焦点 2px var(--mint) + outline-offset 2px；三态（等待琥珀/完成玉绿/失败珊瑚/未知灰）；
   - 零 JavaScript、零内联样式（CSP: style-src 'self'; script-src 'none'）。

   兼容说明：portal.css 由 web-design 并行重写。本文件在 body.portal 上把旧变量
   重映射成浅色值（旧文件里的 var(--bg)/var(--brand) 等随之变浅），因此
   「新 portal.css 未落地」时控制台也是 Daylight；两边同时存在也不打架。
   portal.css 正式浅色版落地后，第 1 段的重映射可整段删除。 */

/* ---------------------------------------------------------------- 1. 令牌层 */
/* 紫粉修订（design/15-DJB-Aurora-Signal-配色修订-v1，D-14）：绿色退成温和玉绿主色，
   紫=第二强调（导航/链接 hover/选中/信息徽标），粉=第三强调（eyebrow/装饰/未读/角标）。
   颜色一律走 theme.css 提供的 token（--bg/--surface/--ink/--mint/--violet/--pink/--glow/--line…），
   本层只做**语义派生**：控制台需要的「警示/危险/信息/紫/粉/骨架/阴影」等语义色，
   在下面三个分支里各给一套值——默认（无 data-theme）= 夜晚，[data-theme=day] = 白天，
   系统浅色偏好且未显式选择时按白天。结构与组件完全不变，只换明度与光晕强度。
   状态语义不变：完成=玉绿 --dl-mint、等待=琥珀 --dl-amber、失败=珊瑚红 --dl-red、未知=灰；
   粉只做非状态强调，绝不用于 danger/bad/停止/金额方向。 */
html:root {
  /* 核心：直接引用 theme.css 的双主题 token（勿在此写死颜色） */
  --dl-bg: var(--bg);
  --dl-bg-2: var(--bg-2);
  --dl-surface: var(--surface);
  --dl-surface-2: var(--surface-2);
  --dl-ink: var(--ink);
  --dl-ink-2: var(--ink-2);
  --dl-muted: var(--muted);
  --dl-line: var(--line);
  --dl-line-2: var(--line-2);
  --dl-mint: var(--mint);
  --dl-mint-2: var(--mint);
  --dl-cyan: var(--cyan);
  --dl-violet: var(--violet);

  /* 统一装饰渐变（绿→紫→粉）：优先取 theme.css 的 --accent-grad（W1 落地后同源），
     未落地时用同一组 token 本地回退；--dl-accent-line 是两端透明淡出的发丝线版本。 */
  --dl-accent-grad: var(--accent-grad, linear-gradient(90deg, var(--mint), var(--violet-2, var(--dl-violet-2)) 55%, var(--pink, var(--dl-pink-2))));
  --dl-accent-line: linear-gradient(90deg, transparent, var(--mint) 8%, var(--violet-2, var(--dl-violet-2)) 55%, var(--pink, var(--dl-pink-2)) 92%, transparent);

  /* 圆角与网格（与主题无关） */
  /* 圆角尺度（值不变，只是每一个都有名字，便于审计与统一改） */
  --dl-radius-2xs: 2px;
  --dl-radius-xs: 4px;
  --dl-radius-sm: 6px;
  --dl-radius-md: 8px;
  --dl-radius-lg: 10px;
  --dl-radius-card: 12px;
  --dl-radius-pop: 14px;
  --dl-radius-pill: 999px;
  /* 既有引用点的别名，避免大面积改调用 */
  --dl-r-card: var(--dl-radius-card);
  --dl-r-ctl: var(--dl-radius-md);
  --dl-r-pop: var(--dl-radius-pop);

  /* ── Night（默认）：紫墨夜色 · 高光晕 ───────────────────── */
  color-scheme: dark;
  /* 玉绿（主色，温和低饱和） */
  --dl-mint-3: rgba(143, 217, 190, .12);      /* 玉绿底（选中项 / ok 胶囊） */
  --dl-on-mint: #08221B;                       /* 玉绿实心上的字 */
  --dl-mint-line: rgba(143, 217, 190, .34);    /* 玉绿描边 */
  --dl-mint-ink: color-mix(in oklab, var(--mint) 76%, var(--ink));  /* 玉绿底上的字 */
  /* 紫（第二强调：导航 / 链接 hover / 选中 / 信息徽标） */
  --dl-violet-2: #D4C7FF;
  --dl-violet-3: rgba(185, 162, 255, .14);
  --dl-violet-line: rgba(185, 162, 255, .35);
  --dl-violet-ink: #CDBDFF;
  /* 粉（第三强调：eyebrow / 装饰 / 未读 / 角标；不承担状态语义） */
  --dl-pink: #F4A6D7;
  --dl-pink-2: #F9C9E4;
  --dl-pink-3: rgba(244, 166, 215, .13);
  --dl-pink-line: rgba(244, 166, 215, .32);
  --dl-pink-ink: #F8C4E2;
  /* 状态色（不参与紫粉轮换） */
  --dl-amber: #F0C56B;
  --dl-amber-2: #F7DCA6;
  --dl-amber-3: rgba(240, 197, 107, .13);
  --dl-red: #FF9B93;
  --dl-red-2: #FFC4BF;
  --dl-red-3: rgba(255, 155, 147, .12);
  --dl-gray: #A49BC0;
  --dl-gray-3: rgba(198, 183, 255, .08);
  --dl-link: color-mix(in oklab, var(--mint) 92%, var(--ink));
  --dl-link-line: color-mix(in oklab, var(--mint) 40%, transparent);
  --dl-link-hover: var(--violet-2, var(--dl-violet-2));  /* 链接 hover 转紫 */
  --dl-select-bg: rgba(185, 162, 255, .26);
  /* 控件边界：可交互控件 1px 描边（夜色 surface 3.42:1；--dl-line-2 只作分隔线） */
  --dl-line-3: var(--line-3, rgba(198, 183, 255, .50));
  --dl-line-hover: var(--line-2);
  --dl-mint-hover: color-mix(in oklab, var(--mint) 78%, var(--surface));
  --dl-mint-active: color-mix(in oklab, var(--mint) 62%, var(--surface));
  --dl-bad-hover: color-mix(in oklab, var(--dl-red) 78%, var(--surface));
  --dl-muted-strong: var(--ink-2);
  --dl-surface-hover: rgba(185, 162, 255, .06);
  --dl-surface-unread: rgba(244, 166, 215, .06);
  --dl-skeleton-a: var(--surface-2);
  --dl-skeleton-b: var(--bg-2);
  /* 语义 tone（横幅 / 胶囊 / 提示条）：描边-底-字 三件套 */
  --dl-tone-warn-line: rgba(240, 197, 107, .38);
  --dl-tone-warn-bg: rgba(240, 197, 107, .1);
  --dl-tone-warn-ink: var(--dl-amber-2);
  --dl-tone-warn-ink-2: var(--dl-amber-2);
  --dl-tone-warn-ink-3: var(--dl-amber);
  --dl-tone-bad-line: rgba(255, 155, 147, .4);
  --dl-tone-bad-bg: rgba(255, 155, 147, .1);
  --dl-tone-bad-ink: var(--dl-red-2);
  --dl-tone-bad-ink-2: var(--dl-red-2);
  --dl-tone-bad-ink-3: var(--dl-red);
  --dl-tone-info-line: rgba(127, 203, 232, .36);
  --dl-tone-info-bg: rgba(127, 203, 232, .1);
  --dl-tone-info-ink: color-mix(in oklab, var(--cyan) 84%, var(--ink));
  --dl-tone-violet-line: rgba(185, 162, 255, .38);
  --dl-tone-violet-bg: rgba(185, 162, 255, .10);
  --dl-tone-violet-ink: #D4C7FF;
  --dl-tone-pink-line: rgba(244, 166, 215, .38);
  --dl-tone-pink-bg: rgba(244, 166, 215, .10);
  --dl-tone-pink-ink: #F9C9E4;
  --dl-shadow-1: 0 1px 0 rgba(198, 183, 255, .05), 0 2px 8px rgba(0, 0, 0, .32);
  --dl-shadow-2: var(--shadow);
  --dl-shadow-focus: 0 0 0 3px var(--glow);
  --dl-card-glow: 0 0 0 1px var(--line), 0 0 24px -8px var(--glow);
  --dl-card-glow-hover: 0 0 0 1px var(--line-2), 0 10px 34px -12px var(--glow-2), 0 0 18px -4px var(--glow-2);
}

/* ── Day：同一结构，提明度、降光晕（alpha 差 ≤ .15） ───────────────── */
html:root[data-theme="day"] {
  color-scheme: light;
  --dl-mint-3: #DDF3EA;
  --dl-on-mint: #FFFFFF;
  --dl-mint-line: #A9E2D2;
  --dl-mint-ink: #256B57;
  --dl-violet-2: #8A6FE0;
  --dl-violet-3: #EEE8FF;
  --dl-violet-line: #D8CBFA;
  --dl-violet-ink: #5B3FA8;
  --dl-pink: #B93C7E;
  --dl-pink-2: #D967A6;
  --dl-pink-3: #FBE7F3;
  --dl-pink-line: #F2C7DF;
  --dl-pink-ink: #A83270;
  --dl-amber: #8A5D12;
  --dl-amber-2: #7D5510;
  --dl-amber-3: #FDF4E1;
  --dl-red: #B94F47;
  --dl-red-2: #A84540;
  --dl-red-3: #FBEAE8;
  --dl-gray: #6B6385;
  --dl-gray-3: #EDE7F6;
  --dl-link: #256B57;
  --dl-link-line: #9DCFC1;
  --dl-link-hover: #5B3FA8;   /* 链接 hover 转紫 */
  --dl-select-bg: #E4DBFB;
  /* 控件边界：日间白底 3.25:1（--dl-line-2 只作分隔线） */
  --dl-line-3: var(--line-3, rgba(60, 40, 110, .55));
  --dl-line-hover: #BFAFD9;
  --dl-mint-hover: #2A735E;
  --dl-mint-active: #23604F;
  --dl-bad-hover: #A84540;
  --dl-muted-strong: #4F4765;
  --dl-surface-hover: #FAF7FE;
  --dl-surface-unread: #FDF4F9;
  --dl-skeleton-a: #F0EAF7;
  --dl-skeleton-b: #FAF7FE;
  --dl-tone-warn-line: #ecd6a8;
  --dl-tone-warn-bg: #fdf7ea;
  --dl-tone-warn-ink: #5c4212;
  --dl-tone-warn-ink-2: #7d5510;
  --dl-tone-warn-ink-3: #4a350d;
  --dl-tone-bad-line: #edc4bf;
  --dl-tone-bad-bg: #fff6f4;
  --dl-tone-bad-ink: #8f352e;
  --dl-tone-bad-ink-2: #7c2f29;
  --dl-tone-bad-ink-3: #6d2924;
  --dl-tone-info-line: #C3DCEA;
  --dl-tone-info-bg: #EAF4FA;
  --dl-tone-info-ink: #23536A;
  --dl-tone-violet-line: #D8CBFA;
  --dl-tone-violet-bg: #F4EFFE;
  --dl-tone-violet-ink: #5B3FA8;
  --dl-tone-pink-line: #F2C7DF;
  --dl-tone-pink-bg: #FDF1F8;
  --dl-tone-pink-ink: #A83270;
  --dl-shadow-1: 0 1px 2px rgba(27, 21, 48, .06), 0 1px 1px rgba(27, 21, 48, .04);
  --dl-shadow-2: var(--shadow);
  --dl-shadow-focus: 0 0 0 3px var(--glow);
  --dl-card-glow: 0 0 0 1px var(--line), 0 6px 18px -14px var(--glow);
  --dl-card-glow-hover: 0 0 0 1px var(--line-2), 0 14px 30px -18px var(--glow-2), 0 0 12px -6px var(--glow-2);
}

/* 系统浅色且未显式选择：按白天一套（与 theme.css 的 prefers-color-scheme 分支同构） */
@media (prefers-color-scheme: light) {
  html:root:not([data-theme]):not([data-surface="public"]) {
    color-scheme: light;
    --dl-mint-3: #DDF3EA;
    --dl-on-mint: #FFFFFF;
    --dl-mint-line: #A9E2D2;
    --dl-mint-ink: #256B57;
    --dl-violet-2: #8A6FE0;
    --dl-violet-3: #EEE8FF;
    --dl-violet-line: #D8CBFA;
    --dl-violet-ink: #5B3FA8;
    --dl-pink: #B93C7E;
    --dl-pink-2: #D967A6;
    --dl-pink-3: #FBE7F3;
    --dl-pink-line: #F2C7DF;
    --dl-pink-ink: #A83270;
    --dl-amber: #8A5D12;
    --dl-amber-2: #7D5510;
    --dl-amber-3: #FDF4E1;
    --dl-red: #B94F47;
    --dl-red-2: #A84540;
    --dl-red-3: #FBEAE8;
    --dl-gray: #6B6385;
    --dl-gray-3: #EDE7F6;
    --dl-link: #256B57;
    --dl-link-line: #9DCFC1;
    --dl-link-hover: #5B3FA8;   /* 链接 hover 转紫 */
    --dl-select-bg: #E4DBFB;
    --dl-line-3: var(--line-3, rgba(60, 40, 110, .55));
    --dl-line-hover: #BFAFD9;
    --dl-mint-hover: #2A735E;
    --dl-mint-active: #23604F;
    --dl-bad-hover: #A84540;
    --dl-muted-strong: #4F4765;
    --dl-surface-hover: #FAF7FE;
    --dl-surface-unread: #FDF4F9;
    --dl-skeleton-a: #F0EAF7;
    --dl-skeleton-b: #FAF7FE;
    --dl-tone-warn-line: #ecd6a8;
    --dl-tone-warn-bg: #fdf7ea;
    --dl-tone-warn-ink: #5c4212;
    --dl-tone-warn-ink-2: #7d5510;
    --dl-tone-warn-ink-3: #4a350d;
    --dl-tone-bad-line: #edc4bf;
    --dl-tone-bad-bg: #fff6f4;
    --dl-tone-bad-ink: #8f352e;
    --dl-tone-bad-ink-2: #7c2f29;
    --dl-tone-bad-ink-3: #6d2924;
    --dl-tone-info-line: #C3DCEA;
    --dl-tone-info-bg: #EAF4FA;
    --dl-tone-info-ink: #23536A;
    --dl-tone-violet-line: #D8CBFA;
    --dl-tone-violet-bg: #F4EFFE;
    --dl-tone-violet-ink: #5B3FA8;
    --dl-tone-pink-line: #F2C7DF;
    --dl-tone-pink-bg: #FDF1F8;
    --dl-tone-pink-ink: #A83270;
    --dl-shadow-1: 0 1px 2px rgba(27, 21, 48, .06), 0 1px 1px rgba(27, 21, 48, .04);
    --dl-shadow-2: var(--shadow);
    --dl-shadow-focus: 0 0 0 3px var(--glow);
    --dl-card-glow: 0 0 0 1px var(--line), 0 6px 18px -14px var(--glow);
    --dl-card-glow-hover: 0 0 0 1px var(--line-2), 0 14px 30px -18px var(--glow-2), 0 0 12px -6px var(--glow-2);
  }
}

body.portal {
  background-color: var(--bg);
  background-image: none; /* 网格由 theme.css 的 .grid-bg 负责 */
  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
  font-size: 15px;
  line-height: 1.65;
}

body.portal ::selection { color: var(--ink); background: var(--dl-select-bg); }
body.portal a { color: var(--dl-link); text-decoration-color: var(--dl-link-line); text-underline-offset: 3px; }
body.portal a:hover { color: var(--dl-link-hover); text-decoration-color: var(--dl-link-hover); }
body.portal :focus-visible { outline: 2px solid var(--mint); outline-offset: 2px; border-radius: var(--dl-radius-xs); }

/* ---------------------------------------------------------------- 2. 控制台骨架 */
.console-layout {
  display: grid;
  grid-template-columns: 248px minmax(0, 1fr);
  gap: 24px;
  align-items: start;
  padding-top: 24px;
  padding-bottom: 56px;
  max-width: 1280px;
  font-size: 14px;
}

.console-content { min-width: 0; }
.page-workspace { display: flex; flex-direction: column; gap: 20px; }

body.portal .wrap { max-width: 1280px; padding: 0 24px; }
body.portal .topbar-inner { max-width: 1280px; }

/* 顶栏：浅色 + 细边 */
body.portal .topbar,
body.portal .site-header {
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  border-top: 0;
  border-bottom: 1px solid var(--dl-line);
  box-shadow: none;
  padding: 0;
  min-height: 64px;
}
body.portal .topbar-inner { min-height: 64px; display: flex; align-items: center; gap: 16px; }
body.portal .brand { color: var(--dl-ink); font-size: 15px; letter-spacing: .02em; }
body.portal .brand-mark {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 40px; height: 28px; padding: 0 8px;
  border-radius: var(--dl-radius-md); background: var(--dl-mint-3); color: var(--dl-mint-ink);
  font-size: 12px; font-weight: 800; letter-spacing: .08em;
}
body.portal .brand-text small { color: var(--dl-muted); font-size: 10px; letter-spacing: .18em; }
body.portal .topbar-nav .nav-items { display: flex; flex-wrap: wrap; gap: 4px; margin: 0; padding: 0; list-style: none; }
body.portal .topbar-nav .nav-group { display: flex; align-items: center; gap: 4px; }
body.portal .topbar-nav .nav-group-label { color: var(--dl-muted); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; }
body.portal .topbar-nav a {
  display: inline-flex; align-items: center; min-height: 40px; padding: 0 10px;
  border-radius: var(--dl-radius-md); color: var(--dl-ink-2); font-size: 13px; text-decoration: none;
}
body.portal .topbar-nav a:hover { background: var(--dl-bg-2); color: var(--dl-ink); }
body.portal .topbar-nav a[aria-current="page"] { background: linear-gradient(90deg, var(--dl-mint-3), var(--dl-violet-3)); color: var(--dl-mint-ink); font-weight: 700; }
body.portal .topbar-actions a,
body.portal .topbar-actions button { min-height: 40px; }

/* 侧栏导航 */
.subnav {
  position: sticky; top: 16px;
  display: flex; flex-direction: column; gap: 12px;
  padding: 16px;
  border: 1px solid var(--dl-line);
  border-radius: var(--dl-r-card);
  background: var(--dl-surface);
  box-shadow: var(--dl-shadow-1);
}
.subnav .eyebrow { margin: 0; font-size: 11px; letter-spacing: .16em; color: var(--dl-muted); text-transform: uppercase; }
.subnav h2 { margin: 0; font-size: 16px; line-height: 1.3; letter-spacing: -.01em; }
.workspace-switch { display: flex; gap: 4px; padding: 4px; border-radius: var(--dl-radius-lg); background: var(--dl-bg-2); }
.workspace-switch a {
  flex: 1 1 0; display: inline-flex; align-items: center; justify-content: center;
  min-height: 36px; border-radius: var(--dl-radius-md); color: var(--dl-ink-2);
  font-size: 13px; text-decoration: none;
}
.workspace-switch a[aria-current="page"],
.workspace-switch a.is-active { background: var(--dl-surface); color: var(--dl-mint-ink); font-weight: 700; box-shadow: var(--dl-shadow-1); }
.subnav .workspace-menu {
  display: flex; flex-direction: column; gap: 2px;
  margin: 0; padding: 0; list-style: none;
  max-height: none; overflow: visible;
}
.subnav .workspace-menu a {
  display: flex; align-items: center; gap: 8px;
  min-height: 40px; padding: 0 12px;
  border-radius: var(--dl-radius-md); color: var(--dl-ink-2); font-size: 13px; text-decoration: none;
}
.subnav .workspace-menu a:hover { background: var(--dl-bg-2); color: var(--dl-ink); }
.subnav .workspace-menu a[aria-current="page"] {
  background: linear-gradient(90deg, var(--dl-mint-3), var(--dl-violet-3)); color: var(--dl-mint-ink); font-weight: 700;
  box-shadow: inset 2px 0 0 var(--dl-mint);
}
/* 分组标题：不可点击，只做视觉分段（constants 里 href 为空串的行） */
.subnav .nav-group {
  display: block; margin: 12px 0 4px; padding: 0 12px;
  color: var(--dl-muted); font-size: 11px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
}
.subnav .nav-group + .nav-group { margin-top: 8px; }
.subnav-support { border-top: 1px solid var(--dl-line); padding-top: 8px; }
.subnav-support summary {
  display: flex; align-items: center; min-height: 40px; padding: 0 12px;
  border-radius: var(--dl-radius-md); color: var(--dl-muted); font-size: 13px; cursor: pointer; list-style: none;
}
.subnav-support summary::-webkit-details-marker { display: none; }
.subnav-support summary:hover { background: var(--dl-bg-2); }
.subnav-support a {
  display: flex; align-items: center; min-height: 36px; padding: 0 12px 0 24px;
  border-radius: var(--dl-radius-md); color: var(--dl-ink-2); font-size: 13px; text-decoration: none;
}
.subnav-support a:hover { background: var(--dl-bg-2); }

/* 页面标题区 */
.page-workspace > h1,
.console-content h1 { margin: 0; font-size: 24px; line-height: 1.25; letter-spacing: -.02em; }
.console-content h2 { margin: 0; font-size: 16px; line-height: 1.35; letter-spacing: -.01em; }
.console-content h3 { margin: 0; font-size: 14px; line-height: 1.4; font-weight: 700; }
.console-content .lead { margin: 0; color: var(--dl-ink-2); font-size: 14px; }
.console-content .eyebrow,
.console-content .kicker { margin: 0; color: var(--dl-muted); font-size: 11px; letter-spacing: .16em; text-transform: uppercase; }
.console-content .meta,
.console-content .hint { margin: 0; color: var(--dl-muted); font-size: 12px; }
.console-content .muted { color: var(--dl-muted); }
.console-content .section-heading {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 12px;
  margin: 8px 0 0; padding-bottom: 8px; border-bottom: 1px solid var(--dl-line);
}
.console-content .section-heading.compact { margin-top: 4px; }
.console-content .section-heading h2,
.console-content .section-heading h3 { margin: 0; }
.console-content .section-heading .meta { margin-left: auto; }

/* ---------------------------------------------------------------- 3. 卡片与网格 */
body.portal .card {
  position: relative;
  padding: 20px;
  border: 1px solid var(--dl-line);
  border-radius: var(--dl-r-card);
  background: var(--dl-surface);
  box-shadow: var(--dl-shadow-1);
  color: var(--dl-ink);
}
/* 旧皮肤的对角切角装饰已删；::before 改作卡片顶部的渐变细线（两套主题同一条） */
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .card::before {
  content: "";
  display: block;
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  border-radius: var(--dl-r-card) var(--dl-r-card) 0 0;
  background: var(--dl-accent-line);
  opacity: .45;
  pointer-events: none;
}
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .card:hover::before { opacity: .8; }
/* 赛博层 M5：边框光晕 + 悬停上浮（两套主题同构，只有光晕 alpha 不同） */
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .card,
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .form-panel,
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .empty-state,
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .onboarding-panel {
  box-shadow: var(--dl-card-glow);
  transition: transform 180ms ease, box-shadow 180ms ease, border-color 180ms ease;
}
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .card:hover,
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .form-panel:hover {
  transform: translateY(-2px);
  border-color: var(--dl-line-2);
  box-shadow: var(--dl-card-glow-hover);
}
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .card:focus-within { box-shadow: var(--dl-card-glow-hover); }
/* 数据卡强弱层次：指标卡第一张最亮（余额/总计），其余降一档 */
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .metric-grid > .card { position: relative; overflow: hidden; }
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .metric-grid > .card::after {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 2px;
  background: var(--dl-accent-line);
  opacity: .55;
}
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .metric-grid > .card:first-child {
  border-color: var(--dl-mint-line);
  background: linear-gradient(180deg, var(--dl-mint-3), var(--dl-surface) 62%);
}
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .metric-grid > .card:nth-child(n+3)::after { opacity: .28; }
body.portal .card > :first-child { margin-top: 0; }
body.portal .card > :last-child { margin-bottom: 0; }
.card-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 12px; margin-bottom: 12px; }
.card-head h2, .card-head h3 { margin: 0; }
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .card-head h2::before,
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .card-head h3::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 8px;
  border-radius: var(--dl-radius-2xs);
  background: var(--dl-accent-grad);
  vertical-align: 2px;
  box-shadow: 0 0 10px var(--glow-3);
}
.card-head .meta { margin-left: auto; }

.grid { display: grid; gap: 16px; }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-metric { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.metric-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 16px; }

/* 数字 / 统计 */
.stat { margin: 4px 0 0; font-size: 24px; line-height: 1.2; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
/* 数字/正文不加 text-shadow（design/15 §2.5：发光只允许非文字元素） */
.stat-label { margin: 0; color: var(--dl-muted); font-size: 12px; letter-spacing: .06em; }

/* 任务入口（旧类，浅色重绘） */
.task-dock { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; }
.task-dock a {
  display: flex; flex-direction: column; gap: 2px;
  padding: 14px 16px; min-height: 44px;
  border: 1px solid var(--dl-line); border-radius: var(--dl-r-card);
  background: var(--dl-surface); color: var(--dl-ink); text-decoration: none;
  box-shadow: var(--dl-shadow-1);
}
.task-dock a:hover { border-color: var(--dl-line-2); background: var(--dl-surface-2); }
.task-dock strong { font-size: 14px; }
.task-dock small { color: var(--dl-muted); font-size: 12px; }
.task-dock span { color: var(--dl-mint); font-size: 11px; letter-spacing: .12em; }

/* ---------------------------------------------------------------- 4. 按钮 */
body.portal button,
body.portal .button,
body.portal .btn,
body.portal input[type="submit"] {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 40px; padding: 0 18px;
  border: 1px solid transparent; border-radius: var(--dl-r-ctl);
  background: var(--dl-mint); color: var(--dl-on-mint);
  font: 600 14px/1.4 inherit; text-align: center; text-decoration: none;
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, box-shadow .15s ease;
}
body.portal button:hover,
body.portal .button:hover,
body.portal .btn:hover,
body.portal input[type="submit"]:hover { background: var(--dl-mint-hover); color: var(--dl-on-mint); text-decoration: none; }
body.portal button:active, body.portal .button:active { background: var(--dl-mint-active); }
/* 主按钮 44（页面主操作） */
body.portal .button-primary,
body.portal .btn-primary,
body.portal form.form-panel button[type="submit"],
body.portal .actions .button:first-child { min-height: 44px; padding: 0 22px; font-size: 15px; }
body.portal .button-secondary,
body.portal .btn-quiet,
body.portal .button-inline {
  background: var(--dl-surface); color: var(--dl-ink);
  border-color: var(--dl-line-3);
}
body.portal .button-secondary:hover,
body.portal .btn-quiet:hover,
body.portal .button-inline:hover { background: var(--dl-bg-2); color: var(--dl-ink); border-color: var(--dl-violet); }
body.portal .button-danger,
body.portal .btn-danger { background: var(--dl-red); color: var(--dl-on-mint); border-color: transparent; }
body.portal .button-danger:hover { background: var(--dl-bad-hover); }
body.portal .button-inline { min-height: 36px; padding: 0 14px; font-size: 13px; }
body.portal .btn-sm { min-height: 36px; padding: 0 12px; font-size: 13px; }
body.portal button[disabled], body.portal .button[aria-disabled="true"] {
  background: var(--dl-gray-3); color: var(--dl-muted); border-color: var(--dl-line);
  cursor: not-allowed;
}
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin: 0; }
.actions form { margin: 0; }

/* ---------------------------------------------------------------- 5. 表单 */
body.portal .form-panel {
  display: flex; flex-direction: column; gap: 16px;
  padding: 20px; border: 1px solid var(--dl-line); border-radius: var(--dl-r-card);
  background: var(--dl-surface); box-shadow: var(--dl-shadow-1);
}
body.portal .form-panel fieldset { margin: 0; padding: 0; border: 0; }
body.portal .form-panel legend { padding: 0; font-size: 14px; font-weight: 700; }
.field { display: flex; flex-direction: column; gap: 6px; }
.field > label, .field-label { color: var(--dl-ink-2); font-size: 13px; font-weight: 600; }
.field .hint { color: var(--dl-muted); font-size: 12px; }
body.portal input[type="text"],
body.portal input[type="password"],
body.portal input[type="email"],
body.portal input[type="number"],
body.portal input[type="url"],
body.portal input[type="date"],
body.portal input[type="search"],
body.portal select,
body.portal textarea {
  display: block; width: 100%; min-height: 44px; padding: 10px 12px;
  border: 1px solid var(--dl-line-3); border-radius: var(--dl-r-ctl);
  background: var(--surface); color: var(--dl-ink); font: 14px/1.5 inherit;
  transition: border-color .15s ease, box-shadow .15s ease;
}
body.portal textarea { min-height: 120px; resize: vertical; line-height: 1.6; }
body.portal input:hover, body.portal select:hover, body.portal textarea:hover { border-color: var(--dl-violet); }
body.portal input:focus-visible, body.portal select:focus-visible, body.portal textarea:focus-visible {
  border-color: var(--dl-mint); box-shadow: var(--dl-shadow-focus); outline: 2px solid transparent; outline-offset: 2px;
}
body.portal input[aria-invalid="true"], body.portal textarea[aria-invalid="true"] { border-color: var(--dl-red); }
body.portal input[type="checkbox"], body.portal input[type="radio"] {
  width: 18px; height: 18px; min-height: 0; margin: 0 8px 0 0; accent-color: var(--dl-mint);
}
.check-label { display: flex; align-items: flex-start; gap: 8px; min-height: 40px; padding: 8px 0; font-size: 13px; }
.check-label input { flex: none; margin-top: 2px; }
.inline-form { display: flex; flex-wrap: wrap; align-items: end; gap: 12px; }
.inline-form .field { flex: 1 1 160px; }
.code-block {
  max-width: 100%; overflow-x: auto; margin: 0; padding: 14px 16px;
  border: 1px solid var(--dl-line); border-left: 3px solid var(--dl-mint);
  border-radius: var(--dl-r-ctl); background: var(--dl-surface-2);
  color: var(--dl-ink); font: 13px/1.7 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  tab-size: 2; white-space: pre-wrap; word-break: break-all;
}
/* 两步验证二维码：白底是硬要求（深色主题下扫码器读反色码会失败） */
.qr-frame {
  display: inline-flex; padding: 12px; margin: 4px 0 10px;
  border: 1px solid var(--dl-line); border-radius: var(--dl-r-ctl);
  background: #fff; line-height: 0;
}
.qr-frame svg { width: 176px; height: 176px; max-width: 100%; }
@media (max-width: 480px) { .qr-frame svg { width: 148px; height: 148px; } }
code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; }
kbd { padding: 1px 6px; border: 1px solid var(--dl-line-2); border-radius: var(--dl-radius-sm); background: var(--dl-surface-2); font-size: 12px; }

/* ---------------------------------------------------------------- 6. 表格 */
.table-scroll, .table-wrap {
  max-width: 100%; overflow-x: auto;
  border: 1px solid var(--dl-line); border-radius: var(--dl-r-card); background: var(--dl-surface);
}
body.portal table { width: 100%; border-collapse: collapse; font-size: 13px; }
body.portal caption { padding: 12px 16px; color: var(--dl-muted); font-size: 12px; text-align: left; }
body.portal th, body.portal td { padding: 12px 16px; text-align: left; vertical-align: top; border-bottom: 1px solid var(--dl-line); }
body.portal thead th {
  position: relative;
  background: var(--dl-surface-2); color: var(--dl-muted);
  font-size: 12px; font-weight: 700; letter-spacing: .06em; white-space: nowrap;
}
/* 赛博层：表头一条渐变细线（两套主题同一条，只是夜里更亮） */
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) thead th::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px;
  background: var(--dl-accent-line);
  opacity: .5;
}
body.portal tbody tr { transition: background 140ms ease; }
body.portal tbody tr:last-child td { border-bottom: 0; }
body.portal tbody tr:hover { background: var(--dl-surface-hover); }
body.portal td.num, body.portal th.num { text-align: right; font-variant-numeric: tabular-nums; }
body.portal tfoot th, body.portal tfoot td { background: var(--dl-surface-2); font-weight: 700; }

/* ---------------------------------------------------------------- 7. 状态：胶囊 / 徽标 / 芯片 */
.pill, .status-chip, .badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px; border: 1px solid var(--dl-line-2); border-radius: var(--dl-radius-pill);
  background: var(--dl-surface-2); color: var(--dl-ink-2);
  font-size: 12px; font-weight: 600; line-height: 1.5; white-space: nowrap;
}
.pill-ok, .status-chip.ok { background: var(--dl-mint-3); border-color: var(--dl-mint-line); color: var(--dl-mint-ink); }
.pill-warn, .status-chip.wait { background: var(--dl-amber-3); border-color: var(--dl-tone-warn-line); color: var(--dl-tone-warn-ink-2); }
.pill-danger, .status-chip.bad { background: var(--dl-red-3); border-color: var(--dl-tone-bad-line); color: var(--dl-tone-bad-ink); }
.pill-unknown, .status-chip.unknown, .status-chip.muted { background: var(--dl-gray-3); border-color: var(--dl-line-2); color: var(--dl-muted-strong); }
.pill-muted { background: var(--dl-gray-3); color: var(--dl-muted-strong); }
.badge-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 6px; border-radius: var(--dl-radius-pill);
  /* 通知角标=粉（非危险语义；危险仍走 --dl-red） */
  background: var(--dl-pink); color: var(--dl-on-mint); font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--dl-gray); }
.dot.ok { background: var(--dl-mint); }
.dot.wait { background: var(--dl-amber); }
.dot.bad { background: var(--dl-red); }
.dot.unknown { background: var(--dl-gray); }

/* ---------------------------------------------------------------- 8. 提示条 / 横幅 / toast */
body.portal .banner {
  display: block; padding: 14px 16px; margin: 0;
  border: 1px solid var(--dl-amber-3); border-left: 4px solid var(--dl-amber);
  border-radius: var(--dl-r-card); background: var(--dl-tone-warn-bg); color: var(--dl-tone-warn-ink);
  font-size: 13px;
}
body.portal .banner strong { color: var(--dl-tone-warn-ink-3); }
body.portal .banner ul { margin: 8px 0 0; padding-left: 20px; }
body.portal .banner-danger { border-color: var(--dl-tone-bad-line); border-left-color: var(--dl-red); background: var(--dl-red-3); color: var(--dl-tone-bad-ink-2); }
body.portal .banner-danger strong { color: var(--dl-tone-bad-ink-3); }
body.portal .banner-ok { border-color: var(--dl-mint-line); border-left-color: var(--dl-mint); background: var(--dl-mint-3); color: var(--dl-mint-ink); }
body.portal .banner-warn { border-color: var(--dl-tone-warn-line); border-left-color: var(--dl-amber); background: var(--dl-tone-warn-bg); color: var(--dl-tone-warn-ink); }
body.portal .banner-info { border-color: var(--dl-tone-info-line); border-left-color: var(--dl-cyan); background: var(--dl-tone-info-bg); color: var(--dl-tone-info-ink); }
body.portal .banner > :first-child { margin-top: 0; }
body.portal .banner > :last-child { margin-bottom: 0; }

/* P0 toast：不遮挡操作（sticky 在内容顶部，不进 fixed 层） */
.toast {
  position: sticky; top: 8px; z-index: 3;
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px;
  padding: 12px 16px; margin: 0;
  border: 1px solid var(--dl-tone-bad-line); border-left: 4px solid var(--dl-red); border-radius: var(--dl-r-card);
  background: var(--dl-tone-bad-bg); color: var(--dl-tone-bad-ink-2); font-size: 13px;
  box-shadow: var(--dl-shadow-2);
}
.toast strong { color: var(--dl-tone-bad-ink-3); }
.toast a { color: var(--dl-tone-bad-ink); }
.toast .toast-close { margin-left: auto; font-size: 12px; }

/* ---------------------------------------------------------------- 9. 三步 / 向导 */
.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; margin: 0; padding: 0; list-style: none; counter-reset: step; }
.steps > li {
  position: relative; padding: 14px 16px 14px 48px;
  border: 1px solid var(--dl-line); border-radius: var(--dl-r-card); background: var(--dl-surface);
  font-size: 13px;
}
.steps > li::before {
  counter-increment: step; content: counter(step);
  position: absolute; left: 14px; top: 14px;
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 50%;
  background: var(--dl-mint-3); color: var(--dl-mint-ink); font-size: 12px; font-weight: 700;
}
.steps > li.ok::before { content: "✓"; background: var(--dl-mint); color: var(--dl-on-mint); }
.steps > li.wait::before { background: var(--dl-amber-3); color: var(--dl-tone-warn-ink-2); }
.steps > li.unknown::before { background: var(--dl-gray-3); color: var(--dl-muted-strong); }

.wizard { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px; margin: 0; padding: 0; list-style: none; }
.wizard-step {
  display: flex; flex-direction: column; gap: 8px;
  padding: 16px; border: 1px solid var(--dl-line); border-radius: var(--dl-r-card);
  background: var(--dl-surface); box-shadow: var(--dl-shadow-1);
}
.wizard-step.ok { border-color: var(--dl-mint-line); }
.wizard-step.wait { border-color: var(--dl-tone-warn-line); }
.wizard-step.unknown { border-color: var(--dl-line-2); background: var(--dl-surface-2); }
.wizard-step .step-no { color: var(--dl-muted); font-size: 11px; letter-spacing: .16em; text-transform: uppercase; }
.wizard-step h3 { margin: 0; font-size: 14px; }
.wizard-step p { margin: 0; color: var(--dl-ink-2); font-size: 13px; }
.wizard-step .step-state { margin-top: auto; }

/* 影响确认块 */
.risk-zone, .risk-note {
  padding: 14px 16px; border: 1px solid var(--dl-tone-warn-line); border-radius: var(--dl-r-card);
  background: var(--dl-tone-warn-bg); color: var(--dl-tone-warn-ink); font-size: 13px;
}
.risk-note { border-left: 4px solid var(--dl-amber); }
.risk-zone ul { margin: 8px 0 0; padding-left: 20px; }
.risk-zone > :first-child, .risk-note > :first-child { margin-top: 0; }
.risk-zone > :last-child, .risk-note > :last-child { margin-bottom: 0; }

/* ---------------------------------------------------------------- 10. Tab 栏 */
.tabs { display: flex; flex-wrap: wrap; gap: 4px; margin: 0; padding: 4px; border-radius: var(--dl-radius-lg); background: var(--dl-bg-2); }
.tabs a, .tab {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 40px; padding: 0 14px; border-radius: var(--dl-radius-md);
  color: var(--dl-ink-2); font-size: 13px; text-decoration: none;
}
.tabs a:hover, .tab:hover { background: color-mix(in srgb, var(--surface) 70%, transparent); color: var(--dl-ink); }
.tabs a[aria-current="page"], .tab[aria-selected="true"] {
  background: var(--dl-select-bg); color: var(--dl-mint-ink); font-weight: 700; box-shadow: var(--dl-shadow-1);
}
.tabs .badge-count { margin-left: 2px; }

/* ---------------------------------------------------------------- 11. 时间线 */
.timeline { position: relative; margin: 0; padding: 0 0 0 24px; list-style: none; }
.timeline::before {
  content: ""; position: absolute; left: 7px; top: 6px; bottom: 6px;
  width: 2px; border-radius: var(--dl-radius-2xs); background: var(--dl-line);
}
.timeline > li { position: relative; padding: 0 0 20px 8px; }
.timeline > li:last-child { padding-bottom: 0; }
.timeline > li::before {
  content: ""; position: absolute; left: -24px; top: 5px;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--dl-gray-3); border: 2px solid var(--dl-surface);
  box-shadow: 0 0 0 2px var(--dl-line);
}
.timeline > li.ok::before { background: var(--dl-mint); box-shadow: 0 0 0 2px var(--dl-mint-line); }
.timeline > li.wait::before { background: var(--dl-amber); box-shadow: 0 0 0 2px var(--dl-tone-warn-line); }
.timeline > li.bad::before { background: var(--dl-red); box-shadow: 0 0 0 2px var(--dl-tone-bad-line); }
.timeline > li.unknown::before { background: var(--dl-gray); box-shadow: 0 0 0 2px var(--dl-line-2); }
.timeline .tl-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 12px; }
.timeline .tl-title { font-size: 14px; font-weight: 700; }
.timeline .tl-meta { color: var(--dl-muted); font-size: 12px; }
.timeline .tl-body { margin: 4px 0 0; color: var(--dl-ink-2); font-size: 13px; }

/* ---------------------------------------------------------------- 12. 图表（纯 CSS 条形，无 JS） */
.chart { display: flex; align-items: flex-end; gap: 8px; height: 168px; margin: 0; padding: 12px 4px 0; border-bottom: 1px solid var(--dl-line); }
.chart-col { display: flex; flex: 1 1 0; flex-direction: column; align-items: center; justify-content: flex-end; gap: 6px; min-width: 0; height: 100%; }
.chart-bar {
  width: 100%; max-width: 44px; min-height: 3px; border-radius: var(--dl-radius-sm) var(--dl-radius-sm) 0 0;
  background: var(--dl-accent-grad);
}
.chart-bar.lv0 { height: 3px; background: var(--dl-gray-3); }
.chart-bar.lv1 { height: 12%; }
.chart-bar.lv2 { height: 24%; }
.chart-bar.lv3 { height: 36%; }
.chart-bar.lv4 { height: 48%; }
.chart-bar.lv5 { height: 60%; }
.chart-bar.lv6 { height: 72%; }
.chart-bar.lv7 { height: 86%; }
.chart-bar.lv8 { height: 100%; }
.chart-bar.state-unknown {
  height: 100%; border: 1px dashed var(--dl-gray); border-radius: var(--dl-radius-sm);
  background: repeating-linear-gradient(45deg, var(--dl-skeleton-a) 0 6px, var(--dl-skeleton-b) 6px 12px);
}
.chart-x { color: var(--dl-muted); font-size: 11px; white-space: nowrap; }
.chart-legend { display: flex; flex-wrap: wrap; gap: 12px; margin: 8px 0 0; color: var(--dl-muted); font-size: 12px; }

/* ---------------------------------------------------------------- 13. 抽屉 / 折叠 / 证据 */
details.inline-drawer > summary, details.filters > summary {
  display: flex; align-items: center; gap: 8px; min-height: 40px;
  padding: 0 12px; border-radius: var(--dl-r-ctl);
  color: var(--dl-link); font-size: 13px; cursor: pointer; list-style: none;
}
details.inline-drawer > summary::-webkit-details-marker, details.filters > summary::-webkit-details-marker { display: none; }
details.inline-drawer > summary::before, details.filters > summary::before {
  content: "▸"; color: var(--dl-mint); font-size: 12px;
}
details.inline-drawer[open] > summary::before, details.filters[open] > summary::before { content: "▾"; }
details.inline-drawer > summary:hover, details.filters > summary:hover { background: var(--dl-bg-2); }
details.inline-drawer[open] {
  border: 1px solid var(--dl-line); border-radius: var(--dl-r-card);
  background: var(--dl-surface-2); padding: 4px 12px 12px;
}
.drawer-body { padding: 4px 0 0; }
.drawer-body dl { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 6px 16px; margin: 0; font-size: 12px; }
.drawer-body dt { color: var(--dl-muted); }
.drawer-body dd { margin: 0; word-break: break-all; }

body.portal details.evidence { margin-top: 8px; }
body.portal details.evidence > summary {
  display: inline-flex; align-items: center; min-height: 32px; padding: 0 10px;
  border: 1px dashed var(--dl-line-2); border-radius: var(--dl-radius-md);
  color: var(--dl-muted); font-size: 12px; cursor: pointer; list-style: none;
  background: color-mix(in srgb, var(--dl-surface-2) 88%, transparent);
}
body.portal details.evidence > summary::-webkit-details-marker { display: none; }
body.portal details.evidence .meta { margin: 8px 0 0; font-size: 12px; }

/* ---------------------------------------------------------------- 14. 空态 / 通知列表 / 引导 */
.empty-state {
  padding: 20px; border: 1px dashed var(--dl-line-2); border-radius: var(--dl-r-card);
  background: var(--dl-surface-2); color: var(--dl-ink-2); font-size: 13px; text-align: left;
}
.empty-state strong { display: block; color: var(--dl-ink); font-size: 14px; }
.empty-state p { margin: 4px 0 0; }
.empty-state .actions { margin-top: 12px; }

.notice-list { display: flex; flex-direction: column; gap: 12px; margin: 0; padding: 0; list-style: none; }
.notice-list > li {
  padding: 14px 16px; border: 1px solid var(--dl-line); border-left: 3px solid var(--dl-line-2);
  border-radius: var(--dl-r-card); background: var(--dl-surface); font-size: 13px;
}
.notice-list > li.unread { background: var(--dl-surface-unread); border-left-color: var(--dl-pink); }
.notice-list > li.p0 { border-left-color: var(--dl-red); }
.notice-list > li.p1 { border-left-color: var(--dl-amber); }
.notice-list > li.p2 { border-left-color: var(--dl-cyan); }
.notice-list .notice-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 12px; }
.notice-list .notice-title { font-size: 14px; font-weight: 700; }
.notice-list .notice-body { margin: 6px 0 0; color: var(--dl-ink-2); }
.notice-list .notice-actions { margin-top: 8px; }

.notification-summary { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px; }
.notification-summary .stat { margin: 0; }

.onboarding-panel {
  display: flex; flex-wrap: wrap; align-items: center; gap: 16px;
  padding: 20px; border: 1px solid var(--dl-line); border-radius: var(--dl-r-card);
  background: linear-gradient(180deg, var(--surface), var(--dl-surface-2)); box-shadow: var(--dl-shadow-1);
}
.onboarding-panel h2 { margin: 0; font-size: 16px; }
.onboarding-panel p { margin: 4px 0 0; color: var(--dl-ink-2); font-size: 13px; }
.onboarding-panel .actions { margin-left: auto; }

.action-composer { display: flex; flex-direction: column; gap: 12px; }
.section { display: flex; flex-direction: column; gap: 12px; }
.section-lead { margin: 0; color: var(--dl-ink-2); font-size: 13px; }
.section-index { color: var(--dl-muted); font-size: 11px; letter-spacing: .16em; }
.page-identity { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 16px; }

/* ---------------------------------------------------------------- 15. 登录 / 错误 / 维护页 */
.auth-surface, .error-wrap, .flow-wrap {
  max-width: 720px; margin: 48px auto; padding: 28px;
  border: 1px solid var(--dl-line); border-radius: var(--dl-r-pop);
  background: var(--dl-surface); box-shadow: var(--dl-shadow-2);
}
.auth-surface h1, .error-wrap h1 { margin: 0 0 8px; font-size: 24px; line-height: 1.25; letter-spacing: -.02em; }
.auth-surface .lead, .error-wrap .lead { margin: 0 0 20px; color: var(--dl-ink-2); font-size: 14px; }
.auth-surface .form-panel { border: 0; box-shadow: none; padding: 0; }
.auth-story, .auth-statement { color: var(--dl-ink-2); font-size: 13px; }
.auth-emblem, .auth-stage { color: var(--dl-muted); font-size: 11px; letter-spacing: .16em; text-transform: uppercase; }
.error-wrap .code-block { margin-top: 16px; }
.flow-wrap { max-width: 880px; }

/* ---------------------------------------------------------------- 16. 响应式 */
@media (max-width: 1024px) {
  .console-layout { grid-template-columns: 220px minmax(0, 1fr); gap: 16px; }
  .grid-3, .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 820px) {
  body.portal .wrap { padding: 0 16px; }
  .console-layout { grid-template-columns: minmax(0, 1fr); gap: 16px; padding-top: 16px; }
  .subnav { position: static; }
  .subnav .workspace-menu {
    flex-direction: row; flex-wrap: nowrap; overflow-x: auto;
    gap: 4px; padding-bottom: 4px; scrollbar-width: thin;
  }
  .subnav .workspace-menu a { white-space: nowrap; }
  .subnav .nav-group { display: none; } /* 小屏横向条里不插标题，避免读起来断裂 */
  .grid-2, .grid-3, .grid-4, .metric-grid, .steps, .wizard, .task-dock { grid-template-columns: minmax(0, 1fr); }
  .auth-surface, .error-wrap, .flow-wrap { margin: 24px 16px; padding: 20px; }
  body.portal .topbar-nav { display: none; } /* 控制台页面靠侧栏导航，顶栏小屏收起 */
  .chart { height: 140px; }
}
@media (max-width: 560px) {
  body.portal h1, .console-content h1 { font-size: 20px; }
  .stat { font-size: 20px; }
  body.portal th, body.portal td { padding: 10px 12px; }
  body.portal .actions { gap: 8px; }
  body.portal button:not(.theme-toggle), body.portal .button { width: 100%; }
  body.portal .button-inline, body.portal .btn-sm, .actions form button { width: auto; }
  .toast { position: static; }
}

/* ---------------------------------------------------------------- 17. 动效与强制色 */
@media (prefers-reduced-motion: reduce) {
  body.portal *, body.portal *::before, body.portal *::after { transition: none !important; animation: none !important; }
}
@media (forced-colors: active) {
  body.portal .card, body.portal .form-panel, .subnav, .wizard-step, .empty-state { border: 1px solid CanvasText; }
  .pill, .badge, .status-chip { border: 1px solid CanvasText; }
  .chart-bar { forced-color-adjust: none; background: Highlight; }
  .chart-bar.lv0 { background: CanvasText; }
  .chart-bar.state-unknown { background: repeating-linear-gradient(45deg, Canvas 0 4px, CanvasText 4px 6px); }
  body.portal :focus-visible { outline: 2px solid Highlight; }
}

/* ---------------------------------------------------------------- 17b. 认证页布局（修「卡片贴右边缘」） */
/* portal.css 把 .page-identity 设成 flex-wrap，认证页的右栏卡片会被挤到视口边缘。
   这里改成显式两栏网格：1440 居中、卡片不贴边、≤820 单栏。 */
body.portal .auth-stage {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(320px, 520px);
  gap: 48px;
  align-items: start;
  place-items: stretch;
  max-width: 1280px;
  margin: 0 auto;
  padding: 40px 24px 64px;
}
body.portal .auth-stage .auth-surface {
  width: 100%;
  max-width: 520px;
  margin: 0;              /* 旧的 ≤820 规则给了 24px 16px 外边距，会把卡片顶到视口右缘 */
  padding: 28px;
  border-radius: var(--dl-r-card);
  border: 1px solid var(--dl-line);
  background: linear-gradient(180deg, var(--surface), var(--dl-surface-2));
  box-shadow: var(--dl-card-glow);
}
body.portal .auth-stage .auth-story { margin-top: 0; padding-top: 8px; max-width: 46ch; }
body.portal .auth-stage .auth-statement { margin: 0 0 12px; font-size: 28px; line-height: 1.25; letter-spacing: -.02em; color: var(--ink); }
body.portal .auth-stage .auth-emblem { margin: 16px 0 12px; }
@media (max-width: 1080px) {
  body.portal .auth-stage { grid-template-columns: minmax(0, 1fr) minmax(300px, 460px); gap: 32px; }
}
@media (max-width: 820px) {
  body.portal .auth-stage {
    grid-template-columns: minmax(0, 1fr);
    gap: 20px;
    padding: 24px 16px 48px;
  }
  body.portal .auth-stage .auth-surface { max-width: none; padding: 20px; }
  body.portal .auth-stage .auth-statement { font-size: 22px; }
}

/* ---------------------------------------------------------------- 17c. 动效接线（M5/M6/M10） */
/* M6 主按钮：斜向 sheen（与 theme.css 的 djb-sheen 同一支动画；控制台按钮类名不同，这里补上） */
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .button-primary,
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .btn-primary,
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) input[type="submit"],
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) form.form-panel button[type="submit"],
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .actions .button:first-child {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .button-primary::after,
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .btn-primary::after,
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) input[type="submit"]::after,
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) form.form-panel button[type="submit"]::after,
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .actions .button:first-child::after {
  content: "";
  position: absolute;
  inset: -60% -20%;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .32), transparent);
  animation: djb-sheen 2.6s ease-in-out infinite;
}

/* M10 模块切入阶梯：同屏卡片按 60ms 依次入场（动画本体在 theme.css 的 .card/.section） */
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .page-workspace > *:nth-child(1) { animation-delay: 0ms; }
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .page-workspace > *:nth-child(2) { animation-delay: 60ms; }
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .page-workspace > *:nth-child(3) { animation-delay: 120ms; }
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .page-workspace > *:nth-child(4) { animation-delay: 180ms; }
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .page-workspace > *:nth-child(5) { animation-delay: 240ms; }
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .page-workspace > *:nth-child(6) { animation-delay: 300ms; }
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .metric-grid > .card:nth-child(1) { animation-delay: 0ms; }
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .metric-grid > .card:nth-child(2) { animation-delay: 60ms; }
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .metric-grid > .card:nth-child(3) { animation-delay: 120ms; }
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .metric-grid > .card:nth-child(4) { animation-delay: 180ms; }
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .timeline-item:nth-child(n) { animation: djb-reveal-up 420ms cubic-bezier(.22, .61, .36, 1) both; }
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .timeline-item:nth-child(2) { animation-delay: 60ms; }
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .timeline-item:nth-child(3) { animation-delay: 120ms; }
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .timeline-item:nth-child(4) { animation-delay: 180ms; }

/* M8 运行中状态点：胶囊里的圆点缓慢 pulse（夜里看得见，白天幅度更小） */
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .pill::before,
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .status-chip::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 6px;
  border-radius: 50%;
  background: currentColor;
  opacity: .75;
  vertical-align: 1px;
}
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .pill-ok::before,
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .status-chip.ok::before { animation: djb-pulse 2s ease-in-out infinite; }

/* ---------------------------------------------------------------- 17d. 缺失类补齐（审计项：模板用了但 CSS 没定义） */
/* 顶栏横向扁平导航（partials/head 在无分组时使用） */
.nav-items-flat { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 18px; margin: 0; padding: 0; list-style: none; }
.nav-items-flat > li { margin: 0; }
/* 等待态胶囊（模板按状态拼 pill-{{state}}，wait 之前没有定义） */
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .pill-wait { background: var(--dl-amber-3); border-color: var(--dl-tone-warn-line); color: var(--dl-tone-warn-ink-2); }
/* 交易哈希 / 长 ID：等宽 + 可断行，不撑破表格 */
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) .txid,
body.portal :is(.console-layout, .flow-wrap, .error-wrap, .auth-stage) code.txid {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  color: var(--dl-muted-strong);
  overflow-wrap: anywhere;
  word-break: break-all;
}

/* ---------------------------------------------------------------- 18. 打印 */
@media print {
  body.portal .topbar, .subnav, .task-dock, .toast { display: none !important; }
  /* 打印：强制纸面黑白，跟随主题会糊成一团 */
  body.portal { background: #fff; color: #000; }
  body.portal .card, body.portal .form-panel, .table-scroll { border-color: #999; box-shadow: none; }
}

/* ---------------------------------------------------------------- 19. WP2 收口（结构化行 / 小屏溢出） */
.pair-rows { border: 0; margin: 0 0 16px; padding: 0; }
.pair-rows legend { padding: 0; margin-bottom: 8px; color: var(--dl-ink-2); font-size: 13px; }
.pair-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-bottom: 12px; }
.pair-row .field { margin: 0; }
.pair-row input { min-height: 40px; }

/* chart：单日数据时不要拉成一根怪柱子 */
.chart { align-items: flex-end; }
.chart-col { min-width: 24px; }
.chart-x { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }

/* 小屏：顶栏与卡片允许收缩，长串（模型名 / 地址 / key 前缀）断行而不是撑破页面 */
@media (max-width: 820px) {
  .pair-row { grid-template-columns: minmax(0, 1fr); }
  body.portal .topbar-inner { flex-wrap: wrap; row-gap: 8px; }
  body.portal .topbar-actions { flex-wrap: wrap; gap: 8px; }
  .console-content, .console-content > *, .card, .metric-grid > *, .grid-2 > * { min-width: 0; }
  body.portal .meta, body.portal .hint, body.portal .lead, body.portal td, body.portal th,
  body.portal .code-block, body.portal code { overflow-wrap: anywhere; }
  body.portal .code-block { white-space: pre-wrap; }
  .section-heading { flex-wrap: wrap; row-gap: 4px; }
  .section-heading .meta { margin-left: 0; }
}

/* 筛选条：portal.css 对 .field 有更高优先级的宽度规则，这里按同权重重申一次 */
body.portal .card.inline-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px 16px; }
body.portal .card.inline-form .field { flex: 1 1 180px; min-width: 0; margin: 0; }
body.portal .card.inline-form .field-wide { flex: 2 1 260px; }
body.portal .card.inline-form .inline-actions { display: flex; gap: 8px; align-items: center; }
@media (max-width: 820px) {
  body.portal .card.inline-form .field { flex: 1 1 100%; }
  body.portal .card.inline-form .inline-actions { width: 100%; }
}

/* 表格小屏：宁可让表格在自己的滚动区里横向滚动，也不要把每个单元格挤成竖排碎字 */
@media (max-width: 820px) {
  body.portal .table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  body.portal .table-scroll > table { min-width: 620px; }
  body.portal .table-scroll th, body.portal .table-scroll td { white-space: nowrap; }
  body.portal .table-scroll caption { white-space: normal; }
}

/* 单行数值单元格（如「每日 $5.00 · 每月 —」）：任何宽度都不折行，避免数字被拆成两行 */
body.portal .nowrap-cell { white-space: nowrap; }

/* 长请求链接/模型 id：任何宽度都允许断行，避免撑破卡片或表格（1440 也一样） */
body.portal .console-content code { overflow-wrap: anywhere; word-break: break-word; }


/* 19. 窄屏表格 → 一行一卡（UAT 手机可用性）
   ≤560px 时，带 .table-stack 的表放弃横向滚动，改成「字段名 + 值」两列堆叠；
   thead 用 clip 隐藏但仍留在无障碍树（屏幕阅读器仍能读到表头语义）。
   桌面端（>560px）不生效，样式与像素均不变。 */
@media (max-width: 560px) {
  body.portal .table-scroll > table.table-stack { min-width: 0; display: block; }
  body.portal .table-stack thead {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap;
  }
  body.portal .table-stack tbody { display: block; }
  body.portal .table-stack tr {
    display: block; height: auto; margin: 0 0 10px; padding: 10px 12px;
    border: 1px solid var(--dl-line); border-radius: var(--dl-r-card);
    background: var(--dl-surface);
  }
  body.portal .table-stack tr:last-child { margin-bottom: 0; }
  body.portal .table-stack tr:hover { background: var(--dl-surface); }
  body.portal .table-stack td {
    display: grid; grid-template-columns: 88px minmax(0, 1fr); gap: 8px;
    border: 0; padding: 3px 0; white-space: normal;
  }
  body.portal .table-stack td::before {
    content: attr(data-label);
    color: var(--dl-muted); font-size: 12px; line-height: 1.6;
  }
  body.portal .table-stack td.num { text-align: left; }
  /* 胶囊是 grid 项目，默认会被拉满整行——收紧到内容宽度 */
  body.portal .table-stack td > .pill { justify-self: start; }
  body.portal .table-stack td[colspan] { display: block; padding: 4px 0; }
  body.portal .table-stack td[colspan]::before { content: none; }
  /* caption 从 table-caption 改成块级，否则会按 min-content 收成一列窄条（390px 实测） */
  body.portal .table-stack caption { display: block; width: 100%; text-align: left; white-space: normal; }
  /* 一个单元格里有多段内容时（徽标 + 说明、两个折叠面板），先包一层，避免它们各自变成 grid 项目 */
  body.portal .table-stack td > .cell-value, body.portal .table-stack td > .cell-actions { display: block; }
  body.portal .table-stack td > .cell-value > .pill { display: inline-flex; }
}
