/* Base tokens — the default look (incl. the "数字员工工作台" redesign from
   PR #123) is layered later in this file. Skins override these per [data-skin]. */
:root {
  color-scheme: light;
  --bg: #f4f6f8;
  --bg-soft: #eef2f5;
  --surface: #ffffff;
  --surface-raised: #ffffff;
  --surface-muted: #f8fafc;
  --fg: #18202a;
  --muted: #627084;
  --faint: #8b98aa;
  --border: #d9e0e8;
  --border-soft: #e8edf3;
  --accent: #2563eb;
  --accent-strong: #1d4ed8;
  --accent-soft: #e8f0ff;
  --success: #15803d;
  --success-soft: #e7f7ec;
  --warning: #b7791f;
  --warning-soft: #fff7df;
  --danger: #dc2626;
  --danger-soft: #feecec;
  --on-accent: #ffffff;
  --on-danger: #ffffff;
  --modal-shadow: 0 24px 80px rgba(0, 0, 0, 0.25);
  --modal-backdrop: rgba(10, 14, 18, 0.48);
  --qr-surface: #ffffff;
  --shadow: 0 18px 44px rgba(15, 23, 42, 0.08);
  --radius: 8px;
  --sidebar-width: 236px;
  --mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #111418;
  --bg-soft: #171b21;
  --surface: #191f26;
  --surface-raised: #202832;
  --surface-muted: #141a20;
  --fg: #ecf1f7;
  --muted: #a5b0bf;
  --faint: #7b8796;
  --border: #2f3946;
  --border-soft: #26303b;
  --accent: #6aa6ff;
  --accent-strong: #8ab8ff;
  --accent-soft: rgba(74, 144, 226, 0.16);
  --success: #5fd18b;
  --success-soft: rgba(64, 166, 98, 0.16);
  --warning: #e8bf62;
  --warning-soft: rgba(199, 142, 39, 0.16);
  --danger: #ff7a7a;
  --danger-soft: rgba(220, 38, 38, 0.16);
  --on-accent: #111418;
  --on-danger: #111418;
  --modal-shadow: 0 24px 80px rgba(0, 0, 0, 0.52);
  --modal-backdrop: rgba(0, 0, 0, 0.62);
  --qr-surface: #ffffff;
  --shadow: 0 18px 44px rgba(0, 0, 0, 0.28);
}

/* Named skins bring their own backdrop — hide PR #123's dark aurora overlay so
   it doesn't tint them (it stays for the default skin's dark mode). */
:root:not([data-skin="default"]):not([data-skin=""]) .aurora { display: none; }

* { box-sizing: border-box; }

body {
  margin: 0;
  min-width: 320px;
  font: 14px/1.45 Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  color: var(--fg);
  background: var(--bg);
}

a { color: inherit; }

.app-shell {
  min-height: 100vh;
  display: grid;
  grid-template-columns: var(--sidebar-width) minmax(0, 1fr);
}

.sidebar {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  padding: 18px 14px;
  background: var(--surface);
  border-right: 1px solid var(--border);
}

.brand {
  display: flex;
  gap: 10px;
  align-items: center;
  padding: 8px;
  text-decoration: none;
}

.brand-mark {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 8px;
  background: var(--fg);
  color: var(--surface);
  font: 700 12px/1 var(--mono);
  letter-spacing: 0;
}

.brand strong,
.topbar-title strong {
  display: block;
  font-size: 16px;
  letter-spacing: 0;
}

.brand small,
.topbar-title span {
  display: block;
  color: var(--muted);
  font-size: 12px;
}

.sidebar-nav {
  display: grid;
  gap: 4px;
  margin-top: 24px;
}

.sidebar-nav a {
  display: flex;
  align-items: center;
  min-height: 36px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  color: var(--muted);
  text-decoration: none;
  font-weight: 600;
}

.sidebar-nav a:hover {
  background: var(--surface-muted);
  color: var(--fg);
}

.sidebar-nav a.active {
  background: var(--accent-soft);
  color: var(--accent-strong);
}

.sidebar-foot {
  margin-top: auto;
  padding: 10px 8px 4px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.sidebar-toggle {
  flex: none;
  width: 28px;
  height: 28px;
  min-height: 28px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
}

.sidebar-toggle:hover {
  background: var(--surface-muted);
  color: var(--fg);
}

.sidebar-toggle svg {
  width: 14px;
  height: 14px;
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 160ms ease;
}

/* 收起态：侧栏收窄成图标栏（只在桌面布局生效；窄屏侧栏本来就折成顶栏） */
@media (min-width: 981px) {
  :root[data-sidebar="collapsed"] {
    --sidebar-width: 68px;
  }
  :root[data-sidebar="collapsed"] .sidebar {
    padding: 18px 10px;
  }
  :root[data-sidebar="collapsed"] .brand {
    justify-content: center;
    padding: 8px 0;
  }
  :root[data-sidebar="collapsed"] .brand > span:not(.brand-mark) {
    display: none;
  }
  :root[data-sidebar="collapsed"] .sidebar-nav a {
    justify-content: center;
    padding: 8px;
  }
  :root[data-sidebar="collapsed"] .sidebar-nav a span {
    display: none;
  }
  :root[data-sidebar="collapsed"] .connection-status {
    display: none;
  }
  :root[data-sidebar="collapsed"] .sidebar-foot {
    justify-content: center;
    padding: 10px 0 4px;
  }
  :root[data-sidebar="collapsed"] .sidebar-toggle svg {
    transform: rotate(180deg);
  }
}

.connection-status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
}

.connection-status::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--faint);
}

.connection-status.online::before { background: var(--success); }
.connection-status.offline::before { background: var(--danger); }
.connection-status.online { color: var(--success); }
.connection-status.offline { color: var(--danger); }

.workspace {
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 66px;
  padding: 12px 24px;
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--border-soft);
}

.topbar-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

.segmented {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
}

.segmented button {
  min-height: 28px;
  padding: 0 10px;
  border: 0;
  background: transparent;
  border-radius: 6px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
}

.segmented button.active {
  background: var(--fg);
  color: var(--surface);
}

.topbar-add-bot {
  white-space: nowrap;
}

/* Theme dropdown — custom listbox so each option can show a real Lucide line
   icon (a native <select> can't render SVG). Sits with the other topbar chips. */
.theme-menu { position: relative; }

.theme-menu-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 34px;
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--fg);
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  transition: border-color .15s ease;
}
.theme-menu-btn:hover { border-color: var(--muted); }

.tm-svg { display: block; width: 15px; height: 15px; }
.theme-menu-btn .tm-chev .tm-svg { width: 14px; height: 14px; opacity: 0.6; }
.tm-ic { display: inline-flex; }

.theme-menu-pop {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  z-index: 50;
  min-width: 192px;
  max-height: min(70vh, 460px);
  overflow: auto;
  padding: 6px;
  display: flex;
  flex-direction: column;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--modal-shadow);
}
.theme-menu-pop[hidden] { display: none; }

.tm-group {
  padding: 7px 8px 3px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--faint);
}

.tm-item {
  display: flex;
  align-items: center;
  justify-content: flex-start; /* override the base button{justify-content:center} */
  gap: 9px;
  width: 100%;
  padding: 7px 9px;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--fg);
  font-size: 13px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}
.tm-item .tm-svg { color: var(--muted); flex: 0 0 auto; }
.tm-item:hover { background: var(--surface-muted); }
.tm-item.active { background: var(--accent-soft); color: var(--accent-strong); }
.tm-item.active .tm-svg { color: var(--accent-strong); }

main {
  width: 100%;
  /* 不设上限：收起侧栏腾出的宽度交还内容区（看板/表格都按容器弹性布局）。 */
  max-width: none;
  padding: 24px;
}

.page {
  display: grid;
  gap: 18px;
}

.page-heading {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 20px;
}

.page-heading h1 {
  margin: 0;
  font-size: 28px;
  line-height: 1.15;
  letter-spacing: 0;
}

.page-heading p {
  margin: 6px 0 0;
  color: var(--muted);
  max-width: 720px;
}

.eyebrow {
  margin: 0 0 5px !important;
  color: var(--accent-strong) !important;
  font-size: 12px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0;
}

.panel,
.metric-card,
.bd-card {
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

/* Team pages: reserve a stable 2-line height for the heading lede so switching
   between 我的团队 / 团队管理 (whose descriptions wrap to a different number of
   lines) doesn't shift the sub-nav below it — no more flash on tab switch. */
.tf-lede {
  min-height: 41px;
}

.panel {
  overflow: hidden;
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  padding: 16px 18px;
  border-bottom: 1px solid var(--border-soft);
}

.panel-header h2 {
  margin: 0;
  font-size: 16px;
  letter-spacing: 0;
}

.panel-header p {
  margin: 4px 0 0;
  color: var(--muted);
  font-size: 13px;
}

/* Keep the "View all →" action on one line; let the title block shrink instead
   (narrow cards like Next Runs were wrapping the button onto two lines). */
.panel-header > div { min-width: 0; }
.panel-header .btn-link { white-space: nowrap; flex: 0 0 auto; }

.metric-grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(140px, 1fr));
  gap: 12px;
}

.metric-card {
  padding: 14px 15px;
}

.metric-card span {
  display: block;
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
}

.metric-card strong {
  display: block;
  margin-top: 6px;
  font-size: 28px;
  line-height: 1;
  letter-spacing: 0;
}

.metric-card small {
  display: block;
  margin-top: 8px;
  color: var(--faint);
  font-size: 12px;
}

.overview-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}

.overview-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.overview-list-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 12px 18px;
  border-bottom: 1px solid var(--border-soft);
}

.overview-list-row:last-child { border-bottom: 0; }
.overview-list-row strong { display: block; }
.overview-list-row span { color: var(--muted); font-size: 12px; }

.filters {
  display: flex;
  gap: 10px;
  margin: 0;
  padding: 14px 16px;
  flex-wrap: wrap;
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

button,
.btn-link {
  font: inherit;
}

/* ── Unified form controls ──────────────────────────────────────────────────
   One consistent look for every text input, <select> and <textarea>: themed
   surface, 1px border, var(--radius) corners, a custom dropdown chevron and a
   soft accent focus ring. Native appearance is reset so WebKit search fields and
   selects stop rendering their own mismatched pill/rounded shapes. */
input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=color]):not([type=file]):not([type=submit]):not([type=button]),
select,
textarea {
  min-height: 34px;
  padding: 7px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background-color: var(--surface-raised);
  color: var(--fg);
  font: inherit;
  font-size: 13px;
  line-height: 1.4;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  transition: border-color .15s ease, box-shadow .15s ease, background-color .15s ease;
}

textarea {
  min-height: 84px;
  resize: vertical;
}

select {
  padding-right: 30px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='none' stroke='%23808a99' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' d='M3 4.5 6 7.5 9 4.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
  cursor: pointer;
}

/* Multi-selects show a list, not a single value — no chevron, full padding. */
select[multiple] {
  background-image: none;
  padding-right: 8px;
}

input:not([type=checkbox]):not([type=radio]):hover:not(:disabled),
select:hover:not(:disabled),
textarea:hover:not(:disabled) {
  border-color: var(--muted);
}

input:not([type=checkbox]):not([type=radio]):focus,
select:focus,
textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

input::placeholder,
textarea::placeholder {
  color: var(--faint);
}

input:disabled,
select:disabled,
textarea:disabled {
  opacity: .55;
  cursor: not-allowed;
}

button:focus-visible,
.btn-link:focus-visible,
a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.filters input[type=search],
.filters input[type=text],
.filters select,
.form-row input[type=text],
.bd-body .bd-row input[type=text],
.oncall-row-body input[type=text] {
  min-height: 34px;
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--fg);
  background: var(--surface-raised);
}

.filters input[type=search] { min-width: min(260px, 100%); }
.filters select[multiple] { min-height: 72px; padding: 6px 8px; }

.sessions-filters {
  display: grid;
  grid-template-columns: minmax(260px, 1fr) minmax(132px, max-content) minmax(132px, max-content) max-content;
  align-items: center;
  gap: 10px 12px;
}

.sessions-filters input[type=search] {
  width: 100%;
  min-width: 0;
}

.sessions-filters select {
  width: 150px;
}

.sessions-view-toggle {
  flex: 0 0 auto;
}

.filter-toggle {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 34px;
  padding: 0 4px;
  color: var(--muted);
  font-weight: 700;
  white-space: nowrap;
}

.filter-toggle input {
  margin: 0;
}

.filter-check-group {
  display: grid;
  grid-template-columns: auto repeat(8, max-content);
  align-items: center;
  gap: 6px;
  min-height: 34px;
  margin: 0;
  padding: 0;
  border: 0;
  width: 100%;
  grid-column: 1 / -1;
}

.filter-check-label {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding-right: 4px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 800;
  white-space: nowrap;
}

.filter-check {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 32px;
  padding: 0 7px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-raised);
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
}

.filter-check:hover {
  border-color: var(--accent);
  color: var(--fg);
}

.filter-check input {
  margin: 0;
}

label {
  color: var(--muted);
}

table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  font-variant-numeric: tabular-nums;
}

th,
td {
  padding: 11px 13px;
  text-align: left;
  border-bottom: 1px solid var(--border-soft);
  white-space: nowrap;
  vertical-align: middle;
}

th {
  background: var(--surface-muted);
  color: var(--muted);
  font-size: 12px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0;
}

tbody tr:last-child td { border-bottom: 0; }

/* ── 首尾列固定的横向滚动矩阵（群组与 Bot）─────────────────────────────
   bot 一多中间的成员列就溢出视口，操作按钮被顶出屏幕。把圆角/阴影挪到
   滚动容器上，表格本体放开宽度横向滚，首列（群）和尾列（操作）sticky 钉住。 */
.table-scroll { overflow-x: auto; }
.matrix-scroll {
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.matrix-scroll table {
  width: max-content;
  min-width: 100%;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  overflow: visible; /* 基础样式的 overflow:hidden 会把 sticky 列钉死在表格自身 */
}
.matrix-scroll th:first-child,
.matrix-scroll td:first-child { position: sticky; left: 0; z-index: 2; }
.matrix-scroll th:last-child,
.matrix-scroll td:last-child { position: sticky; right: 0; z-index: 2; }
.matrix-scroll th:first-child,
.matrix-scroll th:last-child { z-index: 3; }
/* sticky 单元格必须有不透明底色，否则中间列会从底下透出来 */
.matrix-scroll td:first-child,
.matrix-scroll td:last-child { background: var(--surface); }
/* 暗色主题下表格本体有一层 3% 白的提亮，sticky 格子补同款混色保持一致 */
:root[data-theme="dark"] .matrix-scroll td:first-child,
:root[data-theme="dark"] .matrix-scroll td:last-child {
  background: color-mix(in srgb, #ffffff 3%, var(--surface));
}
/* 暗色主题 th 也是半透明提亮（4% 白）——sticky 表头必须不透明，否则横滚时
   中间列标题会从「群聊」「操作」底下透出来。7% ≈ 表格 3% + th 4% 的叠加效果 */
:root[data-theme="dark"] .matrix-scroll th:first-child,
:root[data-theme="dark"] .matrix-scroll th:last-child {
  background: color-mix(in srgb, #ffffff 7%, var(--surface));
}
.matrix-scroll tr[data-chat]:hover td:first-child,
.matrix-scroll tr[data-chat]:hover td:last-child { background: var(--surface-muted); }
/* 滚动边界提示线 */
.matrix-scroll th:first-child,
.matrix-scroll td:first-child { box-shadow: 1px 0 0 var(--border-soft); }
.matrix-scroll th:last-child,
.matrix-scroll td:last-child { box-shadow: -1px 0 0 var(--border-soft); }

/* ── 慢接口在途的页面级 loading 占位：在内容区水平垂直居中 ── */
.page-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  width: 100%;
  min-height: 220px;
  padding: 40px 20px;
  color: var(--muted);
  font-size: 13px;
  animation: page-loading-in 0.25s ease-out;
}
.page-loading-spin {
  width: 28px;
  height: 28px;
  flex: none;
  border-radius: 50%;
  border: 2.5px solid var(--border-soft);
  border-top-color: var(--accent);
  animation: page-loading-rotate 0.8s linear infinite;
}
@keyframes page-loading-rotate { to { transform: rotate(360deg); } }
@keyframes page-loading-in { from { opacity: 0; } }
th[data-sort] { cursor: pointer; user-select: none; }
th[data-sort]:hover,
th.sorted { color: var(--fg); background: var(--bg-soft); }
tr[data-id]:hover,
tr[data-chat]:hover { background: var(--surface-muted); cursor: pointer; }
.token-cell {
  text-align: center;
  font-variant-numeric: tabular-nums;
}

button,
.btn-link {
  min-height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 0 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-raised);
  color: var(--fg);
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}

button:hover,
.btn-link:hover {
  border-color: var(--accent);
}

button:disabled {
  opacity: 0.5;
  cursor: default;
}

button.contrast {
  background: var(--danger);
  color: var(--on-danger);
  border-color: var(--danger);
}

.btn-link.primary,
button.primary {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent);
  font-weight: 700;
}

.badge,
.status {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 22px;
  padding: 0 8px;
  border-radius: var(--radius-sm);
  font-size: 11px;
  font-weight: 800;
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0;
  text-decoration: none;
}

.badge {
  background: var(--surface-muted);
  color: var(--muted);
  border: 1px solid var(--border-soft);
}

.cli-claude-code { background: #e8f0ff; color: #234fb4; border-color: #c8d9ff; }
.cli-codex       { background: #fff0df; color: #a14c11; border-color: #ffd8ad; }
.cli-codex-app   { background: #e9f7ff; color: #11638f; border-color: #bde4fa; }
.cli-cursor      { background: #ece9ff; color: #5b4ac7; border-color: #d9d2ff; }
.cli-gemini      { background: #fde7f1; color: #a13268; border-color: #fac8df; }
.cli-opencode    { background: #e7f7ec; color: #176b36; border-color: #bfe8ce; }
.cli-mtr         { background: #e5f5ff; color: #0f6388; border-color: #b8e2f7; }
.cli-hermes      { background: #f0f4e4; color: #546b14; border-color: #d9e9a8; }
.cli-mira        { background: #e8f6f6; color: #12686d; border-color: #b9e4e5; }
.cli-pi          { background: #f1e9ff; color: #6b2bbf; border-color: #dcc9ff; }
.cli-aiden       { background: #fff7d1; color: #8b6508; border-color: #f7df87; }
.cli-coco        { background: #e4f7f2; color: #0c695b; border-color: #b7e4d9; }
.cli-unknown     { background: var(--surface-muted); color: var(--muted); }

:root[data-theme="dark"] .cli-claude-code,
:root[data-theme="dark"] .cli-codex,
:root[data-theme="dark"] .cli-codex-app,
:root[data-theme="dark"] .cli-cursor,
:root[data-theme="dark"] .cli-gemini,
:root[data-theme="dark"] .cli-opencode,
:root[data-theme="dark"] .cli-mtr,
:root[data-theme="dark"] .cli-hermes,
:root[data-theme="dark"] .cli-mira,
:root[data-theme="dark"] .cli-pi,
:root[data-theme="dark"] .cli-aiden,
:root[data-theme="dark"] .cli-coco {
  background: var(--surface-muted);
  color: var(--fg);
  border-color: var(--border);
}

.status-working,
.status-active { background: var(--accent-soft); color: var(--accent-strong); }
.status-idle { background: var(--surface-muted); color: var(--muted); }
.status-closed { background: var(--danger-soft); color: var(--danger); }
.status-analyzing { background: var(--warning-soft); color: var(--warning); }
.status-starting { background: var(--success-soft); color: var(--success); }
.status-limited { background: var(--danger-soft); color: var(--danger); }

/* ── Sessions board — "control-room signal wall" ─────────────────────────────
   Each column is a signal channel: a LED dot + uppercase channel label in the
   header, and every card inherits the channel color through `--col-signal`.
   The needs-you channel pulses; everything else stays calm. Terminal-native
   typography (mono labels, tabular numerals) over generic SaaS chrome. */
.sessions-board {
  display: grid;
  grid-template-columns: repeat(4, minmax(220px, 1fr));
  gap: 12px;
  align-items: start;
  /* faint blueprint grid behind the wall — atmosphere, not decoration */
  background-image:
    repeating-linear-gradient(0deg, color-mix(in srgb, var(--border-soft) 38%, transparent) 0 1px, transparent 1px 24px),
    repeating-linear-gradient(90deg, color-mix(in srgb, var(--border-soft) 38%, transparent) 0 1px, transparent 1px 24px);
  border-radius: var(--radius);
  padding: 10px;
}

.sessions-board[hidden] {
  display: none;
}

.session-board-column {
  --col-signal: var(--border);
  min-width: 0;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow);
  overflow: hidden;
}

.session-board-column > header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  padding: 12px;
  border-bottom: 1px solid var(--border-soft);
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--col-signal) 7%, transparent), transparent 80%),
    var(--surface-muted);
}

.session-board-column h2 {
  margin: 0;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* channel LED */
.session-board-column h2::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--col-signal);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--col-signal) 18%, transparent);
  flex: none;
}

.session-board-column p {
  margin: 4px 0 0;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.35;
}

.session-board-count {
  min-width: 28px;
  min-height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--col-signal) 10%, var(--surface-raised));
  border: 1px solid color-mix(in srgb, var(--col-signal) 35%, var(--border));
  color: color-mix(in srgb, var(--col-signal) 75%, var(--fg));
  font-family: var(--mono);
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.session-board-list {
  display: grid;
  gap: 10px;
  padding: 10px;
}

.session-board-empty {
  min-height: 64px;
  display: grid;
  place-items: center;
  color: var(--faint);
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  background: transparent;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.04em;
}

.session-board-needs-you {
  --col-signal: var(--danger);
  background: linear-gradient(180deg, color-mix(in srgb, var(--danger) 4%, var(--surface)), var(--surface) 140px);
}

/* the one channel that's allowed to breathe */
.session-board-needs-you h2::before {
  animation: board-led-pulse 1.6s ease-in-out infinite;
}

.session-board-starting {
  --col-signal: var(--warning);
}

.session-board-working {
  --col-signal: var(--success);
}

.session-board-idle {
  --col-signal: var(--faint);
}

@keyframes board-led-pulse {
  0%, 100% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--col-signal) 18%, transparent); }
  50% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--col-signal) 30%, transparent); }
}

.session-card {
  display: grid;
  gap: 10px;
  padding: 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-raised);
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: border-color 120ms ease, transform 120ms ease, box-shadow 120ms ease;
}

/* Entry animation ONLY on the board's first paint (.board-enter set by JS).
 * SSE-driven re-renders rebuild the DOM — replaying the staggered reveal on
 * every status update made the whole page flash. */
.board-enter .session-board-list .session-card {
  animation: board-card-in 280ms ease backwards;
}

/* stagger the first paint — one orchestrated reveal, then calm */
.board-enter .session-board-list .session-card:nth-child(1) { animation-delay: 30ms; }
.board-enter .session-board-list .session-card:nth-child(2) { animation-delay: 75ms; }
.board-enter .session-board-list .session-card:nth-child(3) { animation-delay: 120ms; }
.board-enter .session-board-list .session-card:nth-child(4) { animation-delay: 165ms; }
.board-enter .session-board-list .session-card:nth-child(n+5) { animation-delay: 210ms; }

@keyframes board-card-in {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: none; }
}

.session-card:hover {
  border-color: color-mix(in srgb, var(--col-signal) 55%, var(--border));
  transform: translateY(-1px);
  box-shadow: 0 6px 18px color-mix(in srgb, var(--col-signal) 12%, rgba(15, 23, 42, 0.10));
}

/* whole-card selection (no checkbox) — accent ring + soft tint */
.session-card.selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
  background: color-mix(in srgb, var(--accent) 5%, var(--surface-raised));
}

@media (prefers-reduced-motion: reduce) {
  .session-card { animation: none; transition: none; }
  .session-board-needs-you h2::before { animation: none; }
  .session-card:hover { transform: none; }
}

.session-card-top {
  display: grid;
  grid-template-columns: minmax(0, 1fr) max-content;
  align-items: start;
  gap: 8px;
}

.session-card-title {
  min-width: 0;
}

.session-card-title strong,
.session-card-title span {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.session-card-title strong {
  color: var(--fg);
  font-size: 13px;
}

.session-card-title span {
  margin-top: 2px;
  color: var(--muted);
  font-size: 12px;
}

.session-card-meta,
.session-card-time,
.session-card-actions {
  display: flex;
  align-items: center;
  gap: 7px;
  flex-wrap: wrap;
  min-width: 0;
}

.session-card-meta {
  color: var(--muted);
  font-size: 12px;
}

.session-card-time {
  justify-content: space-between;
  color: var(--muted);
  font-size: 12px;
}

.session-signal {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  justify-self: start;
  max-width: 100%;
  min-height: 22px;
  padding: 3px 8px;
  color: var(--danger);
  font-family: var(--mono);
  font-weight: 700;
  font-size: 11px;
  line-height: 1.35;
  letter-spacing: 0.04em;
  text-align: left;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--danger) 9%, transparent);
  border: 1px solid color-mix(in srgb, var(--danger) 30%, transparent);
}

.session-card-actions {
  padding-top: 2px;
  justify-content: flex-end;
}

.session-card-actions button,
.session-card-actions .btn-link {
  min-height: 30px;
  padding: 0 9px;
  font-size: 12px;
}

/* ── 看板视图（multica Issues 风格）：横排状态列 + 简洁卡片 ─────────────────── */
.sessions-kanban {
  display: flex;
  align-items: stretch;
  gap: 12px;
  overflow-x: auto;
  padding: 4px 2px 12px;
}

.sessions-kanban[hidden] {
  display: none;
}

.kanban-column {
  /* 弹性等分而非固定 280px：5 列在任何视口宽度下收缩到容器内，
     不再把页面撑出横向滚动条（极窄屏由媒体查询改纵向堆叠兜底）。 */
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  min-height: 320px;
  max-height: calc(100vh - 250px);
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  background: color-mix(in srgb, var(--surface-muted) 72%, transparent);
}

.kanban-column > header {
  flex: none;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 10px 12px 8px;
}

.kanban-col-icon {
  display: inline-flex;
  flex: none;
}

.kanban-col-icon svg {
  width: 14px;
  height: 14px;
  display: block;
}

.kanban-column h2 {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
  line-height: 1.4;
}

.kanban-col-count {
  color: var(--muted);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

/* 视图控件排布：团队筛选 + 分组维度切换 + 视图切换并排（窄屏自动换行） */
.sessions-view-controls {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  flex-wrap: wrap;
}

/* .segmented 自带 display:inline-flex 会盖掉 [hidden] 的 UA 样式——显式补回 */
.sessions-view-controls [hidden] {
  display: none !important;
}

/* 团队下拉做成与右侧 .segmented 同款胶囊：同高、同边框、圆角 999，
   去掉原生箭头换内嵌 chevron */
.kanban-team-select {
  appearance: none;
  -webkit-appearance: none;
  max-width: 200px;
  min-height: 38px;
  padding: 0 30px 0 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background-color: var(--surface);
  color: var(--fg);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.6 4.4 6 7.8l3.4-3.4' fill='none' stroke='%238b98aa' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 12px;
}

.kanban-team-select:hover {
  background-color: var(--surface-muted);
}

.kanban-team-select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* 团队筛选范围统计：让"筛掉了什么"可见 */
.kanban-team-stats {
  color: var(--muted);
  font-size: 12px;
  white-space: nowrap;
}

/* 团队清单加载中的整板占位（替代裸文本） */
.kanban-loading {
  flex: 1;
  min-height: 220px;
  display: grid;
  place-items: center;
  color: var(--faint);
  font-size: 13px;
  border: 1px dashed var(--border);
  border-radius: 12px;
}

.kanban-team-select:disabled {
  opacity: 0.7;
  cursor: default;
}

/* 对方部署的会话卡：来源徽章 + 虚线边框区分快照身份 */
.kanban-remote-badge {
  background: color-mix(in srgb, var(--accent) 12%, var(--surface-muted));
  color: var(--accent-strong);
  white-space: nowrap;
  flex: none;
}

.kanban-card-remote {
  border-style: dashed;
}

/* 机器人视角：bot 多时列不再无限压缩——固定列宽 + 容器横向滚动 */
.sessions-kanban.kanban-mode-bot .kanban-column {
  flex: 0 0 264px;
}

/* 整簇拖拽 */
.kanban-cluster > header {
  cursor: grab;
}

.kanban-cluster.dragging {
  opacity: 0.45;
}

/* 同群聚簇容器：虚线框 + 群名头，一眼看出卡片同属一个群 */
.kanban-cluster {
  display: grid;
  gap: 6px;
  padding: 6px;
  border: 1px dashed color-mix(in srgb, var(--accent) 38%, var(--border));
  border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 3%, transparent);
}

.kanban-cluster > header {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  padding: 0 2px;
  color: var(--muted);
  font-size: 11px;
  font-weight: 600;
}

.kanban-cluster-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.kanban-cluster-count {
  flex: none;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--surface-muted);
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* 团队模式列头：bot 头像替代状态图标 */
.kanban-col-avatar {
  display: inline-flex;
  flex: none;
}

.kanban-backlog .kanban-col-icon { color: var(--faint); }
.kanban-todo .kanban-col-icon { color: var(--muted); }
.kanban-in_progress .kanban-col-icon { color: var(--warning); }
.kanban-in_review .kanban-col-icon { color: var(--success); }
.kanban-done .kanban-col-icon { color: var(--accent); }

/* 拖拽视觉：目标列描边、插入位置在目标卡上沿画一条插入线、拖拽源半透明 */
.kanban-column.drag-over {
  border-color: color-mix(in srgb, var(--accent) 55%, var(--border));
}

.kanban-card.dragging {
  opacity: 0.45;
}

.kanban-card.drop-before {
  box-shadow: 0 -2px 0 0 var(--accent);
}

.kanban-col-list {
  flex: 1;
  min-height: 0;
  display: grid;
  gap: 8px;
  align-content: start;
  padding: 2px 8px 10px;
  overflow-y: auto;
}

.kanban-col-empty {
  padding: 32px 0;
  color: var(--faint);
  font-size: 12px;
  text-align: center;
}

.kanban-col-more {
  padding: 6px 0 2px;
  color: var(--faint);
  font-size: 11px;
  text-align: center;
}

.kanban-card {
  display: grid;
  gap: 6px;
  padding: 12px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-raised);
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
  cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease;
}

.kanban-card:hover {
  border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
  background: color-mix(in srgb, var(--accent) 4%, var(--surface-raised));
}

.kanban-card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.kanban-card-top {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

/* CLI 徽章别折行（claude-code 之类带连字符的会被 280px 卡片拆成两行） */
.kanban-card-top .badge {
  white-space: nowrap;
  flex: none;
}

/* 右上角动作区：运行状态点常显；重命名/详情按钮平时隐身，悬停/聚焦才浮现 */
.kanban-card-top-right {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.kanban-card-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--faint);
  flex: none;
}

.kanban-card-dot[data-status="working"],
.kanban-card-dot[data-status="analyzing"],
.kanban-card-dot[data-status="active"] {
  background: var(--success);
}

.kanban-card-dot[data-status="starting"] {
  background: var(--warning);
}

.kanban-card-dot[data-status="limited"] {
  background: var(--danger);
}

.kanban-card-dot[data-status="closed"] {
  background: var(--border);
}

/* 选择器带上 .kanban-card 提特异性：通用 .card-act 基础规则（display/尺寸）
   定义在本节之后，同特异性会反杀这里的覆盖。 */
.kanban-card .kanban-card-act {
  width: 24px;
  height: 24px;
  min-height: 24px;
  /* 不悬停时彻底不占位（opacity:0 仍会把短 ID 永久挤成省略号） */
  display: none;
}

.kanban-card:hover .kanban-card-act,
.kanban-card:focus-within .kanban-card-act {
  display: inline-flex;
}

/* 标题就地编辑输入框：占标题原位，不撑破卡片 */
.kanban-rename-input {
  width: 100%;
  min-width: 0;
  margin: 0;
  padding: 2px 6px;
  border: 1px solid var(--accent);
  border-radius: 6px;
  background: var(--surface);
  color: var(--fg);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.45;
}

.kanban-card-title {
  margin: 0;
  color: var(--fg);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.kanban-card-desc {
  margin: 0;
  color: var(--muted);
  font-size: 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.kanban-card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 2px;
  min-width: 0;
}

.kanban-card-owner {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  color: var(--fg);
  font-size: 12px;
}

.kanban-card-owner > span:last-child {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.kanban-card-updated {
  flex: none;
  color: var(--faint);
  font-size: 11px;
}

/* ── 页面内终端弹窗（看板卡片点击落点）───────────────────────────────────── */
.term-modal {
  width: min(1560px, 96vw);
  height: min(88vh, 1100px);
  max-height: calc(100vh - 24px);
  padding: 0;
  overflow: hidden;
}

.term-modal[open] {
  display: flex;
  flex-direction: column;
}

.term-modal-head {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border-soft);
}

.term-modal-title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.term-modal-title strong {
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 终端弹窗标题旁的铅笔：常显小尺寸，与 card-act 一致 */
.term-modal-title .card-act {
  width: 26px;
  height: 26px;
  min-height: 26px;
  flex: none;
}

/* 标题就地编辑输入框：宽度由 JS 按内容实测设定（fitInput），这里只给兜底上限 */
.term-modal-name-input {
  max-width: 60vw;
  margin: 0;
  padding: 3px 8px;
  border: 1px solid var(--accent);
  border-radius: 6px;
  background: var(--surface);
  color: var(--fg);
  font-size: 13px;
  font-weight: 600;
}

.term-modal-actions {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.term-modal-body {
  flex: 1;
  min-height: 0;
  display: flex;
}

.term-modal-frame {
  flex: 1;
  width: 100%;
  height: 100%;
  border: 0;
  background: #000;
}

.term-modal-loading {
  margin: auto;
  color: var(--faint);
  font-size: 13px;
}

/* ── 会话历史弹窗：飞书式左右气泡 ─────────────────────────────────────────── */
.history-modal {
  width: min(860px, 94vw);
  height: min(82vh, 900px);
  max-height: calc(100vh - 24px);
  padding: 0;
  overflow: hidden;
}

.history-modal[open] {
  display: flex;
  flex-direction: column;
}

.history-scope-tag {
  flex: none;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--surface-muted);
  color: var(--muted);
  font-size: 11px;
}

.history-body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  padding: 14px 16px;
  background: var(--bg-soft);
}

.history-list {
  display: grid;
  gap: 12px;
}

.history-msg {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  max-width: 82%;
}

.history-msg.mine {
  margin-left: auto;
  flex-direction: row-reverse;
}

.history-msg-main {
  min-width: 0;
}

.history-msg-meta {
  display: flex;
  gap: 8px;
  margin-bottom: 3px;
  color: var(--faint);
  font-size: 11px;
}

.history-msg.mine .history-msg-meta {
  justify-content: flex-end;
}

.history-bubble {
  padding: 8px 11px;
  border-radius: 10px;
  border: 1px solid var(--border-soft);
  background: var(--surface-raised);
  color: var(--fg);
  font-size: 13px;
  line-height: 1.55;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.history-msg.mine .history-bubble {
  background: var(--accent-soft);
  border-color: color-mix(in srgb, var(--accent) 30%, transparent);
}

.history-avatar-user {
  flex: none;
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 12px;
}

/* 真人头像（contact API 拿到的）——与首字圆同尺寸 */
.history-avatar-img {
  flex: none;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  object-fit: cover;
}

/* 左上角 brand 的 owner 头像：盖满 brand-mark 方块 */
.brand-mark {
  position: relative;
  overflow: hidden;
}

.brand-owner-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
}

.history-error {
  margin: auto;
  color: var(--faint);
  font-size: 13px;
}

/* 图标方按钮：会话卡片操作行一排，也被详情抽屉 .actions 复用（chat-scope 的
   「打开群聊」走同一个 .card-act）。图标宽度与语言无关，en/zh 都稳定一行，修掉了
   EN 文案更宽把「关闭」挤下行的崩布局。基础按钮外观放在通用 .card-act 选择器上，
   这样抽屉里的裸 <a class="card-act"> 也有按钮态；.session-card-actions 只管布局。
   SVG 走 stroke:currentColor。 */
.card-act svg,
.term-btn svg {
  width: 15px;
  height: 15px;
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.card-act {
  width: 30px;
  height: 30px;
  min-height: 30px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-raised);
  color: var(--muted);
  cursor: pointer;
  transition: color .15s ease, border-color .15s ease, background .15s ease, transform .07s ease;
}
.card-act:hover {
  color: var(--accent);
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 9%, var(--surface-raised));
}
.card-act.danger:hover {
  color: var(--danger);
  border-color: var(--danger);
  background: color-mix(in srgb, var(--danger) 9%, var(--surface-raised));
}
.card-act:active { transform: scale(0.9); }

/* 终端访问药丸：左「终端」段(accent ghost·只读旁观) + 右「钥匙」段(accent 实心·
   主操作，可写)。两段一个圆角壳，钥匙段实心更抢眼，读起来就是「这个才是操作」。 */
.term-pill {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.term-pill .term-btn {
  width: 30px;
  min-height: 28px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  /* the pill shell owns the rounding; reset so the global `button{border-radius:999px}`
     pill-ify rule doesn't turn the <button> key segment into a circle. */
  border-radius: 0;
  background: transparent;
  cursor: pointer;
  transition: background .15s ease, filter .15s ease, transform .07s ease;
}
/* selectors scoped to .term-pill so they out-specify `.term-pill .term-btn`
   above (both 0,2,0) by source order — otherwise the segments stay transparent. */
.term-pill .term-open {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}
.term-pill .term-open:hover { background: color-mix(in srgb, var(--accent) 24%, transparent); }
.term-pill .term-write {
  color: var(--on-accent);
  background: var(--accent);
  border-left: 1px solid color-mix(in srgb, var(--on-accent) 28%, var(--accent));
}
.term-pill .term-write:hover { filter: brightness(1.1); }
.term-pill .term-btn:active { transform: scale(0.88); }

dialog {
  width: min(680px, calc(100vw - 32px));
  max-height: calc(100vh - 32px);
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0;
  background: var(--surface);
  color: var(--fg);
  box-shadow: var(--modal-shadow);
}

dialog::backdrop {
  background: var(--modal-backdrop);
  backdrop-filter: blur(3px);
}

dialog article { padding: 20px; }
dialog header { margin-bottom: 14px; }
dialog h3 { margin: 0 0 4px; font-size: 18px; }
dialog header p { margin: 4px 0 0; color: var(--muted); }
dialog code,
td code,
.form-row code {
  padding: 2px 5px;
  border-radius: 5px;
  background: var(--surface-muted);
  color: var(--fg);
  font: 12px/1.3 var(--mono);
}

.actions,
.actions-cell {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
}

.actions { margin: 14px 0; }

.cell-in,
.cell-out,
.cell-error,
.cell-unknown {
  text-align: center;
  font-weight: 800;
}

.cell-in { color: var(--success); }
.cell-out { color: var(--faint); }
.cell-error { color: var(--danger); }
.cell-unknown { color: var(--warning); }

.checkbox-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  padding: 7px 0;
  color: var(--fg);
}

/* Keep the checkbox and its title on one line (don't let flex shrink the title
   into a vertical sliver), and drop the help text onto its own line, indented
   under the title for readability. */
.checkbox-row input[type=checkbox] { flex: 0 0 auto; margin: 0; }
.checkbox-row strong { flex: 0 0 auto; }

.checkbox-row small {
  flex: 1 1 100%;
  margin-left: 24px;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.5;
}

.empty {
  color: var(--muted);
  padding: 18px;
  text-align: center;
}

.form-row {
  display: block;
  margin: 12px 0;
}

.form-row span,
.bd-body .bd-row span {
  display: block;
  margin-bottom: 5px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
}

.form-row input[type=text],
.bd-body .bd-row input[type=text] {
  width: 100%;
}

fieldset {
  margin: 12px 0;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
}

fieldset legend {
  padding: 0 5px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 800;
}

.hint-ok,
.hint-warn {
  padding: 10px 12px;
  border-radius: 8px;
  margin: 10px 0;
  font-size: 13px;
}

.hint-ok {
  background: var(--success-soft);
  border: 1px solid color-mix(in srgb, var(--success) 28%, transparent);
  color: var(--success);
}

.hint-warn {
  background: var(--warning-soft);
  border: 1px solid color-mix(in srgb, var(--warning) 28%, transparent);
  color: var(--warning);
}

.hint-warn-inline { color: var(--warning); }

.bulk-bar {
  position: sticky;
  top: 78px;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  /* warning-soft 在暗色主题带透明度，sticky 浮条悬在列表上会透字——
     垫一层页面底色保证不透明，同时保留各主题自己的警示色调 */
  background: linear-gradient(var(--warning-soft), var(--warning-soft)), var(--bg);
  border: 1px solid color-mix(in srgb, var(--warning) 28%, transparent);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.bulk-bar[hidden] { display: none; }
.bulk-bar #bulk-count { font-weight: 800; margin-right: 4px; }
input.row-select,
#select-all { cursor: pointer; }

.onboarding-dialog {
  width: min(520px, calc(100vw - 32px));
}

.onboarding-status {
  margin: 12px 0;
  color: var(--muted);
  font-weight: 800;
}

.onboarding-status.status-completed { color: var(--success); }
.onboarding-status.status-failed { color: var(--danger); }

.qr-card {
  display: grid;
  justify-items: center;
  gap: 12px;
  margin: 14px 0;
  padding: 16px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  background: var(--surface-muted);
}

.qr-image {
  width: min(260px, 74vw);
  height: auto;
  border: 10px solid var(--qr-surface);
  border-radius: 8px;
  background: var(--qr-surface);
}

.onboarding-link {
  color: var(--accent-strong);
  font-weight: 800;
  text-decoration: none;
}

.onboarding-link:hover {
  text-decoration: underline;
}

.onboarding-form {
  display: grid;
  gap: 14px;
  margin: 14px 0 4px;
}

.onboarding-field {
  display: grid;
  gap: 6px;
  font-weight: 700;
  font-size: 13px;
  color: var(--muted);
}

.onboarding-field select,
.onboarding-field input {
  width: 100%;
  padding: 9px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
}

.onboarding-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin: 6px 0 0;
  padding: 0;
}

.form-error {
  margin: 0;
  color: var(--danger);
  font-weight: 700;
  font-size: 13px;
}

.onboarding-steps {
  margin: 10px 0 0;
  padding-left: 20px;
  display: grid;
  gap: 8px;
}

.onboarding-steps a {
  color: var(--accent-strong);
  font-weight: 700;
  text-decoration: none;
}

.onboarding-steps a:hover {
  text-decoration: underline;
}

.oncall-row {
  padding: 10px 0;
  border-top: 1px dashed var(--border);
}

.oncall-row:first-of-type { border-top: none; }

.oncall-row-body {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-top: 6px;
  padding-left: 24px;
  flex-wrap: wrap;
}

.oncall-row-body input[type=text] {
  flex: 1;
  min-width: 220px;
  font-family: var(--mono);
  font-size: 12px;
}

.oncall-row-body input[type=text]:disabled,
.bd-body .bd-row input[type=text]:disabled {
  background: var(--surface-muted);
  color: var(--faint);
}

.oncall-status {
  font-size: 12px;
  color: var(--muted);
}

.bd-card {
  max-width: 860px;
  padding: 16px 18px;
  margin-bottom: 14px;
}

.bd-card header {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 8px;
}

.bd-card header strong { font-size: 16px; }
.bd-card header small { color: var(--muted); font-family: var(--mono); font-size: 11px; }
.bd-body .bd-row { margin: 12px 0 8px; }
.bd-body .bd-row label { display: block; }
.bd-body .bd-row input[type=text] { font-family: var(--mono); font-size: 12px; }
.bd-meta { display: flex; gap: 16px; flex-wrap: wrap; color: var(--muted); font-size: 12px; margin: 8px 0; }
.oncall-status.hint-ok { background: transparent; border: none; padding: 0; margin: 0; color: var(--success); }

/* Each bd-card groups several independent defaults (oncall, signature, …);
   bd-section gives every group its own labelled, divided block. */
.bd-section { padding-top: 14px; }
.bd-section + .bd-section { margin-top: 14px; border-top: 1px solid var(--border-soft); }
.bd-section-title {
  margin: 0 0 4px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}
.bd-section-note { margin: 6px 0 0; color: var(--muted); font-size: 12px; line-height: 1.5; }

/* A lighter sub-group inside a bd-section (e.g. 主动开工 lives under 新群 Oncall).
   Separated by a soft top rule + indent so it reads as "part of this block". */
.bd-subsection {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px dashed var(--border-soft);
}
.bd-subsection-title {
  margin: 0 0 6px;
  font-size: 12px;
  font-weight: 700;
  color: var(--fg);
}
/* 入群首轮 prompt textarea — themed to match the text inputs (dark surface,
   bordered) rather than the unstyled browser default. */
.bd-subsection textarea {
  width: 100%;
  box-sizing: border-box;
  padding: 10px;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.5;
  color: var(--fg);
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  resize: vertical;
}

@media (max-width: 980px) {
  .app-shell {
    grid-template-columns: 1fr;
  }
  .sidebar {
    position: static;
    height: auto;
    padding: 12px;
    border-right: 0;
    border-bottom: 1px solid var(--border);
  }
  .sidebar-nav {
    display: flex;
    overflow-x: auto;
    margin-top: 12px;
    padding-bottom: 2px;
  }
  .sidebar-nav a {
    flex: 0 0 auto;
  }
  .sidebar-foot {
    display: none;
  }
  .topbar {
    position: static;
    align-items: flex-start;
  }
  .metric-grid,
  .overview-grid {
    grid-template-columns: 1fr;
  }
  main {
    padding: 16px;
    overflow-x: hidden;
  }
}

@media (max-width: 860px) {
  .filter-check-group {
    grid-template-columns: auto repeat(4, max-content);
  }
}

@media (max-width: 720px) {
  .topbar {
    flex-direction: column;
    padding: 14px 16px;
  }
  .topbar-actions {
    width: 100%;
    justify-content: flex-start;
  }
  .theme-switch {
    max-width: 100%;
    overflow-x: auto;
  }
  .page-heading {
    flex-direction: column;
    align-items: stretch;
  }
  .filters {
    align-items: stretch;
  }
  .sessions-filters {
    grid-template-columns: 1fr;
  }
  .filters input[type=search],
  .filters select,
  .filters button,
  .filter-check-group {
    width: 100%;
  }
  .sessions-filters select {
    width: 100%;
  }
  .sessions-view-toggle {
    display: flex;
    width: 100%;
    max-width: calc(100vw - 32px);
    min-width: 0;
  }
  .sessions-view-toggle button {
    flex: 1 1 0;
    min-width: 0;
  }
  .sessions-board {
    grid-template-columns: 1fr;
  }
  /* 窄屏看板：列改纵向堆叠，高度交还内容 */
  .sessions-kanban {
    flex-direction: column;
  }
  .kanban-column {
    flex: none;
    min-height: 0;
    max-height: none;
  }
  .kanban-col-list {
    overflow-y: visible;
  }
  .term-modal {
    width: calc(100vw - 16px);
    height: calc(100vh - 24px);
  }
  .filter-check-group {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .filter-check-label {
    grid-column: 1 / -1;
  }

  .filter-check {
    justify-content: flex-start;
  }
  table {
    display: block;
    overflow-x: auto;
  }
}

/* ─── Roles Page ─── */
.roles-page .roles-layout {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: 16px;
  height: calc(100vh - 160px);
  min-height: 400px;
}

/* ─── Tree Panel (left) ─── */
.roles-tree-panel {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.roles-tree-header {
  padding: 12px;
  border-bottom: 1px solid var(--border);
  display: flex;
  gap: 8px;
}
.roles-tree-header input { flex: 1; }
.roles-tree {
  flex: 1;
  overflow-y: auto;
}

/* ─── Group rows ─── */
.roles-group-section {
  border-bottom: 1px solid var(--border-soft);
}
.roles-group-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  cursor: pointer;
  user-select: none;
  transition: background 0.12s;
}
.roles-group-row:hover { background: var(--bg-soft); }
.roles-group-row.selected { background: var(--accent-soft); }
.roles-group-arrow {
  font-size: 11px;
  color: var(--muted);
  width: 14px;
  flex-shrink: 0;
  text-align: center;
}
.roles-group-icon {
  font-size: 15px;
  flex-shrink: 0;
}
.roles-group-info {
  flex: 1;
  min-width: 0;
}
.roles-group-name {
  font-weight: 600;
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.roles-group-meta {
  font-size: 11px;
  color: var(--muted);
  margin-top: 1px;
}
.roles-group-chevron { display: none; }

/* ─── Bot rows (nested) ─── */
.roles-bot-list {
  /* visible when parent is expanded */
}
.roles-bot-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px 8px 20px;
  cursor: pointer;
  border-top: 1px solid var(--border-soft);
  transition: background 0.12s;
}
.roles-bot-row:hover { background: var(--bg-soft); }
.roles-bot-row.selected {
  background: var(--accent-soft);
  border-left: 3px solid var(--accent);
  padding-left: 17px;
}
.roles-bot-indent { width: 14px; flex-shrink: 0; }
.roles-bot-icon {
  font-size: 13px;
  flex-shrink: 0;
  opacity: 0.7;
}
.roles-bot-info {
  flex: 1;
  min-width: 0;
}
.roles-bot-name {
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.roles-bot-id {
  font-size: 10px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ─── Badges ─── */
.roles-badge {
  font-size: 10px;
  padding: 2px 8px;
  border-radius: 10px;
  white-space: nowrap;
  font-weight: 600;
  flex-shrink: 0;
}
.roles-badge.has-role {
  background: var(--success-soft);
  color: var(--success);
}
.roles-badge.no-role {
  background: var(--bg-soft);
  color: var(--faint);
}

/* ─── Editor Panel (right) ─── */
.roles-editor-panel {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.roles-editor-empty {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  font-size: 14px;
  padding: 32px;
  text-align: center;
}
.roles-editor-form {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: 20px;
  gap: 14px;
  overflow-y: auto;
}

/* ─── Editor breadcrumb ─── */
.roles-editor-breadcrumb {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  font-weight: 600;
}
.roles-breadcrumb-sep {
  color: var(--faint);
  font-weight: 400;
}
#roles-editor-group-name { color: var(--fg); }
#roles-editor-bot-name { color: var(--accent-strong); }
.roles-editor-meta-line {
  font-size: 11px;
  color: var(--faint);
  font-family: var(--mono);
}

/* ─── Editor textarea ─── */
#roles-editor-textarea {
  flex: 1;
  min-height: 220px;
  font-family: var(--mono);
  font-size: 13px;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  resize: vertical;
  line-height: 1.55;
  background: var(--surface-muted);
  color: var(--fg);
  tab-size: 2;
}
#roles-editor-textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* ─── Editor footer ─── */
.roles-editor-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.roles-bytecount {
  font-size: 12px;
  color: var(--muted);
  font-family: var(--mono);
}
.roles-bytecount.warn { color: var(--warning); }
.roles-bytecount.over { color: var(--danger); font-weight: 700; }
.roles-editor-actions { display: flex; gap: 8px; }

/* ─── Saved flash ─── */
.roles-saved-flash {
  font-size: 12px;
  color: var(--success);
  font-weight: 600;
  animation: roles-fade-out 2s ease forwards;
}
.roles-save-error {
  color: var(--danger);
  animation-duration: 3s;
}
@keyframes roles-fade-out {
  0% { opacity: 1; }
  70% { opacity: 1; }
  100% { opacity: 0; }
}

/* ─── Preview panel ─── */
.roles-preview {
  background: var(--surface-muted);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  padding: 14px;
  font-size: 13px;
  max-height: 140px;
  overflow-y: auto;
}
.roles-preview pre {
  margin: 8px 0 0 0;
  white-space: pre-wrap;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.5;
}

.roles-empty {
  padding: 24px;
  text-align: center;
  color: var(--muted);
  font-size: 13px;
}

@media (max-width: 720px) {
  .roles-page .roles-layout {
    grid-template-columns: 1fr;
    height: auto;
  }
}

/* ─── Workflow runtime: list, detail, parallel timeline, IO cards ─── */
/* Status pills + dangling badges piggyback on the global semantic tokens
   (--accent / --success / --warning / --danger + their *-soft pairs) so
   light <-> dark switches just by flipping data-theme on <html>. */
.wf-status { padding: 0.05rem 0.4rem; border-radius: 999px; font-size: 11px; font-variant: small-caps; background: var(--bg-soft); color: var(--muted); }
.wf-status-pending       { background: var(--bg-soft); color: var(--muted); }
.wf-status-running       { background: var(--accent-soft); color: var(--accent); }
.wf-status-waiting       { background: var(--warning-soft); color: var(--warning); }
.wf-status-succeeded     { background: var(--success-soft); color: var(--success); }
.wf-status-failed        { background: var(--danger-soft); color: var(--danger); }
.wf-status-cancelled     { background: var(--bg-soft); color: var(--muted); }
.wf-dangling.has  { color: var(--danger); font-weight: 600; }
.wf-dangling.none { color: var(--muted); }
.wf-run-error { margin-top: 0.25rem; max-width: 360px; white-space: normal; overflow-wrap: anywhere; color: var(--muted); font-size: 12px; }

.wf-subnav { display: flex; gap: 0.4rem; margin-bottom: 0.8rem; border-bottom: 1px solid var(--border); padding-bottom: 0; }
.wf-subnav a { padding: 0.35rem 0.7rem; color: var(--muted); text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.wf-subnav a.active { color: var(--fg); border-bottom-color: var(--fg); font-weight: 600; }
.wf-subnav a:hover { color: var(--fg); }

.wf-detail-head { display: flex; align-items: flex-start; gap: 0.8rem; margin-bottom: 0.8rem; }
.wf-detail-head h2 { margin: 0 0 0.15rem; font-size: 18px; line-height: 1.25; }
.wf-detail-head #wf-cancel-run { margin-left: auto; }
.wf-detail-head #wf-detail-refresh { white-space: nowrap; }
.wf-summary-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 0.6rem; margin-bottom: 0.8rem; }
.wf-summary-item { border: 1px solid var(--border); border-radius: 6px; padding: 0.5rem 0.6rem; min-width: 0; background: var(--surface); }
.wf-summary-item span { display: block; color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0; margin-bottom: 0.2rem; }
.wf-summary-item strong { display: block; font-weight: 600; overflow-wrap: anywhere; }
.wf-summary-item .wf-status { display: inline-block; }
.wf-panel { border: 1px solid var(--border); border-radius: 6px; padding: 0.7rem; margin-bottom: 0.8rem; background: var(--surface); }
.wf-panel-title { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.5rem; }
.wf-panel-title h3 { margin: 0; font-size: 15px; }
.wf-panel-title button { margin-left: auto; }
.wf-dangling-panel.has { border-color: var(--danger); background: var(--danger-soft); }
.wf-dangling-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 0.7rem; }
.wf-dangling-grid ul { margin: 0.25rem 0 0; padding-left: 1.1rem; }
.wf-dangling-grid li { margin: 0.15rem 0; overflow-wrap: anywhere; }
.wf-table-scroll { overflow-x: auto; }
.wf-timeline-scroll { max-height: 520px; overflow: auto; border: 1px solid var(--border); border-radius: 4px; }
.wf-timeline-scroll table th { position: sticky; top: 0; z-index: 1; }
.wf-parallel-axis { display: flex; justify-content: space-between; color: var(--muted); font-size: 12px; margin: 0 0 0.35rem 170px; }
.wf-parallel-list { display: grid; gap: 0.45rem; }
.wf-parallel-row { display: grid; grid-template-columns: 160px minmax(220px, 1fr); gap: 0.6rem; align-items: center; }
.wf-parallel-label { min-width: 0; }
.wf-parallel-label code { display: block; overflow-wrap: anywhere; }
.wf-parallel-label .muted { display: block; margin-top: 0.1rem; font-size: 11px; overflow-wrap: anywhere; }
.wf-parallel-track { position: relative; height: 28px; border: 1px solid var(--border); border-radius: 4px; background: linear-gradient(90deg, var(--bg-soft), var(--surface)); overflow: hidden; }
/* Coloured bars sit on top of any theme; foreground stays #fff because the
   bars carry the strong fill themselves and the contrast holds in both modes. */
.wf-parallel-bar { position: absolute; top: 4px; bottom: 4px; min-width: 3px; border-radius: 3px; display: flex; align-items: center; padding: 0 0.35rem; color: #fff; font-size: 11px; line-height: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wf-parallel-running, .wf-parallel-effectAttempting { background: var(--accent); }
.wf-parallel-waiting { background: var(--warning); }
.wf-parallel-pending { background: #8250df; }
.wf-parallel-succeeded { background: var(--success); }
.wf-parallel-failed, .wf-parallel-timedOut { background: var(--danger); }
.wf-parallel-cancelled { background: var(--faint); }
:root[data-theme="dark"] .wf-parallel-running,
:root[data-theme="dark"] .wf-parallel-effectAttempting { color: var(--on-accent); }
:root[data-theme="dark"] .wf-parallel-waiting,
:root[data-theme="dark"] .wf-parallel-succeeded,
:root[data-theme="dark"] .wf-parallel-cancelled { color: var(--bg); }
:root[data-theme="dark"] .wf-parallel-failed,
:root[data-theme="dark"] .wf-parallel-timedOut { color: var(--on-danger); }
.wf-io-list { display: grid; gap: 0.7rem; }
.wf-io-card { border: 1px solid var(--border); border-radius: 6px; padding: 0.65rem; background: var(--surface); }
.wf-io-card.is-focused { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.wf-io-card header { display: flex; justify-content: space-between; gap: 0.8rem; align-items: flex-start; }
.wf-io-card header > div:first-child { min-width: 0; }
.wf-io-card header code, .wf-io-meta code { overflow-wrap: anywhere; }
.wf-io-card header .muted { display: block; margin-top: 0.1rem; overflow-wrap: anywhere; }
.wf-io-meta { margin-top: 0.35rem; color: var(--muted); font-size: 12px; overflow-wrap: anywhere; }
.wf-approval-box { margin-top: 0.6rem; padding: 0.55rem; border: 1px solid var(--warning); border-radius: 4px; background: var(--warning-soft); }
.wf-approval-box label span { display: block; margin-bottom: 0.25rem; color: var(--muted); font-size: 12px; }
.wf-approval-comment { width: 100%; resize: vertical; min-height: 48px; padding: 0.35rem 0.45rem; border: 1px solid var(--border); border-radius: var(--radius); font: inherit; background: var(--surface); color: var(--fg); }
.wf-approval-actions { display: flex; align-items: center; gap: 0.45rem; margin-top: 0.45rem; flex-wrap: wrap; }
.wf-approval-status { margin: 0.5rem 0 0; }
.wf-io-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 0.55rem; margin-top: 0.6rem; }
.wf-io-block { border: 1px solid var(--border); border-radius: 4px; background: var(--surface-muted); min-width: 0; }
.wf-io-block summary { cursor: pointer; padding: 0.4rem 0.5rem; font-weight: 600; }
.wf-io-block summary .muted { margin-left: 0.3rem; font-weight: 400; }
.wf-io-pre { margin: 0; padding: 0.5rem; max-height: 340px; overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere; font: 12px/1.45 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; background: var(--surface); color: var(--fg); border-top: 1px solid var(--border); }
.wf-io-empty { padding: 0.5rem; }
.wf-terminal-block { grid-column: 1 / -1; }
.wf-terminal-actions { padding: 0.45rem 0.5rem; border-top: 1px solid var(--border); background: var(--surface); display: flex; gap: 0.75rem; flex-wrap: wrap; align-items: center; }
.wf-resume-status { padding: 0.35rem 0.5rem; border-top: 1px solid var(--border); }
/* Terminal iframe content is itself a CLI surface (Tokyo Night theme), so
   the wrapper stays dark in both modes to avoid a white flash before xterm
   boots. */
.wf-terminal-frame { display: block; width: 100%; height: 460px; border: 0; border-top: 1px solid var(--border); background: #0d1117; }
.wf-error-msg { display: block; margin-top: 0.15rem; white-space: pre-wrap; overflow-wrap: anywhere; font-size: 12px; }

/* Workflow catalog */
.catalog-head, .catalog-detail-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.8rem; margin-bottom: 0.8rem; }
.catalog-head h2, .catalog-detail-head h2 { margin: 0 0 0.15rem; font-size: 18px; line-height: 1.25; }
.catalog-run-form { display: grid; gap: 0.65rem; max-width: 900px; }
.catalog-run-form label span, .catalog-param header { display: block; margin-bottom: 0.25rem; color: var(--muted); font-size: 12px; }
.catalog-run-form textarea, .catalog-run-form input[type=text] { width: 100%; padding: 0.4rem 0.5rem; border: 1px solid var(--border); border-radius: var(--radius); font: 12px/1.45 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: var(--fg); background: var(--surface); }
.catalog-run-form textarea { resize: vertical; min-height: 150px; }
.catalog-chat-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.65rem; }
.catalog-param-errors { background: var(--warning-soft); border-left: 3px solid var(--warning); padding: 0.45rem 0.65rem; border-radius: 3px; }
.catalog-param-errors ul { margin: 0.35rem 0 0; padding-left: 1.2rem; }
.catalog-param-list { display: grid; gap: 0.55rem; }
.catalog-param { border: 1px solid var(--border); border-radius: 4px; padding: 0.55rem; background: var(--surface-muted); }
.catalog-param header { display: flex; align-items: center; gap: 0.45rem; flex-wrap: wrap; margin-bottom: 0.35rem; }

@media (max-width: 720px) {
  .wf-detail-head { flex-wrap: wrap; align-items: center; }
  .wf-detail-head > div { min-width: 0; flex: 1 1 220px; }
  .wf-detail-head h2 code { overflow-wrap: anywhere; }
  .wf-detail-head #wf-cancel-run { margin-left: 0; }
  .wf-summary-grid { grid-template-columns: 1fr 1fr; }
  .wf-panel { padding: 0.55rem; }
  .wf-parallel-axis { margin-left: 0; }
  .wf-parallel-row { grid-template-columns: 1fr; gap: 0.25rem; }
  .wf-io-card header { flex-direction: column; }
  .wf-io-grid { grid-template-columns: 1fr; }
  .wf-terminal-frame { height: 360px; }
  .wf-approval-actions button { flex: 1 1 120px; }
  .wf-timeline-scroll { max-height: 420px; }
  .catalog-head, .catalog-detail-head { flex-direction: column; }
  .catalog-chat-grid { grid-template-columns: 1fr; }
}

@media (max-width: 460px) {
  .wf-summary-grid { grid-template-columns: 1fr; }
  .wf-approval-actions { flex-direction: column; align-items: stretch; }
  .wf-approval-actions button { width: 100%; }
}

/* ════════════════════════════════════════════════════════════════════════════
   数字员工工作台 — 统一视觉层（未来 / 科技 / 数字人）
   设计语言：深空底 + 蓝青极光氛围、玻璃面板、胶囊按钮与标签、
   每个 bot 一颗专属色相的"数字生命球"。强视觉只在品牌区（团队卡），
   工作面（board / 表格 / 表单页）保持密度与可扫描性。
   状态光语义：青=执行中 · 绿=就绪 · 琥珀=需要你 · 红=异常 · 蓝=启动中
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  --info: #2779d8;
  --info-soft: rgba(39, 121, 216, 0.12);
  --accent: #0a8bbf;
  --accent-strong: #066d99;
  --accent-soft: rgba(10, 139, 191, 0.10);
  --radius: 14px;
  --radius-sm: 9px;
  --sidebar-width: 250px;
}

:root[data-theme="dark"] {
  --bg: #07090f;
  --bg-soft: #0b0f17;
  --surface: #0e141d;
  --surface-raised: #151d29;
  --surface-muted: #0b1018;
  --fg: #eef2f8;
  --muted: #99a3b3;
  --faint: #5d6675;
  --border: #25303f;
  --border-soft: #1a2330;
  --accent: #5be3ff;
  --accent-strong: #8feeff;
  --accent-soft: rgba(91, 227, 255, 0.13);
  --success: #4ee69a;
  --success-soft: rgba(78, 230, 154, 0.13);
  --warning: #ffc24d;
  --warning-soft: rgba(255, 194, 77, 0.13);
  --danger: #ff6b81;
  --danger-soft: rgba(255, 107, 129, 0.13);
  --info: #4f8bff;
  --info-soft: rgba(79, 139, 255, 0.14);
  --on-accent: #051018;
  --on-danger: #1c0508;
  --shadow: 0 14px 40px rgba(0, 0, 0, 0.34);
}

/* ── 极光底（dark 专属氛围；紫色只允许出现在这里）─────────────────────────── */
.aurora { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.aurora i { position: absolute; border-radius: 50%; filter: blur(110px); opacity: 0.30; }
.aurora .a1 { width: 520px; height: 420px; left: -20px; top: -200px; background: #1b4dff; opacity: 0.18; }
.aurora .a2 { width: 520px; height: 440px; right: -90px; top: -80px; background: #00c2d8; opacity: 0.17; }
.aurora .a3 { width: 620px; height: 420px; left: 38%; bottom: -280px; background: #6b3df0; opacity: 0.13; }
:root[data-theme="light"] .aurora { display: none; }

.app-shell { position: relative; z-index: 1; }

/* ── 固定侧栏（标准后台布局：齐顶到底、直角、细分割线，背景与主区连续）─────── */
.sidebar {
  margin: 0;
  top: 0;
  height: 100vh;
  border: 0;
  border-right: 1px solid var(--border);
  border-radius: 0;
  background: var(--surface);
}
:root[data-theme="dark"] .sidebar {
  background: rgba(255, 255, 255, 0.03);
  backdrop-filter: blur(20px);
  border-right-color: var(--border);
}

/* 品牌：发光的数字生命球 */
.brand-mark {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: radial-gradient(circle at 32% 28%, #aef4ff, var(--accent) 38%, #4f8bff 68%, #0a1530 105%);
  box-shadow: 0 0 16px color-mix(in srgb, var(--accent) 50%, transparent), inset 0 0 8px rgba(255, 255, 255, 0.3);
}

.sidebar-nav { gap: 2px; }
.sidebar-nav a {
  gap: 11px;
  border-radius: 11px;
  font-size: 13px;
}
.sidebar-nav a svg {
  width: 16px;
  height: 16px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.sidebar-nav a.active {
  background: linear-gradient(120deg, color-mix(in srgb, var(--accent) 16%, transparent), color-mix(in srgb, var(--info) 10%, transparent));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 30%, transparent);
  color: var(--accent-strong);
}

/* ── 顶栏：透明玻璃，仅右侧操作区（品牌只在侧栏出现一次，顶栏不重复）──────── */
.topbar {
  background: color-mix(in srgb, var(--bg) 70%, transparent);
  border-bottom: 1px solid var(--border);
  justify-content: flex-end;
}
.topbar-title { display: none; }

/* ── 全局 attention strip（任何页面常驻，待处理最高优先级）────────────────── */
.attention-strip {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 14px 24px 0;
  padding: 9px 16px;
  border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--warning) 45%, transparent);
  background: linear-gradient(90deg, color-mix(in srgb, var(--warning) 14%, transparent), color-mix(in srgb, var(--warning) 4%, transparent) 70%);
  font-size: 13px;
}
.attention-strip[hidden] { display: none; }
.attention-strip b { color: var(--warning); }
.attention-strip-ic {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  flex: none;
  display: grid;
  place-items: center;
  background: var(--warning);
  color: #2a1c00;
  font-size: 11px;
  font-weight: 800;
  animation: strip-pulse 2s ease-in-out infinite;
}
@keyframes strip-pulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--warning) 40%, transparent); }
  50% { box-shadow: 0 0 0 5px color-mix(in srgb, var(--warning) 18%, transparent); }
}
.attention-strip-longest {
  color: var(--muted);
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.attention-strip-go {
  margin-left: auto;
  flex: none;
  padding: 5px 14px;
  border-radius: 999px;
  background: var(--warning);
  color: #2a1c00;
  font-size: 12px;
  font-weight: 700;
  text-decoration: none;
}
@media (prefers-reduced-motion: reduce) {
  .attention-strip-ic { animation: none; }
}

/* ── 胶囊化：按钮 / 标签 / 分段控件 ──────────────────────────────────────── */
button,
.btn-link {
  border-radius: 999px;
  padding: 0 13px;
}
button.primary,
.btn-link.primary {
  background: linear-gradient(120deg, var(--accent), var(--info));
  border-color: transparent;
  color: var(--on-accent);
  box-shadow: 0 4px 16px color-mix(in srgb, var(--accent) 28%, transparent);
}
button.contrast {
  background: transparent;
  border-color: color-mix(in srgb, var(--danger) 45%, transparent);
  color: var(--danger);
}
button.contrast:hover { background: var(--danger-soft); border-color: var(--danger); }
.segmented { border-radius: 999px; }
.segmented button { border-radius: 999px; }
.segmented button.active {
  background: linear-gradient(120deg, var(--accent), var(--info));
  color: var(--on-accent);
}
.badge,
.status {
  border-radius: 999px;
  text-transform: none;
  font-weight: 700;
}

/* 状态光语义重排：青=执行中 · 蓝=启动 · 绿=就绪 · 琥珀/红=要人管 */
.status-working,
.status-active { background: var(--accent-soft); color: var(--accent); }
.status-analyzing { background: var(--accent-soft); color: var(--accent); }
.status-starting { background: var(--info-soft); color: var(--info); }
.status-idle { background: var(--success-soft); color: var(--success); }
.status-limited { background: var(--danger-soft); color: var(--danger); }

/* ── 玻璃面板（dark 下生效；light 保持实底）─────────────────────────────── */
:root[data-theme="dark"] .panel,
:root[data-theme="dark"] .metric-card,
:root[data-theme="dark"] .bd-card,
:root[data-theme="dark"] .filters {
  background: rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(18px);
  border-color: rgba(255, 255, 255, 0.08);
  background-image: linear-gradient(165deg, rgba(255, 255, 255, 0.045), transparent 40%);
}

/* ── 数字生命球（bot avatar，全站统一）──────────────────────────────────── */
.orb-avatar {
  position: relative;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  flex: none;
  background: radial-gradient(circle at 32% 28%, #d8fbff, var(--c1, #5be3ff) 38%, var(--c2, #4f8bff) 72%, #060d1c 105%);
  box-shadow: 0 0 16px color-mix(in srgb, var(--c1, #5be3ff) 32%, transparent), inset 0 0 9px rgba(255, 255, 255, 0.28);
}
.orb-avatar-sm {
  width: 24px;
  height: 24px;
  box-shadow: inset 0 0 5px rgba(255, 255, 255, 0.28);
}
/* 有真实头像时，把渐变球底色换成中性占位，避免"先亮球后头像"的闪烁；
   渐变球只在头像加载失败（onerror 移除 .orb-has-img）时作为兜底重新露出。 */
.orb-avatar.orb-has-img {
  background: var(--surface-muted);
  box-shadow: inset 0 0 0 1px var(--border);
}
/* 真实头像盖在数字生命球上；onerror 时移除自身，露出下面的渐变球兜底。
   不加淡入动画——innerHTML 每次重绘都会重建 <img>，动画会跟着重放，看起来就是
   头像在"刷新"。图本身有 HTTP 缓存 + URL 走 localStorage，重建即同步出图。 */
.orb-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
}
/* 飞书群头像：圆角方形，和圆形的 bot 头像一眼区分开。 */
.orb-avatar.orb-square,
.orb-avatar.orb-square .orb-img { border-radius: 9px; }
.orb-avatar.orb-square.orb-avatar-sm,
.orb-avatar.orb-square.orb-avatar-sm .orb-img { border-radius: 6px; }
/* 群列表名称单元格：群头像 + 群名/ID 横向排列。 */
.g-chat-cell { display: flex; align-items: center; gap: 8px; }
.g-chat-meta { min-width: 0; }
.orb-dot {
  position: absolute;
  right: -1px;
  bottom: -1px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 2px solid var(--bg);
}
.orb-dot-ok { background: var(--success); }
.orb-dot-busy { background: var(--accent); }
.orb-dot-warn { background: var(--warning); }
.orb-dot-off { background: var(--faint); }

/* ── 工作台首页 ─────────────────────────────────────────────────────────── */
.hero-pills { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 14px;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
}
:root[data-theme="dark"] .pill { background: rgba(255, 255, 255, 0.045); }
.pill b { color: var(--fg); font-size: 14px; }
.pill-hot { border-color: color-mix(in srgb, var(--warning) 45%, transparent); color: var(--warning); }
.pill-hot b { color: var(--warning); }

.sect-head { display: flex; align-items: baseline; gap: 10px; margin-top: 2px; }
.sect-head h2 { margin: 0; font-size: 15px; font-weight: 700; }
.sect-head span { color: var(--faint); font-size: 12px; }
.sect-head a { margin-left: auto; color: var(--accent); font-size: 12px; text-decoration: none; font-weight: 600; }

.team-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 13px;
}
/* AI 团队折叠/展开开关：贴着卡片栅格下沿居中，弱化成次级控件 */
.team-toggle {
  justify-self: center;
  margin-top: -6px;
  min-height: 28px;
  padding: 3px 18px;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 999px;
  box-shadow: none;
}
.team-toggle:hover { color: var(--fg); border-color: var(--accent); }
.mate {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 16px 15px 13px;
  border-radius: 16px;
  border: 1px solid var(--border-soft);
  background: var(--surface);
  box-shadow: var(--shadow);
}
:root[data-theme="dark"] .mate {
  background: rgba(255, 255, 255, 0.045);
  backdrop-filter: blur(20px);
  border-color: rgba(255, 255, 255, 0.09);
  background-image: linear-gradient(165deg, rgba(255, 255, 255, 0.05), transparent 38%);
}
.mate-attn {
  border-color: color-mix(in srgb, var(--warning) 42%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--warning) 18%, transparent), 0 10px 32px color-mix(in srgb, var(--warning) 9%, transparent);
}
.mate-off { opacity: 0.55; }
.mate-top { display: flex; align-items: center; gap: 11px; }
.mate-id { min-width: 0; }
.mate-id b { display: block; font-size: 14px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.mate-role {
  display: inline-block;
  margin-top: 3px;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--muted);
  background: var(--surface-muted);
  border: 1px solid var(--border-soft);
  padding: 1px 9px;
  border-radius: 999px;
}
:root[data-theme="dark"] .mate-role { background: rgba(255, 255, 255, 0.07); border-color: rgba(255, 255, 255, 0.1); }
.mate-task {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.5;
  min-height: 36px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.mate-task b { color: var(--fg); font-weight: 600; }
.mate-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 11px;
  color: var(--faint);
}
.tag {
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 700;
  white-space: nowrap;
}
.tag-run { color: var(--accent); background: var(--accent-soft); }
.tag-ok { color: var(--success); background: var(--success-soft); }
.tag-warn { color: var(--warning); background: var(--warning-soft); }
.tag-off { color: var(--faint); background: var(--surface-muted); }
:root[data-theme="dark"] .tag-off { background: rgba(255, 255, 255, 0.06); }

/* 需要你处理 — 队列卡 */
.qgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); gap: 12px; }
.qcard {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 15px;
  border-radius: 14px;
  border: 1px solid color-mix(in srgb, var(--warning) 38%, transparent);
  background: linear-gradient(120deg, color-mix(in srgb, var(--warning) 10%, transparent), transparent 60%), var(--surface);
}
:root[data-theme="dark"] .qcard {
  background: linear-gradient(120deg, color-mix(in srgb, var(--warning) 10%, transparent), transparent 60%), rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(18px);
}
.qcard-empty {
  border-style: dashed;
  border-color: var(--border);
  background: transparent;
  color: var(--faint);
  font-size: 12px;
  justify-content: center;
}
.qcard-tx { min-width: 0; flex: 1; }
.qcard-tx b { display: block; font-size: 12.5px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.qcard-tx span { color: var(--muted); font-size: 11.5px; }
.qcard-go {
  flex: none;
  padding: 6px 14px;
  border-radius: 999px;
  background: var(--warning);
  color: #2a1c00;
  font-size: 12px;
  font-weight: 700;
  text-decoration: none;
}

/* 下方两栏 */
.overview-cols { display: grid; grid-template-columns: 1.7fr 1fr; gap: 14px; align-items: start; }
.overview-side { display: grid; gap: 14px; }
.sess-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 18px;
  border-bottom: 1px solid var(--border-soft);
}
.sess-row:last-child { border-bottom: 0; }
.sess-tx { min-width: 0; flex: 1; }
.sess-tx b { display: block; font-size: 12.5px; font-weight: 600; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.sess-tx span { color: var(--faint); font-size: 11px; }

/* 此刻概览圆环 */
.donut-row { display: flex; align-items: center; gap: 18px; padding: 14px 18px; }
.donut-wrap { position: relative; width: 92px; height: 92px; flex: none; }
.donut {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  -webkit-mask: radial-gradient(farthest-side, transparent 63%, #000 64%);
  mask: radial-gradient(farthest-side, transparent 63%, #000 64%);
}
/* flex 列整体居中：grid 两行会均分高度，把数字顶上、标签压到环上 */
.donut-center {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  text-align: center;
}
.donut-center b { display: block; font-size: 20px; line-height: 1.1; }
.donut-center span {
  display: block;
  font-size: 9px;
  line-height: 1.2;
  color: var(--faint);
  max-width: 54px; /* 限制在中心孔内，英文 Active Sessions 折两行 */
}
.donut-legend { display: grid; gap: 7px; font-size: 12px; color: var(--muted); }
.donut-legend i { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 7px; }

/* ── 会话看板：工作面收敛（弱玻璃 + 高密度 + 新状态光）───────────────────── */
.sessions-board {
  background-image: none;
  padding: 0;
}
.session-board-column { border-radius: 16px; }
:root[data-theme="dark"] .session-board-column {
  background: rgba(255, 255, 255, 0.03);
  border-color: rgba(255, 255, 255, 0.08);
}
:root[data-theme="dark"] .session-board-column > header {
  background: linear-gradient(180deg, color-mix(in srgb, var(--col-signal) 8%, transparent), transparent 85%);
  border-color: rgba(255, 255, 255, 0.07);
}
.session-board-column h2 {
  font-family: inherit;
  letter-spacing: 0.02em;
  text-transform: none;
  font-size: 13px;
}
.session-board-count { border-radius: 999px; font-family: inherit; }
.session-board-needs-you { --col-signal: var(--warning); }
.session-board-needs-you { background: linear-gradient(180deg, color-mix(in srgb, var(--warning) 4%, var(--surface)), var(--surface) 140px); }
.session-board-starting { --col-signal: var(--info); }
.session-board-working { --col-signal: var(--accent); }
.session-board-idle { --col-signal: var(--success); }
:root[data-theme="dark"] .session-board-needs-you {
  background: linear-gradient(180deg, color-mix(in srgb, var(--warning) 6%, transparent), transparent 140px), rgba(255, 255, 255, 0.03);
}
.session-card { border-radius: 12px; }
:root[data-theme="dark"] .session-card {
  background: rgba(13, 17, 26, 0.6);
  border-color: rgba(255, 255, 255, 0.08);
}
.session-card-top {
  grid-template-columns: max-content minmax(0, 1fr) max-content;
  align-items: center;
}
.session-signal {
  color: var(--warning);
  background: color-mix(in srgb, var(--warning) 10%, transparent);
  border-color: color-mix(in srgb, var(--warning) 32%, transparent);
  font-family: inherit;
  border-radius: 999px;
}

/* 表格 hover 行 */
:root[data-theme="dark"] table { background: rgba(255, 255, 255, 0.03); }
:root[data-theme="dark"] th { background: rgba(255, 255, 255, 0.04); }

/* ── 会话筛选条：一行轻量胶囊，不再是一面板 checkbox 墙 ─────────────────── */
.sessions-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 9px;
  padding: 0;
  background: transparent;
  border: 0;
  box-shadow: none;
}
.sessions-filters input[type=search] {
  flex: 0 1 300px;
  min-width: 200px;
  min-height: 36px;
  padding: 0 16px;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid var(--border-soft);
}
.sessions-filters select {
  width: auto;
  min-height: 36px;
  padding: 0 30px 0 14px;
  border-radius: 999px;
  background-color: var(--surface);
  border: 1px solid var(--border-soft);
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%2399a3b3' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  color: var(--muted);
  font-weight: 600;
  font-size: 12.5px;
  cursor: pointer;
}
:root[data-theme="dark"] .sessions-filters input[type=search],
:root[data-theme="dark"] .sessions-filters select {
  background-color: rgba(255, 255, 255, 0.045);
  border-color: rgba(255, 255, 255, 0.09);
}
.sessions-filters input[type=search]:focus,
.sessions-filters select:focus {
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
}

/* 「仅活跃」toggle chip：checkbox 隐藏，整个胶囊就是开关 */
.sessions-filters .filter-toggle {
  min-height: 36px;
  padding: 0 16px;
  border-radius: 999px;
  border: 1px solid var(--border-soft);
  background: var(--surface);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  user-select: none;
}
:root[data-theme="dark"] .sessions-filters .filter-toggle {
  background: rgba(255, 255, 255, 0.045);
  border-color: rgba(255, 255, 255, 0.09);
}
.sessions-filters .filter-toggle input { position: absolute; opacity: 0; pointer-events: none; }
.sessions-filters .filter-toggle span::before {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  margin-right: 7px;
  background: var(--faint);
  vertical-align: 1px;
}
.sessions-filters .filter-toggle:has(input:checked) {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  background: var(--accent-soft);
}
.sessions-filters .filter-toggle:has(input:checked) span::before {
  background: var(--accent);
  box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 60%, transparent);
}

/* CLI 下拉 chip + 弹层 */
.filter-cli { position: relative; }
.filter-cli summary {
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 36px;
  padding: 0 30px 0 16px;
  border-radius: 999px;
  border: 1px solid var(--border-soft);
  background-color: var(--surface);
  color: var(--muted);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  user-select: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%2399a3b3' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
}
.filter-cli summary::-webkit-details-marker { display: none; }
:root[data-theme="dark"] .filter-cli summary {
  background-color: rgba(255, 255, 255, 0.045);
  border-color: rgba(255, 255, 255, 0.09);
}
.filter-cli summary b { font-weight: 700; color: var(--fg); }
.filter-cli summary b.cli-filter-active { color: var(--accent); }
.filter-cli[open] summary {
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
  color: var(--fg);
}
.filter-cli-pop {
  position: absolute;
  z-index: 30;
  top: calc(100% + 8px);
  left: 0;
  width: 340px;
  max-width: calc(100vw - 48px);
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  padding: 13px;
  border-radius: 14px;
  border: 1px solid var(--border);
  background: var(--surface-raised);
  box-shadow: var(--modal-shadow);
}
:root[data-theme="dark"] .filter-cli-pop {
  background: #131a26;
  border-color: rgba(255, 255, 255, 0.12);
}
.filter-cli-pop .filter-check {
  min-height: 28px;
  padding: 0 12px;
  border-radius: 999px;
  border: 1px solid var(--border-soft);
  background: transparent;
  color: var(--muted);
  font-size: 11.5px;
  font-weight: 600;
  cursor: pointer;
}
.filter-cli-pop .filter-check input { position: absolute; opacity: 0; pointer-events: none; }
.filter-cli-pop .filter-check:has(input:checked) {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  background: var(--accent-soft);
}

@media (max-width: 720px) {
  .sessions-filters input[type=search] { flex: 1 1 100%; }
  .filter-cli-pop { left: auto; right: 0; }
}

/* ── Bot 配置 → 数字员工档案（master-detail）────────────────────────────── */
.bd-layout {
  display: grid;
  grid-template-columns: 252px minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}

/* 左：员工名册 */
.bd-roster {
  border-radius: 16px;
  border: 1px solid var(--border-soft);
  background: var(--surface);
  padding: 8px;
  display: grid;
  gap: 3px;
  position: sticky;
  top: 84px;
}
:root[data-theme="dark"] .bd-roster {
  background: rgba(255, 255, 255, 0.045);
  backdrop-filter: blur(18px);
  border-color: rgba(255, 255, 255, 0.09);
}
.bd-roster-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: 11px;
  cursor: pointer;
}
.bd-roster-item:hover { background: var(--surface-muted); }
:root[data-theme="dark"] .bd-roster-item:hover { background: rgba(255, 255, 255, 0.06); }
.bd-roster-item.on {
  background: linear-gradient(120deg, color-mix(in srgb, var(--accent) 14%, transparent), color-mix(in srgb, var(--info) 8%, transparent));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 30%, transparent);
}
.bd-roster-tx { min-width: 0; flex: 1; }
.bd-roster-tx b { display: block; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bd-roster-tx span { display: block; color: var(--faint); font-size: 10.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bd-roster-flag {
  flex: none;
  font-size: 9px;
  font-weight: 700;
  color: var(--warning);
  border: 1px solid color-mix(in srgb, var(--warning) 42%, transparent);
  border-radius: 999px;
  padding: 1px 7px;
}

/* 右：档案 */
.bd-profile { max-width: none; padding: 0; background: transparent; border: 0; box-shadow: none; }
:root[data-theme="dark"] .bd-profile { background: transparent; backdrop-filter: none; background-image: none; }
.bd-profile-head {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 0;
  padding: 18px 20px;
  border-radius: 18px;
  border: 1px solid var(--border-soft);
  background: var(--surface);
  box-shadow: var(--shadow);
}
:root[data-theme="dark"] .bd-profile-head {
  background: rgba(255, 255, 255, 0.045);
  backdrop-filter: blur(18px);
  border-color: rgba(255, 255, 255, 0.09);
  background-image: linear-gradient(160deg, color-mix(in srgb, var(--accent) 6%, transparent), transparent 45%);
}
.bd-profile-head .orb-avatar { width: 54px; height: 54px; }
.bd-profile-id { min-width: 0; }
.bd-profile-id strong { display: block; font-size: 18px; }
.bd-profile-id .mate-role { margin-top: 5px; }
.bd-profile-id code {
  display: block;
  margin-top: 5px;
  padding: 0;
  background: transparent;
  color: var(--faint);
  font-size: 10.5px;
}
.bd-profile-meta {
  margin: 0 0 0 auto;
  display: grid;
  gap: 5px;
  text-align: right;
  flex: none;
}
.bd-profile-meta small { color: var(--muted); font-size: 11.5px; }
.bd-profile-meta .bd-meta-ok { color: var(--success); }

/* 配置 tile 两栏 */
.bd-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
  align-items: start;
  margin-top: 14px;
}
.bd-tile {
  border-radius: 16px;
  border: 1px solid var(--border-soft);
  background: var(--surface);
  box-shadow: var(--shadow);
  padding: 4px 18px 16px;
}
:root[data-theme="dark"] .bd-tile {
  background: rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(18px);
  border-color: rgba(255, 255, 255, 0.08);
}
.bd-tile .bd-section { padding-top: 14px; }
.bd-tile .bd-section + .bd-section { margin-top: 14px; border-top: 1px solid var(--border-soft); }
.bd-tile .bd-section-title {
  font-size: 12.5px;
  letter-spacing: 0.02em;
  text-transform: none;
  color: var(--fg);
  display: flex;
  align-items: center;
  gap: 8px;
}
.bd-tile .bd-section-title::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 55%, transparent);
  flex: none;
}

.settings-grid {
  display: grid;
  grid-template-columns: minmax(320px, 760px);
  gap: 14px;
  max-width: 100%;
  min-width: 0;
}

.settings-card {
  padding: 4px 18px 16px;
  min-width: 0;
  overflow: hidden;
}

.settings-card .bd-section { padding-top: 14px; }
.settings-card .bd-section + .bd-section { margin-top: 14px; border-top: 1px solid var(--border-soft); }
.settings-actions { margin-top: 8px; }
.settings-card .toggle-row { min-width: 0; }
.settings-card .toggle-tx { min-width: 0; }
.settings-card .toggle-tx strong,
.settings-card .toggle-tx small {
  overflow-wrap: anywhere;
}
.settings-card .toggle-tx small {
  -webkit-line-clamp: unset;
  color: var(--muted);
}

/* toggle 开关行：checkbox 隐藏，switch 是视觉开关 */
.toggle-row {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 9px 0;
  cursor: pointer;
  color: var(--fg);
}
.toggle-row input { position: absolute; opacity: 0; pointer-events: none; }
.toggle-row .switch {
  width: 36px;
  height: 20px;
  border-radius: 999px;
  background: var(--border);
  position: relative;
  flex: none;
  margin-top: 1px;
  transition: background 140ms ease;
}
.toggle-row .switch::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--muted);
  transition: left 140ms ease, background 140ms ease;
}
.toggle-row input:checked + .switch {
  background: linear-gradient(120deg, var(--accent), var(--info));
  box-shadow: 0 0 12px color-mix(in srgb, var(--accent) 28%, transparent);
}
.toggle-row input:checked + .switch::after { left: 18px; background: #fff; }
.toggle-row input:disabled + .switch { opacity: 0.4; }
.toggle-tx { min-width: 0; }
.toggle-tx strong { display: block; font-size: 12.5px; font-weight: 600; }
.toggle-tx small {
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-top: 2px;
  color: var(--faint);
  font-size: 11px;
  line-height: 1.5;
  cursor: pointer;
}
.toggle-tx small:hover { color: var(--muted); }
.toggle-tx small.open { -webkit-line-clamp: unset; color: var(--muted); }
/* toggle 行之外的长帮助文字（签名/额度说明）同样默认一行，点开展开 */
.bd-tile small.bd-help {
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
  color: var(--faint);
  font-size: 11px;
  line-height: 1.5;
  cursor: pointer;
}
.bd-tile small.bd-help:hover { color: var(--muted); }
.bd-tile small.bd-help.open { -webkit-line-clamp: unset; color: var(--muted); }
@media (prefers-reduced-motion: reduce) {
  .toggle-row .switch, .toggle-row .switch::after { transition: none; }
}

.bd-tile textarea,
.bd-tile input[type=text],
.bd-tile input[type=number] {
  width: 100%;
  box-sizing: border-box;
  padding: 9px 13px;
  border: 1px solid var(--border);
  border-radius: 11px;
  background: var(--surface-raised);
  color: var(--fg);
  font: 12px/1.5 var(--mono);
}
:root[data-theme="dark"] .bd-tile textarea,
:root[data-theme="dark"] .bd-tile input[type=text],
:root[data-theme="dark"] .bd-tile input[type=number] {
  background: rgba(13, 17, 26, 0.55);
  border-color: rgba(255, 255, 255, 0.1);
}

@media (max-width: 980px) {
  .bd-layout { grid-template-columns: 1fr; }
  .bd-roster { position: static; display: flex; overflow-x: auto; }
  .bd-roster-item { flex: 0 0 auto; }
  .bd-grid { grid-template-columns: 1fr; }
  .bd-profile-head { flex-wrap: wrap; }
  .bd-profile-meta { text-align: left; margin-left: 0; }
}

/* ── 全站收尾：长尾页面对齐设计语言 ──────────────────────────────────────── */

/* 兜底表单控件基线（零特异性 :where，不会压过上面的胶囊规则）：
   接入点 / 团队 / 弹窗里的裸 input、select、textarea 统一圆角与底色 */
.page :where(input:not([type=checkbox], [type=radio]), select, textarea),
dialog :where(input:not([type=checkbox], [type=radio]), select, textarea) {
  border: 1px solid var(--border);
  border-radius: 11px;
  background: var(--surface-raised);
  color: var(--fg);
  padding: 8px 12px;
  font: inherit;
}
:root[data-theme="dark"] .page :where(input:not([type=checkbox], [type=radio]), select, textarea),
:root[data-theme="dark"] dialog :where(input:not([type=checkbox], [type=radio]), select, textarea) {
  background: rgba(13, 17, 26, 0.55);
  border-color: rgba(255, 255, 255, 0.1);
}

/* 筛选条统一（群组 / 定时 / 工作流共用 .filters）：去面板底，控件胶囊化 */
.filters {
  padding: 0;
  background: transparent;
  border: 0;
  box-shadow: none;
}
.filters input[type=search],
.filters input[type=text],
.filters select {
  min-height: 36px;
  border-radius: 999px;
  padding: 0 16px;
  background: var(--surface);
  border: 1px solid var(--border-soft);
}
.filters select {
  padding-right: 30px;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%2399a3b3' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  color: var(--muted);
  font-weight: 600;
  font-size: 12.5px;
  cursor: pointer;
}
:root[data-theme="dark"] .filters input[type=search],
:root[data-theme="dark"] .filters input[type=text],
:root[data-theme="dark"] .filters select {
  background-color: rgba(255, 255, 255, 0.045);
  border-color: rgba(255, 255, 255, 0.09);
}
.filters .filter-toggle {
  min-height: 36px;
  padding: 0 16px;
  border-radius: 999px;
  border: 1px solid var(--border-soft);
  background: var(--surface);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  user-select: none;
}
:root[data-theme="dark"] .filters .filter-toggle {
  background: rgba(255, 255, 255, 0.045);
  border-color: rgba(255, 255, 255, 0.09);
}
.filters .filter-toggle:has(input:checked) {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  background: var(--accent-soft);
}
.filters .filter-toggle input { position: absolute; opacity: 0; pointer-events: none; }
/* 文本没包 span 的旧式 toggle（群组/定时页）：状态点画在 label 上 */
.filters .filter-toggle:not(:has(> span))::before {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  margin-right: 7px;
  background: var(--faint);
}
.filters .filter-toggle:not(:has(> span)):has(input:checked)::before {
  background: var(--accent);
  box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 60%, transparent);
}

/* 通用 .card（接入点等页面在用）→ 玻璃面板 */
.card {
  border: 1px solid var(--border-soft);
  border-radius: 16px;
  background: var(--surface);
  box-shadow: var(--shadow);
  padding: 16px 18px;
}
:root[data-theme="dark"] .card {
  background: rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(18px);
  border-color: rgba(255, 255, 255, 0.08);
}

/* 角色管理：树面板对齐名册风格 */
:root[data-theme="dark"] .roles-tree-panel,
:root[data-theme="dark"] .roles-editor-panel {
  background: rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(18px);
  border-color: rgba(255, 255, 255, 0.08);
}
.roles-tree-panel,
.roles-editor-panel { border-radius: 16px; }
.roles-group-icon {
  display: inline-flex;
  width: 16px;
  height: 16px;
  color: var(--muted);
}
.roles-group-icon svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.roles-bot-row.selected {
  background: linear-gradient(120deg, color-mix(in srgb, var(--accent) 14%, transparent), color-mix(in srgb, var(--info) 8%, transparent));
  border-left: 0;
  padding-left: 20px;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 30%, transparent);
}
.roles-group-row.selected { background: var(--accent-soft); }
.roles-badge { border-radius: 999px; }

/* ── 看板列顺序自定义：列头可拖拽 + hover 出现 ‹/› 按钮 ──────────────────── */
.session-board-column > header[draggable] { cursor: grab; }
.session-board-column > header[draggable]:active { cursor: grabbing; }
.session-board-head-right {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: none;
}
.session-board-move { display: inline-flex; gap: 3px; opacity: 0; transition: opacity 120ms ease; }
.session-board-column > header:hover .session-board-move,
.session-board-move:focus-within { opacity: 1; }
@media (hover: none) {
  .session-board-move { opacity: 1; }
}
.session-board-move button {
  min-height: 22px;
  min-width: 22px;
  padding: 0;
  border-radius: 999px;
  font-size: 13px;
  line-height: 1;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--border-soft);
}
.session-board-move button:hover:not(:disabled) {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
}
.session-board-move button:disabled { opacity: 0.3; }
.session-board-column.dragging { opacity: 0.55; }
.session-board-column.drag-over {
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 35%, transparent);
}
@media (prefers-reduced-motion: reduce) {
  .session-board-move { transition: none; }
}

/* 工作流子导航：下划线 tab → 胶囊段 */
.wf-subnav { border-bottom: 0; gap: 6px; }
.wf-subnav a {
  border: 1px solid transparent;
  border-radius: 999px;
  padding: 6px 16px;
  margin-bottom: 0;
  font-size: 12.5px;
  font-weight: 600;
}
.wf-subnav a.active {
  color: var(--accent-strong);
  border-color: color-mix(in srgb, var(--accent) 35%, transparent);
  background: var(--accent-soft);
  border-bottom-color: color-mix(in srgb, var(--accent) 35%, transparent);
}

@media (max-width: 980px) {
  .sidebar { margin: 0; height: auto; border-radius: 0; top: 0; }
  .overview-cols { grid-template-columns: 1fr; }
  .attention-strip { margin: 12px 16px 0; }
}

/* ════════════════════════════════════════════════════════════════════════════
   "2077" CYBERPUNK SKIN
   Distilled from the kaboo webui (frontend/src/styles/cyberpunk.css). The whole
   dashboard is variable-driven, so re-pointing the design tokens under
   :root[data-skin="cyber"] re-skins every component; the rest of this section
   adds the neon flourishes (grid, scanlines, data-rain, glow, sharp corners).
   Placed last in the file so it wins over the light/dark token blocks via source
   order (equal specificity). The light/dark mode is intentionally ignored here —
   2077 ships its own dark neon palette.
   ════════════════════════════════════════════════════════════════════════════ */

:root[data-skin="cyber"] {
  color-scheme: dark;
  --bg: hsl(240 44% 6%);
  --bg-soft: hsl(240 40% 8%);
  --surface: hsl(236 40% 9% / 0.72);
  --surface-raised: hsl(238 42% 12% / 0.84);
  --surface-muted: hsl(236 30% 14% / 0.7);
  --fg: hsl(188 72% 88%);
  --muted: hsl(196 30% 64%);
  --faint: hsl(196 22% 52%);
  --border: hsl(196 82% 44% / 0.5);
  --border-soft: hsl(196 70% 40% / 0.3);
  --accent: hsl(186 100% 56%);
  --accent-strong: hsl(186 100% 72%);
  --accent-soft: hsl(186 100% 52% / 0.16);
  --success: hsl(150 85% 58%);
  --success-soft: hsl(150 85% 50% / 0.16);
  --warning: hsl(56 97% 60%);
  --warning-soft: hsl(56 97% 52% / 0.16);
  --danger: hsl(330 100% 64%);
  --danger-soft: hsl(330 100% 58% / 0.18);
  --on-accent: hsl(240 60% 6%);
  --on-danger: hsl(240 60% 6%);
  --modal-shadow: 0 24px 80px hsl(240 70% 2% / 0.7), 0 0 36px hsl(186 100% 52% / 0.18);
  --modal-backdrop: hsl(240 60% 3% / 0.72);
  --qr-surface: #ffffff;
  --shadow: 0 14px 40px hsl(240 70% 3% / 0.55), 0 0 0 1px hsl(186 100% 52% / 0.06);
  --radius: 4px;
}

:root[data-skin="cyber"] body {
  background-color: hsl(240 46% 5%);
  background-image: linear-gradient(
    180deg,
    hsl(240 44% 6%) 0%,
    hsl(252 46% 4%) 58%,
    hsl(240 48% 5%) 100%
  );
  background-attachment: fixed;
  color: var(--fg);
}

/* Lift the real UI above the fixed FX layer (the FX sits at z-index:0). */
:root[data-skin="cyber"] .app-shell {
  position: relative;
  z-index: 1;
}

/* ── Fixed background FX: neon grid + glow + scanlines + vignette + data-rain ─ */
.cyber-fx {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}

.cyber-fx-grid {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse at 78% 112%, hsl(186 100% 52% / 0.18), transparent 44%),
    radial-gradient(ellipse at 16% 104%, hsl(330 100% 58% / 0.16), transparent 42%),
    linear-gradient(0deg, hsl(56 97% 52% / 0.05), transparent 28%),
    repeating-linear-gradient(0deg, hsl(186 100% 52% / 0.05) 0 1px, transparent 1px 44px),
    repeating-linear-gradient(90deg, hsl(330 100% 58% / 0.04) 0 1px, transparent 1px 44px);
  opacity: 0.85;
}

.cyber-fx-scan {
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    0deg,
    hsl(186 100% 52% / 0.04) 0 1px,
    transparent 1px 3px
  );
  opacity: 0.6;
}

/* CRT vignette darkens the corners. */
.cyber-fx::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at 50% 44%, transparent 55%, hsl(240 70% 3% / 0.6) 100%);
}

.cyber-rain {
  position: absolute;
  inset: 0;
}

.cyber-rain-col {
  position: absolute;
  top: 0;
  writing-mode: vertical-rl;
  text-orientation: upright;
  font-family: var(--mono);
  font-size: var(--sz, 14px);
  line-height: 1;
  letter-spacing: 1px;
  color: hsl(var(--rc, 186 100% 60%));
  opacity: var(--op, 0.4);
  text-shadow: 0 0 6px hsl(var(--rc, 186 100% 60%) / 0.7);
  white-space: nowrap;
  /* bright leading glyph (bottom) → fading trail (top) */
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 55%, #fff 100%);
  mask-image: linear-gradient(180deg, transparent 0%, #000 55%, #fff 100%);
  animation: cyber-rain-fall var(--dur, 8s) linear var(--delay, 0s) infinite;
  will-change: transform;
}

@keyframes cyber-rain-fall {
  from { transform: translateY(-115%); }
  to { transform: translateY(115vh); }
}

@media (prefers-reduced-motion: reduce) {
  .cyber-rain-col { animation: none; opacity: 0.12; }
}

/* ── Chrome: glassy neon sidebar + topbar ───────────────────────────────────*/
:root[data-skin="cyber"] .sidebar {
  background: hsl(240 40% 7% / 0.78);
  -webkit-backdrop-filter: blur(14px) saturate(1.15);
  backdrop-filter: blur(14px) saturate(1.15);
  border-right-color: hsl(186 90% 50% / 0.28);
}

:root[data-skin="cyber"] .topbar {
  background: hsl(240 40% 6% / 0.7);
  border-bottom-color: hsl(186 90% 50% / 0.3);
  -webkit-backdrop-filter: blur(16px) saturate(1.15);
  backdrop-filter: blur(16px) saturate(1.15);
}

:root[data-skin="cyber"] .brand-mark {
  background: linear-gradient(135deg, hsl(186 100% 52%), hsl(330 100% 60%));
  color: hsl(240 60% 6%);
  border-radius: 4px;
  box-shadow: 0 0 14px hsl(186 100% 52% / 0.5);
}

:root[data-skin="cyber"] .brand strong,
:root[data-skin="cyber"] .topbar-title strong {
  font-family: var(--mono);
  letter-spacing: 1px;
  text-shadow: 0 0 12px hsl(186 100% 60% / 0.45);
}

/* ── Navigation: neon active rail ───────────────────────────────────────────*/
:root[data-skin="cyber"] .sidebar-nav a:hover {
  background: hsl(186 100% 52% / 0.08);
  color: var(--accent-strong);
}

:root[data-skin="cyber"] .sidebar-nav a.active {
  background: linear-gradient(135deg, hsl(186 80% 26% / 0.45), hsl(330 70% 24% / 0.3));
  color: hsl(186 100% 74%);
  box-shadow: inset 2px 0 0 hsl(186 100% 56%), 0 0 16px hsl(186 100% 52% / 0.18);
}

/* ── Headings ───────────────────────────────────────────────────────────────*/
:root[data-skin="cyber"] .page-heading h1 {
  font-family: var(--mono);
  text-shadow: 0 0 18px hsl(186 100% 60% / 0.35);
}

:root[data-skin="cyber"] .eyebrow {
  color: var(--warning) !important;
  text-shadow: 0 0 10px hsl(56 97% 60% / 0.4);
}

/* ── Cards & metrics: faint inner neon edge + glowing figures ────────────────*/
:root[data-skin="cyber"] .panel,
:root[data-skin="cyber"] .metric-card,
:root[data-skin="cyber"] .bd-card {
  border-color: hsl(196 82% 44% / 0.4);
  box-shadow: var(--shadow), inset 0 1px 0 hsl(186 100% 60% / 0.07);
}

:root[data-skin="cyber"] .metric-card strong {
  color: var(--accent-strong);
  text-shadow: 0 0 14px hsl(186 100% 60% / 0.4);
}

/* ── Primary actions: neon gradient ─────────────────────────────────────────*/
:root[data-skin="cyber"] .btn-link.primary,
:root[data-skin="cyber"] button.primary {
  background: linear-gradient(135deg, hsl(186 100% 52%), hsl(56 97% 56%));
  color: hsl(240 60% 6%);
  border-color: hsl(186 100% 56%);
  box-shadow: 0 0 16px hsl(186 100% 52% / 0.3);
}

/* ── Segmented switchers (incl. the skin switcher itself) ────────────────────*/
:root[data-skin="cyber"] .segmented {
  border-color: hsl(186 80% 46% / 0.35);
  background: hsl(240 36% 9% / 0.6);
}

:root[data-skin="cyber"] .segmented button.active {
  background: linear-gradient(135deg, hsl(186 100% 52%), hsl(186 100% 62%));
  color: hsl(240 60% 6%);
  box-shadow: 0 0 12px hsl(186 100% 52% / 0.35);
}

/* ── Status + badges ────────────────────────────────────────────────────────*/
:root[data-skin="cyber"] .connection-status.online::before {
  box-shadow: 0 0 8px hsl(150 85% 58% / 0.85);
}

/* CLI badges: fold the light hard-coded palette into the neon surface tokens
   (mirrors the existing dark-theme treatment). */
:root[data-skin="cyber"] .cli-claude-code,
:root[data-skin="cyber"] .cli-codex,
:root[data-skin="cyber"] .cli-codex-app,
:root[data-skin="cyber"] .cli-cursor,
:root[data-skin="cyber"] .cli-gemini,
:root[data-skin="cyber"] .cli-opencode,
:root[data-skin="cyber"] .cli-mtr,
:root[data-skin="cyber"] .cli-hermes,
:root[data-skin="cyber"] .cli-mira,
:root[data-skin="cyber"] .cli-pi,
:root[data-skin="cyber"] .cli-aiden,
:root[data-skin="cyber"] .cli-coco {
  background: var(--surface-muted);
  color: var(--fg);
  border-color: var(--border);
}

/* Themed form controls in 2077 — inner glow + accent-cyan focus ring. */
:root[data-skin="cyber"] input:not([type=checkbox]):not([type=radio]),
:root[data-skin="cyber"] select,
:root[data-skin="cyber"] textarea {
  background-color: hsl(240 36% 9% / 0.7);
  box-shadow: inset 0 0 12px hsl(186 100% 52% / 0.06);
}
:root[data-skin="cyber"] input:focus,
:root[data-skin="cyber"] select:focus,
:root[data-skin="cyber"] textarea:focus {
  box-shadow: 0 0 0 3px hsl(186 100% 52% / 0.18), 0 0 14px hsl(186 100% 52% / 0.25);
}

/* ════════════════════════════════════════════════════════════════════════════
   2077 MOTION FX — CRT flicker / roll line, HUD frame, random glitches, and the
   KIROSHI NETLINK boot loader. Ported from kaboo's cyberpunk.css. DOM nodes are
   injected by cyber-fx.ts only while the skin is active.
   ════════════════════════════════════════════════════════════════════════════ */

/* CRT flicker + scrolling roll line (inside the behind-content #cyber-fx). */
.cyber-flicker {
  position: absolute;
  inset: 0;
  background: hsl(186 100% 52% / 0.04);
  mix-blend-mode: screen;
  animation: cyber-flicker 0.18s steps(2, end) infinite;
}

@keyframes cyber-flicker {
  0% { opacity: 0.85; }
  100% { opacity: 0.42; }
}

.cyber-rollline {
  position: absolute;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(90deg, transparent, hsl(330 100% 64% / 0.5), transparent);
  box-shadow: 0 0 12px hsl(330 100% 64% / 0.4);
  opacity: 0.5;
  animation: cyber-roll 9s linear infinite;
}

@keyframes cyber-roll {
  0% { transform: translateY(-6vh); opacity: 0; }
  8% { opacity: 0.5; }
  60% { opacity: 0.5; }
  72%, 100% { transform: translateY(112vh); opacity: 0; }
}

/* Full-screen HUD corner brackets + NETWATCH tag (above content). */
.cyber-hud {
  position: fixed;
  inset: 0;
  z-index: 30;
  pointer-events: none;
}

.cyber-hud-corner {
  position: absolute;
  width: 26px;
  height: 26px;
  border: 2px solid hsl(186 100% 60% / 0.55);
  opacity: 0.7;
  filter: drop-shadow(0 0 6px hsl(186 100% 52% / 0.4));
}

.cyber-hud-corner.tl { top: 12px; left: 12px; border-right: 0; border-bottom: 0; }
.cyber-hud-corner.tr { top: 12px; right: 12px; border-left: 0; border-bottom: 0; }
.cyber-hud-corner.bl { bottom: 12px; left: 12px; border-right: 0; border-top: 0; }
.cyber-hud-corner.br { bottom: 12px; right: 12px; border-left: 0; border-top: 0; }

.cyber-hud-tag {
  position: absolute;
  left: 16px;
  bottom: 14px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  color: hsl(56 97% 64% / 0.6);
  text-shadow: 0 0 8px hsl(56 97% 52% / 0.5);
}

/* Random page-glitch overlay (above content); cp-fx-* on <body> drive it. */
.cyber-glitch {
  position: fixed;
  inset: 0;
  z-index: 9000;
  pointer-events: none;
  mix-blend-mode: screen;
  opacity: 0;
}

body.cp-fx-tear .cyber-glitch {
  background: linear-gradient(
    180deg,
    transparent 0 46%,
    hsl(330 100% 60% / 0.6) 46% 48%,
    hsl(186 100% 60% / 0.6) 48% 50%,
    hsl(56 96% 58% / 0.45) 50% 52%,
    transparent 52%
  );
  animation: cp-fx-tear 0.4s steps(2, end);
}

@keyframes cp-fx-tear {
  0% { opacity: 0; transform: translateY(0); }
  15% { opacity: 0.9; transform: translateY(-26vh) translateX(-8px); }
  35% { opacity: 0.5; transform: translateY(28vh) translateX(9px); }
  55% { opacity: 0.85; transform: translateY(8vh) translateX(-5px); }
  75% { opacity: 0.4; transform: translateY(-14vh) translateX(6px); }
  100% { opacity: 0; transform: translateY(40vh); }
}

body.cp-fx-invert .cyber-glitch {
  mix-blend-mode: difference;
  background: hsl(186 100% 60%);
  animation: cp-fx-invert 0.22s steps(1, end);
}

@keyframes cp-fx-invert {
  0%, 100% { opacity: 0; }
  25% { opacity: 0.95; }
  50% { opacity: 0.1; }
  75% { opacity: 0.7; }
}

body.cp-fx-blackout .cyber-glitch {
  mix-blend-mode: normal;
  background: hsl(240 40% 2%);
  animation: cp-fx-blackout 0.26s steps(1, end);
}

@keyframes cp-fx-blackout {
  0%, 100% { opacity: 0; }
  18% { opacity: 0.92; }
  34% { opacity: 0.08; }
  52% { opacity: 0.85; }
  70% { opacity: 0; }
}

body.cp-fx-shake main { animation: cp-fx-shake 0.28s steps(1, end); }

@keyframes cp-fx-shake {
  0%, 100% { transform: translate(0, 0) skewX(0deg); }
  15% { transform: translate(-3px, 1px) skewX(0.6deg); }
  30% { transform: translate(4px, -2px) skewX(-0.8deg); }
  45% { transform: translate(-2px, 1px); }
  60% { transform: translate(3px, 0) skewX(0.5deg); }
  80% { transform: translate(-1px, -1px); }
}

body.cp-fx-rgb main { animation: cp-fx-rgb 0.34s steps(2, end); }

@keyframes cp-fx-rgb {
  0%, 100% { filter: none; transform: none; }
  25% {
    filter: drop-shadow(3px 0 hsl(330 100% 60% / 0.7)) drop-shadow(-3px 0 hsl(186 100% 60% / 0.7));
    transform: translateX(-2px);
  }
  50% {
    filter: drop-shadow(-4px 0 hsl(330 100% 60% / 0.6)) drop-shadow(4px 0 hsl(186 100% 60% / 0.6));
    transform: translateX(2px);
  }
  75% {
    filter: drop-shadow(2px 0 hsl(330 100% 60% / 0.7)) drop-shadow(-2px 0 hsl(186 100% 60% / 0.7));
  }
}

body.cp-fx-slice main { animation: cp-fx-slice 0.32s steps(2, end); }

@keyframes cp-fx-slice {
  0%, 100% { transform: none; }
  20% { transform: translateX(-12px) skewX(7deg); }
  40% { transform: translateX(10px) skewX(-5deg); }
  60% { transform: translateX(-6px) skewX(3deg); }
  80% { transform: translateX(4px) skewX(-1deg); }
}

/* ── Boot decrypt loader (plays once when switching into 2077) ───────────────*/
.cyber-boot {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  background:
    radial-gradient(ellipse at center, hsl(252 50% 6%) 0%, hsl(252 60% 3%) 100%),
    repeating-linear-gradient(0deg, hsl(186 100% 52% / 0.06) 0 1px, transparent 1px 3px);
  animation: cyber-boot-fade 3.2s ease forwards;
}

.cyber-boot::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at 50% 50%, transparent 50%, hsl(252 70% 2% / 0.85) 100%);
}

.cyber-boot-grid {
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(0deg, hsl(186 100% 52% / 0.05) 0 1px, transparent 1px 40px),
    repeating-linear-gradient(90deg, hsl(330 100% 58% / 0.04) 0 1px, transparent 1px 40px);
  -webkit-mask-image: radial-gradient(ellipse at center, #000 28%, transparent 74%);
  mask-image: radial-gradient(ellipse at center, #000 28%, transparent 74%);
  animation: cyber-grid-pan 3.2s linear;
}

@keyframes cyber-boot-fade {
  0%, 84% { opacity: 1; }
  100% { opacity: 0; }
}

@keyframes cyber-blink { 50% { opacity: 0; } }

@keyframes cyber-grid-pan {
  from { background-position: 0 -40px, -40px 0; opacity: 0.3; }
  to { background-position: 0 0, 0 0; opacity: 1; }
}

.cyber-loader {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  font-family: var(--mono);
}

.cyber-loader-frame {
  position: relative;
  width: min(440px, 86vw);
  padding: 16px 22px;
  overflow: hidden;
  color: hsl(186 100% 72%);
  background: linear-gradient(135deg, hsl(252 50% 8% / 0.92), hsl(240 60% 5% / 0.94));
  border: 1px solid hsl(186 100% 52% / 0.4);
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 14px), calc(100% - 14px) 100%, 0 100%);
  box-shadow: 0 0 36px hsl(186 100% 52% / 0.18), inset 0 0 50px hsl(186 100% 52% / 0.06);
  text-shadow: 0 0 8px hsl(186 100% 52% / 0.45);
}

.cyber-loader-frame::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: -40%;
  width: 40%;
  height: 2px;
  background: linear-gradient(90deg, transparent, hsl(56 96% 56%), transparent);
  box-shadow: 0 0 10px hsl(56 96% 56% / 0.7);
  animation: cyber-loader-scan 1.6s linear infinite;
}

@keyframes cyber-loader-scan {
  from { left: -40%; }
  to { left: 100%; }
}

.cyber-loader-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 8px;
  margin-bottom: 12px;
  border-bottom: 1px solid hsl(186 100% 52% / 0.22);
  font-size: 11px;
  letter-spacing: 0.18em;
  color: hsl(56 96% 70%);
}

.cyber-loader-jp { color: hsl(330 100% 70% / 0.7); letter-spacing: 0.28em; }

.cyber-loader-line {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: clamp(13px, 2.4vw, 16px);
}

.cyber-loader-prompt { color: hsl(56 96% 64%); }

.cyber-loader-text {
  letter-spacing: 0.08em;
  color: hsl(186 100% 80%);
  transition: color 0.2s ease;
}

.cyber-loader-text.done {
  color: hsl(56 96% 80%);
  text-shadow: 0 0 10px hsl(56 96% 56% / 0.6);
}

.cyber-loader-cursor {
  color: hsl(56 96% 70%);
  animation: cyber-blink 1s steps(1, end) infinite;
}

.cyber-loader-stream {
  margin-top: 10px;
  font-size: 11px;
  letter-spacing: 2px;
  color: hsl(186 60% 52% / 0.6);
  white-space: nowrap;
  overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
  .cyber-flicker,
  .cyber-rollline,
  .cyber-glitch,
  .cyber-boot,
  .cyber-boot-grid,
  .cyber-loader-frame::after,
  .cyber-loader-cursor,
  body.cp-fx-shake main,
  body.cp-fx-rgb main,
  body.cp-fx-slice main {
    animation: none;
  }
}

/* ════════════════════════════════════════════════════════════════════════════
   EXTRA SKINS — palettes distilled from the kaboo webui (frontend/src/styles/*).
   Each is a self-contained token override (variable system re-skins everything);
   they ship their own light/dark palette and ignore the base light/dark mode.
   Placed after the base :root blocks so they win by source order.
   ════════════════════════════════════════════════════════════════════════════ */

/* 原神 Genshin — light, Teyvat parchment + teal primary + gold accent */
:root[data-skin="genshin"] {
  color-scheme: light;
  --bg: hsl(216 72% 97%);
  --bg-soft: hsl(214 56% 94%);
  --surface: hsl(0 0% 100%);
  --surface-raised: hsl(0 0% 100%);
  --surface-muted: hsl(214 48% 95%);
  --fg: hsl(219 36% 17%);
  --muted: hsl(219 18% 41%);
  --faint: hsl(219 16% 55%);
  --border: hsl(208 34% 82%);
  --border-soft: hsl(208 34% 88%);
  --accent: hsl(199 70% 42%);
  --accent-strong: hsl(199 74% 33%);
  --accent-soft: hsl(198 68% 92%);
  --success: hsl(160 60% 35%);
  --success-soft: hsl(160 52% 92%);
  --warning: hsl(36 86% 42%);
  --warning-soft: hsl(42 90% 90%);
  --danger: hsl(0 72% 48%);
  --danger-soft: hsl(0 80% 96%);
  --on-accent: hsl(0 0% 100%);
  --on-danger: hsl(0 0% 100%);
  --modal-shadow: 0 24px 80px hsl(219 40% 30% / 0.22);
  --modal-backdrop: hsl(219 36% 17% / 0.4);
  --qr-surface: #ffffff;
  --shadow: 0 18px 44px hsl(216 50% 40% / 0.1);
  --radius: 10px;
}

/* Fallout — Pip-Boy phosphor green terminal on near-black */
:root[data-skin="fallout"] {
  color-scheme: dark;
  --bg: hsl(140 32% 5%);
  --bg-soft: hsl(140 30% 7%);
  --surface: hsl(140 26% 8%);
  --surface-raised: hsl(140 26% 11%);
  --surface-muted: hsl(140 22% 13%);
  --fg: hsl(140 84% 80%);
  --muted: hsl(140 28% 56%);
  --faint: hsl(140 22% 44%);
  --border: hsl(140 48% 22%);
  --border-soft: hsl(140 45% 17%);
  --accent: hsl(138 92% 52%);
  --accent-strong: hsl(138 92% 66%);
  --accent-soft: hsl(138 92% 52% / 0.15);
  --success: hsl(120 80% 55%);
  --success-soft: hsl(120 70% 50% / 0.16);
  --warning: hsl(44 96% 56%);
  --warning-soft: hsl(44 96% 52% / 0.16);
  --danger: hsl(8 90% 62%);
  --danger-soft: hsl(8 88% 55% / 0.18);
  --on-accent: hsl(140 40% 6%);
  --on-danger: hsl(140 40% 6%);
  --modal-shadow: 0 24px 80px hsl(140 60% 2% / 0.7), 0 0 30px hsl(138 92% 52% / 0.12);
  --modal-backdrop: hsl(140 50% 2% / 0.7);
  --qr-surface: #ffffff;
  --shadow: 0 14px 40px hsl(140 60% 2% / 0.6);
  --radius: 2px;
}

/* PRTS (Arknights) — Rhodes Island slate-blue + cyan primary + amber */
:root[data-skin="prts"] {
  color-scheme: dark;
  --bg: hsl(213 50% 5%);
  --bg-soft: hsl(213 46% 7%);
  --surface: hsl(213 44% 8%);
  --surface-raised: hsl(213 44% 11%);
  --surface-muted: hsl(213 32% 14%);
  --fg: hsl(194 65% 92%);
  --muted: hsl(203 22% 62%);
  --faint: hsl(203 18% 50%);
  --border: hsl(194 48% 23%);
  --border-soft: hsl(194 45% 18%);
  --accent: hsl(190 95% 52%);
  --accent-strong: hsl(190 95% 66%);
  --accent-soft: hsl(190 95% 52% / 0.15);
  --success: hsl(150 75% 50%);
  --success-soft: hsl(150 70% 48% / 0.16);
  --warning: hsl(28 96% 56%);
  --warning-soft: hsl(28 96% 52% / 0.16);
  --danger: hsl(0 84% 64%);
  --danger-soft: hsl(0 80% 55% / 0.18);
  --on-accent: hsl(213 70% 6%);
  --on-danger: hsl(213 70% 6%);
  --modal-shadow: 0 24px 80px hsl(213 60% 2% / 0.7);
  --modal-backdrop: hsl(213 60% 3% / 0.7);
  --qr-surface: #ffffff;
  --shadow: 0 14px 40px hsl(213 60% 2% / 0.55);
  --radius: 3px;
}

/* 蔚蓝档案 Blue Archive — deep navy + bright blue primary + halo gold */
:root[data-skin="bluearchive"] {
  color-scheme: dark;
  --bg: hsl(218 51% 12%);
  --bg-soft: hsl(218 48% 15%);
  --surface: hsl(217 48% 18%);
  --surface-raised: hsl(217 48% 21%);
  --surface-muted: hsl(218 36% 18%);
  --fg: hsl(0 0% 96%);
  --muted: hsl(0 0% 76%);
  --faint: hsl(213 20% 64%);
  --border: hsl(213 56% 56% / 0.5);
  --border-soft: hsl(213 56% 56% / 0.3);
  --accent: hsl(209 100% 52%);
  --accent-strong: hsl(209 100% 70%);
  --accent-soft: hsl(209 100% 56% / 0.18);
  --success: hsl(150 65% 55%);
  --success-soft: hsl(150 60% 50% / 0.16);
  --warning: hsl(47 88% 60%);
  --warning-soft: hsl(47 88% 56% / 0.18);
  --danger: hsl(0 80% 66%);
  --danger-soft: hsl(0 78% 58% / 0.18);
  --on-accent: hsl(0 0% 100%);
  --on-danger: hsl(0 0% 100%);
  --modal-shadow: 0 24px 80px hsl(218 60% 4% / 0.6);
  --modal-backdrop: hsl(218 51% 8% / 0.55);
  --qr-surface: #ffffff;
  --shadow: 0 18px 44px hsl(218 60% 4% / 0.4);
  --radius: 10px;
}

/* 绝区零 ZZZ — acid lime on charcoal, bold hollow vibe */
:root[data-skin="zzz"] {
  color-scheme: dark;
  --bg: hsl(240 24% 8%);
  --bg-soft: hsl(244 26% 10%);
  --surface: hsl(244 28% 11%);
  --surface-raised: hsl(244 28% 14%);
  --surface-muted: hsl(244 22% 15%);
  --fg: hsl(75 90% 86%);
  --muted: hsl(280 18% 66%);
  --faint: hsl(280 14% 52%);
  --border: hsl(75 60% 40% / 0.55);
  --border-soft: hsl(75 50% 36% / 0.32);
  --accent: hsl(75 90% 60%);
  --accent-strong: hsl(75 95% 74%);
  --accent-soft: hsl(75 90% 60% / 0.16);
  --success: hsl(140 75% 55%);
  --success-soft: hsl(140 70% 50% / 0.16);
  --warning: hsl(48 100% 62%);
  --warning-soft: hsl(48 100% 56% / 0.16);
  --danger: hsl(340 90% 66%);
  --danger-soft: hsl(340 85% 58% / 0.18);
  --on-accent: hsl(240 30% 8%);
  --on-danger: hsl(240 30% 8%);
  --modal-shadow: 0 24px 80px hsl(240 40% 2% / 0.7);
  --modal-backdrop: hsl(240 30% 3% / 0.7);
  --qr-surface: #ffffff;
  --shadow: 0 14px 40px hsl(240 40% 2% / 0.55);
  --radius: 4px;
}

/* Terminal-flavoured skins: monospace + glow on brand / page titles. */
:root[data-skin="fallout"] .brand strong,
:root[data-skin="fallout"] .topbar-title strong,
:root[data-skin="fallout"] .page-heading h1,
:root[data-skin="prts"] .brand strong,
:root[data-skin="prts"] .topbar-title strong,
:root[data-skin="prts"] .page-heading h1 {
  font-family: var(--mono);
  letter-spacing: 0.5px;
}
:root[data-skin="fallout"] .page-heading h1 { text-shadow: 0 0 14px hsl(138 92% 52% / 0.4); }
:root[data-skin="prts"] .page-heading h1 { text-shadow: 0 0 14px hsl(190 95% 52% / 0.4); }

/* Genshin/Blue Archive carry a gold secondary — tint the brand mark with it. */
:root[data-skin="genshin"] .brand-mark { background: linear-gradient(135deg, hsl(199 70% 42%), hsl(42 78% 58%)); color: #fff; }
:root[data-skin="bluearchive"] .brand-mark { background: linear-gradient(135deg, hsl(209 100% 52%), hsl(47 88% 60%)); color: hsl(218 51% 12%); }

/* ════════════════════════════════════════════════════════════════════════════
   SKIN BACKGROUNDS — the layered neon-glow / grid backgrounds + decorative art
   that make each theme recognisable (ported from kaboo's body.<skin>-mode rules).
   Surfaces are made translucent so the fixed background shows through the chrome
   and cards. Raster art is referenced from kaboo's CDN (loads on-network; if it
   404s off-network the gradient layers still carry the theme).
   ════════════════════════════════════════════════════════════════════════════ */

/* translucent surfaces so the fixed page background reads through chrome + cards */
:root[data-skin="genshin"]     { --surface: hsl(0 0% 100% / 0.74); --surface-raised: hsl(0 0% 100% / 0.88); --surface-muted: hsl(214 48% 95% / 0.7); }
:root[data-skin="fallout"]     { --surface: hsl(140 26% 8% / 0.7); --surface-raised: hsl(140 26% 11% / 0.82); --surface-muted: hsl(140 22% 13% / 0.64); }
:root[data-skin="prts"]        { --surface: hsl(213 44% 8% / 0.7); --surface-raised: hsl(213 44% 11% / 0.82); --surface-muted: hsl(213 32% 14% / 0.64); }
:root[data-skin="bluearchive"] { --surface: hsl(217 48% 18% / 0.74); --surface-raised: hsl(217 48% 21% / 0.86); --surface-muted: hsl(218 36% 18% / 0.66); }
:root[data-skin="zzz"]         { --surface: hsl(244 28% 11% / 0.7); --surface-raised: hsl(244 28% 14% / 0.82); --surface-muted: hsl(244 22% 15% / 0.64); }

/* lift content above any fixed ::before art layer */
:root[data-skin="genshin"] .app-shell,
:root[data-skin="fallout"] .app-shell,
:root[data-skin="prts"] .app-shell,
:root[data-skin="bluearchive"] .app-shell,
:root[data-skin="zzz"] .app-shell { position: relative; z-index: 0; }

/* 原神 — gentle-breeze parchment + Teyvat glow */
:root[data-skin="genshin"] body {
  background:
    linear-gradient(180deg, hsl(216 72% 97% / 0.68) 0%, hsl(202 78% 96% / 0.58) 42%, hsl(42 72% 95% / 0.74) 100%),
    radial-gradient(circle at 20% 16%, hsl(42 88% 78% / 0.36), transparent 28%),
    radial-gradient(circle at 82% 26%, hsl(198 86% 74% / 0.34), transparent 30%),
    radial-gradient(circle at 70% 78%, hsl(154 66% 78% / 0.3), transparent 28%),
    repeating-linear-gradient(115deg, hsl(42 78% 58% / 0.055) 0 1px, transparent 1px 48px),
    url('/assets/skins/genshin-breeze.webp');
  background-position: center, 20% 16%, 82% 26%, 70% 78%, center, center;
  background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, repeat, no-repeat;
  background-size: cover, cover, cover, cover, 100% 100%, cover;
  background-attachment: fixed;
}

/* Fallout — phosphor glow + CRT scanlines, Vault-Boy watermark bottom-right */
:root[data-skin="fallout"] body {
  background:
    radial-gradient(ellipse at 50% -6%, hsl(138 92% 52% / 0.16), transparent 36%),
    radial-gradient(ellipse at 86% 90%, hsl(96 80% 46% / 0.1), transparent 34%),
    linear-gradient(180deg, hsl(140 36% 6%) 0%, hsl(150 34% 4%) 52%, hsl(140 40% 5%) 100%),
    repeating-linear-gradient(0deg, hsl(138 92% 52% / 0.05) 0 1px, transparent 1px 4px),
    repeating-linear-gradient(90deg, hsl(138 92% 52% / 0.04) 0 1px, transparent 1px 44px);
  background-attachment: fixed;
}
:root[data-skin="fallout"] body::before {
  content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background: url('/assets/skins/fallout-vaultboy.webp') right -1% bottom -8% / auto min(100vh, 1100px) no-repeat;
  opacity: 0.12;
  filter: drop-shadow(0 0 24px hsl(138 92% 52% / 0.35));
}

/* PRTS — Rhodes Island operator console (cyan glow + fine grid) */
:root[data-skin="prts"] body {
  background:
    radial-gradient(ellipse at 18% 12%, hsl(190 95% 52% / 0.18), transparent 34%),
    radial-gradient(ellipse at 88% 78%, hsl(28 96% 56% / 0.12), transparent 30%),
    linear-gradient(180deg, hsl(216 56% 6%) 0%, hsl(213 50% 4%) 58%, hsl(217 56% 5%) 100%),
    repeating-linear-gradient(90deg, hsl(190 95% 52% / 0.055) 0 1px, transparent 1px 72px),
    repeating-linear-gradient(0deg, hsl(190 95% 52% / 0.045) 0 1px, transparent 1px 36px);
  background-attachment: fixed;
}
:root[data-skin="prts"] body::before {
  content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background: url('/assets/skins/prts-priestess.webp') right -2% bottom / auto min(94vh, 1000px) no-repeat;
  opacity: 0.16;
  filter: saturate(1.1);
}

/* 蔚蓝档案 — halo gradients + soft grid, Kei sunset hero bottom-right */
:root[data-skin="bluearchive"] body {
  background:
    radial-gradient(ellipse at 14% 12%, hsl(209 100% 34% / 0.34), transparent 36%),
    radial-gradient(ellipse at 88% 16%, hsl(47 88% 60% / 0.2), transparent 30%),
    radial-gradient(ellipse at 50% 92%, hsl(213 60% 60% / 0.22), transparent 38%),
    radial-gradient(ellipse at 86% 78%, hsl(188 76% 56% / 0.16), transparent 32%),
    linear-gradient(180deg, hsl(218 51% 10%) 0%, hsl(217 48% 16%) 48%, hsl(213 42% 14%) 100%),
    linear-gradient(90deg, hsl(213 56% 56% / 0.08) 1px, transparent 1px),
    linear-gradient(0deg, hsl(47 88% 60% / 0.06) 1px, transparent 1px);
  background-size: cover, cover, cover, cover, cover, 40px 40px, 40px 40px;
  background-attachment: fixed;
}
:root[data-skin="bluearchive"] body::before {
  content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background: url('/assets/skins/bluearchive-hero.webp') right bottom / auto min(86vh, 920px) no-repeat;
  opacity: 0.2;
}

/* 绝区零 — lime/violet glow + Hollow heatmap pattern */
:root[data-skin="zzz"] body {
  background:
    radial-gradient(ellipse at 50% -6%, hsl(75 90% 60% / 0.14), transparent 36%),
    radial-gradient(ellipse at 86% 90%, hsl(280 60% 50% / 0.14), transparent 34%),
    linear-gradient(180deg, hsl(244 30% 7%) 0%, hsl(252 32% 5%) 52%, hsl(244 30% 7%) 100%),
    repeating-linear-gradient(0deg, hsl(75 90% 60% / 0.05) 0 1px, transparent 1px 56px),
    repeating-linear-gradient(90deg, hsl(75 90% 60% / 0.04) 0 1px, transparent 1px 56px);
  background-attachment: fixed;
}
:root[data-skin="zzz"] body::before {
  content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background: url('/assets/skins/zzz-hero.webp') center / cover no-repeat;
  opacity: 0.62;
}
/* keep the Hollow heatmap pattern as a faint overlay above the wallpaper */
:root[data-skin="zzz"] body::after {
  content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background: url('/assets/skins/zzz-pattern.svg') center / 420px repeat;
  opacity: 0.16;
}

/* ════════════════════════════════════════════════════════════════════════════
   2077 EASTER EGG — "BREACH PROTOCOL". Over-scroll past the bottom of the page
   to detonate a full-screen RGB-split glitch storm. Driven by cyber-fx.ts.
   Ported from kaboo's CyberpunkBreach.
   ════════════════════════════════════════════════════════════════════════════ */
.cyber-breach {
  position: fixed;
  inset: 0;
  z-index: 100000;
  pointer-events: none;
  overflow: hidden;
}

.cyber-breach-flash {
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg, hsl(186 100% 52% / 0.5), hsl(330 100% 58% / 0.4));
  mix-blend-mode: screen;
  animation: cyber-breach-flash 4.2s ease-out forwards;
}

.cyber-breach-grid {
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(0deg, hsl(186 100% 52% / 0.12) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(90deg, hsl(330 100% 58% / 0.1) 0 1px, transparent 1px 38px);
  animation: cyber-breach-grid 4.2s steps(8, end) forwards;
}

.cyber-breach-shards { position: absolute; inset: 0; }

.cyber-breach-shard {
  position: absolute;
  left: 0;
  right: 0;
  background: hsl(var(--hue, 186 100% 52%) / 0.4);
  mix-blend-mode: screen;
  opacity: 0;
  animation: cyber-breach-shard var(--dur, 0.4s) steps(2, end) var(--delay, 0s) infinite;
}

.cyber-breach-banner {
  position: absolute;
  left: 0;
  right: 0;
  top: 34%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 0 16px;
  text-align: center;
  font-family: var(--mono);
  animation: cyber-breach-caption 4.2s ease forwards;
}

.cyber-breach-tag {
  font-size: clamp(11px, 2vw, 16px);
  letter-spacing: 0.24em;
  color: hsl(186 100% 70%);
  text-shadow: 0 0 12px hsl(186 100% 52% / 0.8);
}

.cyber-breach-caption,
.cyber-breach-sub {
  position: relative;
  font-weight: 700;
  letter-spacing: 0.16em;
  color: hsl(56 96% 84%);
}

.cyber-breach-caption {
  font-size: clamp(20px, 5vw, 54px);
  text-shadow: 0 0 18px hsl(330 100% 58% / 0.9), 0 0 4px hsl(186 100% 70% / 0.85);
}

.cyber-breach-sub {
  font-size: clamp(13px, 2.6vw, 28px);
  color: hsl(186 96% 78%);
  text-shadow: 0 0 12px hsl(186 100% 52% / 0.8);
}

.cyber-breach-caption::before,
.cyber-breach-caption::after,
.cyber-breach-sub::before,
.cyber-breach-sub::after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  mix-blend-mode: screen;
}

.cyber-breach-caption::before,
.cyber-breach-sub::before {
  color: hsl(330 100% 60%);
  animation: cyber-breach-glitch-a 0.4s steps(2, end) infinite;
}

.cyber-breach-caption::after,
.cyber-breach-sub::after {
  color: hsl(186 100% 56%);
  animation: cyber-breach-glitch-b 0.4s steps(2, end) infinite;
}

.cyber-breach-quake .app-shell {
  animation: cyber-breach-quake 0.76s cubic-bezier(0.36, 0.07, 0.19, 0.97);
}

@keyframes cyber-breach-flash {
  0% { opacity: 0; }
  3% { opacity: 1; }
  18% { opacity: 0.4; }
  100% { opacity: 0; }
}

@keyframes cyber-breach-grid {
  0% { opacity: 0; transform: translateY(-6px); }
  10% { opacity: 1; }
  86% { opacity: 0.9; }
  100% { opacity: 0; transform: translateY(6px); }
}

@keyframes cyber-breach-shard {
  0%, 100% { opacity: 0; transform: translateX(0); }
  40% { opacity: 0.85; transform: translateX(var(--shift, 10px)); }
  60% { opacity: 0.5; transform: translateX(calc(var(--shift, 10px) * -0.6)); }
}

@keyframes cyber-breach-glitch-a {
  0%, 100% { transform: translate(-2px, 0); }
  50% { transform: translate(-5px, 1px); }
}

@keyframes cyber-breach-glitch-b {
  0%, 100% { transform: translate(2px, 0); }
  50% { transform: translate(5px, -1px); }
}

@keyframes cyber-breach-caption {
  0%, 16% { opacity: 0; }
  30% { opacity: 1; }
  84% { opacity: 1; }
  100% { opacity: 0; }
}

@keyframes cyber-breach-quake {
  10%, 90% { transform: translate(-2px, 1px); }
  20%, 80% { transform: translate(4px, -2px); }
  30%, 50%, 70% { transform: translate(-7px, 2px); }
  40%, 60% { transform: translate(7px, -1px); }
}

@media (prefers-reduced-motion: reduce) {
  .cyber-breach-flash,
  .cyber-breach-shards { display: none; }
  .cyber-breach-grid,
  .cyber-breach-banner { animation: none; opacity: 1; }
  .cyber-breach-caption::before,
  .cyber-breach-caption::after,
  .cyber-breach-sub::before,
  .cyber-breach-sub::after { display: none; }
  .cyber-breach-quake .app-shell { animation: none; }
}

/* ════════════════════════════════════════════════════════════════════════════
   七龙珠 Dragon Ball — warm shonen energy: Goku-gi orange + Super-Saiyan gold,
   sunlit cream sky, and the Dragon Ball orb art bottom-right.
   Orb art: "Dragon ball.svg" by Frédéric Mahé, CC-BY-3.0, via Wikimedia Commons.
   ════════════════════════════════════════════════════════════════════════════ */
:root[data-skin="dragonball"] {
  color-scheme: light;
  --bg: hsl(36 92% 96%);
  --bg-soft: hsl(33 86% 93%);
  --surface: hsl(0 0% 100% / 0.8);
  --surface-raised: hsl(0 0% 100% / 0.92);
  --surface-muted: hsl(35 80% 93% / 0.78);
  --fg: hsl(24 50% 17%);
  --muted: hsl(26 22% 40%);
  --faint: hsl(28 18% 54%);
  --border: hsl(32 58% 80%);
  --border-soft: hsl(33 64% 87%);
  --accent: hsl(26 95% 48%);
  --accent-strong: hsl(18 92% 42%);
  --accent-soft: hsl(35 95% 88%);
  --success: hsl(145 60% 36%);
  --success-soft: hsl(145 55% 90%);
  --warning: hsl(42 100% 44%);
  --warning-soft: hsl(45 100% 88%);
  --danger: hsl(2 80% 50%);
  --danger-soft: hsl(2 85% 95%);
  --on-accent: hsl(0 0% 100%);
  --on-danger: hsl(0 0% 100%);
  --modal-shadow: 0 24px 80px hsl(26 60% 30% / 0.25);
  --modal-backdrop: hsl(24 50% 17% / 0.4);
  --qr-surface: #ffffff;
  --shadow: 0 18px 44px hsl(26 70% 40% / 0.12);
  --radius: 12px;
}

:root[data-skin="dragonball"] .app-shell { position: relative; z-index: 0; }

:root[data-skin="dragonball"] body {
  background:
    radial-gradient(circle at 18% 14%, hsl(45 100% 75% / 0.45), transparent 30%),
    radial-gradient(circle at 84% 20%, hsl(26 95% 62% / 0.28), transparent 34%),
    /* warm veil over the wallpaper so cards + text stay readable */
    linear-gradient(180deg, hsl(38 92% 96% / 0.78), hsl(30 86% 93% / 0.66) 50%, hsl(45 80% 95% / 0.8)),
    url('/assets/skins/dragonball-goku.webp') center / cover no-repeat;
  background-attachment: fixed;
}

:root[data-skin="dragonball"] .brand-mark {
  background: linear-gradient(135deg, hsl(26 95% 52%), hsl(45 100% 55%));
  color: #fff;
}
:root[data-skin="dragonball"] .page-heading h1 {
  text-shadow: 0 2px 0 hsl(45 100% 72% / 0.55);
}

/* ════════════════════════════════════════════════════════════════════════════
   中分鸡 iKun — 唱跳 rap 篮球 meme skin: stage-purple backdrop, basketball
   orange + hot-pink/cyan spotlight glows, and an original basketball motif.
   (No real-person photo / no song lyrics — original artwork only.)
   ════════════════════════════════════════════════════════════════════════════ */
:root[data-skin="ikun"] {
  color-scheme: dark;
  --bg: hsl(268 38% 8%);
  --bg-soft: hsl(270 36% 10%);
  --surface: hsl(268 34% 12% / 0.74);
  --surface-raised: hsl(268 34% 15% / 0.86);
  --surface-muted: hsl(268 26% 16% / 0.66);
  --fg: hsl(40 60% 94%);
  --muted: hsl(280 16% 66%);
  --faint: hsl(280 13% 52%);
  --border: hsl(28 70% 50% / 0.5);
  --border-soft: hsl(28 60% 46% / 0.3);
  --accent: hsl(24 95% 55%);
  --accent-strong: hsl(28 100% 67%);
  --accent-soft: hsl(24 95% 55% / 0.16);
  --success: hsl(150 70% 52%);
  --success-soft: hsl(150 65% 48% / 0.16);
  --warning: hsl(45 100% 58%);
  --warning-soft: hsl(45 100% 52% / 0.16);
  --danger: hsl(330 90% 62%);
  --danger-soft: hsl(330 85% 58% / 0.18);
  --on-accent: hsl(268 50% 8%);
  --on-danger: hsl(268 50% 8%);
  --modal-shadow: 0 24px 80px hsl(270 50% 2% / 0.7);
  --modal-backdrop: hsl(270 40% 3% / 0.7);
  --qr-surface: #ffffff;
  --shadow: 0 14px 40px hsl(270 50% 2% / 0.55);
  --radius: 14px;
}

:root[data-skin="ikun"] .app-shell { position: relative; z-index: 0; }

:root[data-skin="ikun"] body {
  background:
    radial-gradient(ellipse at 50% -8%, hsl(24 95% 55% / 0.22), transparent 38%),
    radial-gradient(ellipse at 12% 92%, hsl(330 90% 60% / 0.16), transparent 36%),
    radial-gradient(ellipse at 88% 86%, hsl(190 90% 55% / 0.14), transparent 36%),
    linear-gradient(180deg, hsl(270 40% 8%) 0%, hsl(276 42% 6%) 55%, hsl(268 40% 8%) 100%);
  background-attachment: fixed;
}
:root[data-skin="ikun"] body::before {
  content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background: url('/assets/skins/ikun-hero.webp') center / cover no-repeat;
  opacity: 0.6;
}

:root[data-skin="ikun"] .brand-mark {
  background: linear-gradient(135deg, hsl(24 95% 55%), hsl(330 90% 60%));
  color: #fff;
}

/* ── Skin ↔ PR #123 bridge ───────────────────────────────────────────────────
   PR #123 hardcodes panel/card backgrounds under [data-theme="dark"] (glass look)
   instead of using --surface, so dark skins would all look alike. Re-point the
   prominent surfaces to the active skin's --surface so switching is visible.
   Appended last → wins over the PR's [data-theme="dark"] rules by source order. */
:root:not([data-skin="default"]) .panel,
:root:not([data-skin="default"]) .metric-card,
:root:not([data-skin="default"]) .bd-card,
:root:not([data-skin="default"]) .qcard,
:root:not([data-skin="default"]) .mate,
:root:not([data-skin="default"]) .session-card,
:root:not([data-skin="default"]) .session-board-column,
:root:not([data-skin="default"]) .filters {
  background: var(--surface);
}
:root:not([data-skin="default"]) .session-board-column > header {
  background: var(--surface-muted);
}

/* ════════════════════════════════════════════════════════════════════════════
   SKIN SWITCH-IN INTROS — short, original per-skin transitions (mounted by
   skin-intro.ts; 2077 uses its own boot loader). All fade out via si-fade.
   ════════════════════════════════════════════════════════════════════════════ */
.skin-intro {
  position: fixed;
  inset: 0;
  z-index: 99999;
  pointer-events: none;
  overflow: hidden;
  display: grid;
  place-items: center;
  /* frosted mask so the page dims softly behind the intro (less abrupt) */
  -webkit-backdrop-filter: blur(7px);
  backdrop-filter: blur(7px);
  animation: si-fade var(--si-dur, 2s) ease forwards;
}
/* ease IN at the start + OUT at the end, instead of popping on instantly */
@keyframes si-fade {
  0% { opacity: 0; }
  11% { opacity: 1; }
  80% { opacity: 1; }
  100% { opacity: 0; visibility: hidden; }
}

/* —— 原神: "原神，启动" — ZZZ-style text loader in Genshin's cream/teal/gold —— */
.si-genshin {
  background:
    radial-gradient(circle at 50% 46%, hsl(42 92% 82% / 0.5), transparent 42%),
    radial-gradient(circle at 50% 46%, hsl(198 80% 74% / 0.4), transparent 60%),
    linear-gradient(180deg, hsl(214 66% 97% / 0.82), hsl(204 72% 94% / 0.82));
}
.si-genshin .si-gi-shine {
  position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 36%, hsl(42 95% 82% / 0.6) 48%, hsl(198 92% 86% / 0.55) 52%, transparent 66%);
  background-size: 250% 100%;
  animation: si-gi-shine var(--si-dur, 2s) ease forwards;
}
.si-genshin .si-gi-text {
  position: relative;
  font-weight: 900;
  font-size: clamp(30px, 7vw, 64px);
  letter-spacing: 0.12em;
  background: linear-gradient(100deg, hsl(199 76% 40%), hsl(186 72% 46%) 42%, hsl(42 88% 50%));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  filter: drop-shadow(0 2px 0 hsl(0 0% 100% / 0.6)) drop-shadow(0 0 28px hsl(42 90% 62% / 0.6));
  animation: si-gi-pop var(--si-dur, 2s) cubic-bezier(0.2, 0.9, 0.3, 1) forwards;
}
@keyframes si-gi-shine {
  0% { background-position: 120% 0; opacity: 0; }
  25% { opacity: 1; }
  75% { background-position: -40% 0; opacity: 1; }
  100% { opacity: 0; }
}
@keyframes si-gi-pop {
  0% { transform: scale(0.6); opacity: 0; letter-spacing: 0.5em; }
  35% { transform: scale(1.06); opacity: 1; letter-spacing: 0.12em; }
  60% { transform: scale(1); }
  100% { transform: scale(1); opacity: 1; }
}
@keyframes si-blink { 0%, 100% { opacity: 0.25; } 50% { opacity: 1; } }

/* —— 绝区零: TV static / channel-switch "NOW LOADING" —— */
.si-zzz { background: rgba(7, 7, 13, 0.85); }
.si-zzz .si-static {
  position: absolute; inset: 0;
  background:
    repeating-linear-gradient(0deg, hsl(75 90% 60% / 0.05) 0 2px, transparent 2px 4px),
    repeating-linear-gradient(90deg, rgba(255,255,255,0.04) 0 2px, transparent 2px 3px);
  mix-blend-mode: screen;
  animation: si-zzz-static 0.12s steps(2) infinite, si-zzz-off var(--si-dur, 1.9s) ease forwards;
}
.si-zzz .si-roll {
  position: absolute; left: 0; right: 0; height: 14%;
  background: linear-gradient(180deg, transparent, hsl(75 90% 60% / 0.18), transparent);
  animation: si-zzz-roll 0.7s linear infinite;
}
.si-zzz .si-now {
  position: relative; font-family: var(--mono);
  font-size: clamp(20px, 5vw, 40px); font-weight: 800; letter-spacing: 0.22em;
  color: hsl(75 95% 64%); text-shadow: 0 0 18px hsl(75 90% 55% / 0.7);
  animation: si-blink 0.7s steps(2, end) infinite;
}
@keyframes si-zzz-static { 0% { transform: translateY(0); } 100% { transform: translateY(-3px); } }
@keyframes si-zzz-roll { from { top: -14%; } to { top: 100%; } }
@keyframes si-zzz-off { 0%, 78% { transform: scaleY(1); opacity: 1; } 90% { transform: scaleY(0.02); opacity: 1; } 100% { transform: scaleY(0); opacity: 0; } }

/* —— 七龙珠: 悟空骑筋斗云 whooshing across with speed lines —— */
.si-dragonball {
  background: linear-gradient(180deg, hsl(205 85% 72% / 0.8), hsl(198 80% 86% / 0.78) 60%, hsl(45 90% 92% / 0.8));
}
.si-dragonball .si-cloud {
  display: block;
  width: clamp(150px, 26vw, 280px); height: auto;
  filter: drop-shadow(0 12px 18px hsl(38 80% 35% / 0.45));
  animation: si-db-fly var(--si-dur, 1.9s) cubic-bezier(0.4, 0.02, 0.45, 1) forwards;
}
.si-dragonball .si-speed {
  position: absolute; inset: 0;
  background: repeating-linear-gradient(90deg, rgba(255,255,255,0.55) 0 2px, transparent 2px 26px);
  opacity: 0; mix-blend-mode: overlay;
  animation: si-db-speed var(--si-dur, 1.9s) ease forwards;
}
@keyframes si-db-fly {
  0% { transform: translateX(-65vw) translateY(22px) rotate(-6deg) scale(0.9); }
  50% { transform: translateX(0) translateY(-22px) rotate(3deg) scale(1.05); }
  100% { transform: translateX(72vw) translateY(16px) rotate(-4deg) scale(0.92); }
}
@keyframes si-db-speed { 0% { opacity: 0; } 25%, 70% { opacity: 0.85; } 100% { opacity: 0; } }

/* —— ikun: bouncing 3D basketball (shaded sphere + only the seams spin) —— */
.si-ikun {
  background:
    radial-gradient(circle at 50% 46%, hsl(24 95% 55% / 0.22), transparent 46%),
    linear-gradient(180deg, hsl(270 42% 9% / 0.84), hsl(276 44% 6% / 0.84));
}
.si-ikun .si-bball {
  position: relative;
  width: clamp(108px, 19vw, 168px);
  aspect-ratio: 1;
  border-radius: 50%;
  transform-origin: 50% 100%;
  background: radial-gradient(circle at 35% 28%, #ffbf80 0%, #ef8033 34%, #cf6020 66%, #8f3d0e 100%);
  box-shadow:
    inset -12px -14px 30px rgba(60, 20, 0, 0.55),
    inset 9px 9px 20px rgba(255, 210, 150, 0.4),
    0 20px 32px rgba(0, 0, 0, 0.5);
  animation: si-ikun-bounce var(--si-dur, 1.9s) cubic-bezier(0.5, 0, 0.5, 1) forwards;
}
.si-ikun .si-bball::after {
  content: '';
  position: absolute;
  left: 18%; top: 12%;
  width: 32%; height: 24%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 255, 255, 0.55), transparent 72%);
  filter: blur(3px);
}
.si-ikun .si-bball-seams {
  position: absolute;
  inset: 0;
  animation: si-spin 0.6s linear infinite;
}
.si-ikun .si-bball-seams svg { display: block; width: 100%; height: 100%; }
@keyframes si-spin { to { transform: rotate(360deg); } }
/* uniform scale only — never distort the circle (no squash → always round) */
@keyframes si-ikun-bounce {
  0% { transform: translateY(-135%) scale(0.72); }
  34% { transform: translateY(0) scale(1); }
  52% { transform: translateY(-38%) scale(1); }
  70% { transform: translateY(0) scale(1); }
  84% { transform: translateY(-13%) scale(1); }
  100% { transform: translateY(0) scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .skin-intro { display: none; }
}
