:root {
  --bg: #061018;
  --bg-2: #0d1724;
  --panel: #0f1827cc;
  --panel-solid: #121d2d;
  --line: #293a54;
  --text: #ebf1f6;
  --muted: #93a5bd;
  --teal: #77c9cb;
  --amber: #9ca9bb;
  --cyan: #7ab4dd;
  --danger: #ff88a3;
  --shadow: rgba(2, 9, 19, 0.38);
  --surface-strong: rgba(8, 15, 26, 0.98);
  --surface-soft: rgba(9, 17, 29, 0.92);
  --surface-elevated: rgba(12, 21, 33, 0.82);
  --surface-sidebar: rgba(6, 12, 20, 0.98);
  --surface-border: rgba(48, 66, 92, 0.34);
  --surface-border-strong: rgba(41, 56, 80, 0.5);
  --surface-hover: rgba(19, 31, 47, 0.88);
  --surface-active: rgba(29, 46, 68, 0.9);
  --panel-shadow: 0 30px 90px rgba(0, 0, 0, 0.42);
  --terminal-bg: #08101a;
  --terminal-text: #8ed0d9;
  --command-bg: rgba(10, 19, 32, 0.92);
  --theme-font: "IBM Plex Mono", "JetBrains Mono", "SFMono-Regular", Menlo, Consolas, monospace;
  /* Status hues for pills and badges. Kept apart from --teal/--amber/--danger
     because several themes use those as decoration (the default --amber is a
     grey); a light theme overrides these three so a pill stays readable. */
  --ok: #8cf5ce;
  --warn: #f8d27d;
  --bad: #ff9ca0;

  /* Brand marks. Deliberately NOT redefined per theme: a logo that changes
     colour with the UI theme is not a logo. Pillar 05 R2 still applies —
     these are the only place these two values appear. */
  --brand-d: #b98cff;
  --brand-l: #f057a3;
}

body[data-theme="matte"] {
  --bg: #111418;
  --bg-2: #181c21;
  --panel: #1b2028d9;
  --panel-solid: #212834;
  --line: #556376;
  --text: #f0f5ff;
  --muted: #b4c2d7;
  --teal: #74e6c4;
  --amber: #e8be7c;
  --cyan: #89d5ff;
  --danger: #ff92aa;
  --surface-strong: rgba(20, 25, 32, 0.98);
  --surface-soft: rgba(28, 34, 42, 0.95);
  --surface-elevated: rgba(36, 44, 56, 0.9);
  --surface-sidebar: rgba(20, 25, 32, 0.98);
  --surface-border: rgba(85, 99, 118, 0.42);
  --surface-border-strong: rgba(85, 99, 118, 0.58);
  --surface-hover: rgba(38, 46, 58, 0.92);
  --surface-active: rgba(58, 70, 86, 0.98);
  --terminal-bg: #171c22;
  --terminal-text: #d7f4e9;
  --command-bg: rgba(24, 30, 40, 0.96);
}

body[data-theme="retro"] {
  --bg: #1d1511;
  --bg-2: #2b2018;
  --panel: #2a1e16d8;
  --panel-solid: #332418;
  --line: #8d6641;
  --text: #ffebcc;
  --muted: #e5c89f;
  --teal: #a3ff79;
  --amber: #ffd06f;
  --cyan: #89ebd4;
  --danger: #ff9f86;
  --surface-strong: rgba(35, 24, 17, 0.98);
  --surface-soft: rgba(42, 30, 22, 0.94);
  --surface-elevated: rgba(51, 36, 24, 0.9);
  --surface-sidebar: rgba(31, 22, 16, 0.98);
  --surface-border: rgba(141, 102, 65, 0.45);
  --surface-border-strong: rgba(141, 102, 65, 0.62);
  --surface-hover: rgba(58, 40, 27, 0.92);
  --surface-active: rgba(73, 51, 34, 0.98);
  --terminal-bg: #1f1712;
  --terminal-text: #c8ff93;
  --command-bg: rgba(49, 34, 22, 0.95);
}

body[data-theme="classic"] {
  --bg: #081329;
  --bg-2: #11264d;
  --panel: #0f1f3fd1;
  --panel-solid: #152a54;
  --line: #3f6299;
  --text: #eff6ff;
  --muted: #b9cdf0;
  --teal: #8bffb6;
  --amber: #ffd27e;
  --cyan: #86d8ff;
  --danger: #ffa4bb;
  --surface-strong: rgba(10, 22, 45, 0.98);
  --surface-soft: rgba(15, 31, 63, 0.94);
  --surface-elevated: rgba(21, 42, 84, 0.9);
  --surface-sidebar: rgba(8, 19, 41, 0.98);
  --surface-border: rgba(63, 98, 153, 0.45);
  --surface-border-strong: rgba(63, 98, 153, 0.6);
  --surface-hover: rgba(24, 47, 87, 0.94);
  --surface-active: rgba(33, 60, 108, 0.98);
  --terminal-bg: #0a1933;
  --terminal-text: #9ae6ff;
  --command-bg: rgba(12, 28, 54, 0.96);
}

body[data-theme="white"] {
  --bg: #f3f8ff;
  --bg-2: #e6eef9;
  --panel: rgba(255, 255, 255, 0.96);
  --panel-solid: #f7fbff;
  --line: #90a4bd;
  --text: #0f172a;
  --muted: #475569;
  --teal: #0f9d58;
  --amber: #9c6800;
  --cyan: #005f96;
  --danger: #b4232c;
  --surface-strong: rgba(255, 255, 255, 0.98);
  --surface-soft: rgba(255, 255, 255, 0.96);
  --surface-elevated: rgba(247, 251, 255, 0.98);
  --surface-sidebar: rgba(238, 245, 252, 0.98);
  --surface-border: rgba(144, 164, 189, 0.62);
  --surface-border-strong: rgba(144, 164, 189, 0.74);
  --surface-hover: rgba(233, 241, 250, 1);
  --surface-active: rgba(216, 231, 247, 1);
  --panel-shadow: 0 24px 60px rgba(148, 163, 184, 0.22);
  --terminal-bg: #edf4fb;
  --terminal-text: #005f96;
  --command-bg: rgba(248, 251, 255, 1);
  --ok: #0f7a45;
  --warn: #8a5a00;
  --bad: #b4232c;
}

/* ── Public Safety ─────────────────────────────────────────────────────────
   Night-shift dispatch floor: a dark, low-glare ground so a console left open
   for twelve hours does not light the room, high-contrast text, and status
   hues that mean what they mean on a CAD board — green available, amber
   caution, red emergency. The accent is unit blue. Mono stays: dispatch
   terminals are read in columns. */
body[data-theme="dispatch"] {
  --bg: #07090c;
  --bg-2: #0c1016;
  --panel: rgba(13, 17, 23, 0.96);
  --panel-solid: #0d1117;
  --line: #2b3542;
  --text: #f1f5f9;
  --muted: #9aa8b8;
  --teal: #4ade80;
  --amber: #fbbf24;
  --cyan: #60a5fa;
  --danger: #f87171;
  --surface-strong: rgba(9, 12, 16, 0.98);
  --surface-soft: rgba(13, 17, 23, 0.96);
  --surface-elevated: rgba(19, 25, 33, 0.96);
  --surface-sidebar: rgba(7, 9, 12, 0.98);
  --surface-border: rgba(148, 163, 184, 0.16);
  --surface-border-strong: rgba(148, 163, 184, 0.28);
  --surface-hover: rgba(96, 165, 250, 0.08);
  --surface-active: rgba(96, 165, 250, 0.16);
  --panel-shadow: 0 24px 70px rgba(0, 0, 0, 0.6);
  --terminal-bg: #05070a;
  --terminal-text: #86efac;
  --command-bg: rgba(7, 9, 12, 0.98);
  --ok: #4ade80;
  --warn: #fbbf24;
  --bad: #f87171;
}

/* ── Versaterm ──────────────────────────────────────────────────────────────
   Taken from versaterm.com's own stylesheet (2026-10-02): turquoise #00505D
   for headings and primary actions, ocean #073350 into turquoise for banners,
   orange #E76E25 for uppercase category labels, light blue #7BC3D0, on white.
   Their faces (Articulat, Publico) are licensed webfonts and this server's CSP
   allows no font CDN, so this uses the fallback stack their CSS names itself.
   No logo or wordmark of theirs is used — colour and type only. Orange is
   darkened to #B4531A for text, because #E76E25 on white is 3.1:1. */
body[data-theme="versaterm"] {
  --bg: #f3f6f7;
  --bg-2: #e6eef0;
  --panel: rgba(255, 255, 255, 0.98);
  --panel-solid: #ffffff;
  --line: #b9cbd0;
  --text: #0b2a33;
  --muted: #4a6670;
  --teal: #00505d;
  --amber: #b4531a;
  --cyan: #b4531a;
  --danger: #b4232c;
  --surface-strong: rgba(255, 255, 255, 0.99);
  --surface-soft: rgba(255, 255, 255, 0.98);
  --surface-elevated: rgba(247, 250, 251, 0.99);
  --surface-sidebar: rgba(236, 243, 245, 0.99);
  --surface-border: rgba(0, 80, 93, 0.16);
  --surface-border-strong: rgba(0, 80, 93, 0.28);
  --surface-hover: rgba(0, 80, 93, 0.06);
  --surface-active: rgba(0, 80, 93, 0.12);
  --panel-shadow: 0 18px 50px rgba(7, 51, 80, 0.12);
  --terminal-bg: #eef4f5;
  --terminal-text: #00505d;
  --command-bg: rgba(243, 247, 248, 1);
  --theme-font: "Helvetica Neue", Helvetica, Arial, sans-serif;
  --ok: #0f7a45;
  --warn: #8a5a00;
  --bad: #b4232c;
}

body[data-theme="win95"] {
  --bg: #008080;
  --bg-2: #1e6c6c;
  --panel: rgba(192, 192, 192, 0.98);
  --panel-solid: #c0c0c0;
  --line: #808080;
  --text: #111827;
  --muted: #374151;
  --teal: #004f4f;
  --amber: #6b7280;
  --cyan: #0f172a;
  --danger: #7f1d1d;
  --surface-strong: rgba(192, 192, 192, 0.98);
  --surface-soft: rgba(212, 212, 212, 0.98);
  --surface-elevated: rgba(234, 234, 234, 1);
  --surface-sidebar: rgba(176, 176, 176, 0.98);
  --surface-border: rgba(96, 96, 96, 0.9);
  --surface-border-strong: rgba(80, 80, 80, 1);
  --surface-hover: rgba(220, 220, 220, 1);
  --surface-active: rgba(160, 160, 160, 1);
  --panel-shadow: 6px 6px 0 rgba(20, 20, 20, 0.35);
  --terminal-bg: #000000;
  --terminal-text: #00ff9c;
  --command-bg: rgba(242, 242, 242, 1);
  --theme-font: "MS Sans Serif", "Chicago", "IBM Plex Mono", monospace;
}

body[data-theme="win95"] {
  background:
    linear-gradient(180deg, #008080 0%, #0a6c6c 100%) !important;
  color: #000 !important;
}

body[data-theme="win95"]::before,
body[data-theme="win95"]::after {
  display: none !important;
}

body[data-theme="win95"] .panel,
body[data-theme="win95"] .story-card,
body[data-theme="win95"] .feature-marquee,
body[data-theme="win95"] .cta-band,
body[data-theme="win95"] .about-band,
body[data-theme="win95"] .vector-metric,
body[data-theme="win95"] .hero-card,
body[data-theme="win95"] .about-card,
body[data-theme="win95"] .terminal,
body[data-theme="win95"] .status,
body[data-theme="win95"] .auth-shell,
body[data-theme="win95"] .auth-signin-card,
body[data-theme="win95"] .theme-picker,
body[data-theme="win95"] .landing-themebar,
body[data-theme="win95"] .landing-btn,
body[data-theme="win95"] .proof-rail span,
body[data-theme="win95"] .signal-wall__hero,
body[data-theme="win95"] .signal-wall__proofs span,
body[data-theme="win95"] .frontdoor-terminal,
body[data-theme="win95"] .vector-map__hub {
  border-radius: 0 !important;
  border-top: 2px solid #fff !important;
  border-left: 2px solid #fff !important;
  border-right: 2px solid #808080 !important;
  border-bottom: 2px solid #808080 !important;
  box-shadow: none !important;
}

body[data-theme="win95"] .panel,
body[data-theme="win95"] .story-card,
body[data-theme="win95"] .feature-marquee,
body[data-theme="win95"] .cta-band,
body[data-theme="win95"] .about-band,
body[data-theme="win95"] .vector-metric,
body[data-theme="win95"] .hero-card,
body[data-theme="win95"] .about-card,
body[data-theme="win95"] .terminal,
body[data-theme="win95"] .status,
body[data-theme="win95"] .auth-shell,
body[data-theme="win95"] .auth-signin-card,
body[data-theme="win95"] .theme-picker,
body[data-theme="win95"] .landing-themebar,
body[data-theme="win95"] .signal-wall__hero,
body[data-theme="win95"] .frontdoor-terminal {
  background: #c0c0c0 !important;
}

body[data-theme="win95"] .landing-brand__muted,
body[data-theme="win95"] .landing-nav__links a,
body[data-theme="win95"] .hero__eyebrow,
body[data-theme="win95"] .hero__lede,
body[data-theme="win95"] .vector-map__label,
body[data-theme="win95"] .vector-map__status,
body[data-theme="win95"] .vector-metric span,
body[data-theme="win95"] .about-card p,
body[data-theme="win95"] .story-card p,
body[data-theme="win95"] .feature-marquee__text,
body[data-theme="win95"] .auth__hint,
body[data-theme="win95"] .auth__tagline,
body[data-theme="win95"] .auth-help-text,
body[data-theme="win95"] .auth__subnote,
body[data-theme="win95"] .proof-rail span,
body[data-theme="win95"] .signal-wall__answer,
body[data-theme="win95"] .frontdoor-terminal__line--result,
body[data-theme="win95"] .signal-wall__proofs span {
  color: #333 !important;
}

body[data-theme="win95"] .landing-brand__bright,
body[data-theme="win95"] .hero__title,
body[data-theme="win95"] .story-card h2,
body[data-theme="win95"] .feature-marquee h2,
body[data-theme="win95"] .cta-band h2,
body[data-theme="win95"] .about-band h2,
body[data-theme="win95"] .about-card h3,
body[data-theme="win95"] .auth__title,
body[data-theme="win95"] .auth__title--signin,
body[data-theme="win95"] .vector-map__hub strong,
body[data-theme="win95"] .signal-wall__question {
  color: #000080 !important;
  -webkit-text-fill-color: #000080 !important;
}

body[data-theme="win95"] .landing-btn,
body[data-theme="win95"] .landing-nav__links a,
body[data-theme="win95"] .theme-picker select,
body[data-theme="win95"] .auth-provider-tile,
body[data-theme="win95"] .auth-provider-button,
body[data-theme="win95"] .auth-input,
body[data-theme="win95"] .auth-channel-chip,
body[data-theme="win95"] .auth-channel-chip--logo {
  border-radius: 0 !important;
  background: #c0c0c0 !important;
  color: #000 !important;
  border-top: 2px solid #fff !important;
  border-left: 2px solid #fff !important;
  border-right: 2px solid #808080 !important;
  border-bottom: 2px solid #808080 !important;
}

body[data-theme="win95"] .landing-btn:hover,
body[data-theme="win95"] .landing-nav__links a:hover,
body[data-theme="win95"] .auth-provider-button:hover,
body[data-theme="win95"] .auth-provider-tile:hover {
  background: #000080 !important;
  color: #fff !important;
  -webkit-text-fill-color: #fff !important;
}

body[data-theme="win95"] .auth-signin-card,
body[data-theme="win95"] .auth-shell {
  background: #c0c0c0 !important;
}

body[data-theme="win95"] .frontdoor-terminal__head,
body[data-theme="win95"] .signal-wall__hero-top,
body[data-theme="win95"] .chrome__title {
  color: #000080 !important;
}

body[data-theme="win95"] .frontdoor-terminal__status span {
  background: #000080 !important;
  color: #fff !important;
}

body[data-theme="neon"] {
  --bg: #07001a;
  --bg-2: #130028;
  --panel: rgba(20, 0, 50, 0.82);
  --panel-solid: #140032;
  --line: rgba(255, 0, 200, 0.22);
  --text: #f0e6ff;
  --muted: #9b59f7;
  --teal: #00f5ff;
  --amber: #ff2dc8;
  --cyan: #7c3aed;
  --danger: #ff7eb6;
  --surface-strong: rgba(7, 0, 26, 0.98);
  --surface-soft: rgba(20, 0, 50, 0.92);
  --surface-elevated: rgba(24, 0, 58, 0.92);
  --surface-sidebar: rgba(7, 0, 26, 0.98);
  --surface-border: rgba(255, 0, 200, 0.22);
  --surface-border-strong: rgba(255, 0, 200, 0.42);
  --surface-hover: rgba(255, 45, 200, 0.08);
  --surface-active: rgba(0, 245, 255, 0.1);
  --panel-shadow: 0 30px 90px rgba(0, 0, 0, 0.5);
  --terminal-bg: #0a001f;
  --terminal-text: #00f5ff;
  --command-bg: rgba(10, 0, 31, 0.96);
}

body[data-theme="steel"] {
  --bg: #0c0c0e;
  --bg-2: #111114;
  --panel: rgba(18, 18, 20, 0.95);
  --panel-solid: #121214;
  --line: rgba(255, 255, 255, 0.08);
  --text: #d4d4d8;
  --muted: #71717a;
  --teal: #e4e4e7;
  --amber: #a1a1aa;
  --cyan: #f4f4f5;
  --danger: #fda4af;
  --surface-strong: rgba(10, 10, 12, 0.98);
  --surface-soft: rgba(18, 18, 20, 0.96);
  --surface-elevated: rgba(22, 22, 24, 0.96);
  --surface-sidebar: rgba(10, 10, 12, 0.98);
  --surface-border: rgba(255, 255, 255, 0.08);
  --surface-border-strong: rgba(255, 255, 255, 0.18);
  --surface-hover: rgba(255, 255, 255, 0.04);
  --surface-active: rgba(255, 255, 255, 0.06);
  --panel-shadow: 0 30px 90px rgba(0, 0, 0, 0.55);
  --terminal-bg: #101012;
  --terminal-text: #f4f4f5;
  --command-bg: rgba(12, 12, 14, 0.98);
}

body[data-theme="abyss"] {
  --bg: #04000e;
  --bg-2: #10021f;
  --panel: rgba(8, 2, 22, 0.88);
  --panel-solid: #080216;
  --line: rgba(139, 92, 246, 0.14);
  --text: #ddd6fe;
  --muted: #8b5cf6;
  --teal: #c4b5fd;
  --amber: #f0abfc;
  --cyan: #a78bfa;
  --danger: #fb7185;
  --surface-strong: rgba(4, 0, 14, 0.98);
  --surface-soft: rgba(8, 2, 22, 0.92);
  --surface-elevated: rgba(18, 6, 34, 0.92);
  --surface-sidebar: rgba(4, 0, 14, 0.98);
  --surface-border: rgba(139, 92, 246, 0.14);
  --surface-border-strong: rgba(167, 139, 250, 0.28);
  --surface-hover: rgba(109, 40, 217, 0.08);
  --surface-active: rgba(190, 24, 93, 0.1);
  --panel-shadow: 0 30px 90px rgba(0, 0, 0, 0.62);
  --terminal-bg: #070014;
  --terminal-text: #c4b5fd;
  --command-bg: rgba(8, 2, 22, 0.96);
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  min-height: 100vh;
  color: var(--text);
  background:
    radial-gradient(1200px 700px at 5% -20%, #18304d 0%, transparent 60%),
    radial-gradient(1000px 500px at 100% 0%, #1d4352 0%, transparent 65%),
    linear-gradient(160deg, var(--bg) 0%, var(--bg-2) 100%);
  font-family: var(--theme-font);
  overflow-x: hidden;
}

.landing-body {
  background:
    radial-gradient(820px 520px at 8% 8%, rgba(76, 144, 172, 0.16) 0%, transparent 58%),
    radial-gradient(760px 440px at 92% 8%, rgba(124, 144, 170, 0.12) 0%, transparent 55%),
    linear-gradient(180deg, #08121b 0%, #0f1b28 54%, #131d28 100%);
}

.login-body {
  background:
    radial-gradient(520px 420px at 12% 28%, rgba(73, 78, 180, 0.12) 0%, transparent 70%),
    radial-gradient(520px 420px at 88% 74%, rgba(84, 97, 186, 0.1) 0%, transparent 70%),
    linear-gradient(180deg, #080f1a 0%, #0b1220 100%);
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  background-image: linear-gradient(rgba(255, 255, 255, 0.025) 1px, transparent 1px);
  background-size: 100% 3px;
  opacity: 0.24;
  mix-blend-mode: soft-light;
}

body[data-theme="steel"] {
  background-image:
    repeating-linear-gradient(-15deg, transparent 0px, transparent 3px, rgba(255,255,255,0.012) 3px, rgba(255,255,255,0.012) 4px),
    linear-gradient(180deg, var(--bg) 0%, var(--bg-2) 100%);
}

body[data-theme="abyss"]::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 65% 45% at 15% 25%, rgba(109,40,217,0.18) 0%, transparent 65%),
    radial-gradient(ellipse 55% 65% at 85% 75%, rgba(219,39,119,0.1) 0%, transparent 60%),
    radial-gradient(ellipse 45% 45% at 55% 50%, rgba(76,29,149,0.1) 0%, transparent 70%);
  opacity: .85;
  z-index: 0;
}

.landing {
  width: min(1680px, calc(100vw - 36px));
  margin: 0 auto;
  padding: 4px 0;
}

.landing--about {
  min-height: calc(100vh - 4px);
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  overflow: hidden;
  padding-bottom: 4px;
}

.landing--frontdoor {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  padding-top: 28px;
  padding-bottom: 64px;
}

.landing-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 4px;
}

.landing-nav--compact {
  margin-bottom: 56px;
}

.landing-brand {
  text-decoration: none;
  font-size: 23px;
  font-weight: 700;
  letter-spacing: -0.04em;
  display: inline-flex;
  align-items: center;
  /* No flex `gap` here: gap applies between EVERY child, so it would also
     split the wordmark's own pieces apart. The mark is spaced with a margin
     instead, which affects only the mark. */
}

.landing-brand > .brand-mark {
  /* Larger than the shared 28px: the tile carries the whole mark — eight
     strands and the light along them — against a wordmark of 23px type, and
     at 28px it read as an afterthought beside the word rather than as its
     equal. */
  width: 36px;
  height: 36px;
  margin-right: 11px;
}

.landing-brand__muted {
  color: var(--muted);
}

.landing-brand__bright {
  background: linear-gradient(135deg, #dbe4f1 0%, #78c0d1 56%, #96a4bb 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.brand-mark {
  width: 28px;
  height: 28px;
  flex: 0 0 auto;
}

.brand-mark--large {
  width: 34px;
  height: 34px;
}

.brand-mark--pulse {
  animation: brandPulse 4s ease-in-out infinite;
}

@keyframes brandPulse {
  0%, 100% {
    opacity: 0.74;
    transform: scale(1);
    filter: drop-shadow(0 0 0 rgba(108, 176, 214, 0));
  }
  50% {
    opacity: 1;
    transform: scale(1.05);
    filter: drop-shadow(0 0 22px rgba(108, 176, 214, 0.34));
  }
}

.landing-nav__links,
.landing-nav__actions,
.hero__actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

.hero__actions {
  gap: 14px;
  margin-top: 36px;
}

.landing-nav__actions {
  gap: 10px;
}

.landing-themebar {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 11px;
  border-radius: 999px;
  border: 1px solid rgba(178, 191, 208, 0.18);
  background: rgba(8, 15, 25, 0.54);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

.landing-themebar__swatch {
  width: 18px;
  height: 18px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform 140ms ease, box-shadow 140ms ease;
}

.landing-themebar__swatch span {
  width: 12px;
  height: 12px;
  border-radius: 999px;
  display: block;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.28),
    0 0 0 1px rgba(255, 255, 255, 0.06);
}

.landing-themebar__swatch:hover,
.landing-themebar__swatch:focus-visible {
  transform: translateY(-1px) scale(1.08);
  outline: 0;
}

.landing-themebar__swatch.is-active {
  box-shadow: 0 0 0 2px rgba(125, 183, 216, 0.24);
}

.landing-nav__links a,
.landing-link {
  color: var(--muted);
  text-decoration: none;
  font-size: 13px;
}

.landing-link:hover,
.landing-nav__links a:hover,
.status__link:hover {
  color: var(--text);
}

.landing-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0 24px;
  border-radius: 999px;
  text-decoration: none;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: #0a1723;
  background: linear-gradient(135deg, #d8e2ee 0%, #7db7d8 56%, #92a3bb 100%);
  box-shadow: 0 14px 40px rgba(41, 77, 107, 0.22);
}

.theme-picker {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 0 12px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--line) 80%, #ffffff 20%);
  background: linear-gradient(180deg, var(--panel), var(--panel-solid));
  color: var(--muted);
}

.theme-picker span {
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.theme-picker select {
  border: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  outline: 0;
}

body[data-theme="white"] .theme-picker select,
body[data-theme="win95"] .theme-picker select {
  color: var(--text);
}

.auth-skinbar {
  display: flex;
  justify-content: center;
  margin-bottom: 10px;
}

.auth-skinbar__swatches {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--line) 80%, #ffffff 20%);
  background: linear-gradient(180deg, var(--panel), var(--panel-solid));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

.auth-skinbar__swatch {
  width: 18px;
  height: 18px;
  padding: 0;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: transparent;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform 140ms ease, box-shadow 140ms ease, border-color 140ms ease;
}

.auth-skinbar__swatch span {
  width: 12px;
  height: 12px;
  border-radius: 999px;
  display: block;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35);
}

.auth-skinbar__swatch:hover,
.auth-skinbar__swatch:focus-visible {
  transform: translateY(-1px) scale(1.08);
  border-color: rgba(255, 255, 255, 0.42);
  box-shadow: 0 0 0 3px rgba(125, 183, 216, 0.12);
  outline: 0;
}

.auth-skinbar__swatch.is-active {
  border-color: color-mix(in srgb, var(--cyan) 68%, white 32%);
  box-shadow: 0 0 0 3px rgba(125, 183, 216, 0.18);
}

body[data-theme="white"] .auth-skinbar__swatch,
body[data-theme="win95"] .auth-skinbar__swatch {
  border-color: rgba(15, 23, 42, 0.16);
}

.landing-btn--ghost {
  color: var(--text);
  background: rgba(10, 22, 37, 0.44);
  border: 1px solid rgba(168, 185, 204, 0.26);
  box-shadow: none;
}

.hero {
  display: grid;
  grid-template-columns: minmax(560px, 1.18fr) minmax(440px, 0.82fr);
  gap: 64px;
  align-items: start;
  padding: 0;
}

.hero--marketing {
  min-height: calc(100vh - 70px);
}

.hero--frontdoor {
  align-items: start;
  margin-bottom: 0;
  padding: 0;
}

.hero__copy--frontdoor {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0;
  max-width: 980px;
}

.hero__eyebrow,
.story-card__eyebrow {
  margin: 0 0 18px;
  color: #8ec9d7;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-size: 11px;
}

.hero-brandlockup {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  margin: 0 0 14px;
  padding: 6px 0;
}

.hero-brandlockup__mark {
  width: 58px;
  height: 58px;
  filter: drop-shadow(0 16px 34px rgba(49, 77, 116, 0.2));
}

.hero-brandlockup__text {
  font-size: 36px;
  line-height: 1;
  letter-spacing: -0.05em;
}

.hero-brandlockup__text span {
  color: var(--muted);
}

.hero-brandlockup__text strong {
  color: var(--text);
}

.hero__title {
  margin: 0;
  font-size: clamp(52px, 5.2vw, 104px);
  line-height: 0.98;
  letter-spacing: -0.05em;
  max-width: 8.2ch;
}

.hero__title--serif,
.auth__title {
  font-family: "Iowan Old Style", "Palatino Linotype", "Book Antiqua", Georgia, serif;
  font-weight: 700;
}

.hero__title span {
  color: var(--muted);
}

.hero__title--wide {
  max-width: 8.7ch;
}

.hero__title--about {
  max-width: 9.2ch;
}

.hero__lede {
  margin: 12px 0 14px;
  max-width: 720px;
  color: var(--text);
  font-size: 20px;
  line-height: 1.85;
}

.hero__lede--tight {
  max-width: 56ch;
  margin: 20px 0 0;
  font-size: 18px;
  line-height: 1.6;
}

.hero__microproof {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 16px;
}

.hero__microproof span {
  color: var(--muted);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  opacity: 0.9;
}

.hero__trustbar,
.feature-marquee__list,
.pill-list,
.tag-list,
.action-grid,
.org-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.hero__trustbar {
  margin-top: 14px;
}

.hero__trustbar span,
.feature-chip,
.pill,
.tag-list__item,
.org-switch {
  border-radius: 999px;
  /* A pill is one label. The list above already wraps BETWEEN pills, so
     breaking inside one only ever produces a word split across two lines
     ("NO RANCHE / R"), which reads as a rendering fault rather than a value.

     nowrap alone was not enough. In a flex row the pill was being SHRUNK, and
     with nowrap its text then spilled past its own box and was clipped by the
     card ("OVER-SCO…"). flex-shrink: 0 stops the squeeze: a status label is
     the one thing in the row that must stay whole, and the prose beside it is
     what should give way. Caught in a cropped screenshot — the pill's layout
     box measured as inside the card, so only looking at it revealed the
     overflow. */
  white-space: nowrap;
  flex-shrink: 0;
  padding: 10px 14px;
  color: var(--text);
  border: 1px solid var(--surface-border-strong);
  background: color-mix(in srgb, var(--panel-solid) 32%, transparent);
  font-size: 11px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  /* font-family, not the `font` shorthand: `font: inherit` here reset the
     font-size above back to the parent's, so every pill rendered at 16px. */
  font-family: inherit;
}

.proof-rail {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 28px;
  max-width: 760px;
}

.proof-rail span {
  border-radius: 999px;
  padding: 9px 14px;
  color: var(--text);
  border: 1px solid rgba(199, 213, 229, 0.18);
  background: color-mix(in srgb, var(--panel-solid) 34%, transparent);
  font-size: 11px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.hero__audiences {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 24px;
  max-width: 720px;
}

.hero__audiences span {
  padding: 8px 13px;
  border-radius: 999px;
  border: 1px solid rgba(199, 213, 229, 0.16);
  background: rgba(10, 19, 31, 0.26);
  color: var(--muted);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.signal-wall {
  display: grid;
  grid-template-rows: auto auto auto;
  gap: 18px;
  padding: 24px;
  border-radius: 24px;
  border: 1px solid rgba(204, 214, 224, 0.16);
  background:
    radial-gradient(360px 220px at 65% 10%, rgba(110, 187, 206, 0.16), transparent 68%),
    linear-gradient(180deg, rgba(8, 14, 22, 0.9), rgba(14, 26, 39, 0.97));
  box-shadow: 0 32px 90px var(--shadow);
  position: relative;
  overflow: hidden;
  min-height: 0;
  height: auto;
  align-content: start;
  align-self: start;
  width: min(100%, 760px);
}

.signal-wall::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(90deg, rgba(255,255,255,0.028) 1px, transparent 1px),
    linear-gradient(rgba(255,255,255,0.024) 1px, transparent 1px);
  background-size: 72px 72px;
  opacity: 0.18;
  mask-image: radial-gradient(circle at 68% 14%, black 0%, black 48%, transparent 88%);
}

.signal-wall__hero {
  padding: 22px 24px;
  border-radius: 18px;
  border: 1px solid rgba(179, 193, 207, 0.12);
  background: rgba(7, 13, 22, 0.42);
}

.signal-wall__hero-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}

.signal-wall__label,
.signal-card__eyebrow {
  color: var(--muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.11em;
}

.signal-wall__status {
  border-radius: 999px;
  padding: 7px 10px;
  border: 1px solid rgba(136, 203, 158, 0.26);
  background: rgba(36, 99, 58, 0.22);
  color: var(--text);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.signal-wall__question {
  font-size: clamp(24px, 2vw, 36px);
  line-height: 1.08;
  letter-spacing: -0.03em;
  color: var(--text);
  max-width: 9ch;
  margin-bottom: 10px;
}

.signal-wall__answer {
  color: var(--muted);
  font-size: 14px;
  line-height: 1.5;
  max-width: 30ch;
}

.signal-wall__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
  position: relative;
  z-index: 1;
}

.signal-wall__grid--compact .signal-card {
  min-height: 96px;
}

.signal-wall__grid--compact {
  margin-top: 0;
}

.signal-card {
  min-height: 0;
  padding: 20px;
  border-radius: 20px;
  border: 1px solid rgba(184, 197, 214, 0.14);
  background: linear-gradient(180deg, rgba(11, 19, 30, 0.82), rgba(10, 17, 27, 0.94));
}

.signal-card strong {
  display: block;
  margin: 6px 0 6px;
  font-size: 18px;
  line-height: 1.15;
  letter-spacing: -0.03em;
  color: var(--text);
}

.signal-card p {
  margin: 0;
  color: var(--muted);
  font-size: 12.5px;
  line-height: 1.45;
}

.frontdoor-terminal {
  min-height: 112px;
  padding: 20px 22px;
  border-radius: 18px;
  border: 1px solid rgba(184, 197, 214, 0.14);
  background:
    radial-gradient(240px 120px at 78% 12%, rgba(110, 187, 206, 0.12), transparent 72%),
    linear-gradient(180deg, rgba(8, 14, 22, 0.88), rgba(10, 18, 29, 0.96));
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.frontdoor-terminal__status span:last-child {
  color: var(--text);
}

.frontdoor-terminal__header,
.frontdoor-terminal__status {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.frontdoor-terminal__header span,
.frontdoor-terminal__status span {
  color: var(--muted);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.11em;
}

.frontdoor-terminal__line {
  color: var(--text);
  font-size: 13px;
  line-height: 1.26;
}

.frontdoor-terminal__line--prompt {
  color: var(--text);
}

.frontdoor-terminal__line--result {
  color: var(--muted);
}

.frontdoor-terminal__cursor {
  display: inline-block;
  width: 10px;
  height: 20px;
  margin-left: 5px;
  border-radius: 2px;
  background: #7cd4d7;
  vertical-align: -3px;
  animation: frontdoorCursorBlink 1.05s steps(1) infinite;
}

@keyframes frontdoorCursorBlink {
  0%, 46% {
    opacity: 1;
  }

  47%, 100% {
    opacity: 0;
  }
}

.signal-wall__proofs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 18px;
  padding: 4px 4px 0;
  position: relative;
  z-index: 1;
}

.signal-wall__proofs span {
  color: var(--muted);
  font-size: 11px;
  letter-spacing: 0.04em;
  line-height: 1.4;
}

.signal-flow {
  display: none;
}

.signal-flow span {
  color: var(--muted);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  opacity: 0.92;
  animation: signalFlowPulse 4.4s ease-in-out infinite;
}

.signal-flow span:nth-child(2) { animation-delay: .16s; }
.signal-flow span:nth-child(3) { animation-delay: .32s; }
.signal-flow span:nth-child(4) { animation-delay: .48s; }
.signal-flow span:nth-child(5) { animation-delay: .64s; }
.signal-flow span:nth-child(6) { animation-delay: .8s; }

@keyframes signalFlowPulse {
  0%, 100% {
    opacity: 0.46;
    transform: translateY(0);
  }
  50% {
    opacity: 1;
    transform: translateY(-1px);
  }
}

.about-surface {
  display: grid;
  gap: 10px;
  min-height: calc(100vh - 64px);
  align-content: center;
}

.about-hero {
  display: grid;
  grid-template-columns: minmax(720px, 1.14fr) minmax(460px, 0.86fr);
  gap: 10px;
  align-items: center;
  padding: 0;
}

.about-hero__copy {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.hero__title--about {
  max-width: 8.2ch;
}

.hero__lede--about {
  max-width: 24ch;
  margin: 8px 0 0;
  font-size: 15px;
  line-height: 1.32;
}

.about-signal {
  padding: 14px 16px;
  border-radius: 20px;
  border: 1px solid rgba(191, 204, 220, 0.16);
  background:
    radial-gradient(220px 140px at 72% 8%, rgba(110, 187, 206, 0.12), transparent 75%),
    linear-gradient(180deg, rgba(10, 18, 30, 0.78), rgba(9, 16, 26, 0.95));
  box-shadow: 0 18px 44px rgba(4, 9, 17, 0.28);
}

.about-signal__header,
.cta-band {
  display: flex;
  justify-content: space-between;
  gap: 12px;
}

.about-signal__header {
  align-items: center;
  margin-bottom: 8px;
  color: var(--muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.11em;
}

.about-signal__prompt {
  color: var(--text);
  font-size: 16px;
  line-height: 1.35;
  margin-bottom: 8px;
}

.about-signal__line {
  color: var(--muted);
  font-size: 14px;
  line-height: 1.35;
  margin-top: 6px;
}

.about-story-grid,
.about-pillars {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
}

.about-story-grid {
  margin: 0;
}

.about-story-grid--tight .about-card--elevated,
.about-pillars--tight .pillar-card {
  min-height: 100%;
}

.about-card--elevated,
.pillar-card {
  padding: 14px;
  border-radius: 18px;
  border: 1px solid rgba(191, 204, 220, 0.16);
  background: linear-gradient(180deg, rgba(10, 18, 30, 0.76), rgba(9, 16, 26, 0.94));
  box-shadow: 0 18px 44px rgba(4, 9, 17, 0.28);
}

.about-card--elevated h3,
.pillar-card h2 {
  margin-top: 0;
}

.pillar-card h2 {
  margin-bottom: 8px;
  font-size: 17px;
  line-height: 1.08;
  letter-spacing: -0.04em;
}

.pillar-card p,
.about-card--elevated p {
  margin-bottom: 0;
  color: var(--text);
  line-height: 1.3;
  font-size: 13px;
}

@media (max-width: 1500px) {
  .landing {
    width: min(1560px, calc(100vw - 28px));
  }

  .landing--about {
    min-height: calc(100vh - 8px);
  }

  .hero {
    grid-template-columns: minmax(520px, 1.14fr) minmax(420px, 0.86fr);
    gap: 40px;
  }

  .hero__copy--frontdoor {
    max-width: 900px;
  }

  .hero__title {
    font-size: clamp(46px, 5.1vw, 92px);
  }

  .signal-wall__question {
    font-size: clamp(22px, 2.2vw, 34px);
    max-width: 9ch;
  }

  .about-surface {
    min-height: calc(100vh - 68px);
    gap: 10px;
  }
}

@media (max-height: 860px) {
  .landing {
    width: min(1560px, calc(100vw - 28px));
  }

  .landing--about {
    min-height: calc(100vh - 8px);
    padding: 4px 0;
  }

  .about-surface {
    min-height: calc(100vh - 68px);
  }

  .hero {
    grid-template-columns: minmax(520px, 1.14fr) minmax(420px, 0.86fr);
  }
}

.hero__visual {
  display: flex;
  justify-content: center;
}

.vector-map {
  width: min(540px, 100%);
  border-radius: 32px;
  padding: 20px;
  border: 1px solid rgba(204, 214, 224, 0.18);
  background:
    radial-gradient(280px 140px at 50% 14%, rgba(110, 187, 206, 0.18), transparent 65%),
    linear-gradient(180deg, rgba(8, 14, 22, 0.88), rgba(14, 26, 39, 0.96));
  box-shadow: 0 32px 90px var(--shadow);
}

.vector-map__header,
.status__top,
.status__row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
}

.vector-map__header {
  align-items: center;
  margin-bottom: 16px;
}

.vector-map__brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
  padding: 10px 12px;
  border-radius: 16px;
  border: 1px solid rgba(179, 193, 207, 0.14);
  background: color-mix(in srgb, var(--panel-solid) 48%, transparent);
}

.vector-map__brand-mark {
  width: 34px;
  height: 34px;
}

.vector-map__brand-text {
  font-size: 24px;
  line-height: 1;
  letter-spacing: -0.05em;
}

.vector-map__brand-text span {
  color: var(--muted);
}

.vector-map__brand-text strong {
  color: var(--text);
}

.vector-map__label,
.vector-map__status,
.vector-metric span,
.about-card h3,
.auth__eyebrow,
.auth-shell__title,
.hero-card__label,
.status__key {
  color: var(--muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.11em;
}

.vector-map__status {
  color: var(--text);
}

.vector-map__field {
  position: relative;
  min-height: 320px;
  border-radius: 26px;
  border: 1px solid rgba(172, 188, 205, 0.14);
  background:
    linear-gradient(rgba(125, 166, 208, 0.08) 1px, transparent 1px),
    linear-gradient(90deg, rgba(125, 166, 208, 0.08) 1px, transparent 1px),
    radial-gradient(circle at 50% 50%, rgba(115, 196, 207, 0.16), transparent 56%);
  background-size: 44px 44px, 44px 44px, auto;
  overflow: hidden;
}

.vector-map__hub {
  position: absolute;
  width: 128px;
  min-height: 84px;
  padding: 16px;
  border-radius: 24px;
  border: 1px solid rgba(198, 210, 221, 0.18);
  background: color-mix(in srgb, var(--panel-solid) 78%, transparent);
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.18);
}

.vector-map__hub span {
  display: block;
  margin-bottom: 10px;
  color: var(--muted);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
}

.vector-map__hub strong {
  font-size: 18px;
  letter-spacing: -0.03em;
}

.vector-map__hub--core {
  top: calc(50% - 42px);
  left: calc(50% - 64px);
  background: linear-gradient(180deg, rgba(20, 36, 52, 0.96), rgba(12, 22, 34, 0.96));
}

.vector-map__hub--dev {
  top: 34px;
  left: 28px;
}

.vector-map__hub--ops {
  top: 34px;
  right: 28px;
}

.vector-map__hub--cloud {
  bottom: 32px;
  left: calc(50% - 64px);
}

.vector-map__line {
  position: absolute;
  border-top: 1px dashed rgba(136, 175, 206, 0.34);
  transform-origin: left center;
}

.vector-map__line--one {
  width: 168px;
  left: 122px;
  top: 108px;
  transform: rotate(19deg);
}

.vector-map__line--two {
  width: 168px;
  right: 122px;
  top: 108px;
  transform: rotate(-19deg);
}

.vector-map__line--three {
  width: 128px;
  left: calc(50% - 64px);
  top: 194px;
  transform: rotate(90deg);
}

.vector-map__metrics {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-top: 16px;
}

.vector-metric,
.story-card,
.feature-marquee,
.cta-band,
.about-band,
.hero-card,
.stat-card,
.org-health-card,
.terminal,
.status,
.admin-card,
.admin-sidebar,
.auth-shell,
.flight-marker,
.about-card {
  border: 1px solid rgba(177, 192, 207, 0.16);
  border-radius: 22px;
  background: rgba(8, 16, 28, 0.58);
}

.vector-metric,
.hero-card,
.about-card,
.flight-marker {
  padding: 14px 16px;
}

.vector-metric strong,
.hero-card__value,
.stat-card__value {
  font-size: 15px;
  line-height: 1.5;
}

.story-grid,
.about-band__grid,
.content {
  display: grid;
  gap: 16px;
}

.story-grid {
  grid-template-columns: repeat(3, 1fr);
  margin-top: 18px;
}

.story-card,
.feature-marquee,
.cta-band,
.about-band {
  padding: 24px;
}

.story-card h2,
.feature-marquee h2,
.cta-band h2,
.about-band h2 {
  margin: 0 0 12px;
  font-size: 28px;
  line-height: 1.15;
  letter-spacing: -0.04em;
}

.story-card p,
.feature-marquee__text,
.about-card p,
.auth__hint,
.runbook__summary,
.admin-copy,
.cta-band p {
  color: var(--muted);
  line-height: 1.8;
}

.feature-marquee {
  margin-top: 18px;
}

.feature-marquee--split {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: 24px;
}

.feature-chip {
  font-size: 13px;
  text-transform: none;
  letter-spacing: 0;
  padding: 12px 16px;
}

.about-band {
  margin-top: 18px;
  background:
    linear-gradient(180deg, rgba(12, 22, 34, 0.7), rgba(16, 29, 45, 0.74)),
    radial-gradient(340px 180px at 10% 0%, rgba(122, 180, 214, 0.08), transparent 70%);
}

.about-band__grid {
  grid-template-columns: repeat(3, 1fr);
  margin-top: 20px;
}

.cta-band {
  align-items: center;
  margin-top: 18px;
}

.cta-band--warm {
  background:
    linear-gradient(135deg, rgba(13, 24, 36, 0.9), rgba(16, 29, 43, 0.9)),
    radial-gradient(300px 180px at 100% 20%, rgba(122, 180, 214, 0.1), transparent 70%);
}

.app,
.auth-frame {
  width: min(1180px, calc(100vw - 28px));
  margin: 18px auto;
}

.auth-frame {
  min-height: calc(100vh - 34px);
  display: flex;
  align-items: center;
  justify-content: center;
}

.admin-app {
  width: min(1380px, calc(100vw - 28px));
}

.panel {
  border-radius: 30px;
  border: 1px solid rgba(178, 194, 211, 0.16);
  background: linear-gradient(180deg, rgba(7, 15, 24, 0.94), rgba(10, 18, 30, 0.96));
  box-shadow: 0 30px 100px var(--shadow);
  overflow: hidden;
}

.chrome {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 20px;
  border-bottom: 1px solid rgba(176, 190, 206, 0.12);
}

.chrome__lights {
  display: flex;
  gap: 10px;
}

.chrome__light {
  width: 11px;
  height: 11px;
  border-radius: 999px;
}

.chrome__light--red { background: #ff7e75; }
.chrome__light--yellow { background: #efb85f; }
.chrome__light--green { background: #6dd6b0; }

.chrome__title {
  color: var(--muted);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-size: 12px;
}

.hidden {
  display: none !important;
}

.auth {
  padding: 34px;
}

.auth--console {
  width: auto;
  margin: 0;
  border: 0;
  background: transparent;
}

.auth-signin-card {
  width: min(520px, 100%);
  border-radius: 24px;
  border: 1px solid var(--surface-border-strong);
  background:
    radial-gradient(220px 140px at 50% 0%, color-mix(in srgb, var(--cyan) 12%, transparent), transparent 70%),
    linear-gradient(180deg, color-mix(in srgb, var(--surface-soft) 84%, transparent), var(--surface-elevated));
  box-shadow: var(--panel-shadow);
  padding: 28px 32px 24px;
}

.auth-signin-card--family {
  width: min(520px, 100%);
}

.auth-error {
  margin: 0 0 16px;
  padding: 12px 14px;
  border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--cyan) 40%, transparent);
  background: color-mix(in srgb, var(--cyan) 10%, transparent);
  color: var(--text);
  font-size: 13px;
  line-height: 1.5;
}

.auth-layout {
  display: grid;
  grid-template-columns: 1.04fr 0.96fr;
  gap: 28px;
  align-items: stretch;
}

.auth-copy {
  padding: 24px 8px 24px 8px;
}

.auth__brand {
  margin: 0 0 12px;
  font-size: 28px;
  letter-spacing: -0.05em;
}

.auth__brand--with-mark {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.auth__brand--stacked {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin-bottom: 18px;
}

.auth__brand--vertical {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  margin-bottom: 12px;
}

.auth__brand--family {
  gap: 12px;
  margin-bottom: 8px;
}

.auth__wordmark {
  display: inline-flex;
  align-items: baseline;
  gap: 3px;
}

.auth__wordmark--stacked {
  font-size: 1.1rem;
}

.auth__brand--family .auth__wordmark--stacked {
  font-size: 1.28rem;
  letter-spacing: -0.04em;
}

.auth__brand span {
  color: var(--muted);
}

.auth__brand strong {
  color: var(--text);
}

.auth__title {
  margin: 8px 0 12px;
  max-width: 13ch;
  font-size: clamp(30px, 3.4vw, 46px);
  line-height: 1.02;
  letter-spacing: -0.05em;
}

.auth__title--console {
  max-width: 11ch;
}

.auth__title--centered {
  max-width: none;
  text-align: center;
  font-size: clamp(24px, 2.6vw, 34px);
  line-height: 1.08;
  letter-spacing: -0.04em;
}

.auth__title--plain {
  max-width: none;
  text-align: center;
  font-size: 1.05rem;
  line-height: 1.2;
  letter-spacing: 0;
  font-family: "IBM Plex Sans", "Segoe UI", sans-serif;
  font-weight: 600;
  margin-top: 0;
}

.auth__title--signin {
  font-size: 2.1rem;
  font-family: "Iowan Old Style", "Palatino Linotype", Georgia, serif;
  font-weight: 700;
  color: var(--text);
  margin: 0 0 8px;
}

.auth__eyebrow--centered,
.auth__hint--centered {
  text-align: center;
}

.auth__hint--centered {
  max-width: 30ch;
  margin: 0 auto 20px;
}

.auth__hint--family {
  color: var(--muted);
  font-size: .8rem;
  margin-bottom: 1rem;
}

.auth__hint--family.auth__hint--centered {
  margin-bottom: 22px;
}

.auth__tagline {
  margin: 0 0 16px;
  text-align: center;
  color: var(--muted);
  font-size: .78rem;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.auth__tagline--family {
  color: var(--muted);
  margin-bottom: 18px;
}

.auth__subnote {
  margin: 14px 0 0;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.7;
  text-align: center;
}

.auth__subnote strong {
  color: var(--text);
}

.auth-provider-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin: 0 0 18px;
}

.auth-channel-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
  margin: 0 0 16px;
}

.auth-channel-row--logos {
  row-gap: 10px;
}

.auth-channel-row--tight {
  gap: 8px;
  margin-bottom: 18px;
}

.auth-channel-chip {
  padding: .28rem .7rem;
  border-radius: 999px;
  background: rgba(79, 70, 229, 0.12);
  border: 1px solid rgba(99, 102, 241, 0.2);
  color: #818cf8;
  font-size: .72rem;
}

.auth-channel-chip--logo {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: .38rem .82rem;
  border-radius: 999px;
  background: rgba(17, 25, 40, 0.92);
  border-color: rgba(58, 72, 96, 0.84);
  color: var(--muted);
}

.auth-channel-chip--active {
  color: var(--text);
}

.auth-chip-row {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  gap: .45rem;
  margin: 0 0 1rem;
}

.auth-chip-row--family {
  margin-bottom: 1.1rem;
}

.auth-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 28px;
  padding: 0 .72rem;
  border-radius: 999px;
  border: 1px solid rgba(99, 102, 241, 0.22);
  background: rgba(79, 70, 229, 0.1);
  color: #818cf8;
  font-size: .7rem;
  letter-spacing: .03em;
}

.auth-provider {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 38px;
  padding: 0 14px;
  border-radius: 12px;
  border: 1px solid rgba(84, 101, 127, 0.28);
  background: rgba(14, 24, 38, 0.58);
  color: var(--muted);
  font-size: 13px;
}

.auth-provider--active {
  color: var(--text);
  border-color: rgba(77, 143, 188, 0.4);
  background: rgba(18, 48, 74, 0.84);
}

.auth-provider-button {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  min-height: 52px;
  margin-bottom: 14px;
  padding: 0 16px;
  border-radius: 14px;
  border: 1px solid var(--surface-border-strong);
  background: var(--surface-active);
  color: var(--text);
  text-decoration: none;
  font-size: .95rem;
  font-weight: 600;
}

.auth-provider-button--family {
  min-height: 50px;
  border-radius: 13px;
  background: linear-gradient(180deg, color-mix(in srgb, var(--surface-active) 92%, transparent), color-mix(in srgb, var(--surface-hover) 82%, transparent));
  border-color: var(--surface-border-strong);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

.auth-provider-button:hover {
  filter: brightness(1.04);
  background: color-mix(in srgb, var(--surface-hover) 85%, var(--surface-active) 15%);
}

.auth-provider-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}

.auth-provider-label {
  font-size: .72rem;
  color: var(--muted);
  text-align: center;
  margin-bottom: .7rem;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.auth-provider-tile-grid {
  display: flex;
  flex-wrap: wrap;
  gap: .55rem;
  justify-content: center;
  margin-bottom: .5rem;
}

.auth-provider-tile-grid--family {
  gap: .6rem;
  margin-bottom: .65rem;
}

.auth-provider-tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 38px;
  padding: 0 .9rem;
  border-radius: 12px;
  border: 1px solid var(--surface-border);
  background: var(--surface-soft);
  font-size: .82rem;
  color: var(--muted);
  text-decoration: none;
  transition: transform 140ms ease, border-color 140ms ease, background 140ms ease;
}

.auth-provider-tile:hover {
  transform: translateY(-1px);
  border-color: var(--surface-border-strong);
  background: color-mix(in srgb, var(--surface-hover) 88%, transparent);
}

.auth-provider-tile--muted {
  opacity: .8;
}

.auth-help-text {
  margin: 0 0 16px;
  text-align: center;
  color: var(--muted);
  font-size: .72rem;
}

body[data-theme="retro"] .login-body,
body[data-theme="retro"] {
  background:
    radial-gradient(520px 420px at 12% 28%, rgba(255, 208, 111, 0.12) 0%, transparent 70%),
    radial-gradient(520px 420px at 88% 74%, rgba(163, 255, 121, 0.08) 0%, transparent 70%),
    linear-gradient(180deg, #1b130f 0%, #261a13 100%);
}

body[data-theme="white"] .login-body,
body[data-theme="white"] {
  background:
    radial-gradient(520px 420px at 12% 28%, rgba(0, 95, 150, 0.08) 0%, transparent 70%),
    radial-gradient(520px 420px at 88% 74%, rgba(15, 157, 88, 0.06) 0%, transparent 70%),
    linear-gradient(180deg, #eef4fb 0%, #e5eef9 100%);
}

body[data-theme="neon"] .login-body,
body[data-theme="neon"] {
  background:
    radial-gradient(520px 420px at 12% 28%, rgba(255, 45, 200, 0.14) 0%, transparent 70%),
    radial-gradient(520px 420px at 88% 74%, rgba(0, 245, 255, 0.1) 0%, transparent 70%),
    linear-gradient(180deg, #07001a 0%, #130028 100%);
}

body[data-theme="steel"] .login-body,
body[data-theme="steel"] {
  background:
    radial-gradient(520px 420px at 12% 28%, rgba(255, 255, 255, 0.05) 0%, transparent 70%),
    radial-gradient(520px 420px at 88% 74%, rgba(255, 255, 255, 0.03) 0%, transparent 70%),
    linear-gradient(180deg, #0b0b0d 0%, #111114 100%);
}

body[data-theme="abyss"] .login-body,
body[data-theme="abyss"] {
  background:
    radial-gradient(520px 420px at 12% 28%, rgba(139, 92, 246, 0.13) 0%, transparent 70%),
    radial-gradient(520px 420px at 88% 74%, rgba(219, 39, 119, 0.08) 0%, transparent 70%),
    linear-gradient(180deg, #04000e 0%, #10021f 100%);
}

.auth-provider-button.is-disabled,
.auth-provider-tile.is-disabled {
  opacity: .52;
  filter: saturate(0.72);
  cursor: not-allowed;
}

.flight-markers {
  display: grid;
  gap: 14px;
  margin-top: 26px;
}

.flight-marker strong {
  display: block;
  margin-top: 8px;
  font-size: 17px;
  letter-spacing: -0.03em;
}

.auth-shell {
  padding: 22px;
  background:
    radial-gradient(240px 140px at 50% 0%, rgba(122, 198, 212, 0.06), transparent 68%),
    linear-gradient(180deg, rgba(12, 23, 35, 0.92), rgba(10, 19, 31, 0.97));
}

.auth-shell__header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 18px;
}

.auth-shell__line {
  display: inline-block;
  width: 42px;
  height: 1px;
  background: linear-gradient(90deg, color-mix(in srgb, var(--text) 55%, transparent), transparent);
}

.auth-divider {
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--surface-border), transparent);
}

.auth-divider--tight {
  margin: 2px 0 18px;
}

.auth-input {
  width: 100%;
  min-height: 46px;
  border-radius: 12px;
  border: 1px solid var(--surface-border-strong);
  background: var(--surface-soft);
  color: var(--text);
  font: inherit;
  padding: 0 14px;
}

.auth-input::placeholder {
  color: color-mix(in srgb, var(--muted) 85%, transparent);
}

.auth-input:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--cyan) 55%, var(--surface-border-strong));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--cyan) 14%, transparent);
}

.cta-band--compact {
  align-items: center;
  padding: 14px 16px;
}

.hero-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.hero-grid--stack {
  grid-template-columns: 1fr;
}

.hero-card {
  background: rgba(9, 18, 30, 0.44);
}

.auth-cta-stack .btn {
  justify-content: center;
}

.auth-devnote .pill-list {
  margin-top: 12px;
}

.auth-devnote {
  padding-top: 18px;
  border-top: 1px solid rgba(177, 192, 207, 0.12);
}

.pill-list--centered {
  justify-content: center;
}

.auth-divider {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 16px 0 18px;
  color: var(--muted);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.auth-divider::before,
.auth-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: rgba(76, 88, 118, 0.4);
}

.auth-divider--tight {
  margin: 0 0 18px;
}

.auth-links-row {
  display: flex;
  justify-content: center;
  margin-top: 18px;
}

.auth-text-link {
  color: #818cf8;
  text-decoration: none;
  font-size: .84rem;
}

.auth-text-link:hover {
  color: var(--text);
}

.auth-links-row--spread {
  justify-content: space-between;
  gap: 16px;
}

.auth-form {
  display: grid;
  gap: 12px;
}

.auth-field-label {
  color: var(--muted);
  font-size: 13px;
}

.auth-input {
  width: 100%;
  min-height: 52px;
  padding: 0 14px;
  border-radius: 14px;
  border: 1px solid rgba(52, 65, 85, 0.9);
  background: rgba(30, 41, 59, 0.7);
  color: var(--text);
  font: inherit;
  outline: none;
}

.auth-input::placeholder {
  color: color-mix(in srgb, var(--muted) 72%, transparent);
}

.auth-input:focus {
  border-color: rgba(125, 183, 216, 0.52);
  box-shadow: 0 0 0 3px rgba(72, 138, 186, 0.12);
}

.auth-checkbox-row {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  color: var(--muted);
  font-size: .8rem;
}

.auth-checkbox-row input {
  accent-color: #1d8cc7;
}

.auth-submit-button {
  width: 100%;
  min-height: 54px;
  border: 1px solid rgba(78, 212, 255, 0.35);
  border-radius: 14px;
  background: #12304a;
  color: var(--text);
  font: inherit;
  font-size: .95rem;
  font-weight: 700;
  cursor: pointer;
}

.auth-submit-button:hover {
  filter: brightness(1.06);
}

.auth-submit-button:disabled {
  opacity: 0.7;
  cursor: wait;
}

.form {
  display: grid;
  gap: 14px;
  margin-top: 18px;
}

.form__field {
  display: grid;
  gap: 8px;
}

.form__field[hidden] {
  display: none;
}

.form__field span {
  color: var(--muted);
  font-size: 13px;
}

.form__field input {
  min-height: 48px;
  border-radius: 16px;
  border: 1px solid rgba(173, 189, 206, 0.14);
  background: color-mix(in srgb, var(--panel-solid) 78%, transparent);
  color: var(--text);
  padding: 0 14px;
  font: inherit;
}

.cp-ws-tag-rows {
  display: grid;
  gap: 8px;
}

.cp-ws-tag-row {
  display: grid;
  grid-template-columns: 1fr 1fr auto;
  gap: 8px;
  align-items: center;
}

.cp-ws-tag-row input {
  min-height: 40px;
  width: 100%;
  min-width: 0;
  border-radius: 12px;
  border: 1px solid rgba(173, 189, 206, 0.14);
  background: color-mix(in srgb, var(--panel-solid) 78%, transparent);
  color: var(--text);
  padding: 0 12px;
  font: inherit;
}

.form__field textarea {
  min-height: 80px;
  border-radius: 16px;
  border: 1px solid rgba(173, 189, 206, 0.14);
  background: color-mix(in srgb, var(--panel-solid) 78%, transparent);
  color: var(--text);
  padding: 12px 14px;
  font: inherit;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px;
  resize: vertical;
}

.btn {
  /* inline-flex with centred content is what makes buttons in a row actually
     line up. With min-height alone a wrapping label grows the box past its
     siblings — measured at 61px next to 50px in the AWS connect wizard — and a
     row of buttons reads as broken rather than as one control group. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 10px 18px;
  border: 0;
  border-radius: 14px;
  background: linear-gradient(135deg, #d8e2ee 0%, #7db7d8 56%, #92a3bb 100%);
  color: #0c1722;
  font: inherit;
  font-weight: 700;
  line-height: 1.25;
  text-align: center;
  cursor: pointer;
}

.btn:hover {
  filter: brightness(1.04);
}

.btn--linklike {
  text-decoration: none;
}

.auth-cta-stack--compact {
  margin-top: 20px;
}

.brand-mark--hero {
  width: 54px;
  height: 54px;
}

.auth-logo {
  display: inline-block;
  width: 14px;
  height: 14px;
  border-radius: 999px;
  flex: 0 0 auto;
}

.auth-logo--google {
  background: conic-gradient(#4285f4 0 25%, #34a853 25% 50%, #fbbc05 50% 75%, #ea4335 75% 100%);
}

.auth-logo--microsoft {
  border-radius: 2px;
  background:
    linear-gradient(#f25022 0 0) left top/6px 6px no-repeat,
    linear-gradient(#7fba00 0 0) right top/6px 6px no-repeat,
    linear-gradient(#00a4ef 0 0) left bottom/6px 6px no-repeat,
    linear-gradient(#ffb900 0 0) right bottom/6px 6px no-repeat;
}

.auth-logo--github {
  background: #cbd5e1;
  mask: radial-gradient(circle at 50% 35%, transparent 2px, #000 2.2px) center/100% 100%;
  -webkit-mask: radial-gradient(circle at 50% 35%, transparent 2px, #000 2.2px) center/100% 100%;
}

.auth-logo--slack {
  border-radius: 4px;
  background:
    linear-gradient(#e01e5a 0 0) left 1px top 4px/4px 8px no-repeat,
    linear-gradient(#36c5f0 0 0) left 4px top 1px/8px 4px no-repeat,
    linear-gradient(#2eb67d 0 0) right 1px top 4px/4px 8px no-repeat,
    linear-gradient(#ecb22e 0 0) left 4px bottom 1px/8px 4px no-repeat;
}

.auth-logo--apple {
  background: linear-gradient(180deg, #e2e8f0, #94a3b8);
  border-radius: 4px 4px 6px 6px;
}

.auth-logo--okta {
  background: #007dc1;
  box-shadow: inset 0 0 0 3px #0f172a;
}

.btn--ghost {
  background: transparent;
  border: 1px solid rgba(181, 194, 207, 0.18);
  color: var(--text);
}

.btn--small {
  min-height: auto;
  padding: 6px 10px;
  font-size: 12px;
}

.btn--danger {
  border-color: rgba(224, 94, 94, 0.4);
  color: var(--danger);
}

.btn--danger:hover {
  background: rgba(224, 94, 94, 0.12);
}

.pill {
  color: var(--text);
}

/* A pill holding a VALUE, not a label.
   
   .pill above is nowrap + flex-shrink:0 on purpose: a status label must stay
   whole, because breaking one produces "NO RANCHE / R" and reads as a rendering
   fault. That reasoning does not transfer to a callback URL or a shell command.
   
   Given to one, a 58-character URL cannot shrink and cannot wrap, so inside a
   240px grid track it forces its tile wider than the column and spills across
   the neighbouring cards. Seen on the admin Identity Providers page, where the
   Google tile's callback URL ran underneath the Microsoft tile.
   
   min-width:0 is the other half: a grid item defaults to min-width:auto, which
   refuses to shrink below its content, so the track widens instead of the text
   wrapping. */
.pill--value {
  white-space: normal;
  flex-shrink: 1;
  min-width: 0;
  overflow-wrap: anywhere;
  text-transform: none;
  letter-spacing: 0.02em;
  text-align: left;
  border-radius: 8px;
}

.pill--accent,
.org-switch--active {
  background: rgba(114, 191, 242, 0.16);
  border-color: rgba(114, 191, 242, 0.34);
}

.error {
  color: var(--danger);
  margin-top: 10px;
}

.workspace,
.admin-layout {
  padding: 18px;
}

.content {
  grid-template-columns: 1.08fr 0.92fr;
  gap: 22px;
}

.content--admin {
  grid-template-columns: 1fr 0.78fr;
}

.terminal,
.status,
.admin-card,
.admin-sidebar,
.admin-main {
  padding: 20px;
}

.terminal__lead,
.status__head,
.status__link {
  color: var(--muted);
}

.terminal__title {
  margin: 12px 0 18px;
  font-size: clamp(34px, 5vw, 54px);
  line-height: 1;
  letter-spacing: -0.06em;
}

.command {
  margin: 20px 0;
  padding: 16px;
  border-radius: 18px;
  background: color-mix(in srgb, var(--panel-solid) 78%, transparent);
  border: 1px solid rgba(171, 188, 205, 0.12);
  display: flex;
  align-items: center;
  gap: 10px;
}

.command__line {
  color: var(--text);
}

.command__caret {
  width: 8px;
  height: 16px;
  background: #7ee0c9;
  animation: blink 1s step-start infinite;
}

.tag-list,
.org-list {
  margin: 14px 0 0;
  padding: 0;
  list-style: none;
}

.runbook {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid rgba(177, 194, 211, 0.14);
}

.runbook__title {
  margin: 0 0 10px;
}

.action-grid {
  margin-top: 8px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

.stats-grid,
.org-card-grid,
.flag-list {
  display: grid;
  gap: 10px;
}

.stats-grid {
  grid-template-columns: repeat(4, 1fr);
  margin: 16px 0;
}

.status__rows {
  display: grid;
  gap: 12px;
  margin: 18px 0;
}

.status__row {
  padding: 10px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

.status__value {
  text-align: right;
  font-size: 13px;
}

.status__footer {
  margin-top: 18px;
}

.status__link {
  text-decoration: none;
  font-size: 12px;
}

.org-switch {
  cursor: pointer;
}

.admin-layout {
  display: grid;
  grid-template-columns: 250px 1fr;
  gap: 14px;
}

.admin-user {
  color: var(--muted);
  margin: 0 0 12px;
  font-size: 12px;
}

.auth__brand--admin {
  margin-bottom: 14px;
}

.flag-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  border: 1px solid rgba(177, 194, 211, 0.14);
  border-radius: 16px;
  background: color-mix(in srgb, var(--panel-solid) 72%, transparent);
  padding: 12px 14px;
}

.flag-row strong {
  display: block;
  font-size: 13px;
}

.flag-row p {
  margin: 4px 0 0;
  color: var(--muted);
  font-size: 12px;
}

.admin-console {
  display: grid;
  grid-template-columns: 260px 1fr;
  min-height: 820px;
  background: linear-gradient(180deg, rgba(7, 14, 24, 0.98), rgba(9, 18, 30, 0.98));
}

.admin-rail {
  padding: 22px 18px;
  border-right: 1px solid rgba(177, 194, 211, 0.1);
  background: color-mix(in srgb, var(--panel-solid) 96%, transparent);
}

.admin-rail__subtitle,
.admin-kicker,
.admin-section__eyebrow {
  color: var(--muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
}

.admin-rail__identity {
  display: grid;
  gap: 10px;
  margin: 18px 0 22px;
}

.admin-nav {
  display: grid;
  gap: 10px;
  margin-bottom: 22px;
}

.admin-nav a {
  color: var(--muted);
  text-decoration: none;
  padding: 10px 12px;
  border-radius: 12px;
  border: 1px solid rgba(177, 194, 211, 0.08);
  background: color-mix(in srgb, var(--panel-solid) 36%, transparent);
}

.admin-rail__actions {
  display: grid;
  gap: 10px;
}

.admin-workspace {
  padding: 22px;
}

.admin-hero,
.admin-section,
.metric-card,
.support-card,
.apikey-card {
  border-radius: 24px;
  border: 1px solid rgba(177, 194, 211, 0.14);
  background: rgba(9, 19, 31, 0.72);
}

.admin-hero {
  display: flex;
  justify-content: space-between;
  gap: 20px;
  padding: 24px;
}

.admin-hero__actions {
  display: flex;
  gap: 10px;
  align-items: flex-start;
}

.admin-title {
  margin: 8px 0 12px;
  font-size: clamp(30px, 4vw, 42px);
  line-height: 1.05;
  letter-spacing: -0.05em;
}

.metric-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 14px;
  margin-top: 16px;
}

.metric-card {
  padding: 18px;
}

.metric-card__value {
  display: block;
  margin-top: 8px;
  font-size: 28px;
}

.admin-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-top: 16px;
}

.admin-section {
  padding: 22px;
}

.admin-section--wide {
  grid-column: 1 / -1;
}

.admin-section__head {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  align-items: end;
  margin-bottom: 18px;
}

.admin-section__head h2,
.support-card h3 {
  margin: 6px 0 0;
}

.admin-select {
  display: grid;
  gap: 6px;
  min-width: 240px;
}

.admin-select select,
.form__field select {
  min-height: 48px;
  width: 100%;
  min-width: 0;
  border-radius: 16px;
  border: 1px solid rgba(173, 189, 206, 0.14);
  background: color-mix(in srgb, var(--panel-solid) 78%, transparent);
  color: var(--text);
  padding: 0 14px;
  font: inherit;
}

.form--inline {
  grid-template-columns: repeat(4, 1fr);
  align-items: end;
}

.form--grid-two {
  grid-template-columns: repeat(2, 1fr);
  align-items: end;
}

.form--admin {
  margin-top: 18px;
}

.member-table-wrap {
  overflow-x: auto;
  border-radius: 18px;
  border: 1px solid rgba(177, 194, 211, 0.12);
  background: color-mix(in srgb, var(--panel-solid) 70%, transparent);
}

.member-table {
  width: 100%;
  border-collapse: collapse;
}

.member-table th,
.member-table td {
  padding: 14px 16px;
  text-align: left;
  border-bottom: 1px solid rgba(177, 194, 211, 0.08);
  font-size: 14px;
}

.member-table th {
  color: var(--muted);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.org-health-card__top,
.apikey-row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  align-items: center;
}

.apikey-card {
  padding: 18px;
}

.action-grid--two {
  grid-template-columns: 1fr 1fr;
}

.support-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
}

.support-card {
  padding: 18px;
}

.auth-cta-stack {
  display: grid;
  gap: 12px;
  margin-top: 20px;
}

.auth-devnote {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid rgba(177, 194, 211, 0.14);
}

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

@media (max-width: 1080px) {
  .hero,
  .auth-layout,
  .content,
  .content--admin,
  .feature-marquee--split,
  .story-grid,
  .about-band__grid,
  .vector-map__metrics,
  .hero-grid,
  .stats-grid,
  .action-grid,
  .admin-layout,
  .metric-grid,
  .admin-grid,
  .support-grid,
  .form--inline,
  .form--grid-two,
  .admin-console {
    grid-template-columns: 1fr;
  }

  .signal-wall__grid,
  .about-story-grid,
  .about-pillars,
  .signal-wall__grid--compact {
    grid-template-columns: 1fr;
  }

  .frontdoor-terminal {
    min-height: auto;
  }

  .landing--frontdoor,
  .landing--about {
    overflow: visible;
  }

  .vector-map__field {
    min-height: 420px;
  }

  .vector-map__hub--ops {
    top: 148px;
    right: 28px;
  }

  .vector-map__hub--dev {
    top: 34px;
  }

  .vector-map__hub--cloud {
    bottom: 30px;
  }

  .vector-map__line--two {
    width: 108px;
    right: 122px;
    top: 214px;
    transform: rotate(-45deg);
  }
}

@media (max-width: 720px) {
  .landing,
  .app {
    width: min(100vw - 24px, 1240px);
  }

  .landing {
    padding-top: 18px;
  }

  .landing--frontdoor {
    min-height: auto;
  }

  .landing--about {
    min-height: auto;
  }

  .app {
    margin: 18px auto;
  }

  .landing-nav,
  .landing-nav__links,
  .landing-nav__actions,
  .hero__actions,
  .cta-band,
  .admin-hero,
  .admin-section__head,
  .admin-hero__actions {
    flex-wrap: wrap;
  }

  .auth,
  .terminal,
  .status,
  .signal-wall,
  .feature-marquee,
  .about-band,
  .cta-band,
  .workspace,
  .admin-layout {
    padding: 20px;
  }

  .auth-copy {
    padding: 0;
  }

  .hero__title,
  .auth__title,
  .terminal__title {
    font-size: clamp(34px, 11vw, 54px);
  }

  .hero--frontdoor {
    min-height: auto;
  }

  .vector-map__field {
    min-height: 500px;
  }

  .vector-map__hub {
    width: 118px;
  }

  .vector-map__hub--core {
    top: 182px;
    left: calc(50% - 59px);
  }

  .vector-map__hub--dev {
    top: 28px;
    left: 18px;
  }

  .vector-map__hub--ops {
    top: 28px;
    right: 18px;
  }

  .vector-map__hub--cloud {
    bottom: 20px;
    left: calc(50% - 59px);
  }

  .vector-map__line--one {
    width: 112px;
    left: 118px;
    top: 122px;
  }

  .vector-map__line--two {
    width: 112px;
    right: 118px;
    top: 122px;
    transform: rotate(-17deg);
  }
}

.pill-list--login {
  justify-content: center;
  margin-bottom: 14px;
}

.auth-links-row {
  display: flex;
  justify-content: center;
  margin-top: 8px;
}

.auth-text-link {
  color: var(--muted);
  text-decoration: none;
  font-size: .85rem;
}

.auth-text-link:hover {
  color: var(--text);
}

/* Log-feed vocabulary — originally admin.html-only, moved here so
   console.html's new per-cluster pod-log viewer can reuse the exact same
   visual language instead of a third duplicate copy (admin.html previously
   carried its own inline copy of these same rules). */
.cp-admin-log-controls {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  align-items: center;
  margin-bottom: 14px;
}

.cp-admin-log-controls input,
.cp-admin-log-controls select {
  min-width: 180px;
}

.cp-admin-logfeed {
  display: grid;
  gap: 12px;
}

.cp-admin-logfeed__item {
  border-radius: 14px;
  border: 1px solid var(--surface-border);
  background: var(--surface-elevated);
  padding: 14px;
}

.cp-admin-logfeed__meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
  color: var(--muted);
  font-size: 12px;
}

.cp-admin-logfeed__message {
  color: var(--text);
  font-size: 14px;
  margin-bottom: 8px;
}

.cp-admin-logfeed__detail {
  color: var(--muted);
  font-size: 12px;
  white-space: pre-wrap;
  word-break: break-word;
}

/* Real, table-based log viewer — matches the reference design used
   elsewhere in the product (category pills + time-range pills + live
   toggle + entry count above a dense monospace table with a colored
   left-border accent per row and a colored level pill). Shared between
   the admin console's operator log feed and the Kubernetes cluster
   monitor's pod-log viewer — same visual language, different data
   sources underneath. */
.cp-log-toolbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 14px;
}

.cp-log-pillgroup {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.cp-log-pill {
  border: 1px solid var(--surface-border);
  background: var(--surface-elevated);
  color: var(--muted);
  border-radius: 999px;
  padding: 6px 14px;
  font-size: 12px;
  cursor: pointer;
  white-space: nowrap;
}

.cp-log-pill:hover {
  color: var(--text);
}

.cp-log-pill.is-active {
  background: color-mix(in srgb, var(--amber) 22%, transparent);
  border-color: color-mix(in srgb, var(--amber) 50%, transparent);
  color: var(--warn);
}

.cp-log-divider {
  width: 1px;
  height: 22px;
  background: var(--surface-border);
}

.cp-log-filter-input {
  flex: 1;
  min-width: 140px;
  border-radius: 10px;
  border: 1px solid var(--surface-border);
  background: var(--surface-elevated);
  color: inherit;
  padding: 7px 12px;
  font: inherit;
  font-size: 12px;
}

.cp-log-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
}

.cp-log-live {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--surface-border);
  border-radius: 999px;
  padding: 5px 12px;
  cursor: pointer;
  background: var(--surface-elevated);
  color: var(--muted);
}

.cp-log-live.is-on {
  border-color: color-mix(in srgb, #4ade9c 50%, transparent);
  color: var(--ok);
}

.cp-log-live__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #4f647e;
}

.cp-log-live.is-on .cp-log-live__dot {
  background: #4ade9c;
  animation: cp-value-pulse 1.6s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .cp-log-live.is-on .cp-log-live__dot {
    animation: none;
  }
}

.cp-log-table-wrap {
  overflow-x: auto;
  border-radius: 16px;
  border: 1px solid var(--surface-border);
}

.cp-log-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
  font-family: "SFMono-Regular", ui-monospace, Menlo, Consolas, monospace;
  min-width: 640px;
}

.cp-log-table th {
  text-align: left;
  padding: 10px 14px;
  color: var(--muted);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border-bottom: 1px solid var(--surface-border);
  background: var(--surface-strong);
  position: sticky;
  top: 0;
}

.cp-log-table td {
  padding: 9px 14px;
  border-bottom: 1px solid rgba(48, 66, 92, 0.22);
  vertical-align: top;
  color: var(--text);
}

.cp-log-table tr.cp-log-row {
  border-left: 3px solid var(--surface-border);
}

.cp-log-row--pass { border-left-color: #4ade9c; }
.cp-log-row--warn { border-left-color: #f8d27d; }
.cp-log-row--fail { border-left-color: #ff9ca0; }
.cp-log-row--audit { border-left-color: #b39ddb; }
.cp-log-row--info { border-left-color: var(--surface-border); }

.cp-log-level {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 6px;
  font-size: 10.5px;
  letter-spacing: 0.04em;
  font-weight: 600;
}

.cp-log-level--pass { background: color-mix(in srgb, var(--panel-solid) 40%, transparent); color: var(--ok); }
.cp-log-level--warn { background: rgba(93, 70, 18, 0.35); color: var(--warn); }
.cp-log-level--fail { background: color-mix(in srgb, var(--panel-solid) 40%, transparent); color: var(--bad); }
.cp-log-level--audit { background: color-mix(in srgb, var(--panel-solid) 40%, transparent); color: var(--muted); }
.cp-log-level--info { background: color-mix(in srgb, var(--panel-solid) 32%, transparent); color: var(--muted); }

.cp-log-table td.cp-log-timestamp {
  color: var(--muted);
  white-space: nowrap;
}

.cp-log-table td.cp-log-actor {
  color: var(--muted);
  white-space: nowrap;
}

/* ---- Landing hero: live command demo ---- */
.frontdoor-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 12px;
}

.frontdoor-chip {
  font: inherit;
  font-size: 11px;
  cursor: pointer;
  padding: 4px 11px;
  border-radius: 999px;
  border: 1px solid rgba(122, 180, 221, 0.28);
  background: transparent;
  color: var(--muted);
}

.frontdoor-chip:hover {
  border-color: rgba(122, 180, 221, 0.6);
  color: var(--text);
}

.frontdoor-chip[aria-pressed="true"] {
  border-color: rgba(119, 201, 203, 0.7);
  background: rgba(119, 201, 203, 0.12);
  color: var(--text);
}

.frontdoor-chip:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 2px;
}

/* Output severity, so a held check reads differently from a clean one. */
.frontdoor-terminal__line--ok { color: #77c9cb; }
.frontdoor-terminal__line--warn { color: #e8be7c; }
.frontdoor-terminal__line--dim { opacity: 0.72; }

/* The output block swaps between commands — hold a stable height so the
   hero does not jump every time a command finishes. */
[data-terminal-output] {
  min-height: 66px;
}

/* The toggle that reveals the ungoverned agent lane most platforms ship. */
.bypass-toggle {
  font: inherit;
  font-size: 11.5px;
  cursor: pointer;
  margin-top: 10px;
  padding: 5px 13px;
  border-radius: 999px;
  border: 1px dashed rgba(255, 136, 163, 0.45);
  background: transparent;
  color: var(--bad);
}

.bypass-toggle:hover { border-style: solid; }
.bypass-toggle[aria-pressed="true"] {
  border-style: solid;
  background: rgba(255, 136, 163, 0.12);
  color: var(--text);
}
.bypass-toggle:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }

/* ---- Landing hero: one screen, no scrolling ----
   Two columns. Left leads with the diagram sitting directly beneath the
   brand; right carries the terminal and the cards that hold the detail the
   hero copy used to spell out. Heights are viewport-relative so the whole
   page fits without scrolling. */
/* The shared main padding is generous for scrolling pages; this one must fit
   a single viewport, so its bottom space scales with the viewport instead. */
.landing-body main.landing {
  padding-bottom: clamp(14px, 3vh, 44px);
}

.hero--frontdoor {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: 30px;
  align-items: start;
  padding-top: 4px;
}

.hero__main { min-width: 0; }

/* The diagram, not a background: it is the argument, so it gets real space
   and sits high — immediately under the wordmark. */
.hero__fabric {
  display: block;
  width: 100%;
  height: clamp(196px, 26vh, 320px);
  margin-bottom: 14px;
  cursor: pointer;
}

.hero--frontdoor .hero__eyebrow { margin: 0 0 6px; }

/* The base .hero__title--wide is sized for a full-bleed hero and rendered at
   83px here — 489px of headline, half the page, which is what forced the
   scroll. In a two-column hero it has to be sized to its column. */
.hero--frontdoor .hero__title {
  margin: 0 0 10px;
  font-size: clamp(28px, 3.1vw, 46px);
  line-height: 1.08;
}

.hero--frontdoor .hero__lede {
  margin: 0 0 16px;
  max-width: 46ch;
  font-size: 15px;
  line-height: 1.55;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

.hero__side {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* Detail lives in cards, each a real link onward, so the hero can stay short. */
.hero__cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
}

.hero__card {
  display: block;
  text-decoration: none;
  border: 1px solid rgba(85, 99, 118, 0.32);
  border-radius: 12px;
  padding: 11px 13px;
  background: rgba(12, 21, 33, 0.6);
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.hero__card:hover {
  border-color: rgba(122, 180, 221, 0.55);
  transform: translateY(-2px);
}

.hero__card strong {
  display: block;
  font-size: 12.5px;
  margin-bottom: 3px;
  color: var(--text);
}

.hero__card span {
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--muted);
}

@media (max-width: 980px) {
  .hero--frontdoor { grid-template-columns: minmax(0, 1fr); }
}

/* The map's honesty line: what it is not showing, and why. Sits below the
   legend rows and quieter than them, because it is context rather than a
   count — but it is present, because a filtered view that does not admit to
   filtering is just a wrong one. */
.cp-ws-legend-note {
  margin: 0.75rem 0 0;
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--cp-text-muted, #8a8aa3);
  border-top: 1px solid var(--cp-border-soft, rgba(255, 255, 255, 0.08));
  padding-top: 0.65rem;
}

/* Cloud posture findings.
   An accepted finding is deliberately NOT styled as resolved — it keeps its
   severity chip at full strength and only gains a marker. The moment an
   exception looks like a fix, the feature has become a way to make a dashboard
   green. */
.cp-ws-finding {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.85rem 1rem;
  border: 1px solid var(--cp-border-soft, rgba(255, 255, 255, 0.08));
  border-radius: 10px;
  margin-top: 0.6rem;
}
.cp-ws-finding.is-accepted {
  /* A dashed edge reads as provisional rather than done. */
  border-style: dashed;
}
.cp-ws-finding__head {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  flex-wrap: wrap;
}
.cp-ws-finding__sev {
  font-size: 0.65rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.15rem 0.45rem;
  border-radius: 4px;
  font-weight: 600;
}
.cp-ws-finding__sev--critical,
.cp-ws-finding__sev--high {
  background: rgba(220, 80, 90, 0.18);
  color: var(--bad);
}
/* `warning` and `info` are the EVENT BUS severity vocabulary, which live
   detections use (info/warning/critical) while scan findings use
   critical/high/medium/low. Both vocabularies render in this badge, so both
   need a rule — without these two, a warning detection fell back to plain body
   text and read as less serious than a low-severity finding beside it. They
   share the medium and low treatments rather than introducing a third palette,
   because the badge's job is severity at a glance, not provenance. */
.cp-ws-finding__sev--medium,
.cp-ws-finding__sev--warning {
  background: rgba(220, 170, 70, 0.16);
  color: var(--warn);
}
.cp-ws-finding__sev--low,
.cp-ws-finding__sev--info {
  background: rgba(120, 140, 190, 0.16);
  color: var(--muted);
}
.cp-ws-finding__title {
  flex: 1 1 18rem;
  font-weight: 600;
}
.cp-ws-finding__provider {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--cp-text-muted, #8a8aa3);
}
.cp-ws-finding__hint,
.cp-ws-finding__accepted {
  margin: 0;
  font-size: 0.8rem;
  line-height: 1.55;
  color: var(--cp-text-muted, #8a8aa3);
}
/* A caption under a view: what the picture means and what it cannot say.
   It had only `font-style: italic`, so it inherited body size — in the mono
   themes, a block of large italic prose under every Kubernetes layout that
   outweighed the picture it was explaining. */
.cp-ws-finding__note {
  margin: 8px 0 0;
  max-width: 110ch;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--muted);
}
.cp-ws-finding__error {
  margin: 0.4rem 0 0;
  font-size: 0.78rem;
  color: var(--bad);
}
.cp-ws-finding__actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  align-items: center;
}
.cp-ws-finding__reason {
  flex: 1 1 16rem;
  min-width: 0;
}
.cp-ws-finding__days {
  width: 5rem;
}
.cp-ws-finding__reason,
.cp-ws-finding__days {
  padding: 0.4rem 0.6rem;
  border-radius: 7px;
  border: 1px solid var(--cp-border-soft, rgba(255, 255, 255, 0.12));
  background: var(--cp-surface-sunken, rgba(0, 0, 0, 0.2));
  color: inherit;
  font: inherit;
  font-size: 0.82rem;
}

/* A template the control plane cannot build.
   Disabled and dimmed, never hidden: a hidden option reads as "the platform
   never supported this", where a visible disabled one with its reason beneath
   reads as "a provider someone can install". The distinction is the whole
   point of showing it at all. */
.cp-choice.is-unavailable {
  opacity: 0.45;
  cursor: not-allowed;
}
.cp-choice.is-unavailable:hover {
  /* Suppress the affordance the enabled state carries — a hover lift on a
     button that cannot be pressed is a lie the pointer tells. */
  transform: none;
  border-color: var(--cp-border-soft, rgba(255, 255, 255, 0.08));
}
.cp-choice.is-unavailable .cp-choice__meta {
  opacity: 1;
}

/* A stale cluster snapshot. The page below it is a stored point-in-time read,
   and pods are rescheduled constantly — an old snapshot names pods that no
   longer exist and shows Running beside them. Warning-toned rather than
   error-toned: the data is not wrong, it is old, and those are different
   claims. */
#cluster-detail-meta.is-stale {
  color: var(--warn, #e8be7c);
}

/* The text half of a list row must be allowed to shrink.
   A flex child defaults to min-width: auto, which refuses to go below its
   content's intrinsic width — so without this the row grows instead of the
   prose wrapping, and the status label beside it gets squeezed off the edge. */
.cp-ws-list__item {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}

.cp-ws-list__item > div {
  min-width: 0;
}

/* ---------------------------------------------------------------------------
   Recovery planning: drag-and-drop trays, with the non-drag controls styled as
   equal citizens rather than as a fallback.

   The visual language deliberately does NOT make the drag targets look like
   the primary path. Every chip and every row is a real button, so it carries
   the same focus ring and the same hover treatment the rest of the console
   uses — somebody working by keyboard should not be able to tell they are on
   the "other" path, because there is no other path.
   --------------------------------------------------------------------------- */

.cp-ws-subhead {
  margin: 1.6rem 0 0.4rem;
  font-size: 0.95rem;
  letter-spacing: 0.02em;
  color: var(--text);
}

.cp-dnd {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 0.9rem;
  margin: 0.7rem 0;
}

.cp-dnd__label {
  margin: 0 0 0.35rem;
  font-size: 0.72rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
}

.cp-dnd__tray {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  min-height: 88px;
  /* Capped and scrolled. A namespace with thirty container images would
     otherwise push the timeline below it off the screen entirely, and the
     three sections of this card are meant to be read together. */
  padding: 0.6rem;
  border: 1px dashed var(--surface-border-strong);
  border-radius: 10px;
  background: var(--surface-soft);
  transition: border-color 140ms ease, background 140ms ease;
}

/* The drop-accepting state is announced by colour AND by the border going
   solid, because a colour-only cue is invisible to a meaningful share of
   readers and this one carries the whole affordance. */
.cp-dnd__tray.is-over {
  border-style: solid;
  border-color: var(--teal);
  background: var(--surface-hover);
}

.cp-dnd__chip,
.cp-dnd__zone,
.cp-dnd__row {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  width: 100%;
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--surface-border);
  border-radius: 8px;
  background: var(--surface-elevated);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: grab;
}

.cp-dnd__row { flex-wrap: wrap; }

.cp-dnd__chip:hover,
.cp-dnd__zone:hover,
.cp-dnd__row:hover {
  border-color: var(--surface-border-strong);
  background: var(--surface-hover);
}

.cp-dnd__chip:focus-visible,
.cp-dnd__zone:focus-visible,
.cp-dnd__row:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 2px;
}

.cp-dnd__chip.is-dragging,
.cp-dnd__row.is-dragging {
  opacity: 0.5;
  cursor: grabbing;
}

.cp-dnd__zone {
  flex-direction: column;
  align-items: flex-start;
  gap: 0.2rem;
  min-height: 56px;
  cursor: pointer;
}

.cp-dnd__zone-name { font-weight: 600; }

.cp-dnd__zone-hint {
  font-size: 0.74rem;
  color: var(--muted);
}

.cp-dnd__row-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cp-dnd__row-class {
  flex: 0 0 auto;
  font-size: 0.72rem;
  letter-spacing: 0.05em;
  color: var(--muted);
  white-space: nowrap;
}

/* The reason an override was set, shown on the row itself. A component quietly
   excluded from a gap count with its justification hidden behind a click is
   how a true-looking report starts lying. */
.cp-dnd__row-why {
  flex: 1 1 100%;
  font-size: 0.74rem;
  color: var(--muted);
}

.cp-dnd__move {
  flex: 0 0 auto;
  margin-left: auto;
  padding: 0.25rem 0.55rem;
  font-size: 0.74rem;
  white-space: nowrap;
}

.cp-dnd__reason {
  margin: 0.7rem 0;
  padding: 0.8rem;
  border: 1px solid var(--teal);
  border-radius: 10px;
  background: var(--surface-soft);
}

.cp-scrub {
  flex: 1 1 220px;
  min-width: 160px;
  accent-color: var(--teal);
}

.cp-scrub:disabled { opacity: 0.4; }

@media (prefers-reduced-motion: reduce) {
  .cp-dnd__tray { transition: none; }
}

/* ---------------------------------------------------------------------------
   Coverage map: globe, table, tabbed detail.

   The state colours are COVERAGE colours, not severity colours. Red here means
   "we could not look", which is a different alarm from "we looked and found
   something bad" — so they are defined separately from the finding severities
   rather than reusing them and quietly conflating the two.
   --------------------------------------------------------------------------- */

.cp-viewswitch {
  display: flex;
  gap: 0.4rem;
  margin: 0.7rem 0 0.35rem;
}

.cp-viewswitch .btn.is-active {
  border-color: var(--teal);
  color: var(--text);
  background: var(--surface-active);
}

/* The coverage bar: proportion of the estate whose silence can be trusted. */
.cp-cov {
  display: flex;
  overflow: hidden;
  width: 100%;
  height: 8px;
  margin: 0.5rem 0 0.6rem;
  border: 1px solid var(--surface-border);
  border-radius: 999px;
  background: var(--surface-sunken, rgba(0, 0, 0, 0.25));
}

.cp-cov__seg { height: 100%; }
.cp-cov__seg--watched         { background: var(--teal); }
.cp-cov__seg--clean           { background: rgba(119, 201, 203, 0.45); }
.cp-cov__seg--stale           { background: #e0b978; }
.cp-cov__seg--failing         { background: var(--danger); }
/* Never-polled is drawn as a HATCH, not a flat colour: it is an absence of
   information, and a solid block reads as a measured quantity. */
.cp-cov__seg--never_attempted {
  background: repeating-linear-gradient(
    45deg, rgba(154, 167, 189, 0.55) 0 4px, transparent 4px 8px);
}

.cp-globe {
  position: relative;
  width: 100%;
  min-height: 620px;
}

.cp-globe canvas {
  display: block;
  width: 100%;
  height: 620px;
  cursor: grab;
  touch-action: none;
}

.cp-globe canvas:active { cursor: grabbing; }

.cp-covrow { cursor: pointer; }
.cp-covrow:hover { background: var(--surface-hover); }
.cp-covrow.is-selected { background: var(--surface-active); }
.cp-covrow:focus-visible { outline: 2px solid var(--teal); outline-offset: -2px; }

.cp-pill {
  display: inline-block;
  padding: 0.12rem 0.5rem;
  border: 1px solid currentColor;
  border-radius: 999px;
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
}

.cp-pill--watched, .cp-pill--clean { color: var(--teal); }
.cp-pill--stale                    { color: var(--warn); }
.cp-pill--failing                  { color: var(--danger); }
.cp-pill--never_attempted          { color: var(--muted); border-style: dashed; }

/* Tabbed detail — progressive disclosure. The verdict is always the landing
   tab, so the panel answers the question before it offers the evidence. */
.cp-tabs {
  display: flex;
  gap: 0.2rem;
  margin: 0 0 0.6rem;
  border-bottom: 1px solid var(--surface-border);
}

.cp-tab {
  padding: 0.35rem 0.7rem;
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: 0.78rem;
  cursor: pointer;
}

.cp-tab:hover { color: var(--text); }
.cp-tab.is-active { border-bottom-color: var(--teal); color: var(--text); }
.cp-tab:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }

.cp-unplaced {
  display: block;
  width: 100%;
  border: 1px solid var(--surface-border);
  background: var(--surface-elevated);
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.cp-unplaced:hover { background: var(--surface-hover); }
.cp-unplaced:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  .cp-globe canvas { cursor: default; }
}

/* Globe and table views: canvas left, legend and detail stacked in a right
   rail.

   Grid places items in DOM ORDER, so simply hiding the graph's legend did not
   widen the canvas — it slid the canvas into the fixed-width track the legend
   had vacated and made it NARROWER than before. The columns are therefore
   assigned explicitly rather than inferred from what happens to be visible. */
.cp-ws-topology-layout:has(#topology-legend-card[hidden]) {
  grid-template-columns: minmax(0, 1fr) 300px;
}

.cp-ws-topology-layout:has(#topology-legend-card[hidden]) > .cp-ws-topology-card {
  grid-column: 1;
  grid-row: 1 / span 2;
  /* Spanning two rows stretches the card to the height of BOTH cards in the
     right rail, which leaves a block of empty panel under a fixed-height
     canvas. It should be as tall as what it contains. */
  align-self: start;
}

.cp-ws-topology-layout:has(#topology-legend-card[hidden]) > #coverage-legend-card,
.cp-ws-topology-layout:has(#topology-legend-card[hidden]) > #coverage-detail {
  grid-column: 2;
}

.cp-covlegend p {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  margin: 0 0 0.7rem;
  color: var(--muted);
  font-size: 0.78rem;
  line-height: 1.45;
}

.cp-covlegend .cp-pill { align-self: flex-start; }

/* The graph's zoom/fit/reset controls are display:flex from their own class,
   which outranks the [hidden] attribute's display:none — so hiding them in
   globe and table view did nothing and they floated over the planet offering
   buttons that do not apply. */
.cp-ws-topology-controls[hidden] { display: none !important; }

/* [hidden] is only a default `display: none`, so ANY element with its own
   display rule ignores it. Three elements on the Map panel set their own —
   the SVG graph, the controls, and the flex trays — which is why hiding the
   graph left it rendering underneath the globe. Stated once, for every view
   this panel switches between, rather than patched per element as each one is
   noticed. */
#topology-graph[hidden],
#obs-view-globe[hidden],
#obs-view-table[hidden],
#topology-legend-card[hidden],
#coverage-legend-card[hidden],
#topology-detail[hidden],
#coverage-detail[hidden] {
  display: none !important;
}

/* Globe controls. The bar sits above the canvas rather than floating over it:
   controls overlaying a draggable surface steal the drag the moment the
   pointer crosses them. */
.cp-globebar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.5rem;
}

.cp-provfilter,
.cp-globenav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  align-items: center;
}

.cp-provfilter .btn,
.cp-globenav .btn {
  padding: 0.25rem 0.6rem;
  font-size: 0.75rem;
}

.cp-provfilter .btn.is-active,
.cp-globenav .btn.is-active {
  border-color: var(--teal);
  color: var(--text);
  background: var(--surface-active);
}

.cp-globetoggle {
  display: inline-flex;
  gap: 0.35rem;
  align-items: center;
  color: var(--muted);
  font-size: 0.73rem;
  cursor: pointer;
}

.cp-globetoggle input { accent-color: var(--teal); }

#globe-note {
  margin-top: 0.5rem;
}

/* Globe controls, floated over the canvas.

   Stacked ABOVE the canvas they scrolled off the top of the panel the moment
   anyone scrolled down to look at the map, leaving a globe with no visible
   zoom. Floated, they are always reachable — and the container is
   pointer-events:none so dragging the planet still works everywhere except
   directly on a control. */
.cp-globebar {
  position: absolute;
  z-index: 3;
  top: 0.6rem;
  right: 0.6rem;
  left: 0.6rem;
  display: flex;
  gap: 0.5rem;
  align-items: flex-start;
  justify-content: space-between;
  pointer-events: none;
}

.cp-globenav {
  display: flex;
  gap: 0.3rem;
  align-items: center;
  padding: 0.25rem;
  border: 1px solid var(--surface-border);
  border-radius: 10px;
  background: color-mix(in srgb, var(--panel-solid) 82%, transparent);
  pointer-events: auto;
}

/* The zoom column is pinned to the right EDGE and vertically centred, not
   placed in the top row. In the row it sat over the middle of the canvas and
   covered the region marker — the one thing the map exists to show. */
.cp-globenav--zoom {
  position: absolute;
  z-index: 3;
  top: 50%;
  right: 0.6rem;
  flex-direction: column;
  gap: 0.35rem;
  transform: translateY(-50%);
}

.cp-globenav--frame { flex-wrap: wrap; max-width: 46%; }

.cp-globenav .btn {
  padding: 0.2rem 0.5rem;
  font-size: 0.74rem;
}

.cp-globenav .btn.is-active {
  border-color: var(--teal);
  color: var(--text);
  background: var(--surface-active);
}

.cp-zoombtn {
  width: 26px;
  padding: 0.15rem 0 !important;
  font-size: 0.9rem !important;
  line-height: 1;
}

/* A vertical slider so zoom reads as a height, next to + above and − below. */
.cp-zoomrange {
  width: 20px;
  height: 108px;
  accent-color: var(--teal);
  writing-mode: vertical-lr;
  direction: rtl;
  cursor: ns-resize;
}

.cp-zoomlabel {
  color: var(--muted);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.66rem;
  font-variant-numeric: tabular-nums;
}

.cp-globe { position: relative; }

/* The remedy block. Visually separated from the verdict because it is a
   different kind of statement — the verdict is what is true, this is what to
   do about it. */
.cp-remedy {
  margin: 0.7rem 0 0;
  padding: 0.7rem;
  border: 1px solid rgba(119, 201, 203, 0.35);
  border-left: 3px solid var(--teal);
  border-radius: 8px;
  background: rgba(119, 201, 203, 0.05);
}

.cp-remedy .cp-ws-copy { margin: 0 0 0.5rem; }

/* ---------------------------------------------------------------------------
   Map panel: brought back to the house card shape.

   The header card had grown to kicker + title + headline + bar + a paragraph +
   chips + a paragraph + switcher + a paragraph + insights, which filled the
   whole viewport and pushed the map itself entirely below the fold. Every other
   pillar is kicker → title → ONE line of copy → controls → results, and this
   one now matches: the explanation moved into a disclosure and the insights
   moved to their own card.
   --------------------------------------------------------------------------- */

/* A label in front of a control row, so a row of chips reads as an answer to a
   question rather than as a floating set of buttons. */
/* Provider and View sit side by side on a wide card and stack only when they
   genuinely do not fit.

   Scoped to the Map panel. Unscoped, this changed EVERY chipline in the console
   from block to inline-flex — a layout change on panels that were never looked
   at, which is exactly the app-wide breakage a bare `.cp-ws-card >` selector
   invites. */
@media (min-width: 900px) {
  #panel-map .cp-ws-card > .cp-ws-chipline {
    display: inline-flex;
    margin-right: 1.2rem;
  }
}

.cp-ws-chipline__label {
  align-self: center;
  min-width: 62px;
  color: var(--muted);
  font-size: 0.68rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

/* Collapsed explanation. Native <details>, so it opens with JS broken — the
   same reasoning as the sidebar pillars. */
.cp-ws-note {
  margin-top: 0.7rem;
  border-top: 1px solid var(--surface-border);
  padding-top: 0.6rem;
}

.cp-ws-note > summary {
  color: var(--muted);
  cursor: pointer;
  font-size: 0.76rem;
  list-style: none;
}

.cp-ws-note > summary::-webkit-details-marker { display: none; }

.cp-ws-note > summary::before {
  content: "▸ ";
  display: inline-block;
  transition: transform 120ms ease;
}

.cp-ws-note[open] > summary::before { content: "▾ "; }
.cp-ws-note > summary:hover { color: var(--text); }
.cp-ws-note > summary:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }
.cp-ws-note > .cp-ws-copy { margin-top: 0.5rem; }

/* The map is the content, so it gets the height the prose was taking. */
.cp-globe { min-height: 560px; }
.cp-globe canvas { height: 560px; }

@media (prefers-reduced-motion: reduce) {
  .cp-ws-note > summary::before { transition: none; }
}

/* The Map header and its attention list share the top row: the header carries
   the coverage verdict and the controls, the attention card is a two-line
   summary, and stacking them pushed the map itself another 260px down. */
.cp-ws-grid--maphead {
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  /* Cards size to their own content. Stretched to match the tallest sibling,
     the header grew 60px of empty panel below its controls. */
  align-items: start;
}

@media (max-width: 1100px) {
  .cp-ws-grid--maphead { grid-template-columns: 1fr; }
}

/* Shown over the globe when a filter leaves nothing placeable. Without it an
   empty planet reads identically whether a provider has no regions or has
   regions whose names cannot be resolved to a location — and the second case
   is the interesting one. */
.cp-globeempty {
  position: absolute;
  z-index: 2;
  top: 50%;
  left: 50%;
  width: min(440px, 82%);
  padding: 0.9rem;
  transform: translate(-50%, -50%);
  border: 1px solid rgba(255, 136, 163, 0.4);
  border-radius: 10px;
  background: color-mix(in srgb, var(--panel-solid) 94%, transparent);
}

.cp-globeempty .cp-unplaced { margin-top: 0.5rem; }

.cp-acctfilter {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  align-items: center;
}

.cp-acctfilter .btn {
  padding: 0.25rem 0.6rem;
  font-size: 0.75rem;
}

.cp-acctfilter .btn.is-active {
  border-color: var(--teal);
  color: var(--text);
  background: var(--surface-active);
}

/* ---------------------------------------------------------------------------
   Two app shells, switchable live.

   `window` is the original: a desktop-window frame with traffic lights. It is
   what the win95 theme is built on, so it stays.

   `flush` removes the mimicry. The frame becomes a status bar carrying real
   state — where you are, which org, and how much of the estate is actually
   watched. The traffic lights are inert decoration and are HIDDEN rather than
   restyled: a control that looks like a control and does nothing is worse than
   no control.
   --------------------------------------------------------------------------- */

.chrome__status,
.chrome__shelltoggle { display: none; }

.chrome__shelltoggle {
  margin-left: auto;
  padding: 0.15rem 0.55rem;
  border: 1px solid var(--surface-border);
  border-radius: 6px;
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
}

.chrome__shelltoggle:hover { color: var(--text); border-color: var(--surface-border-strong); }
.chrome__shelltoggle:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }

/* The toggle is present in BOTH shells, so the choice is reversible from
   wherever you are. */
.chrome .chrome__shelltoggle { display: inline-block; }

body[data-shell="flush"] .cp-ws { padding: 0; }

body[data-shell="flush"] .cp-ws-shell {
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

body[data-shell="flush"] .chrome__lights,
body[data-shell="flush"] .chrome__title { display: none; }

/* win95 is deliberately a desktop-window pastiche, so it keeps the frame even
   when the flush shell is selected — the theme IS the window. */
body[data-theme="win95"] .chrome__lights,
body[data-theme="win95"] .chrome__title { display: flex; }
body[data-theme="win95"] .chrome__title { display: block; }
body[data-theme="win95"] .chrome__status { display: none; }

body[data-shell="flush"] .chrome__status {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.74rem;
}

body[data-shell="flush"] .chrome {
  gap: 0.6rem;
  border-bottom: 1px solid var(--surface-border);
  background: var(--surface-strong);
}

.chrome__crumb { color: var(--text); }
.chrome__sep,
.chrome__org { color: var(--muted); }

/* Live coverage in the shell itself: the one number that decides whether
   anything else on screen can be trusted, visible from every panel. */
.chrome__coverage {
  padding: 0.1rem 0.5rem;
  border: 1px solid currentColor;
  border-radius: 999px;
  font-size: 0.68rem;
}

.chrome__coverage--ok { color: var(--teal); }
.chrome__coverage--warn { color: var(--danger); }

/* [hidden] loses to the class's own display:flex — the same conflict that left
   the graph controls floating over the globe. Stated for the control groups
   too, so hiding zoom in the field view (which has no geography to zoom) is
   not a silent no-op. */
.cp-globenav[hidden] { display: none !important; }

/* Alternate cluster layouts — the four views beside the ring.

   They render into their OWN svg (#cluster-layouts) so nothing here can
   disturb renderLivingCluster, which owns #cluster-living. [hidden] is stated
   explicitly because .cp-living-svg sets its own display. */
#cluster-living[hidden],
#cluster-layouts[hidden] { display: none !important; }

.cp-layoutswitch {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin-bottom: 0.6rem;
}

.cp-layoutswitch .btn {
  padding: 0.25rem 0.7rem;
  font-size: 0.75rem;
}

.cp-layoutswitch .btn.is-active {
  border-color: var(--teal);
  color: var(--text);
  background: var(--surface-active);
}

/* The isometric floor plates. Deliberately fainter than a namespace cell:
   a floor is where pods stand, not a thing in its own right. */
.cp-layout-plane {
  fill: color-mix(in srgb, var(--cyan) 7%, transparent);
  stroke: color-mix(in srgb, var(--cyan) 30%, transparent);
  stroke-width: 1;
}

.cp-layout-tick {
  fill: var(--muted);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10px;
}

#cluster-layout-note {
  margin: 0.5rem 0 0;
  min-height: 1.2rem;
}

/* ---------------------------------------------------------------------------
   Coverage views that are not maps.

   Rendered into #coverage-panel, their own SVG, so nothing here can disturb
   the canvas renderer. State colours are COVERAGE colours — red means "we
   could not look", not "we looked and found something bad".
   --------------------------------------------------------------------------- */

#obs-view-svg[hidden] { display: none !important; }

#coverage-panel {
  display: block;
  width: 100%;
  height: 560px;
}

.cv-watched { fill: var(--teal); stroke: var(--teal); }
.cv-stale   { fill: #e0b978; stroke: #e0b978; }
.cv-failing { fill: var(--danger); stroke: var(--danger); }
.cv-never   { fill: none; stroke: #9aa7bd; stroke-dasharray: 3 3; }

.cv-lbl    { fill: var(--muted); font-size: 12px; }
.cv-lbl-sm { fill: #6a7d96; font-size: 10.5px; }
.cv-lbl-lg { fill: var(--text); font-size: 14px; font-weight: 600; }
.cv-huge   { fill: var(--text); font-size: 54px; font-weight: 600; }
.cv-band   { fill: #6a7d96; font-size: 10px; letter-spacing: 0.14em; }
.cv-warn   { fill: #e0b978; font-size: 10px; }

#coverage-panel text {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.cv-card {
  fill: rgba(119, 201, 203, 0.06);
  stroke: rgba(119, 201, 203, 0.4);
}

.cv-card--hot {
  fill: rgba(255, 136, 163, 0.07);
  stroke: rgba(255, 136, 163, 0.42);
}

.cv-grid { stroke: rgba(120, 160, 200, 0.13); fill: none; }

/* A region nobody has ever polled. Dashed and empty on purpose: it is the
   absence of evidence, and a solid bar would read as measured. */
.cv-void {
  stroke: #9aa7bd;
  stroke-dasharray: 4 6;
  opacity: 0.5;
  fill: none;
}

.cv-bar { fill-opacity: 0.55; stroke: none; }
.cv-bar-fail { fill: rgba(255, 136, 163, 0.12); stroke: rgba(255, 136, 163, 0.5); }
/* Time since the last success. Hatched rather than coloured — it is a hole in
   the record, not a measured state. */
.cv-bar-gap { fill: rgba(154, 167, 189, 0.10); stroke: rgba(154, 167, 189, 0.28); }

.cv-track { fill: none; stroke: rgba(120, 160, 200, 0.18); stroke-width: 32; }
.cv-arc   { fill: none; stroke: var(--teal); stroke-width: 32; }
.cv-chip  { fill-opacity: 0.75; }
.cv-dot   { fill-opacity: 0.85; }

.cv-cell {
  fill: rgba(255, 255, 255, 0.02);
  stroke: rgba(120, 160, 200, 0.3);
}

.cv-cell--empty {
  fill: transparent;
  stroke: rgba(120, 160, 200, 0.1);
  stroke-dasharray: 3 4;
}

/* Depth on the topology tree. The glyphs sit on the panel rather than being
   painted onto it — a soft drop shadow and a lit top edge, which is what makes
   a flat SVG read as objects with a surface. */
.cp-cluster-minimap circle.cp-minimap-node,
.cp-cluster-minimap rect.cp-minimap-node {
  filter: drop-shadow(0 3px 5px rgba(2, 8, 16, 0.65));
}

.cp-cluster-minimap .cp-minimap-node--alive {
  filter: drop-shadow(0 0 8px color-mix(in srgb, var(--teal) 55%, transparent))
          drop-shadow(0 3px 5px rgba(2, 8, 16, 0.65));
}

.cp-cluster-minimap .cp-minimap-node--clickable { cursor: pointer; }

.cp-cluster-minimap .cp-minimap-node--clickable:hover {
  filter: drop-shadow(0 0 9px color-mix(in srgb, var(--cyan) 65%, transparent))
          drop-shadow(0 3px 5px rgba(2, 8, 16, 0.65));
}

@media (prefers-reduced-motion: reduce) {
  .cp-cluster-minimap circle.cp-minimap-node,
  .cp-cluster-minimap rect.cp-minimap-node { filter: none; }
}

/* The tree scales to its frame, so its type is sized in viewBox units that
   survive that scaling. Labels at the old size rendered at ~62% and became
   unreadable the moment a cluster had more than a few namespaces. */
.cp-cluster-minimap text {
  font-size: 15px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* ── Hygiene panel ─────────────────────────────────────────────────────────
   Retention classes, protected classes, and per-repository automation.

   The bars are information, not decoration: each fill is a class's retention
   window against the longest configured one, so two policies can be compared
   without reading and subtracting two numbers. */

.cp-hyg-classes {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  margin-top: 0.75rem;
}

.cp-hyg-class {
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--cp-border, rgba(148, 163, 184, 0.22));
  border-radius: 10px;
  /* Transparent rather than unset: the sweep pulse animates this property,
     and animating from `unset` produces no transition in some engines. */
  background-color: rgba(0, 0, 0, 0);
}

.cp-hyg-class__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
}

.cp-hyg-class__name {
  font-weight: 600;
  text-transform: capitalize;
}

.cp-hyg-class__value {
  font-variant-numeric: tabular-nums;
  font-size: 0.85rem;
  opacity: 0.85;
}

.cp-hyg-bar {
  margin-top: 0.45rem;
  height: 6px;
  border-radius: 999px;
  background: rgba(148, 163, 184, 0.18);
  overflow: hidden;
}

.cp-hyg-bar__fill {
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: linear-gradient(90deg, rgba(56, 189, 248, 0.85), rgba(45, 212, 191, 0.85));
}

/* A class with no policy gets a muted bar. It is at zero width anyway; the
   colour change is what says "kept forever" rather than "very short". */
.cp-hyg-class:not(.is-on) .cp-hyg-bar__fill {
  background: rgba(148, 163, 184, 0.4);
}

.cp-hyg-class__desc,
.cp-hyg-class__meta {
  margin: 0.4rem 0 0;
  font-size: 0.8rem;
  opacity: 0.75;
}

/* "Configured but never swept" is a real and dangerous state — the policy looks
   active and nothing has enforced it. It gets the warning colour. */
.cp-hyg-class__meta--warn {
  color: var(--cp-warn, #f59e0b);
  opacity: 1;
}

.cp-hyg-subhead {
  margin-top: 1.4rem;
}

.cp-hyg-protected {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin-top: 0.75rem;
}

.cp-hyg-protected__row {
  padding-left: 0.75rem;
  border-left: 3px solid var(--cp-accent, #38bdf8);
}

.cp-hyg-protected__name {
  font-weight: 600;
  text-transform: capitalize;
}

.cp-hyg-protected__why {
  margin: 0.2rem 0 0;
  font-size: 0.8rem;
  opacity: 0.75;
}

.cp-hyg-repos {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin-top: 0.75rem;
}

.cp-hyg-repo {
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--cp-border, rgba(148, 163, 184, 0.22));
  border-radius: 10px;
}

.cp-hyg-repo__name {
  font-weight: 600;
  font-family: var(--cp-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 0.9rem;
}

.cp-hyg-repo__flags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.5rem;
}

.cp-hyg-flag {
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  font-size: 0.72rem;
  letter-spacing: 0.02em;
  border: 1px solid rgba(148, 163, 184, 0.3);
  opacity: 0.6;
}

.cp-hyg-flag.is-on {
  opacity: 1;
  border-color: rgba(45, 212, 191, 0.5);
  background: rgba(45, 212, 191, 0.12);
}

/* AI switches get their own colour when on. Repository content leaving the
   boundary is a different kind of fact from a scan running locally, and the
   panel should not render them identically. */
.cp-hyg-flag--ai.is-on {
  border-color: rgba(168, 85, 247, 0.55);
  background: rgba(168, 85, 247, 0.14);
}

@media (prefers-reduced-motion: reduce) {
  /* The JS already skips its animations; this catches any CSS transition that
     might be added to these elements later. */
  .cp-hyg-bar__fill,
  .cp-hyg-class {
    transition: none !important;
  }
}

/* ── Status page ───────────────────────────────────────────────────────────
   The visual design has one job above all: `unknown` must not LOOK
   reassuring. A grey dot beside a service name reads as neutral, and neutral
   reads as fine — which would undo the whole point of tracking whether
   anything actually checked. */

.status-title { margin-bottom: 1.2rem; }

.status-dot--degraded { background: #f59e0b; box-shadow: 0 0 0 4px rgba(245, 158, 11, 0.18); }
.status-dot--outage   { background: #ef4444; box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.18); }
.status-dot--maintenance { background: #6366f1; box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.18); }

/* Unknown is HATCHED and drifting, not a flat grey.
   Flat grey is ignorable and reads as neutral; a moving hatch reads as
   "missing data", which is what it is. */
.status-dot--unknown {
  background: repeating-linear-gradient(
    45deg, #9ca3af, #9ca3af 2px, #4b5563 2px, #4b5563 4px
  );
  background-size: 200% 200%;
  animation: status-drift 3s linear infinite;
  box-shadow: 0 0 0 4px rgba(156, 163, 175, 0.2);
}

@keyframes status-drift {
  from { background-position: 0 0; }
  to   { background-position: 8px 8px; }
}

.status-banner__note { margin: 0.35rem 0 0; font-size: 0.9rem; opacity: 0.85; }

.status-components { display: flex; flex-direction: column; gap: 0.75rem; margin-bottom: 2rem; }
.status-group { margin: 1rem 0 0.25rem; font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.06em; opacity: 0.6; }

.status-component {
  border: 1px solid var(--surface-border, rgba(148, 163, 184, 0.22));
  border-left-width: 3px;
  border-radius: 12px;
  padding: 0.85rem 1rem;
}
.status-component--operational { border-left-color: #2eb67d; }
.status-component--degraded    { border-left-color: #f59e0b; }
.status-component--outage      { border-left-color: #ef4444; }
.status-component--maintenance { border-left-color: #6366f1; }
/* The same hatch as the dot, so unknown is recognisable at both scales. */
.status-component--unknown {
  border-left-color: transparent;
  border-left-style: dashed;
  border-left-color: #9ca3af;
}

.status-component__head { display: flex; justify-content: space-between; align-items: center; gap: 1rem; }
.status-component__name { font-weight: 600; }
.status-component__reason { margin: 0.4rem 0 0; font-size: 0.85rem; opacity: 0.85; }
.status-component__meta { margin: 0.3rem 0 0; font-size: 0.78rem; opacity: 0.65; }

.status-pill {
  padding: 0.12rem 0.55rem; border-radius: 999px;
  font-size: 0.72rem; letter-spacing: 0.03em; text-transform: uppercase;
  border: 1px solid currentColor;
}
.status-pill--operational { color: var(--ok); }
.status-pill--degraded    { color: var(--warn); }
.status-pill--outage      { color: #ef4444; }
.status-pill--maintenance { color: #6366f1; }
.status-pill--unknown     { color: var(--muted); }

/* Latency bars: scaled to the max, so p50 against p99 is a SHAPE rather than
   two numbers the reader has to subtract. */
.status-latency, .status-availability { margin-top: 0.75rem; }
.status-latency__title, .status-phases__title {
  margin: 0 0 0.4rem; font-size: 0.78rem; text-transform: uppercase;
  letter-spacing: 0.05em; opacity: 0.6;
}
.status-bar { display: grid; grid-template-columns: 3rem 1fr 4.5rem; align-items: center; gap: 0.5rem; margin-bottom: 0.3rem; }
.status-bar__label { font-size: 0.75rem; opacity: 0.7; }
.status-bar__track { height: 6px; border-radius: 999px; background: rgba(148, 163, 184, 0.18); overflow: hidden; }
.status-bar__fill { height: 100%; width: 0; border-radius: 999px; background: linear-gradient(90deg, #38bdf8, #2dd4bf); }
.status-bar__fill--coverage { background: linear-gradient(90deg, #a78bfa, #38bdf8); }
.status-bar__value { font-size: 0.75rem; text-align: right; font-variant-numeric: tabular-nums; opacity: 0.85; }

.status-latency__meta { margin: 0.35rem 0 0; font-size: 0.75rem; opacity: 0.6; }
/* The percentiles DevEx Lattice refused to invent, said out loud. An absent p99 with
   no explanation reads as a bug. */
.status-latency__omitted { margin: 0.25rem 0 0; font-size: 0.73rem; opacity: 0.55; font-style: italic; }

/* The stacked phase bar. "Slow" is four different problems with four different
   owners, and this is the element that says which. */
.status-phases { margin-top: 0.7rem; }
.status-phases__bar { display: flex; height: 10px; border-radius: 999px; overflow: hidden; background: rgba(148, 163, 184, 0.15); }
.status-phases__seg { height: 100%; width: 0; }
.status-phases__seg--dns,     .status-phases__swatch--dns     { background: #f472b6; }
.status-phases__seg--connect, .status-phases__swatch--connect { background: #fbbf24; }
.status-phases__seg--tls,     .status-phases__swatch--tls     { background: #34d399; }
.status-phases__seg--server,  .status-phases__swatch--server  { background: #60a5fa; }
.status-phases__legend { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 0.4rem; font-size: 0.72rem; opacity: 0.75; }
.status-phases__key { display: inline-flex; align-items: center; gap: 0.3rem; }
.status-phases__swatch { width: 8px; height: 8px; border-radius: 2px; display: inline-block; }

.status-availability__headline { display: flex; align-items: baseline; gap: 0.6rem; }
.status-availability__percent { font-size: 1.35rem; font-weight: 650; font-variant-numeric: tabular-nums; }
.status-availability__window { font-size: 0.78rem; opacity: 0.65; }
.status-availability__none { margin: 0; font-size: 0.82rem; opacity: 0.8; }
.status-coverage { display: grid; grid-template-columns: 8rem 1fr 3rem; align-items: center; gap: 0.5rem; margin-top: 0.5rem; }
.status-coverage__label { font-size: 0.75rem; opacity: 0.7; }

.status-confidence { margin: 0.4rem 0 0; font-size: 0.78rem; }
.status-confidence--high   { opacity: 0.65; }
.status-confidence--medium { color: var(--warn); }
/* Low and none are the states that change how the number should be read, so
   they are the ones that get colour. */
.status-confidence--low, .status-confidence--none { color: #ef4444; }

.status-honesty {
  margin-top: 2.5rem; padding-top: 1rem;
  border-top: 1px solid var(--surface-border, rgba(148, 163, 184, 0.22));
  font-size: 0.8rem; opacity: 0.7; max-width: 46ch;
}

@media (prefers-reduced-motion: reduce) {
  /* Every animation is a SECOND encoding of something already stated in text,
     so removing them costs no information. */
  .status-dot--unknown { animation: none; }
  .status-bar__fill, .status-phases__seg { transition: none !important; }
}

.status-incident {
  border: 1px solid var(--surface-border, rgba(148, 163, 184, 0.22));
  border-left: 3px solid #ef4444;
  border-radius: 12px;
  padding: 0.85rem 1rem;
  margin-bottom: 0.6rem;
}
.status-incident__title { margin: 0; font-weight: 600; }

/* The history strip. A bucket where no probe ran is neither healthy nor failed,
   and it gets its own hatched segment — drawing only the buckets that HAVE data
   would compress the gaps out and leave ninety green segments with the outage
   missing. */
.status-history { margin-top: 0.7rem; }
.status-history__strip { display: flex; gap: 1px; height: 22px; border-radius: 4px; overflow: hidden; }
.status-history__seg { flex: 1 1 0; min-width: 1px; border-radius: 1px; }
.status-history__seg--operational { background: #2eb67d; }
.status-history__seg--degraded    { background: #f59e0b; }
.status-history__seg--outage      { background: #ef4444; }
.status-history__seg--maintenance { background: #6366f1; }
/* The same hatch as the unknown dot, so "no data" is recognisable everywhere
   it appears. Deliberately not a pale green or a soft grey — both read as fine. */
.status-history__seg--unknown {
  background: repeating-linear-gradient(45deg, #4b5563, #4b5563 2px, #1f2937 2px, #1f2937 4px);
}
.status-history__caption { margin: 0.3rem 0 0; font-size: 0.72rem; opacity: 0.6; }

/* ── Status page operator panel ───────────────────────────────────────────── */
.cp-sp-form { display: flex; flex-direction: column; gap: 0.35rem; margin-top: 0.75rem; }
.cp-sp-label { margin: 0.5rem 0 0; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.05em; opacity: 0.6; }
.cp-sp-input {
  padding: 0.45rem 0.6rem; border-radius: 8px;
  border: 1px solid var(--cp-border, rgba(148, 163, 184, 0.28));
  background: transparent; color: inherit; font: inherit;
}
.cp-sp-note { margin: 0.25rem 0 0; font-size: 0.78rem; opacity: 0.7; }
/* Public visibility and an unchecked component are the two configuration
   states with a consequence somebody should see BEFORE saving, not after. */
.cp-sp-note--warn { color: var(--cp-warn, #f59e0b); opacity: 1; }

.cp-sp-components, .cp-sp-baselines { display: flex; flex-direction: column; gap: 0.6rem; margin-top: 0.75rem; }
.cp-sp-component, .cp-sp-baseline {
  padding: 0.6rem 0.7rem; border-radius: 10px;
  border: 1px solid var(--cp-border, rgba(148, 163, 184, 0.22));
  border-left-width: 3px;
}
.cp-sp-component--operational { border-left-color: #2eb67d; }
.cp-sp-component--degraded    { border-left-color: #f59e0b; }
.cp-sp-component--outage      { border-left-color: #ef4444; }
.cp-sp-component--maintenance { border-left-color: #6366f1; }
.cp-sp-component--unknown     { border-left-color: #9ca3af; border-left-style: dashed; }
.cp-sp-component__head { display: flex; justify-content: space-between; align-items: center; gap: 1rem; }
.cp-sp-component__name, .cp-sp-baseline__name { font-weight: 600; }

/* ── Access panel ─────────────────────────────────────────────────────────
   The rendering has one job beyond looking tidy: keep "I hold this org-wide"
   visually distinct from "I hold this over these two resources". Collapsing
   them hides the reason a list looks short, which is the single most common
   confusion the team model creates. */

.cp-acc-identity { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 0.75rem; }
.cp-acc-identity__name { font-weight: 650; }
.cp-acc-role {
  padding: 0.12rem 0.55rem; border-radius: 999px; font-size: 0.72rem;
  border: 1px solid rgba(56, 189, 248, 0.5); background: rgba(56, 189, 248, 0.12);
}

.cp-acc-heading {
  margin: 1rem 0 0.35rem; font-size: 0.74rem; text-transform: uppercase;
  letter-spacing: 0.06em; opacity: 0.6;
}
.cp-acc-note { margin: 0.25rem 0 0; font-size: 0.8rem; opacity: 0.75; }
.cp-acc-note--warn { color: var(--cp-warn, #f59e0b); opacity: 1; }

.cp-acc-chips { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.cp-acc-chip {
  padding: 0.12rem 0.5rem; border-radius: 6px; font-size: 0.73rem;
  border: 1px solid rgba(148, 163, 184, 0.3);
  font-family: var(--cp-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
}
/* Org-wide infrastructure permissions mean EVERY resource of that kind. They
   should not look like an ordinary chip. */
.cp-acc-chip--wide { border-color: rgba(56, 189, 248, 0.55); background: rgba(56, 189, 248, 0.1); }
.cp-acc-chip--team { border-color: rgba(45, 212, 191, 0.5); background: rgba(45, 212, 191, 0.12); }

.cp-acc-grant {
  display: grid; grid-template-columns: 8rem 1fr auto; gap: 0.6rem;
  align-items: baseline; padding: 0.35rem 0;
  border-bottom: 1px solid rgba(148, 163, 184, 0.14);
  font-size: 0.82rem;
}
.cp-acc-grant__kind { opacity: 0.6; }
.cp-acc-grant__id { font-family: var(--cp-mono, ui-monospace, monospace); }
.cp-acc-grant__perms { opacity: 0.7; font-size: 0.75rem; }

.cp-acc-teams { display: flex; flex-direction: column; gap: 0.6rem; margin-top: 0.75rem; }
.cp-acc-team {
  padding: 0.65rem 0.75rem; border-radius: 10px;
  border: 1px solid var(--cp-border, rgba(148, 163, 184, 0.22));
  border-left: 3px solid rgba(45, 212, 191, 0.6);
}
.cp-acc-team__head { display: flex; align-items: baseline; gap: 0.5rem; }
.cp-acc-team__name { font-weight: 600; }
.cp-acc-team__slug {
  font-size: 0.75rem; opacity: 0.55;
  font-family: var(--cp-mono, ui-monospace, monospace);
}

.cp-acc-code {
  display: inline-block; padding: 0.2rem 0.5rem; border-radius: 6px;
  background: rgba(148, 163, 184, 0.14);
  font-family: var(--cp-mono, ui-monospace, monospace); font-size: 0.8rem;
}
.cp-acc-mappings { margin-top: 1rem; }
.cp-acc-mapping {
  display: flex; justify-content: space-between; gap: 1rem;
  padding: 0.3rem 0; font-size: 0.8rem;
  border-bottom: 1px solid rgba(148, 163, 184, 0.14);
}
.cp-acc-mapping__group { font-family: var(--cp-mono, ui-monospace, monospace); }
.cp-acc-mapping__to { opacity: 0.7; }
/* A mapping that grants a ROLE is a privilege-escalation path. It should not
   look like an ordinary row. */
.cp-acc-mapping__to--role { color: var(--cp-warn, #f59e0b); opacity: 1; }

/* ── External dependencies ────────────────────────────────────────────────
   The two-reading rule is carried in the CSS as well as the markup: a
   `reported` and an `observed` block are styled identically and sit side by
   side, so neither reads as the authoritative one. `unknown` is deliberately
   the LEAST visually assertive state — hollow, dashed, desaturated — because a
   thing nobody measured must not compete for attention with a thing that is
   actually broken. */

/* Status colour is NOT the theme's accent.
   The console has seven themes and several restyle the semantic tokens as
   decoration: `abyss` resolves --teal to #c4b5fd and --amber to #f0abfc, so
   operational, degraded and outage all rendered as neighbouring violets and
   the severity encoding disappeared. Health is not a mood — this scale is
   defined once here, tuned for contrast on both dark and light grounds, and
   every surface on this panel reads from it, canvas included. */
#panel-upstream {
  --up-ok: #2ea043;
  --up-warn: #d29922;
  --up-bad: #f85149;
  --up-info: #58a6ff;
  --up-none: #8b949e;
}
/* The light themes need darker greens and ambers to stay legible on white. */
body[data-theme="white"] #panel-upstream,
body[data-theme="classic"] #panel-upstream {
  --up-ok: #1a7f37;
  --up-warn: #9a6700;
  --up-bad: #cf222e;
  --up-info: #0969da;
  --up-none: #57606a;
}

@keyframes cp-up-pulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--up-bad) 55%, transparent); }
  50% { box-shadow: 0 0 0 7px transparent; }
}

.cp-up-canvas {
  /* Published to the constellation, which reads them with getComputedStyle.
     Without this the canvas would be the one element in the console that does
     not follow the theme picker — and it is the largest one on the panel. */
  --cp-up-ink: var(--text);
  --cp-up-void: var(--panel-solid);
  /* NOT var(--line): several themes set that to a near-transparent hairline
     (abyss uses 0.14 alpha), and orbit rings drawn from it disappeared
     entirely. The scene needs a colour it can actually apply alpha to. */
  --cp-up-line: var(--up-none);
  --cp-up-ok: var(--up-ok);
  --cp-up-warn: var(--up-warn);
  --cp-up-bad: var(--up-bad);
  --cp-up-info: var(--up-info);
  --cp-up-none: var(--up-none);
  width: 100%; height: 440px; display: block; border-radius: 10px;
  background:
    radial-gradient(circle at 50% 45%, color-mix(in srgb, var(--up-info) 8%, transparent), transparent 62%),
    var(--panel);
  border: 1px solid var(--surface-border, var(--line));
}
.cp-up-canvas:focus-visible { outline: 2px solid var(--up-info); outline-offset: 2px; }

/* ── Work: every tracker, one view ───────────────────────────────────────
   Status colour here follows the same rule as the dependencies panel: it is
   its own scale, not the theme's decorative accent. Several themes restyle
   --teal and --amber as ornament, and a queue whose priorities all render as
   neighbouring violets has lost the only thing the colour was carrying.

   The other rule the CSS carries: anything DevEx Lattice cannot attribute or cannot
   read is styled as INCOMPLETE — dashed, desaturated — never as fine. */
#panel-work {
  --wk-ok: #2ea043;
  --wk-warn: #d29922;
  --wk-bad: #f85149;
  --wk-info: #58a6ff;
  --wk-none: #8b949e;
}
body[data-theme="white"] #panel-work,
body[data-theme="classic"] #panel-work {
  --wk-ok: #1a7f37;
  --wk-warn: #9a6700;
  --wk-bad: #cf222e;
  --wk-info: #0969da;
  --wk-none: #57606a;
}

.cp-prop {
  display: flex; flex-direction: column; gap: 0.55rem;
  padding: 0.9rem 1rem; border-radius: 10px;
  border: 1px solid var(--surface-border, var(--line));
  border-left-width: 4px;
  background: color-mix(in srgb, var(--line) 5%, transparent);
}
.cp-prop--observed { border-left-color: var(--wk-info); }
.cp-prop--likely { border-left-color: var(--wk-warn); }
/* The least-certain tier is visually the quietest, so a maybe cannot compete
   for attention with something demonstrated. */
.cp-prop--possible { border-left-color: var(--wk-none); border-left-style: dashed; }

.cp-prop__head { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.cp-prop__confidence {
  font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.08em; font-weight: 600;
  padding: 0.12rem 0.45rem; border-radius: 4px; border: 1px solid currentColor;
}
.cp-prop--observed .cp-prop__confidence { color: var(--wk-info); }
.cp-prop--likely .cp-prop__confidence { color: var(--wk-warn); }
.cp-prop--possible .cp-prop__confidence { color: var(--wk-none); }
.cp-prop__kind { font-size: 0.72rem; opacity: 0.7; }
.cp-prop__seen { margin-left: auto; font-size: 0.7rem; opacity: 0.6; font-variant-numeric: tabular-nums; }
.cp-prop__title { margin: 0; font-size: 1.02rem; }
.cp-prop__body { display: flex; flex-direction: column; gap: 0.45rem; font-size: 0.85rem; line-height: 1.5; }
.cp-prop__body p { margin: 0; }

.cp-prop__evidence {
  display: flex; flex-direction: column; gap: 0.3rem;
  padding: 0.55rem 0.7rem; border-radius: 7px;
  background: color-mix(in srgb, var(--line) 9%, transparent);
}
.cp-prop__evidence-head {
  margin: 0; font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.08em; opacity: 0.6;
}
.cp-prop__evidence-row { display: flex; gap: 0.5rem; font-size: 0.79rem; }
.cp-prop__evidence-kind {
  font-family: ui-monospace, SFMono-Regular, monospace; font-size: 0.71rem;
  opacity: 0.6; white-space: nowrap; padding-top: 0.1rem;
}
.cp-prop__caveat {
  margin: 0; font-size: 0.79rem; opacity: 0.85; line-height: 1.45;
  padding: 0.5rem 0.65rem; border-radius: 7px;
  border-left: 3px dashed color-mix(in srgb, var(--wk-none) 60%, transparent);
}
.cp-prop__actions { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.cp-prop__promote, .cp-prop__dismiss {
  font: inherit; font-size: 0.8rem; cursor: pointer;
  padding: 0.35rem 0.7rem; border-radius: 6px;
  border: 1px solid var(--surface-border, var(--line));
  background: transparent; color: inherit;
}
.cp-prop__promote { border-color: color-mix(in srgb, var(--wk-info) 55%, transparent); color: var(--wk-info); }
.cp-prop__promote:hover:not(:disabled) { background: color-mix(in srgb, var(--wk-info) 12%, transparent); }
.cp-prop__promote:disabled, .cp-prop__dismiss:disabled { opacity: 0.45; cursor: not-allowed; }
.cp-prop__reason { font: inherit; font-size: 0.8rem; padding: 0.35rem 0.5rem; flex: 1 1 18rem; min-width: 0; }

.cp-detector {
  display: flex; flex-direction: column; gap: 0.25rem; font-size: 0.82rem;
  padding: 0.55rem 0.7rem; border-radius: 8px;
  background: color-mix(in srgb, var(--line) 6%, transparent);
}
.cp-detector__kind { font-weight: 600; }
.cp-detector__counts { display: flex; gap: 0.5rem; font-size: 0.72rem; opacity: 0.7; font-variant-numeric: tabular-nums; }
.cp-detector__verdict { font-size: 0.78rem; opacity: 0.9; }
.cp-detector__reasons { margin: 0.2rem 0 0; padding-left: 1.1rem; font-size: 0.75rem; opacity: 0.72; }

.cp-tracker {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; font-size: 0.8rem;
  padding: 0.5rem 0.65rem; border-radius: 8px;
  border: 1px solid var(--surface-border, var(--line));
}
.cp-tracker--off { opacity: 0.55; border-style: dashed; }
.cp-tracker__provider { font-weight: 600; }
.cp-tracker__name { font-family: ui-monospace, SFMono-Regular, monospace; font-size: 0.75rem; opacity: 0.8; }
.cp-tracker__flags { display: flex; gap: 0.3rem; flex-wrap: wrap; }
.cp-tracker__flag {
  font-size: 0.66rem; padding: 0.08rem 0.38rem; border-radius: 999px;
  border: 1px dashed color-mix(in srgb, var(--wk-none) 55%, transparent); opacity: 0.75;
}
.cp-tracker__flag--on {
  border-style: solid; opacity: 1;
  border-color: color-mix(in srgb, var(--wk-ok) 55%, transparent); color: var(--wk-ok);
}
.cp-tracker__flag--bad { border-color: color-mix(in srgb, var(--wk-bad) 60%, transparent); color: var(--wk-bad); }
.cp-tracker__sync { margin-left: auto; font-size: 0.72rem; opacity: 0.65; }
.cp-tracker__sync--err { color: var(--wk-warn); opacity: 0.95; }

.cp-delivery {
  display: flex; gap: 0.55rem; align-items: baseline; font-size: 0.76rem;
  padding: 0.35rem 0.5rem; border-radius: 6px;
  border-left: 3px solid color-mix(in srgb, var(--wk-none) 50%, transparent);
}
.cp-delivery--applied { border-left-color: var(--wk-ok); }
.cp-delivery--rejected { border-left-color: var(--wk-bad); }
.cp-delivery--failed { border-left-color: var(--wk-warn); }
.cp-delivery__when { opacity: 0.6; white-space: nowrap; font-family: ui-monospace, SFMono-Regular, monospace; font-size: 0.7rem; }
.cp-delivery__outcome { text-transform: uppercase; font-size: 0.66rem; letter-spacing: 0.06em; opacity: 0.8; }
.cp-delivery__detail { flex: 1 1 auto; min-width: 0; opacity: 0.85; }
.cp-delivery__scheme { font-size: 0.66rem; opacity: 0.55; font-family: ui-monospace, SFMono-Regular, monospace; }

/* ── Status page: adding a component ─────────────────────────────────────
   The form was missing entirely, so the whole synthetic-check feature was
   reachable only by curl. The endpoint field is the load-bearing one: the
   template picker sets the interval, and an interval with nothing to check
   produces a component that reports `unknown` forever while looking
   configured. */
.cp-sp-addcomponent { margin: 0.9rem 0 1.2rem; }
.cp-sp-form {
  display: grid; gap: 0.7rem;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}
.cp-sp-field { display: flex; flex-direction: column; gap: 0.25rem; font-size: 0.82rem; }
.cp-sp-field__label { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.07em; opacity: 0.65; }
.cp-sp-field__input {
  font: inherit; font-size: 0.85rem; padding: 0.4rem 0.55rem; border-radius: 6px;
  border: 1px solid var(--surface-border, var(--line));
  background: color-mix(in srgb, var(--line) 6%, transparent);
  color: inherit; min-width: 0;
}
.cp-sp-field__hint { font-size: 0.72rem; opacity: 0.6; line-height: 1.35; }
.cp-sp-form__actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.9rem; }
.cp-sp-form__add, .cp-sp-form__self {
  font: inherit; font-size: 0.82rem; cursor: pointer;
  padding: 0.4rem 0.85rem; border-radius: 6px;
  border: 1px solid var(--surface-border, var(--line));
  background: transparent; color: inherit;
}
.cp-sp-form__add { border-color: color-mix(in srgb, var(--cyan) 55%, transparent); color: var(--cyan); }
.cp-sp-form__add:hover:not(:disabled) { background: color-mix(in srgb, var(--cyan) 12%, transparent); }
/* The one-click path is visually secondary — it is a shortcut, not the point. */
.cp-sp-form__self { opacity: 0.85; }
.cp-sp-form__self:hover:not(:disabled) { opacity: 1; background: color-mix(in srgb, var(--line) 10%, transparent); }
.cp-sp-form__add:disabled, .cp-sp-form__self:disabled { opacity: 0.45; cursor: not-allowed; }

/* ── Reports ─────────────────────────────────────────────────────────────
   Semantic colour is its own scale here for the same reason it is on the
   Dependencies and Work panels: several themes restyle --teal and --amber as
   decoration, and a chart whose "failing" band is a neighbouring violet to its
   "passing" band has lost the only thing the colour was carrying.

   The other rule the CSS encodes: `not measured` is styled as ABSENCE —
   dashed, desaturated, italic — and can never be mistaken for a number. */
#panel-reports {
  --rp-good: #2ea043;
  --rp-warn: #d29922;
  --rp-bad: #f85149;
  --rp-info: #58a6ff;
  --rp-muted: #8b949e;
}
body[data-theme="white"] #panel-reports,
body[data-theme="classic"] #panel-reports {
  --rp-good: #1a7f37; --rp-warn: #9a6700; --rp-bad: #cf222e;
  --rp-info: #0969da; --rp-muted: #57606a;
}

.cp-rep-body { margin-top: 1rem; display: flex; flex-direction: column; gap: 1.2rem; }
.cp-rep-chrome { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: center; }
.cp-rep-views { display: inline-flex; border-radius: 8px; overflow: hidden;
  border: 1px solid var(--surface-border, var(--line)); }
.cp-rep-view {
  font: inherit; font-size: 0.78rem; cursor: pointer; padding: 0.35rem 0.75rem;
  border: 0; background: transparent; color: inherit; opacity: 0.7;
}
.cp-rep-view--on { background: color-mix(in srgb, var(--rp-info) 18%, transparent); opacity: 1; color: var(--rp-info); }
.cp-rep-window { font: inherit; font-size: 0.78rem; padding: 0.3rem 0.5rem; border-radius: 6px;
  border: 1px solid var(--surface-border, var(--line)); background: transparent; color: inherit; }
.cp-rep-stamp { margin-left: auto; font-size: 0.72rem; opacity: 0.55; }

.cp-rep-tabs { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.cp-rep-tab {
  font: inherit; font-size: 0.82rem; cursor: pointer; padding: 0.35rem 0.85rem;
  border-radius: 999px; background: transparent; color: inherit;
  border: 1px solid var(--surface-border, var(--line)); opacity: 0.75;
}
.cp-rep-tab--on { opacity: 1; border-color: var(--rp-info); color: var(--rp-info);
  background: color-mix(in srgb, var(--rp-info) 12%, transparent); }

/* The DORA strip */
.cp-dora { display: grid; gap: 0.6rem; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }
.cp-dora--big { grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
.cp-metric {
  display: flex; flex-direction: column; gap: 0.2rem;
  padding: 0.75rem 0.9rem; border-radius: 10px;
  border: 1px solid var(--surface-border, var(--line));
  background: color-mix(in srgb, var(--line) 5%, transparent);
}
.cp-metric--big { padding: 1.1rem 1.2rem; cursor: pointer; transition: border-color 150ms ease, transform 150ms ease; }
.cp-metric--big:hover { transform: translateY(-2px); border-color: color-mix(in srgb, var(--rp-info) 50%, transparent); }
.cp-metric--big:focus-visible { outline: 2px solid var(--rp-info); outline-offset: 2px; }
.cp-metric__label { margin: 0; font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.08em; opacity: 0.6; }
.cp-metric__value { margin: 0; font-size: 1.6rem; font-weight: 600; font-variant-numeric: tabular-nums; line-height: 1.1; }
.cp-metric--big .cp-metric__value { font-size: 2.2rem; }
/* Absence, styled as absence. It must never read as a number. */
.cp-metric__none { font-size: 1rem; font-weight: 400; font-style: italic; opacity: 0.55;
  border-bottom: 1px dashed color-mix(in srgb, var(--rp-muted) 60%, transparent); }
.cp-metric--big .cp-metric__none { font-size: 1.1rem; }
.cp-metric__support { margin: 0; font-size: 0.72rem; opacity: 0.6; font-variant-numeric: tabular-nums; }
.cp-metric__why { margin: 0.25rem 0 0; font-size: 0.72rem; opacity: 0.75; line-height: 1.4;
  padding-left: 0.55rem; border-left: 2px dashed color-mix(in srgb, var(--rp-muted) 50%, transparent); }

.cp-rep-section { display: flex; flex-direction: column; gap: 0.6rem;
  padding-top: 0.9rem; border-top: 1px solid color-mix(in srgb, var(--line) 25%, transparent); }
.cp-rep-section__title { margin: 0; font-size: 1rem; }
.cp-rep-section__blurb { margin: 0; font-size: 0.82rem; opacity: 0.75; line-height: 1.45; }
.cp-note { margin: 0; font-size: 0.76rem; opacity: 0.72; line-height: 1.45;
  padding: 0.4rem 0.6rem; border-radius: 6px;
  border-left: 3px dashed color-mix(in srgb, var(--rp-muted) 50%, transparent);
  background: color-mix(in srgb, var(--line) 5%, transparent); }
.cp-callout { margin: 0; font-size: 0.86rem; padding: 0.55rem 0.75rem; border-radius: 7px;
  border-left: 3px solid var(--rp-muted); background: color-mix(in srgb, var(--line) 6%, transparent); }
.cp-callout--good { border-left-color: var(--rp-good); }
.cp-callout--warn { border-left-color: var(--rp-warn); }
.cp-callout--bad { border-left-color: var(--rp-bad); background: color-mix(in srgb, var(--rp-bad) 10%, transparent); }

/* Charts */
.cp-chart { width: 100%; height: auto; overflow: visible; }
.cp-chart__line { fill: none; stroke: var(--rp-info); stroke-width: 1.6; stroke-linejoin: round; }
.cp-chart__fill { fill: color-mix(in srgb, var(--rp-info) 16%, transparent); stroke: none; }
.cp-chart__dot { fill: var(--rp-info); }
.cp-chart__grid { stroke: color-mix(in srgb, var(--rp-muted) 22%, transparent); stroke-width: 1; }
.cp-chart__axis { fill: var(--rp-muted); font-size: 8px; opacity: 0.7; }
.cp-chart__none { fill: var(--rp-muted); font-size: 10px; font-style: italic; opacity: 0.7; }
/* A period with no reading is HATCHED, not blank. Blank reads as zero. */
.cp-chart__gap { fill: color-mix(in srgb, var(--rp-muted) 14%, transparent); }
.cp-chart__band--good { fill: var(--rp-good); }
.cp-chart__band--bad { fill: var(--rp-bad); }
.cp-chart__band--muted { fill: color-mix(in srgb, var(--rp-muted) 45%, transparent); }

.cp-legend { display: flex; gap: 0.7rem; margin: 0.3rem 0 0; font-size: 0.7rem; opacity: 0.75; }
.cp-legend__item::before { content: ""; display: inline-block; width: 9px; height: 9px;
  margin-right: 0.3rem; border-radius: 2px; vertical-align: middle; }
.cp-legend__item--good::before { background: var(--rp-good); }
.cp-legend__item--bad::before { background: var(--rp-bad); }
.cp-legend__item--muted::before { background: color-mix(in srgb, var(--rp-muted) 45%, transparent); }

/* Ranked bars */
.cp-bars { display: flex; flex-direction: column; gap: 0.3rem; }
.cp-bars__row { display: grid; grid-template-columns: minmax(6rem, 12rem) 1fr auto; gap: 0.6rem; align-items: center; font-size: 0.79rem; }
.cp-bars__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; opacity: 0.9; }
.cp-bars__track { height: 0.6rem; border-radius: 3px; background: color-mix(in srgb, var(--line) 14%, transparent); overflow: hidden; }
.cp-bars__fill { display: block; height: 100%; background: var(--rp-info); border-radius: 3px; }
.cp-bars__fill--warn { background: var(--rp-warn); }
.cp-bars__fill--bad { background: var(--rp-bad); }
.cp-bars__value { font-size: 0.72rem; opacity: 0.7; white-space: nowrap; font-variant-numeric: tabular-nums; }

/* Funnel */
.cp-funnel { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.cp-funnel__step { flex: 1 1 7rem; min-width: 6rem; }
.cp-funnel__bar { height: 0.5rem; border-radius: 3px; background: var(--rp-muted); margin-bottom: 0.3rem; }
.cp-funnel__step--warn .cp-funnel__bar { background: var(--rp-warn); }
.cp-funnel__step--info .cp-funnel__bar { background: var(--rp-info); }
.cp-funnel__step--good .cp-funnel__bar { background: var(--rp-good); }
.cp-funnel__step--muted .cp-funnel__bar { background: color-mix(in srgb, var(--rp-muted) 45%, transparent); }
.cp-funnel__text { display: flex; flex-direction: column; font-size: 0.74rem; }
.cp-funnel__text strong { font-size: 1.2rem; font-variant-numeric: tabular-nums; }
.cp-funnel__text span { opacity: 0.65; }
.cp-funnel__arrow { opacity: 0.4; }

/* Coverage */
.cp-coverage { display: flex; flex-direction: column; gap: 0.15rem; }
.cp-coverage__bar { display: flex; height: 0.4rem; border-radius: 3px; overflow: hidden;
  background: color-mix(in srgb, var(--line) 12%, transparent); }
.cp-coverage__got { background: var(--rp-good); }
/* The unobserved share is hatched rather than red — it is a blind spot, not a
   fault, and must not compete with something that is actually failing. */
.cp-coverage__lost { background: repeating-linear-gradient(45deg,
  color-mix(in srgb, var(--rp-muted) 45%, transparent) 0 3px, transparent 3px 6px); }
.cp-coverage__caption { font-size: 0.68rem; opacity: 0.6; }

/* Cluster health */
.cp-cluster { display: flex; flex-direction: column; gap: 0.5rem; padding: 0.7rem 0.85rem;
  border-radius: 9px; border: 1px solid var(--surface-border, var(--line)); }
.cp-cluster__head { display: flex; justify-content: space-between; gap: 0.6rem; flex-wrap: wrap; align-items: baseline; }
.cp-cluster__meta { font-size: 0.73rem; opacity: 0.6; font-variant-numeric: tabular-nums; }
.cp-cluster__metric { display: grid; grid-template-columns: 5rem minmax(9rem, 1fr) minmax(8rem, 1fr); gap: 0.6rem; align-items: center; font-size: 0.78rem; }
.cp-cluster__name { opacity: 0.65; text-transform: uppercase; font-size: 0.68rem; letter-spacing: 0.06em; }
.cp-cluster__value { font-variant-numeric: tabular-nums; }
.cp-cluster__chart { margin-top: 0.35rem; }
.cp-cluster__charttitle { margin: 0 0 0.25rem; font-size: 0.7rem; opacity: 0.6; }

/* Coverage rows */
.cp-account { display: grid; grid-template-columns: minmax(8rem,1fr) auto auto; gap: 0.6rem;
  align-items: center; font-size: 0.79rem; padding: 0.35rem 0.5rem; border-radius: 6px;
  background: color-mix(in srgb, var(--line) 5%, transparent); }
.cp-account--unscanned { border-left: 3px solid var(--rp-warn); }
.cp-account__state--bad { color: var(--rp-bad); }
.cp-account__state--warn { color: var(--rp-warn); }
.cp-account__findings { font-size: 0.72rem; opacity: 0.7; font-variant-numeric: tabular-nums; }

/* Unavailable — the finance panel's honest core */
.cp-unavailable { padding: 0.7rem 0.85rem; border-radius: 8px;
  border: 1px dashed color-mix(in srgb, var(--rp-muted) 55%, transparent);
  background: color-mix(in srgb, var(--line) 4%, transparent); }
.cp-unavailable__head { margin: 0 0 0.25rem; font-size: 0.86rem; font-weight: 600; opacity: 0.85; }
.cp-unavailable__why { margin: 0; font-size: 0.76rem; opacity: 0.7; line-height: 1.45; }

/* Exceptions */
.cp-exceptions { display: flex; flex-direction: column; gap: 0.25rem; }
.cp-exception { display: grid; grid-template-columns: 9rem minmax(6rem,1fr) auto; gap: 0.6rem;
  font-size: 0.76rem; padding: 0.3rem 0.5rem; border-radius: 5px;
  background: color-mix(in srgb, var(--line) 5%, transparent); }
.cp-exception__kind { opacity: 0.65; text-transform: uppercase; font-size: 0.66rem; letter-spacing: 0.05em; }
.cp-exception__actor { opacity: 0.6; }

/* Grid layout */
.cp-rep-grid { display: grid; gap: 0.9rem; grid-template-columns: repeat(auto-fit, minmax(24rem, 1fr)); }
.cp-rep-cell { padding: 0.6rem 0.8rem; border-radius: 10px;
  border: 1px solid var(--surface-border, var(--line)); }
.cp-rep-cell .cp-rep-section { border-top: 0; padding-top: 0; }

/* The blurbs carry real gate names, so they need a code face and enough room
   to be worth reading. A one-line card is a label, not information. */
.hero__cards--row .hero__card span {
  font-size: 12px;
  line-height: 1.55;
}

.hero__cards--row .hero__card code {
  font-family: var(--theme-font);
  font-size: 11px;
  color: var(--teal);
  word-break: break-word;
}

.hero__cards--row .hero__card strong {
  font-size: 13px;
  margin-bottom: 6px;
}

/* This page leads with the instrument, so it does not get the 56px the
   marketing pages put under the nav. */
.landing--frontdoor .landing-nav--compact {
  margin-bottom: clamp(10px, 1.8vh, 22px);
}

/* ── One screen, by construction ──────────────────────────────────────────
   Adding up margins until the hero happens to fit is not a layout; it fits on
   the machine it was measured on and overflows on the next one, because font
   metrics, default sizes and viewport chrome all differ. So: bind the shell to
   the viewport and give the stage the leftover row. Whatever the intro turns
   out to be, the instrument absorbs the remainder and the page ends exactly at
   the fold — on any browser, at any type size.

   No `overflow: hidden` anywhere: pillar 05 R7 is explicit that clipping is
   strictly worse than scrolling. Below the guard sizes the layout simply flows
   and the page scrolls normally. */
@media (min-width: 1280px) and (min-height: 660px),
       (min-width: 900px) and (min-height: 760px) {
  /* min-height, not height: a page that fits ends at the fold; one that does
     not grows and the document scrolls, never a box inside it. */
  .landing--frontdoor {
    min-height: 100vh;
    min-height: 100dvh;
    padding-top: clamp(10px, 1.8vh, 18px);
    padding-bottom: clamp(8px, 1.4vh, 18px);
  }

}

.hero__intro {
  max-width: 900px;
  margin-bottom: 30px;
}

.trail {
  flex: 1;
  min-height: 0;
  padding: 12px 14px 16px;
  font-family: var(--theme-font);
  font-size: 12px;
  line-height: 1.7;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}

@keyframes trail-blink {
  0%, 50% { opacity: 1; }
  50.01%, 100% { opacity: 0; }
}

.hero__cards--row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
  gap: 1px;
  margin: 0;
  border: 1px solid var(--surface-border);
  border-top: none;
  border-radius: 0 0 4px 4px;
  background: var(--surface-border);
  overflow: hidden;
}

.hero__cards--row .hero__card {
  margin: 0;
  border: none;
  border-radius: 0;
  background: var(--surface-soft);
  padding: 16px 18px;
}

.hero__cards--row .hero__card:hover {
  background: var(--surface-hover);
}

/* ── The lattice front door ───────────────────────────────────────────────
   Two instruments side by side: the GATE RING (a real repository against the
   real devex-kit matrix) and CATALOG TO CLUSTER (illustrative, and labelled
   so). Every colour is a token; assets/js/home-lattice.js reads the same
   tokens back so a theme switch repaints both canvases.

   This page does not use the one-screen binding the bonded hero needed. Both
   canvases keep their own aspect ratio, and squeezing them into a leftover
   grid row would distort the ring. The page flows and scrolls instead —
   pillar 05 R7: scrolling is better than clipping. */

.landing--frontdoor.landing--lattice {
  height: auto;
}

/* Outranks `.landing-body main.landing`'s 3vh, which alone pushed the page
   past the fold on a 13" laptop. */
.landing-body main.landing--lattice {
  padding-bottom: clamp(8px, 1.4vh, 18px);
}

.hero--lattice {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(10px, 1.8vh, 18px);
  padding: 0;
}

.hero--lattice .hero__intro {
  max-width: 1080px;
  margin: 0 auto 8px;
  text-align: center;
}

.hero--lattice .hero__title {
  max-width: none;
  font-size: clamp(28px, min(3.4vw, 5.8vh), 54px);
  line-height: 1.06;
  text-wrap: balance;
}

.hero--lattice .hero__title span { display: block; }
.hero--lattice .hero__eyebrow { margin-bottom: 12px; }

.hero--lattice .hero__lede {
  max-width: 104ch;
  margin: 14px auto 0;
  text-wrap: pretty;
  font-size: clamp(13.5px, min(1.05vw, 1.8vh), 16px);
  line-height: 1.6;
}

.hero--lattice .hero__lede code {
  font-family: var(--theme-font);
  font-size: 0.92em;
  color: var(--teal);
}

.hero--lattice .hero__actions {
  justify-content: center;
  margin-top: clamp(12px, 2vh, 22px);
}

/* Wide screens: the headline beside its explanation, not above it. Stacked,
   the intro alone took 274px and pushed the board past the fold on a
   1920x1080 window; side by side it is the height of the taller column. */
@media (min-width: 1200px) {
  .hero--lattice .hero__intro {
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
    grid-template-areas: "eye eye" "title lede" "title actions";
    column-gap: 40px;
    align-items: center;
    max-width: none;
    margin: 0 0 4px;
    text-align: left;
  }
  .hero--lattice .hero__eyebrow { grid-area: eye; }
  .hero--lattice .hero__title { grid-area: title; font-size: clamp(28px, min(2.45vw, 4.8vh), 46px); }
  .hero--lattice .hero__lede { grid-area: lede; margin: 0; max-width: none; }
  .hero--lattice .hero__actions { grid-area: actions; justify-content: flex-start; margin-top: 14px; }
  .hero--lattice .hero__cards--row .hero__card { padding: 9px 13px; }
  .hero--lattice .hero__cards--row .hero__card span { line-height: 1.45; }
}

.lattice-board {
  display: grid;
  gap: 14px;
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 1040px) {
  .lattice-board {
    grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr);
    align-items: stretch;
  }
}

.lattice-panel {
  display: flex;
  flex-direction: column;
  min-width: 0;
  border: 1px solid var(--surface-border);
  border-radius: 4px;
  background: linear-gradient(180deg, var(--surface-soft), var(--surface-strong));
}

.lattice-panel__head {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 9px 14px;
  border-bottom: 1px solid var(--surface-border);
  font-family: var(--theme-font);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--command-bg);
}

.lattice-panel__head span:last-child {
  color: var(--teal);
  text-transform: none;
  letter-spacing: 0.04em;
  text-align: right;
}

/* ring + its readout */
.ring-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: center;
  gap: 6px 16px;
  padding: 12px 14px 6px;
}

@media (min-width: 560px) {
  .ring-body {
    grid-template-columns: minmax(200px, 0.9fr) minmax(0, 1.1fr);
  }
}

#ring-canvas {
  display: block;
  width: 100%;
  /* Square, so its height is its width: tie it to the viewport's height so
     the front door fits a laptop screen instead of scrolling for the ring. */
  max-width: clamp(220px, 29vh, 340px);
  justify-self: center;
}

.ring-readout {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  font-family: var(--theme-font);
  font-size: 12px;
  line-height: 1.55;
}

.ring-readout__cmd {
  color: var(--teal);
  margin-bottom: 4px;
}

.ring-readout__row {
  display: grid;
  grid-template-columns: 8ch minmax(0, 1fr);
  gap: 10px;
}

.ring-readout__k { color: var(--muted); }

.ring-readout__v {
  display: flex;
  flex-direction: column;
  min-width: 0;
  color: var(--text);
  overflow-wrap: anywhere;
}

.ring-readout__row--open .ring-readout__k,
.ring-readout__gate { color: var(--danger); }

.ring-readout__why {
  color: var(--muted);
  font-size: 11px;
}

.ring-readout__row--pass .ring-readout__k,
.ring-readout__row--pass .ring-readout__v { color: var(--teal); }

.ring-readout__row--held .ring-readout__k,
.ring-readout__row--held .ring-readout__v { color: var(--danger); }

/* controls: buttons, not a drag target */
.ring-controls {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: auto;
  padding: 10px 14px 14px;
  border-top: 1px solid var(--surface-border);
}

.ring-controls__row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 10px;
}

.ring-controls__label {
  min-width: 11ch;
  font-family: var(--theme-font);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.ring-controls__group {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 6px;
}

.ring-controls__note {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
}

.ring-chip {
  font-family: var(--theme-font);
  font-size: 12px;
  padding: 5px 11px;
  border: 1px solid var(--surface-border-strong);
  border-radius: 3px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
}

.ring-chip:hover {
  color: var(--text);
  background: var(--surface-hover);
}

.ring-chip[aria-pressed="true"] {
  color: var(--text);
  border-color: var(--teal);
  background: var(--surface-active);
}

.ring-chip:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 2px;
}

/* catalog to cluster */
.lattice-panel--ship canvas {
  display: block;
  width: calc(100% - 20px);
  margin: auto 10px;
  padding-block: 12px;
}

/* the about page: the rules per tier, then every gate */
.tier-rings {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
  padding: 18px 18px 6px;
}

@media (max-width: 760px) {
  .tier-rings {
    grid-template-columns: minmax(0, 1fr);
    max-width: 320px;
    margin-inline: auto;
  }
}

.tier-ring {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.tier-ring canvas {
  display: block;
  width: 100%;
  max-width: 280px;
}

.tier-ring__cap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  font-family: var(--theme-font);
}

.tier-ring__env {
  font-size: 13px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text);
}

.tier-ring__counts {
  font-size: 11.5px;
  color: var(--muted);
}

.tier-rings__empty {
  grid-column: 1 / -1;
  margin: 0;
  font-family: var(--theme-font);
  font-size: 13px;
  color: var(--danger);
}

.tier-legend {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 18px;
  margin: 0;
  padding: 6px 18px 16px;
  font-family: var(--theme-font);
  font-size: 11.5px;
  color: var(--muted);
}

.tier-legend i {
  display: inline-block;
  width: 18px;
  height: 4px;
  margin-right: 6px;
  border-radius: 2px;
  vertical-align: middle;
}

.tier-legend .lg-base { height: 6px; background: var(--teal); }
.tier-legend .lg-cond { height: 3px; background: var(--cyan); }
.tier-legend .lg-opt {
  height: 3px;
  background: repeating-linear-gradient(90deg, var(--muted) 0 3px, transparent 3px 6px);
  opacity: 0.8;
}

.gate-table-wrap {
  overflow-x: auto;
  padding: 4px 8px 6px;
}

.gate-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
}

.gate-table th,
.gate-table td {
  padding: 7px 10px;
  border-bottom: 1px solid var(--surface-border);
  text-align: left;
  vertical-align: top;
}

.gate-table thead th {
  font-family: var(--theme-font);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

.gate-table__gate code {
  font-family: var(--theme-font);
  font-size: 12px;
  color: var(--text);
}

.gate-table__pillar {
  font-family: var(--theme-font);
  white-space: nowrap;
  color: var(--muted);
}

.gate-table__desc {
  min-width: 26ch;
  color: var(--muted);
}

.gate-table__cell {
  font-family: var(--theme-font);
  font-size: 11.5px;
  white-space: nowrap;
}

.gate-table__cell--base { color: var(--teal); }
.gate-table__cell--cond { color: var(--cyan); white-space: normal; }
.gate-table__cell--cond code { font-size: 11px; }
.gate-table__cell--opt { color: var(--muted); }
.gate-table__cell--none { color: var(--muted); opacity: 0.5; }

.compliance-note {
  padding: 8px 18px 16px;
  font-size: 12.5px;
  color: var(--muted);
}

.compliance-note p { margin: 0; }

.compliance-note ul {
  margin: 6px 0 0;
  padding-left: 18px;
  font-family: var(--theme-font);
  font-size: 11.5px;
}

.compliance-note li { margin-bottom: 3px; }

.compliance-note strong {
  font-weight: 600;
  color: var(--text);
}

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

/* ── The wordmark ─────────────────────────────────────────────────────────
   "DevEx Lattice", as real text: crisp at any size, read correctly by
   assistive tech, and findable with the browser's search. It used to be
   assembled from glyph fragments, which is exactly how an old name survived a
   rename. Real text cannot hide a word.

   "Ex" takes the teal of the trellis's applied strands; "Lattice" sits lighter
   so the eye lands on DevEx first. */

.brand-word {
  display: inline-flex;
  align-items: baseline;
  gap: 0.3em;
  font-family: "SFMono-Regular", ui-monospace, Menlo, Consolas, monospace;
  font-weight: 600;
  letter-spacing: -0.02em;
  white-space: nowrap;
  color: var(--text);
}

.brand-word__ex { color: var(--teal); }

.brand-word__lattice {
  font-weight: 400;
  color: var(--muted);
}

.landing-brand:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 4px;
  border-radius: 4px;
}

/* cp-ws-copy--warn had no rule at all, while access-panel.js, cluster-scene.js
   and the map's telemetry note all set it — so every "this is a caveat" line
   rendered as ordinary body copy. Defined once here rather than given a fourth
   name, which would have left the three existing callers still silent. */
.cp-ws-copy--warn {
  color: var(--amber);
}

/* A command the reader is meant to run themselves, click-to-copy. Used where
   the server genuinely cannot act — an `aws sso login` that must happen on the
   operator's own machine because this container has no aws CLI and ~/.aws is
   mounted read-only. */
.cp-inline-cmd {
  display: inline-block;
  margin-top: 0.3rem;
  padding: 0.28rem 0.55rem;
  border: 1px solid var(--surface-border-strong);
  border-radius: 6px;
  background: var(--command-bg);
  color: var(--terminal-text);
  font-family: var(--theme-font);
  font-size: 0.74rem;
  cursor: pointer;
  user-select: all;
}
.cp-inline-cmd:hover { border-color: var(--teal); }
.cp-inline-cmd[data-copied]::after {
  content: " ✓ copied";
  color: var(--teal);
}

/* Live cloud inventory: a read of the provider APIs, next to DevEx Lattice's own
   registry. Dense rows because the interesting case is scanning forty of them
   for the one nobody created through DevEx Lattice. */
.cp-liveres {
  display: flex;
  flex-direction: column;
  gap: 1px;
  margin-top: 0.5rem;
  border: 1px solid var(--surface-border);
  border-radius: 8px;
  overflow: hidden;
}
.cp-liveres__row {
  display: grid;
  grid-template-columns: minmax(7rem, 10rem) minmax(8rem, 1.4fr) minmax(6rem, 9rem) 1.6fr;
  gap: 0.7rem;
  align-items: baseline;
  padding: 0.32rem 0.6rem;
  background: var(--surface-elevated);
  font-size: 0.72rem;
}
.cp-liveres__kind {
  color: var(--muted);
  font-size: 0.62rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.cp-liveres__name {
  color: var(--text);
  font-family: var(--theme-font);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cp-liveres__region {
  color: var(--cyan);
  font-variant-numeric: tabular-nums;
}
/* An unknown region is drawn as unknown, never as the current one. A marker
   or a label placing data somewhere is a residency claim. */
.cp-liveres__region--unknown {
  color: var(--amber);
  font-style: italic;
}
.cp-liveres__detail {
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
@media (max-width: 900px) {
  .cp-liveres__row { grid-template-columns: 1fr; gap: 0.15rem; }
}

/* ── Review panel ────────────────────────────────────────────────────────────
 *
 * Scoped to #panel-review, the same discipline #panel-map follows: a bare
 * `.cp-ws-card > .cp-ws-chipline` rule once changed every control row in the
 * console, a layout change on twenty panels nobody had looked at.
 *
 * `.review-burst` is the one deliberate exception. It is appended to
 * document.body so it can rise past the card's overflow, which puts it outside
 * #panel-review — scoping it would silently kill the only animation here.
 */
#panel-review .review-finding {
  border: 1px solid var(--border, #2a2f3a);
  border-left: 3px solid var(--border, #2a2f3a);
  border-radius: 8px;
  padding: 0.85rem 1rem;
  margin: 0 0 0.75rem;
  background: var(--surface, #151922);
}

/* Severity is carried by the left border rather than by the card's background: a wall of tinted
 * cards is harder to scan than a wall of neutral ones with a coloured edge, and colour is never
 * the only signal — the severity word is always present in the header. */
#panel-review .review-finding.sev-error   { border-left-color: var(--danger, #e5484d); }
#panel-review .review-finding.sev-warning { border-left-color: var(--warning, #f5a524); }
#panel-review .review-finding.sev-info    { border-left-color: var(--muted, #6b7280); }

#panel-review .review-finding-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.4rem;
}

#panel-review .review-sev {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted, #9aa4b2);
}

#panel-review .review-loc { font-size: 0.8rem; color: var(--text, #e6e9ef); }
#panel-review .review-rule {
  font-size: 0.72rem;
  color: var(--muted, #6b7280);
  margin-left: auto;
}

/* The verified / unverified distinction is the whole product, so it gets a chip rather than a
 * tooltip. A reader who cannot tell a reproduced defect from a model's hypothesis cannot
 * calibrate their trust in either. */
#panel-review .review-chip {
  font-size: 0.68rem;
  font-weight: 600;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  border: 1px solid transparent;
}
#panel-review .review-chip.is-confirmed {
  color: var(--success, #30a46c);
  border-color: color-mix(in srgb, var(--success, #30a46c) 40%, transparent);
}
#panel-review .review-chip.is-plausible {
  color: var(--muted, #9aa4b2);
  border-color: var(--border, #2a2f3a);
}

.review-msg { margin: 0.2rem 0 0.5rem; line-height: 1.45; }

#panel-review .review-evidence summary {
  cursor: pointer;
  font-size: 0.78rem;
  color: var(--muted, #9aa4b2);
}
#panel-review .review-evidence pre {
  white-space: pre-wrap;
  word-break: break-word;
  font-size: 0.75rem;
  margin: 0.4rem 0 0;
  padding: 0.5rem;
  border-radius: 6px;
  background: var(--surface-2, #0f1319);
  color: var(--muted, #9aa4b2);
}

#panel-review .review-contested {
  margin: 0.4rem 0;
  font-size: 0.8rem;
  color: var(--warning, #f5a524);
}

/* ── reactions ───────────────────────────────────────────────────────────────
 *
 * The most prominent interactive element on the card, deliberately. A reaction is the cheapest
 * true signal about whether the reviewer is right, and one tucked under a fold is one nobody
 * clicks. */

#panel-review .review-reactions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.6rem;
}

#panel-review .review-react {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.25rem 0.55rem;
  font: inherit;
  font-size: 0.78rem;
  color: var(--muted, #9aa4b2);
  background: var(--surface-2, #0f1319);
  border: 1px solid var(--border, #2a2f3a);
  border-radius: 999px;
  cursor: pointer;
  transition: transform 120ms ease, border-color 120ms ease, color 120ms ease;
}

#panel-review .review-react:hover { border-color: var(--accent, #5b8def); color: var(--text, #e6e9ef); }
.review-react:active { transform: scale(0.94); }

/* A visible focus ring, always. These are the primary controls on the panel and a keyboard user
 * must be able to see which one they are on. */
#panel-review .review-react:focus-visible {
  outline: 2px solid var(--accent, #5b8def);
  outline-offset: 2px;
}

/* Your own reaction is marked by border AND weight, never by colour alone. */
#panel-review .review-react.is-mine {
  border-color: var(--accent, #5b8def);
  color: var(--text, #e6e9ef);
  font-weight: 600;
}

.review-react-emoji { font-size: 0.95rem; line-height: 1; }
.review-react-count { font-variant-numeric: tabular-nums; opacity: 0.75; }

/* The one animation, and it carries meaning: it confirms the click landed and says which
 * judgement it was. It runs once, under 0.7s, and is switched off entirely for anyone who asked
 * for reduced motion — where the button's own state change is the confirmation. */
.review-burst {
  position: fixed;
  transform: translate(-50%, 0);
  pointer-events: none;
  font-size: 1.1rem;
  z-index: 9999;
  animation: review-burst-rise 700ms cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
}

@keyframes review-burst-rise {
  0%   { opacity: 0; transform: translate(-50%, 0) scale(0.6); }
  25%  { opacity: 1; transform: translate(-50%, -14px) scale(1.15); }
  100% { opacity: 0; transform: translate(-50%, -42px) scale(0.9); }
}

@media (prefers-reduced-motion: reduce) {
  .review-burst { display: none; }
  .review-react { transition: none; }
  .review-react:active { transform: none; }
}

/* ── the reviewer's own standing ───────────────────────────────────────────── */

#panel-review .review-authority {
  margin: 0 0 0.85rem;
  padding: 0.6rem 0.8rem;
  border-radius: 8px;
  font-size: 0.82rem;
  color: var(--warning, #f5a524);
  border: 1px solid color-mix(in srgb, var(--warning, #f5a524) 35%, transparent);
  background: color-mix(in srgb, var(--warning, #f5a524) 8%, transparent);
}

#panel-review .review-empty { color: var(--muted, #9aa4b2); }

/* A skipped check is not a clean result, so it is not styled like one. */
#panel-review .review-skipped {
  margin: 0.3rem 0 0;
  font-size: 0.78rem;
  color: var(--warning, #f5a524);
}

/* The server's answer to a reaction, shown where the person clicked.
 *
 * The first question anybody asks about an event hook is "did that do anything", and silence is
 * the one answer that teaches them to stop clicking. A refusal is styled as a refusal — "we filed
 * a ticket" and "tickets are not configured here" must not look the same. */
#panel-review .review-result {
  margin: .45rem 0 0;
  font-size: .78rem;
  color: var(--success, #30a46c);
}
#panel-review .review-result.is-refused { color: var(--warning, #f5a524); }

#panel-review .cp-ws-select {
  font: inherit;
  font-size: .85rem;
  padding: .3rem .5rem;
  color: var(--text, #e6e9ef);
  background: var(--surface-2, #0f1319);
  border: 1px solid var(--border, #2a2f3a);
  border-radius: 6px;
}
#panel-review .cp-ws-select:focus-visible {
  outline: 2px solid var(--accent, #5b8def);
  outline-offset: 2px;
}

/* ── Public Safety: ground and controls ── */
body[data-theme="dispatch"],
body[data-theme="dispatch"].landing-body {
  background-color: var(--bg);
  background-image:
    radial-gradient(900px 420px at 0% 0%, rgba(239, 68, 68, 0.07) 0%, transparent 60%),
    radial-gradient(900px 420px at 100% 0%, rgba(59, 130, 246, 0.08) 0%, transparent 60%),
    linear-gradient(180deg, var(--bg) 0%, var(--bg-2) 100%);
}
/* A light bar: red into unit blue across the top of the shell. */
body[data-theme="dispatch"] .cp-ws-shell,
body[data-theme="dispatch"] .cp-admin-layout {
  border-top: 3px solid transparent;
  border-image: linear-gradient(90deg, #ef4444 0%, #ef4444 48%, #3b82f6 52%, #3b82f6 100%) 1;
}

/* ── Versaterm: ground, banner and controls ── */
body[data-theme="versaterm"],
body[data-theme="versaterm"].landing-body {
  background-color: var(--bg);
  background-image: linear-gradient(180deg, var(--bg) 0%, var(--bg-2) 100%);
}
body[data-theme="versaterm"] .chrome {
  background-color: #04505d;
  background-image: linear-gradient(180deg, #073350 0%, #04505d 100%);
  color: #ffffff;
}
body[data-theme="versaterm"] .chrome * { color: inherit; }
body[data-theme="versaterm"] .cp-ws-kicker,
body[data-theme="versaterm"] .lattice-panel__head {
  font-weight: 600;
}
body[data-theme="versaterm"] .theme-picker select,
body[data-theme="dispatch"] .theme-picker select { color: var(--text); }
body[data-theme="versaterm"] .auth-skinbar__swatch { border-color: rgba(11, 42, 51, 0.18); }



/* ══ Weave outline — the control style (owner's pick, 2026-10-02) ══════════
   What sets this edition's controls apart from the rounded, gradient-filled
   ones it inherited: hairline outlines with square corners, hover and active
   states drawn as a diagonal hatch (the lattice as a texture), corner
   brackets on actions, dashed chips that go solid when chosen.

   Everything reads the theme's own tokens, so every theme gets it. The block
   is prefixed `body:not([data-theme="win95"])`: that outranks the console's
   inline styles without !important, leaves win95's bevels alone, and still
   loses to a theme's own rules (`body[data-theme="x"] .btn:not(...)`), which
   is how Versaterm and Public Safety keep their own fills. */
body {
  --weave-hover: repeating-linear-gradient(135deg, color-mix(in srgb, var(--cyan) 10%, transparent) 0 2px, transparent 2px 7px);
  /* Whatever you have chosen or are on (a toggle, a nav item, a tab) reads as
     chosen: a flat fill, not a texture. The weave is only for hover. */
  --toggle-on: color-mix(in srgb, var(--cyan) 30%, transparent);
}

/* actions */
body:not([data-theme="win95"]) .btn,
body:not([data-theme="win95"]) .landing-btn,
body:not([data-theme="win95"]) .cp-ws-rowbtn,
body:not([data-theme="win95"]) .cp-tagquick__btn {
  position: relative;
  border-radius: 0;
  box-shadow: none;
}
body:not([data-theme="win95"]) .btn:not(.btn--ghost),
body:not([data-theme="win95"]) .landing-btn:not(.landing-btn--ghost) {
  border: 1px solid var(--cyan);
  background: var(--cyan);
  color: var(--bg);
}
body:not([data-theme="win95"]) .btn:not(.btn--ghost):hover,
body:not([data-theme="win95"]) .landing-btn:not(.landing-btn--ghost):hover {
  filter: brightness(1.08);
}
body:not([data-theme="win95"]) .btn--ghost,
body:not([data-theme="win95"]) .landing-btn--ghost,
body:not([data-theme="win95"]) .cp-ws-rowbtn,
body:not([data-theme="win95"]) .cp-tagquick__btn {
  border: 1px solid var(--surface-border-strong);
  background: transparent;
  color: var(--text);
}
body:not([data-theme="win95"]) .btn--ghost:hover,
body:not([data-theme="win95"]) .landing-btn--ghost:hover,
body:not([data-theme="win95"]) .cp-ws-rowbtn:hover,
body:not([data-theme="win95"]) .cp-tagquick__btn:hover {
  border-color: var(--cyan);
  background: var(--weave-hover);
}
body:not([data-theme="win95"]) .btn--ghost.is-active,
body:not([data-theme="win95"]) .btn--ghost[aria-pressed="true"] {
  border-color: var(--cyan);
  background: var(--toggle-on);
  box-shadow: inset 0 0 0 1px var(--cyan);
  color: var(--text);
}
/* the brackets: one at the top-left, one at the bottom-right */
body:not([data-theme="win95"]) .btn::before,
body:not([data-theme="win95"]) .btn::after,
body:not([data-theme="win95"]) .landing-btn::before,
body:not([data-theme="win95"]) .landing-btn::after {
  content: "";
  position: absolute;
  width: 6px;
  height: 6px;
  border: 0 solid var(--cyan);
  pointer-events: none;
}
body:not([data-theme="win95"]) .btn::before,
body:not([data-theme="win95"]) .landing-btn::before {
  top: -4px;
  left: -4px;
  border-width: 1px 0 0 1px;
}
body:not([data-theme="win95"]) .btn::after,
body:not([data-theme="win95"]) .landing-btn::after {
  right: -4px;
  bottom: -4px;
  border-width: 0 1px 1px 0;
}
body:not([data-theme="win95"]) .btn:disabled::before,
body:not([data-theme="win95"]) .btn:disabled::after { border-color: var(--surface-border-strong); }

/* navigation and tabs */
body:not([data-theme="win95"]) .cp-ws-nav__item,
body:not([data-theme="win95"]) .cp-admin-nav__item {
  border-radius: 0;
}
body:not([data-theme="win95"]) .cp-ws-nav__item:hover,
body:not([data-theme="win95"]) .cp-admin-nav__item:hover {
  background: var(--weave-hover);
}
body:not([data-theme="win95"]) .cp-ws-nav__item.is-active,
body:not([data-theme="win95"]) .cp-admin-nav__item.is-active {
  background: var(--toggle-on);
  color: var(--text);
}
body:not([data-theme="win95"]) .cp-ws-subnav__item,
body:not([data-theme="win95"]) .cp-rep-tab,
body:not([data-theme="win95"]) .cp-rep-view,
body:not([data-theme="win95"]) .cp-slide-deck__tab {
  border: 1px solid var(--surface-border-strong);
  border-radius: 0;
  background: transparent;
}
body:not([data-theme="win95"]) .cp-ws-subnav__item:hover,
body:not([data-theme="win95"]) .cp-rep-tab:hover,
body:not([data-theme="win95"]) .cp-rep-view:hover,
body:not([data-theme="win95"]) .cp-slide-deck__tab:hover {
  background: var(--weave-hover);
  color: var(--text);
}
body:not([data-theme="win95"]) .cp-ws-subnav__item.is-active,
body:not([data-theme="win95"]) .cp-rep-tab.is-active,
body:not([data-theme="win95"]) .cp-rep-tab[aria-selected="true"],
body:not([data-theme="win95"]) .cp-rep-tab--on,
body:not([data-theme="win95"]) .cp-rep-view--on,
body:not([data-theme="win95"]) .cp-slide-deck__tab.is-active {
  border-color: var(--cyan);
  background: var(--toggle-on);
  box-shadow: inset 0 0 0 1px var(--cyan);
  color: var(--text);
}

/* chips: dashed until chosen */
body:not([data-theme="win95"]) .dl-chip,
body:not([data-theme="win95"]) .ring-chip,
body:not([data-theme="win95"]) .cp-k8s-chip,
body:not([data-theme="win95"]) .cp-acc-chip,
body:not([data-theme="win95"]) .cp-dnd__chip,
body:not([data-theme="win95"]) .feature-chip,
body:not([data-theme="win95"]) .frontdoor-chip {
  border-radius: 0;
  border-style: dashed;
  background: transparent;
}
body:not([data-theme="win95"]) .dl-chip[aria-pressed="true"],
body:not([data-theme="win95"]) .ring-chip[aria-pressed="true"] {
  border-style: solid;
  border-color: var(--teal);
  background: color-mix(in srgb, var(--teal) 30%, transparent);
  box-shadow: inset 0 0 0 1px var(--teal);
  color: var(--text);
}
body:not([data-theme="win95"]) .dl-chip:hover,
body:not([data-theme="win95"]) .ring-chip:hover {
  background: var(--weave-hover);
}

/* status stays a filled tint, squared off to match */
body:not([data-theme="win95"]) .cp-ws-status,
body:not([data-theme="win95"]) .status-pill,
body:not([data-theme="win95"]) .cp-pill,
body:not([data-theme="win95"]) .pill,
body:not([data-theme="win95"]) .cp-log-pill,
body:not([data-theme="win95"]) .cp-promo__chip {
  border-radius: 2px;
}

/* cards: square, with one accent bracket at the top-left */
body:not([data-theme="win95"]) .cp-ws-card,
body:not([data-theme="win95"]) .pillar-card,
body:not([data-theme="win95"]) .cp-admin-pillar,
body:not([data-theme="win95"]) .lattice-panel,
body:not([data-theme="win95"]) .hero__card,
body:not([data-theme="win95"]) .cp-admin-card,
body:not([data-theme="win95"]) .cp-admin-tile,
body:not([data-theme="win95"]) .cp-admin-list__item,
body:not([data-theme="win95"]) .cp-admin-ecg,
body:not([data-theme="win95"]) .cp-admin-otel-card,
body:not([data-theme="win95"]) .cp-admin-runtime__item,
body:not([data-theme="win95"]) .cp-toast,
body:not([data-theme="win95"]) .role-assign-select {
  border-radius: 0;
}
body:not([data-theme="win95"]) .cp-admin-status {
  border-radius: 2px;
}
body:not([data-theme="win95"]) .cp-ws-card,
body:not([data-theme="win95"]) .cp-admin-card,
body:not([data-theme="win95"]) .lattice-panel {
  position: relative;
}
body:not([data-theme="win95"]) .cp-ws-card::before,
body:not([data-theme="win95"]) .cp-admin-card::before,
body:not([data-theme="win95"]) .lattice-panel::before {
  content: "";
  position: absolute;
  top: -1px;
  left: -1px;
  width: 12px;
  height: 12px;
  border-top: 2px solid var(--cyan);
  border-left: 2px solid var(--cyan);
  pointer-events: none;
}

/* Neon's --cyan is a deep violet that reads at 2.9:1 as small text on its
   near-black ground; kickers take the lighter violet it already uses. */
body[data-theme="neon"] .cp-ws-kicker { color: #a78bfa; }

/* The product brand in a sidebar: mark, wordmark, one line under it. Shared by
   the console and the admin console, which used to differ — the admin borrowed
   the login page's display-size wordmark, which ran out of its 248px sidebar
   and over the page title. */
.cp-ws-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 6px 12px;
  border-bottom: 1px solid var(--surface-border);
  min-width: 0;
}
.cp-ws-brand .brand-mark--large { width: 34px; height: 34px; flex: none; }
.cp-ws-brand__title {
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
  white-space: nowrap;
}
.cp-ws-brand__subtitle {
  color: var(--muted);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* Theme-owned action colours. These come AFTER the Weave outline block on
   purpose: both are body-prefixed with the same specificity, so source order
   decides, and a theme must win on colour (Weave decides shape). */
body[data-theme="dispatch"] .btn:not(.btn--ghost) {
  background: #2563eb;
  border-color: #2563eb;
  color: #ffffff;
}
body[data-theme="dispatch"] .btn:not(.btn--ghost):hover { background: #1d4ed8; filter: none; }
body[data-theme="versaterm"] .btn:not(.btn--ghost) {
  background: #00505d;
  border-color: #00505d;
  color: #ffffff;
}
body[data-theme="versaterm"] .btn:not(.btn--ghost):hover { background: #073350; filter: none; }
body[data-theme="versaterm"] .btn--ghost {
  border-color: rgba(0, 80, 93, 0.45);
  color: #00505d;
}
/* The marketing buttons are their own component (.landing-btn), so each
   theme that restyles .btn restyles these to match. */
body[data-theme="versaterm"] .landing-btn {
  background: #00505d;
  color: #ffffff;
  box-shadow: none;
}
body[data-theme="versaterm"] .landing-btn:hover { background: #073350; }
body[data-theme="versaterm"] .landing-btn--ghost {
  background: transparent;
  color: #00505d;
  border: 1px solid rgba(0, 80, 93, 0.45);
}
body[data-theme="versaterm"] .landing-btn--ghost:hover { background: rgba(0, 80, 93, 0.06); }
body[data-theme="dispatch"] .landing-btn {
  background: #2563eb;
  color: #ffffff;
  box-shadow: none;
}
body[data-theme="dispatch"] .landing-btn:hover { background: #1d4ed8; }
body[data-theme="dispatch"] .landing-btn--ghost {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--surface-border-strong);
}

/* ── Console title bar: three fixed slots ──────────────────────────────────
   It was a space-between flex row whose toggle carried margin-left: auto, so
   all the free space went to the toggle's margin and the title sat flush
   against the traffic lights with no gap. Three columns instead: lights (or
   the live breadcrumb, in the flush shell) left, the title centred the way a
   window title is, the shell toggle right — each in its own slot whatever is
   hidden. Win95 keeps its own window. */
body:not([data-theme="win95"]) .cp-ws-shell > .chrome {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  column-gap: 16px;
  padding: 14px 20px;
}
body:not([data-theme="win95"]) .cp-ws-shell > .chrome .chrome__lights,
body:not([data-theme="win95"]) .cp-ws-shell > .chrome .chrome__status {
  grid-column: 1;
  grid-row: 1;
  justify-self: start;
}
body:not([data-theme="win95"]) .cp-ws-shell > .chrome .chrome__title {
  grid-column: 2;
  grid-row: 1;
  line-height: 1;
}
body:not([data-theme="win95"]) .cp-ws-shell > .chrome .chrome__shelltoggle {
  grid-column: 3;
  grid-row: 1;
  justify-self: end;
  margin-left: 0;
  /* Weave outline: square hairline, hatched on hover, same type as the title */
  border-radius: 0;
  border: 1px solid var(--surface-border-strong);
  padding: 6px 11px;
  font-size: 11px;
  line-height: 1;
  letter-spacing: 0.12em;
}
body:not([data-theme="win95"]) .cp-ws-shell > .chrome .chrome__shelltoggle:hover {
  border-color: var(--cyan);
  background: var(--weave-hover);
  color: var(--text);
}

/* ── Login: the Microsoft single sign-on button ─────────────────────────────
   The login page shows ONE control by default: "Sign in with Microsoft",
   carrying the Versaterm mark and Microsoft's. Everything else the page can do
   (the other providers, the form for the seeded local accounts) stays in the
   markup, hidden, and login.js reveals it when the server's configuration says
   so (DEVEXLATTICE_LOGIN_PROVIDERS, DEVEXLATTICE_LOGIN_SEEDED_FORM).

   The button is a .btn.btn--ghost, so it takes the Weave outline above as it
   stands: square hairline, hatch on hover, corner brackets, the .btn
   min-height, and a theme's own ghost colours. Only its inside is styled here.

   The Versaterm mark is teal and orange and was drawn for a light ground, so it
   sits on a white chip in every theme; on the dark ones it would otherwise
   vanish into the card. The chip's white is deliberately NOT a theme token, for
   the reason a brand mark does not change with the theme (see --brand-d at
   :root). The Versaterm THEME still uses no logo: only this button carries the
   mark, copied from the owner's dems-ui repository with the owner's go-ahead on
   2026-10-12. */

/* `hidden` is the promise the markup makes: not drawn until the script says so.
   A class that sets `display` (.auth-provider-tile is inline-flex, .form is
   grid) outranks the browser's own [hidden] rule and breaks that promise
   silently, so on this page it is restated where nothing can outrank it. */
.login-body [hidden] {
  display: none !important;
}

.auth-reveal {
  margin-top: 18px;
}

.auth-sso {
  --auth-sso-chip: #ffffff;
  display: flex;
  width: 100%;
  gap: 14px;
  padding: 10px 16px;
}

.auth-sso__marks {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  flex: none;
}

.auth-sso__chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  background: var(--auth-sso-chip);
  border: 1px solid var(--surface-border-strong);
}

.auth-sso__vt {
  display: block;
  width: 24px;
  height: auto;
}

.auth-sso__ms {
  display: inline-flex;
  align-items: center;
  align-self: stretch;
  padding-left: 10px;
  border-left: 1px solid var(--surface-border-strong);
}

.auth-sso__text {
  display: grid;
  gap: 2px;
  min-width: 0;
  text-align: left;
}

.auth-sso__title {
  font-size: .95rem;
  font-weight: 700;
  line-height: 1.25;
}

.auth-sso__sub {
  color: var(--muted);
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .02em;
  line-height: 1.25;
}

body:not([data-theme="win95"]) .auth-sso:active {
  background: var(--weave-active);
}

.auth-sso:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 3px;
}

/* Not seeded for this provider: the same look as the other provider buttons,
   and login.js explains why on click. */
.auth-sso.is-disabled {
  opacity: .52;
  filter: saturate(0.72);
  cursor: not-allowed;
}

/* On a phone the marks go above the words, so "Versaterm single sign-on" is not
   broken in the middle of "sign-on" beside a column too narrow for it. */
@media (max-width: 480px) {
  .auth-sso {
    flex-direction: column;
    gap: 8px;
  }

  .auth-sso__text {
    text-align: center;
  }
}

/* Win95 keeps its bevels and is left out of Weave; the button follows the
   .auth-provider-button rules above for it. */
body[data-theme="win95"] .auth-sso {
  border-radius: 0 !important;
  background: #c0c0c0 !important;
  color: #000 !important;
  border-top: 2px solid #fff !important;
  border-left: 2px solid #fff !important;
  border-right: 2px solid #808080 !important;
  border-bottom: 2px solid #808080 !important;
}

body[data-theme="win95"] .auth-sso:hover {
  background: #000080 !important;
  color: #fff !important;
}

body[data-theme="win95"] .auth-sso:hover .auth-sso__sub {
  color: inherit;

/* vtp plan preview: the exact files a pull request will contain. Code may
   overflow SIDEWAYS only; the page is the one vertical scroller. */
.cp-vtp-file {
  margin: 0 0 10px;
  padding: 8px 10px;
  border: 1px solid var(--surface-border-strong);
  border-radius: 0;
  background: transparent;
  color: var(--text);
  font-size: 12px;
  line-height: 1.45;
  white-space: pre;
  overflow-x: auto;
}
.cp-vtp-notes {
  margin: 0 0 10px;
  padding-left: 18px;
  color: var(--muted);
}
.cp-vtp-notice {
  margin: 0 0 14px;
  padding: 8px 12px;
  border: 1px solid var(--warn);
  border-radius: 0;
}

/* Infra (VTP): the tables and key/value lists on My apps, the app page and the
   Catalogue. Cells wrap instead of the table scrolling: the document is the only scroller. */
.cp-ws-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8rem;
  margin: 0.4rem 0 0.9rem;
}

.cp-ws-table th {
  text-align: left;
  padding: 0.5rem 0.75rem;
  color: var(--muted);
  font-weight: 500;
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border-bottom: 1px solid var(--surface-border);
}

.cp-ws-table td {
  padding: 0.55rem 0.75rem;
  border-bottom: 1px solid var(--surface-border);
  vertical-align: top;
  overflow-wrap: anywhere;
}

.cp-ws-table tr:last-child td { border-bottom: 0; }

/* A name in the first column stays whole (the other cells still wrap). */
.cp-ws-table td:first-child { overflow-wrap: normal; word-break: keep-all; white-space: nowrap; }

/* One request in the Infra Requests list: a hairline between rows, not a card inside the card. */
.ia-req {
  border-top: 1px solid var(--surface-border);
  padding: 0.7rem 0;
}

.ia-kv {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 0.35rem 1.1rem;
  margin: 0.4rem 0 0.9rem;
}

.ia-kv dt { color: var(--muted); font-size: 0.75rem; }
.ia-kv dd { margin: 0; overflow-wrap: anywhere; }

.cp-ws-copy a { color: var(--cyan); }

@media (max-width: 640px) {
  .ia-kv { grid-template-columns: minmax(0, 1fr); }
}

/* Repos and Infra pages read in IBM Plex Sans, as the design mock does; headings, labels, pills and buttons keep
   the console's mono. The faces are served from the console itself (the CSP allows no outside font host). */
@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 400; font-display: swap; src: url("/assets/fonts/ibm-plex-sans-400.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 500; font-display: swap; src: url("/assets/fonts/ibm-plex-sans-500.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Sans"; font-style: normal; font-weight: 600; font-display: swap; src: url("/assets/fonts/ibm-plex-sans-600.woff2") format("woff2"); }

#panel-repos-list .cp-ws-copy,
#panel-infra-apps .cp-ws-copy,
#panel-repos-list .cp-ws-table td,
#panel-infra-apps .cp-ws-table td,
#panel-repos-list .ia-kv dd,
#panel-infra-apps .ia-kv dd,
#panel-repos-list .form__field > span,
#panel-repos-list .form__field input,
#panel-repos-list .form__field select {
  font-family: "IBM Plex Sans", "Segoe UI", system-ui, sans-serif;
  font-size: 0.875rem;
  line-height: 1.5;
}

#panel-repos-list .cp-ws-table td code,
#panel-infra-apps .cp-ws-table td code {
  font-family: var(--theme-font);
  font-size: 0.8125rem;
}

.cp-admin-flagbar { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.75rem 0 0.25rem; }
.cp-admin-flagbar input[type="search"] { flex: 1 1 18rem; min-width: 0; }
.cp-admin-flaggroup { margin: 0 0 1rem; }
.cp-admin-flaggroup > summary { cursor: pointer; padding: 0.5rem 0; color: var(--text); }
