/*!
 * Wolf Cloud Style System
 * Canonical design baseline for Wolf Cloud frontend projects.
 *
 * Maintainer: Liam Wolf <liam@wolf-cloud.com>
 * Repository: git.wolf-cloud.com/liamwolf/wolf-cloud-style-system.git
 *
 * Copyright (C) 2026 Liam Wolf
 * Licensed under the GNU Affero General Public License v3.0 or later.
 * You should have received a copy of the AGPL along with this file.
 * If not, see <https://www.gnu.org/licenses/agpl-3.0.html>.
 *
 * Design principles:
 * - Dark, atmospheric, technical, premium.
 * - Strong blue brand accent with restrained status colors.
 * - Soft glass surfaces over a deep layered background.
 * - IBM Plex Sans for body copy, IBM Plex Mono for UI labels and controls.
 * - High clarity, low clutter, controlled glow.
 * - Rounded corners, thin translucent borders, soft depth.
 * - Motion should feel calm and precise, never playful or noisy.
 *
 * Theme:
 * - Default is dark mode.
 * - Light mode: set data-theme="light" on the <html> element.
 *
 * This file is generated by wolf-cloud/build.sh from the modular sources
 * under wolf-cloud/{tokens,base,components}/ — see manifest.json for the
 * concatenation order. Do not hand-edit the generated bundle; edit the
 * source modules and re-run build.sh.
 *
 */

/* -- Fonts (Wolf Cloud CDN) ----------------------------------- */
@import url("https://static.wolf-cloud.com/fonts/ibmplexsans/fonts.css");
@import url("https://static.wolf-cloud.com/fonts/ibmplexmono/fonts.css");

:root {
  color-scheme: dark;

  /* Core palette */
  --ink:         #080c10;
  --ink-2:       #0d1420;
  --surface:     rgba(10, 16, 28, 0.80);
  --surface-2:   rgba(14, 20, 36, 0.60);
  --surface-3:   rgba(18, 28, 46, 0.72);
  --line:        rgba(255, 255, 255, 0.06);
  --line-hi:     rgba(255, 255, 255, 0.11);
  --line-strong: rgba(255, 255, 255, 0.16);

  /* Brand */
  --brand:       #2e7fff;
  --brand-2:     #1d6be0;
  --brand-soft:  #6eb8ff;
  --brand-pale:  #a8d8ff;
  --brand-dim:   rgba(46, 127, 255, 0.18);
  --brand-glow:  rgba(46, 127, 255, 0.30);
  --brand-ring:  rgba(46, 127, 255, 0.12);

  /* Text */
  --text:        #eef2ff;
  --muted:       rgba(238, 242, 255, 0.50);
  --subtle:      rgba(238, 242, 255, 0.25);
  --text-soft:   rgba(238, 242, 255, 0.78);

  /* Status */
  --ok:          #22c55e;
  --ok-bg:       rgba(34, 197, 94, 0.09);
  --ok-bdr:      rgba(34, 197, 94, 0.25);
  --deg:         #f59e0b;
  --deg-bg:      rgba(245, 158, 11, 0.09);
  --deg-bdr:     rgba(245, 158, 11, 0.25);
  --err:         #ef4444;
  --err-bg:      rgba(239, 68, 68, 0.09);
  --err-bdr:     rgba(239, 68, 68, 0.25);
  --info:        #38bdf8;
  --info-bg:     rgba(56, 189, 248, 0.10);
  --info-bdr:    rgba(56, 189, 248, 0.24);
  --protect:     #a78bfa;
  --protect-bg:  rgba(167, 139, 250, 0.10);
  --protect-bdr: rgba(167, 139, 250, 0.28);

  /* Neutral UI badge state */
  --chip-bdr:    rgba(238, 242, 255, 0.10);
  --chip-bg:     rgba(238, 242, 255, 0.04);
  --chip-text:   rgba(238, 242, 255, 0.35);

  /* Typography */
  --font-sans: "IBM Plex Sans", "Plex Sans", system-ui, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, monospace;

  /* Brand assets */
  --logo:          url("https://static.wolf-cloud.com/logos/wolf-cloud/logo.svg");
  --logo-full:     url("https://static.wolf-cloud.com/logos/wolf-cloud/full-logo.svg");
  --logo-png:      url("https://static.wolf-cloud.com/logos/wolf-cloud/logo.png");
  --logo-full-png: url("https://static.wolf-cloud.com/logos/wolf-cloud/full-logo.png");
  --favicon:       url("https://static.wolf-cloud.com/logos/wolf-cloud/favicon.ico");

  /* Sizing */
  --radius-sm:   6px;
  --radius-md:   10px;
  --radius-lg:   14px;
  --radius-xl:   16px;
  --radius-pill: 999px;

  /* Layout (narrow content pages — docs, forms, admin panels) */
  --page-width: 820px;
  --page-pad-x: 1.5rem;
  --page-pad-y: 4rem;

  /* Layout (wide marketing/landing pages) */
  --gutter: clamp(20px, 4.5vw, 64px);
  --shell:  min(1240px, 100vw - 2 * var(--gutter));
  --rhythm: clamp(96px, 13vw, 180px);

  /* Chrome surfaces (sticky headers, dropdown menus — blurred over content) */
  --nav-bg:  rgba(8, 12, 16, 0.62);
  --menu-bg: rgba(11, 16, 27, 0.97);

  /* Shadows */
  --shadow-card:      0 8px 40px rgba(4, 8, 20, 0.50);
  --shadow-card-soft: 0 4px 18px rgba(4, 8, 20, 0.30);
  --shadow-brand:     0 2px 12px rgba(46, 127, 255, 0.35);
  --inset:            inset 0 1px 0 rgba(255, 255, 255, 0.05);

  /* Motion */
  --ease-standard: cubic-bezier(.4, 0, .2, 1);
  --dur-fast: 150ms;
  --dur-mid:  220ms;
  --dur-slow: 450ms;

  /* Effects */
  --blur-card: 20px;
  --blur-soft: 16px;
  --grid-size: 48px;

  /* Media scrim — gradient overlay for legible text/controls over
     thumbnail/video artwork. Deliberately not redefined under
     [data-theme="light"]: artwork is unpredictable in tone regardless of
     page theme, so the scrim always darkens toward black, same as every
     other video/photo surface does. */
  --scrim-strong: rgba(3, 6, 14, 0.92);
  --scrim-soft:   rgba(3, 6, 14, 0.55);
}

/* -- Light mode ----------------------------------------------- */
[data-theme="light"] {
  color-scheme: light;

  /* Core palette */
  --ink:         #eef2ff;
  --ink-2:       #e2e8f7;
  --surface:     rgba(255, 255, 255, 0.88);
  --surface-2:   rgba(245, 248, 255, 0.80);
  --surface-3:   rgba(235, 240, 255, 0.90);
  --line:        rgba(46, 80, 200, 0.07);
  --line-hi:     rgba(46, 80, 200, 0.13);
  --line-strong: rgba(46, 80, 200, 0.20);

  /* Brand */
  --brand-dim:   rgba(46, 127, 255, 0.10);
  --brand-glow:  rgba(46, 127, 255, 0.20);
  --brand-ring:  rgba(46, 127, 255, 0.15);

  /* Text */
  --text:        #0d1420;
  --muted:       rgba(13, 20, 50, 0.58);
  --subtle:      rgba(13, 20, 50, 0.33);
  --text-soft:   rgba(13, 20, 50, 0.80);

  /* Status */
  --ok:          #16a34a;
  --ok-bg:       rgba(22, 163, 74, 0.08);
  --ok-bdr:      rgba(22, 163, 74, 0.25);
  --deg:         #d97706;
  --deg-bg:      rgba(217, 119, 6, 0.08);
  --deg-bdr:     rgba(217, 119, 6, 0.24);
  --err:         #dc2626;
  --err-bg:      rgba(220, 38, 38, 0.08);
  --err-bdr:     rgba(220, 38, 38, 0.22);
  --info:        #0284c7;
  --info-bg:     rgba(2, 132, 199, 0.08);
  --info-bdr:    rgba(2, 132, 199, 0.22);
  --protect:     #7c3aed;
  --protect-bg:  rgba(124, 58, 237, 0.08);
  --protect-bdr: rgba(124, 58, 237, 0.22);

  /* Neutral UI badge state */
  --chip-bdr:    rgba(13, 20, 50, 0.12);
  --chip-bg:     rgba(13, 20, 50, 0.04);
  --chip-text:   rgba(13, 20, 50, 0.45);

  /* Chrome surfaces */
  --nav-bg:  rgba(238, 242, 255, 0.78);
  --menu-bg: rgba(255, 255, 255, 0.97);

  /* Shadows */
  --shadow-card:      0 4px 24px rgba(13, 20, 80, 0.10);
  --shadow-card-soft: 0 2px 10px rgba(13, 20, 80, 0.07);
  --shadow-brand:     0 2px 12px rgba(46, 127, 255, 0.22);
  --inset:            inset 0 1px 0 rgba(255, 255, 255, 0.65);
}

        :root {
            color-scheme: dark;
            --app-bg: #080c10;
            --app-topbar-bg: rgba(8, 12, 16, .78);
            --app-surface: rgba(10, 16, 28, .78);
            --app-surface-hi: rgba(17, 27, 46, .84);
            --app-surface-soft: rgba(255, 255, 255, .035);
            --app-border: rgba(255, 255, 255, .11);
            --app-border-soft: rgba(255, 255, 255, .06);
            --app-accent: #2e7fff;
            --app-accent-strong: #6eb8ff;
            --app-accent-dim: rgba(46, 127, 255, .13);
            --app-accent-bdr: rgba(46, 127, 255, .32);
            --app-text: #eef2ff;
            --app-soft: rgba(238, 242, 255, .76);
            --app-muted: rgba(238, 242, 255, .50);
            --app-ok: #22c55e;
            --app-ok-dim: rgba(34, 197, 94, .1);
            --app-ok-bdr: rgba(34, 197, 94, .26);
            --app-err: #f87171;
            --app-err-dim: rgba(248, 113, 113, .1);
            --app-err-bdr: rgba(248, 113, 113, .26);
            --app-warn: #fbbf24;
            --app-warn-dim: rgba(251, 191, 36, .1);
            --app-warn-bdr: rgba(251, 191, 36, .26);
            --app-slate: #64748b;
            --app-slate-dim: rgba(100, 116, 139, .13);
            --app-slate-bdr: rgba(100, 116, 139, .28);
            --app-purple: #a855f7;
            --app-purple-dim: rgba(168, 85, 247, .13);
            --app-purple-bdr: rgba(168, 85, 247, .28);
            --app-radius: 16px;
            --app-radius-sm: 10px;
            --app-radius-xs: 7px;
            --app-blur: 20px;
            --app-shadow: 0 8px 40px rgba(4, 8, 20, .50);
            --app-shadow-soft: 0 8px 28px rgba(4, 8, 20, .30);
            --app-inset: inset 0 1px 0 rgba(255, 255, 255, .05);
            --app-grid-line: rgba(46, 127, 255, .035);
            --intro-logo-duration: 1.55s;
            --overlay-exit-delay: 1.30s;
            --overlay-exit-duration: .45s;
            --intro-logo-width: min(72vw, 520px);
            --shell-header-h: 54px;
            --shell-sidebar-w: 220px;
            --shell-sidebar-collapsed-w: 56px;
            --shell-footer-h: 36px;
        }

        :root[data-theme="light"] {
            color-scheme: light;
            --app-bg: #eef2ff;
            --app-topbar-bg: rgba(238, 242, 255, .88);
            --app-surface: rgba(255, 255, 255, .88);
            --app-surface-hi: rgba(255, 255, 255, .96);
            --app-surface-soft: rgba(255, 255, 255, .58);
            --app-border: rgba(46, 80, 200, .13);
            --app-border-soft: rgba(46, 80, 200, .07);
            --app-accent: #1d64e8;
            --app-accent-strong: #1d6be0;
            --app-accent-dim: rgba(29, 100, 232, .11);
            --app-accent-bdr: rgba(29, 100, 232, .24);
            --app-text: #0d1420;
            --app-soft: rgba(13, 20, 50, .78);
            --app-muted: rgba(13, 20, 50, .56);
            --app-ok: #12813f;
            --app-ok-dim: rgba(18, 129, 63, .1);
            --app-ok-bdr: rgba(18, 129, 63, .24);
            --app-err: #dc2626;
            --app-err-dim: rgba(220, 38, 38, .1);
            --app-err-bdr: rgba(220, 38, 38, .22);
            --app-warn: #b77905;
            --app-warn-dim: rgba(183, 121, 5, .12);
            --app-warn-bdr: rgba(183, 121, 5, .24);
            --app-slate: #64748b;
            --app-slate-dim: rgba(100, 116, 139, .11);
            --app-slate-bdr: rgba(100, 116, 139, .24);
            --app-purple: #7c3aed;
            --app-purple-dim: rgba(124, 58, 237, .1);
            --app-purple-bdr: rgba(124, 58, 237, .24);
            --app-shadow: 0 4px 24px rgba(13, 20, 80, .10);
            --app-shadow-soft: 0 4px 20px rgba(13, 20, 80, .08);
            --app-inset: inset 0 1px 0 rgba(255, 255, 255, .65);
            --app-grid-line: rgba(46, 127, 255, .055);
        }

/* -- Base reset ----------------------------------------------- */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  font-size: 100%;
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  min-height: 100dvh;
  font-family: var(--font-sans);
  color: var(--text);
  background:
    radial-gradient(ellipse 1200px 500px at 15% 0%, rgba(46,127,255,0.22), transparent 60%),
    radial-gradient(ellipse 600px 600px at 85% 5%, rgba(14,165,233,0.16), transparent 55%),
    radial-gradient(ellipse 1000px 700px at 50% 100%, rgba(30,80,200,0.14), transparent 65%),
    var(--ink);
  overflow-x: hidden;
}

/* Fixed so it covers the viewport regardless of scroll position */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  background-image:
    linear-gradient(rgba(46,127,255,0.035) 1px, transparent 1px),
    linear-gradient(90deg, rgba(46,127,255,0.035) 1px, transparent 1px);
  background-size: var(--grid-size) var(--grid-size);
  pointer-events: none;
  z-index: 0;
}

[data-theme="light"] body {
  background:
    radial-gradient(ellipse 1200px 500px at 15% 0%, rgba(46,127,255,0.09), transparent 60%),
    radial-gradient(ellipse 600px 600px at 85% 5%, rgba(14,165,233,0.07), transparent 55%),
    radial-gradient(ellipse 1000px 700px at 50% 100%, rgba(30,80,200,0.05), transparent 65%),
    var(--ink);
}

[data-theme="light"] body::before {
  background-image:
    linear-gradient(rgba(46,127,255,0.055) 1px, transparent 1px),
    linear-gradient(90deg, rgba(46,127,255,0.055) 1px, transparent 1px);
}

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

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

button,
input,
select,
textarea {
  font: inherit;
}

/* Fallback focus ring: most interactive components define their own
   :focus-visible (see buttons.css, launcher.css, forms.css), but plain
   links and anything not yet componentized still need visible keyboard
   focus rather than silently falling back to the browser default. */
:focus-visible {
  outline: 2px solid var(--brand-soft);
  outline-offset: 3px;
}

/* -- Typography ----------------------------------------------- */
.wc-eyebrow,
.wc-label,
.wc-kicker,
.wc-mono {
  font-family: var(--font-mono);
  letter-spacing: .04em;
}

.wc-eyebrow {
  font-size: .72rem;
  color: var(--muted);
}

.wc-title {
  font-size: clamp(2rem, 5vw, 3.2rem);
  font-weight: 600;
  letter-spacing: -.035em;
  line-height: 1.1;
}

.wc-title em,
.wc-text-gradient {
  font-style: normal;
  background: linear-gradient(110deg, var(--brand-soft) 15%, var(--brand-pale) 85%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.wc-lead {
  font-size: 1rem;
  line-height: 1.6;
  font-weight: 300;
  color: var(--muted);
}

.wc-text-muted  { color: var(--muted); }
.wc-text-subtle { color: var(--subtle); }
.wc-text-soft   { color: var(--text-soft); }

@media (max-width: 580px) {
  .wc-title {
    font-size: 1.85rem;
  }
}

/* -- Page shell (narrow content pages) ------------------------ */
.wc-page {
  position: relative;
  z-index: 1;
  max-width: var(--page-width);
  margin: 0 auto;
  padding: 0 var(--page-pad-x) var(--page-pad-y);
}

@media (max-width: 580px) {
  .wc-page {
    padding: 0 1rem 3rem;
  }
}

/* -- Shell sections (wide marketing/landing pages) ------------- */
.wc-shell-section {
  width: var(--shell);
  margin: 0 auto;
  padding-bottom: var(--rhythm);
}

.wc-section-heading {
  border-top: 1px solid var(--line);
  padding: clamp(36px, 5vw, 64px) 0;
}

.wc-section-heading > div {
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: 48ch;
}

.wc-section-eyebrow {
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--brand-soft);
}

.wc-section-title {
  font-size: clamp(1.7rem, 3.6vw, 2.6rem);
  font-weight: 600;
  letter-spacing: -.03em;
  line-height: 1.12;
  color: var(--text);
}

.wc-section-description {
  max-width: 38ch;
  font-size: .95rem;
  line-height: 1.65;
  color: var(--muted);
}

/* -- Skip link -------------------------------------------------- */
.wc-skip-link {
  position: fixed;
  top: -60px;
  left: 12px;
  z-index: 1000;
  padding: 12px 20px;
  border-radius: var(--radius-md);
  border: 1px solid var(--line-hi);
  background: var(--menu-bg);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: .75rem;
  letter-spacing: .05em;
  text-transform: uppercase;
  box-shadow: var(--shadow-card);
  transition: top var(--dur-fast) var(--ease-standard);
}

.wc-skip-link:focus {
  top: 12px;
}

/* -- Visually hidden ---------------------------------------------------
   Keeps an element in the accessibility tree (labels, native form
   controls under a styled label, live-region text) while removing it from
   visual layout. Use instead of `display:none`/`visibility:hidden` for
   anything a screen reader still needs to announce. */
.wc-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* -- Header pattern (simple flex row) --------------------------- */
.wc-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

/* -- Site header (sticky, blurred, full-bleed marketing nav) ---- */
.wc-site-header {
  position: sticky;
  top: 0;
  z-index: 200;
  background: var(--nav-bg);
  backdrop-filter: blur(var(--blur-card));
  -webkit-backdrop-filter: blur(var(--blur-card));
  border-bottom: 1px solid var(--line);
  transition: background var(--dur-slow) var(--ease-standard);
}

.wc-site-header-inner {
  width: var(--shell);
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  height: clamp(64px, 7vh, 80px);
}

/* -- Logo components ------------------------------------------ */
.wc-logo {
  display: inline-block;
  width: 32px;
  height: 32px;
  background-image: var(--logo);
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}

.wc-logo-full {
  display: inline-block;
  width: 180px;
  max-width: 100%;
  height: 36px;
  background-image: var(--logo-full);
  background-size: contain;
  background-repeat: no-repeat;
  background-position: left center;
}

.wc-logo-glow {
  filter: drop-shadow(0 4px 14px rgba(46,127,255,.28));
}

/* The mark is a saturated brand red (#ff0c19-ish) that already reads
   clearly on light backgrounds, so light mode renders it unfiltered
   instead of forcing it through an invert/brightness pass meant for
   monochrome (white) logo assets — that chain washed the red out to
   a pale pink/gray. */
[data-theme="light"] .wc-logo-glow {
  filter: drop-shadow(0 4px 14px rgba(46,127,255,.18));
}

/* -- Application shell ------------------------------------------------
   Primitives for a responsive app layout — sidebar + top bar + content —
   shared by both the public video app and the admin area. Deliberately
   unopinionated about labels/items/icons; the consuming app supplies the
   nav content. Pair with js/sidebar-collapse.js for a persisted collapsed
   state on desktop, and .wc-app-nav-toggle for a mobile drawer.

   <div class="wc-app">
     <aside class="wc-app-sidebar">
       <div class="wc-app-sidebar-brand"><span class="wc-logo"></span></div>
       <nav class="wc-app-nav">
         <a class="wc-app-nav-item is-active" href="…"><svg>…</svg>Home</a>
         <a class="wc-app-nav-item" href="…"><svg>…</svg>Library</a>
       </nav>
     </aside>
     <div class="wc-app-main">
       <header class="wc-app-topbar">…</header>
       <main class="wc-app-content">…</main>
     </div>
   </div>
*/
.wc-app {
  display: flex;
  min-height: 100dvh;
}

.wc-app-sidebar {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  flex: 0 0 240px;
  width: 240px;
  padding: 1.25rem 1rem;
  border-right: 1px solid var(--line);
  background: var(--surface-2);
  backdrop-filter: blur(var(--blur-soft));
  transition: width var(--dur-mid) var(--ease-standard),
    flex-basis var(--dur-mid) var(--ease-standard);
}

.wc-app-sidebar-brand {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: 0 .5rem;
}

.wc-app-nav {
  display: flex;
  flex-direction: column;
  gap: .15rem;
}

.wc-app-nav-group {
  display: flex;
  flex-direction: column;
  gap: .15rem;
  margin-top: .75rem;
}

.wc-app-nav-label {
  padding: .4rem .75rem;
  color: var(--subtle);
  font-family: var(--font-mono);
  font-size: .62rem;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.wc-app-nav-item {
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: .55rem .75rem;
  border-radius: var(--radius-md);
  color: var(--text-soft);
  font-size: .84rem;
  font-weight: 500;
  transition: background var(--dur-fast) var(--ease-standard),
    color var(--dur-fast) var(--ease-standard);
}

.wc-app-nav-item svg {
  width: 17px;
  height: 17px;
  flex-shrink: 0;
  color: var(--subtle);
  transition: color var(--dur-fast) var(--ease-standard);
}

.wc-app-nav-item:hover {
  background: var(--surface-3);
  color: var(--text);
}

.wc-app-nav-item.is-active {
  background: var(--brand-dim);
  color: var(--text);
}

.wc-app-nav-item.is-active svg {
  color: var(--brand-soft);
}

.wc-app-nav-item:focus-visible {
  outline: 2px solid var(--brand-soft);
  outline-offset: 2px;
}

/* -- Collapsed state (see js/sidebar-collapse.js) -----------------------
   The toggle script sets this class on the element named by its
   data-collapsed-class attribute — point it at .wc-app-sidebar (or an
   ancestor of it) to drive this. */
.wc-app-sidebar.is-collapsed {
  flex-basis: 72px;
  width: 72px;
  padding-inline: .5rem;
}

.wc-app-sidebar.is-collapsed .wc-app-nav-label,
.wc-app-sidebar.is-collapsed .wc-app-nav-item span,
.wc-app-sidebar.is-collapsed .wc-app-sidebar-brand span {
  display: none;
}

.wc-app-sidebar.is-collapsed .wc-app-nav-item {
  justify-content: center;
}

.wc-app-main {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1;
}

.wc-app-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  height: clamp(56px, 6vh, 68px);
  padding: 0 1.5rem;
  border-bottom: 1px solid var(--line);
  background: var(--nav-bg);
  backdrop-filter: blur(var(--blur-card));
}

.wc-app-content {
  flex: 1;
  padding: 1.75rem;
}

/* Mobile hamburger, hidden on desktop — pairs with a drawer-mode sidebar
   below the breakpoint. */
.wc-app-nav-toggle {
  display: none;
}

@media (max-width: 860px) {
  .wc-app-sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 300;
    transform: translateX(-100%);
    box-shadow: var(--shadow-card);
  }

  .wc-app-sidebar.is-open {
    transform: translateX(0);
  }

  .wc-app-nav-toggle {
    display: inline-flex;
  }

  .wc-app-content {
    padding: 1.25rem;
  }
}

/* -- Button system -------------------------------------------- */
.wc-btn-primary-sm,
.wc-btn-primary-lg,
.wc-btn-chip {
  border: none;
  cursor: pointer;
  transition:
    background var(--dur-mid),
    border-color var(--dur-mid),
    color var(--dur-mid),
    opacity var(--dur-mid),
    box-shadow var(--dur-mid),
    transform var(--dur-fast);
}

/* Base button: shared shape/type for every .wc-btn-* modifier below.
   Always pair a modifier with this base class, e.g.
   <button class="wc-btn wc-btn-primary">. The pill-shaped CTA variants
   (-primary-sm/-lg further down) are a separate, standalone pattern for
   marketing hero/nav CTAs and don't use this base. */
.wc-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .45rem;
  min-height: 36px;
  padding: .48rem .9rem;
  border-radius: var(--radius-md);
  cursor: pointer;
  font: inherit;
  font-size: .84rem;
  font-weight: 600;
  border: 1px solid transparent;
  transition: background .15s, border-color .15s, box-shadow .15s, color .15s;
  text-decoration: none;
  white-space: nowrap;
}

.wc-btn:focus-visible {
  outline: 2px solid var(--brand-soft);
  outline-offset: 3px;
}

.wc-btn-primary {
  color: #fff;
  background: var(--brand);
  border-color: var(--brand-glow);
  box-shadow: var(--inset), 0 2px 12px rgba(46,127,255,.20);
}

.wc-btn-primary:hover {
  background: var(--brand-2);
  box-shadow: var(--inset), 0 4px 20px rgba(46,127,255,.30);
}

.wc-btn-danger {
  color: var(--err);
  background: var(--err-bg);
  border-color: var(--err-bdr);
}

.wc-btn-danger:hover {
  background: rgba(239,68,68,.16);
}

.wc-btn-sm {
  min-height: 30px;
  padding: .3rem .65rem;
  font-size: .78rem;
}

/* Generic loading state for a single-shot form submit (e.g. "Sync now") --
   disables further clicks and shows a small spinner until the page
   navigates away with the result. */
.wc-btn.is-loading {
  pointer-events: none;
  opacity: .72;
}

.wc-btn.is-loading::after {
  content: '';
  display: inline-block;
  width: 12px;
  height: 12px;
  margin-left: .5rem;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: wc-spin .6s linear infinite;
}

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

/* Inline success feedback for a single-shot action button (new in 2.3.0) --
   an alternative to a page-level status banner: shown briefly on the button
   itself after the page reloads with a successful result, then reverts.
   Pairs with [data-feedback-success] / data-success-label and
   js/button-feedback.js. */
.wc-btn.is-success {
  pointer-events: none;
  color: var(--ok);
  background: var(--ok-bg);
  border-color: var(--ok-bdr);
  animation: wc-success-pop var(--dur-mid) var(--ease-standard);
}

.wc-btn.is-success svg {
  width: 14px;
  height: 14px;
}

@keyframes wc-success-pop {
  from { transform: scale(.92); }
  to   { transform: scale(1); }
}

/* Pill-shaped size variants, for sticky nav bars / hero CTAs */
.wc-btn-primary-sm,
.wc-btn-primary-lg {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  border-radius: var(--radius-pill);
  color: #fff;
  font-family: var(--font-mono);
  text-transform: uppercase;
  background: linear-gradient(135deg, var(--brand), var(--brand-2));
}

.wc-btn-primary-sm {
  height: 38px;
  padding: 0 18px;
  font-size: .68rem;
  letter-spacing: .1em;
  box-shadow: 0 2px 14px rgba(46,127,255,.32);
}

.wc-btn-primary-lg {
  height: 48px;
  padding: 0 24px;
  font-size: .7rem;
  letter-spacing: .1em;
  box-shadow: 0 4px 20px rgba(46,127,255,.28);
}

.wc-btn-primary-sm:hover,
.wc-btn-primary-lg:hover {
  opacity: .9;
  transform: translateY(-1px);
  box-shadow: 0 6px 22px rgba(46,127,255,.45);
}

.wc-btn-primary-lg:hover {
  box-shadow: 0 8px 30px rgba(46,127,255,.42);
}

.wc-btn-primary-sm:focus-visible,
.wc-btn-primary-lg:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 3px;
}

.wc-btn-ghost {
  color: var(--text-soft);
  background: transparent;
  border-color: var(--line-hi);
}

.wc-btn-ghost:hover {
  color: var(--text);
  background: var(--surface-2);
  border-color: var(--brand-glow);
}

/* Text-only ghost link, e.g. secondary hero CTA or footer links */
.wc-link-ghost {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: .7rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
  transition: color var(--dur-mid) var(--ease-standard);
}

.wc-link-ghost:hover {
  color: var(--brand-soft);
}

.wc-btn-chip,
.wc-chip {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .32rem .75rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line-hi);
  background: rgba(46,127,255,.04);
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: .7rem;
  letter-spacing: .04em;
}

.wc-btn-chip:hover,
.wc-chip:hover {
  background: rgba(46,127,255,.12);
  border-color: rgba(46,127,255,.3);
  color: #afd6ff;
}

.wc-btn-chip:focus-visible,
.wc-chip:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 3px;
}

/* Icon-only square button, e.g. theme toggle, sidebar toggle */
.wc-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  color: var(--text-soft);
  background: var(--surface);
  border: 1px solid var(--line-hi);
  border-radius: var(--radius-md);
  box-shadow: var(--inset);
  cursor: pointer;
  transition: background .15s, border-color .15s, color .15s, transform .1s;
}

.wc-icon-btn:hover {
  color: var(--text);
  background: var(--surface-3);
  border-color: var(--brand-glow);
}

.wc-icon-btn:active {
  transform: scale(.91);
}

.wc-icon-btn:focus-visible {
  outline: 2px solid var(--brand-soft);
  outline-offset: 3px;
}

.wc-icon-btn svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.wc-icon-btn.spinning svg {
  animation: wc-spin .6s linear infinite;
}

/* Inline success feedback on an icon-only button (new in 2.3.0) — same
   [data-feedback-success] contract as .wc-btn.is-success above, but sized
   for a single icon glyph; omit data-success-label so js/button-feedback.js
   swaps only the icon, not the button's fixed square footprint. */
.wc-icon-btn.is-success {
  pointer-events: none;
  color: var(--ok);
  background: var(--ok-bg);
  border-color: var(--ok-bdr);
  animation: wc-success-pop var(--dur-mid) var(--ease-standard);
}

@media (prefers-reduced-motion: reduce) {
  .wc-icon-btn.spinning svg,
  .wc-btn.is-loading::after {
    animation-duration: 1.2s;
  }

  .wc-btn.is-success,
  .wc-icon-btn.is-success {
    animation: none;
  }
}

/* Theme toggle icon swap: put both a moon and a sun icon inside the
   [data-theme-toggle] button (see js/theme.js) — only one shows at a
   time based on [data-theme] on <html>. */
.theme-icon-sun { display: none; }
[data-theme="light"] .theme-icon-sun { display: block; }
[data-theme="light"] .theme-icon-moon { display: none; }

button:disabled,
.wc-disabled,
[aria-disabled="true"] {
  opacity: .45;
  cursor: not-allowed;
}

/* -- Form controls -------------------------------------------- */
.wc-input-wrap {
  display: flex;
  align-items: center;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--surface);
  border: 1px solid var(--line-hi);
  box-shadow: var(--shadow-card), inset 0 1px 0 rgba(255,255,255,.05);
  backdrop-filter: blur(var(--blur-card));
  transition: border-color var(--dur-mid), box-shadow var(--dur-mid);
}

.wc-input-wrap:focus-within {
  border-color: rgba(46,127,255,.45);
  box-shadow:
    var(--shadow-card),
    0 0 0 3px var(--brand-ring),
    inset 0 1px 0 rgba(255,255,255,.05);
}

/* Self-contained by default (own border/background/radius) so .wc-input/
   .wc-select work standalone, without requiring the .wc-input-wrap parent
   above. Nesting one inside a .wc-input-wrap isn't a supported combination
   today (no current consumer does it) — border/background would double up. */
.wc-input,
.wc-select {
  width: 100%;
  min-height: 38px;
  padding: .5rem .75rem;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--line-hi);
  border-radius: var(--radius-md);
  font: inherit;
  font-size: .9rem;
  outline: none;
  caret-color: var(--brand);
  transition: border-color .14s, box-shadow .14s;
}

.wc-input:focus,
.wc-select:focus {
  border-color: var(--brand-glow);
  box-shadow: 0 0 0 3px var(--brand-ring);
}

.wc-select option {
  background: #111827;
}

.wc-input-center {
  letter-spacing: .18em;
  text-align: center;
  font-size: 1.1rem;
}

.wc-input::placeholder {
  color: var(--subtle);
}

.wc-field-error {
  min-height: 1.1rem;
  margin-top: .55rem;
  text-align: center;
  color: rgba(239, 68, 68, .82);
  font-family: var(--font-mono);
  font-size: .68rem;
}

/* -- Badges and status ---------------------------------------- */
.wc-badge,
.wc-status {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  padding: .38rem .9rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--chip-bdr);
  background: var(--chip-bg);
  color: var(--chip-text);
  font-family: var(--font-mono);
  font-size: .75rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;
}

.wc-badge.ok,
.wc-status.ok {
  background: var(--ok-bg);
  border-color: var(--ok-bdr);
  color: var(--ok);
}

.wc-badge.deg,
.wc-status.deg {
  background: var(--deg-bg);
  border-color: var(--deg-bdr);
  color: var(--deg);
}

.wc-badge.err,
.wc-status.err {
  background: var(--err-bg);
  border-color: var(--err-bdr);
  color: var(--err);
}

.wc-badge.info,
.wc-status.info {
  background: var(--info-bg);
  border-color: var(--info-bdr);
  color: var(--info);
}

.wc-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}

/* -- Extended status vocabulary --------------------------------------------
   Additive modifiers for .wc-badge/.wc-status (see components/badges.css
   for the base classes and the original ok/deg/err/info modifiers). These
   map processing/publishing/visibility states onto the *existing* status
   tokens instead of inventing video-specific colors — only "protect" is
   new (see tokens/tokens.css --protect*), because content-protection is a
   genuinely distinct concept none of ok/deg/err/info/neutral already mean.

   Suggested mapping (apply whichever single modifier fits — these are
   plain aliases, not a new class family, so any consumer already using
   .wc-badge.ok etc. is unaffected):

     draft       → .wc-badge            (bare — neutral chip, no modifier)
     queued      → .wc-badge.info
     uploading   → .wc-badge.info
     transcoding → .wc-badge.info
     packaging   → .wc-badge.info
     encrypting  → .wc-badge.info
     processing  → .wc-badge.info
     ready       → .wc-badge.ok
     published   → .wc-badge.ok
     scheduled   → .wc-badge.info
     private     → .wc-badge            (bare — visibility, not health)
     failed      → .wc-badge.err
     warning     → .wc-badge.deg
     protected   → .wc-badge.protect
*/
.wc-badge.protect,
.wc-status.protect {
  background: var(--protect-bg);
  border-color: var(--protect-bdr);
  color: var(--protect);
}

/* Pairs a status badge with its icon at a consistent size — the icon
   alone never carries the meaning; the label text next to it does. */
.wc-status-badge {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
}

.wc-status-badge svg {
  width: 12px;
  height: 12px;
  flex-shrink: 0;
}

/* -- Surface primitives --------------------------------------- */
.wc-card,
.wc-panel,
.wc-surface {
  background: var(--surface);
  border: 1px solid var(--line-hi);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-card), var(--inset);
  backdrop-filter: blur(var(--blur-card));
  -webkit-backdrop-filter: blur(var(--blur-card));
  padding: 1.5rem;
}

.wc-card-sm {
  padding: 1rem;
  border-radius: var(--radius-md);
}

.wc-surface-soft {
  background: var(--surface-2);
  border: 1px solid var(--line-hi);
  border-radius: var(--radius-xl);
  backdrop-filter: blur(var(--blur-soft));
}

.wc-divider {
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--line-hi) 30%, var(--line-hi) 70%, transparent);
}

/* -- Service card (icon + title + description + meta footer) -- */
/* Note: deliberately a distinct class from .wc-card above rather than
   reusing it — .wc-card is the plain surface primitive already relied on
   by existing consumers (wc-admin-framework, docker-admin); this is a
   different, more opinionated composite pattern lifted from the marketing
   site's service grid. */
.wc-service-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: clamp(22px, 3vw, 38px);
  padding: clamp(24px, 2.6vw, 36px);
  min-height: clamp(200px, 22vw, 260px);
  border-radius: 20px;
  border: 1px solid var(--line-hi);
  background: var(--surface-2);
  backdrop-filter: blur(var(--blur-card));
  -webkit-backdrop-filter: blur(var(--blur-card));
  box-shadow: var(--shadow-card-soft), inset 0 1px 0 rgba(255,255,255,.05);
  color: inherit;
  transition:
    border-color var(--dur-mid) var(--ease-standard),
    transform var(--dur-mid) var(--ease-standard),
    box-shadow var(--dur-mid) var(--ease-standard);
}

.wc-service-card:hover {
  border-color: rgba(46,127,255,.34);
  transform: translateY(-3px);
  box-shadow: var(--shadow-card), 0 0 32px rgba(46,127,255,.10), inset 0 1px 0 rgba(255,255,255,.05);
}

.wc-card-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: var(--radius-md);
  background: var(--brand-dim);
  border: 1px solid rgba(46,127,255,.18);
  flex-shrink: 0;
}

.wc-card-icon img {
  width: 30px;
  height: 30px;
  object-fit: contain;
  border-radius: var(--radius-sm);
}

.wc-card-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: auto;
}

.wc-card-title {
  font-family: var(--font-mono);
  font-size: 1rem;
  font-weight: 500;
  letter-spacing: -.01em;
  color: var(--text);
}

.wc-card-description {
  font-size: .9rem;
  line-height: 1.6;
  color: var(--muted);
}

.wc-card-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-top: clamp(16px, 2vw, 22px);
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: .65rem;
  letter-spacing: .07em;
  text-transform: uppercase;
}

.wc-card-host {
  color: var(--subtle);
}

.wc-card-open {
  color: var(--brand-soft);
}

/* Live reachability dot for a .wc-service-card (needs js/status-check.js):
   grey while checking, green once the visitor's browser can reach the
   host, red if the request fails or times out. There's no shared backend
   to ask "is this up" — each client probes the host directly, so this
   reflects the visitor's own network path, not a canonical status. */
.wc-status-dot {
  position: absolute;
  top: 16px;
  right: 16px;
  z-index: 1;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--subtle);
  transition: background var(--dur-mid) var(--ease-standard), box-shadow var(--dur-mid) var(--ease-standard);
}

.wc-status-dot.is-checking { animation: wc-status-dot-pulse 1.4s ease-in-out infinite; }
.wc-status-dot.is-online { background: #34d399; box-shadow: 0 0 0 3px rgba(52,211,153,.16), 0 0 10px rgba(52,211,153,.55); }
.wc-status-dot.is-offline { background: #f87171; box-shadow: 0 0 0 3px rgba(248,113,113,.16), 0 0 8px rgba(248,113,113,.4); }

@keyframes wc-status-dot-pulse {
  0%, 100% { opacity: .35; }
  50% { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .wc-status-dot.is-checking { animation: none; }
}

/* -- Grid and tiles ------------------------------------------- */
.wc-grid {
  display: grid;
  gap: .75rem;
}

.wc-grid-cards {
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

/* Responsive grid sized for .wc-service-card tiles */
.wc-service-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: clamp(14px, 1.6vw, 22px);
}

.wc-shortcut,
.wc-tile {
  padding: 1rem 1.1rem;
  border-radius: 12px;
  border: 1px solid var(--line-hi);
  background: var(--surface);
  backdrop-filter: blur(var(--blur-soft));
  transition: border-color var(--dur-mid), background var(--dur-mid), transform var(--dur-fast);
}

.wc-shortcut:hover,
.wc-tile:hover {
  border-color: rgba(46,127,255,.3);
  background: rgba(46,127,255,.05);
  transform: translateY(-1px);
}

.wc-shortcut-title {
  font-family: var(--font-mono);
  font-size: .78rem;
  font-weight: 500;
  color: var(--text);
  margin-bottom: .3rem;
}

.wc-shortcut-desc {
  font-size: .75rem;
  font-weight: 300;
  color: var(--muted);
}

/* -- Data table -------------------------------------------------------
   Admin list views (video management, upload queue, users). Plain
   semantic <table> markup — no JS required for the static shell; sorting/
   filtering/pagination behavior is the consuming app's job.

   <div class="wc-table-wrap">
     <table class="wc-table">
       <thead>
         <tr><th>Title</th><th>Status</th><th class="wc-table-num">Duration</th></tr>
       </thead>
       <tbody>
         <tr>
           <td>
             <div class="wc-table-media">
               <div class="wc-aspect wc-aspect-video wc-table-thumb"><img src="…" alt=""></div>
               <span>Title</span>
             </div>
           </td>
           <td><span class="wc-badge ok">Ready</span></td>
           <td class="wc-table-num">12:34</td>
         </tr>
       </tbody>
     </table>
   </div>
*/
.wc-table-wrap {
  overflow-x: auto;
  border: 1px solid var(--line-hi);
  border-radius: var(--radius-lg);
  background: var(--surface);
}

.wc-table {
  width: 100%;
  border-collapse: collapse;
  font-size: .84rem;
}

.wc-table th,
.wc-table td {
  padding: .8rem 1rem;
  text-align: left;
  vertical-align: middle;
  white-space: nowrap;
}

.wc-table thead th {
  border-bottom: 1px solid var(--line-hi);
  color: var(--subtle);
  font-family: var(--font-mono);
  font-size: .65rem;
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.wc-table tbody tr {
  border-bottom: 1px solid var(--line);
  transition: background var(--dur-fast) var(--ease-standard);
}

.wc-table tbody tr:last-child {
  border-bottom: none;
}

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

.wc-table td {
  color: var(--text-soft);
}

/* Wrap long text columns (title, description) instead of truncating the
   whole row — pair with a max-width on the cell. */
.wc-table td.wc-table-wrap-text {
  white-space: normal;
  max-width: 32ch;
}

.wc-table-num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* Title cell with a small thumbnail — the common shape for a video-row. */
.wc-table-media {
  display: flex;
  align-items: center;
  gap: .75rem;
  white-space: normal;
}

.wc-table-thumb {
  flex: 0 0 64px;
  width: 64px;
  border-radius: var(--radius-sm);
}

.wc-table-media span {
  overflow: hidden;
  color: var(--text);
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Row-level action cluster, right-aligned. */
.wc-table-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: .35rem;
}

/* Sortable column header button — pairs a label with a chevron; toggle
   `[aria-sort]` on the parent <th> from application JS. */
.wc-table-sort {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  background: none;
  border: none;
  cursor: pointer;
}

.wc-table-sort svg {
  width: 11px;
  height: 11px;
  opacity: .5;
}

th[aria-sort="ascending"] .wc-table-sort svg,
th[aria-sort="descending"] .wc-table-sort svg {
  opacity: 1;
  color: var(--brand-soft);
}

th[aria-sort="ascending"] .wc-table-sort svg {
  transform: rotate(180deg);
}

@media (max-width: 640px) {
  .wc-table th,
  .wc-table td {
    padding: .65rem .75rem;
  }
}

/* -- Tabs ---------------------------------------------------------------
   Section navigation for a multi-part editor (video details: general,
   thumbnail, renditions, subtitles, publishing, permissions, DRM, …).
   Plain ARIA tabs markup; switching panels is the consuming app's job.

   <div class="wc-tabs" role="tablist" aria-label="Video settings">
     <button class="wc-tab" role="tab" aria-selected="true" id="tab-general" aria-controls="panel-general">General</button>
     <button class="wc-tab" role="tab" aria-selected="false" id="tab-drm" aria-controls="panel-drm">DRM</button>
   </div>
   <div class="wc-tab-panel" role="tabpanel" id="panel-general" aria-labelledby="tab-general">…</div>
*/
.wc-tabs {
  display: flex;
  gap: .25rem;
  overflow-x: auto;
  border-bottom: 1px solid var(--line-hi);
  scrollbar-width: none;
}

.wc-tabs::-webkit-scrollbar {
  display: none;
}

.wc-tab {
  flex: 0 0 auto;
  padding: .7rem .9rem;
  border: none;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: .82rem;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease-standard),
    border-color var(--dur-fast) var(--ease-standard);
}

.wc-tab:hover {
  color: var(--text);
}

.wc-tab:focus-visible {
  outline: 2px solid var(--brand-soft);
  outline-offset: -2px;
}

.wc-tab[aria-selected="true"] {
  color: var(--text);
  border-bottom-color: var(--brand);
}

.wc-tab-panel {
  padding-top: 1.5rem;
}

.wc-tab-panel[hidden] {
  display: none;
}

/* -- Media artwork (aspect-ratio containers, thumbnails, posters) --------
   Predictable, pre-sized boxes for video/image artwork so nothing shifts
   layout while the real asset is still loading. The box itself carries the
   ratio and a neutral fill; put an <img>/<video>/poster inside it and it
   is stretched to cover via the child rule below. Combine with
   .wc-media-skeleton (loading) or .wc-media-missing (no artwork) as
   needed — both are independent of the ratio class. */
.wc-aspect {
  position: relative;
  overflow: hidden;
  background: var(--surface-2);
  border-radius: var(--radius-md);
}

.wc-aspect > img,
.wc-aspect > video,
.wc-aspect > picture > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.wc-aspect-video {
  aspect-ratio: 16 / 9;
}

.wc-aspect-square {
  aspect-ratio: 1 / 1;
}

.wc-aspect-poster {
  aspect-ratio: 2 / 3;
}

/* -- Loading state ---------------------------------------------
   Static shimmer-free placeholder — see components/skeleton.css for the
   animated .wc-skeleton treatment; use that instead if the surrounding
   page already uses skeletons elsewhere and consistency matters more than
   restraint. This flat state is the default because it never competes for
   attention with thumbnail artwork once it starts painting. */
.wc-media-loading {
  background:
    radial-gradient(circle at 50% 50%, var(--surface-3), transparent 70%),
    var(--surface-2);
}

/* -- Missing artwork state ---------------------------------------
   Shown when a video/poster genuinely has no artwork (not merely still
   loading) — e.g. a freshly-created upload before a thumbnail has been
   extracted. Put a single icon (from assets/icons/) inside as the direct
   child; it is centered and dimmed automatically. */
.wc-media-missing {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-2);
  color: var(--subtle);
}

.wc-media-missing svg {
  width: 28px;
  height: 28px;
}

/* -- Scrim ---------------------------------------------------------------
   A bottom-anchored gradient for legible overlaid text/controls (title,
   duration, badges) on top of unpredictable thumbnail artwork. Add as a
   sibling of the <img>, then position content inside .wc-media-scrim
   itself or absolutely within the .wc-aspect parent. */
.wc-media-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, var(--scrim-strong) 0%, transparent 55%);
  pointer-events: none;
}

/* -- Duration badge ------------------------------------------------------
   Bottom-right overlay on a thumbnail, e.g. "12:34". */
.wc-media-duration {
  position: absolute;
  right: 8px;
  bottom: 8px;
  z-index: 1;
  padding: .18rem .45rem;
  border-radius: var(--radius-sm);
  background: var(--scrim-strong);
  color: #fff;
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .03em;
  line-height: 1.4;
}

/* -- Playback progress bar ------------------------------------------------
   Thin bar pinned to the bottom edge of a thumbnail, showing how far a
   viewer got into a video — e.g. inside a .wc-video-card. `--wc-progress`
   (0–100) sets the fill; see also components/progress.css for the
   standalone determinate/indeterminate bars used outside media artwork. */
.wc-media-progress {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1;
  height: 3px;
  background: rgba(255, 255, 255, 0.22);
}

.wc-media-progress::after {
  content: "";
  display: block;
  height: 100%;
  width: calc(var(--wc-progress, 0) * 1%);
  background: var(--brand);
}

/* -- Video card ------------------------------------------------------------
   Two variants, one markup shape:
   - .wc-video-card            grid card, artwork above metadata (library
                                grids, home rails)
   - .wc-video-card.is-compact horizontal layout, small fixed-width
                                artwork beside metadata (queue lists,
                                related-videos rail, playlist items)

   Markup contract (see ai.txt for a full example):

   <a class="wc-video-card" href="…">
     <div class="wc-aspect wc-aspect-video wc-video-card-art">
       <img src="…" alt="" loading="lazy">
       <div class="wc-media-scrim"></div>
       <span class="wc-media-duration">12:34</span>
       <div class="wc-media-progress" style="--wc-progress: 40"></div>
       <span class="wc-badge ready wc-video-card-badge">Ready</span>
     </div>
     <div class="wc-video-card-body">
       <h3 class="wc-video-card-title">Title</h3>
       <p class="wc-video-card-meta">Creator · 3 days ago</p>
     </div>
   </a>
*/
.wc-video-card {
  display: flex;
  flex-direction: column;
  gap: .7rem;
  color: inherit;
  border-radius: var(--radius-md);
  transition: transform var(--dur-mid) var(--ease-standard);
}

.wc-video-card:hover .wc-video-card-art,
.wc-video-card:focus-visible .wc-video-card-art {
  box-shadow: 0 0 0 2px var(--brand-glow);
}

.wc-video-card:focus-visible {
  outline: 2px solid var(--brand-soft);
  outline-offset: 4px;
}

.wc-video-card-art {
  transition: box-shadow var(--dur-mid) var(--ease-standard);
}

.wc-video-card-body {
  display: flex;
  flex-direction: column;
  gap: .3rem;
}

.wc-video-card-title {
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  color: var(--text);
  font-size: .92rem;
  font-weight: 600;
  line-height: 1.35;
}

.wc-video-card-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .35rem;
  color: var(--muted);
  font-size: .78rem;
  line-height: 1.4;
}

.wc-video-card-meta .wc-dot {
  width: 3px;
  height: 3px;
  color: var(--subtle);
}

/* Small semantic badge pinned to a corner of the artwork — pair with the
   status classes from components/status.css, e.g.
   class="wc-badge processing wc-video-card-badge" */
.wc-video-card-badge {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 1;
}

/* -- Grid layout for a library/rail of video cards ------------------- */
.wc-video-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 1.5rem 1.1rem;
}

/* -- Compact horizontal variant (queue, related, playlist rows) ------ */
.wc-video-card.is-compact {
  flex-direction: row;
  gap: .75rem;
  align-items: flex-start;
}

.wc-video-card.is-compact .wc-video-card-art {
  flex: 0 0 148px;
  width: 148px;
}

.wc-video-card.is-compact .wc-video-card-title {
  font-size: .84rem;
  -webkit-line-clamp: 2;
}

.wc-video-card.is-compact .wc-video-card-meta {
  font-size: .72rem;
}

@media (max-width: 480px) {
  .wc-video-card.is-compact .wc-video-card-art {
    flex-basis: 120px;
    width: 120px;
  }
}

/* -- Watched state -----------------------------------------------------
   Dims artwork slightly once a video has been fully watched, so it reads
   as "done" at a glance in a grid without needing a text label. */
.wc-video-card.is-watched .wc-video-card-art > img,
.wc-video-card.is-watched .wc-video-card-art > video {
  opacity: .55;
}

.wc-video-card.is-watched .wc-video-card-title {
  color: var(--muted);
}

/* -- Player shell ----------------------------------------------------------
   Visual chrome for embedding a real player (Shaka Player or a plain
   <video>) — this system draws the surface, its states, and the badges
   around it; it does not implement playback. Toggle the state classes
   below from application JS as the underlying player reports events.

   Markup contract:

   <div class="wc-player">
     <div class="wc-aspect wc-aspect-video wc-player-surface">
       <video class="wc-player-media">…</video>
       <div class="wc-player-state wc-player-state-loading">…</div>
       <div class="wc-player-state wc-player-state-buffering">…</div>
       <div class="wc-player-state wc-player-state-error">
         <p class="wc-player-error-title">Playback failed</p>
         <p class="wc-player-error-detail">…</p>
       </div>
       <div class="wc-player-indicators">
         <span class="wc-player-indicator" title="Protected content">…svg…</span>
         <span class="wc-player-indicator" title="Subtitles available">…svg…</span>
       </div>
     </div>
   </div>
*/
.wc-player {
  position: relative;
}

.wc-player-surface {
  background: #000;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
}

.wc-player-media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  background: #000;
}

/* -- Player overlay states -----------------------------------------------
   Only one should be visible at a time — toggle with a `hidden` attribute
   or `display:none` from application JS as playback state changes. */
.wc-player-state {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .75rem;
  padding: 1.5rem;
  text-align: center;
  background: var(--scrim-soft);
}

.wc-player-state[hidden] {
  display: none;
}

.wc-player-spinner {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.22);
  border-top-color: var(--brand-soft);
  animation: wc-spin .8s linear infinite;
}

.wc-player-state-buffering .wc-player-spinner {
  width: 26px;
  height: 26px;
}

@media (prefers-reduced-motion: reduce) {
  .wc-player-spinner {
    animation: none;
  }
}

.wc-player-state-error {
  background: var(--scrim-strong);
}

.wc-player-error-title {
  color: #fff;
  font-size: 1rem;
  font-weight: 600;
}

.wc-player-error-detail {
  max-width: 44ch;
  color: rgba(255, 255, 255, 0.72);
  font-family: var(--font-mono);
  font-size: .78rem;
  line-height: 1.6;
}

/* -- Status indicators (protected / subtitles / audio tracks) -----------
   Top-right cluster of small pills over the player surface. Icons alone
   are not a substitute for the title attribute / visually-hidden text —
   keep an accessible label on each. */
.wc-player-indicators {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 3;
  display: flex;
  gap: .4rem;
}

.wc-player-indicator {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: var(--radius-sm);
  background: var(--scrim-strong);
  color: rgba(255, 255, 255, 0.85);
}

.wc-player-indicator svg {
  width: 15px;
  height: 15px;
}

.wc-player-indicator.is-protected {
  color: var(--protect);
}

/* -- Theater layout -------------------------------------------------------
   Widens the player and demotes surrounding metadata/rails to a narrower
   column (or below, on small screens). Apply `.is-theater` to a page-level
   wrapper containing both `.wc-player` and the rest of the watch layout. */
.wc-watch-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 360px);
  gap: 1.75rem;
  align-items: start;
}

.wc-watch-layout.is-theater {
  grid-template-columns: minmax(0, 1fr);
}

.wc-watch-layout.is-theater .wc-watch-sidebar {
  display: none;
}

.wc-watch-primary {
  min-width: 0;
}

.wc-watch-sidebar {
  display: flex;
  flex-direction: column;
  gap: .75rem;
}

@media (max-width: 900px) {
  .wc-watch-layout,
  .wc-watch-layout.is-theater {
    grid-template-columns: minmax(0, 1fr);
  }

  .wc-watch-layout .wc-watch-sidebar {
    display: flex;
  }
}

/* -- Content rails ---------------------------------------------------------
   Horizontal scrolling group of cards — "Continue watching", "Recently
   uploaded", playlists, related videos. Snap-scrolls, touch-scrollable by
   default (native overflow scrolling, no JS required), with a heading
   that carries the same eyebrow/title pattern as .wc-section-heading.

   <section class="wc-rail">
     <div class="wc-rail-heading">
       <h2 class="wc-rail-title">Continue watching</h2>
     </div>
     <div class="wc-rail-track">
       <div class="wc-rail-item"><!-- .wc-video-card --></div>
       …
     </div>
   </section>
*/
.wc-rail {
  display: flex;
  flex-direction: column;
  gap: .9rem;
}

.wc-rail-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}

.wc-rail-title {
  color: var(--text);
  font-size: 1.1rem;
  font-weight: 600;
  letter-spacing: -.01em;
}

.wc-rail-link {
  flex: 0 0 auto;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  transition: color var(--dur-mid) var(--ease-standard);
}

.wc-rail-link:hover {
  color: var(--brand-soft);
}

.wc-rail-track {
  display: flex;
  gap: 1.1rem;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  scroll-padding-inline: var(--page-pad-x, 1.5rem);
  padding-bottom: .3rem;
  margin-bottom: -.3rem;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}

.wc-rail-item {
  flex: 0 0 auto;
  width: min(280px, 78vw);
  scroll-snap-align: start;
}

/* Compact rails (e.g. queue/related in the watch sidebar) stack instead
   of scrolling horizontally — apply alongside .wc-rail. */
.wc-rail.is-stacked .wc-rail-track {
  flex-direction: column;
  overflow: visible;
  scroll-snap-type: none;
}

.wc-rail.is-stacked .wc-rail-item {
  width: auto;
}

/* -- Progress indicators ----------------------------------------------------
   Standalone bars for anything that isn't playback progress on a
   thumbnail (see .wc-media-progress in components/media.css for that).
   Covers upload/transcode/packaging progress, background-job status, and
   generic determinate/indeterminate loading.

   Determinate:
     <div class="wc-progress" role="progressbar" aria-valuenow="42"
          aria-valuemin="0" aria-valuemax="100">
       <div class="wc-progress-bar" style="--wc-progress: 42"></div>
     </div>

   Indeterminate (unknown duration — e.g. "queued", "waiting for worker"):
     <div class="wc-progress is-indeterminate" role="progressbar"
          aria-label="Processing">
       <div class="wc-progress-bar"></div>
     </div>
*/
.wc-progress {
  position: relative;
  overflow: hidden;
  height: 8px;
  border-radius: var(--radius-pill);
  background: var(--surface-2);
  border: 1px solid var(--line);
}

.wc-progress-bar {
  height: 100%;
  width: calc(var(--wc-progress, 0) * 1%);
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, var(--brand-2), var(--brand));
  transition: width var(--dur-mid) var(--ease-standard);
}

.wc-progress.is-compact {
  height: 4px;
}

.wc-progress.ok .wc-progress-bar    { background: var(--ok); }
.wc-progress.deg .wc-progress-bar   { background: var(--deg); }
.wc-progress.err .wc-progress-bar   { background: var(--err); }

.wc-progress.is-indeterminate .wc-progress-bar {
  width: 40%;
  animation: wc-progress-indeterminate 1.4s var(--ease-standard) infinite;
}

@keyframes wc-progress-indeterminate {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(250%); }
}

@media (prefers-reduced-motion: reduce) {
  .wc-progress.is-indeterminate .wc-progress-bar {
    animation: none;
    width: 100%;
    opacity: .5;
  }
}

/* -- Progress card ---------------------------------------------------------
   A named job with a progress bar and current stage — the shape used for
   an in-flight upload/transcode/packaging job in an admin queue view. */
.wc-progress-card {
  display: flex;
  flex-direction: column;
  gap: .6rem;
  padding: 1rem 1.1rem;
  border: 1px solid var(--line-hi);
  border-radius: var(--radius-md);
  background: var(--surface);
}

.wc-progress-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
}

.wc-progress-card-title {
  overflow: hidden;
  color: var(--text);
  font-size: .86rem;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.wc-progress-card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .04em;
}

/* -- Step indicator ---------------------------------------------------------
   Horizontal pipeline of named stages, e.g.
   uploading → queued → transcoding → packaging → encrypting → ready.

   <ol class="wc-steps">
     <li class="wc-step is-done"><span class="wc-step-dot"></span>Uploading</li>
     <li class="wc-step is-active"><span class="wc-step-dot"></span>Transcoding</li>
     <li class="wc-step"><span class="wc-step-dot"></span>Packaging</li>
   </ol>
*/
.wc-steps {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0;
  list-style: none;
}

.wc-step {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .3rem .8rem .3rem 0;
  color: var(--subtle);
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .05em;
  text-transform: uppercase;
}

.wc-step:not(:last-child)::after {
  content: "";
  width: 20px;
  height: 1px;
  margin-left: .8rem;
  background: var(--line-strong);
}

.wc-step-dot {
  width: 7px;
  height: 7px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--subtle);
}

.wc-step.is-done {
  color: var(--muted);
}

.wc-step.is-done .wc-step-dot {
  background: var(--ok);
}

.wc-step.is-active {
  color: var(--text);
}

.wc-step.is-active .wc-step-dot {
  background: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-ring);
}

.wc-step.is-error .wc-step-dot {
  background: var(--err);
}

/* -- Upload / drop zone ------------------------------------------------
   Large target for a video-file upload. States are toggled by adding one
   of the modifier classes to .wc-dropzone; application JS drives drag
   events and the file input itself (this system only provides the
   surface). The native <input type="file"> should be visually hidden but
   still present and labelled for keyboard/screen-reader users — don't
   remove it from the DOM.

   <label class="wc-dropzone" for="video-upload">
     <input type="file" id="video-upload" accept="video/*" class="wc-sr-only">
     <svg class="wc-dropzone-icon">…</svg>
     <p class="wc-dropzone-title">Drop a video file, or click to browse</p>
     <p class="wc-dropzone-hint">MP4, MOV, MKV — up to 20GB</p>
   </label>
*/
.wc-dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .6rem;
  padding: clamp(2rem, 6vw, 3.5rem) 1.5rem;
  text-align: center;
  border: 1.5px dashed var(--line-strong);
  border-radius: var(--radius-lg);
  background: var(--surface-2);
  color: var(--muted);
  cursor: pointer;
  transition: border-color var(--dur-mid) var(--ease-standard),
    background var(--dur-mid) var(--ease-standard);
}

.wc-dropzone:hover,
.wc-dropzone:focus-within {
  border-color: var(--brand-glow);
  background: var(--brand-dim);
}

.wc-dropzone:focus-within {
  outline: 2px solid var(--brand-soft);
  outline-offset: 3px;
}

.wc-dropzone.is-drag-over {
  border-color: var(--brand);
  background: var(--brand-dim);
  box-shadow: 0 0 0 3px var(--brand-ring);
}

.wc-dropzone.is-error {
  border-color: var(--err-bdr);
  background: var(--err-bg);
}

.wc-dropzone-icon {
  width: 32px;
  height: 32px;
  color: var(--brand-soft);
}

.wc-dropzone-title {
  color: var(--text);
  font-size: .92rem;
  font-weight: 600;
}

.wc-dropzone-hint {
  color: var(--subtle);
  font-family: var(--font-mono);
  font-size: .7rem;
  letter-spacing: .04em;
  text-transform: uppercase;
}

/* -- Uploading / processing state ---------------------------------------
   Swapped in (e.g. by replacing the dropzone's content, or toggling a
   sibling element) once a file has been selected and is uploading. Pairs
   with .wc-progress from components/progress.css. */
.wc-dropzone-active {
  display: flex;
  flex-direction: column;
  gap: .75rem;
  padding: 1.25rem 1.5rem;
  border: 1px solid var(--line-hi);
  border-radius: var(--radius-lg);
  background: var(--surface);
}

.wc-dropzone-active-head {
  display: flex;
  align-items: center;
  gap: .75rem;
}

.wc-dropzone-file-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border-radius: var(--radius-md);
  background: var(--brand-dim);
  color: var(--brand-soft);
}

.wc-dropzone-file-icon svg {
  width: 18px;
  height: 18px;
}

.wc-dropzone-file-meta {
  min-width: 0;
  flex: 1;
}

.wc-dropzone-file-name {
  overflow: hidden;
  color: var(--text);
  font-size: .84rem;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.wc-dropzone-file-size {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: .68rem;
}

/* -- Success / error result ---------------------------------------------- */
.wc-dropzone-result {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .9rem 1.1rem;
  border-radius: var(--radius-md);
  font-size: .84rem;
}

.wc-dropzone-result.ok {
  background: var(--ok-bg);
  border: 1px solid var(--ok-bdr);
  color: var(--ok);
}

.wc-dropzone-result.err {
  background: var(--err-bg);
  border: 1px solid var(--err-bdr);
  color: var(--err);
}

.wc-dropzone-result svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

/* -- Empty states -------------------------------------------------------
   For a library/table/rail with nothing to show yet — no videos, no
   search results, no uploads, no playlists, an empty processing queue.
   One shared shape; vary the icon, copy, and optional action.

   <div class="wc-empty-state">
     <span class="wc-empty-state-icon">…svg…</span>
     <p class="wc-empty-state-title">No videos yet</p>
     <p class="wc-empty-state-description">Upload your first video to get started.</p>
     <a class="wc-btn wc-btn-primary" href="…">Upload a video</a>
   </div>
*/
.wc-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .6rem;
  padding: clamp(2.5rem, 6vw, 4rem) 1.5rem;
  text-align: center;
  color: var(--muted);
}

.wc-empty-state-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  margin-bottom: .4rem;
  border-radius: 50%;
  background: var(--surface-2);
  border: 1px solid var(--line-hi);
  color: var(--subtle);
}

.wc-empty-state-icon svg {
  width: 24px;
  height: 24px;
}

.wc-empty-state-title {
  color: var(--text);
  font-size: .96rem;
  font-weight: 600;
}

.wc-empty-state-description {
  max-width: 42ch;
  font-size: .84rem;
  line-height: 1.6;
}

.wc-empty-state > .wc-btn,
.wc-empty-state > .wc-btn-primary-sm {
  margin-top: .4rem;
}

/* Compact variant for a smaller inline slot (e.g. inside a sidebar rail
   or an admin table with no rows) rather than a full-page state. */
.wc-empty-state.is-compact {
  padding: 1.75rem 1rem;
  gap: .4rem;
}

.wc-empty-state.is-compact .wc-empty-state-icon {
  width: 40px;
  height: 40px;
  margin-bottom: 0;
}

.wc-empty-state.is-compact .wc-empty-state-icon svg {
  width: 18px;
  height: 18px;
}

.wc-empty-state.is-compact .wc-empty-state-title {
  font-size: .84rem;
}

/* -- Skeleton loading state -----------------------------------------------
   A restrained pulse (opacity, not a sweeping shimmer gradient) — matches
   the calm motion language already established by .wc-status-dot.is-checking
   and the particles/portal transitions. Apply .wc-skeleton to any element
   that stands in for not-yet-loaded content; its own size/radius should
   already match what it's replacing (a .wc-aspect box, a text line, an
   avatar circle, …).

   <div class="wc-aspect wc-aspect-video wc-skeleton"></div>
   <div class="wc-skeleton-line" style="width: 70%"></div>
   <div class="wc-skeleton-line" style="width: 40%"></div>
*/
.wc-skeleton {
  position: relative;
  overflow: hidden;
  background: var(--surface-2);
  animation: wc-skeleton-pulse 1.8s ease-in-out infinite;
}

.wc-skeleton-line {
  height: .8em;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  animation: wc-skeleton-pulse 1.8s ease-in-out infinite;
}

@keyframes wc-skeleton-pulse {
  0%, 100% { opacity: .55; }
  50%      { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .wc-skeleton,
  .wc-skeleton-line {
    animation: none;
    opacity: .75;
  }
}

/* -- Composite skeleton patterns ----------------------------------------- */

/* Video-card grid: pair with .wc-video-grid, one per card. */
.wc-skeleton-card {
  display: flex;
  flex-direction: column;
  gap: .7rem;
}

.wc-skeleton-card .wc-skeleton-line:nth-child(2) { width: 85%; }
.wc-skeleton-card .wc-skeleton-line:nth-child(3) { width: 50%; }

/* Table rows: pair with .wc-table, replaces <td> contents. */
.wc-skeleton-cell {
  display: inline-block;
  width: 100%;
  max-width: 12rem;
}

/* Player shell before the source is ready. */
.wc-skeleton-player {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* -- Stat blocks ---------------------------------------------- */
.wc-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border: 1px solid var(--line-hi);
  border-top: none;
  background: var(--surface);
  backdrop-filter: blur(var(--blur-card));
}

.wc-stat {
  padding: 1.1rem 1.4rem;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.wc-stat:nth-child(3n) {
  border-right: none;
}

.wc-stat-label {
  margin-bottom: .45rem;
  color: var(--subtle);
  font-family: var(--font-mono);
  font-size: .65rem;
  letter-spacing: .14em;
  text-transform: uppercase;
}

.wc-stat-value {
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 1.05rem;
  font-weight: 500;
}

@media (max-width: 580px) {
  .wc-stats {
    grid-template-columns: repeat(2, 1fr);
  }

  .wc-stat:nth-child(3n) {
    border-right: 1px solid var(--line);
  }

  .wc-stat:nth-child(2n) {
    border-right: none;
  }
}

/* -- Architecture rows (numbered feature list) ----------------- */
.wc-architecture {
  display: flex;
  flex-direction: column;
}

.wc-architecture-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: clamp(12px, 2.5vw, 48px);
  align-items: start;
  padding: clamp(24px, 3.2vw, 40px) 0;
  border-top: 1px solid var(--line-hi);
}

.wc-architecture-label {
  display: flex;
  align-items: center;
  gap: 16px;
}

.wc-architecture-number {
  width: 2.4ch;
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .1em;
  color: var(--subtle);
}

.wc-architecture-icon {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: var(--radius-md);
  background: var(--brand-dim);
  border: 1px solid rgba(46,127,255,.18);
  color: var(--brand-soft);
  flex-shrink: 0;
}

.wc-architecture-icon img {
  width: 24px;
  height: 24px;
  object-fit: contain;
  border-radius: 4px;
}

.wc-architecture-title {
  font-family: var(--font-mono);
  font-size: .8rem;
  font-weight: 500;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--text);
}

.wc-architecture-description {
  max-width: 52ch;
  font-size: .95rem;
  line-height: 1.7;
  color: var(--muted);
}

/* -- Footer ----------------------------------------------------- */
.wc-footer {
  border-top: 1px solid var(--line);
  padding: clamp(40px, 5vw, 64px) 0 clamp(28px, 3vw, 40px);
}

.wc-footer-main {
  width: var(--shell);
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 36px;
}

.wc-footer-brand {
  display: flex;
  align-items: flex-start;
  gap: 16px;
}

.wc-footer-copy {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.wc-footer-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.wc-footer-tag {
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line-hi);
  font-family: var(--font-mono);
  font-size: .6rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--subtle);
}

.wc-footer-nav {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(18px, 3vw, 36px);
}

.wc-footer-link {
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--muted);
  transition: color var(--dur-mid) var(--ease-standard);
}

.wc-footer-link:hover {
  color: var(--brand-soft);
}

.wc-footer-bottom {
  width: var(--shell);
  margin: clamp(36px, 5vw, 56px) auto 0;
  padding-top: clamp(20px, 3vw, 28px);
  border-top: 1px solid var(--line);
}

.wc-footer-tagline {
  max-width: 64ch;
  font-size: .78rem;
  line-height: 1.6;
  color: var(--subtle);
}

/* -- App launcher ------------------------------------------------
   Markup contract (see js/launcher.js and ai.txt for the full example):

   <div class="wc-launcher">
     <button class="wc-icon-btn wc-launcher-toggle" aria-haspopup="true"
             aria-expanded="false" aria-controls="wc-launcher-menu">…</button>
     <div class="wc-launcher-menu" id="wc-launcher-menu">
       <a class="wc-menu-item" href="…" data-mobile-app-url="…(optional)">
         <span class="wc-menu-icon">
           <span class="wc-launcher-fallback">N</span>
           <img src="…" onerror="this.style.display='none'; this.previousElementSibling.style.display='flex';" />
         </span>
         Label
       </a>
       …
     </div>
   </div>
------------------------------------------------------------------ */
.wc-launcher {
  position: relative;
}

.wc-launcher-toggle svg {
  transition: transform .3s cubic-bezier(.34,1.56,.64,1);
}

.wc-launcher-toggle[aria-expanded="true"] svg {
  transform: rotate(90deg);
}

.wc-launcher-menu {
  position: absolute;
  top: calc(100% + 18px);
  left: 50%;
  z-index: 20;
  display: grid;
  grid-template-columns: repeat(3, minmax(74px, 1fr));
  gap: 6px;
  padding: 14px;
  width: min(300px, calc(100vw - 32px));
  border-radius: var(--radius-xl);
  border: 1px solid var(--line-hi);
  background: var(--menu-bg);
  backdrop-filter: blur(28px) saturate(1.4);
  -webkit-backdrop-filter: blur(28px) saturate(1.4);
  box-shadow: var(--shadow-card);
  transform-origin: top center;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateX(-50%) translateY(-8px) scale(.94);
  transition: opacity .18s ease, transform .34s cubic-bezier(.34,1.56,.64,1), visibility .34s;
}

.wc-launcher-menu::before {
  content: "";
  position: absolute;
  top: -6px;
  left: 50%;
  margin-left: -6px;
  width: 12px;
  height: 12px;
  background: var(--menu-bg);
  border-left: 1px solid var(--line-hi);
  border-top: 1px solid var(--line-hi);
  border-radius: 3px 0 0 0;
  transform: rotate(45deg);
}

.wc-launcher-menu.open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0) scale(1);
}

.wc-menu-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 12px 4px;
  border-radius: var(--radius-md);
  color: var(--text-soft);
  font-family: var(--font-mono);
  font-size: .6rem;
  letter-spacing: .04em;
  text-align: center;
  opacity: 0;
  transform: translateY(6px) scale(.92);
  transition: background 150ms var(--ease-standard), color 150ms var(--ease-standard),
    transform .3s cubic-bezier(.34,1.56,.64,1), opacity .2s ease;
}

.wc-menu-item:hover,
.wc-menu-item:focus-visible {
  background: var(--brand-dim);
  color: var(--brand-soft);
}

.wc-launcher-menu.open .wc-menu-item {
  opacity: 1;
  transform: translateY(0) scale(1);
}

.wc-launcher-menu.open .wc-menu-item:nth-child(1) { transition-delay: .02s; }
.wc-launcher-menu.open .wc-menu-item:nth-child(2) { transition-delay: .05s; }
.wc-launcher-menu.open .wc-menu-item:nth-child(3) { transition-delay: .08s; }
.wc-launcher-menu.open .wc-menu-item:nth-child(4) { transition-delay: .11s; }
.wc-launcher-menu.open .wc-menu-item:nth-child(5) { transition-delay: .14s; }
.wc-launcher-menu.open .wc-menu-item:nth-child(6) { transition-delay: .17s; }
.wc-launcher-menu.open .wc-menu-item:nth-child(7) { transition-delay: .2s; }
.wc-launcher-menu.open .wc-menu-item:nth-child(8) { transition-delay: .23s; }

.wc-menu-icon {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  border: 1px solid var(--line-hi);
  color: var(--brand-soft);
  font-family: var(--font-mono);
  font-size: .8rem;
  font-weight: 500;
}

.wc-menu-icon img {
  position: absolute;
  inset: 6px;
  width: 22px;
  height: 22px;
  object-fit: contain;
  border-radius: 4px;
}

/* Single-letter fallback glyph shown if the icon image 404s */
.wc-launcher-fallback {
  display: none;
  position: absolute;
  inset: 0;
  align-items: center;
  justify-content: center;
}

/* On mobile the 3-col icon grid is fiddly to tap — collapse it into a
   single-column dropdown list instead. */
@media (max-width: 640px) {
  .wc-launcher-menu {
    position: fixed !important;
    top: calc(env(safe-area-inset-top,0px) + clamp(64px,7vh,80px) + 10px) !important;
    left: 12px !important;
    right: 12px !important;
    width: auto !important;
    grid-template-columns: 1fr !important;
    gap: 2px !important;
    padding: 8px !important;
    max-height: calc(100vh - clamp(64px,7vh,80px) - env(safe-area-inset-top,0px) - env(safe-area-inset-bottom,0px) - 32px);
    overflow-y: auto;
    transform-origin: top center;
    transform: translateY(-8px) scale(.94) !important;
  }

  .wc-launcher-menu.open {
    transform: translateY(0) scale(1) !important;
  }

  .wc-launcher-menu::before {
    display: none;
  }

  .wc-launcher-menu .wc-menu-item {
    flex-direction: row !important;
    justify-content: flex-start !important;
    text-align: left !important;
    gap: 14px !important;
    padding: 11px 10px !important;
    font-size: .78rem !important;
    letter-spacing: .02em !important;
    text-transform: none;
  }
}

/* -- Portal transition veil --------------------------------------
   Shown briefly while navigating away via a .wc-portal-link, so the
   jump to another Wolf Cloud subdomain doesn't feel like a hard cut.
   See js/portal-transition.js. */
.wc-portal-veil {
  position: fixed;
  inset: 0;
  z-index: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(ellipse 1000px 500px at 50% 34%, rgba(46,127,255,.16), transparent 62%),
    var(--ink);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 260ms var(--ease-standard), visibility 0ms linear 260ms;
}

.wc-portal-veil.is-active {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity 220ms var(--ease-standard);
}

.wc-portal-veil-inner {
  text-align: center;
}

.wc-portal-spinner {
  width: 30px;
  height: 30px;
  margin: 0 auto 18px;
  border-radius: 50%;
  border: 2px solid rgba(46,127,255,.22);
  border-top-color: var(--brand-soft);
  animation: wc-spin .8s linear infinite;
}

.wc-portal-veil-label {
  margin: 0;
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-soft);
}

@media (prefers-reduced-motion: reduce) {
  .wc-portal-spinner {
    animation: none;
  }
}

/* -- Intro overlay (full-logo splash on first paint) --------------
   Optional: a page can include this once, near the top of <body>, for
   a brief branded reveal before content settles. Purely decorative —
   removes itself once its animation ends (see js/portal-transition.js). */
.wc-intro-overlay {
  position: fixed;
  inset: 0;
  z-index: 400;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(ellipse 1000px 500px at 50% 34%, rgba(46,127,255,.16), transparent 62%),
    var(--ink);
  pointer-events: none;
  animation: wc-veil 1.65s var(--ease-standard) both;
}

.wc-intro-overlay img {
  width: min(70vw, 460px);
  height: auto;
  animation: wc-intro-reveal 1.65s cubic-bezier(.16,1,.3,1) both;
}

@keyframes wc-veil {
  0%, 72% { opacity: 1; }
  100%    { opacity: 0; visibility: hidden; }
}

@keyframes wc-intro-reveal {
  0%         { opacity: 0; transform: scale(.95) translateY(10px); filter: blur(10px); }
  22%, 64%   { opacity: 1; transform: none; filter: blur(0); }
  100%       { opacity: 0; transform: scale(.92) translateY(-10px); filter: blur(4px); }
}

/* -- Motion --------------------------------------------------- */
.wc-fade-up {
  animation: wc-fade-up var(--dur-slow) ease-out both;
}

@keyframes wc-fade-up {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}

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

/* -- Particles -------------------------------------------------
   Container is styled here; individual dots get their randomized
   left/size/duration/delay set inline by js/particles.js, using the
   --pd (drift distance) and --po (peak opacity) custom properties
   consumed by @keyframes wc-drift below. */
#wc-particles,
.wc-particles {
  position: fixed;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 0;
}

.wc-particle {
  position: absolute;
  top: 0;
  border-radius: 50%;
  background: rgba(46,127,255,.42);
  box-shadow: 0 0 18px rgba(46,127,255,.22);
  opacity: 0;
  animation-name: wc-drift;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}

@keyframes wc-drift {
  0%   { transform: translate3d(0, 110vh, 0); opacity: 0; }
  12%  { opacity: var(--po, .3); }
  100% { transform: translate3d(var(--pd, 0px), -12vh, 0); opacity: 0; }
}

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

  html {
    scroll-behavior: auto;
  }

  .wc-fade-up {
    animation: none;
  }
}

/* -- Map shell (new in 2.4.0) ------------------------------------------
   Full-bleed container for a map view plus a positioning system for the
   floating chrome (controls, search, attribution) that sits over it. This
   system draws no tiles/vectors itself — .wc-map-canvas is a plain
   background surface for whatever map provider (Leaflet, MapLibre, Google
   Maps JS, Mapbox GL) mounts into it; this file only styles the frame
   around it, same principle as components/player.css around real <video>.

   <div class="wc-map-shell">
     <div class="wc-map-canvas" id="map"><!-- map library mounts here --></div>
     <div class="wc-map-controls is-top-left"><!-- .wc-map-search --></div>
     <div class="wc-map-controls is-top-right"><!-- mode switch --></div>
     <div class="wc-map-controls is-bottom-right"><!-- .wc-map-zoom, recenter --></div>
     <div class="wc-map-attribution">© Map data contributors</div>
   </div>
*/
.wc-map-shell {
  position: relative;
  overflow: hidden;
  width: 100%;
  height: 100%;
  min-height: 320px;
  background: var(--ink-2);
  border-radius: var(--radius-lg);
  isolation: isolate;
}

/* Full-bleed usage (the primary app view, not a card) skips the radius. */
.wc-map-shell.is-fullbleed {
  border-radius: 0;
}

.wc-map-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  background: var(--surface-2);
}

/* Placeholder texture shown until a real map provider paints over it —
   keeps the shell from reading as broken/blank in demos and during load. */
.wc-map-canvas.is-placeholder {
  background-image:
    linear-gradient(var(--line) 1px, transparent 1px),
    linear-gradient(90deg, var(--line) 1px, transparent 1px);
  background-size: var(--grid-size) var(--grid-size);
  background-color: var(--surface-2);
}

/* -- Floating chrome anchors -------------------------------------------
   Each corner is an independent flex stack so controls can be added or
   removed per screen without renegotiating layout. z-index sits above the
   canvas but below modal/sheet chrome (see map-sheet.css). */
.wc-map-controls {
  position: absolute;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: .6rem;
  max-width: calc(100% - 2rem);
}

.wc-map-controls.is-top-left {
  top: 1rem;
  left: 1rem;
}

.wc-map-controls.is-top-right {
  top: 1rem;
  right: 1rem;
  align-items: flex-end;
}

.wc-map-controls.is-bottom-left {
  bottom: 1rem;
  left: 1rem;
}

.wc-map-controls.is-bottom-right {
  bottom: 1rem;
  right: 1rem;
  align-items: flex-end;
}

.wc-map-attribution {
  position: absolute;
  z-index: 15;
  right: .6rem;
  bottom: .5rem;
  padding: .2rem .55rem;
  border-radius: var(--radius-sm);
  background: rgba(3, 6, 14, 0.45);
  backdrop-filter: blur(6px);
  color: var(--text-soft);
  font-family: var(--font-mono);
  font-size: .62rem;
  letter-spacing: .03em;
}

@media (max-width: 640px) {
  .wc-map-controls {
    gap: .5rem;
  }

  .wc-map-controls.is-top-left,
  .wc-map-controls.is-top-right {
    top: .75rem;
  }

  .wc-map-controls.is-bottom-left,
  .wc-map-controls.is-bottom-right {
    bottom: .75rem;
  }
}

/* -- Map controls (new in 2.4.0) ----------------------------------------
   Floating buttons that sit inside a .wc-map-controls corner (see
   map-shell.css). Built on the same visual language as .wc-icon-btn but
   opaque and shadowed, since they float directly over unpredictable map
   imagery instead of a page background.

   <div class="wc-map-controls is-bottom-right">
     <div class="wc-map-control-group">
       <button class="wc-map-control-btn" aria-label="Zoom in"><svg>+</svg></button>
       <button class="wc-map-control-btn" aria-label="Zoom out"><svg>-</svg></button>
     </div>
     <button class="wc-map-control-btn" aria-label="Show my location"><svg><!-- crosshair --></svg></button>
     <button class="wc-map-control-btn" aria-label="Map layers"><svg><!-- layers --></svg></button>
   </div>

   Style switcher (Map / Satellite / Terrain), typically top-right:
   <div class="wc-map-style-switch" role="group" aria-label="Map style">
     <button class="wc-btn-chip is-active">Map</button>
     <button class="wc-btn-chip">Satellite</button>
     <button class="wc-btn-chip">Terrain</button>
   </div>

   Compass — rotates its needle icon to match the map's current bearing
   (0 = north-up), and resets to north on click:
   <button class="wc-map-control-btn wc-map-compass" aria-label="Reset rotation to north"
           style="--wc-bearing: 42deg"><svg><!-- compass.svg --></svg></button>
*/
.wc-map-control-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  border: 1px solid var(--line-hi);
  border-radius: var(--radius-md);
  background: var(--surface);
  backdrop-filter: blur(var(--blur-card));
  box-shadow: var(--shadow-card-soft);
  color: var(--text-soft);
  transition: background var(--dur-fast) var(--ease-standard),
    color var(--dur-fast) var(--ease-standard),
    transform var(--dur-fast) var(--ease-standard);
}

.wc-map-control-btn svg {
  width: 19px;
  height: 19px;
  flex-shrink: 0;
}

.wc-map-control-btn:hover {
  background: var(--surface-3);
  color: var(--text);
}

.wc-map-control-btn:active {
  transform: scale(0.94);
}

.wc-map-control-btn:focus-visible {
  outline: 2px solid var(--brand-soft);
  outline-offset: 2px;
}

.wc-map-control-btn.is-active {
  background: var(--brand-dim);
  color: var(--brand-soft);
  border-color: rgba(46, 127, 255, .35);
}

/* Compass — the app sets --wc-bearing (a per-instance value, same pattern
   as --wc-progress/--wc-rating) to match the map's current rotation on
   every frame/pan event; the needle rotates, the button frame doesn't.
   Pair with .is-rotated (app toggles it off only when bearing is exactly
   0) so "you're rotated off north" stays visible at a glance without
   reading the angle — CSS can't branch on a custom property's value, so
   this can't be derived from --wc-bearing alone. */
.wc-map-compass {
  --wc-bearing: 0deg;
}

.wc-map-compass svg {
  transition: transform var(--dur-fast) var(--ease-standard);
  transform: rotate(var(--wc-bearing));
}

.wc-map-compass.is-rotated {
  color: var(--brand-soft);
}

/* Vertically-stacked pair (zoom in/out) sharing one rounded surface with a
   hairline divider instead of two separate floating buttons. */
.wc-map-control-group {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line-hi);
  border-radius: var(--radius-md);
  background: var(--surface);
  backdrop-filter: blur(var(--blur-card));
  box-shadow: var(--shadow-card-soft);
  overflow: hidden;
}

.wc-map-control-group .wc-map-control-btn {
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  backdrop-filter: none;
}

.wc-map-control-group .wc-map-control-btn:first-child {
  border-bottom: 1px solid var(--line);
}

.wc-map-control-group .wc-map-control-btn:active {
  transform: none;
  background: var(--surface-3);
}

/* -- Map style switch ---------------------------------------------------
   Reuses .wc-btn-chip (components/buttons.css) as a segmented group. */
.wc-map-style-switch {
  display: flex;
  gap: .4rem;
  padding: .3rem;
  border: 1px solid var(--line-hi);
  border-radius: var(--radius-pill);
  background: var(--surface);
  backdrop-filter: blur(var(--blur-card));
  box-shadow: var(--shadow-card-soft);
}

/* .wc-btn-chip has no built-in active state (its existing consumers are
   plain filter pills) — scope one here rather than changing the shared
   component's default look for every other page that uses it. */
.wc-map-style-switch .wc-btn-chip.is-active {
  background: var(--brand-dim);
  border-color: rgba(46, 127, 255, .4);
  color: var(--brand-soft);
}

@media (max-width: 640px) {
  .wc-map-control-btn {
    width: 36px;
    height: 36px;
  }
}

/* -- Map search / geocoder (new in 2.4.0) --------------------------------
   A floating search bar over the map plus its autocomplete results list.
   Pair with js/map-search.js for open/close and keyboard-navigation
   plumbing — fetching/ranking results is the consuming app's job, this
   only owns the UI shell and its interaction states.

   <div class="wc-map-search">
     <div class="wc-input-wrap wc-map-search-field">
       <span class="wc-map-search-icon"><svg><!-- search --></svg></span>
       <input class="wc-input" type="text" placeholder="Search here"
              data-map-search data-results="#pg-map-results" autocomplete="off">
       <button class="wc-map-search-clear" type="button" aria-label="Clear search"><svg><!-- close --></svg></button>
     </div>
     <div class="wc-map-search-results" id="pg-map-results" hidden>
       <a class="wc-map-result" href="#">
         <span class="wc-map-result-icon"><svg><!-- map-pin --></svg></span>
         <span class="wc-map-result-body">
           <span class="wc-map-result-name">Union Square</span>
           <span class="wc-map-result-address">San Francisco, CA</span>
         </span>
         <span class="wc-map-result-distance">1.2 mi</span>
       </a>
     </div>
   </div>
*/
.wc-map-search {
  position: relative;
  width: min(360px, 100%);
}

.wc-map-search-field {
  gap: .5rem;
  padding: 0 .6rem;
}

.wc-map-search-field .wc-input {
  border: 0;
  background: transparent;
  box-shadow: none;
  min-height: 44px;
  padding: .5rem .1rem;
}

.wc-map-search-field .wc-input:focus {
  box-shadow: none;
}

.wc-map-search-icon {
  display: inline-flex;
  flex-shrink: 0;
  color: var(--subtle);
}

.wc-map-search-icon svg {
  width: 18px;
  height: 18px;
}

.wc-map-search-clear {
  display: none;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  color: var(--subtle);
  transition: background var(--dur-fast) var(--ease-standard), color var(--dur-fast) var(--ease-standard);
}

.wc-map-search-clear svg {
  width: 14px;
  height: 14px;
}

.wc-map-search-clear:hover {
  background: var(--surface-3);
  color: var(--text);
}

.wc-map-search-field.has-value .wc-map-search-clear {
  display: inline-flex;
}

/* Loading state (query in flight) — swaps the clear button for a spinner,
   reusing the same @keyframes wc-spin already defined in buttons.css
   rather than redeclaring it. The app toggles this class itself around
   its geocoding request; js/map-search.js does not fetch, so it never
   sets this. */
.wc-map-search-field.is-loading .wc-map-search-clear {
  display: none;
}

.wc-map-search-field.is-loading::after {
  content: '';
  flex-shrink: 0;
  width: 14px;
  height: 14px;
  margin-right: .1rem;
  border: 2px solid var(--subtle);
  border-top-color: var(--brand-soft);
  border-radius: 50%;
  animation: wc-spin .6s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
  .wc-map-search-field.is-loading::after {
    animation-duration: 1.4s;
  }
}

.wc-map-search-results {
  position: absolute;
  z-index: 25;
  top: calc(100% + .5rem);
  left: 0;
  right: 0;
  max-height: min(360px, 60vh);
  overflow-y: auto;
  border: 1px solid var(--line-hi);
  border-radius: var(--radius-lg);
  background: var(--menu-bg);
  backdrop-filter: blur(var(--blur-card));
  box-shadow: var(--shadow-card);
  padding: .4rem;
}

.wc-map-result {
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: .6rem .65rem;
  border-radius: var(--radius-md);
  color: var(--text-soft);
  transition: background var(--dur-fast) var(--ease-standard);
}

.wc-map-result:hover,
.wc-map-result.is-active {
  background: var(--surface-3);
  color: var(--text);
}

.wc-map-result-icon {
  display: inline-flex;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--brand-soft);
}

.wc-map-result-icon svg {
  width: 16px;
  height: 16px;
}

.wc-map-result-body {
  display: flex;
  flex-direction: column;
  gap: .1rem;
  min-width: 0;
  flex: 1;
}

.wc-map-result-name {
  font-size: .86rem;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.wc-map-result-address {
  font-size: .74rem;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.wc-map-result-distance {
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-size: .68rem;
  color: var(--subtle);
}

.wc-map-search-empty {
  padding: 1.1rem .8rem;
  text-align: center;
  color: var(--muted);
  font-size: .82rem;
}

@media (max-width: 640px) {
  .wc-map-search {
    width: 100%;
  }
}

/* -- Map markers (new in 2.4.0) ------------------------------------------
   Custom HTML marker/pin styling for map libraries that render overlays as
   DOM elements positioned absolutely over the canvas (Leaflet divIcon,
   MapLibre/Mapbox GL Markers, Google Maps AdvancedMarkerElement) rather
   than the library's own default pin. The map library still owns
   positioning (translate to lat/lng); this file only styles the marker
   itself once placed.

   <button class="wc-map-pin" aria-label="Union Square">
     <span class="wc-map-pin-icon"><svg><!-- category icon --></svg></span>
   </button>

   Destination/selected variant: add .is-selected. Plain dot (current
   location, transit stop): .wc-map-dot, optionally .wc-map-dot-accuracy
   as a sibling for the accuracy-radius pulse. Clustered group: .wc-map-cluster.
*/
.wc-map-pin {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  transform: translate(-50%, -100%);
  transform-origin: bottom center;
  filter: drop-shadow(0 4px 8px rgba(4, 8, 20, .45));
  transition: transform var(--dur-fast) var(--ease-standard);
}

.wc-map-pin::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--brand);
  border: 2px solid var(--ink);
  border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
}

.wc-map-pin-icon {
  position: relative;
  z-index: 1;
  display: inline-flex;
  color: #fff;
  margin-top: -6px;
}

.wc-map-pin-icon svg {
  width: 16px;
  height: 16px;
}

.wc-map-pin:hover,
.wc-map-pin:focus-visible {
  transform: translate(-50%, -100%) scale(1.08);
}

.wc-map-pin:focus-visible {
  outline: none;
}

.wc-map-pin.is-selected {
  width: 42px;
  height: 42px;
}

.wc-map-pin.is-selected::before {
  background: var(--brand-2);
  box-shadow: 0 0 0 4px var(--brand-ring);
}

/* Muted variant for secondary/context results shown alongside a primary
   selection (e.g. other search hits while one is open in the infobox). */
.wc-map-pin.is-muted::before {
  background: var(--surface-3);
  border-color: var(--line-strong);
}

.wc-map-pin.is-muted .wc-map-pin-icon {
  color: var(--muted);
}

/* -- Plain dot marker (current location, transit stop) ------------------ */
.wc-map-dot {
  position: relative;
  width: 16px;
  height: 16px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: var(--brand);
  border: 3px solid var(--ink);
  box-shadow: var(--shadow-card-soft);
}

.wc-map-dot-accuracy {
  position: absolute;
  inset: 50% auto auto 50%;
  width: 60px;
  height: 60px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: var(--brand-dim);
  animation: wc-map-pulse 2.4s var(--ease-standard) infinite;
}

@keyframes wc-map-pulse {
  0% { transform: translate(-50%, -50%) scale(0.6); opacity: .55; }
  100% { transform: translate(-50%, -50%) scale(1); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .wc-map-dot-accuracy {
    animation: none;
    opacity: .35;
  }
}

/* -- Cluster badge -------------------------------------------------------
   Circular count badge replacing individual pins once the map is zoomed
   out past a legibility threshold — the map library decides when to swap,
   this only styles the result. */
.wc-map-cluster {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 38px;
  height: 38px;
  padding: 0 .5rem;
  transform: translate(-50%, -50%);
  border-radius: var(--radius-pill);
  background: var(--brand);
  border: 3px solid var(--ink);
  color: #fff;
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: .82rem;
  box-shadow: var(--shadow-card-soft);
  transition: transform var(--dur-fast) var(--ease-standard);
}

.wc-map-cluster:hover,
.wc-map-cluster:focus-visible {
  transform: translate(-50%, -50%) scale(1.08);
  outline: none;
}

.wc-map-cluster.is-lg {
  min-width: 48px;
  height: 48px;
  font-size: .95rem;
  background: var(--brand-2);
}

/* -- Map infobox / place card (new in 2.4.0) -----------------------------
   The popover a marker opens into — place name, rating, address, and
   quick actions. Works both anchored over the map (absolute-positioned by
   the map library next to the marker, tail pointing at it) and as a plain
   panel in a results list/sidebar (drop .wc-map-infobox-tail).

   <div class="wc-map-infobox">
     <button class="wc-map-infobox-close" aria-label="Close"><svg><!-- close --></svg></button>
     <img class="wc-map-infobox-image" src="…" alt="">
     <div class="wc-map-infobox-body">
       <h3 class="wc-map-infobox-title">Union Square</h3>
       <div class="wc-map-rating">
         <span class="wc-map-rating-stars" style="--wc-rating: 4.5"><span></span></span>
         <span class="wc-map-rating-value">4.5</span>
         <span class="wc-map-rating-count">(2,140)</span>
       </div>
       <p class="wc-map-infobox-address">333 Post St, San Francisco, CA</p>
       <p class="wc-map-infobox-meta"><span class="wc-badge ok">Open now</span><span class="wc-dot"></span>Closes 9 PM</p>
       <div class="wc-map-infobox-actions">
         <button class="wc-btn wc-btn-primary wc-btn-sm">Directions</button>
         <button class="wc-icon-btn" aria-label="Save"><svg><!-- star --></svg></button>
         <button class="wc-icon-btn" aria-label="Share"><svg><!-- share --></svg></button>
       </div>
     </div>
     <span class="wc-map-infobox-tail"></span>
   </div>
*/
.wc-map-infobox {
  position: relative;
  width: min(300px, 82vw);
  border: 1px solid var(--line-hi);
  border-radius: var(--radius-lg);
  background: var(--menu-bg);
  backdrop-filter: blur(var(--blur-card));
  box-shadow: var(--shadow-card);
  overflow: hidden;
}

.wc-map-infobox-close {
  position: absolute;
  z-index: 1;
  top: .5rem;
  right: .5rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: rgba(3, 6, 14, .45);
  color: #fff;
  backdrop-filter: blur(6px);
}

.wc-map-infobox-close svg {
  width: 14px;
  height: 14px;
}

.wc-map-infobox-close:hover {
  background: rgba(3, 6, 14, .65);
}

.wc-map-infobox-image {
  display: block;
  width: 100%;
  height: 128px;
  object-fit: cover;
  background: var(--surface-2);
}

.wc-map-infobox-body {
  display: flex;
  flex-direction: column;
  gap: .35rem;
  padding: .9rem 1rem 1rem;
}

.wc-map-infobox-title {
  font-size: 1rem;
  font-weight: 600;
  color: var(--text);
  letter-spacing: -.01em;
}

.wc-map-infobox-address {
  font-size: .8rem;
  color: var(--muted);
  line-height: 1.4;
}

.wc-map-infobox-meta {
  display: flex;
  align-items: center;
  gap: .5rem;
  font-size: .78rem;
  color: var(--text-soft);
}

.wc-map-infobox-actions {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin-top: .3rem;
}

.wc-map-infobox-actions .wc-btn {
  flex: 1;
}

/* Saved/favorite toggle — .wc-icon-btn has no built-in "filled" state
   elsewhere (its other consumers are momentary actions, not toggles), so
   it's scoped here rather than changing that shared component's default
   look. Toggle the class on click; the star SVG itself doesn't change. */
.wc-map-infobox-actions .wc-icon-btn.is-saved {
  background: var(--brand-dim);
  border-color: rgba(46, 127, 255, .4);
  color: var(--brand-soft);
}

.wc-map-infobox-actions .wc-icon-btn.is-saved svg {
  fill: currentColor;
}

/* -- Rating row -----------------------------------------------------------
   Star fill uses the same gradient-clip trick as .wc-progress' filled
   bar: --wc-rating (0–5) sets how much of the star row is painted brand
   color vs. the dim outline color, via a linear-gradient background. */
.wc-map-rating {
  display: flex;
  align-items: center;
  gap: .4rem;
}

.wc-map-rating-stars {
  --wc-rating: 0;
  display: inline-flex;
  width: 74px;
  height: 14px;
  background: linear-gradient(
    90deg,
    var(--brand-soft) 0%,
    var(--brand-soft) calc(var(--wc-rating, 0) / 5 * 100%),
    var(--line-strong) calc(var(--wc-rating, 0) / 5 * 100%),
    var(--line-strong) 100%
  );
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 16'%3E%3Cg fill='%23000'%3E%3Cpath d='M8 0l2.1 5.2 5.6.4-4.3 3.6 1.4 5.4L8 11.8 3.2 14.6l1.4-5.4L.3 5.6l5.6-.4z'/%3E%3Cpath d='M24 0l2.1 5.2 5.6.4-4.3 3.6 1.4 5.4-4.8-2.8-4.8 2.8 1.4-5.4-4.3-3.6 5.6-.4z'/%3E%3Cpath d='M40 0l2.1 5.2 5.6.4-4.3 3.6 1.4 5.4-4.8-2.8-4.8 2.8 1.4-5.4-4.3-3.6 5.6-.4z'/%3E%3Cpath d='M56 0l2.1 5.2 5.6.4-4.3 3.6 1.4 5.4-4.8-2.8-4.8 2.8 1.4-5.4-4.3-3.6 5.6-.4z'/%3E%3Cpath d='M72 0l2.1 5.2 5.6.4-4.3 3.6 1.4 5.4-4.8-2.8-4.8 2.8 1.4-5.4-4.3-3.6 5.6-.4z'/%3E%3C/g%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 16'%3E%3Cg fill='%23000'%3E%3Cpath d='M8 0l2.1 5.2 5.6.4-4.3 3.6 1.4 5.4L8 11.8 3.2 14.6l1.4-5.4L.3 5.6l5.6-.4z'/%3E%3Cpath d='M24 0l2.1 5.2 5.6.4-4.3 3.6 1.4 5.4-4.8-2.8-4.8 2.8 1.4-5.4-4.3-3.6 5.6-.4z'/%3E%3Cpath d='M40 0l2.1 5.2 5.6.4-4.3 3.6 1.4 5.4-4.8-2.8-4.8 2.8 1.4-5.4-4.3-3.6 5.6-.4z'/%3E%3Cpath d='M56 0l2.1 5.2 5.6.4-4.3 3.6 1.4 5.4-4.8-2.8-4.8 2.8 1.4-5.4-4.3-3.6 5.6-.4z'/%3E%3Cpath d='M72 0l2.1 5.2 5.6.4-4.3 3.6 1.4 5.4-4.8-2.8-4.8 2.8 1.4-5.4-4.3-3.6 5.6-.4z'/%3E%3C/g%3E%3C/svg%3E");
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
}

.wc-map-rating-value {
  font-family: var(--font-mono);
  font-size: .78rem;
  font-weight: 600;
  color: var(--text);
}

.wc-map-rating-count {
  font-size: .76rem;
  color: var(--subtle);
}

/* -- Anchored tail --------------------------------------------------------
   Add alongside a positioning modifier the consuming app sets (this file
   only draws the triangle; which edge it sits on depends on where the map
   library places the box relative to the marker). Default points down,
   for a box positioned above its marker. */
.wc-map-infobox-tail {
  position: absolute;
  left: 50%;
  bottom: -8px;
  width: 16px;
  height: 16px;
  transform: translateX(-50%) rotate(45deg);
  background: var(--menu-bg);
  border-right: 1px solid var(--line-hi);
  border-bottom: 1px solid var(--line-hi);
}

.wc-map-infobox.is-tail-top .wc-map-infobox-tail {
  top: -8px;
  bottom: auto;
  transform: translateX(-50%) rotate(225deg);
}

/* -- Directions panel (new in 2.4.0) --------------------------------------
   Route planning sidebar: origin/destination fields, travel-mode tabs, a
   summary header, and a turn-by-turn step list. Routing/ETA computation is
   the consuming app's job (a routing API or engine) — this only lays out
   whatever result it returns.

   <div class="wc-directions-panel">
     <div class="wc-directions-fields">
       <div class="wc-input-wrap"><input class="wc-input" placeholder="Your location"></div>
       <button class="wc-directions-swap" aria-label="Swap origin and destination"><svg><!-- swap --></svg></button>
       <div class="wc-input-wrap"><input class="wc-input" placeholder="Destination"></div>
     </div>
     <div class="wc-directions-modes" role="tablist" aria-label="Travel mode">
       <button class="wc-directions-mode is-active" role="tab" aria-selected="true"><svg><!-- car --></svg></button>
       <button class="wc-directions-mode" role="tab" aria-selected="false"><svg><!-- walk --></svg></button>
       <button class="wc-directions-mode" role="tab" aria-selected="false"><svg><!-- bike --></svg></button>
       <button class="wc-directions-mode" role="tab" aria-selected="false"><svg><!-- transit --></svg></button>
     </div>
     <div class="wc-directions-summary">
       <span class="wc-directions-duration">18 min</span>
       <span class="wc-directions-distance">6.2 mi</span>
       <span class="wc-badge ok">Fastest</span>
     </div>
     <ol class="wc-directions-steps">
       <li class="wc-directions-step">
         <span class="wc-directions-step-icon"><svg><!-- turn arrow --></svg></span>
         <span class="wc-directions-step-body">
           <span class="wc-directions-step-text">Head north on Market St</span>
           <span class="wc-directions-step-distance">0.4 mi</span>
         </span>
       </li>
     </ol>
   </div>
*/
.wc-directions-panel {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1.1rem;
  border-radius: var(--radius-lg);
  background: var(--surface);
  border: 1px solid var(--line-hi);
  box-shadow: var(--shadow-card-soft);
}

.wc-directions-fields {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: .5rem .6rem;
  align-items: center;
}

.wc-directions-fields .wc-input-wrap {
  grid-column: 1;
}

.wc-directions-swap {
  grid-column: 2;
  grid-row: 1 / span 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid var(--line-hi);
  background: var(--surface-2);
  color: var(--muted);
  transition: color var(--dur-fast) var(--ease-standard), transform var(--dur-mid) var(--ease-standard);
}

.wc-directions-swap svg {
  width: 15px;
  height: 15px;
}

.wc-directions-swap:hover {
  color: var(--brand-soft);
  transform: rotate(180deg);
}

.wc-directions-modes {
  display: flex;
  gap: .4rem;
}

.wc-directions-mode {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 1;
  height: 38px;
  border-radius: var(--radius-md);
  border: 1px solid var(--line-hi);
  background: var(--surface-2);
  color: var(--muted);
  transition: background var(--dur-fast) var(--ease-standard),
    color var(--dur-fast) var(--ease-standard),
    border-color var(--dur-fast) var(--ease-standard);
}

.wc-directions-mode svg {
  width: 17px;
  height: 17px;
}

.wc-directions-mode:hover {
  color: var(--text);
}

.wc-directions-mode.is-active {
  background: var(--brand-dim);
  border-color: rgba(46, 127, 255, .4);
  color: var(--brand-soft);
}

.wc-directions-summary {
  display: flex;
  align-items: baseline;
  gap: .6rem;
  padding-bottom: .8rem;
  border-bottom: 1px solid var(--line);
}

.wc-directions-duration {
  font-size: 1.4rem;
  font-weight: 600;
  color: var(--text);
  letter-spacing: -.02em;
}

.wc-directions-distance {
  font-family: var(--font-mono);
  font-size: .82rem;
  color: var(--muted);
}

.wc-directions-steps {
  display: flex;
  flex-direction: column;
  gap: 0;
  list-style: none;
}

.wc-directions-step {
  display: flex;
  align-items: flex-start;
  gap: .8rem;
  padding: .75rem 0;
  border-top: 1px solid var(--line);
}

.wc-directions-step:first-child {
  border-top: 0;
  padding-top: 0;
}

.wc-directions-step-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--brand-soft);
}

.wc-directions-step-icon svg {
  width: 15px;
  height: 15px;
}

.wc-directions-step-body {
  display: flex;
  flex-direction: column;
  gap: .15rem;
  padding-top: .3rem;
}

.wc-directions-step-text {
  font-size: .86rem;
  color: var(--text-soft);
  line-height: 1.4;
}

.wc-directions-step-distance {
  font-family: var(--font-mono);
  font-size: .72rem;
  color: var(--subtle);
}

/* Traffic-aware ETA badge — reuses the existing status tokens (ok/deg/err)
   rather than adding new "traffic" color tokens, since light/moderate/
   heavy congestion is exactly the same three-state semantic already
   defined for service status elsewhere in this system. */
.wc-directions-eta.wc-badge {
  font-size: .7rem;
}

/* Active step during turn-by-turn navigation — the app moves .is-current
   from step to step as the traveler's position updates. */
.wc-directions-step.is-current {
  margin: 0 -.75rem;
  padding: .75rem;
  border-top-color: transparent;
  border-radius: var(--radius-md);
  background: var(--brand-dim);
}

.wc-directions-step.is-current + .wc-directions-step {
  border-top-color: transparent;
}

.wc-directions-step.is-current .wc-directions-step-icon {
  background: var(--brand);
  color: #fff;
}

.wc-directions-step.is-current .wc-directions-step-text {
  color: var(--text);
  font-weight: 500;
}

/* -- Route options ---------------------------------------------------------
   Alternate-route picker shown after a directions request returns more
   than one option, before the traveler commits to one and starts
   navigating. Each card mirrors the summary row's duration/distance/ETA
   badge at a smaller scale.

   <div class="wc-directions-route-options">
     <button class="wc-directions-route-option is-selected">
       <span class="wc-directions-route-option-body">
         <span class="wc-directions-route-option-duration">18 min</span>
         <span class="wc-directions-route-option-label">via Market St</span>
       </span>
       <span class="wc-badge ok">Fastest</span>
     </button>
     <button class="wc-directions-route-option">
       <span class="wc-directions-route-option-body">
         <span class="wc-directions-route-option-duration">24 min</span>
         <span class="wc-directions-route-option-label">via 19th Ave</span>
       </span>
       <span class="wc-badge deg">Moderate traffic</span>
     </button>
   </div>
*/
.wc-directions-route-options {
  display: flex;
  flex-direction: column;
  gap: .5rem;
}

.wc-directions-route-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  padding: .7rem .85rem;
  border: 1px solid var(--line-hi);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  text-align: left;
  transition: background var(--dur-fast) var(--ease-standard),
    border-color var(--dur-fast) var(--ease-standard);
}

.wc-directions-route-option:hover {
  background: var(--surface-3);
}

.wc-directions-route-option.is-selected {
  background: var(--brand-dim);
  border-color: rgba(46, 127, 255, .4);
}

.wc-directions-route-option-body {
  display: flex;
  align-items: baseline;
  gap: .5rem;
}

.wc-directions-route-option-duration {
  font-size: .92rem;
  font-weight: 600;
  color: var(--text);
}

.wc-directions-route-option-label {
  font-size: .76rem;
  color: var(--muted);
}

/* -- Turn-by-turn navigation banner -----------------------------------------
   Full-width immersive bar for active navigation mode — replaces
   .wc-directions-panel once the traveler starts a route; the map takes
   the rest of the screen behind it. Reuses the existing chevron icons
   for turn direction rather than adding new ones (chevron-up = continue
   straight, chevron-left/-right = turn).

   <div class="wc-nav-banner">
     <span class="wc-nav-banner-icon"><svg><!-- chevron-left.svg --></svg></span>
     <div class="wc-nav-banner-body">
       <span class="wc-nav-banner-distance">400 ft</span>
       <span class="wc-nav-banner-instruction">Turn left onto Post St</span>
     </div>
     <span class="wc-nav-banner-next">Then right onto Grant Ave</span>
     <button class="wc-nav-banner-exit" aria-label="Exit navigation"><svg><!-- close.svg --></svg></button>
   </div>
*/
.wc-nav-banner {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.2rem;
  border-radius: var(--radius-lg);
  background: var(--menu-bg);
  backdrop-filter: blur(var(--blur-card));
  box-shadow: var(--shadow-card);
  border: 1px solid var(--line-hi);
}

.wc-nav-banner-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 52px;
  height: 52px;
  border-radius: var(--radius-md);
  background: var(--brand);
  color: #fff;
}

.wc-nav-banner-icon svg {
  width: 30px;
  height: 30px;
}

.wc-nav-banner-body {
  display: flex;
  flex-direction: column;
  gap: .1rem;
  min-width: 0;
}

.wc-nav-banner-distance {
  font-family: var(--font-mono);
  font-size: .78rem;
  color: var(--brand-soft);
}

.wc-nav-banner-instruction {
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--text);
  letter-spacing: -.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.wc-nav-banner-next {
  margin-left: auto;
  padding-left: 1rem;
  border-left: 1px solid var(--line);
  color: var(--muted);
  font-size: .78rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.wc-nav-banner-exit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  color: var(--muted);
  transition: background var(--dur-fast) var(--ease-standard), color var(--dur-fast) var(--ease-standard);
}

.wc-nav-banner-exit svg {
  width: 16px;
  height: 16px;
}

.wc-nav-banner-exit:hover {
  background: var(--surface-3);
  color: var(--text);
}

@media (max-width: 640px) {
  .wc-nav-banner-next {
    display: none;
  }
}

/* -- Bottom sheet (new in 2.4.0) ------------------------------------------
   Mobile drag-up panel for place details / directions / search results
   layered over the map. Pair with js/bottom-sheet.js for drag-to-resize
   and handle-click-to-cycle between its three snap states; without the
   script it still renders correctly at whichever state class is set
   server-side (is-peek/is-half/is-full), just without drag interaction.

   <div class="wc-sheet is-half" id="pg-sheet"
        data-snap-peek="96" data-snap-half="55%">
     <button class="wc-sheet-handle" aria-label="Resize panel" aria-expanded="true"></button>
     <div class="wc-sheet-content">
       <!-- .wc-map-infobox-body content, or a results/directions list -->
     </div>
   </div>

   Desktop layout typically doesn't use this at all — .wc-directions-panel
   or .wc-map-infobox sit in a fixed sidebar instead; this component is for
   the narrow/mobile layout where there's no room for a persistent sidebar.
*/
.wc-sheet {
  position: fixed;
  z-index: 40;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  max-height: 92vh;
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  background: var(--menu-bg);
  backdrop-filter: blur(var(--blur-card));
  box-shadow: 0 -8px 40px rgba(4, 8, 20, .45);
  border: 1px solid var(--line-hi);
  border-bottom: 0;
  touch-action: none;
  transition: height var(--dur-mid) var(--ease-standard);
}

/* Snap-state heights — js/bottom-sheet.js reads data-snap-peek/
   data-snap-half off the element (falling back to these) and animates
   between them plus a fixed 92vh "full" state. Set here too so the sheet
   renders correctly even before the script runs. */
.wc-sheet.is-peek {
  height: 96px;
}

.wc-sheet.is-half {
  height: 55%;
}

.wc-sheet.is-full {
  height: 92vh;
}

.wc-sheet-handle {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 28px;
  cursor: grab;
}

.wc-sheet-handle::before {
  content: "";
  width: 36px;
  height: 4px;
  border-radius: var(--radius-pill);
  background: var(--line-strong);
}

.wc-sheet-handle:active {
  cursor: grabbing;
}

.wc-sheet-handle:focus-visible {
  outline: 2px solid var(--brand-soft);
  outline-offset: -2px;
}

.wc-sheet-content {
  flex: 1;
  overflow-y: auto;
  padding: 0 1.1rem 1.25rem;
  -webkit-overflow-scrolling: touch;
}

/* Dragging state (set by bottom-sheet.js while a pointer is down) skips
   the height transition so the sheet tracks the finger 1:1. */
.wc-sheet.is-dragging {
  transition: none;
}

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

/* Above ~860px there's usually room for a persistent sidebar instead —
   consuming pages typically render .wc-directions-panel/.wc-map-infobox
   directly and never mount .wc-sheet at that width, but this keeps it
   sane if one is left in the DOM. */
@media (min-width: 861px) {
  .wc-sheet {
    left: 1rem;
    right: auto;
    bottom: 1rem;
    width: min(360px, 30vw);
    max-height: calc(100vh - 2rem);
    border-radius: var(--radius-lg);
    border-bottom: 1px solid var(--line-hi);
  }
}


        *,
        *::before,
        *::after {
            box-sizing: border-box;
        }

        html {
            background: var(--app-bg);
            -webkit-tap-highlight-color: transparent;
        }

        body {
            min-height: 100svh;
            margin: 0;
            color: var(--app-text);
            background-color: var(--app-bg);
            background-image:
                radial-gradient(ellipse 1200px 500px at 15% 0%, rgba(46, 127, 255, .22), transparent 60%),
                radial-gradient(ellipse 600px 600px at 85% 5%, rgba(14, 165, 233, .16), transparent 55%),
                radial-gradient(ellipse 1000px 700px at 50% 100%, rgba(30, 80, 200, .14), transparent 65%),
                var(--app-bg);
            background-attachment: fixed;
            padding-bottom: env(safe-area-inset-bottom);
            font-family: var(--font-sans, "IBM Plex Sans", system-ui, sans-serif);
        }

        :root[data-theme="light"] body {
            background-image:
                radial-gradient(ellipse 1200px 500px at 15% 0%, rgba(46, 127, 255, .09), transparent 60%),
                radial-gradient(ellipse 600px 600px at 85% 5%, rgba(14, 165, 233, .07), transparent 55%),
                radial-gradient(ellipse 1000px 700px at 50% 100%, rgba(30, 80, 200, .05), transparent 65%),
                var(--app-bg);
        }

        body::before {
            content: "";
            position: fixed;
            inset: 0;
            z-index: 0;
            pointer-events: none;
            background-image:
                linear-gradient(var(--app-grid-line) 1px, transparent 1px),
                linear-gradient(90deg, var(--app-grid-line) 1px, transparent 1px);
            background-size: 48px 48px;
        }

        .content,
        noscript {
            position: relative;
            z-index: 1;
        }

        button {
            font: inherit;
        }

        .intro-overlay {
            position: fixed;
            inset: 0;
            z-index: 999;
            display: flex;
            align-items: center;
            justify-content: center;
            pointer-events: none;
            background:
                radial-gradient(ellipse 1000px 500px at 50% 30%, rgba(46, 127, 255, .18), transparent 60%),
                var(--app-bg);
            animation: overlayExit var(--overlay-exit-duration) var(--overlay-exit-delay) cubic-bezier(.4, 0, .2, 1) both;
        }

        .intro-logo {
            display: block;
            width: var(--intro-logo-width);
            max-width: 90vw;
            height: auto;
            animation: introLogoReveal var(--intro-logo-duration) cubic-bezier(.16, 1, .3, 1) forwards;
            will-change: transform, opacity, filter;
        }

        @keyframes introLogoReveal {
            0% {
                opacity: 0;
                transform: translate3d(0, 18px, 0) scale(.94);
                filter: blur(12px);
            }

            18% {
                opacity: 1;
                transform: translate3d(0, 0, 0) scale(1);
                filter: blur(0);
            }

            68% {
                opacity: 1;
                transform: translate3d(0, 0, 0) scale(1);
                filter: blur(0);
            }

            100% {
                opacity: 0;
                transform: translate3d(0, -14px, 0) scale(.88);
                filter: blur(3px);
            }
        }

        @keyframes overlayExit {
            0% {
                opacity: 1;
                transform: scale(1);
                visibility: visible;
            }

            99% {
                opacity: 0;
                transform: scale(1.03);
                visibility: visible;
            }

            100% {
                opacity: 0;
                transform: scale(1.03);
                visibility: hidden;
            }
        }

        .progress-bar {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            z-index: 200;
            height: 2px;
            background: var(--app-accent);
            opacity: 0;
            transform: scaleX(0);
            transform-origin: left;
            transition: opacity .2s;
        }

        .progress-bar.on {
            opacity: 1;
            transition: transform .9s cubic-bezier(.1, 1, .2, 1);
        }

        .topbar {
            position: sticky;
            top: 0;
            z-index: 50;
            display: flex;
            align-items: center;
            gap: .75rem;
            min-height: 60px;
            padding: .6rem 1.35rem;
            background: var(--app-topbar-bg);
            border-bottom: 1px solid var(--app-border);
            box-shadow: 0 8px 40px rgba(4, 8, 20, .24), var(--app-inset);
            backdrop-filter: blur(var(--app-blur)) saturate(1.35);
            -webkit-backdrop-filter: blur(var(--app-blur)) saturate(1.35);
        }

        .topbar-logo {
            display: flex;
            align-items: center;
            justify-content: center;
            flex: 0 0 auto;
            width: 32px;
            height: 32px;
            color: var(--app-accent);
            background: var(--app-accent-dim);
            border: 1px solid var(--app-accent-bdr);
            border-radius: var(--app-radius-sm);
            box-shadow: var(--app-inset);
        }

        .topbar-logo svg,
        .icon-button svg,
        .action-svg,
        .toast-icon {
            fill: none;
            stroke: currentColor;
            stroke-linecap: round;
            stroke-linejoin: round;
        }

        .topbar-logo svg {
            width: 17px;
            height: 17px;
            stroke-width: 1.6;
        }

        .topbar-text {
            min-width: 0;
        }

        .topbar-title {
            color: var(--app-text);
            font-size: 1rem;
            font-weight: 600;
            letter-spacing: 0;
        }

        .topbar-subtitle {
            margin-top: 1px;
            color: var(--app-muted);
            font-family: var(--font-mono);
            font-size: .65rem;
            letter-spacing: .04em;
        }

        .topbar-actions {
            display: flex;
            align-items: center;
            gap: .55rem;
            margin-left: auto;
        }

        .logout-form {
            display: flex;
            margin: 0;
        }

        .role-chip {
            color: var(--app-accent-strong);
            background: var(--app-accent-dim);
            border: 1px solid var(--app-accent-bdr);
            border-radius: 999px;
            padding: .22rem .58rem;
            font-family: var(--font-mono);
            font-size: .58rem;
            font-weight: 700;
            letter-spacing: .08em;
            text-transform: uppercase;
            box-shadow: var(--app-inset);
        }

        .live-dot {
            flex: 0 0 auto;
            width: 6px;
            height: 6px;
            border-radius: 50%;
            background: var(--app-ok);
            box-shadow: 0 0 0 0 rgba(34, 197, 94, .4);
            animation: live-pulse 2.8s ease-in-out infinite;
        }

        .live-dot.stale {
            background: var(--app-muted);
            box-shadow: none;
            animation: none;
        }

        /* In-flight poll: pulse faster so the dashboard reads as "working". */
        .live-dot.refreshing {
            animation-duration: 1s;
        }

        /* Request is taking a while (slow/unresponsive container) — go amber. */
        .live-dot.slow {
            background: var(--app-warn);
            box-shadow: 0 0 0 0 rgba(234, 179, 8, .4);
            animation: live-pulse-slow 1s ease-in-out infinite;
        }

        @keyframes live-pulse-slow {
            0%,
            100% {
                box-shadow: 0 0 0 0 rgba(234, 179, 8, .5);
            }

            50% {
                box-shadow: 0 0 0 5px rgba(234, 179, 8, 0);
            }
        }

        @keyframes live-pulse {
            0%,
            100% {
                box-shadow: 0 0 0 0 rgba(34, 197, 94, .5);
            }

            50% {
                box-shadow: 0 0 0 5px rgba(34, 197, 94, 0);
            }
        }

        .icon-button {
            display: flex;
            align-items: center;
            justify-content: center;
            flex: 0 0 auto;
            width: 34px;
            height: 34px;
            color: var(--app-soft);
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-sm);
            box-shadow: var(--app-inset);
            cursor: pointer;
            transition: background .15s, border-color .15s, color .15s, transform .1s;
        }

        .icon-button:hover {
            color: var(--app-text);
            background: var(--app-surface-hi);
            border-color: var(--app-accent-bdr);
        }

        .icon-button:active {
            transform: scale(.91);
        }

        .icon-button:focus-visible,
        .tab-button:focus-visible,
        .sidebar-nav-button:focus-visible,
        .view-choice:focus-visible,
        .sort-button:focus-visible,
        .admin-save:focus-visible,
        .btn-ghost:focus-visible,
        .action-button:focus-visible,
        .fallback-actions button:focus-visible,
        .lock-toggle input:focus-visible {
            outline: 2px solid var(--app-accent-strong);
            outline-offset: 3px;
            box-shadow: 0 0 0 4px rgba(46, 127, 255, .18), var(--app-inset);
        }

        .icon-button svg {
            width: 15px;
            height: 15px;
            stroke-width: 1.75;
        }

        .icon-button.spinning svg {
            animation: spin .6s linear infinite;
        }

        .theme-icon-light,
        :root[data-theme="light"] .theme-icon-dark {
            display: none;
        }

        :root[data-theme="light"] .theme-icon-light {
            display: block;
        }

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

        .content {
            max-width: 1180px;
            margin: 0 auto;
            padding: 1.35rem 1.1rem 3rem;
        }

        .meta-bar {
            display: flex;
            align-items: center;
            gap: .5rem;
            min-height: 30px;
            margin-bottom: 1.1rem;
        }

        .count-chip {
            color: var(--app-accent-strong);
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: 999px;
            padding: .24rem .68rem;
            font-family: var(--font-mono);
            font-size: .63rem;
            font-weight: 600;
            box-shadow: var(--app-inset);
        }

        .count-chip .chip-prefix {
            color: var(--app-muted);
        }

        .count-chip .chip-ok {
            color: var(--app-ok);
        }

        .count-chip .chip-err {
            color: var(--app-err);
        }

        .count-chip span + span::before {
            content: ' · ';
            color: var(--app-muted);
        }

        .count-chip .chip-prefix + span::before {
            content: '';
        }

        .updated-at {
            margin-left: auto;
            color: var(--app-muted);
            font-family: var(--font-mono);
            font-size: .63rem;
        }

        .list-controls {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: .75rem;
            margin-bottom: 1rem;
        }

        .server-search {
            flex: 1 1 220px;
            max-width: 320px;
            min-height: 34px;
            padding: .38rem .68rem;
            color: var(--app-text);
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-sm);
            box-shadow: var(--app-inset);
            font: inherit;
            font-size: .75rem;
        }

        .view-switch {
            display: inline-flex;
            gap: .25rem;
            padding: .25rem;
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-sm);
            box-shadow: var(--app-inset);
        }

        .view-choice {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            gap: .38rem;
            min-height: 30px;
            padding: .34rem .62rem;
            color: var(--app-soft);
            background: transparent;
            border: 0;
            border-radius: var(--app-radius-xs);
            cursor: pointer;
            font-family: var(--font-mono);
            font-size: .58rem;
            font-weight: 700;
            letter-spacing: .08em;
            text-transform: uppercase;
            transition: background .15s, color .15s, transform .1s;
        }

        .view-choice:hover,
        .view-choice.active {
            color: var(--app-text);
            background: var(--app-accent-dim);
        }

        .view-choice:active {
            transform: scale(.96);
        }

        .view-choice svg {
            width: 13px;
            height: 13px;
            fill: none;
            stroke: currentColor;
            stroke-linecap: round;
            stroke-linejoin: round;
            stroke-width: 1.75;
        }

        .row-sort-bar {
            display: flex;
            align-items: center;
            gap: .35rem;
            min-width: 0;
        }

        .row-sort-bar.visible {
            display: flex;
        }

        .sort-label {
            color: var(--app-muted);
            font-family: var(--font-mono);
            font-size: .58rem;
            font-weight: 700;
            letter-spacing: .08em;
            text-transform: uppercase;
        }

        .sort-button {
            min-height: 32px;
            padding: .35rem .62rem;
            color: var(--app-soft);
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            box-shadow: var(--app-inset);
            cursor: pointer;
            font-family: var(--font-mono);
            font-size: .58rem;
            font-weight: 700;
            letter-spacing: .08em;
            text-transform: uppercase;
            transition: background .15s, border-color .15s, color .15s;
        }

        .sort-button:hover,
        .sort-button.active {
            color: var(--app-text);
            background: var(--app-accent-dim);
            border-color: var(--app-accent-bdr);
        }

        .tab-bar {
            display: inline-flex;
            gap: .3rem;
            margin-bottom: 1rem;
            padding: .25rem;
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-sm);
            box-shadow: var(--app-inset);
        }

        .tab-button {
            min-height: 32px;
            padding: .38rem .78rem;
            color: var(--app-soft);
            background: transparent;
            border: 0;
            border-radius: var(--app-radius-xs);
            cursor: pointer;
            font-family: var(--font-mono);
            font-size: .62rem;
            font-weight: 700;
            letter-spacing: .08em;
            text-transform: uppercase;
        }

        .tab-button.active {
            color: var(--app-text);
            background: var(--app-accent-dim);
        }

        .tab-panel[hidden] {
            display: none;
        }

        .settings-tab-bar {
            margin-top: .15rem;
        }

        .settings-tab-panel[hidden] {
            display: none;
        }

        .settings-field-label {
            display: block;
            color: var(--app-soft);
            font-family: var(--font-mono);
            font-size: .6rem;
            font-weight: 700;
            letter-spacing: .08em;
            text-transform: uppercase;
            margin-bottom: .2rem;
            margin-top: .55rem;
        }

        .settings-field-label:first-child {
            margin-top: 0;
        }

        .notif-form {
            display: flex;
            flex-direction: column;
            gap: .75rem;
            max-width: 560px;
        }

        .notif-enable-card {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 1.25rem;
            padding: .9rem 1rem;
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-sm);
            box-shadow: var(--app-inset);
        }

        .notif-enable-info {
            display: flex;
            flex-direction: column;
            gap: .2rem;
            min-width: 0;
        }

        .notif-enable-label {
            color: var(--app-text);
            font-size: .85rem;
            font-weight: 600;
        }

        .notif-enable-desc {
            color: var(--app-muted);
            font-size: .72rem;
        }

        .toggle-switch {
            position: relative;
            display: inline-block;
            width: 44px;
            height: 24px;
            flex-shrink: 0;
            cursor: pointer;
        }

        .toggle-switch input {
            opacity: 0;
            width: 0;
            height: 0;
            position: absolute;
        }

        .toggle-track {
            position: absolute;
            inset: 0;
            border-radius: 12px;
            background: var(--app-surface-soft);
            border: 1px solid var(--app-border);
            transition: background .2s, border-color .2s;
        }

        .toggle-track::after {
            content: '';
            position: absolute;
            top: 3px;
            left: 3px;
            width: 16px;
            height: 16px;
            border-radius: 50%;
            background: var(--app-muted);
            transition: transform .2s, background .2s;
        }

        .toggle-switch input:checked + .toggle-track {
            background: var(--app-accent-dim);
            border-color: var(--app-accent-bdr);
        }

        .toggle-switch input:checked + .toggle-track::after {
            transform: translateX(20px);
            background: var(--app-accent);
        }

        .toggle-switch input:focus-visible + .toggle-track {
            outline: 2px solid var(--app-accent-strong);
            outline-offset: 2px;
        }

        .notif-section {
            display: flex;
            flex-direction: column;
            gap: .65rem;
            padding: .9rem 1rem;
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-sm);
            box-shadow: var(--app-inset);
        }

        .notif-section-head {
            color: var(--app-soft);
            font-family: var(--font-mono);
            font-size: .58rem;
            font-weight: 700;
            letter-spacing: .1em;
            text-transform: uppercase;
            padding-bottom: .45rem;
            border-bottom: 1px solid var(--app-border-soft);
        }

        .notif-field {
            display: flex;
            flex-direction: column;
            gap: .25rem;
        }

        .notif-field input {
            min-height: 36px;
            padding: .45rem .6rem;
            color: var(--app-text);
            background: var(--app-surface-soft);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            font: inherit;
        }

        .notif-field input:focus-visible {
            outline: 2px solid var(--app-accent-strong);
            outline-offset: 1px;
            border-color: var(--app-accent-bdr);
        }

        .notif-label {
            display: flex;
            align-items: center;
            gap: .4rem;
            color: var(--app-soft);
            font-family: var(--font-mono);
            font-size: .6rem;
            font-weight: 700;
            letter-spacing: .08em;
            text-transform: uppercase;
        }

        .notif-label-row {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: .5rem;
        }

        .notif-required {
            color: var(--app-muted);
            font-size: .55rem;
            font-weight: 600;
            letter-spacing: .06em;
            text-transform: uppercase;
        }

        .notif-token-badge {
            display: inline-flex;
            align-items: center;
            padding: .15rem .45rem;
            color: var(--app-ok);
            background: var(--app-ok-dim);
            border: 1px solid var(--app-ok-bdr);
            border-radius: var(--app-radius-xs);
            font-family: var(--font-mono);
            font-size: .55rem;
            font-weight: 700;
            letter-spacing: .07em;
            text-transform: uppercase;
        }

        .notif-token-badge[hidden] {
            display: none;
        }

        .notif-actions {
            display: flex;
            align-items: center;
            gap: .55rem;
        }

        .host-panel {
            display: grid;
            grid-template-columns: repeat(3, minmax(0, 1fr));
            gap: .85rem;
            margin-bottom: 1.05rem;
        }

        .host-panel[hidden] {
            display: none;
        }

        .host-stat {
            min-width: 0;
            padding: 1rem;
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-sm);
            box-shadow: var(--app-shadow-soft), var(--app-inset);
            backdrop-filter: blur(var(--app-blur));
            -webkit-backdrop-filter: blur(var(--app-blur));
        }

        .host-stat-label {
            margin-bottom: .35rem;
            color: var(--app-muted);
            font-family: var(--font-mono);
            font-size: .58rem;
            font-weight: 600;
            letter-spacing: .09em;
            text-transform: uppercase;
        }

        .host-stat-value {
            color: var(--app-text);
            font-size: .92rem;
            font-weight: 600;
            overflow-wrap: anywhere;
        }

        .host-stat-sub {
            margin-top: .28rem;
            color: var(--app-soft);
            font-family: var(--font-mono);
            font-size: .6rem;
            overflow-wrap: anywhere;
        }

        .host-stat-bar {
            height: 4px;
            margin-top: .58rem;
            overflow: hidden;
            background: rgba(255, 255, 255, .06);
            border: 1px solid var(--app-border);
            border-radius: 999px;
            box-shadow: var(--app-inset);
        }

        .host-stat-fill {
            display: block;
            width: 0;
            height: 100%;
            background: linear-gradient(90deg, var(--app-accent), var(--app-accent-strong));
            border-radius: inherit;
            transition: width .28s ease;
        }

        .host-stat-fill-memory {
            background: linear-gradient(90deg, #a855f7, var(--app-accent-strong));
        }

        .server-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(288px, 1fr));
            gap: .95rem;
        }

        .server-grid.row-view {
            grid-template-columns: 1fr;
            gap: .55rem;
        }

        .activity-panel {
            margin-top: 1.15rem;
            padding: 1rem 1.05rem;
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius);
            box-shadow: var(--app-shadow), var(--app-inset);
            backdrop-filter: blur(var(--app-blur));
            -webkit-backdrop-filter: blur(var(--app-blur));
        }

        .activity-panel[hidden] {
            display: none;
        }

        .admin-panel {
            padding: 1rem;
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius);
            box-shadow: var(--app-shadow), var(--app-inset);
            backdrop-filter: blur(var(--app-blur));
            -webkit-backdrop-filter: blur(var(--app-blur));
        }

        .admin-panel-head {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 1rem;
            margin-bottom: .85rem;
        }

        .admin-panel-title {
            margin: 0;
            color: var(--app-text);
            font-size: 1.05rem;
            font-weight: 700;
        }

        .admin-save {
            min-height: 34px;
            padding: .45rem .85rem;
            color: #fff;
            background: var(--app-accent);
            border: 1px solid var(--app-accent-bdr);
            border-radius: var(--app-radius-sm);
            cursor: pointer;
            font-family: var(--font-mono);
            font-size: .62rem;
            font-weight: 700;
            letter-spacing: .08em;
            text-transform: uppercase;
            box-shadow: var(--app-inset);
        }

        .admin-save:hover:not(:disabled) {
            color: #fff;
            background: var(--app-accent-strong);
        }

        .admin-save:disabled {
            cursor: not-allowed;
            opacity: .45;
        }

        .btn-ghost {
            min-height: 34px;
            padding: .45rem .85rem;
            color: var(--app-soft);
            background: transparent;
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-sm);
            cursor: pointer;
            font-family: var(--font-mono);
            font-size: .62rem;
            font-weight: 700;
            letter-spacing: .08em;
            text-transform: uppercase;
            box-shadow: var(--app-inset);
            transition: background .15s, border-color .15s, color .15s;
        }

        .btn-ghost:hover:not(:disabled) {
            color: var(--app-text);
            background: var(--app-surface-hi);
            border-color: var(--app-accent-bdr);
        }

        .btn-ghost:disabled {
            cursor: not-allowed;
            opacity: .45;
        }

        .admin-list {
            display: grid;
            gap: .55rem;
        }

        .access-row {
            display: grid;
            grid-template-columns: minmax(0, 1fr) auto;
            gap: .75rem;
            align-items: center;
            padding: .75rem;
            background: var(--app-surface-soft);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-sm);
            box-shadow: var(--app-inset);
        }

        .access-row > span:first-child {
            display: flex;
            flex-direction: column;
            gap: .18rem;
            min-width: 0;
        }

        .access-name {
            display: block;
            color: var(--app-text);
            font-size: .82rem;
            font-weight: 600;
            overflow-wrap: anywhere;
        }

        .access-meta {
            display: block;
            color: var(--app-muted);
            font-family: var(--font-mono);
            font-size: .58rem;
            overflow-wrap: anywhere;
        }

        .lock-toggle {
            display: inline-flex;
            align-items: center;
            gap: .45rem;
            color: var(--app-soft);
            font-family: var(--font-mono);
            font-size: .6rem;
            font-weight: 700;
            letter-spacing: .08em;
            text-transform: uppercase;
            cursor: pointer;
        }

        .lock-toggle input {
            width: 1rem;
            height: 1rem;
            accent-color: var(--app-err);
        }

        /* Access user-assignment matrix */
        .access-user-row {
            display: flex;
            flex-direction: column;
            gap: .5rem;
            padding: .75rem;
            background: var(--app-surface-soft);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-sm);
            box-shadow: var(--app-inset);
        }

        .access-user-identity {
            display: flex;
            align-items: center;
            gap: .5rem;
        }

        .access-user-chips {
            display: flex;
            flex-wrap: wrap;
            gap: .35rem;
            align-items: center;
        }

        .access-unrestricted {
            font-family: var(--font-mono);
            font-size: .62rem;
            color: var(--app-muted);
            font-style: italic;
            padding: .1rem .2rem;
        }

        /* Account page */
        .account-gate {
            display: flex;
            justify-content: center;
            padding: 1.5rem 1rem 1rem;
            margin-bottom: .75rem;
        }

        .account-gate-inner {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: .75rem;
            max-width: 340px;
            width: 100%;
            text-align: center;
        }

        .account-gate-icon {
            width: 2.2rem;
            height: 2.2rem;
            color: var(--app-muted);
            fill: none;
            stroke: currentColor;
            stroke-width: 1.6;
            stroke-linecap: round;
            stroke-linejoin: round;
        }

        .account-gate-text {
            margin: 0;
            color: var(--app-muted);
            font-size: .8rem;
        }

        .account-gate-form {
            display: flex;
            gap: .5rem;
            width: 100%;
        }

        .account-gate-form input {
            flex: 1;
            min-height: 36px;
            padding: .45rem .6rem;
            color: var(--app-text);
            background: var(--app-surface-soft);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            font: inherit;
        }

        .account-gate-form input:focus-visible {
            outline: 2px solid var(--app-accent-strong);
            outline-offset: 1px;
            border-color: var(--app-accent-bdr);
        }

        .account-unlock-bar {
            display: flex;
            align-items: center;
            justify-content: space-between;
            flex-wrap: wrap;
            gap: .5rem;
            padding: .55rem .85rem;
            margin-bottom: .85rem;
            background: var(--app-ok-dim);
            border: 1px solid var(--app-ok-bdr);
            border-radius: var(--app-radius-xs);
        }

        .account-unlock-label {
            color: var(--app-ok);
            font-family: var(--font-mono);
            font-size: .6rem;
            font-weight: 700;
            letter-spacing: .08em;
            text-transform: uppercase;
        }

        .account-unlock-meta {
            color: var(--app-muted);
            font-size: .72rem;
        }

        .account-sections {
            display: grid;
            gap: .85rem;
        }

        .account-sections-locked {
            opacity: .45;
            pointer-events: none;
            user-select: none;
        }

        .account-section {
            padding: .85rem;
            background: var(--app-surface-soft);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-sm);
            box-shadow: var(--app-inset);
        }

        .account-section-head {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 1rem;
            margin-bottom: .7rem;
        }

        .account-section-title {
            margin: 0;
            color: var(--app-text);
            font-size: .88rem;
            font-weight: 700;
        }

        /* Profile section */
        .account-profile-form {
            display: flex;
            flex-direction: column;
            gap: .75rem;
        }

        .account-avatar-wrap {
            display: flex;
            align-items: center;
            gap: .7rem;
            flex-wrap: wrap;
        }

        .account-avatar {
            width: 52px;
            height: 52px;
            border-radius: 50%;
            object-fit: cover;
            border: 2px solid var(--app-border);
            flex: 0 0 auto;
        }

        .account-avatar-placeholder {
            display: flex;
            align-items: center;
            justify-content: center;
            width: 52px;
            height: 52px;
            border-radius: 50%;
            background: var(--app-surface-hi);
            border: 2px solid var(--app-border);
            flex: 0 0 auto;
        }

        .account-avatar-placeholder svg {
            width: 26px;
            height: 26px;
            color: var(--app-muted);
            fill: none;
            stroke: currentColor;
            stroke-width: 1.6;
            stroke-linecap: round;
            stroke-linejoin: round;
        }

        .account-avatar-file {
            position: absolute;
            width: 1px;
            height: 1px;
            opacity: 0;
            pointer-events: none;
        }

        .account-form-fields {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
            gap: .5rem;
        }

        .account-form-label {
            display: flex;
            flex-direction: column;
            gap: .32rem;
            color: var(--app-muted);
            font-family: var(--font-mono);
            font-size: .6rem;
            font-weight: 700;
            letter-spacing: .08em;
            text-transform: uppercase;
        }

        .account-form-label input {
            min-height: 36px;
            padding: .45rem .6rem;
            color: var(--app-text);
            background: var(--app-surface-soft);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            font: inherit;
            font-size: 1rem;
            letter-spacing: 0;
            text-transform: none;
        }

        .account-form-label input:focus-visible {
            outline: 2px solid var(--app-accent-strong);
            outline-offset: 1px;
            border-color: var(--app-accent-bdr);
        }

        .account-form-actions {
            display: flex;
            justify-content: flex-end;
        }

        /* Credentials section */
        .account-credentials-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
            gap: .75rem;
        }

        .account-cred-form {
            display: flex;
            flex-direction: column;
            gap: .5rem;
        }

        .account-cred-form input {
            min-height: 36px;
            padding: .45rem .6rem;
            color: var(--app-text);
            background: var(--app-surface-soft);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            font: inherit;
        }

        .account-cred-form input:focus-visible {
            outline: 2px solid var(--app-accent-strong);
            outline-offset: 1px;
            border-color: var(--app-accent-bdr);
        }

        /* Two-factor authentication section */
        .account-security-status {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            min-height: 24px;
            padding: .22rem .55rem;
            color: var(--app-soft);
            background: var(--app-slate-dim);
            border: 1px solid var(--app-slate-bdr);
            border-radius: 999px;
            font-family: var(--font-mono);
            font-size: .58rem;
            font-weight: 700;
            letter-spacing: .08em;
            text-transform: uppercase;
            white-space: nowrap;
        }

        .account-security-status.is-enabled {
            color: var(--app-ok);
            background: var(--app-ok-dim);
            border-color: var(--app-ok-bdr);
        }

        .account-2fa-desc {
            margin: 0 0 .85rem;
            color: var(--app-muted);
            font-size: .78rem;
            line-height: 1.5;
        }

        .account-2fa-rows {
            display: grid;
            gap: 0;
        }

        .account-2fa-row {
            display: flex;
            align-items: flex-end;
            gap: .65rem;
            flex-wrap: wrap;
        }

        .account-2fa-row .account-code-field {
            flex: 0 1 180px;
        }

        .account-2fa-row .admin-save,
        .account-2fa-row .btn-ghost {
            flex: 0 0 auto;
        }

        .account-2fa-sep {
            margin: .75rem 0;
            border: none;
            border-top: 1px solid var(--app-border-soft);
        }

        .account-2fa-row-danger .btn-ghost {
            color: var(--app-err);
            border-color: var(--app-err-bdr);
        }

        .account-code-field {
            gap: .38rem;
        }

        .account-code-field input {
            width: 100%;
            font-family: var(--font-mono);
            letter-spacing: .2em;
            text-align: center;
        }

        /* Recent activity section */
        .account-activity-list {
            list-style: none;
            margin: 0;
            padding: 0;
            display: grid;
            gap: .4rem;
        }

        .account-activity-item {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: .75rem;
            padding: .5rem .65rem;
            border: 1px solid var(--app-border-soft);
            border-radius: var(--app-radius-xs);
            font-size: .78rem;
        }

        .account-activity-main {
            color: var(--app-soft);
            display: flex;
            align-items: center;
            gap: .4rem;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        .account-activity-meta {
            color: var(--app-muted);
            font-family: var(--font-mono);
            font-size: .58rem;
            flex: 0 0 auto;
        }

        /* Danger zone */
        .account-danger-zone {
            border-color: var(--app-err-bdr);
            background: var(--app-err-dim);
        }

        .account-danger-row {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 1rem;
            flex-wrap: wrap;
        }

        .account-danger-label {
            display: block;
            color: var(--app-err);
            font-size: .82rem;
            font-weight: 600;
            margin-bottom: .2rem;
        }

        .account-danger-meta {
            color: var(--app-muted);
            font-size: .72rem;
        }

        .account-delete-armed {
            color: #fff !important;
            background: var(--app-err) !important;
            border-color: var(--app-err-bdr) !important;
        }

        .secondary-head {
            margin-top: 1rem;
            padding-top: 1rem;
            border-top: 1px solid var(--app-border);
        }

        .tool-form {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
            gap: .55rem;
            margin-bottom: .85rem;
        }

        .tool-form input,
        .tool-form select,
        .schedule-row input,
        .schedule-row select,
        .user-row input,
        .user-row select {
            min-height: 36px;
            padding: .45rem .6rem;
            color: var(--app-text);
            background: var(--app-surface-soft);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            font: inherit;
        }

        .tool-form input:focus-visible,
        .tool-form select:focus-visible,
        .server-search:focus-visible,
        .user-row input:focus-visible,
        .user-row select:focus-visible,
        .schedule-row input:focus-visible,
        .schedule-row select:focus-visible {
            outline: 2px solid var(--app-accent-strong);
            outline-offset: 1px;
            border-color: var(--app-accent-bdr);
        }

        .pw-wrap {
            position: relative;
            display: flex;
            align-items: stretch;
        }

        .pw-wrap input {
            flex: 1;
            min-width: 0;
            padding-right: 2.3rem;
        }

        .account-gate-form .pw-wrap {
            flex: 1;
        }

        .pw-toggle {
            position: absolute;
            right: 0;
            top: 0;
            bottom: 0;
            display: flex;
            align-items: center;
            justify-content: center;
            width: 2.2rem;
            padding: 0;
            background: none;
            border: none;
            cursor: pointer;
            color: var(--app-muted);
            transition: color .15s;
        }

        .pw-toggle:hover {
            color: var(--app-text);
        }

        .pw-toggle:focus-visible {
            outline: 2px solid var(--app-accent-strong);
            outline-offset: -2px;
            border-radius: var(--app-radius-xs);
        }

        .pw-toggle svg {
            width: 15px;
            height: 15px;
            fill: none;
            stroke: currentColor;
            stroke-width: 1.75;
            stroke-linecap: round;
            stroke-linejoin: round;
            pointer-events: none;
        }

        .pw-eye-slash {
            display: none;
        }

        .pw-toggle[aria-pressed="true"] .pw-eye-slash {
            display: block;
        }

        .table-wrap {
            overflow: auto;
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-sm);
        }

        .data-table {
            width: 100%;
            border-collapse: collapse;
            color: var(--app-soft);
            font-size: .74rem;
        }

        .data-table th,
        .data-table td {
            padding: .55rem .65rem;
            border-bottom: 1px solid var(--app-border-soft);
            text-align: left;
            vertical-align: top;
            overflow-wrap: anywhere;
        }

        .data-table th {
            color: var(--app-muted);
            font-family: var(--font-mono);
            font-size: .56rem;
            letter-spacing: .08em;
            text-transform: uppercase;
        }

        .pager {
            display: flex;
            align-items: center;
            justify-content: flex-end;
            gap: .6rem;
            margin-top: .75rem;
            color: var(--app-muted);
            font-family: var(--font-mono);
            font-size: .62rem;
        }

        .user-row,
        .schedule-row {
            display: grid;
            grid-template-columns: minmax(0, 1fr) auto;
            gap: .7rem;
            align-items: center;
            padding: .75rem;
            background: var(--app-surface-soft);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-sm);
            box-shadow: var(--app-inset);
        }

        .row-actions,
        .day-picks {
            display: flex;
            flex-wrap: wrap;
            gap: .35rem;
            align-items: center;
        }

        .day-picks label,
        .bulk-select {
            color: var(--app-muted);
            font-family: var(--font-mono);
            font-size: .56rem;
            letter-spacing: .08em;
            text-transform: uppercase;
        }

        .port-pills {
            display: flex;
            flex-wrap: wrap;
            gap: .28rem;
        }

        .port-pill {
            padding: .12rem .42rem;
            color: var(--app-accent-strong);
            background: var(--app-accent-dim);
            border: 1px solid var(--app-accent-bdr);
            border-radius: 999px;
            font-family: var(--font-mono);
            font-size: .58rem;
        }

        .modal-backdrop {
            position: fixed;
            inset: 0;
            z-index: 250;
            display: grid;
            place-items: center;
            padding: 1rem;
            background: rgba(0, 0, 0, .58);
            backdrop-filter: blur(8px);
        }

        .modal-backdrop[hidden] {
            display: none;
        }

        .modal {
            width: min(980px, 100%);
            max-height: min(760px, calc(100svh - 2rem));
            display: grid;
            grid-template-rows: auto minmax(220px, 1fr);
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius);
            box-shadow: var(--app-shadow), var(--app-inset);
        }

        .modal-head {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 1rem;
            padding: .9rem 1rem;
            border-bottom: 1px solid var(--app-border);
        }

        .modal-head h2 {
            margin: 0;
            min-width: 0;
            font-size: .92rem;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        .modal-actions {
            display: flex;
            gap: .45rem;
            align-items: center;
        }

        .logs-pre {
            margin: 0;
            padding: 1rem;
            overflow: auto;
            color: var(--app-soft);
            font-family: var(--font-mono);
            font-size: .72rem;
            line-height: 1.45;
            white-space: pre-wrap;
        }

        .log-line.stderr {
            color: var(--app-err);
        }

        .ansi-bold {
            font-weight: 700;
        }

        .ansi-fg-black { color: #64748b; }
        .ansi-fg-red { color: var(--app-err); }
        .ansi-fg-green { color: var(--app-ok); }
        .ansi-fg-yellow { color: var(--app-warn); }
        .ansi-fg-blue { color: var(--app-accent-strong); }
        .ansi-fg-magenta { color: #d946ef; }
        .ansi-fg-cyan { color: #06b6d4; }
        .ansi-fg-white { color: var(--app-text); }
        .ansi-bg-black { background: rgba(15, 23, 42, .55); }
        .ansi-bg-red { background: var(--app-err-dim); }
        .ansi-bg-green { background: var(--app-ok-dim); }
        .ansi-bg-yellow { background: var(--app-warn-dim); }
        .ansi-bg-blue { background: var(--app-accent-dim); }
        .ansi-bg-magenta { background: rgba(217, 70, 239, .14); }
        .ansi-bg-cyan { background: rgba(6, 182, 212, .14); }
        .ansi-bg-white { background: rgba(238, 242, 255, .12); }

        .scroll-bottom-button {
            position: absolute;
            right: 1.1rem;
            bottom: 1.1rem;
            width: auto;
        }

        .modal {
            position: relative;
        }

        .settings-tab-panel[data-settings-tab="access"] > .secondary-head {
            display: none;
        }

        .bulk-bar {
            position: fixed;
            left: 50%;
            bottom: calc(1rem + env(safe-area-inset-bottom));
            z-index: 220;
            display: flex;
            align-items: center;
            gap: .5rem;
            padding: .55rem;
            color: var(--app-soft);
            background: var(--app-surface-hi);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius);
            box-shadow: var(--app-shadow), var(--app-inset);
            transform: translateX(-50%);
        }

        .bulk-bar[hidden] {
            display: none;
        }

        .bulk-confirm-text {
            color: var(--app-warn);
            font-family: var(--font-mono);
            font-size: .68rem;
            font-weight: 700;
        }

        .toast.session-warning {
            align-items: center;
        }

        .toast-action {
            flex: 0 0 auto;
            min-height: 30px;
            width: auto;
            margin-left: auto;
            padding: .25rem .55rem;
        }

        .activity-title {
            margin: 0 0 .7rem;
            color: var(--app-text);
            font-size: .8rem;
            font-weight: 600;
            letter-spacing: 0;
        }

        .activity-list {
            display: flex;
            flex-direction: column;
            gap: .48rem;
            margin: 0;
            padding: 0;
            list-style: none;
        }

        .activity-item {
            display: grid;
            grid-template-columns: minmax(0, 1fr) auto;
            gap: .5rem;
            align-items: baseline;
            min-width: 0;
            color: var(--app-soft);
            font-size: .78rem;
        }

        .activity-main {
            min-width: 0;
            overflow-wrap: anywhere;
        }

        .activity-result {
            display: inline-flex;
            align-items: center;
            gap: .22rem;
        }

        .activity-result svg {
            width: .72rem;
            height: .72rem;
            flex: 0 0 auto;
            fill: none;
            stroke: currentColor;
            stroke-linecap: round;
            stroke-linejoin: round;
            stroke-width: 2.2;
        }

        .activity-meta {
            color: var(--app-muted);
            font-family: var(--font-mono);
            font-size: .58rem;
            white-space: nowrap;
        }

        .activity-result-success {
            color: var(--app-ok);
        }

        .activity-result-error {
            color: var(--app-err);
        }

        .server-card {
            position: relative;
            display: flex;
            flex-direction: column;
            overflow: hidden;
            min-height: 206px;
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius);
            box-shadow: var(--app-shadow), var(--app-inset);
            backdrop-filter: blur(var(--app-blur));
            -webkit-backdrop-filter: blur(var(--app-blur));
            animation: card-in .32s ease both;
            transition: border-color .2s, box-shadow .2s, transform .2s;
        }

        .server-card:hover {
            border-color: var(--app-accent-bdr);
            box-shadow: 0 14px 44px rgba(4, 8, 20, .58), var(--app-inset);
            transform: translateY(-1px);
        }

        .server-card.state-running {
            border-left: 2px solid var(--app-ok-bdr);
            box-shadow: var(--app-shadow), var(--app-inset), 0 0 28px rgba(34, 197, 94, .07);
        }

        .server-card.state-exited,
        .server-card.state-created {
            border-left: 2px solid var(--app-slate-bdr);
        }

        .server-card.state-dead {
            border-left: 2px solid var(--app-err-bdr);
        }

        .server-card.state-paused,
        .server-card.state-restarting {
            border-left: 2px solid var(--app-warn-bdr);
        }

        .server-card.locked {
            border-color: var(--app-err-bdr);
            border-left: 2px solid var(--app-err);
            background: linear-gradient(135deg, var(--app-err-dim), var(--app-surface) 42%);
        }

        .server-card.locked:hover {
            border-color: var(--app-err-bdr);
        }

        .server-grid.row-view .server-card {
            display: grid;
            grid-template-columns: minmax(0, 1fr) auto;
            min-height: 0;
            border-radius: var(--app-radius-sm);
        }

        .server-grid.row-view .server-card:hover {
            transform: none;
        }

        .server-grid.row-view .card-body {
            display: grid;
            grid-template-columns: minmax(170px, 1fr) minmax(180px, .9fr) minmax(260px, 1.25fr);
            align-items: center;
            gap: .75rem;
            min-width: 0;
            padding: .72rem .85rem;
        }

        .server-grid.row-view .card-top {
            display: grid;
            grid-template-columns: minmax(0, 1fr) auto;
            align-items: center;
            gap: .55rem;
            min-width: 0;
        }

        .server-grid.row-view .server-name {
            font-size: .88rem;
            line-height: 1.2;
        }

        .server-grid.row-view .friendly-state {
            margin-top: .2rem;
            font-size: 1.05rem;
        }

        .server-grid.row-view .friendly-readiness {
            margin-top: .18rem;
            font-size: .68rem;
        }

        .server-grid.row-view .lock-badge {
            margin-top: .26rem;
        }

        .server-grid.row-view .card-meta {
            gap: .28rem;
            min-width: 0;
        }

        .server-grid.row-view .meta-row {
            gap: .42rem;
        }

        .server-grid.row-view .meta-key {
            flex-basis: 76px;
            font-size: .52rem;
        }

        .server-grid.row-view .meta-value {
            font-size: .7rem;
        }

        .server-grid.row-view .detail-row,
        .server-grid.row-view .docker-name-row,
        .server-grid.row-view .image-row {
            display: none;
        }

        .server-grid.row-view .stats-grid {
            grid-template-columns: repeat(3, minmax(0, 1fr));
            gap: .36rem;
            min-width: 0;
        }

        .server-grid.row-view .stat-cell {
            padding: .42rem;
            border-radius: var(--app-radius-xs);
        }

        .server-grid.row-view .stat-label {
            margin-bottom: .12rem;
            font-size: .48rem;
        }

        .server-grid.row-view .metric-sparkline-wrap {
            min-height: 36px;
        }

        .server-grid.row-view .metric-sparkline {
            height: 22px;
        }

        .server-grid.row-view .stat-value {
            font-size: .53rem;
            line-height: 1.25;
        }

        .server-grid.row-view .card-actions {
            display: flex;
            min-width: 174px;
            border-top: 0;
            border-left: 1px solid var(--app-border);
        }

        .server-grid.row-view .action-button {
            min-width: 58px;
            min-height: 100%;
            padding: .5rem .34rem;
        }

        @keyframes card-in {
            from {
                opacity: 0;
                transform: translateY(10px) scale(.985);
            }

            to {
                opacity: 1;
                transform: none;
            }
        }

        .server-card.flash::after {
            content: "";
            position: absolute;
            inset: 0;
            pointer-events: none;
            border-radius: inherit;
            animation: state-flash .55s ease forwards;
        }

        @keyframes state-flash {
            from {
                background: rgba(46, 127, 255, .16);
            }

            to {
                background: transparent;
            }
        }

        .card-overlay {
            position: absolute;
            inset: 0;
            z-index: 10;
            display: flex;
            align-items: center;
            justify-content: center;
            pointer-events: none;
            opacity: 0;
            background: rgba(8, 12, 16, .62);
            border-radius: inherit;
            backdrop-filter: blur(6px);
            -webkit-backdrop-filter: blur(6px);
            transition: opacity .18s;
        }

        .card-overlay.on {
            pointer-events: all;
            opacity: 1;
        }

        .card-spinner {
            width: 26px;
            height: 26px;
            border: 2px solid rgba(255, 255, 255, .08);
            border-top-color: var(--app-accent);
            border-radius: 50%;
            animation: spin .65s linear infinite;
        }

        .card-body {
            display: flex;
            flex: 1;
            flex-direction: column;
            gap: .85rem;
            padding: 1.12rem 1.12rem .95rem;
        }

        .card-top {
            display: flex;
            align-items: flex-start;
            justify-content: space-between;
            gap: .5rem;
        }

        .server-name {
            margin: 0;
            color: var(--app-text);
            font-size: .97rem;
            font-weight: 600;
            line-height: 1.3;
            letter-spacing: 0;
            overflow-wrap: anywhere;
        }

        .friendly-state {
            margin-top: .35rem;
            color: var(--app-text);
            font-size: 1.38rem;
            font-weight: 700;
            line-height: 1.08;
            letter-spacing: 0;
        }

        .friendly-readiness {
            margin-top: .22rem;
            color: var(--app-soft);
            font-size: .8rem;
            line-height: 1.35;
            overflow-wrap: anywhere;
        }

        .state-badge {
            display: inline-flex;
            align-items: center;
            flex: 0 0 auto;
            gap: .28rem;
            padding: .2rem .52rem;
            border: 1px solid;
            border-radius: 999px;
            font-family: var(--font-mono);
            font-size: .58rem;
            font-weight: 600;
            letter-spacing: .09em;
            text-transform: uppercase;
            white-space: nowrap;
            box-shadow: var(--app-inset);
            transition: background .35s, color .35s, border-color .35s;
        }

        .state-badge.running {
            color: var(--app-ok);
            background: var(--app-ok-dim);
            border-color: var(--app-ok-bdr);
        }

        .state-badge.exited {
            color: var(--app-slate);
            background: var(--app-slate-dim);
            border-color: var(--app-slate-bdr);
        }

        .state-badge.created,
        .state-badge.paused {
            color: var(--app-warn);
            background: var(--app-warn-dim);
            border-color: var(--app-warn-bdr);
        }

        .state-badge.dead {
            color: var(--app-err);
            background: var(--app-err-dim);
            border-color: var(--app-err-bdr);
        }

        .state-badge.restarting {
            color: var(--app-accent);
            background: var(--app-accent-dim);
            border-color: var(--app-accent-bdr);
        }

        .lock-badge {
            display: inline-flex;
            align-items: center;
            flex: 0 0 auto;
            gap: .25rem;
            margin-top: .35rem;
            color: var(--app-err);
            background: var(--app-err-dim);
            border: 1px solid var(--app-err-bdr);
            border-radius: 999px;
            padding: .18rem .48rem;
            font-family: var(--font-mono);
            font-size: .55rem;
            font-weight: 700;
            letter-spacing: .08em;
            text-transform: uppercase;
            box-shadow: var(--app-inset);
        }

        .lock-badge svg {
            width: 11px;
            height: 11px;
            fill: none;
            stroke: currentColor;
            stroke-linecap: round;
            stroke-linejoin: round;
            stroke-width: 1.8;
        }

        .badge-dot {
            width: 5px;
            height: 5px;
            border-radius: 50%;
            background: currentColor;
        }

        .state-badge.running .badge-dot {
            animation: live-pulse 2.2s ease-in-out infinite;
        }

        .card-meta {
            display: flex;
            flex-direction: column;
            gap: .38rem;
        }

        .meta-row {
            display: flex;
            align-items: baseline;
            gap: .55rem;
            min-width: 0;
        }

        .meta-key {
            flex: 0 0 84px;
            color: var(--app-muted);
            font-family: var(--font-mono);
            font-size: .59rem;
            font-weight: 500;
            letter-spacing: .09em;
            text-transform: uppercase;
        }

        .meta-value {
            min-width: 0;
            color: var(--app-soft);
            font-size: .79rem;
            line-height: 1.3;
            overflow-wrap: anywhere;
        }

        .meta-value.ok {
            color: var(--app-ok);
        }

        .meta-value.warn {
            color: var(--app-warn);
        }

        .stats-grid {
            display: grid;
            grid-template-columns: repeat(3, minmax(0, 1fr));
            gap: .42rem;
        }

        .stat-cell {
            min-width: 0;
            padding: .5rem;
            background: var(--app-surface-soft);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-sm);
            box-shadow: var(--app-inset);
        }

        .stat-label {
            margin-bottom: .22rem;
            color: var(--app-muted);
            font-family: var(--font-mono);
            font-size: .52rem;
            font-weight: 600;
            letter-spacing: .08em;
            text-transform: uppercase;
        }

        .stat-value {
            color: var(--app-soft);
            font-family: var(--font-mono);
            font-size: .58rem;
            line-height: 1.35;
            overflow-wrap: anywhere;
        }

        .metric-sparkline-wrap {
            display: grid;
            gap: .2rem;
            min-height: 42px;
        }

        .metric-sparkline {
            display: block;
            width: 100%;
            height: 28px;
            overflow: visible;
        }

        .metric-sparkline-line {
            fill: none;
            stroke-linecap: round;
            stroke-linejoin: round;
            stroke-width: 2.5;
        }

        .metric-sparkline-line-cpu {
            stroke: var(--app-accent);
            filter: drop-shadow(0 0 5px rgba(46, 127, 255, .22));
        }

        .metric-sparkline-line-memory {
            stroke: #a855f7;
            filter: drop-shadow(0 0 5px rgba(168, 85, 247, .22));
        }

        .metric-sparkline-line-network {
            stroke: #06b6d4;
            filter: drop-shadow(0 0 5px rgba(6, 182, 212, .22));
        }

        .metric-sparkline-empty {
            fill: none;
            stroke: var(--app-border);
            stroke-dasharray: 3 5;
            stroke-linecap: round;
            stroke-width: 1.4;
        }

        .stat-metric {
            min-height: 1.58rem;
        }

        .card-actions {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
            border-top: 1px solid var(--app-border);
            background: rgba(255, 255, 255, .018);
        }

        .action-button {
            position: relative;
            display: flex;
            align-items: center;
            justify-content: center;
            flex-direction: column;
            gap: .28rem;
            min-height: 60px;
            padding: .65rem .4rem;
            overflow: hidden;
            color: var(--app-soft);
            background: transparent;
            border: 0;
            border-right: 1px solid var(--app-border);
            cursor: pointer;
            touch-action: manipulation;
            -webkit-user-select: none;
            user-select: none;
            transition: background .14s, color .14s, transform .07s, opacity .14s;
        }

        .action-button:last-child {
            border-right: 0;
        }

        .action-button:hover:not(:disabled) {
            color: var(--app-text);
            background: var(--app-surface-hi);
        }

        .btn-start:hover:not(:disabled) {
            box-shadow: inset 0 2px 0 var(--app-ok);
        }

        .btn-stop:hover:not(:disabled) {
            box-shadow: inset 0 2px 0 var(--app-err);
        }

        .btn-restart:hover:not(:disabled) {
            box-shadow: inset 0 2px 0 var(--app-warn);
        }

        .action-button:active:not(:disabled) {
            transform: scale(.94);
        }

        .action-button:disabled {
            cursor: not-allowed;
            opacity: .25;
        }

        .action-icon {
            display: flex;
            align-items: center;
            justify-content: center;
            flex: 0 0 auto;
            width: 30px;
            height: 30px;
            border-radius: 50%;
            box-shadow: var(--app-inset);
            transition: background .14s, transform .14s;
        }

        .action-button:hover:not(:disabled) .action-icon {
            transform: scale(1.1);
        }

        .action-svg {
            width: 14px;
            height: 14px;
            stroke-width: 1.8;
        }

        .btn-start .action-icon {
            color: var(--app-ok);
            background: var(--app-ok-dim);
        }

        .btn-start .action-svg,
        .btn-stop .action-svg {
            fill: currentColor;
            stroke: none;
        }

        .btn-stop .action-icon {
            color: var(--app-err);
            background: var(--app-err-dim);
        }

        .btn-restart .action-icon {
            color: var(--app-warn);
            background: var(--app-warn-dim);
        }

        .btn-logs .action-icon {
            color: var(--app-accent-strong);
            background: var(--app-accent-dim);
        }

        .action-label {
            font-family: var(--font-mono);
            font-size: .58rem;
            font-weight: 600;
            letter-spacing: .08em;
            text-transform: uppercase;
        }

        .btn-start .action-label {
            color: var(--app-ok);
        }

        .btn-stop .action-label {
            color: var(--app-err);
        }

        .btn-restart .action-label {
            color: var(--app-warn);
        }

        .btn-logs .action-label {
            color: var(--app-accent-strong);
        }

        .action-button.armed .action-icon {
            color: var(--app-text);
            background: rgba(255, 255, 255, .12);
            animation: arm-bounce .22s ease;
        }

        .action-button.armed .action-label {
            color: var(--app-text);
        }

        @keyframes arm-bounce {
            0% {
                transform: scale(1);
            }

            45% {
                transform: scale(.88);
            }

            100% {
                transform: scale(1);
            }
        }

        .skeleton {
            height: 206px;
            background: linear-gradient(90deg, var(--app-surface) 25%, rgba(255, 255, 255, .09) 50%, var(--app-surface) 75%);
            background-size: 200% 100%;
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius);
            box-shadow: var(--app-shadow), var(--app-inset);
            backdrop-filter: blur(var(--app-blur));
            -webkit-backdrop-filter: blur(var(--app-blur));
            animation: skeleton-move 1.5s ease-in-out infinite;
        }

        @keyframes skeleton-move {
            from {
                background-position: 200% 0;
            }

            to {
                background-position: -200% 0;
            }
        }

        .empty-card {
            grid-column: 1 / -1;
            padding: 3rem 1.5rem;
            color: var(--app-soft);
            background: var(--app-surface);
            border: 1px dashed var(--app-border);
            border-radius: var(--app-radius);
            box-shadow: var(--app-shadow-soft), var(--app-inset);
            font-size: .85rem;
            text-align: center;
        }

        .toast-shelf {
            position: fixed;
            bottom: calc(1.1rem + env(safe-area-inset-bottom));
            left: 50%;
            z-index: 300;
            display: flex;
            flex-direction: column-reverse;
            gap: .45rem;
            width: min(calc(100vw - 2rem), 360px);
            pointer-events: none;
            transform: translateX(-50%);
        }

        .toast {
            position: relative;
            display: flex;
            align-items: center;
            gap: .65rem;
            overflow: hidden;
            padding: .72rem .95rem;
            color: var(--app-text);
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius);
            box-shadow: var(--app-shadow), var(--app-inset);
            font-size: .82rem;
            pointer-events: all;
            backdrop-filter: blur(var(--app-blur));
            -webkit-backdrop-filter: blur(var(--app-blur));
            animation: toast-in .25s cubic-bezier(.34, 1.56, .64, 1) both;
        }

        .toast.out {
            animation: toast-out .18s ease forwards;
        }

        @keyframes toast-in {
            from {
                opacity: 0;
                transform: translateY(14px) scale(.94);
            }

            to {
                opacity: 1;
                transform: none;
            }
        }

        @keyframes toast-out {
            to {
                opacity: 0;
                transform: translateY(6px) scale(.97);
            }
        }

        .toast-bar {
            position: absolute;
            top: 0;
            bottom: 0;
            left: 0;
            width: 3px;
        }

        .toast.ok .toast-bar {
            background: var(--app-ok);
        }

        .toast.err .toast-bar {
            background: var(--app-err);
        }

        .toast.info .toast-bar {
            background: var(--app-accent);
        }

        .toast-icon {
            flex: 0 0 auto;
            width: 16px;
            height: 16px;
            stroke-width: 1.9;
        }

        .toast.ok .toast-icon {
            color: var(--app-ok);
        }

        .toast.err .toast-icon {
            color: var(--app-err);
        }

        .toast.info .toast-icon {
            color: var(--app-accent);
        }

        .fallback-message,
        .fallback-card,
        .fallback-activity {
            margin: 1rem 1.1rem;
            padding: 1rem;
            color: var(--app-text);
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius);
            box-shadow: var(--app-shadow-soft), var(--app-inset);
            backdrop-filter: blur(var(--app-blur));
            -webkit-backdrop-filter: blur(var(--app-blur));
        }

        .fallback-card.locked {
            border-color: var(--app-err-bdr);
            background: linear-gradient(135deg, var(--app-err-dim), var(--app-surface) 46%);
        }

        .fallback-message.success {
            color: var(--app-ok);
            background: var(--app-ok-dim);
            border-color: var(--app-ok-bdr);
        }

        .fallback-message.error {
            color: var(--app-err);
            background: var(--app-err-dim);
            border-color: var(--app-err-bdr);
        }

        .fallback-card-head {
            display: flex;
            align-items: flex-start;
            justify-content: space-between;
            gap: .75rem;
            margin-bottom: .65rem;
        }

        .fallback-status {
            margin-bottom: 1rem;
            color: var(--app-soft);
            font-size: .78rem;
        }

        .fallback-actions {
            display: flex;
            flex-wrap: wrap;
            gap: .4rem;
        }

        .fallback-actions form {
            display: contents;
        }

        .fallback-actions button {
            padding: .45rem .9rem;
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-sm);
            cursor: pointer;
            font-family: var(--font-mono);
            font-size: .65rem;
            letter-spacing: .06em;
            text-transform: uppercase;
            box-shadow: var(--app-inset);
        }

        * {
            scrollbar-width: thin;
            scrollbar-color: rgba(46, 127, 255, .30) rgba(8, 12, 16, .55);
        }

        *::-webkit-scrollbar {
            width: 8px;
            height: 8px;
        }

        *::-webkit-scrollbar-track {
            background: rgba(8, 12, 16, .55);
        }

        *::-webkit-scrollbar-thumb {
            background: rgba(46, 127, 255, .30);
            border: 2px solid rgba(8, 12, 16, .55);
            border-radius: 999px;
        }

        :root[data-theme="light"] * {
            scrollbar-color: rgba(46, 80, 200, .28) rgba(238, 242, 255, .88);
        }

        :root[data-theme="light"] *::-webkit-scrollbar-track {
            background: rgba(238, 242, 255, .88);
        }

        :root[data-theme="light"] *::-webkit-scrollbar-thumb {
            background: rgba(46, 80, 200, .28);
            border-color: rgba(238, 242, 255, .88);
        }

        .fallback-actions .start {
            color: var(--app-ok);
            background: var(--app-ok-dim);
            border-color: var(--app-ok-bdr);
        }

        .fallback-actions .stop {
            color: var(--app-err);
            background: var(--app-err-dim);
            border-color: var(--app-err-bdr);
        }

        .fallback-actions .restart {
            color: var(--app-warn);
            background: var(--app-warn-dim);
            border-color: var(--app-warn-bdr);
        }

        .fallback-actions button:disabled {
            cursor: not-allowed;
            opacity: .35;
        }

        .fallback-actions button:hover:not(:disabled) {
            background: var(--app-surface-hi);
            border-color: var(--app-accent-bdr);
        }

        .fallback-detail {
            margin-bottom: .7rem;
            color: var(--app-soft);
            font-size: .78rem;
            overflow-wrap: anywhere;
        }

        /* === SHELL LAYOUT === */
        .shell {
            position: relative;
            z-index: 1;
        }

        .shell-header {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            z-index: 100;
            display: flex;
            align-items: center;
            gap: .75rem;
            height: var(--shell-header-h);
            padding: .5rem .9rem;
            background: var(--app-topbar-bg);
            border-bottom: 1px solid var(--app-border);
            box-shadow: 0 8px 40px rgba(4, 8, 20, .24), var(--app-inset);
            backdrop-filter: blur(var(--app-blur)) saturate(1.35);
            -webkit-backdrop-filter: blur(var(--app-blur)) saturate(1.35);
        }

        .shell-brand {
            display: flex;
            align-items: center;
            gap: .62rem;
            min-width: 0;
        }

        .shell-brand-wordmark {
            color: var(--app-text);
            font-size: .95rem;
            font-weight: 700;
            letter-spacing: 0;
            white-space: nowrap;
        }

        .shell-header-actions {
            display: flex;
            align-items: center;
            gap: .48rem;
            margin-left: auto;
        }

        .live-status {
            display: inline-flex;
            align-items: center;
            gap: .4rem;
            color: var(--app-soft);
            font-family: var(--font-mono);
            font-size: .62rem;
            font-weight: 700;
            letter-spacing: .08em;
            text-transform: uppercase;
        }

        .sidebar-toggle .toggle-icon-collapsed,
        .shell-sidebar.collapsed ~ .shell-main .toggle-icon-expanded {
            display: none;
        }

        .shell-sidebar {
            position: fixed;
            top: var(--shell-header-h);
            bottom: var(--shell-footer-h);
            left: 0;
            z-index: 95;
            display: flex;
            flex-direction: column;
            width: var(--shell-sidebar-w);
            padding: .75rem .55rem;
            background: var(--app-surface);
            border-right: 1px solid var(--app-border);
            box-shadow: var(--app-inset);
            backdrop-filter: blur(var(--app-blur)) saturate(1.35);
            -webkit-backdrop-filter: blur(var(--app-blur)) saturate(1.35);
            transition: width .2s ease, transform .2s ease;
        }

        .shell-sidebar.collapsed {
            width: var(--shell-sidebar-collapsed-w);
        }

        .sidebar-nav {
            display: grid;
            gap: .28rem;
        }

        .sidebar-divider {
            height: 1px;
            margin: .55rem .45rem;
            background: var(--app-border);
        }

        .sidebar-section-label {
            padding: .5rem .62rem .18rem;
            color: var(--app-muted);
            font-family: var(--font-mono);
            font-size: .52rem;
            font-weight: 700;
            letter-spacing: .1em;
            text-transform: uppercase;
        }

        .shell-sidebar.collapsed .sidebar-section-label,
        body.sidebar-collapsed .sidebar-section-label {
            display: none;
        }

        .sidebar-nav-button {
            display: flex;
            align-items: center;
            gap: .62rem;
            width: 100%;
            min-height: 44px;
            padding: .45rem .62rem;
            color: var(--app-soft);
            background: transparent;
            border: 0;
            border-left: 3px solid transparent;
            border-radius: var(--app-radius-xs);
            cursor: pointer;
            font-family: var(--font-mono);
            font-size: .64rem;
            font-weight: 700;
            letter-spacing: .06em;
            text-align: left;
            text-transform: uppercase;
            transition: background .15s, color .15s, border-color .15s;
        }

        .sidebar-nav-button:hover {
            color: var(--app-text);
            background: var(--app-surface-hi);
        }

        .sidebar-nav-button.active {
            color: var(--app-text);
            background: var(--app-accent-dim);
            border-left-color: var(--app-accent);
        }

        .sidebar-nav-button svg,
        .host-stats-toggle svg {
            flex: 0 0 auto;
            width: 16px;
            height: 16px;
            fill: none;
            stroke: currentColor;
            stroke-linecap: round;
            stroke-linejoin: round;
            stroke-width: 1.75;
        }

        .shell-sidebar.collapsed .sidebar-nav-button {
            justify-content: center;
            gap: 0;
            padding-left: .35rem;
            padding-right: .35rem;
        }

        .shell-sidebar.collapsed .sidebar-label,
        .shell-sidebar.collapsed .sidebar-username,
        .shell-sidebar.collapsed .sidebar-role-text {
            display: none;
        }

        .sidebar-role-icon {
            display: none;
        }

        .sidebar-identity {
            display: grid;
            gap: .45rem;
            margin-top: auto;
            padding: .65rem .5rem .2rem;
            border-top: 1px solid var(--app-border);
        }

        .sidebar-username {
            min-width: 0;
            color: var(--app-soft);
            font-family: var(--font-mono);
            font-size: .62rem;
            overflow: hidden;
            text-overflow: ellipsis;
            text-transform: lowercase;
            white-space: nowrap;
        }

        .shell-sidebar.collapsed .sidebar-identity {
            justify-items: center;
            padding-left: 0;
            padding-right: 0;
        }

        .shell-sidebar.collapsed .role-chip {
            width: 28px;
            height: 28px;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            padding: 0;
        }

        .shell-sidebar.collapsed .sidebar-role-icon {
            display: inline;
        }

        .shell-main {
            height: calc(100svh - var(--shell-header-h) - var(--shell-footer-h));
            margin-top: var(--shell-header-h);
            margin-bottom: var(--shell-footer-h);
            margin-left: var(--shell-sidebar-w);
            overflow-y: auto;
            padding: 1.15rem;
            transition: margin-left .2s ease;
        }

        body.sidebar-collapsed .shell-main {
            margin-left: var(--shell-sidebar-collapsed-w);
        }

        .shell-section[hidden] {
            display: none;
        }

        .section-header {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 1rem;
            margin-bottom: 1rem;
        }

        .section-title-wrap {
            min-width: 0;
        }

        .section-title {
            margin: 0;
            color: var(--app-text);
            font-size: 1.05rem;
            font-weight: 700;
            letter-spacing: 0;
        }

        .section-subtitle {
            margin-top: .2rem;
            color: var(--app-muted);
            font-family: var(--font-mono);
            font-size: .62rem;
        }

        .section-controls {
            display: flex;
            align-items: center;
            justify-content: flex-end;
            flex-wrap: wrap;
            gap: .55rem;
        }

        .section-body {
            min-width: 0;
        }

        .shell-section .activity-panel {
            margin-top: 0;
        }

        .host-stats-toggle {
            display: inline-flex;
            align-items: center;
            gap: .35rem;
            min-height: 32px;
            padding: .36rem .62rem;
            color: var(--app-soft);
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            box-shadow: var(--app-inset);
            cursor: pointer;
            font-family: var(--font-mono);
            font-size: .58rem;
            font-weight: 700;
            letter-spacing: .08em;
            text-transform: uppercase;
        }

        .host-stats-toggle:hover {
            color: var(--app-text);
            background: var(--app-surface-hi);
            border-color: var(--app-accent-bdr);
        }

        .host-stats-toggle[aria-expanded="false"] svg {
            transform: rotate(-90deg);
        }

        .shell-footer {
            position: fixed;
            right: 0;
            bottom: 0;
            left: 0;
            z-index: 100;
            display: grid;
            grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
            align-items: center;
            gap: .75rem;
            height: var(--shell-footer-h);
            padding: 0 .9rem calc(env(safe-area-inset-bottom) * 0);
            background: var(--app-topbar-bg);
            border-top: 1px solid var(--app-border);
            box-shadow: 0 -8px 36px rgba(4, 8, 20, .18), var(--app-inset);
            backdrop-filter: blur(var(--app-blur)) saturate(1.35);
            -webkit-backdrop-filter: blur(var(--app-blur)) saturate(1.35);
        }

        .shell-footer-center {
            color: var(--app-muted);
            font-family: var(--font-mono);
            font-size: .58rem;
            letter-spacing: .08em;
            text-transform: uppercase;
            white-space: nowrap;
        }

        .shell-footer-right {
            justify-self: end;
        }

        .sidebar-overlay {
            display: none;
        }

        .toast-shelf {
            bottom: calc(var(--shell-footer-h) + 1.1rem + env(safe-area-inset-bottom));
        }

        .bulk-bar {
            bottom: calc(var(--shell-footer-h) + 1rem + env(safe-area-inset-bottom));
        }

        @media (max-width: 480px) {
            .content {
                padding: 1rem .85rem 2.5rem;
            }

            .list-controls {
                align-items: stretch;
                flex-direction: column;
            }

            .row-sort-bar,
            .row-sort-bar.visible {
                display: grid;
                grid-template-columns: repeat(3, minmax(0, 1fr));
            }

            .sort-label {
                grid-column: 1 / -1;
            }

            .sort-button {
                padding-left: .35rem;
                padding-right: .35rem;
            }

            .server-grid {
                grid-template-columns: 1fr;
            }

            .server-grid.row-view .server-card,
            .server-grid.row-view .card-body {
                grid-template-columns: 1fr;
            }

            .server-grid.row-view .card-actions {
                min-width: 0;
                border-top: 1px solid var(--app-border);
                border-left: 0;
            }

            .host-panel {
                grid-template-columns: 1fr;
            }

            .topbar-subtitle {
                display: none;
            }

            .topbar {
                padding-left: .85rem;
                padding-right: .85rem;
            }

            .topbar-text {
                flex: 1 1 auto;
            }

            .topbar-actions {
                gap: .42rem;
            }

            .activity-item {
                grid-template-columns: 1fr;
                gap: .12rem;
            }

            .account-2fa-row {
                flex-direction: column;
                align-items: flex-start;
            }

            .account-2fa-row .account-code-field {
                flex: 1 1 auto;
                width: 100%;
            }

            .role-chip {
                display: none;
            }

            .admin-panel-head,
            .access-row {
                grid-template-columns: 1fr;
            }

            .admin-panel-head {
                align-items: stretch;
                flex-direction: column;
            }
        }

        @media (max-width: 768px) {
            .shell-sidebar {
                width: var(--shell-sidebar-w);
                transform: translateX(calc(var(--shell-sidebar-w) * -1));
            }

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

            .shell-sidebar.collapsed {
                width: var(--shell-sidebar-w);
            }

            .shell-sidebar.collapsed .sidebar-nav-button {
                justify-content: flex-start;
                gap: .62rem;
                padding-left: .62rem;
                padding-right: .62rem;
            }

            .shell-sidebar.collapsed .sidebar-label,
            .shell-sidebar.collapsed .sidebar-username,
            .shell-sidebar.collapsed .sidebar-role-text {
                display: inline;
            }

            .shell-sidebar .role-chip {
                display: inline-flex;
            }

            .shell-sidebar.collapsed .sidebar-role-icon {
                display: none;
            }

            .shell-sidebar.collapsed .sidebar-identity {
                justify-items: stretch;
                padding: .65rem .5rem .2rem;
            }

            .shell-sidebar.collapsed .role-chip {
                width: auto;
                height: auto;
                padding: .22rem .58rem;
            }

            .sidebar-overlay {
                position: fixed;
                inset: 0;
                z-index: 90;
                display: block;
                pointer-events: none;
                opacity: 0;
                background: rgba(0, 0, 0, .45);
                transition: opacity .2s ease;
            }

            body.sidebar-open .sidebar-overlay {
                pointer-events: auto;
                opacity: 1;
            }

            .shell-main,
            body.sidebar-collapsed .shell-main {
                margin-left: 0;
                padding: 1rem .85rem;
            }

            .section-header {
                align-items: stretch;
                flex-direction: column;
            }

            .section-controls {
                justify-content: flex-start;
            }

            .shell-footer {
                grid-template-columns: minmax(0, 1fr);
            }

            .shell-footer-center,
            .shell-footer-right {
                display: none;
            }

            .count-chip {
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
            }
        }

        @media (min-width: 768px) {
            .content {
                padding: 1.5rem 1.5rem 3rem;
            }
        }

        .empty-search-state {
            display: none;
            padding: 3rem 1.5rem;
            color: var(--app-soft);
            font-size: .85rem;
            text-align: center;
        }

        .server-grid:has(.server-card[hidden]):not(:has(.server-card:not([hidden]))) + .empty-search-state {
            display: block;
        }

        /* ── Dashboard ─────────────────────────────────────────── */

        /* KPI tiles */
        .dash-kpis {
            display: grid;
            grid-template-columns: repeat(3, minmax(0, 1fr));
            gap: .75rem;
            margin-bottom: 1.15rem;
        }

        .dash-kpi {
            display: flex;
            align-items: center;
            gap: .85rem;
            padding: .95rem 1.1rem;
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-left-width: 3px;
            border-radius: var(--app-radius);
            box-shadow: var(--app-shadow-soft), var(--app-inset);
            backdrop-filter: blur(var(--app-blur));
            -webkit-backdrop-filter: blur(var(--app-blur));
        }

        .dash-kpi--ok {
            border-left-color: var(--app-ok);
        }

        .dash-kpi--err {
            border-left-color: var(--app-err);
        }

        .dash-kpi-icon {
            flex: 0 0 auto;
            display: flex;
            align-items: center;
            justify-content: center;
            width: 34px;
            height: 34px;
            border-radius: 9px;
        }

        .dash-kpi-icon svg {
            width: 15px;
            height: 15px;
            fill: none;
            stroke: currentColor;
            stroke-width: 1.7;
            stroke-linecap: round;
            stroke-linejoin: round;
        }

        .dash-kpi-icon--neutral {
            color: var(--app-muted);
            background: var(--app-surface-soft);
            border: 1px solid var(--app-border);
        }

        .dash-kpi-icon--ok {
            color: var(--app-ok);
            background: var(--app-ok-dim);
            border: 1px solid var(--app-ok-bdr);
        }

        .dash-kpi-icon--err {
            color: var(--app-err);
            background: var(--app-err-dim);
            border: 1px solid var(--app-err-bdr);
        }

        .dash-kpi-body {
            min-width: 0;
        }

        .dash-kpi-num {
            font-size: 1.8rem;
            font-weight: 700;
            line-height: 1;
            color: var(--app-text);
            letter-spacing: -.03em;
        }

        .dash-kpi--ok .dash-kpi-num {
            color: var(--app-ok);
        }

        .dash-kpi--err .dash-kpi-num {
            color: var(--app-err);
        }

        .dash-kpi-lbl {
            margin-top: .3rem;
            color: var(--app-muted);
            font-family: var(--font-mono);
            font-size: .57rem;
            font-weight: 600;
            letter-spacing: .08em;
            text-transform: uppercase;
        }

        .dash-kpi-sub {
            margin-top: .18rem;
            color: var(--app-muted);
            font-family: var(--font-mono);
            font-size: .57rem;
        }

        .dash-grid {
            display: grid;
            grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
            gap: .85rem;
            align-items: start;
        }

        .dash-col {
            display: flex;
            flex-direction: column;
            gap: .85rem;
        }

        .dash-card {
            padding: 1.05rem 1.1rem;
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius);
            box-shadow: var(--app-shadow-soft), var(--app-inset);
            backdrop-filter: blur(var(--app-blur));
            -webkit-backdrop-filter: blur(var(--app-blur));
        }

        .dash-card-head {
            display: flex;
            align-items: center;
            justify-content: space-between;
            margin-bottom: .8rem;
            color: var(--app-muted);
            font-family: var(--font-mono);
            font-size: .58rem;
            font-weight: 700;
            letter-spacing: .1em;
            text-transform: uppercase;
        }

        .dash-link-btn {
            padding: 0;
            color: var(--app-accent);
            background: none;
            border: none;
            cursor: pointer;
            font-family: var(--font-mono);
            font-size: .58rem;
            font-weight: 600;
            letter-spacing: .04em;
            text-transform: none;
        }

        .dash-link-btn:hover {
            color: var(--app-accent-strong);
            text-decoration: underline;
        }

        /* Ring gauges */
        .dash-gauge-row {
            display: flex;
            align-items: center;
            justify-content: space-around;
            gap: .5rem;
            padding-top: .25rem;
        }

        .dash-gauge {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: .3rem;
            position: relative;
        }

        .gauge-ring {
            width: 80px;
            height: 80px;
        }

        .gauge-track {
            fill: none;
            stroke: var(--app-border);
            stroke-width: 7;
        }

        :root[data-theme="light"] .gauge-track {
            stroke: rgba(0,0,0,.09);
        }

        .gauge-fill {
            fill: none;
            stroke: var(--app-accent);
            stroke-width: 7;
            stroke-linecap: round;
            stroke-dasharray: 188.5;
            stroke-dashoffset: 188.5;
            transform-origin: 40px 40px;
            transform: rotate(-90deg);
            transition: stroke-dashoffset .4s ease, stroke .3s ease;
        }

        .gauge-fill--ram {
            stroke: #a855f7;
        }

        .gauge-fill--warn {
            stroke: var(--app-warn) !important;
        }

        .gauge-fill--err {
            stroke: var(--app-err) !important;
        }

        .gauge-center {
            position: absolute;
            top: 0;
            left: 0;
            width: 80px;
            height: 80px;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .gauge-pct {
            font-size: .88rem;
            font-weight: 700;
            color: var(--app-text);
            letter-spacing: -.02em;
            font-family: var(--font-mono);
        }

        .gauge-lbl {
            color: var(--app-muted);
            font-family: var(--font-mono);
            font-size: .57rem;
            font-weight: 600;
            letter-spacing: .09em;
            text-transform: uppercase;
        }

        /* Network split display */
        .dash-net-pair {
            display: flex;
            flex-direction: column;
            gap: .6rem;
            align-items: flex-start;
            padding: .4rem .5rem;
        }

        .dash-net-item {
            display: flex;
            align-items: center;
            gap: .4rem;
        }

        .dash-net-arrow {
            flex: 0 0 auto;
            width: 14px;
            height: 14px;
            fill: none;
            stroke-width: 1.8;
            stroke-linecap: round;
            stroke-linejoin: round;
        }

        .dash-net-arrow--down {
            stroke: var(--app-ok);
        }

        .dash-net-arrow--up {
            stroke: var(--app-accent-strong);
        }

        .dash-net-val {
            color: var(--app-text);
            font-family: var(--font-mono);
            font-size: .7rem;
            font-weight: 600;
            white-space: nowrap;
        }

        .dash-net-lbl {
            color: var(--app-muted);
            font-family: var(--font-mono);
            font-size: .57rem;
            text-transform: uppercase;
            letter-spacing: .07em;
        }

        /* Server list in dashboard */
        .dash-server-list {
            list-style: none;
            margin: 0;
            padding: 0;
        }

        .dash-server-item {
            display: flex;
            align-items: center;
            gap: .62rem;
            padding: .5rem 0;
            border-top: 1px solid var(--app-border-soft);
        }

        .dash-server-item:first-child {
            border-top: none;
        }

        .dash-server-skeleton {
            height: 28px;
            border-radius: var(--app-radius-xs);
            background: var(--app-surface-soft);
            animation: skeleton-pulse 1.6s ease-in-out infinite;
        }

        @keyframes skeleton-pulse {
            0%, 100% { opacity: .6; }
            50% { opacity: 1; }
        }

        .dash-server-dot {
            flex: 0 0 auto;
            width: 7px;
            height: 7px;
            border-radius: 50%;
            background: var(--app-slate);
        }

        .dash-server-dot--running {
            background: var(--app-ok);
            box-shadow: 0 0 0 3px var(--app-ok-dim);
        }

        .dash-server-dot--stopped {
            background: var(--app-err);
        }

        .dash-server-name {
            flex: 1;
            min-width: 0;
            color: var(--app-text);
            font-size: .8rem;
            font-weight: 500;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        .dash-server-state {
            flex: 0 0 auto;
            padding: .2rem .52rem;
            border-radius: 999px;
            font-family: var(--font-mono);
            font-size: .55rem;
            font-weight: 700;
            letter-spacing: .06em;
            text-transform: uppercase;
        }

        .dash-server-state--running {
            color: var(--app-ok);
            background: var(--app-ok-dim);
            border: 1px solid var(--app-ok-bdr);
        }

        .dash-server-state--stopped {
            color: var(--app-err);
            background: var(--app-err-dim);
            border: 1px solid var(--app-err-bdr);
        }

        .dash-server-empty {
            display: block;
            padding: .5rem 0;
            color: var(--app-muted);
            font-size: .78rem;
            text-align: center;
        }

        /* Activity in dashboard */
        .dash-activity-list {
            list-style: none;
            margin: 0;
            padding: 0;
        }

        .dash-activity-item {
            display: flex;
            align-items: baseline;
            justify-content: space-between;
            gap: .5rem;
            padding: .52rem 0;
            border-top: 1px solid var(--app-border-soft);
        }

        .dash-activity-item:first-child {
            border-top: none;
        }

        .dash-activity-main {
            display: flex;
            align-items: center;
            gap: .38rem;
            color: var(--app-soft);
            font-size: .79rem;
            min-width: 0;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        .dash-activity-badge {
            flex: 0 0 auto;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            width: 15px;
            height: 15px;
            border-radius: 50%;
        }

        .dash-activity-badge svg {
            width: 10px;
            height: 10px;
            fill: none;
            stroke: currentColor;
            stroke-width: 2.2;
            stroke-linecap: round;
            stroke-linejoin: round;
        }

        .dash-activity-badge--ok {
            color: var(--app-ok);
            background: var(--app-ok-dim);
        }

        .dash-activity-badge--err {
            color: var(--app-err);
            background: var(--app-err-dim);
        }

        .dash-activity-action {
            color: var(--app-accent-strong);
            font-weight: 600;
        }

        .dash-activity-meta {
            flex: 0 0 auto;
            color: var(--app-muted);
            font-family: var(--font-mono);
            font-size: .57rem;
            white-space: nowrap;
        }

        .dash-activity-empty {
            display: block;
            padding: .5rem 0;
            color: var(--app-muted);
            font-size: .78rem;
            text-align: center;
        }

        @media (max-width: 900px) {
            .dash-grid {
                grid-template-columns: 1fr;
            }
        }

        @media (max-width: 600px) {
            .dash-kpis {
                grid-template-columns: 1fr;
                gap: .5rem;
            }
            .dash-kpi {
                padding: .75rem .9rem;
            }
        }

        @media (max-width: 400px) {
            .dash-gauge-row {
                flex-wrap: wrap;
                justify-content: center;
            }
        }

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

        /* ── Server Dashboard Two-Panel Layout ───────────────────────── */

        .servers-split {
            display: flex;
            min-height: 500px;
            height: calc(100svh - 220px);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius);
            overflow: hidden;
            background: var(--app-surface);
            box-shadow: var(--app-shadow), var(--app-inset);
        }

        .server-list-panel {
            flex: 0 0 280px;
            min-width: 200px;
            display: flex;
            flex-direction: column;
            border-right: 1px solid var(--app-border);
            overflow-y: auto;
            overscroll-behavior: contain;
        }

        .list-panel-toolbar {
            flex-shrink: 0;
            padding: .45rem .35rem;
            border-bottom: 1px solid var(--app-border);
            display: flex;
            flex-direction: column;
            gap: .3rem;
            background: var(--app-surface-soft);
        }

        .list-panel-search {
            width: 100%;
            box-sizing: border-box;
            background: var(--app-surface-hi);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            color: var(--app-text);
            font-size: .72rem;
            font-family: inherit;
            padding: .28rem .5rem;
            outline: none;
        }

        .list-panel-search::placeholder { color: var(--app-muted); }
        .list-panel-search:focus { border-color: var(--app-accent-bdr); box-shadow: 0 0 0 2px var(--app-accent-dim); }

        .list-panel-sort {
            display: flex;
            align-items: center;
            gap: .4rem;
        }

        .list-panel-sort-label {
            font-size: .6rem;
            font-weight: 600;
            color: var(--app-muted);
            font-family: var(--font-mono);
            text-transform: uppercase;
            letter-spacing: .04em;
        }

        .list-panel-sort-select {
            flex: 1;
            box-sizing: border-box;
            background: var(--app-surface-hi);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            color: var(--app-text);
            font-size: .72rem;
            font-family: inherit;
            padding: .22rem .4rem;
            cursor: pointer;
            outline: none;
        }

        .list-panel-sort-select:focus { border-color: var(--app-accent-bdr); box-shadow: 0 0 0 2px var(--app-accent-dim); }

        .list-empty-state {
            padding: 1.25rem .75rem;
            font-size: .72rem;
            color: var(--app-muted);
            text-align: center;
        }

        .server-list {
            list-style: none;
            margin: 0;
            padding: .35rem;
            display: flex;
            flex-direction: column;
            gap: .2rem;
        }

        .server-list-item {
            display: grid;
            grid-template-columns: 8px 1fr auto auto;
            align-items: center;
            gap: .5rem;
            padding: .5rem .65rem;
            border-radius: var(--app-radius-xs);
            cursor: pointer;
            transition: background .12s;
            user-select: none;
            border: 1px solid transparent;
        }

        .server-list-item:hover {
            background: var(--app-surface-hi);
        }

        .server-list-item.selected {
            background: var(--app-accent-dim);
            border-color: var(--app-accent-bdr);
        }

        .sli-dot {
            width: 8px;
            height: 8px;
            border-radius: 50%;
            flex-shrink: 0;
        }

        .state-dot-running   { background: var(--app-ok); }
        .state-dot-exited,
        .state-dot-created   { background: var(--app-slate); }
        .state-dot-dead      { background: var(--app-err); }
        .state-dot-restarting,
        .state-dot-paused    { background: var(--app-warn); }

        .sli-name {
            font-size: .78rem;
            font-weight: 600;
            color: var(--app-text);
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        .sli-cpu,
        .sli-ram {
            font-family: var(--font-mono);
            font-size: .58rem;
            color: var(--app-muted);
            white-space: nowrap;
        }

        .server-dashboard {
            flex: 1 1 0;
            min-width: 0;
            display: flex;
            flex-direction: column;
            overflow: hidden;
        }

        .dashboard-empty {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            flex: 1;
            gap: 1rem;
            color: var(--app-muted);
            font-size: .85rem;
            padding: 2rem;
        }

        .dashboard-empty[hidden] {
            display: none;
        }

        .dashboard-empty svg {
            width: 48px;
            height: 48px;
            opacity: .3;
        }

        .dashboard-content {
            display: flex;
            flex-direction: column;
            flex: 1;
            min-width: 0;
            overflow: hidden;
        }

        .dashboard-content[hidden] {
            display: none;
        }

        .dashboard-header {
            display: flex;
            align-items: flex-start;
            justify-content: space-between;
            gap: 1rem;
            padding: .85rem 1rem;
            border-bottom: 1px solid var(--app-border);
            flex-wrap: wrap;
        }

        .dashboard-server-info {
            min-width: 0;
        }

        .dashboard-name {
            font-size: 1rem;
            font-weight: 700;
            color: var(--app-text);
        }

        .dashboard-state {
            font-size: .7rem;
            font-weight: 600;
            font-family: var(--font-mono);
            margin-top: .15rem;
        }

        .dashboard-state.state-running   { color: var(--app-ok); }
        .dashboard-state.state-exited,
        .dashboard-state.state-created   { color: var(--app-muted); }
        .dashboard-state.state-dead      { color: var(--app-err); }
        .dashboard-state.state-restarting,
        .dashboard-state.state-paused    { color: var(--app-warn); }

        .dashboard-meta {
            font-size: .65rem;
            color: var(--app-muted);
            font-family: var(--font-mono);
            margin-top: .2rem;
        }

        .dashboard-actions {
            display: flex;
            gap: .45rem;
            flex-shrink: 0;
            flex-wrap: wrap;
        }

        .dashboard-actions .action-button {
            min-height: 48px;
            min-width: 64px;
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            border-right: 1px solid var(--app-border);
        }

        .dashboard-charts {
            display: grid;
            grid-template-columns: repeat(3, minmax(0, 1fr));
            gap: .75rem;
            padding: .85rem 1rem;
            border-bottom: 1px solid var(--app-border);
        }

        .dashboard-chart-card {
            background: var(--app-surface-soft);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-sm);
            padding: .65rem .75rem;
            min-width: 0;
        }

        .chart-label {
            font-family: var(--font-mono);
            font-size: .52rem;
            font-weight: 600;
            color: var(--app-muted);
            text-transform: uppercase;
            letter-spacing: .08em;
            margin-bottom: .2rem;
        }

        .chart-value {
            font-family: var(--font-mono);
            font-size: .65rem;
            color: var(--app-soft);
            margin-bottom: .35rem;
            min-height: 1.2em;
        }

        .dashboard-chart-svg {
            display: block;
            width: 100%;
            height: 80px;
            overflow: visible;
        }

        .dashboard-logs {
            display: flex;
            flex-direction: column;
            flex: 1;
            min-height: 0;
            overflow: hidden;
        }

        .dashboard-logs-head {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: .5rem .85rem;
            border-bottom: 1px solid var(--app-border);
            background: var(--app-surface-soft);
            flex-shrink: 0;
        }

        .dashboard-logs-title {
            font-family: var(--font-mono);
            font-size: .62rem;
            color: var(--app-muted);
            text-transform: uppercase;
            letter-spacing: .06em;
        }

        .dashboard-logs-actions {
            display: flex;
            gap: .3rem;
            align-items: center;
        }

        .dashboard-logs .logs-pre {
            flex: 1;
            min-height: 0;
            max-height: none;
            border-radius: 0;
            border: none;
            overflow-y: auto;
        }

        /* ── State dot animations ────────────────────────────────────── */

        @keyframes dotPulse {
            0%, 100% { transform: scale(1); opacity: 1; }
            50%      { transform: scale(.5); opacity: .3; }
        }

        @keyframes spinSlow {
            from { transform: rotate(0deg); }
            to   { transform: rotate(360deg); }
        }

        .state-dot-restarting {
            animation: dotPulse 1.05s ease-in-out infinite;
        }

        .state-dot-created {
            background: var(--app-ok) !important;
            opacity: .65;
            animation: dotPulse 1.7s ease-in-out infinite;
        }

        /* ── List item state styling ──────────────────────────────────── */

        .server-list-item.state-exited,
        .server-list-item.state-dead {
            opacity: .65;
        }

        .server-list-item.state-dead .sli-name {
            color: var(--app-err);
        }

        .server-list-item.state-restarting .sli-name,
        .server-list-item.state-created .sli-name {
            color: var(--app-warn);
        }

        /* ── Dashboard content state-based styling ────────────────────── */

        .dashboard-content[data-state="running"] .dashboard-header {
            border-left: 3px solid var(--app-ok-bdr);
        }

        .dashboard-content[data-state="exited"] .dashboard-header,
        .dashboard-content[data-state="created"] .dashboard-header {
            border-left: 3px solid var(--app-slate-bdr);
        }

        .dashboard-content[data-state="dead"] .dashboard-header {
            border-left: 3px solid var(--app-err-bdr);
            background: var(--app-err-dim);
        }

        .dashboard-content[data-state="restarting"] .dashboard-header,
        .dashboard-content[data-state="paused"] .dashboard-header {
            border-left: 3px solid var(--app-warn-bdr);
            background: var(--app-warn-dim);
        }

        /* Offline: dim charts, grey lines */
        .dashboard-content[data-state="exited"] .dashboard-chart-card,
        .dashboard-content[data-state="dead"] .dashboard-chart-card {
            opacity: .5;
        }

        .dashboard-content[data-state="exited"] .metric-sparkline-line,
        .dashboard-content[data-state="dead"] .metric-sparkline-line {
            stroke: var(--app-slate);
            filter: none;
        }

        /* Restarting: dim charts, amber lines */
        .dashboard-content[data-state="restarting"] .dashboard-chart-card,
        .dashboard-content[data-state="created"] .dashboard-chart-card {
            opacity: .7;
        }

        .dashboard-content[data-state="restarting"] .metric-sparkline-line,
        .dashboard-content[data-state="created"] .metric-sparkline-line {
            stroke: var(--app-warn);
            filter: none;
        }

        /* Spinner on restarting / starting-up state badge */
        .dashboard-state.state-restarting::before,
        .dashboard-state.state-created::before {
            content: '';
            display: inline-block;
            width: .65em;
            height: .65em;
            border: 1.5px solid currentColor;
            border-top-color: transparent;
            border-radius: 50%;
            animation: spinSlow .9s linear infinite;
            margin-right: .4em;
            vertical-align: middle;
        }

        /* ── Going-offline / restarting flourish animations ──────────── */

        @keyframes wentOffline {
            0%   { background: transparent; box-shadow: none; }
            10%  { background: var(--app-err-dim); box-shadow: inset 0 0 0 1px var(--app-err-bdr); }
            55%  { background: var(--app-err-dim); box-shadow: inset 0 0 0 1px var(--app-err-bdr); }
            100% { background: transparent; box-shadow: none; }
        }

        @keyframes wentRestarting {
            0%   { background: transparent; box-shadow: none; }
            10%  { background: var(--app-warn-dim); box-shadow: inset 0 0 0 1px var(--app-warn-bdr); }
            55%  { background: var(--app-warn-dim); box-shadow: inset 0 0 0 1px var(--app-warn-bdr); }
            100% { background: transparent; box-shadow: none; }
        }

        .dashboard-content.anim-went-offline {
            animation: wentOffline 1.4s ease-out forwards;
        }

        .dashboard-content.anim-went-restarting {
            animation: wentRestarting 1.4s ease-out forwards;
        }

        @media (max-width: 768px) {
            .servers-split {
                flex-direction: column;
                height: auto;
                min-height: auto;
            }

            .server-list-panel {
                flex: 0 0 auto;
                max-height: 220px;
                border-right: none;
                border-bottom: 1px solid var(--app-border);
            }

            .server-dashboard {
                min-height: 400px;
                overflow-y: auto;
            }

            .dashboard-content {
                overflow: visible;
            }

            .dashboard-logs {
                min-height: 280px;
            }

            .dashboard-logs .logs-pre {
                max-height: 380px;
            }

            .dashboard-charts {
                grid-template-columns: 1fr;
            }
        }

        /* ── RCON Console ────────────────────────────────────────── */

        .rcon-console-toolbar {
            display: flex;
            align-items: center;
            gap: .5rem;
            margin-bottom: .75rem;
        }

        .rcon-server-select {
            flex: 1;
            min-width: 0;
            padding: .4rem .6rem;
            background: var(--app-base);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            color: var(--app-text);
            font-family: var(--font-mono);
            font-size: .75rem;
        }

        .rcon-output-wrap {
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            background: #000;
            margin-bottom: .5rem;
        }

        .rcon-output {
            height: 360px;
            min-height: 120px;
            max-height: 600px;
            overflow-y: auto;
            font-size: .72rem;
            color: #d4d4d4;
        }

        .rcon-output .log-line {
            color: #d4d4d4;
        }

        .rcon-output .log-line.stderr {
            color: #f48771;
        }

        .rcon-command-form {
            display: flex;
            gap: .5rem;
        }

        .rcon-command-input {
            flex: 1;
            min-width: 0;
            padding: .4rem .6rem;
            background: var(--app-base);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            color: var(--app-text);
            font-family: var(--font-mono);
            font-size: .75rem;
        }

        .rcon-command-input:focus {
            outline: none;
            border-color: var(--app-accent);
        }

        .rcon-server-row {
            display: flex;
            align-items: center;
            gap: .75rem;
            padding: .6rem .75rem;
            border-bottom: 1px solid var(--app-border);
        }

        .rcon-server-row:last-child {
            border-bottom: none;
        }

        .rcon-server-row .access-name {
            font-weight: 600;
            font-size: .8rem;
        }

        .rcon-server-row .access-meta {
            color: var(--app-muted);
            font-size: .72rem;
        }

        .rcon-server-row .row-actions {
            margin-left: auto;
            display: flex;
            gap: .4rem;
            flex-shrink: 0;
        }

        .rcon-enabled-label {
            display: flex;
            align-items: center;
            gap: .35rem;
            font-size: .78rem;
            white-space: nowrap;
        }

        .rcon-access-chip {
            display: inline-flex;
            align-items: center;
            padding: .2rem .5rem;
            border-radius: var(--app-radius-xs);
            font-family: var(--font-mono);
            font-size: .65rem;
            font-weight: 700;
            white-space: nowrap;
            cursor: pointer;
            border: 1px solid var(--app-border);
            background: var(--app-surface);
            color: var(--app-muted);
            transition: background .15s, color .15s, border-color .15s;
        }

        button.rcon-access-chip:hover {
            border-color: var(--app-accent);
            color: var(--app-accent);
        }

        .rcon-access-chip--on {
            background: var(--app-ok-dim, rgba(34,197,94,.12));
            border-color: var(--app-ok);
            color: var(--app-ok);
        }

        .rcon-access-chip--admin {
            border-color: var(--app-accent);
            color: var(--app-accent);
            cursor: default;
        }

        .rcon-container-stats {
            display: flex;
            align-items: center;
            gap: 0;
            margin-bottom: .75rem;
            padding: .45rem .75rem;
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            flex-wrap: wrap;
            row-gap: .35rem;
        }

        .rcon-cstat {
            display: flex;
            align-items: center;
            gap: .35rem;
            padding: 0 .75rem;
            border-right: 1px solid var(--app-border);
            font-size: .72rem;
        }

        .rcon-cstat:first-child {
            padding-left: 0;
        }

        .rcon-cstat:last-child {
            border-right: none;
        }

        .rcon-cstat-label {
            color: var(--app-muted);
            font-size: .65rem;
            text-transform: uppercase;
            letter-spacing: .04em;
        }

        .rcon-cstat-value {
            font-family: var(--font-mono);
            font-size: .72rem;
            color: var(--app-text);
        }

        .rcon-cstat-dot {
            width: 6px;
            height: 6px;
            border-radius: 50%;
            background: var(--app-muted);
            flex-shrink: 0;
        }

        .rcon-cstat-dot--online  { background: var(--app-ok); }
        .rcon-cstat-dot--offline { background: var(--app-err); }

        /* ── RCON Docs ───────────────────────────────────────────────────── */

        .rcon-docs-viewer[hidden],
        .rcon-docs-editor[hidden],
        .rcon-docs-empty[hidden] { display: none; }

        .btn-link {
            background: none;
            border: none;
            padding: 0;
            color: var(--app-accent-strong);
            font: inherit;
            cursor: pointer;
            text-decoration: underline;
        }

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

        .rcon-docs-layout {
            display: grid;
            grid-template-columns: 220px 1fr;
            gap: 1rem;
            min-height: 400px;
        }

        .rcon-docs-sidebar {
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-sm);
            background: var(--app-surface);
            overflow-y: auto;
            max-height: 600px;
        }

        .rcon-docs-list {
            display: flex;
            flex-direction: column;
        }

        .rcon-doc-list-item {
            display: flex;
            align-items: center;
            gap: .4rem;
            width: 100%;
            padding: .6rem .75rem;
            background: transparent;
            border: 0;
            border-bottom: 1px solid var(--app-border-soft);
            color: var(--app-soft);
            cursor: pointer;
            font: inherit;
            font-size: .8rem;
            text-align: left;
            transition: background .12s;
        }

        .rcon-doc-list-item:last-child { border-bottom: none; }

        .rcon-doc-list-item:hover {
            background: var(--app-surface-soft);
            color: var(--app-text);
        }

        .rcon-doc-list-item.active {
            background: var(--app-accent-dim);
            color: var(--app-text);
            border-left: 2px solid var(--app-accent);
        }

        .rcon-doc-list-title {
            flex: 1;
            min-width: 0;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        .rcon-doc-scope-badge {
            font-size: .62rem;
            font-family: var(--font-mono);
            font-weight: 700;
            letter-spacing: .05em;
            text-transform: uppercase;
            padding: .1rem .3rem;
            background: var(--app-accent-dim);
            border: 1px solid var(--app-accent-bdr);
            border-radius: var(--app-radius-xs);
            color: var(--app-accent-strong);
            flex-shrink: 0;
        }

        /* ── Doc Viewer ────────────────────────────────────────────────── */

        .rcon-docs-main {
            min-width: 0;
            display: flex;
            flex-direction: column;
        }

        .rcon-docs-viewer,
        .rcon-docs-editor { flex: 1; }

        .rcon-docs-viewer-head {
            display: flex;
            align-items: baseline;
            gap: .75rem;
            margin-bottom: .85rem;
            flex-wrap: wrap;
        }

        .rcon-docs-title {
            font-size: 1rem;
            font-weight: 700;
            color: var(--app-text);
            margin: 0;
        }

        .rcon-docs-scope {
            font-size: .65rem;
            font-family: var(--font-mono);
            font-weight: 700;
            text-transform: uppercase;
            letter-spacing: .06em;
            color: var(--app-accent-strong);
            padding: .1rem .3rem;
            background: var(--app-accent-dim);
            border: 1px solid var(--app-accent-bdr);
            border-radius: var(--app-radius-xs);
        }

        .rcon-docs-viewer-actions {
            margin-left: auto;
            display: flex;
            gap: .4rem;
            flex-shrink: 0;
        }

        .rcon-doc-delete-confirm {
            color: var(--app-err) !important;
            border-color: var(--app-err) !important;
        }

        .rcon-docs-body {
            font-size: .84rem;
            line-height: 1.65;
            color: var(--app-soft);
            overflow-wrap: break-word;
        }

        .rcon-docs-body h1,
        .rcon-docs-body h2,
        .rcon-docs-body h3,
        .rcon-docs-body h4 {
            color: var(--app-text);
            font-weight: 700;
            margin: 1.1em 0 .45em;
            line-height: 1.25;
        }

        .rcon-docs-body h1 { font-size: 1.2em; border-bottom: 1px solid var(--app-border); padding-bottom: .3em; }
        .rcon-docs-body h2 { font-size: 1.05em; }
        .rcon-docs-body h3 { font-size: .95em; }
        .rcon-docs-body h4 { font-size: .88em; color: var(--app-muted); }

        .rcon-docs-body p { margin: .55em 0; }

        .rcon-docs-body a {
            color: var(--app-accent-strong);
            text-decoration: underline;
            word-break: break-all;
        }

        .rcon-docs-body strong { font-weight: 700; color: var(--app-text); }
        .rcon-docs-body em { font-style: italic; }

        .rcon-docs-body code {
            font-family: var(--font-mono);
            font-size: .82em;
            background: var(--app-surface-soft);
            border: 1px solid var(--app-border-soft);
            border-radius: 3px;
            padding: .1em .3em;
        }

        .rcon-docs-body pre {
            background: #000;
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            padding: .75rem 1rem;
            overflow-x: auto;
            margin: .7em 0;
            cursor: pointer;
            transition: border-color .15s;
        }

        .rcon-docs-body pre:hover {
            border-color: var(--app-accent-bdr);
        }

        .rcon-docs-body pre:active {
            border-color: var(--app-accent);
        }

        .rcon-docs-body pre code {
            background: none;
            border: none;
            padding: 0;
            font-size: .8em;
            color: #d4d4d4;
        }

        .rcon-docs-body ul,
        .rcon-docs-body ol { padding-left: 1.5em; margin: .5em 0; }

        .rcon-docs-body li { margin: .2em 0; }

        .rcon-docs-body hr {
            border: none;
            border-top: 1px solid var(--app-border);
            margin: 1em 0;
        }

        .rcon-docs-body blockquote {
            border-left: 3px solid var(--app-accent-bdr);
            margin: .55em 0;
            padding: .35em .75em;
            color: var(--app-muted);
            background: var(--app-accent-dim);
            border-radius: 0 var(--app-radius-xs) var(--app-radius-xs) 0;
        }

        /* ── Admin Editor (split pane) ─────────────────────────────────── */

        .rcon-doc-form-meta {
            display: flex;
            gap: .55rem;
            align-items: center;
            margin-bottom: .65rem;
            flex-wrap: wrap;
        }

        .rcon-doc-title-input {
            flex: 1;
            min-width: 160px;
            height: 36px;
            padding: 0 .6rem;
            background: var(--app-surface-soft);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            color: var(--app-text);
            font: inherit;
            font-size: .84rem;
        }

        .rcon-doc-title-input:focus-visible {
            outline: 2px solid var(--app-accent-strong);
            outline-offset: 1px;
            border-color: var(--app-accent-bdr);
        }

        .rcon-doc-form select {
            height: 36px;
            padding: 0 .6rem;
            background: var(--app-surface-soft);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            color: var(--app-text);
            font: inherit;
            font-size: .82rem;
        }

        .rcon-doc-form-actions {
            display: flex;
            gap: .4rem;
            flex-shrink: 0;
            margin-left: auto;
        }

        .rcon-doc-split {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: .75rem;
            height: 420px;
        }

        .rcon-doc-textarea {
            width: 100%;
            height: 100%;
            resize: none;
            padding: .65rem .75rem;
            background: #0a0a0a;
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            color: #d4d4d4;
            font-family: var(--font-mono);
            font-size: .78rem;
            line-height: 1.55;
            box-sizing: border-box;
        }

        .rcon-doc-textarea:focus {
            outline: none;
            border-color: var(--app-accent);
        }

        .rcon-doc-preview {
            height: 100%;
            overflow-y: auto;
            padding: .65rem .85rem;
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            background: var(--app-surface);
            box-sizing: border-box;
            font-size: .84rem;
            line-height: 1.65;
            color: var(--app-soft);
        }

        .rcon-doc-preview h1,
        .rcon-doc-preview h2,
        .rcon-doc-preview h3,
        .rcon-doc-preview h4 { color: var(--app-text); font-weight: 700; margin: 1em 0 .4em; line-height: 1.25; }
        .rcon-doc-preview h1 { font-size: 1.2em; border-bottom: 1px solid var(--app-border); padding-bottom: .25em; }
        .rcon-doc-preview h2 { font-size: 1.05em; }
        .rcon-doc-preview h3 { font-size: .95em; }
        .rcon-doc-preview p  { margin: .5em 0; }
        .rcon-doc-preview a  { color: var(--app-accent-strong); text-decoration: underline; word-break: break-all; }
        .rcon-doc-preview strong { font-weight: 700; color: var(--app-text); }
        .rcon-doc-preview em { font-style: italic; }
        .rcon-doc-preview code { font-family: var(--font-mono); font-size: .82em; background: var(--app-surface-soft); border: 1px solid var(--app-border-soft); border-radius: 3px; padding: .1em .3em; }
        .rcon-doc-preview pre { background: #000; border: 1px solid var(--app-border); border-radius: var(--app-radius-xs); padding: .75rem 1rem; overflow-x: auto; margin: .65em 0; }
        .rcon-doc-preview pre code { background: none; border: none; padding: 0; font-size: .8em; color: #d4d4d4; }
        .rcon-doc-preview ul, .rcon-doc-preview ol { padding-left: 1.5em; margin: .4em 0; }
        .rcon-doc-preview li { margin: .2em 0; }
        .rcon-doc-preview hr { border: none; border-top: 1px solid var(--app-border); margin: 1em 0; }
        .rcon-doc-preview blockquote { border-left: 3px solid var(--app-accent-bdr); margin: .5em 0; padding: .3em .75em; color: var(--app-muted); background: var(--app-accent-dim); border-radius: 0 var(--app-radius-xs) var(--app-radius-xs) 0; }

        .rcon-docs-empty {
            display: flex;
            align-items: center;
            justify-content: center;
            min-height: 200px;
            color: var(--app-muted);
            font-size: .84rem;
            border: 1px dashed var(--app-border);
            border-radius: var(--app-radius-sm);
            text-align: center;
            padding: 1.5rem;
        }

        @media (max-width: 768px) {
            .rcon-docs-layout { grid-template-columns: 1fr; }
            .rcon-docs-sidebar { max-height: 180px; }
            .rcon-doc-split { grid-template-columns: 1fr; height: auto; }
            .rcon-doc-textarea, .rcon-doc-preview { height: 240px; }
        }

        /* ── End RCON Docs ───────────────────────────────────────────────── */

        /* ── SFTP Browser ────────────────────────────────────────────────── */

        .sftp-tab-panel[hidden] { display: none; }

        .sftp-toolbar {
            display: flex;
            align-items: center;
            gap: .5rem;
            flex-wrap: wrap;
            margin-bottom: .75rem;
        }

        .sftp-server-select {
            flex: 1;
            min-width: 160px;
            max-width: 320px;
            padding: .38rem .6rem;
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-sm);
            color: var(--app-text);
            font-size: .85rem;
        }

        .sftp-toolbar-btn {
            display: inline-flex;
            align-items: center;
            gap: .35rem;
            font-size: .8rem;
        }

        .sftp-toolbar-btn svg {
            width: 14px;
            height: 14px;
            flex-shrink: 0;
            fill: none;
            stroke: currentColor;
            stroke-linecap: round;
            stroke-linejoin: round;
            stroke-width: 1.75;
        }

        #sftpRestartBtn.armed {
            color: var(--app-warn);
            border-color: var(--app-warn);
        }

        .sftp-upload-label {
            display: inline-flex;
            align-items: center;
            gap: .35rem;
            padding: .38rem .72rem;
            cursor: pointer;
            font-size: .8rem;
            user-select: none;
        }

        .sftp-upload-label[aria-disabled="true"] {
            opacity: .45;
            pointer-events: none;
        }

        .sftp-upload-label svg {
            width: 14px;
            height: 14px;
            flex-shrink: 0;
            fill: none;
            stroke: currentColor;
            stroke-linecap: round;
            stroke-linejoin: round;
            stroke-width: 1.75;
        }

        .sftp-breadcrumb {
            display: flex;
            align-items: center;
            flex-wrap: wrap;
            gap: .1rem;
            min-height: 28px;
            margin-bottom: .5rem;
            padding: .3rem .5rem;
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            font-family: var(--font-mono);
            font-size: .78rem;
            color: var(--app-muted);
        }

        .sftp-breadcrumb-seg {
            background: none;
            border: 0;
            padding: .1rem .25rem;
            color: var(--app-accent);
            cursor: pointer;
            font-family: inherit;
            font-size: inherit;
            border-radius: var(--app-radius-xs);
        }

        .sftp-breadcrumb-seg:hover { text-decoration: underline; }

        .sftp-breadcrumb-sep {
            color: var(--app-border);
            padding: 0 .1rem;
        }

        .sftp-listing {
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-sm);
            overflow: hidden;
        }

        .sftp-listing-empty {
            padding: 2rem 1rem;
            text-align: center;
            color: var(--app-muted);
            font-size: .85rem;
        }

        .sftp-listing-header,
        .sftp-listing-row {
            display: grid;
            grid-template-columns: 20px 1fr 6rem 11rem 116px;
            align-items: center;
            gap: .5rem;
            padding: .42rem .65rem;
        }

        .sftp-listing-header {
            background: var(--app-surface);
            border-bottom: 1px solid var(--app-border);
            font-size: .72rem;
            font-weight: 600;
            color: var(--app-muted);
            text-transform: uppercase;
            letter-spacing: .06em;
        }

        .sftp-listing-row {
            border-bottom: 1px solid var(--app-border);
            transition: background .12s;
        }

        .sftp-listing-row:last-child { border-bottom: 0; }

        .sftp-listing-row:hover { background: var(--app-surface); }

        .sftp-entry-icon {
            display: flex;
            align-items: center;
            color: var(--app-muted);
        }

        .sftp-entry-icon svg {
            width: 14px;
            height: 14px;
        }

        .sftp-entry-icon svg path { fill: currentColor; }

        .sftp-entry-name {
            font-size: .85rem;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        .sftp-entry-name-btn {
            background: none;
            border: 0;
            padding: 0;
            color: var(--app-text);
            cursor: pointer;
            font-family: inherit;
            font-size: inherit;
            text-align: left;
            width: 100%;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        .sftp-listing-row--dir .sftp-entry-name-btn { color: var(--app-accent); font-weight: 500; }

        .sftp-entry-name-btn:hover { text-decoration: underline; }

        .sftp-entry-size,
        .sftp-entry-date {
            font-family: var(--font-mono);
            font-size: .75rem;
            color: var(--app-muted);
            white-space: nowrap;
        }

        .sftp-entry-actions {
            display: flex;
            gap: .25rem;
            justify-content: flex-end;
        }

        .sftp-entry-actions .icon-button {
            width: 26px;
            height: 26px;
            opacity: .6;
        }

        .sftp-entry-actions .icon-button:hover { opacity: 1; }

        .sftp-entry-actions .icon-button svg { width: 13px; height: 13px; stroke: currentColor; fill: none; }

        .sftp-entry-actions .icon-button.armed { color: var(--app-err); opacity: 1; }

        /* Text editor */
        .sftp-text-editor {
            margin-top: 1rem;
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-sm);
            overflow: hidden;
        }

        .sftp-editor-bar {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 1rem;
            padding: .4rem .65rem;
            background: var(--app-surface);
            border-bottom: 1px solid var(--app-border);
        }

        .sftp-editor-path {
            font-family: var(--font-mono);
            font-size: .75rem;
            color: var(--app-muted);
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        .sftp-editor-actions { display: flex; gap: .4rem; flex-shrink: 0; }

        .sftp-editor-textarea[hidden] { display: none; }

        .sftp-editor-textarea {
            display: block;
            width: 100%;
            min-height: 360px;
            padding: .75rem;
            background: var(--app-bg);
            border: 0;
            color: var(--app-text);
            font-family: var(--font-mono);
            font-size: .82rem;
            line-height: 1.6;
            resize: vertical;
            box-sizing: border-box;
        }

        /* INI structured editor */
        .sftp-ini-editor {
            padding: .75rem;
            background: var(--app-bg);
            max-height: 620px;
            overflow-y: auto;
        }

        .ini-editor {
            display: flex;
            flex-direction: column;
            gap: .35rem;
        }

        .ini-section {
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            overflow: hidden;
        }

        .ini-section--global {
            border: 0;
            border-radius: 0;
        }

        .ini-section-head {
            display: flex;
            align-items: center;
            gap: .5rem;
            padding: .4rem .65rem;
            background: var(--app-surface);
            cursor: pointer;
            list-style: none;
            user-select: none;
            border-bottom: 1px solid var(--app-border);
        }

        .ini-section-head::-webkit-details-marker { display: none; }

        .ini-section-chevron {
            width: 8px;
            height: 12px;
            flex-shrink: 0;
            color: var(--app-muted);
            transition: transform .15s;
        }

        details.ini-section[open] > .ini-section-head .ini-section-chevron {
            transform: rotate(90deg);
        }

        .ini-section-name {
            font-size: .82rem;
            font-weight: 600;
            color: var(--app-text);
            flex: 1;
            font-family: var(--font-mono);
        }

        .ini-section-count {
            font-size: .72rem;
            color: var(--app-muted);
            font-family: var(--font-mono);
        }

        .ini-section-body {
            padding: .25rem .65rem;
        }

        .ini-section--global .ini-section-body {
            padding: .25rem 0;
        }

        .ini-field {
            display: grid;
            grid-template-columns: minmax(140px, 32%) 1fr;
            gap: .4rem .75rem;
            align-items: start;
            padding: .35rem 0;
            border-bottom: 1px solid var(--app-border-soft);
        }

        .ini-field:last-child { border-bottom: 0; }

        .ini-field-label-wrap {
            padding-top: .3rem;
        }

        .ini-field-label {
            display: block;
            font-size: .8rem;
            font-family: var(--font-mono);
            color: var(--app-text);
            word-break: break-all;
        }

        .ini-field-hint {
            font-size: .71rem;
            color: var(--app-muted);
            margin-top: .2rem;
            font-style: italic;
            line-height: 1.4;
            font-family: var(--font-mono);
        }

        .ini-field-control {
            display: flex;
            align-items: flex-start;
            padding-top: .15rem;
        }

        .ini-field-input {
            width: 100%;
            padding: .28rem .5rem;
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            color: var(--app-text);
            font-family: var(--font-mono);
            font-size: .8rem;
            box-sizing: border-box;
            transition: border-color .12s;
        }

        .ini-field-input:focus {
            outline: none;
            border-color: var(--app-accent-bdr);
        }

        .ini-field-input:disabled {
            opacity: .5;
            cursor: default;
        }

        .ini-field-textarea {
            width: 100%;
            padding: .28rem .5rem;
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-xs);
            color: var(--app-text);
            font-family: var(--font-mono);
            font-size: .8rem;
            resize: vertical;
            box-sizing: border-box;
            line-height: 1.5;
            transition: border-color .12s;
        }

        .ini-field-textarea:focus {
            outline: none;
            border-color: var(--app-accent-bdr);
        }

        .ini-field-textarea:disabled {
            opacity: .5;
            cursor: default;
        }

        .ini-bool-toggle {
            padding: .24rem .7rem;
            border-radius: var(--app-radius-xs);
            border: 1px solid var(--app-border);
            background: var(--app-surface);
            font-size: .78rem;
            font-weight: 600;
            cursor: pointer;
            transition: background .12s, border-color .12s, color .12s;
            font-family: inherit;
            color: var(--app-muted);
        }

        .ini-bool-toggle--on {
            background: var(--app-ok-dim);
            border-color: var(--app-ok-bdr);
            color: var(--app-ok);
        }

        .ini-bool-toggle--off:hover {
            border-color: var(--app-border);
            color: var(--app-text);
        }

        .ini-bool-static {
            font-size: .8rem;
            font-family: var(--font-mono);
            color: var(--app-muted);
            padding: .3rem 0;
            display: inline-block;
        }

        .ini-bool-static--on { color: var(--app-ok); }

        .ini-blank { height: .3rem; }

        .ini-comment {
            font-size: .73rem;
            font-family: var(--font-mono);
            color: var(--app-muted);
            font-style: italic;
            padding: .1rem 0;
            line-height: 1.45;
            opacity: .75;
        }

        .ini-comments-block {
            padding: .2rem 0;
        }

        .ini-unknown {
            font-size: .75rem;
            font-family: var(--font-mono);
            color: var(--app-muted);
            padding: .15rem 0;
            opacity: .6;
        }

        /* Access panel */
        .sftp-access-section {
            margin-bottom: 1.5rem;
        }

        .sftp-access-section-title {
            font-size: .78rem;
            font-weight: 600;
            text-transform: uppercase;
            letter-spacing: .07em;
            color: var(--app-muted);
            margin-bottom: .6rem;
        }

        .sftp-access-server-block {
            margin-bottom: 1.25rem;
            padding: .75rem;
            background: var(--app-surface);
            border: 1px solid var(--app-border);
            border-radius: var(--app-radius-sm);
        }

        .sftp-access-server-name {
            font-size: .85rem;
            font-weight: 600;
            margin-bottom: .5rem;
        }

        .sftp-access-chips {
            display: flex;
            flex-wrap: wrap;
            gap: .35rem;
        }

        .sftp-access-user-rows {
            display: flex;
            flex-direction: column;
            gap: .4rem;
        }

        .sftp-access-user-row {
            display: flex;
            flex-wrap: wrap;
            align-items: center;
            gap: .3rem;
        }

        .sftp-perm-chip {
            display: inline-flex;
            align-items: center;
            padding: .15rem .4rem;
            border-radius: var(--app-radius-xs);
            font-family: var(--font-mono);
            font-size: .6rem;
            font-weight: 600;
            white-space: nowrap;
            cursor: pointer;
            border: 1px solid var(--app-border);
            background: var(--app-surface);
            color: var(--app-muted);
            transition: background .15s, color .15s, border-color .15s;
        }

        .sftp-perm-chip:hover {
            border-color: var(--app-accent);
            color: var(--app-accent);
        }

        .sftp-perm-chip--on {
            background: var(--app-ok-dim, rgba(34,197,94,.12));
            border-color: var(--app-ok);
            color: var(--app-ok);
        }

        .sftp-upload-progress {
            margin-top: .5rem;
            font-size: .8rem;
            color: var(--app-muted);
            font-family: var(--font-mono);
        }

        @media (max-width: 640px) {
            .sftp-listing-header,
            .sftp-listing-row {
                grid-template-columns: 16px 1fr auto;
            }
            .sftp-entry-size,
            .sftp-entry-date { display: none; }
        }

        /* ── End SFTP Browser ────────────────────────────────────────────── */

        /* ── Server dashboard tab bar ────────────────────────────────────── */

        .dashboard-tab-bar {
            display: flex;
            flex-shrink: 0;
            margin: 0;
            padding: .2rem .5rem;
            border-radius: 0;
            border-left: none;
            border-right: none;
            border-top: none;
            box-shadow: none;
            background: var(--app-surface-soft);
            border-bottom: 1px solid var(--app-border);
            overflow-x: auto;
            white-space: nowrap;
        }

        .dashboard-tab-pane {
            display: flex;
            flex-direction: column;
            flex: 1;
            min-height: 0;
            overflow: hidden;
        }

        .dashboard-tab-pane[hidden] {
            display: none;
        }

        .dashboard-tab-pane--rcon {
            padding: .75rem 1rem;
            overflow-y: auto;
        }

        .dashboard-tab-pane--sftp {
            padding: .5rem 0;
            overflow-y: auto;
        }

        /* ── Embedded RCON console ────────────────────────────────────────── */

        .dash-rcon-header {
            display: flex;
            align-items: center;
            gap: .75rem;
            margin-bottom: .5rem;
            flex-wrap: wrap;
        }

        .dash-rcon-server-name {
            font-family: var(--font-mono);
            font-size: .72rem;
            font-weight: 700;
            color: var(--app-text);
        }

        .dash-rcon-server-addr {
            font-family: var(--font-mono);
            font-size: .65rem;
            color: var(--app-muted);
        }

        .dash-rcon-console {
            display: flex;
            flex-direction: column;
            gap: .5rem;
        }

        .dash-rcon-output-wrap {
            border: 1px solid #1a1a1a;
            border-radius: var(--app-radius-xs);
            overflow: hidden;
        }

        .dash-rcon-output {
            height: 280px;
            min-height: 120px;
            max-height: 400px;
            overflow-y: auto;
            font-size: .72rem;
            border-radius: 0;
            border: none;
            margin: 0;
            background: #0a0a0a;
            color: #c8d8e8;
        }

        .dash-rcon-command-row {
            display: flex;
            gap: .5rem;
        }

        .dash-rcon-command-row .rcon-command-input {
            flex: 1;
        }

        .dash-rcon-run-btn {
            flex-shrink: 0;
        }

        /* ── Embedded SFTP browser ────────────────────────────────────────── */

        .dash-sftp-header {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: .75rem;
            padding: .4rem 1rem;
            border-bottom: 1px solid var(--app-border);
            background: var(--app-surface-soft);
            flex-wrap: wrap;
        }

        .dash-sftp-server-name {
            font-family: var(--font-mono);
            font-size: .72rem;
            font-weight: 700;
            color: var(--app-text);
        }

        .dash-sftp-toolbar {
            display: flex;
            gap: .4rem;
            align-items: center;
        }

        .dash-sftp-toolbar-btn {
            font-size: .65rem;
            padding: .3rem .65rem;
            display: flex;
            align-items: center;
            gap: .3rem;
        }

        .dash-sftp-toolbar-btn svg {
            stroke: currentColor;
            fill: none;
            flex-shrink: 0;
        }

        #dashSftpBreadcrumb {
            padding: .4rem 1rem;
        }

        /* ── Shared dashboard empty/info messages ─────────────────────────── */

        .dashboard-empty-msg {
            padding: 1.5rem 1rem;
            color: var(--app-muted);
            font-size: .78rem;
            font-family: var(--font-mono);
        }

        .btn-link {
            background: none;
            border: none;
            color: var(--app-accent);
            cursor: pointer;
            font-family: inherit;
            font-size: inherit;
            padding: 0;
            text-decoration: underline;
        }

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

        /* ── Embedded RCON docs accordion ────────────────────────────────── */

        .dash-rcon-docs {
            margin-top: .75rem;
            border-top: 1px solid #222;
        }

        .dash-rcon-docs-header {
            font-family: var(--font-mono);
            font-size: .58rem;
            font-weight: 700;
            letter-spacing: .1em;
            text-transform: uppercase;
            color: #556;
            padding: .5rem .1rem .25rem;
        }

        .dash-rcon-doc-item {
            border-bottom: 1px solid #1c1c1c;
        }

        .dash-rcon-doc-item summary {
            list-style: none;
        }

        .dash-rcon-doc-item summary::-webkit-details-marker { display: none; }

        .dash-rcon-doc-title {
            display: flex;
            align-items: center;
            gap: .5rem;
            padding: .4rem .2rem;
            font-family: var(--font-mono);
            font-size: .72rem;
            color: #8ab;
            cursor: pointer;
            user-select: none;
            border-radius: 3px;
        }

        .dash-rcon-doc-title:hover { color: #acd; }

        .dash-rcon-doc-title::before {
            content: '▶';
            font-size: .55rem;
            transition: transform .15s;
            flex-shrink: 0;
            color: #445;
        }

        .dash-rcon-doc-item[open] .dash-rcon-doc-title::before {
            transform: rotate(90deg);
        }

        .dash-rcon-doc-global {
            font-size: .58rem;
            color: #556;
            background: #1a1a2e;
            border: 1px solid #2a2a4a;
            border-radius: 3px;
            padding: .1rem .3rem;
            margin-left: auto;
            text-transform: uppercase;
            letter-spacing: .06em;
        }

        .dash-rcon-doc-body {
            padding: .4rem .4rem .6rem 1rem;
            color: #9ab;
            font-size: .75rem;
            line-height: 1.6;
        }

        .dash-rcon-doc-body h1,
        .dash-rcon-doc-body h2,
        .dash-rcon-doc-body h3 {
            color: #bcd;
            font-size: .8rem;
            margin: .5rem 0 .25rem;
        }

        .dash-rcon-doc-body p { margin: .25rem 0; }

        .dash-rcon-doc-body code,
        .dash-rcon-doc-body pre {
            background: #111;
            border: 1px solid #222;
            border-radius: 3px;
            font-family: var(--font-mono);
            font-size: .7rem;
            color: #cde;
        }

        .dash-rcon-doc-body code {
            padding: .1rem .3rem;
        }

        .dash-rcon-doc-body pre {
            padding: .5rem .65rem;
            overflow-x: auto;
            margin: .35rem 0;
            cursor: pointer;
        }

        .dash-rcon-doc-body pre:hover { border-color: #334; }

        .dash-rcon-doc-body ul,
        .dash-rcon-doc-body ol {
            padding-left: 1.25rem;
            margin: .25rem 0;
        }

        /* ── End server dashboard tabs ────────────────────────────────────── */
