/* =============================================================================
   Warp Admin Console — design system
   =============================================================================

   This file is the ONLY global stylesheet. It replaced three stacked theme
   generations (dark indigo, dark lime, light Grok2API refresh) that overrode each
   other and left 122 class names with no definition at all — which is why the
   console read as several design drafts stapled together.

   Rules for extending it:

   1. Use the tokens. A raw hex value or rgba() in a component rule is a bug
      unless it is a shadow or a translucent state overlay.
   2. One component, one definition. Later sections do not patch earlier ones.
   3. Text colour comes from --text-* only. --text-muted still has a 4.6:1
      contrast ratio on --surface-1; never use it below 12px.
   4. Page-specific rules go in that page's stylesheet (ops.css, accounts.css,
      models.css, config.css, tutorial.css), never here.
   5. Layout primitives in this file: .page, .page-head, .toolbar, .card, .kpi,
      .data-table, .badge, .btn, .drawer, .empty-state, .skeleton.

   Sections: 1 tokens · 2 reset · 3 shell · 4 page head · 5 buttons · 6 forms
   7 surfaces · 8 metrics · 9 tables · 10 badges · 11 tabs · 12 overlays
   13 states · 14 login · 15 docs · 16 utilities · 17 responsive
   ============================================================================= */

/* -----------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  color-scheme: dark;

  /* Surfaces, from the page background up to a raised popover. */
  --bg-app: #0b0e14;
  --bg-body: #0b0e14;
  --surface-1: #121722;
  --surface-2: #171d2b;
  --surface-3: #1e2634;
  --bg-surface: var(--surface-1);
  --bg-surface-hover: var(--surface-2);
  --bg-elevated: var(--surface-3);
  --bg-inset: rgba(0, 0, 0, 0.28);
  --bg-sidebar: #0e131c;

  /* Text. --text-soft is the lowest tone allowed for body copy; --text-faint is
     reserved for identifiers and stays above a 4.5:1 contrast ratio on
     --surface-1 so even the smallest labels remain readable. */
  --text-main: #eef2f8;
  --text-soft: #c3cddd;
  --text-secondary: #9aa7bd;
  --text-muted: #8593ab;
  --text-faint: #7d8aa1;
  --text-on-accent: #10130f;

  /* Brand. Warp's amber, used only for the primary action, focus and active nav. */
  --accent: #ffb257;
  --accent-strong: #ff9f2e;
  --accent-soft: rgba(255, 178, 87, 0.14);
  --accent-line: rgba(255, 178, 87, 0.45);
  --primary: var(--accent);
  --primary-hover: var(--accent-strong);
  --primary-light: var(--accent-soft);
  --primary-glow: rgba(255, 178, 87, 0.22);

  /* Semantic states. Every badge, pill and chart series draws from these. */
  --ok: #4ade9b;
  --ok-soft: rgba(74, 222, 155, 0.14);
  --warn: #f5c264;
  --warn-soft: rgba(245, 194, 100, 0.14);
  --bad: #fb7185;
  --bad-soft: rgba(251, 113, 133, 0.14);
  --info: #6cb6ff;
  --info-soft: rgba(108, 182, 255, 0.14);
  --idle: #8f9cb3;
  --idle-soft: rgba(143, 156, 179, 0.14);

  /* Legacy aliases kept so page stylesheets and inline styles keep resolving. */
  --accent-purple: #a78bfa;
  --accent-pink: #f0a6bd;
  --accent-cyan: #5eead4;
  --accent-blue: var(--info);
  --accent-green: var(--ok);
  --accent-orange: var(--accent);
  --accent-red: var(--bad);

  --border-color: rgba(148, 163, 184, 0.16);
  --border-strong: rgba(148, 163, 184, 0.28);
  --border-highlight: rgba(255, 178, 87, 0.35);

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.35);
  --shadow-md: 0 6px 20px rgba(3, 6, 12, 0.45);
  --shadow-lg: 0 24px 60px rgba(3, 6, 12, 0.6);
  --shadow-glow: 0 0 0 3px rgba(255, 178, 87, 0.18);

  /* 4px spacing scale. Every gap, padding and margin uses a step. */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;

  /* Three radii only: controls, containers, pills. */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 14px;
  --radius-pill: 999px;
  --radius-xs: var(--radius-sm);
  --radius-xl: var(--radius-lg);

  /* One control height for every button, input and select. */
  --control-h: 34px;
  --control-h-sm: 28px;
  --control-h-lg: 40px;

  --sidebar-w: 248px;
  --content-max: 1440px;
  --table-row-h: 42px;

  --font-sans: 'Outfit', 'Geist Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, 'JetBrains Mono', 'Cascadia Mono', Consolas, monospace;

  --transition: 140ms ease;
  --z-sidebar: 60;
  --z-overlay: 70;
  --z-drawer: 80;
  --z-modal: 90;
  --z-toast: 100;
}

/* -----------------------------------------------------------------------------
   2. Reset & base
   -------------------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
  padding: 0;
}

/* Author-level display rules such as .form-group { display:block } override the
   browser's built-in [hidden] rule. Keep hidden state authoritative everywhere. */
[hidden] {
  display: none !important;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  display: flex;
  min-height: 100vh;
  background: var(--bg-app);
  color: var(--text-main);
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

a {
  color: inherit;
  text-decoration: none;
}

h1,
h2,
h3,
h4 {
  font-weight: 650;
  line-height: 1.25;
  letter-spacing: -0.01em;
}

h1 { font-size: 1.35rem; }
h2 { font-size: 1rem; }
h3 { font-size: 0.94rem; }

p { color: var(--text-soft); }

ul, ol { list-style: none; }

img, svg { display: block; max-width: 100%; }

code, pre, .token-text, .key-display {
  font-family: var(--font-mono);
}

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

::selection {
  background: var(--accent-soft);
  color: var(--text-main);
}

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: rgba(148, 163, 184, 0.28);
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: var(--radius-pill);
}
::-webkit-scrollbar-thumb:hover { background: rgba(148, 163, 184, 0.45); background-clip: content-box; }

/* Decorative layers from the first theme generation: retired, kept as no-ops so
   stale markup cannot resurrect them. */
body::before,
.ambient-bg,
.blob,
.blob-1,
.blob-2,
.grid-orbit {
  display: none !important;
}

/* -----------------------------------------------------------------------------
   3. Shell: sidebar + content column
   -------------------------------------------------------------------------- */
.sidebar {
  position: fixed;
  inset: 0 auto 0 0;
  z-index: var(--z-sidebar);
  display: flex;
  flex-direction: column;
  width: var(--sidebar-w);
  padding: var(--space-4) var(--space-3) var(--space-3);
  background: var(--bg-sidebar);
  border-right: 1px solid var(--border-color);
  overflow-y: auto;
}

.sidebar-header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-2) var(--space-4);
}

.logo {
  flex: none;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-md);
  background: linear-gradient(140deg, var(--accent), #d97706);
  color: var(--text-on-accent);
  font-weight: 800;
  font-size: 0.95rem;
}

.sidebar-brand-text { min-width: 0; }

.sidebar-header .title,
.sidebar-title,
.mobile-topbar-brand .title {
  color: var(--text-main);
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.sidebar-subtitle {
  color: var(--text-muted);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.sidebar-menu {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.sidebar-item { display: block; }

.sidebar-link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: 0.86rem;
  font-weight: 500;
  transition: background var(--transition), color var(--transition);
}

.sidebar-link:hover {
  background: var(--surface-2);
  color: var(--text-main);
}

.sidebar-link.active {
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 650;
}

.nav-glyph {
  flex: none;
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border-radius: var(--radius-sm);
  color: currentColor;
  font-size: 0.62rem;
  font-weight: 700;
}

.nav-glyph svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.nav-glyph-small { width: 16px; height: 16px; }

.sidebar-footer {
  margin-top: auto;
  padding-top: var(--space-4);
  border-top: 1px solid var(--border-color);
}

.sidebar-footer-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}

.footer-stat-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--surface-1);
}

.footer-stat-label { color: var(--text-muted); font-size: 0.7rem; }
.footer-stat-value { font-variant-numeric: tabular-nums; font-size: 0.95rem; font-weight: 650; }
.footer-stat-value.normal { color: var(--ok); }
.footer-stat-value.abnormal { color: var(--bad); }

/* Which build rendered this page. Small, but the first thing to check when the
   console looks outdated. */
.sidebar-build {
  margin: 0 0 var(--space-3);
  color: var(--text-faint);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  word-break: break-all;
}

.sidebar-logout {
  width: 100%;
  justify-content: center;
}

.sidebar-actions,
.sidebar-list,
.sidebar-toggle,
.sidebar-expand-btn,
.sidebar-action-btn { display: none; }

/* Small screens: the sidebar becomes a drawer behind the top bar. */
.mobile-topbar {
  display: none;
  position: fixed;
  inset: 0 0 auto 0;
  z-index: var(--z-overlay);
  align-items: center;
  gap: var(--space-3);
  height: 56px;
  padding: 0 var(--space-4);
  background: rgba(11, 14, 20, 0.92);
  border-bottom: 1px solid var(--border-color);
  backdrop-filter: blur(12px);
}

.mobile-topbar-brand { display: flex; align-items: center; gap: var(--space-3); }

.mobile-menu-btn {
  display: grid;
  gap: 4px;
  width: 36px;
  height: 36px;
  padding: 9px;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  cursor: pointer;
}

.mobile-menu-btn span {
  display: block;
  height: 2px;
  border-radius: var(--radius-pill);
  background: var(--text-soft);
}

.sidebar-overlay {
  display: none;
  position: fixed;
  inset: 0;
  /* The backdrop belongs to the sidebar, so it sits just under it — the same rule the
     log detail panel's backdrop follows. It used to share --z-overlay with the mobile
     top bar (70), which put it ABOVE the open drawer (60): every tap meant for a nav
     link landed on the backdrop, which closed the drawer instead of navigating, so the
     drawer was a dead end on a phone. */
  z-index: calc(var(--z-sidebar) - 1);
  background: rgba(3, 6, 12, 0.6);
}

.sidebar-overlay.active { display: block; }

.main-content {
  flex: 1;
  min-width: 0;
  width: 100%;
  max-width: var(--content-max);
  margin: 0 0 0 var(--sidebar-w);
  padding: var(--space-8) var(--space-8) var(--space-10);
  animation: none;
}

/* -----------------------------------------------------------------------------
   4. Page head & toolbar
   -------------------------------------------------------------------------- */
.header-section {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4) var(--space-6);
  margin-bottom: var(--space-5);
}

/* The title block never shrinks below its text: a page title that wraps to two
   lines ("运维总 / 览") was the symptom of a two-column head with no basis. */
.header-section > div:first-child,
.page-head-text {
  flex: 0 1 auto;
  min-width: max-content;
}

.header-section h1,
.page-title {
  margin-bottom: var(--space-1);
  font-size: 1.5rem;
  font-weight: 700;
  white-space: nowrap;
}

.header-section p,
.page-sub {
  max-width: 76ch;
  color: var(--text-secondary);
  font-size: 0.86rem;
}

.page-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  flex: 0 0 auto;
  margin-left: auto;
}

.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  background: var(--surface-1);
}

.toolbar-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-left: auto;
}

.toolbar-actions-spread { justify-content: space-between; }
.toolbar-compact { padding: var(--space-2) var(--space-3); }
.toolbar-divider { width: 1px; height: 22px; background: var(--border-color); }
.toolbar-group { display: flex; align-items: center; gap: var(--space-2); }
.toolbar-spacer { flex: 1 1 auto; }

/* -----------------------------------------------------------------------------
   5. Buttons
   -------------------------------------------------------------------------- */
.btn,
.btn-primary,
.btn-secondary,
.btn-outline,
.btn-neutral,
.btn-danger,
.btn-danger-outline,
.btn-save,
.btn-page,
.btn-icon,
.icon-btn,
.action-icon,
.ops-refresh,
.ops-chip,
.chip,
.send-btn,
.models-primary-action,
.models-refresh-action,
.models-action-btn,
.capability-action,
.panel-close-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: var(--control-h);
  padding: 0 var(--space-3);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text-main);
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 550;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--transition), border-color var(--transition), color var(--transition), opacity var(--transition);
}

.btn:hover,
.btn-secondary:hover,
.btn-outline:hover,
.btn-neutral:hover,
.btn-icon:hover,
.icon-btn:hover,
.action-icon:hover,
.models-action-btn:hover,
.capability-action:hover,
.panel-close-btn:hover {
  background: var(--surface-3);
  border-color: var(--border-strong);
}

.btn:disabled,
.btn[disabled],
.btn.is-loading {
  opacity: 0.45;
  cursor: not-allowed;
}

.btn-primary,
.btn-save,
.send-btn,
.models-primary-action,
.models-refresh-action {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--text-on-accent);
  font-weight: 650;
}

.btn-primary:hover,
.btn-save:hover,
.send-btn:hover,
.models-primary-action:hover,
.models-refresh-action:hover {
  background: var(--accent-strong);
  border-color: var(--accent-strong);
  color: var(--text-on-accent);
}

.btn-outline {
  background: transparent;
  border-color: var(--border-strong);
  color: var(--text-soft);
}

.btn-neutral { background: var(--surface-3); }

.btn-danger,
.models-action-btn-danger {
  background: var(--bad-soft);
  border-color: rgba(251, 113, 133, 0.4);
  color: var(--bad);
}

.btn-danger:hover,
.models-action-btn-danger:hover {
  background: rgba(251, 113, 133, 0.22);
  color: #ffd6de;
}

.btn-danger-outline {
  background: transparent;
  border-color: rgba(251, 113, 133, 0.45);
  color: var(--bad);
}

.btn-xs,
.models-action-btn.mobile-only {
  height: 24px;
  padding: 0 var(--space-2);
  font-size: 0.72rem;
}

.btn-sm { height: var(--control-h-sm); padding: 0 var(--space-2); font-size: 0.78rem; }
.btn-lg { height: var(--control-h-lg); padding: 0 var(--space-5); font-size: 0.9rem; }

/* Square icon button: 34x34 with a single glyph. */
.btn-icon,
.icon-btn,
.action-icon,
.panel-close-btn {
  width: var(--control-h);
  padding: 0;
  background: transparent;
  border-color: var(--border-color);
  color: var(--text-secondary);
}

.panel-close-btn { width: var(--control-h-sm); height: var(--control-h-sm); }

/* Segmented control: time ranges, tabs and log kinds. */
.ops-chip,
.chip,
.btn-page,
.tab-item,
.logs-tab,
.filter-tabs .tab-item {
  height: var(--control-h-sm);
  padding: 0 var(--space-3);
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-color);
  background: transparent;
  color: var(--text-secondary);
  font-size: 0.78rem;
  font-weight: 550;
}

.ops-chip:hover,
.chip:hover,
.btn-page:hover,
.tab-item:hover,
.logs-tab:hover {
  border-color: var(--border-strong);
  color: var(--text-main);
  background: var(--surface-2);
}

.ops-chip.is-active,
.chip.is-active,
.tab-item.active,
.tab-item.is-active,
.logs-tab.is-active,
.btn-page-current {
  background: var(--accent-soft);
  border-color: var(--accent-line);
  color: var(--accent);
  font-weight: 650;
}

.btn-page-current { cursor: default; }

/* -----------------------------------------------------------------------------
   6. Forms
   -------------------------------------------------------------------------- */
input,
select,
textarea,
.form-input,
.form-control {
  width: 100%;
  min-height: var(--control-h);
  padding: 0 var(--space-3);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: var(--bg-inset);
  color: var(--text-main);
  font-family: inherit;
  font-size: 0.84rem;
  transition: border-color var(--transition), box-shadow var(--transition);
}

textarea {
  min-height: 96px;
  padding: var(--space-3);
  line-height: 1.6;
  resize: vertical;
}

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

input:focus,
select:focus,
textarea:focus,
.form-input:focus {
  outline: none;
  border-color: var(--accent-line);
  box-shadow: var(--shadow-glow);
}

input:disabled,
select:disabled,
textarea:disabled,
.is-unavailable input {
  opacity: 0.55;
  cursor: not-allowed;
}

select {
  appearance: none;
  padding-right: var(--space-8);
  background-image: linear-gradient(45deg, transparent 50%, var(--text-muted) 50%),
    linear-gradient(135deg, var(--text-muted) 50%, transparent 50%);
  background-position: calc(100% - 18px) 50%, calc(100% - 13px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  cursor: pointer;
}

select option { background: var(--surface-3); color: var(--text-main); }

input[type="checkbox"],
input[type="radio"],
.row-checkbox {
  width: 16px;
  height: 16px;
  min-height: 0;
  padding: 0;
  accent-color: var(--accent);
  cursor: pointer;
}

.row-checkbox { vertical-align: middle; }

input[type="range"],
.range-input {
  min-height: 0;
  padding: 0;
  border: 0;
  background: transparent;
  accent-color: var(--accent);
}

.compact-select {
  min-width: 108px;
  min-height: var(--control-h-sm);
  font-size: 0.78rem;
}

.form-group,
.field,
.config-field { display: flex; flex-direction: column; gap: var(--space-2); }

.form-label,
.field-label,
.config-key-label,
.models-section-label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--text-soft);
  font-size: 0.78rem;
  font-weight: 600;
}

.form-row,
.field-row {
  display: grid;
  grid-template-columns: minmax(160px, 240px) minmax(0, 1fr);
  gap: var(--space-4);
  align-items: start;
}

.helper-text,
.form-hint,
.field-hint {
  color: var(--text-muted);
  font-size: 0.75rem;
  line-height: 1.6;
}

.input-wrapper {
  position: relative;
  display: flex;
  align-items: center;
}

.input-wrapper .input-icon {
  position: absolute;
  left: var(--space-3);
  display: grid;
  place-items: center;
  color: var(--text-faint);
  font-size: 0.8rem;
  pointer-events: none;
}

.input-wrapper .input-icon ~ input { padding-left: var(--space-8); }

.input-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.password-toggle,
.key-toggle {
  position: absolute;
  right: var(--space-2);
  display: grid;
  place-items: center;
  width: var(--control-h-sm);
  height: var(--control-h-sm);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-muted);
  font-size: 0.7rem;
  cursor: pointer;
}

.password-toggle:hover,
.key-toggle:hover { color: var(--text-main); background: var(--surface-2); }

/* Switch. The JS toggles `.toggle.active` and keeps the native checkbox hidden. */
.toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  width: 38px;
  height: 22px;
  flex: none;
  border-radius: var(--radius-pill);
  background: var(--surface-3);
  border: 1px solid var(--border-strong);
  cursor: pointer;
  transition: background var(--transition), border-color var(--transition);
}

.toggle-slider {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--text-soft);
  transition: transform var(--transition), background var(--transition);
}

.toggle.active {
  background: var(--accent);
  border-color: var(--accent);
}

.toggle.active .toggle-slider {
  transform: translateX(16px);
  background: var(--text-on-accent);
}

/* Belt and braces: a switch whose checkbox is checked reads as ON even if the page
   forgot to mirror the state onto the label. The models table did exactly that —
   the box was checked and the switch still looked off, which is how a 启用 toggle
   came to look disabled. */
.toggle:has(input:checked) {
  background: var(--accent);
  border-color: var(--accent);
}

.toggle:has(input:checked) .toggle-slider {
  transform: translateX(16px);
  background: var(--text-on-accent);
}

.toggle input { position: absolute; opacity: 0; pointer-events: none; }

/* Advanced / collapsed blocks: a control that hides rarely used fields. */
.advanced-settings {
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  background: var(--surface-1);
  overflow: hidden;
}

.advanced-settings > summary,
details.collapsible > summary {
  padding: var(--space-3) var(--space-4);
  color: var(--text-soft);
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}

.advanced-settings > summary::-webkit-details-marker { display: none; }

.advanced-settings > summary::before {
  content: "＋";
  margin-right: var(--space-2);
  color: var(--text-muted);
}

.advanced-settings[open] > summary::before { content: "－"; }

.advanced-settings[open] > summary { border-bottom: 1px solid var(--border-color); }

.advanced-settings .advanced-body { padding: var(--space-4); }

.collapsed { display: none; }
.section-hidden { display: none; }

/* -----------------------------------------------------------------------------
   7. Surfaces: cards, panels, sections
   -------------------------------------------------------------------------- */
.content-card,
.card,
.dr-card,
.ops-card,
.models-filter-panel,
.models-results-card,
.grok-panel,
.settings-panel,
.estimate-panel,
.doc-callout,
.doc-table-wrap,
.config-key-card,
.cache-list,
.task-list {
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  background: var(--surface-1);
  box-shadow: none;
}

.card,
.content-card,
.models-results-card { overflow: hidden; }

.card-head,
.section-head,
.models-results-head,
.models-filter-top,
.config-key-head,
.settings-panel-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--border-color);
}

.card-head h2,
.section-title,
.config-section,
.settings-panel-title,
.models-section-label {
  font-size: 0.92rem;
  font-weight: 650;
}

.card-body,
.section-body,
.settings-panel-body { padding: var(--space-4) var(--space-5); }

.card-title,
.doc-title {
  font-size: 0.98rem;
  font-weight: 650;
}

/* Tinted stat icon for the two account KPIs that carry their own meaning. */
.stat-icon.total { background: var(--info-soft); color: var(--info); }
.stat-icon.selected { background: rgba(167, 139, 250, 0.14); color: var(--accent-purple); }

.settings-panel-spaced { margin-top: var(--space-5); }

.settings-panel-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-4);
}

/* The save bar that closes a settings panel. On the config page this is the
   sticky .sticky-actions bar instead. */
.save-footer {
  display: flex;
  justify-content: flex-end;
  padding: var(--space-4) var(--space-5);
  border-top: 1px solid var(--border-color);
  background: var(--surface-1);
}

.config-section-shell { padding: var(--space-5); }
.config-subsection { margin-top: var(--space-3); }
.config-grid { display: grid; gap: var(--space-5); }
.config-grid-two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.config-grid-gap-sm { gap: var(--space-4); }

.estimate-card-green { border-color: rgba(74, 222, 155, 0.28); background: var(--ok-soft); }
.estimate-card-blue { border-color: rgba(108, 182, 255, 0.28); background: var(--info-soft); }
.estimate-card-purple { border-color: rgba(167, 139, 250, 0.28); background: rgba(167, 139, 250, 0.08); }

.estimate-meta {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-2);
  color: var(--text-muted);
  font-size: 0.74rem;
}

.doc-callout-inline {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
}

.modal-close {
  display: grid;
  place-items: center;
  width: var(--control-h);
  height: var(--control-h);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-muted);
  font-size: 1.15rem;
  line-height: 1;
  cursor: pointer;
}

.modal-close:hover { background: var(--surface-3); color: var(--text-main); }

.hint,
.card-hint,
.helper,
.ops-hint,
.meta-text,
.meta-text-xs {
  color: var(--text-muted);
  font-size: 0.75rem;
  line-height: 1.6;
}

.section-head { border-bottom: 0; padding-bottom: 0; }

/* Settings blocks: label on the left, control on the right, one row per knob. */
.settings-block,
.function-settings-block {
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  padding: var(--space-4);
}

.settings-block-full { grid-column: 1 / -1; }

.settings-block-head,
.function-header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.settings-block-title,
.function-title { font-size: 0.86rem; font-weight: 650; }

.settings-grid,
.function-stack {
  display: grid;
  gap: var(--space-3);
}

/* -----------------------------------------------------------------------------
   8. Metrics & stats
   -------------------------------------------------------------------------- */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--space-3);
  margin-bottom: var(--space-5);
}

.stat-card,
.kpi {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: 92px;
  padding: var(--space-4);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  background: var(--surface-1);
}

.stat-card::after { content: none; }
.stat-card { background: var(--surface-1); }

.stat-info {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}

.stat-info .label,
.kpi .label {
  color: var(--text-muted);
  font-size: 0.74rem;
  font-weight: 550;
  letter-spacing: 0.01em;
}

.stat-info .value,
.kpi .value {
  color: var(--text-main);
  font-size: 1.6rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.stat-info .note,
.kpi .note {
  color: var(--text-muted);
  font-size: 0.72rem;
}

.stat-icon {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  flex: none;
  border-radius: var(--radius-sm);
  background: var(--surface-3);
  color: var(--text-secondary);
  font-size: 0.66rem;
  font-weight: 700;
}

.stat-icon svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.metric-positive { color: var(--ok); }
.metric-negative { color: var(--bad); }
.metric-accent { color: var(--accent); }

.meta-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--space-3);
}

.meta-item { display: flex; flex-direction: column; gap: 2px; }
.meta-label { color: var(--text-muted); font-size: 0.72rem; }
.meta-value { color: var(--text-main); font-size: 0.84rem; font-variant-numeric: tabular-nums; }

.estimate-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-3);
}

.estimate-card {
  padding: var(--space-4);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  background: var(--surface-2);
}

.estimate-title,
.estimate-caption { color: var(--text-muted); font-size: 0.74rem; }
.estimate-value { font-size: 1.3rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.estimate-value-blue { color: var(--info); }
.estimate-value-green { color: var(--ok); }
.estimate-value-purple { color: var(--accent-purple); }

.progress-wrap,
.progress-wrap-spaced {
  position: relative;
  width: 100%;
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--bg-inset);
  overflow: hidden;
}

.progress-wrap-spaced { margin-top: var(--space-2); }

.progress-bar,
.progress-fill {
  height: 100%;
  border-radius: var(--radius-pill);
  background: var(--accent);
  transition: width var(--transition);
}

.progress-meta {
  display: flex;
  justify-content: space-between;
  margin-top: var(--space-1);
  color: var(--text-muted);
  font-size: 0.72rem;
}

/* -----------------------------------------------------------------------------
   9. Tables
   -------------------------------------------------------------------------- */
.table-wrap,
.models-table-wrap,
.ops-table-wrap,
.doc-table-wrap,
.logs-list-wrap {
  width: 100%;
  overflow-x: auto;
}

table,
.table,
.data-table,
.models-table,
.ops-table,
.logs-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 0.83rem;
}

table thead th,
.data-table thead th,
.models-table thead th,
.ops-table thead th,
.logs-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-strong);
  background: var(--surface-2);
  color: var(--text-muted);
  font-size: 0.74rem;
  font-weight: 600;
  text-align: left;
  white-space: nowrap;
}

table tbody td,
.data-table tbody td,
.models-table tbody td,
.ops-table tbody td,
.logs-table tbody td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-color);
  color: var(--text-soft);
  vertical-align: middle;
}

table tbody tr:hover td,
.data-table tbody tr:hover td { background: var(--surface-2); }

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

.data-table tbody tr.is-selected td,
.logs-table tbody tr.is-selected td { background: var(--accent-soft); }

.data-table tbody tr.is-group td {
  background: var(--surface-2);
  color: var(--text-main);
  font-weight: 650;
}

.data-table tbody tr.is-child td:first-child { padding-left: var(--space-8); }
.data-table tbody tr.is-child td { color: var(--text-secondary); }

.table-empty-cell,
.table-empty {
  padding: var(--space-8) var(--space-4);
  color: var(--text-muted);
  text-align: center;
}

.table-checkbox-cell,
.col-check { width: 40px; text-align: center; }
.col-actions { width: 120px; text-align: right; white-space: nowrap; }
.col-model { min-width: 220px; }
.col-status { width: 120px; }
.col-sort { width: 90px; }
.col-toggle { width: 90px; }
.col-token { max-width: 260px; }

.num,
td.num,
.metrics-value { font-variant-numeric: tabular-nums; text-align: right; }

.pagination-shell {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--border-color);
  background: var(--surface-1);
}

.pagination-controls { display: flex; align-items: center; gap: var(--space-2); }
.pagination-info { color: var(--text-muted); font-size: 0.76rem; }

/* -----------------------------------------------------------------------------
   10. Badges, tags & tokens
   -------------------------------------------------------------------------- */
.badge,
.status-badge,
.tag,
.tag-mini,
.mini-badge,
.models-status-badge,
.models-default-badge,
.models-meta-pill,
.protocol-tag,
.account-nsfw-tag,
.account-tier-tag,
.model-chip,
.selected-count {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  height: 22px;
  padding: 0 var(--space-2);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-pill);
  background: var(--idle-soft);
  color: var(--text-soft);
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
}

.status-badge:empty { display: none; }

.is-ok,
.is-ready,
.tag.is-ok,
.status-badge.is-ok { color: var(--ok); border-color: rgba(74, 222, 155, 0.35); background: var(--ok-soft); }

.is-warn,
.is-warning,
.is-pending,
.status-badge.is-warn { color: var(--warn); border-color: rgba(245, 194, 100, 0.35); background: var(--warn-soft); }

.is-bad,
.is-error,
.status-badge.is-error,
.warning-text { color: var(--bad); border-color: rgba(251, 113, 133, 0.35); background: var(--bad-soft); }

.is-info,
.status-badge.is-info { color: var(--info); border-color: rgba(108, 182, 255, 0.35); background: var(--info-soft); }

.is-idle,
.is-running,
.is-loading,
.is-unavailable,
.is-filtered { color: var(--idle); border-color: var(--border-strong); background: var(--idle-soft); }

.badge-grok,
.badge-warp,
.badge-puter,
.badge-workbuddy,
.badge-qoder,
.protocol-tag-claude,
.protocol-tag-openai {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.02em;
}

.badge-grok { color: var(--accent); border-color: var(--accent-line); background: var(--accent-soft); }
.badge-warp { color: var(--info); border-color: rgba(108, 182, 255, 0.35); background: var(--info-soft); }
.badge-puter { color: var(--accent-purple); border-color: rgba(167, 139, 250, 0.35); background: rgba(167, 139, 250, 0.14); }
.badge-workbuddy { color: var(--ok); border-color: rgba(74, 222, 155, 0.35); background: var(--ok-soft); }
.badge-qoder { color: var(--warn); border-color: rgba(251, 191, 36, 0.35); background: rgba(251, 191, 36, 0.14); }

.account-nsfw-tag { color: var(--accent-pink); border-color: rgba(240, 166, 189, 0.35); background: rgba(240, 166, 189, 0.12); }
.account-tier-tag { color: var(--text-soft); }

.token-text,
.key-display {
  display: block;
  max-width: 100%;
  overflow: hidden;
  color: var(--text-muted);
  font-size: 0.74rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* -----------------------------------------------------------------------------
   11. Tabs
   -------------------------------------------------------------------------- */
.filter-tabs,
.platform-tabs,
.config-tabs-shell,
.grok-tabs,
.logs-tabs,
.tabs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  padding: 0;
  border: 0;
  background: transparent;
}

.tabs { margin-bottom: var(--space-4); }

/* -----------------------------------------------------------------------------
   12. Overlays: modal, drawer, popover, toast
   -------------------------------------------------------------------------- */
.modal {
  display: none;
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  align-items: center;
  justify-content: center;
  padding: var(--space-6);
  background: rgba(3, 6, 12, 0.7);
  backdrop-filter: blur(3px);
}

.modal.active { display: flex; }

.modal-content {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 620px;
  max-height: 88vh;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  background: var(--surface-2);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}

.modal-content-sm { max-width: 420px; }
.modal-content-md { max-width: 620px; }
.modal-content-lg { max-width: 880px; }

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--border-color);
}

.modal-title { font-size: 0.98rem; font-weight: 650; }

.modal-body,
.modal-scroll {
  padding: var(--space-5);
  overflow-y: auto;
}

.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-5);
  border-top: 1px solid var(--border-color);
}

/* Drawer: the log centre's detail panel and the models editor. */
.drawer {
  position: fixed;
  inset: 0 0 0 auto;
  z-index: var(--z-drawer);
  display: flex;
  flex-direction: column;
  width: min(560px, 100vw);
  background: var(--surface-2);
  border-left: 1px solid var(--border-strong);
  box-shadow: var(--shadow-lg);
  transform: translateX(100%);
  transition: transform 180ms ease;
}

.drawer.is-open { transform: translateX(0); }

.drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--border-color);
}

.drawer-body { flex: 1; padding: var(--space-5); overflow-y: auto; }
.drawer-foot { padding: var(--space-4) var(--space-5); border-top: 1px solid var(--border-color); }

.drawer-backdrop {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-drawer) - 1);
  display: none;
  background: rgba(3, 6, 12, 0.55);
}

.drawer-backdrop.is-open { display: block; }

.popover,
.model-dropdown {
  position: absolute;
  z-index: var(--z-drawer);
  min-width: 200px;
  padding: var(--space-2);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface-3);
  box-shadow: var(--shadow-md);
}

.toast-container {
  position: fixed;
  top: var(--space-5);
  right: var(--space-5);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  pointer-events: none;
}

.toast {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 240px;
  max-width: 420px;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-strong);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-md);
  background: var(--surface-3);
  box-shadow: var(--shadow-md);
  color: var(--text-main);
  font-size: 0.82rem;
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity var(--transition), transform var(--transition);
}

.toast.show { opacity: 1; transform: translateY(0); }
.toast[data-type="error"] { border-left-color: var(--bad); }
.toast[data-type="info"] { border-left-color: var(--info); }

.toast-mark {
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  flex: none;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 0.66rem;
  font-weight: 700;
}

.toast[data-type="error"] .toast-mark { background: var(--bad-soft); color: var(--bad); }

.toast-message { min-width: 0; }

/* -----------------------------------------------------------------------------
   13. States: empty, loading, error
   -------------------------------------------------------------------------- */
.empty-state,
.empty-state-panel,
.models-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-8) var(--space-4);
  text-align: center;
}

.empty-state-panel { border-radius: var(--radius-md); background: var(--surface-1); }

.empty-state-mark,
.models-empty-icon,
.empty-title {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-md);
  background: var(--surface-3);
  color: var(--text-muted);
  font-size: 0.78rem;
  font-weight: 700;
}

.empty-subtitle,
.empty-state p { color: var(--text-muted); font-size: 0.8rem; }

/* Loading is a skeleton shimmer, never a grey veil over live content: a veil
   reads as "the page is broken". */
.loading,
.is-loading-block {
  position: relative;
  min-height: 60px;
  border-radius: var(--radius-md);
}

.skeleton,
.skeleton-line {
  border-radius: var(--radius-sm);
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 37%, var(--surface-2) 63%);
  background-size: 400% 100%;
  animation: skeleton-shimmer 1.4s ease-in-out infinite;
}

.skeleton-line { height: 12px; margin-bottom: var(--space-2); }
.skeleton-line.w-40 { width: 40%; }
.skeleton-line.w-70 { width: 70%; }
.skeleton-card { height: 92px; border-radius: var(--radius-lg); }

@keyframes skeleton-shimmer {
  from { background-position: 100% 50%; }
  to { background-position: 0 50%; }
}

.loading-spinner {
  display: inline-block;
  width: 16px;
  height: 16px;
  border: 2px solid var(--border-strong);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

.error,
.warning-box {
  padding: var(--space-3) var(--space-4);
  border: 1px solid rgba(251, 113, 133, 0.35);
  border-left: 3px solid var(--bad);
  border-radius: var(--radius-md);
  background: var(--bad-soft);
  color: var(--text-main);
  font-size: 0.8rem;
}

.warning-box { border-color: rgba(245, 194, 100, 0.35); border-left-color: var(--warn); background: var(--warn-soft); }

/* Sticky action bar: saves without scrolling back down a long page. */
.sticky-actions {
  position: sticky;
  bottom: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-5);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: rgba(23, 29, 43, 0.96);
  backdrop-filter: blur(10px);
}

.unsaved-dot {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--warn);
  font-size: 0.78rem;
}

.unsaved-dot::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--warn);
}

/* -----------------------------------------------------------------------------
   14. Login page
   -------------------------------------------------------------------------- */
.login-body {
  display: grid;
  place-items: center;
  min-height: 100vh;
  padding: var(--space-6);
  background: radial-gradient(120% 80% at 50% 0%, #16202e 0%, var(--bg-app) 60%);
}

.login-card {
  width: 100%;
  max-width: 400px;
  padding: var(--space-8) var(--space-6);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  background: var(--surface-1);
  box-shadow: var(--shadow-md);
}

.login-hero,
.login-brand { display: flex; flex-direction: column; gap: var(--space-2); margin-bottom: var(--space-6); }
.login-kicker { color: var(--accent); font-size: 0.72rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; }
.login-brand-subtitle,
.login-links { color: var(--text-muted); font-size: 0.78rem; }
.login-links { margin-top: var(--space-4); display: flex; justify-content: space-between; }
.login-submit { width: 100%; height: var(--control-h-lg); }

/* -----------------------------------------------------------------------------
   15. Documentation blocks (使用教程)
   -------------------------------------------------------------------------- */
.doc-shell {
  display: grid;
  gap: var(--space-5);
}

.doc-callout {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-5);
  border-left: 3px solid var(--info);
}

.doc-callout-head { font-weight: 650; }
.doc-callout-amber { border-left-color: var(--warn); }
.doc-callout-cyan { border-left-color: var(--info); }
.doc-callout-green { border-left-color: var(--ok); }

.doc-code-block,
.code-block,
.clear-block,
.length-block,
.preset-block,
.upload-block,
.ratio-block,
.ref-block,
.img-grid {
  display: block;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  background: var(--bg-inset);
  color: var(--text-soft);
  font-family: var(--font-mono);
  font-size: 0.78rem;
  line-height: 1.7;
  overflow-x: auto;
}

.doc-inline-code,
.inline-code,
.inline-code,
.doc-inline-code-green,
.doc-inline-code-amber,
.doc-inline-code-red,
.doc-link-code,
.doc-model-code {
  padding: 1px 6px;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: var(--bg-inset);
  color: var(--text-main);
  font-family: var(--font-mono);
  font-size: 0.78rem;
}

.doc-inline-code-green { color: var(--ok); }
.doc-inline-code-amber { color: var(--warn); }
.doc-inline-code-red { color: var(--bad); }
.doc-strong { color: var(--text-main); font-weight: 650; }
.doc-strong-green { color: var(--ok); font-weight: 650; }
.doc-strong-amber { color: var(--warn); font-weight: 650; }
.doc-strong-red { color: var(--bad); font-weight: 650; }
.doc-mark,
.doc-mark-amber,
.doc-mark-cyan,
.doc-mark-green {
  color: var(--accent);
  font-weight: 650;
}

/* -----------------------------------------------------------------------------
   16. Utilities
   -------------------------------------------------------------------------- */
.hidden,
.is-hidden { display: none !important; }

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.inline-flex-row { display: inline-flex; align-items: center; gap: var(--space-2); }
.inline-actions { display: flex; align-items: center; gap: var(--space-2); }
.eq { display: flex; align-items: center; }
.has-url { word-break: break-all; }
.nowrap { white-space: nowrap; }
.muted { color: var(--text-muted); }
.normal { color: var(--text-soft); }
.abnormal { color: var(--bad); }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.compact-select { width: auto; }

/* -----------------------------------------------------------------------------
   17. Responsive
   -------------------------------------------------------------------------- */
@media (max-width: 1200px) {
  .main-content { padding: var(--space-6); }
  .header-section h1 { white-space: normal; }
}

@media (max-width: 900px) {
  body { display: block; }

  .mobile-topbar { display: flex; }

  .sidebar {
    transform: translateX(-100%);
    transition: transform 180ms ease;
    box-shadow: var(--shadow-lg);
    /* The drawer slides under the fixed top bar; without this its own brand block
       sits behind the bar and reads as clipped text. The top bar already carries the
       brand, so the duplicate header goes. */
    padding-top: calc(56px + env(safe-area-inset-top) + var(--space-3));
  }

  .sidebar-header { display: none; }

  .sidebar.mobile-open { transform: translateX(0); }

  body.sidebar-open { overflow: hidden; }

  .main-content {
    margin: 0;
    padding: 72px var(--space-4) var(--space-8);
  }

  .header-section { align-items: flex-start; }
  .page-actions { margin-left: 0; }
  .toolbar { padding: var(--space-3); }
  .form-row,
  .field-row,
  .config-grid-two,
  .estimate-grid { grid-template-columns: 1fr; gap: var(--space-2); }

  .pagination-shell,
  .settings-panel-head,
  .settings-panel-foot,
  .section-head,
  .doc-callout-inline {
    flex-direction: column;
    align-items: stretch;
  }
}

@media (max-width: 640px) {
  .main-content { padding: 68px var(--space-3) var(--space-6); }
  .header-section h1 { font-size: 1.25rem; }
  .stats-grid { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
  .modal { padding: var(--space-3); }
  .drawer { width: 100vw; }
  .toolbar-actions { width: 100%; margin-left: 0; }
}

/* -----------------------------------------------------------------------------
   18. Phone
   --------------------------------------------------------------------------
   Two properties decide whether this console works on a phone.

   First, the layout viewport must never be fitted wider than the device. When any
   row is wider than the screen, Chrome widens the layout viewport to fit it and the
   whole console renders zoomed out — 439px and 576px were the measured results of a
   wide page head and a wide pagination bar, and every page inherited the smaller
   scale. The clamp is therefore applied on <html> in each page template at parse
   time, before any stylesheet arrives, and the real widths are fixed here too.

   Second, every control has to be tappable: 34px is a desktop height, and iOS zooms
   the page when a form control under 16px takes focus.
   -------------------------------------------------------------------------- */
@media (max-width: 900px) {
  /* A single row wider than the screen makes Chrome fit the layout viewport to it —
     439px and 576px were the measured results of a wide page head and a wide
     pagination bar — and the whole console then renders zoomed out. Content that is
     genuinely wider keeps its own scroll box (the matrices, the log detail, the
     config strip); the document itself never scrolls sideways on a phone. */
  html,
  body { overflow-x: hidden; }

  /* The head is a column here. The title block keeps min-width: max-content on
     desktop so a title never wraps mid-word; at phone width that same rule makes the
     page as wide as its longest unwrapped line. */
  .header-section {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-3);
  }

  .header-section > div:first-child,
  .page-head-text { min-width: 0; }

  .header-section h1,
  .page-title { white-space: normal; }

  .header-section p,
  .page-sub { max-width: none; }

  .page-actions {
    width: 100%;
    margin-left: 0;
  }

  /* Touch targets. 34px is a desktop height; a phone needs 44px in both axes.
     `button` is named as an element so page-specific buttons (the tutorial's channel
     picker, the Grok tool's density toggles) are covered too, and the class list
     carries the variants whose markup has no <button>: most templates write
     `class="btn-primary"` without the base `.btn`. A control that is a word inside a
     sentence keeps its line height — 44px there would break the sentence.

     !important is deliberate and scoped to this breakpoint. Each page stylesheet is
     linked after this one and sizes its own controls (`.imagine-basic-field
     .form-input`, `.alerts-checkbox`), so a global phone contract cannot win on
     specificity from here; the alternative is repeating the contract in five page
     stylesheets, which is how these drifts start. */
  button:not([class*='inline-link']),
  summary,
  [role='button'],
  .tut-toc a,
  select,
  input:not([type='checkbox']):not([type='radio']):not([type='hidden']),
  textarea,
  .form-input,
  .form-control,
  .compact-select,
  .btn,
  .btn-primary,
  .btn-secondary,
  .btn-outline,
  .btn-neutral,
  .btn-danger,
  .btn-danger-outline,
  .btn-save,
  .btn-page,
  .btn-icon,
  .icon-btn,
  .action-icon,
  .ops-refresh,
  .chip,
  .ops-chip,
  .tab-item,
  .logs-tab,
  .modal-close,
  .panel-close-btn,
  .filter-tabs .tab-item { min-height: 44px !important; }

  .ops-inline-link { min-height: 0 !important; }

  /* A link inside a sentence keeps its line height, but not an 18px target: padding
     on an inline element grows the hit area without moving the text around it. */
  .ops-inline-link { padding: 10px 2px; }

  /* A checkbox at 34px looks broken; 24px is the compromise every mobile console
     makes, and the label beside it stays a tap target. */
  input[type='checkbox'],
  input[type='radio'],
  .row-checkbox,
  .alerts-checkbox { width: 24px; height: 24px; }

  .page-actions > button,
  .page-actions > .btn,
  .page-actions > [class*='btn-'] { flex: 1 1 auto; }

  .panel-close-btn,
  .modal-close,
  .btn-icon,
  .icon-btn,
  .action-icon,
  .ops-refresh { min-width: 44px; }

  .mobile-menu-btn { width: 44px; height: 44px; padding: 13px; }
  .sidebar-link { min-height: 48px; padding: 0 var(--space-3); }
  .sidebar-item { margin-bottom: 2px; }

  /* The switch stays 38x22 — that is the design — but a thumb needs more. A tap a few
     pixels high used to hit the card and do nothing, which reads as an unresponsive
     switch. The pseudo-element belongs to the label, so a tap on it still toggles the
     checkbox, and it is invisible. */
  label.toggle::after {
    content: "";
    position: absolute;
    inset: -10px -6px;
  }

  /* iOS zooms the page when a control under 16px takes focus. Same reason for the
     !important as above: the page stylesheets size their own inputs. */
  input,
  select,
  textarea,
  .form-input,
  .form-control { font-size: 16px !important; }

  /* Sheets read better than centred dialogs on a phone. */
  .modal {
    align-items: flex-end;
    padding: 0;
  }

  .modal-content {
    max-height: 92vh;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  }

  .modal-actions > .btn { flex: 1 1 auto; }

  .drawer {
    width: 100vw;
    padding-bottom: env(safe-area-inset-bottom);
  }

  /* The detail panel covers the list on a phone: the page must not scroll behind it. */
  body.drawer-open { overflow: hidden; }

  .drawer-head { padding: var(--space-4); }
  .drawer-body { padding: var(--space-4); }

  .toast-container {
    top: auto;
    left: var(--space-4);
    right: var(--space-4);
    bottom: calc(var(--space-4) + env(safe-area-inset-bottom));
  }

  .toast { max-width: none; }

  /* The top bar owns the notch; the content starts below it. */
  .mobile-topbar {
    height: calc(56px + env(safe-area-inset-top));
    padding-top: env(safe-area-inset-top);
  }

  .main-content {
    padding-top: calc(72px + env(safe-area-inset-top));
    padding-bottom: calc(var(--space-8) + env(safe-area-inset-bottom));
  }
}

@media (max-width: 640px) {
  /* Five page buttons and a page-size select do not fit one line: they were the
     439px row that zoomed the accounts page out. */
  .pagination-shell {
    flex-direction: column;
    align-items: stretch;
  }

  .pagination-shell .inline-actions {
    flex-direction: column;
    align-items: stretch;
  }

  .pagination-controls {
    flex-wrap: wrap;
    justify-content: space-between;
  }

  .pagination-info { text-align: center; }

  .table-actions,
  .inline-actions { flex-wrap: wrap; }

  .filters,
  .toolbar-filters { flex-direction: column; align-items: stretch; }

  .filters > *,
  .toolbar-filters > * { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
