/* ============================================================================
   Cloboxy — operator console stylesheet
   ----------------------------------------------------------------------------
   Self-contained, classless brand layer for the support-plane console. Replaces
   the previous Pico + override stack (the Layout no longer links Pico). Styles
   the semantic HTML the server-rendered views emit (nav, main, article, table,
   mark[data-status], form controls) directly off the Cloboxy design tokens.

   Served from /console/static/console.css under a strict CSP
   (default-src 'self'; style-src 'self'; no font-src). Two consequences honored
   here:
     • No external @import — the design's Google-Fonts link is blocked, so the
       brand families fall back to a high-quality system stack. To get the real
       faces, self-host Space Grotesk / Hanken Grotesk / JetBrains Mono woff2
       under /console/static and add @font-face rules at the top of this file.
     • No inline <style>/<script> — every visual is pure CSS off the markup.

   Themes: Daylight (light, default) + Deep Plane (dark) via prefers-color-scheme
   and an explicit [data-theme] override. Source: design/tokens/*.css.
   ========================================================================== */

/* ── Design tokens — theme-independent scales ─────────────────────────────── */
:root {
  /* Brand: Cobalt — the signal hue (interactive + brand only). */
  --cobalt-50:#eef1ff; --cobalt-100:#e0e5ff; --cobalt-200:#c4ccff;
  --cobalt-300:#9da9ff; --cobalt-400:#7480ff; --cobalt-500:#4d5dfb;
  --cobalt-600:#3a45ec; --cobalt-700:#2f37c8; --cobalt-800:#2931a0;
  --cobalt-900:#27307e; --cobalt-950:#181c4a;

  /* Neutrals: Slate (cool, faintly blue). */
  --slate-0:#ffffff;  --slate-25:#fafbfd;  --slate-50:#f4f6fa;
  --slate-100:#eaedf3; --slate-150:#dfe3ec; --slate-200:#d2d7e2;
  --slate-300:#b3bacb; --slate-400:#8b93a8; --slate-500:#686f85;
  --slate-600:#4e556a; --slate-700:#3a4054; --slate-800:#272c3d;
  --slate-850:#1d2230; --slate-900:#161a26; --slate-950:#0e111a;
  --slate-1000:#080a11;

  /* Status raw (tuned to read on both themes). */
  --green-light:#1a7f37; --green-dark:#46d97f;
  --amber-light:#9a6700; --amber-dark:#f0b537;
  --red-light:#cf222e;   --red-dark:#ff6b6b;
  --gray-light:#57606a;  --gray-dark:#8b93a8;
  --green-tint-l:#e7f5ec; --green-tint-d:#102a1a;
  --amber-tint-l:#fdf3e0; --amber-tint-d:#2e2310;
  --red-tint-l:#fdeaec;   --red-tint-d:#2e1417;
  --cobalt-tint-l:#eef1ff; --cobalt-tint-d:#181f4a;

  /* Type. Brand families first, system fallback (webfonts blocked by CSP). */
  --font-display:'Space Grotesk', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-body:'Hanken Grotesk', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono:'JetBrains Mono', ui-monospace, 'SF Mono', 'SFMono-Regular', Menlo, Consolas, monospace;

  --text-2xs:0.6875rem; --text-xs:0.75rem; --text-sm:0.8125rem;
  --text-base:0.9375rem; --text-md:1.0625rem; --text-lg:1.25rem;
  --text-xl:1.5rem; --text-2xl:1.9375rem;
  --weight-regular:400; --weight-medium:500; --weight-semibold:600; --weight-bold:700;
  --leading-tight:1.1; --leading-snug:1.28; --leading-normal:1.55;
  --tracking-tight:-0.02em; --tracking-snug:-0.01em;
  --tracking-wide:0.04em; --tracking-wider:0.08em;

  /* Spacing (4px grid), radii, layout, motion. */
  --space-1:0.25rem; --space-2:0.5rem; --space-3:0.75rem; --space-4:1rem;
  --space-5:1.5rem; --space-6:2rem; --space-7:2.5rem; --space-8:3rem;
  --radius-xs:6px; --radius-sm:9px; --radius-md:12px; --radius-lg:18px;
  --radius-xl:24px; --radius-full:999px;
  --container:1180px; --container-narrow:760px; --sidebar-w:240px;
  --dur-fast:120ms; --dur-base:180ms; --dur-slow:260ms;
  --ease-out:cubic-bezier(0.22,0.72,0.2,1);
  --ease-in-out:cubic-bezier(0.5,0,0.2,1);
  --ease-spring:cubic-bezier(0.34,1.4,0.5,1);
}

/* ── Daylight (light, default) ────────────────────────────────────────────── */
:root, [data-theme='light'] {
  color-scheme: light;
  --bg:var(--slate-50); --bg-subtle:var(--slate-100);
  --surface:var(--slate-0); --surface-raised:var(--slate-0);
  --surface-hover:var(--slate-50); --surface-inset:var(--slate-100);
  --text:var(--slate-900); --text-muted:var(--slate-600);
  --text-subtle:var(--slate-400); --text-inverted:var(--slate-0);
  --border:var(--slate-150); --border-strong:var(--slate-300);
  --brand:var(--cobalt-600); --brand-hover:var(--cobalt-700);
  --brand-active:var(--cobalt-800); --brand-contrast:#ffffff;
  --brand-subtle:var(--cobalt-50); --brand-text:var(--cobalt-700);
  --status-ok:var(--green-light); --status-ok-tint:var(--green-tint-l);
  --status-warn:var(--amber-light); --status-warn-tint:var(--amber-tint-l);
  --status-err:var(--red-light); --status-err-tint:var(--red-tint-l);
  --status-idle:var(--gray-light);
  --status-info:var(--cobalt-600); --status-info-tint:var(--cobalt-tint-l);
  --globe-bg:var(--cobalt-200); --globe-sphere:var(--slate-100);
  --focus-ring:0 0 0 3px color-mix(in srgb, var(--cobalt-500) 35%, transparent);
  --shadow-sm:0 1px 3px rgba(16,20,34,0.08), 0 1px 2px rgba(16,20,34,0.04);
  --shadow-md:0 4px 12px rgba(16,20,34,0.08), 0 2px 4px rgba(16,20,34,0.05);
  --shadow-lg:0 12px 32px rgba(16,20,34,0.12), 0 4px 8px rgba(16,20,34,0.06);
  --mesh-dot:rgba(16,20,34,0.05);
  --topbar-bg:color-mix(in srgb, var(--slate-0) 78%, transparent);
}

/* ── Deep Plane (dark) — explicit override + OS preference ─────────────────── */
[data-theme='dark'] {
  color-scheme: dark;
  --bg:var(--slate-950); --bg-subtle:var(--slate-1000);
  --surface:var(--slate-900); --surface-raised:var(--slate-850);
  --surface-hover:var(--slate-850); --surface-inset:var(--slate-1000);
  --text:var(--slate-50); --text-muted:var(--slate-400);
  --text-subtle:var(--slate-500); --text-inverted:var(--slate-950);
  --border:var(--slate-800); --border-strong:var(--slate-700);
  --brand:var(--cobalt-500); --brand-hover:var(--cobalt-400);
  --brand-active:var(--cobalt-300); --brand-contrast:#0b0e17;
  --brand-subtle:var(--cobalt-950); --brand-text:var(--cobalt-300);
  --status-ok:var(--green-dark); --status-ok-tint:var(--green-tint-d);
  --status-warn:var(--amber-dark); --status-warn-tint:var(--amber-tint-d);
  --status-err:var(--red-dark); --status-err-tint:var(--red-tint-d);
  --status-idle:var(--gray-dark);
  --status-info:var(--cobalt-400); --status-info-tint:var(--cobalt-tint-d);
  --globe-bg:var(--cobalt-950); --globe-sphere:var(--slate-1000);
  --focus-ring:0 0 0 3px color-mix(in srgb, var(--cobalt-400) 45%, transparent);
  --shadow-sm:0 1px 3px rgba(0,0,0,0.5), 0 1px 2px rgba(0,0,0,0.4);
  --shadow-md:0 4px 14px rgba(0,0,0,0.5), 0 2px 4px rgba(0,0,0,0.4);
  --shadow-lg:0 16px 40px rgba(0,0,0,0.6), 0 4px 10px rgba(0,0,0,0.45);
  --mesh-dot:rgba(157,169,203,0.08);
  --topbar-bg:color-mix(in srgb, var(--slate-900) 78%, transparent);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    color-scheme: dark;
    --bg:var(--slate-950); --bg-subtle:var(--slate-1000);
    --surface:var(--slate-900); --surface-raised:var(--slate-850);
    --surface-hover:var(--slate-850); --surface-inset:var(--slate-1000);
    --text:var(--slate-50); --text-muted:var(--slate-400);
    --text-subtle:var(--slate-500); --text-inverted:var(--slate-950);
    --border:var(--slate-800); --border-strong:var(--slate-700);
    --brand:var(--cobalt-500); --brand-hover:var(--cobalt-400);
    --brand-active:var(--cobalt-300); --brand-contrast:#0b0e17;
    --brand-subtle:var(--cobalt-950); --brand-text:var(--cobalt-300);
    --status-ok:var(--green-dark); --status-ok-tint:var(--green-tint-d);
    --status-warn:var(--amber-dark); --status-warn-tint:var(--amber-tint-d);
    --status-err:var(--red-dark); --status-err-tint:var(--red-tint-d);
    --status-idle:var(--gray-dark);
    --status-info:var(--cobalt-400); --status-info-tint:var(--cobalt-tint-d);
    --globe-bg:var(--cobalt-950); --globe-sphere:var(--slate-1000);
    --focus-ring:0 0 0 3px color-mix(in srgb, var(--cobalt-400) 45%, transparent);
    --shadow-sm:0 1px 3px rgba(0,0,0,0.5), 0 1px 2px rgba(0,0,0,0.4);
    --shadow-md:0 4px 14px rgba(0,0,0,0.5), 0 2px 4px rgba(0,0,0,0.4);
    --shadow-lg:0 16px 40px rgba(0,0,0,0.6), 0 4px 10px rgba(0,0,0,0.45);
    --mesh-dot:rgba(157,169,203,0.08);
    --topbar-bg:color-mix(in srgb, var(--slate-900) 78%, transparent);
  }
}

/* ── Reset ────────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  background-color: var(--bg);
  /* Faint dot-mesh — the "mission control" backdrop. */
  background-image: radial-gradient(var(--mesh-dot) 1px, transparent 1.2px);
  background-size: 22px 22px;
  background-position: -1px -1px;
  /* NOT background-attachment:fixed — on iOS that leaves the bottom safe-area
     inset unpainted (a black strip under the home indicator). */
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
/* Guarantee the FULL screen — including the iOS bottom safe-area inset — is
   painted with the theme bg, so the home-indicator strip is never a bare black
   web-view band behind the translucent bottom nav. A fixed inset:0 layer covers
   the whole layout viewport (which spans the safe areas under viewport-fit=cover). */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  background: var(--bg);
  z-index: -1;
  pointer-events: none;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
  line-height: var(--leading-tight);
  color: var(--text);
  margin: 0 0 var(--space-3);
  text-wrap: balance;
}
h1 { font-size: var(--text-2xl); }
h2 { font-size: var(--text-xl); }
h3 { font-size: var(--text-lg); }
p { margin: 0 0 var(--space-4); text-wrap: pretty; }
hgroup { margin-bottom: var(--space-5); }
hgroup > * { margin-bottom: var(--space-1); }
hgroup > p { color: var(--text-muted); font-size: var(--text-md); }
small { font-size: var(--text-xs); color: var(--text-muted); }
strong { font-weight: var(--weight-semibold); }

a { color: var(--brand-text); text-decoration: none; }
a:hover { text-decoration: underline; }
::selection { background: color-mix(in srgb, var(--brand) 28%, transparent); }
:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--radius-xs); }

code, kbd, samp { font-family: var(--font-mono); font-size: 0.92em; }
:not(pre) > code {
  background: var(--surface-inset);
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  padding: 0.08em 0.36em;
}

/* ═══════════════════════════════════════════════════════════════════════════
   THE CLOBOXY CONSOLE SHELL — sidebar + main grid (design ref Shell.jsx)
   Ported from design/ui_kits/console/Shell.jsx into static CSS (no <style>
   injection, no inline). Sidebar carries the animated aurora + flow-lines; the
   main column has the sticky frosted topbar and a scrolling content region.
   ═══════════════════════════════════════════════════════════════════════════ */
html { height: 100%; background: var(--bg); } /* iOS overscroll matches the theme */
body { min-height: 100%; }

.cx-app {
  position: relative;
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  grid-template-rows: 100%;
  height: 100vh;
  height: 100dvh; /* browser: dynamic viewport clears the Safari toolbar */
  overflow: hidden;
  background: var(--bg);
  color: var(--text);
}
/* Installed/home-screen app: there is NO Safari toolbar, so 100vh (the LARGE
   viewport) equals the full screen and — unlike 100dvh — it is stable on the
   first paint. This kills the iOS "short viewport on load → dark strip at the
   bottom until you scroll" bug without leaving a permanent gap. */
@media all and (display-mode: standalone) {
  .cx-app { height: 100vh; }
}
/* iOS apple-mobile-web-app-capable doesn't match display-mode:standalone, so
   console-fx.js adds .cx-standalone via navigator.standalone. 100vh = full
   screen here and is stable on first paint (no 100dvh short-viewport gap). */
html.cx-standalone .cx-app { height: 100vh; }
/* Aurora bleed that flows across the whole plane, masked away from the content. */
.cx-app::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(30% 26% at 12% 22%, color-mix(in srgb, #6d52ef 70%, transparent), transparent 60%),
    radial-gradient(26% 22% at 22% 72%, color-mix(in srgb, #4d8dff 60%, transparent), transparent 60%),
    radial-gradient(24% 20% at 6% 52%, color-mix(in srgb, #ff6cd4 54%, transparent), transparent 62%),
    radial-gradient(22% 18% at 30% 40%, color-mix(in srgb, #7c4ddb 50%, transparent), transparent 62%);
  background-size: 150% 150%, 140% 140%, 135% 135%, 130% 130%;
  background-repeat: no-repeat;
  -webkit-mask-image: linear-gradient(90deg, #000 var(--sidebar-w), transparent calc(var(--sidebar-w) + 200px));
  mask-image: linear-gradient(90deg, #000 var(--sidebar-w), transparent calc(var(--sidebar-w) + 200px));
  /* Static: animating background-position + filter:hue-rotate forever pinned
     the GPU (Safari "Graphics & Media"). The gradients alone carry the brand. */
}
@keyframes cx-bgmove {
  0% { background-position: 0% 24%, 100% 76%, 0% 46%, 60% 20%; }
  100% { background-position: 40% 70%, 50% 24%, 30% 68%, 10% 80%; }
}
@keyframes cx-bleed-hue {
  0% { filter: hue-rotate(0deg); }
  50% { filter: hue-rotate(80deg); }
  100% { filter: hue-rotate(0deg); }
}

/* ── Sidebar ──────────────────────────────────────────────────────────────── */
.cx-side {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  background: transparent;
  padding: 18px 14px;
  gap: 6px;
  overflow: hidden;
  min-height: 0;
}
.cx-side > * { position: relative; z-index: 1; }
.cx-side__aurora {
  position: absolute;
  inset: -25% -20% -10%;
  z-index: 0;
  pointer-events: none;
  opacity: 0.55;
  /* No filter:blur — a 30px blur over the blended flow-lines re-rasterized
     every frame on Safari's GPU. Softness comes from the gradient falloff. */
  background:
    radial-gradient(46% 22% at 28% 8%, color-mix(in srgb, var(--cobalt-500) 75%, transparent), transparent 70%),
    radial-gradient(40% 20% at 74% 30%, color-mix(in srgb, #6d52ef 72%, transparent), transparent 70%),
    radial-gradient(52% 26% at 20% 56%, color-mix(in srgb, #2f9bce 66%, transparent), transparent 70%),
    radial-gradient(44% 24% at 72% 82%, color-mix(in srgb, #7c4ddb 66%, transparent), transparent 70%),
    radial-gradient(40% 22% at 40% 100%, color-mix(in srgb, var(--cobalt-400) 64%, transparent), transparent 70%);
  background-size: 200% 200%, 220% 220%, 180% 240%, 240% 200%, 200% 220%;
}
.cx-side__flow {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: 0.5;
}
.cx-side__aurora, .cx-side__flow {
  -webkit-mask-image: linear-gradient(90deg, #000 20%, transparent 78%);
  mask-image: linear-gradient(90deg, #000 20%, transparent 78%);
}
@keyframes cx-aurora-move {
  0% { background-position: 0% 0%, 100% 0%, 0% 100%, 100% 80%, 50% 100%; transform: translateY(-6%) scale(1); }
  50% { background-position: 40% 50%, 50% 40%, 50% 50%, 40% 30%, 30% 50%; }
  100% { background-position: 0% 100%, 100% 80%, 20% 0%, 100% 20%, 70% 0%; transform: translateY(8%) scale(1.15); }
}
@keyframes cx-aurora-hue {
  0% { filter: blur(30px) saturate(1.4) hue-rotate(0deg); }
  50% { filter: blur(30px) saturate(1.6) hue-rotate(90deg); }
  100% { filter: blur(30px) saturate(1.4) hue-rotate(0deg); }
}

.cx-brand { display: flex; align-items: center; justify-content: space-between; padding: 6px 8px 16px; }
.cx-logo { display: flex; align-items: center; gap: 9px; }
.cx-logo__txt {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: 19px;
  letter-spacing: -0.5px;
  color: var(--text);
}
.cx-logo__live { transform-origin: center; transform-box: fill-box; }
@keyframes cx-nodepulse { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } }

.cx-grouplbl {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-subtle);
  padding: 14px 10px 6px;
}
.cx-nav { display: flex; flex-direction: column; gap: 2px; }
.cx-navitem {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 10px;
  border-radius: var(--radius-md);
  cursor: pointer;
  font-family: var(--font-display);
  font-weight: var(--weight-medium);
  font-size: var(--text-sm);
  color: var(--text-muted);
  border: none;
  background: none;
  text-align: left;
  width: 100%;
  position: relative;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.cx-navitem:hover { background: var(--surface-hover); color: var(--text); text-decoration: none; }
.cx-navitem[data-active='true'] { background: var(--brand-subtle); color: var(--brand-text); }
.cx-navitem[data-active='true']::before {
  content: '';
  position: absolute;
  left: -14px;
  top: 8px;
  bottom: 8px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--brand);
}
.cx-sidefoot { margin-top: auto; padding-top: 14px; border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: 4px; }
.cx-logout-form { margin: 0; display: contents; }
.cx-logout { color: var(--text-muted); }
.cx-logout:hover { color: var(--status-err); background: var(--status-err-tint); }

/* ── Main column ──────────────────────────────────────────────────────────── */
/* THE single scroll container (display:block + min-height:0 so it actually
   constrains & scrolls; overflow-x hidden = no stray horizontal bar; overscroll
   contain = no rubber-band into empty space). The sticky topbar is a child, so
   content scrolls UNDER it = glass, while it reserves its own space. */
.cx-main { display: block; min-width: 0; min-height: 0; height: 100%; position: relative; z-index: 1; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; }
.cx-top {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px 28px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  background: color-mix(in srgb, var(--surface) 94%, transparent); /* solid bar — backdrop-filter blur was the #1 Safari GPU cost (re-blur over scroll) */
  box-shadow: 0 1px 0 color-mix(in srgb, #ffffff 10%, transparent) inset;
  /* Sticky inside the scrolling .cx-main: reserves its own space (content starts
     right below it — intervals intact) AND content scrolls UNDER it on scroll,
     so the frosted glass is actually translucent over the content. */
  position: sticky;
  top: 0;
  z-index: 20;
  overflow: hidden;
}
.cx-top::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 38%;
  background: linear-gradient(90deg, transparent, var(--brand), transparent);
  display: none; /* topbar sweep shimmer removed — continuous idle GPU on Safari */
}
@keyframes cx-sweep {
  0% { transform: translateX(-100%); opacity: 0; }
  20%, 80% { opacity: 0.9; }
  100% { transform: translateX(320%); opacity: 0; }
}
.cx-top__logo { display: none; }
.cx-iconbtn.cx-top__theme { display: none; } /* desktop: theme lives in the sidebar footer */
.cx-top__head { min-width: 0; flex: 1; }
.cx-top__title { font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--text-xl); letter-spacing: var(--tracking-snug); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cx-top__sub { font-size: var(--text-sm); color: var(--text-muted); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cx-top__right { margin-left: auto; display: flex; align-items: center; gap: 12px; flex: none; }
.cx-agent {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-family: var(--font-mono);
}
.cx-agent__pulse {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--brand);
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--brand) 60%, transparent);
}
@keyframes cx-ping {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--brand) 55%, transparent); }
  70%, 100% { box-shadow: 0 0 0 7px transparent; }
}
/* Topbar icon buttons (theme, logout) — ghost squares, not primary buttons. */
.cx-iconbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.cx-iconbtn:hover { color: var(--text); background: var(--surface-hover); border-color: var(--border-strong); }
/* Normal flow — .cx-main is the single scroller (NO overflow here, or it becomes
   a nested second scroll container = the "double scroll" bug). console-fx.js
   resets .cx-main.scrollTop to 0 on each boosted page swap. */
.cx-content { padding: 26px 28px 60px; }

/* ── Mobile bottom-nav (sidebar hidden ≤820px) ────────────────────────────── */
.cx-mobnav { display: none; }
@media (max-width: 820px) {
  .cx-app { grid-template-columns: 1fr; }
  .cx-side { display: none; }
  .cx-top { padding: calc(12px + env(safe-area-inset-top)) calc(16px + env(safe-area-inset-right)) 12px calc(16px + env(safe-area-inset-left)); gap: 10px; }
  .cx-top__logo { display: inline-flex; line-height: 0; flex: none; }
  .cx-top__title { font-size: var(--text-lg); }
  .cx-top__sub { display: none; }
  .cx-iconbtn.cx-top__theme { display: inline-flex; } /* theme toggle moves into the topbar on mobile */
  .cx-content { padding: 18px calc(16px + env(safe-area-inset-right)) calc(76px + env(safe-area-inset-bottom)) calc(16px + env(safe-area-inset-left)); }
  .cx-mobnav {
    display: flex;
    position: fixed; /* pinned to the viewport bottom — never moves on content swap */
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 40;
    gap: 4px;
    width: 100%;
    padding: 6px calc(8px + env(safe-area-inset-right)) calc(6px + env(safe-area-inset-bottom)) calc(8px + env(safe-area-inset-left));
    background: color-mix(in srgb, var(--surface) 94%, transparent); /* solid bar — no backdrop blur */
    border-top: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  }
  .cx-mobnav__item {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    padding: 7px 2px;
    border: none;
    background: none;
    cursor: pointer;
    font-family: var(--font-display);
    font-weight: var(--weight-medium);
    font-size: 11px;
    color: var(--text-muted);
    border-radius: var(--radius-md);
    text-decoration: none;
    transition: color var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out);
  }
  .cx-mobnav__item[data-active='true'] {
    color: var(--brand-contrast);
    background: linear-gradient(135deg, #7480ff, #4d5dfb);
    box-shadow: 0 4px 14px color-mix(in srgb, var(--brand) 38%, transparent);
  }
  .cx-mobnav__ic { line-height: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .cx-app::before, .cx-side__aurora, .cx-logo__live, .cx-top::after, .cx-agent__pulse { animation: none; }
}

/* ── Cards (article) + sections ───────────────────────────────────────────── */
article {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--space-5);
  margin-bottom: var(--space-5);
}
article > header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}
article > header :is(h1, h2, h3) { margin-bottom: 0; }
article > header hgroup { margin-bottom: 0; }
/* A leading back-link takes its own full-width line so the title left-aligns
   below it (detail pages), while a card header with title + filter form still
   sits as a space-between row (Fleet). */
article > header > a:first-child {
  flex-basis: 100%;
  margin-bottom: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}
/* Proposal-card headers are inline text (kind · title · [status]) — let them flow. */
.proposal-row > header { display: block; }
/* Key/value tables (ticket detail): row-header cells become a tidy label column. */
tbody th[scope='row'] {
  text-align: left;
  font-family: var(--font-display);
  font-weight: var(--weight-medium);
  color: var(--text-muted);
  white-space: nowrap;
  vertical-align: top;
  width: 1%;
  padding: var(--space-3);
  border-bottom: 1px solid var(--border);
}
/* Proposal payload preview: definition list with mono eyebrow keys. */
dl { margin: 0; }
dt {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-subtle);
  margin-top: var(--space-3);
}
dd { margin: 0 0 var(--space-2); }
article > footer { margin-top: var(--space-4); padding-top: var(--space-4); border-top: 1px solid var(--border); }
section + section { margin-top: var(--space-6); }
section > h2 {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-bottom: var(--space-2);
  margin-bottom: var(--space-4);
  border-bottom: 1px solid var(--border);
}

/* ── Tables — the data grid ───────────────────────────────────────────────── */
table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
}
thead th {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  text-align: left;
  color: var(--text-subtle);
  background: var(--surface-inset);
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
thead th:first-child { border-top-left-radius: var(--radius-sm); }
thead th:last-child { border-top-right-radius: var(--radius-sm); }
tbody td {
  padding: var(--space-3);
  border-bottom: 1px solid var(--border);
  color: var(--text);
  vertical-align: middle;
}
tbody tr { transition: background var(--dur-fast) var(--ease-out); }
tbody tr:hover { background: var(--surface-hover); }
tbody tr:last-child td { border-bottom: none; }

/* ── Status badges — soft-tint pills off the semantic vocabulary ──────────── */
mark[data-status] {
  display: inline-flex;
  align-items: center;
  gap: 0.45ch;
  padding: 0.14rem 0.6rem;
  border-radius: var(--radius-full);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  line-height: 1.5;
  letter-spacing: var(--tracking-snug);
  white-space: nowrap;
  /* default: idle/gray */
  color: var(--status-idle);
  background: color-mix(in srgb, var(--status-idle) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--status-idle) 30%, transparent);
}
mark[data-status]::before {
  content: '';
  width: 6px; height: 6px;
  border-radius: var(--radius-full);
  background: currentColor;
}
/* healthy / terminal-good → ok */
mark[data-status='online'], mark[data-status='acked'], mark[data-status='available'],
mark[data-status='active'], mark[data-status='fulfilled'], mark[data-status='executed'],
mark[data-status='approved'], mark[data-status='applied'], mark[data-status='healthy'],
mark[data-status='ready'] {
  color: var(--status-ok);
  background: var(--status-ok-tint);
  border-color: color-mix(in srgb, var(--status-ok) 32%, transparent);
}
/* in-progress / warning → warn */
mark[data-status='stale'], mark[data-status='pending'], mark[data-status='claimed'],
mark[data-status='delivered'], mark[data-status='provisioning'], mark[data-status='awaiting_approval'],
mark[data-status='coming_soon'], mark[data-status='triaged'], mark[data-status='new'],
mark[data-status='queued'], mark[data-status='dispatching'], mark[data-status='bootstrapping'],
mark[data-status='creating'], mark[data-status='decommissioning'] {
  color: var(--status-warn);
  background: var(--status-warn-tint);
  border-color: color-mix(in srgb, var(--status-warn) 32%, transparent);
}
/* offline / failed / removed → err */
mark[data-status='offline'], mark[data-status='revoked'], mark[data-status='expired'],
mark[data-status='failed'], mark[data-status='rejected'], mark[data-status='cancelled'],
mark[data-status='unavailable'], mark[data-status='refused'] {
  color: var(--status-err);
  background: var(--status-err-tint);
  border-color: color-mix(in srgb, var(--status-err) 32%, transparent);
}
/* archived / inert → idle */
mark[data-status='decommissioned'], mark[data-status='closed'], mark[data-status='never'],
mark[data-status='retired'], mark[data-status='unknown'] {
  color: var(--status-idle);
  background: color-mix(in srgb, var(--status-idle) 14%, transparent);
  border-color: color-mix(in srgb, var(--status-idle) 30%, transparent);
}
/* informational / transport (the agent's own voice) → cobalt info */
mark[data-status='air_gapped'], mark[data-status='bundle'], mark[data-status='relay'],
mark[data-status='info'] {
  color: var(--status-info);
  background: var(--status-info-tint);
  border-color: color-mix(in srgb, var(--status-info) 32%, transparent);
}

/* ── Forms & controls ─────────────────────────────────────────────────────── */
label {
  display: block;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-muted);
  margin-bottom: var(--space-2);
}
input, select, textarea {
  font: inherit;
  font-size: var(--text-sm);
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3);
  width: 100%;
  max-width: 32rem;
  transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
label > input, label > select, label > textarea { margin-top: var(--space-2); }
textarea { min-height: 7rem; resize: vertical; line-height: var(--leading-normal); }
input::placeholder, textarea::placeholder { color: var(--text-subtle); }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: var(--focus-ring);
}
select {
  appearance: none;
  -webkit-appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-subtle) 50%),
                    linear-gradient(135deg, var(--text-subtle) 50%, transparent 50%);
  background-position: calc(100% - 17px) 53%, calc(100% - 12px) 53%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: var(--space-7);
}

/* Buttons — primary cobalt fill; .secondary / [role] = quiet outline. */
button, [role='button'], input[type='submit'], input[type='button'] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5ch;
  font-family: var(--font-display);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-snug);
  line-height: 1.2;
  color: var(--brand-contrast);
  background: var(--brand);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-4);
  cursor: pointer;
  text-decoration: none;
  transition: background var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-spring),
              box-shadow var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
button:hover, [role='button']:hover, input[type='submit']:hover { background: var(--brand-hover); text-decoration: none; }
button:active, [role='button']:active, input[type='submit']:active { background: var(--brand-active); transform: scale(0.98); }
button:disabled, button[aria-disabled='true'] { opacity: 0.52; cursor: not-allowed; transform: none; }
button.secondary, [role='button'].secondary, button.outline {
  color: var(--text);
  background: var(--surface);
  border-color: var(--border-strong);
}
button.secondary:hover, [role='button'].secondary:hover, button.outline:hover {
  background: var(--surface-hover);
  border-color: var(--brand);
  color: var(--brand-text);
}

/* Destructive action (Decommission only) — UI-SPEC Color contract: --status-err reserved for this button. */
button.cx-btn--danger { background: var(--status-err); }
button.cx-btn--danger:hover { background: color-mix(in srgb, var(--status-err) 85%, black); }

/* ── HTMX inline filter forms (declarative attributes) ────────────────────── */
form[hx-get], form[hx-post] { display: flex; align-items: flex-end; gap: var(--space-4); flex-wrap: wrap; margin-bottom: var(--space-4); }
form[hx-get] label, form[hx-post] label { margin: 0; }
form[hx-get] :is(input, select), form[hx-post] :is(input, select) { width: auto; min-width: 12rem; }

/* ── Code / pre wells — wrap long bodies (live finding) ───────────────────── */
pre {
  background: var(--surface-inset);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  word-break: break-word;
}
.md-body { overflow-wrap: anywhere; }
.md-body :first-child { margin-top: 0; }
.md-body :last-child { margin-bottom: 0; }
.md-body h1, .md-body h2, .md-body h3, .md-body h4 {
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-snug);
  margin: 16px 0 6px;
}
.md-body p { margin: 0 0 10px; }
.md-body ul, .md-body ol { margin: 0 0 10px; padding-left: 20px; }
.md-body li { margin: 3px 0; }
.md-body pre { margin: 0 0 10px; }
.md-body a { color: var(--brand-text); }
.md-body strong { font-weight: var(--weight-semibold); }
.md-body blockquote { margin: 0 0 10px; padding-left: 12px; border-left: 3px solid var(--border); color: var(--text-muted); }
.md-body hr { border: none; border-top: 1px solid var(--border); margin: 14px 0; }
/* Long unbroken strings (tokens, URLs) wrap instead of overflowing the card. */
.cx-msg__body { overflow-wrap: anywhere; word-break: break-word; }

/* ── Details / summary ────────────────────────────────────────────────────── */
details {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
}
summary {
  cursor: pointer;
  font-weight: var(--weight-medium);
  color: var(--text);
  list-style-position: inside;
}
summary:hover { color: var(--brand-text); }
details[open] > summary { margin-bottom: var(--space-3); }

/* ── role=alert (login/recovery errors) ───────────────────────────────────── */
[role='alert'] {
  color: var(--status-err);
  background: var(--status-err-tint);
  border: 1px solid color-mix(in srgb, var(--status-err) 32%, transparent);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
}

/* ── Approvals — the human-in-the-loop queue (agent drafts) ───────────────── */
.proposal-row {
  border-left: 3px solid var(--status-info);
}
.proposal-actions {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  align-items: center;
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border);
}

/* ── Region catalog inline mutation controls ──────────────────────────────── */
#region-catalog td form { display: flex; gap: var(--space-2); align-items: center; margin: 0; flex-wrap: nowrap; }
#region-catalog td select { margin: 0; width: auto; min-width: 0; }
#region-catalog td button { margin: 0; width: auto; padding: var(--space-1) var(--space-3); font-size: var(--text-xs); }
#region-catalog details { margin-top: var(--space-4); }

/* ═══════════════════════════════════════════════════════════════════════════
   FLEET DASHBOARD — hero (live signal + health ring), KPI tiles, tabs, table
   (design ref design/ui_kits/console/Fleet.jsx). rAF chart + count-ups are
   driven by console-fx.js; ring arcs/sweep + tile rise are CSS.
   ═══════════════════════════════════════════════════════════════════════════ */
.cx-pagehead { margin-bottom: var(--space-5); }
.cx-pagehead h1 { font-size: var(--text-2xl); }
.cx-pagehead p { color: var(--text-muted); margin: var(--space-1) 0 0; }

.cx-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.cx-card--glow { box-shadow: var(--shadow-md), 0 0 0 1px color-mix(in srgb, var(--brand) 10%, transparent); }
.cx-card--nopad { padding: 0; }

.cx-rise { opacity: 0; transform: translateY(10px); animation: cx-rise 0.5s var(--ease-out) forwards; }
@keyframes cx-rise { to { opacity: 1; transform: none; } }

/* Hero row: signal chart (wide) + health ring. */
.cx-hero { display: grid; grid-template-columns: 1.6fr 1fr; gap: 16px; margin-bottom: 16px; }
.cx-signal { position: relative; overflow: hidden; padding: 20px 22px; min-height: 168px; display: flex; flex-direction: column; }
.cx-signal__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; z-index: 2; position: relative; }
.cx-signal__k { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-subtle); }
.cx-signal__v { font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: 40px; line-height: 1; letter-spacing: -0.02em; margin-top: 8px; }
.cx-signal__chart { position: absolute; left: 0; right: 0; bottom: 0; width: 100%; height: 104px; display: block; }
@keyframes cx-sig-hue { 0% { filter: hue-rotate(0deg); } 50% { filter: hue-rotate(90deg); } 100% { filter: hue-rotate(0deg); } }
.cx-livebadge {
  display: inline-flex; align-items: center; gap: 7px; font-family: var(--font-mono); font-size: 10px;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--brand-text); background: var(--brand-subtle);
  border: 1px solid color-mix(in srgb, var(--brand) 26%, transparent); padding: 4px 10px; border-radius: var(--radius-full);
}
.cx-livebadge::before {
  content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--brand);
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--brand) 60%, transparent);
}

/* Health ring. */
.cx-ring { display: flex; align-items: center; gap: 20px; padding: 18px 22px; height: 100%; }
.cx-ring__track { stroke: var(--surface-inset); }
.cx-ring__dial { position: relative; flex: none; display: grid; place-items: center; }
.cx-ring__center { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; pointer-events: none; }
.cx-ring__pct { font-family: var(--font-display); font-weight: var(--weight-bold); font-size: 30px; letter-spacing: -0.03em; color: var(--text); line-height: 1; }
.cx-ring__pct i { font-style: normal; font-size: 15px; font-weight: var(--weight-semibold); color: var(--text-muted); margin-left: 1px; }
.cx-ring__cap { font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-subtle); margin-top: 3px; }
.cx-ring__sweep { transform-origin: 58px 58px; transform-box: view-box; }
@keyframes cx-ring-rot { to { transform: rotate(360deg); } }
.cx-ring__legend { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.cx-ring__item { display: flex; align-items: center; gap: 8px; font-size: var(--text-sm); color: var(--text-muted); }
.cx-ring__item strong { font-family: var(--font-display); font-weight: var(--weight-semibold); color: var(--text); min-width: 14px; }
.cx-ring__item--total { margin-top: 4px; padding-top: 9px; border-top: 1px solid var(--border); }
.cx-ring__item--total .cx-ring__lblt, .cx-ring__item--total strong { color: var(--text); }
.cx-ring__dot { width: 9px; height: 9px; border-radius: 3px; flex: none; }

/* KPI stat tiles. */
.cx-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-bottom: 24px; }
.cx-stat { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); padding: 16px 18px; }
.cx-stat__k { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-subtle); display: flex; align-items: center; gap: 7px; }
.cx-stat__v { font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: 30px; line-height: 1.1; margin-top: 8px; letter-spacing: -0.02em; color: var(--text); }
.cx-stat__d { font-size: var(--text-xs); color: var(--text-muted); margin-top: 4px; }
.cx-ic-ok { color: var(--status-ok); }
.cx-ic-warn { color: var(--status-warn); }
.cx-ic-brand { color: var(--brand-text); }
.cx-stat[data-tone='ok'] .cx-stat__v { color: var(--status-ok); }
.cx-stat[data-tone='warn'] .cx-stat__v { color: var(--status-err); }

/* ── Deploys panel (Plan 27-06, PANEL-01/PANEL-04) ─────────────────────────── */
/* Globe hero card / Regions-strip fallback — never both. globe.js only ever
   ADDS `.cx-globe--unsupported` to `.cx-globe` on real WebGL init failure; it
   never touches `.cx-regionsstrip`. Visibility is therefore CSS-driven:
   `.cx-globe` renders responsively at every viewport width (operator wants the
   globe on mobile too); `.cx-regionsstrip` is hidden by default and only shown
   when the globe reports itself unsupported. */
.cx-globehero { display: flex; flex-direction: column; gap: var(--space-4); margin-bottom: var(--space-6); }
.cx-globe { position: relative; aspect-ratio: 16 / 9; border-radius: var(--radius-md); overflow: hidden; background: var(--globe-bg); }
/* touch-action:none — the hand-rolled pointer-drag rotation in globe.js must
   own touch gestures on the canvas instead of the browser treating a drag as a
   page-scroll, now that the globe also renders on mobile viewports. */
.cx-globe canvas { display: block; width: 100%; height: 100%; touch-action: none; }
.cx-globe--unsupported canvas { display: none; }
/* Reduced height on narrow viewports (16:9 stays quite tall at phone widths). */
@media (max-width: 767px) {
  .cx-globe { aspect-ratio: 4 / 3; }
}
.cx-globe__legend {
  position: absolute;
  top: var(--space-3);
  left: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--surface-inset) 80%, transparent);
  font-size: var(--text-2xs);
  color: var(--text);
}
.cx-globe__legenditem { display: flex; align-items: center; gap: 6px; }
.cx-globe__dot { width: 8px; height: 8px; border-radius: var(--radius-full); flex: none; background: var(--status-idle); }
.cx-globe__dot[data-tone='ok'] { background: var(--status-ok); }
.cx-globe__dot[data-tone='warn'] { background: var(--status-warn); }
.cx-globe__dot[data-tone='err'] { background: var(--status-err); }
.cx-globe__dot[data-tone='idle'] { background: var(--status-idle); }
.cx-globe__dot[data-tone='home'] { background: var(--brand); transform: rotate(45deg); border-radius: 2px; }
.cx-pillrow { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.cx-regionpill { display: inline-flex; align-items: center; gap: 6px; }
.cx-regionpill[data-active='true'] {
  outline: 2px solid var(--brand);
  outline-offset: 1px;
}
.cx-jobstep__err { color: var(--status-err); }
.cx-actionresult { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3); }
.cx-regionsstrip { display: none; }
.cx-globehero:has(.cx-globe--unsupported) .cx-globe { display: none; }
.cx-globehero:has(.cx-globe--unsupported) .cx-regionsstrip { display: block; }
/* Section-to-section vertical rhythm on the deploys page specifically (UI-SPEC
   spacing table: space-7/40px) — scoped so Fleet's shared .cx-stats keeps its
   own existing rhythm. */
.cx-deploys .cx-stats { margin-bottom: var(--space-7); }

/* Toolbar + product tabs — UNDERLINE tabs with an animated active bar
   (design ref components/navigation/Tabs.jsx), NOT a segmented pill. */
.cx-toolbar { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; flex-wrap: wrap; max-width: 100%; }
.cx-tabs {
  display: flex;
  gap: var(--space-1);
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
  border-bottom: 1px solid var(--border);
}
.cx-tabs::-webkit-scrollbar { display: none; }
.cx-tab {
  position: relative;
  flex: none;
  white-space: nowrap;
  background: none;
  border: none;
  cursor: pointer;
  text-decoration: none;
  font-family: var(--font-display);
  font-weight: var(--weight-medium);
  font-size: var(--text-sm);
  color: var(--text-muted);
  padding: var(--space-3);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  transition: color var(--dur-fast) var(--ease-out);
}
.cx-tab:hover { color: var(--text); text-decoration: none; }
.cx-tab[data-active='true'] { color: var(--brand-text); }
.cx-tab::after {
  content: '';
  position: absolute;
  left: var(--space-2);
  right: var(--space-2);
  bottom: -1px;
  height: 2px;
  background: var(--brand);
  border-radius: 2px;
  transform: scaleX(0);
  transform-origin: center;
  transition: transform var(--dur-base) var(--ease-out);
}
.cx-tab[data-active='true']::after { transform: scaleX(1); }

/* Product tag pill. */
.cx-tag {
  display: inline-flex; align-items: center; font-family: var(--font-mono); font-size: var(--text-2xs); font-weight: var(--weight-medium);
  padding: 2px 9px; border-radius: var(--radius-full); color: var(--brand-text); background: var(--brand-subtle);
  border: 1px solid color-mix(in srgb, var(--brand) 24%, transparent);
}
.cx-tag[data-product='neksur'] {
  color: #8a6cff; background: color-mix(in srgb, #6d52ef 14%, transparent);
  border-color: color-mix(in srgb, #6d52ef 30%, transparent);
}

/* Dashboard table — EXACT port of the reference .cx-table (design/ui_kits/console/Fleet.jsx).
   The reference header is NOT framed: no inset background, no radius — just a hairline
   bottom border. Override the global thead th (which DOES frame) for these tables. */
.cx-dtable thead th {
  background: none;
  border-radius: 0;
  font-weight: var(--weight-medium);
  padding: 10px 16px;
}
.cx-dtable tbody td { padding: 12px 16px; }
.cx-dtable tbody tr {
  cursor: pointer;
  opacity: 0;
  transform: translateX(-8px);
  animation: cx-rowin 0.42s var(--ease-out) forwards;
  /* Cobalt gradient sweeps across the row on hover (design ref Fleet.jsx). */
  background-image: linear-gradient(90deg, color-mix(in srgb, #4d5dfb 16%, transparent), color-mix(in srgb, #6d52ef 9%, transparent) 46%, transparent 82%);
  background-repeat: no-repeat;
  background-position: 0 0;
  background-size: 0% 100%;
  transition: background-size 0.45s var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}
.cx-dtable tbody tr:last-child td { border-bottom: none; }
/* Hover = the animated cobalt gradient sweep (background-size 0→100%, transitioned)
   + the brand rail. background-color stays transparent so the global solid
   tbody tr:hover surface-hover (which would SNAP in, killing the animation)
   never wins on these tables. */
.cx-dtable tbody tr:hover { background-color: transparent; background-size: 100% 100%; box-shadow: inset 3px 0 0 0 var(--brand); }
@keyframes cx-rowin { to { opacity: 1; transform: none; } }
/* Staggered cascade — reference uses inline animationDelay = 140 + i*45ms per row.
   CSP forbids inline styles, so mirror that ramp with nth-child rules (base 0.06s, +45ms). */
.cx-dtable tbody tr:nth-child(1) { animation-delay: 0.06s; }
.cx-dtable tbody tr:nth-child(2) { animation-delay: 0.105s; }
.cx-dtable tbody tr:nth-child(3) { animation-delay: 0.15s; }
.cx-dtable tbody tr:nth-child(4) { animation-delay: 0.195s; }
.cx-dtable tbody tr:nth-child(5) { animation-delay: 0.24s; }
.cx-dtable tbody tr:nth-child(6) { animation-delay: 0.285s; }
.cx-dtable tbody tr:nth-child(7) { animation-delay: 0.33s; }
.cx-dtable tbody tr:nth-child(8) { animation-delay: 0.375s; }
.cx-dtable tbody tr:nth-child(9) { animation-delay: 0.42s; }
.cx-dtable tbody tr:nth-child(10) { animation-delay: 0.465s; }
.cx-dtable tbody tr:nth-child(11) { animation-delay: 0.51s; }
.cx-dtable tbody tr:nth-child(12) { animation-delay: 0.555s; }
.cx-dtable tbody tr:nth-child(13) { animation-delay: 0.6s; }
.cx-dtable tbody tr:nth-child(14) { animation-delay: 0.645s; }
.cx-dtable tbody tr:nth-child(n + 15) { animation-delay: 0.69s; }
.cx-namecell { display: inline-flex; align-items: center; gap: 11px; text-decoration: none; }
.cx-namecell:hover { text-decoration: none; }
.cx-name { font-family: var(--font-mono); font-weight: var(--weight-semibold); font-size: var(--text-sm); color: var(--text); transition: color var(--dur-fast) var(--ease-out); }
.cx-dtable tbody tr:hover .cx-name { color: var(--brand-text); }
.cx-chip { line-height: 0; flex: none; }
.cx-mono { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-muted); }
.cx-chev { text-align: right; color: var(--text-subtle); width: 1%; }
/* Section heading (e.g. Region catalog) — matches reference .cx-sectionhead:
   icon + title, NO underline border, 30px above / 14px below. */
.cx-fleet > section { margin-top: 30px; }
.cx-fleet section > h2 {
  font-size: var(--text-lg);
  border-bottom: none;
  padding-bottom: 0;
  margin-bottom: 14px;
  gap: 10px;
}

/* Class replacements for CSP-forbidden inline styles (style-src 'self' strips
   every style="" attribute, so these MUST live in the stylesheet). */
.cx-genicon { flex: none; display: block; }
.cx-ml-auto { margin-left: auto; }
.cx-rise--d80 { animation-delay: 80ms; }
.cx-rise--d120 { animation-delay: 120ms; }

@media (max-width: 820px) {
  /* overflow-x is handled by .cx-main (the scroller); .cx-content MUST stay
     overflow:visible so it does NOT become a second nested scroll container. */
  .cx-hero { grid-template-columns: 1fr; }
  .cx-stats { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .cx-stat__v { font-size: 26px; }
  .cx-detail { gap: 16px; }
  .cx-signal__v { font-size: 34px; }
}
@media (prefers-reduced-motion: reduce) {
  .cx-signal__chart, .cx-ring__sweep, .cx-rise, .cx-dtable tbody tr, .cx-livebadge::before { animation: none; }
  .cx-rise { opacity: 1; transform: none; }
  .cx-dtable tbody tr { opacity: 1; transform: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   TICKETS + APPROVALS (design ref Tickets.jsx / Approvals.jsx)
   ═══════════════════════════════════════════════════════════════════════════ */
/* Shared card internals. */
.cx-card__head { padding: 14px 18px; border-bottom: 1px solid var(--border); font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--text-base); }
.cx-card__body { padding: 16px 18px; }
.cx-mt { margin-top: 20px; }
.cx-mb { margin-bottom: 8px; }
.cx-muted { color: var(--text-muted); font-size: var(--text-sm); margin: 0; }
.cx-hint { font-size: var(--text-xs); color: var(--text-subtle); margin-top: 8px; }
.cx-empty-row { padding: var(--space-5); color: var(--text-muted); margin: 0; }
.cx-btn-sec {
  display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-display); font-weight: var(--weight-semibold);
  font-size: var(--text-sm); color: var(--text); background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius-md); padding: 7px 14px; cursor: pointer; text-decoration: none; list-style: none;
}
.cx-btn-sec:hover { background: var(--surface-hover); border-color: var(--brand); color: var(--brand-text); text-decoration: none; }

/* Tickets queue. */
.cx-ttitle { font-weight: var(--weight-semibold); font-size: var(--text-sm); color: var(--text); display: block; }
.cx-subid { margin-top: 2px; }
.cx-prio { font-family: var(--font-mono); font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: 0.04em; }
.cx-prio[data-p='high'], .cx-prio[data-p='urgent'] { color: var(--status-err); }
.cx-prio[data-p='medium'] { color: var(--status-warn); }
.cx-prio[data-p='low'] { color: var(--text-subtle); }
.cx-src { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-muted); }

/* Ticket detail. */
.cx-back { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-display); font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--text-muted); padding: 6px 0; margin-bottom: 14px; text-decoration: none; }
.cx-back:hover { color: var(--text); text-decoration: none; }
.cx-tk-head { margin-bottom: 20px; }
.cx-tk-head h1 { font-size: var(--text-2xl); letter-spacing: -0.02em; margin: 0; }
.cx-tk-badges { display: flex; gap: 8px; margin-top: 10px; align-items: center; flex-wrap: wrap; }
.cx-detail { display: grid; grid-template-columns: 1fr 320px; gap: 24px; align-items: start; }
@media (max-width: 820px) { .cx-detail { grid-template-columns: 1fr; } }
.cx-meta { display: flex; flex-direction: column; }
.cx-meta__row { display: flex; justify-content: space-between; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--border); font-size: var(--text-sm); }
.cx-meta__row:last-child { border-bottom: none; }
.cx-meta__k { color: var(--text-subtle); font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.04em; text-transform: uppercase; }
.cx-msg { display: flex; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--border); }
.cx-msg:last-child { border-bottom: none; }
.cx-msg__body { font-size: var(--text-sm); color: var(--text); line-height: 1.55; }
.cx-msg__head { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-subtle); margin-bottom: 4px; }
.cx-sens { display: flex; align-items: center; gap: 10px; }
.cx-sens__bar { flex: 1; height: 6px; border-radius: 999px; background: var(--surface-inset); overflow: hidden; }
.cx-sens__fill { height: 100%; border-radius: 999px; }
.cx-prop { padding: 14px; border: 1px solid var(--border); border-radius: var(--radius-md); margin-bottom: 12px; background: var(--bg-subtle); }
.cx-prop__head { display: flex; align-items: center; gap: 9px; margin-bottom: 8px; }
.cx-prop__kind { font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--text-sm); }

/* Approvals. */
.cx-banner {
  display: flex; align-items: flex-start; gap: 12px; margin-bottom: 20px; padding: 14px 16px; color: var(--brand-text);
  background: var(--brand-subtle); border-radius: var(--radius-md); border: 1px solid color-mix(in srgb, var(--brand) 22%, transparent);
}
.cx-banner > div { font-size: var(--text-sm); color: var(--text); }
.cx-banner strong { font-family: var(--font-display); }
.cx-pwrap { overflow: hidden; margin-bottom: 16px; }
.cx-pcard { animation: cx-rise 0.5s var(--ease-out) both; }
.cx-card--raised { box-shadow: var(--shadow-md); }
.cx-pmeta-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 14px 18px; border-bottom: 1px solid var(--border); }
.cx-pmeta { display: flex; align-items: center; gap: 10px; }
.cx-pkind { font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--text-base); }
.cx-psub { font-size: var(--text-xs); color: var(--text-muted); margin-top: 2px; }
.cx-pbadges { display: flex; gap: 8px; align-items: center; flex: none; }
.cx-avatar { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; border-radius: 50%; flex: none; }
.cx-avatar--agent { background: var(--brand-subtle); color: var(--brand-text); border: 1px solid color-mix(in srgb, var(--brand) 26%, transparent); }
.cx-payload { margin: 16px 18px; background: var(--surface-inset); border: 1px solid var(--border); border-radius: var(--radius-md); overflow: hidden; }
.cx-payload__field { border-bottom: 1px solid var(--border); }
.cx-payload__field:last-child { border-bottom: none; }
.cx-payload__k { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-subtle); padding: 8px 14px 0; }
.cx-payload__v { font-size: var(--text-sm); color: var(--text); white-space: pre-wrap; line-height: 1.55; padding: 4px 14px 12px; font-family: var(--font-body); overflow-wrap: anywhere; }
.cx-payload__v.mono { font-family: var(--font-mono); font-size: var(--text-xs); }
.cx-edit {
  width: 100%; font-family: var(--font-body); font-size: var(--text-sm); color: var(--text); background: var(--surface);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm); padding: 8px 10px; resize: vertical; line-height: 1.5; margin-top: var(--space-2);
}
.cx-pactions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 0 18px 16px; }
/* Approval cards use single-button ACTION forms + a stacked EDIT form. Neither
   may inherit the search/region multi-field form layout (flex row + flex-end +
   margin-bottom + min-width:12rem + mobile column-stretch) — that is what made
   the buttons sit crooked and the edit fields lay out sideways. Reset it. */
.cx-pwrap form { display: block; margin: 0; gap: 0; align-items: initial; flex-wrap: nowrap; margin-bottom: 0; }
.cx-pwrap form button { width: auto; min-width: 0; }
.cx-editwrap form label { display: block; margin-top: var(--space-3); }
.cx-editwrap form :is(input, textarea) { width: 100%; min-width: 0; }
.cx-editwrap { border: none; background: none; padding: 0; margin: 0; }
.cx-editwrap > summary { display: inline-flex; }
.cx-editwrap[open] { display: block; width: 100%; }
.cx-editwrap[open] > summary { margin-bottom: var(--space-3); }
.cx-editwrap form label { margin-top: var(--space-3); }
.cx-reject { margin-left: auto; display: inline; }
.cx-reject button.ghost { background: transparent; color: var(--text-muted); border: 1px solid transparent; }
.cx-reject button.ghost:hover { background: var(--status-err-tint); color: var(--status-err); }
.cx-empty { text-align: center; padding: 60px 20px; color: var(--text-muted); }
.cx-empty > svg { color: var(--status-ok); display: block; margin: 0 auto 12px; }
.cx-empty__title { font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--text-lg); color: var(--text); }
.cx-empty p { margin-top: 4px; }
.cx-note { margin: 0; color: var(--text-muted); line-height: 1.55; }
.cx-note strong { color: var(--text); font-weight: var(--weight-semibold); }
.cx-note .cx-mono { color: var(--text); }

/* ── Pre-auth pages (login / setup): centered card on the dot-mesh ──────────
   <body class="auth"> (no shell). Plain BLOCK centering — a block element at
   width:100% can never exceed its container, so this is overflow-proof. */
body.auth { display: block; }
body.auth > main {
  display: block;
  max-width: none;
  padding: max(8vh, var(--space-6)) var(--space-4) var(--space-6);
}
body.auth > main > article {
  width: 100%;
  max-width: 26rem;
  margin-inline: auto;
}
body.auth > main > article > button { width: 100%; }
/* Brand title must wrap, never push the card wide on a phone. */
body.auth > main > article h1 { font-size: var(--text-xl); overflow-wrap: anywhere; }

/* ── Deployment detail: each section is its own card (design parity) ───────── */
.cx-deploy section {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 18px 20px;
  margin: 0 0 16px;
}
.cx-deploy section + section { margin-top: 0; }
.cx-deploy section > h2 { margin-top: 0; font-size: var(--text-lg); border-bottom: none; padding-bottom: 0; margin-bottom: 14px; display: flex; align-items: baseline; gap: 9px; }
.cx-deploy section > h2 .cx-count { font-family: var(--font-mono); font-size: var(--text-2xs); font-weight: var(--weight-medium); color: var(--text-subtle); background: var(--surface-inset); border: 1px solid var(--border); border-radius: var(--radius-full); padding: 1px 8px; }
.cx-deploy section table { margin-top: 0; }
.cx-deploy details { margin-top: 14px; }

/* Top-of-page summary tiles (tickets / consumption / events). Reuses .cx-stat
   visuals but its own responsive 3-up grid; no .cx-rise so the numbers are
   never animation-gated to invisible. */
.cx-deploy__summary { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); margin-bottom: 18px; }

/* Event-type grouping chips under the (moved-down) Events heading. */
.cx-evgroups { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.cx-evgroup { display: inline-flex; align-items: center; gap: 7px; padding: 3px 10px; border-radius: var(--radius-full); background: var(--surface-inset); border: 1px solid var(--border); font-family: var(--font-mono); font-size: var(--text-2xs); }
.cx-evgroup__t { color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; }
.cx-evgroup__n { color: var(--text); font-weight: var(--weight-semibold); }

/* Key/value overview grid — the Cloboxy "definition" card (replaces vertical th/td tables). */
.cx-kv { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 0 26px; }
.cx-kv__row { display: flex; flex-direction: column; gap: 3px; padding: 9px 0; border-bottom: 1px solid var(--border); min-width: 0; }
.cx-kv__k { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-subtle); }
.cx-kv__v { font-size: var(--text-sm); color: var(--text); overflow-wrap: anywhere; }

/* Compact action rows (export / mark air-gapped / import) — no raw stacked forms. */
.cx-deploy__actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.cx-deploy__actions form { display: inline-flex; gap: 8px; align-items: center; margin: 0; }
.cx-deploy__actions select { min-width: 130px; }

/* ── "New deploy" intake card (operator-initiated provision) ───────────────
   Field spec follows the design system's forms components verbatim
   (design/components/forms/Input.jsx + Select.jsx): display-font text-sm
   medium labels in normal case, 38px controls on --surface with
   --border-strong and the shared focus ring. Pico's width:100% +
   margin-bottom on controls is reset (same requirement as #region-catalog). */
/* .cx-card has NO intrinsic padding (tiles/tables pad themselves) — without
   this the form content sat flush against the card border (operator-reported
   2026-07-06 'текст вылезает за границы'). 16/18 matches .cx-stat rhythm. */
.cx-newdeploy { margin-bottom: var(--space-6); padding: 16px 18px; }
.cx-newdeploy__title { font-family: var(--font-display); font-weight: var(--weight-semibold); font-size: var(--text-md); margin: 0 0 14px 0; }
/* form.-prefixed everywhere below: the GLOBAL `form[hx-post]` rules
   (display/gap/margin at 0-1-1, and `:is(input,select){min-width:12rem}` at
   0-1-2) out-specified the bare-class versions — on the live page every
   select ballooned to 192px min and the row wrapped crooked (operator-
   reported; the local preview lacked the hx-post attribute and hid it). */
form.cx-newdeploy__form { display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: flex-end; margin: 0 0 var(--space-3) 0; }
form.cx-newdeploy__form :is(select, input, button) {
  margin: 0; width: auto; min-width: 0;
  height: 38px; padding-top: 0; padding-bottom: 0;
  /* text-base in controls — Input/Select spec (text-sm was visibly off scale). */
  font-family: var(--font-body); font-size: var(--text-base);
  /* background-COLOR only — pico's select chevron is a background-image
     and the shorthand would wipe it. */
  background-color: var(--surface); color: var(--text);
  border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  box-shadow: none;
  line-height: 36px;
}
form.cx-newdeploy__form :is(select, input) { padding-inline: var(--space-3); min-width: 0; }
/* Product/cloud/region values are identifiers — mono per the Input spec's
   `mono` variant ("IDs, tokens, regions"); the canonical forms card renders
   Region exactly this way. */
form.cx-newdeploy__form select { padding-right: 36px; font-family: var(--font-mono); font-size: var(--text-sm); }
form.cx-newdeploy__form :is(select, input):hover { border-color: var(--text-subtle); }
form.cx-newdeploy__form :is(select, input):focus { outline: none; border-color: var(--brand); box-shadow: var(--focus-ring); }
form.cx-newdeploy__form input::placeholder { color: var(--text-subtle); }
.cx-newdeploy__field { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
/* Label dialect of THIS page (stat tiles' .cx-stat__k, .cx-dtable thead):
   mono 10px uppercase subtle — the design-kit's normal-case sans label read
   foreign next to them (operator feedback). */
.cx-newdeploy__field label {
  font-family: var(--font-mono); font-size: 10px;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-subtle);
  font-weight: var(--weight-regular);
  margin: 0; line-height: 1;
}
form.cx-newdeploy__form .cx-newdeploy__field select { min-width: 132px; }
.cx-newdeploy__field--grow { flex: 1 1 150px; }
.cx-newdeploy__field--grow input { width: 100%; }
/* button.-prefixed: must out-specify the shared control rule above
   (0-1-1) — a bare class (0-1-0) loses and the button renders ghost.
   Metrics = design-system Button --md (text-base, 0 space-4, 38px). */
form.cx-newdeploy__form button.cx-newdeploy__submit {
  flex: none; padding-inline: var(--space-5); margin-left: auto;
  background: var(--brand); color: var(--brand-contrast); border-color: transparent;
  font-family: var(--font-display); font-weight: var(--weight-semibold);
  font-size: var(--text-base);
}
form.cx-newdeploy__form button.cx-newdeploy__submit:hover { background: var(--brand-hover); }
.cx-newdeploy__hint { color: var(--text-subtle); font-size: var(--text-xs); margin: 0; }
@media (max-width: 768px) {
  form.cx-newdeploy__form { flex-direction: column; align-items: stretch; }
  form.cx-newdeploy__form :is(input, select, button) { width: 100%; }
  .cx-newdeploy__field--grow { flex: 1 1 auto; }
  form.cx-newdeploy__form button.cx-newdeploy__submit { margin-left: 0; margin-top: var(--space-2); }
}
.cx-deploy__import { margin-top: 14px; display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.cx-deploy__import label { font-family: var(--font-mono); font-size: var(--text-2xs); letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-subtle); }
.cx-deploy__note { color: var(--text-muted); font-size: var(--text-sm); margin: 0; }

/* ── Mobile (≤768px): content-region tweaks (shell handles its own ≤820px) ── */
@media (max-width: 768px) {
  article { padding: var(--space-4); border-radius: var(--radius-md); }
  .cx-deploy section { padding: 14px; }
  form[hx-get] :is(input, select, button), form[hx-post] :is(input, select, button) { min-width: 0; width: 100%; }
  form[hx-get], form[hx-post] { flex-direction: column; align-items: stretch; }
  article > header { flex-direction: column; align-items: stretch; gap: var(--space-2); }
  pre, .md-body { white-space: pre-wrap; }
  .md-body * { white-space: normal; }

  /* ALL data tables inside the shell STACK into cards on phones — no horizontal
     scroll. Dashboard tables (.cx-dtable) also show per-cell labels. */
  .cx-fleet table thead, .cx-deploys .cx-dtable thead { display: none; }
  .cx-fleet table, .cx-fleet table tbody,
  .cx-deploys .cx-dtable, .cx-deploys .cx-dtable tbody { display: block; width: 100%; }
  .cx-fleet table tr,
  .cx-deploys .cx-dtable tr {
    display: block;
    padding: 12px 14px;
    border-bottom: 1px solid var(--border);
    animation: none;
    opacity: 1;
    transform: none;
  }
  .cx-fleet table tr:hover, .cx-deploys .cx-dtable tr:hover { box-shadow: none; }
  .cx-fleet table td,
  .cx-deploys .cx-dtable td {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    padding: 4px 0;
    border: none;
    text-align: right;
    white-space: normal;
    overflow-wrap: anywhere;
    min-width: 0;
  }
  .cx-fleet table td[data-label]::before,
  .cx-deploys .cx-dtable td[data-label]::before {
    content: attr(data-label);
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-subtle);
    text-align: left;
    flex: none;
  }
  /* Actions cell: forms stack under the label, full width. */
  .cx-deploys .cx-dtable td.cx-actioncell { flex-direction: column; align-items: stretch; text-align: left; }
  .cx-deploys .cx-dtable td.cx-actioncell .cx-deploy__actions { flex-direction: column; align-items: stretch; }
  .cx-deploys .cx-dtable td.cx-actioncell form { display: flex; flex-direction: column; align-items: stretch; }
  /* Name cell spans the row full-width (icon + title), no label, left-aligned. */
  .cx-fleet table td.cx-namecol { padding-bottom: 8px; text-align: left; }
  .cx-fleet table td.cx-namecol::before { display: none; }
  .cx-fleet table .cx-namecell { width: 100%; }
  .cx-fleet table td.cx-chev { display: none; }
  /* Region "set status" action cell: the label sits on its own line, then a
     full-width [select][Set] control row — NOT a centered floating dropdown
     detached from the rest of the stacked row. */
  .cx-fleet table td form { width: 100%; }
  .cx-fleet table td.cx-actioncell { display: block; text-align: left; padding-top: 10px; }
  .cx-fleet table td.cx-actioncell::before { display: block; margin-bottom: 6px; }
  #region-catalog td.cx-actioncell form {
    width: 100%;
    flex-direction: row;     /* override the mobile form[hx-post] column stack */
    align-items: center;     /* override the desktop align-items:center vertical centering */
    justify-content: flex-start;
    flex-wrap: nowrap;
    gap: 8px;
  }
  #region-catalog td.cx-actioncell select { flex: 1; min-width: 0; }
  #region-catalog td.cx-actioncell button { flex: none; width: auto; }
}

/* ── Reduced motion ───────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}
