@charset "UTF-8";
/* ==========================================================================
   WebOS Manager — Instrument Design System
   --------------------------------------------------------------------------
   One stylesheet. Loaded after Bootstrap 5.3 and re-tokenises it, so every
   existing page inherits the identity without markup churn.

   Identity notes
   - Ground is ink-navy, not black: rack steel under datacentre lighting.
   - The interactive accent is indigo-violet and is NEVER a status colour, so
     a violet control can never be mistaken for "healthy" or "alarm".
   - Status is always carried by four signals at once: bar shape, glyph shape,
     text label and colour. Colour alone never encodes server state.
   - Archivo carries the interface. IBM Plex Mono is reserved for machine data
     you would copy-paste: addresses, ports, PIDs, hashes, byte counts, output.
   ========================================================================== */

/* ==========================================================================
   1. TOKENS
   ========================================================================== */

:root {
  /* -- Type ------------------------------------------------------------- */
  --wos-font-ui: "Archivo", system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --wos-font-mono: "IBM Plex Mono", ui-monospace, "Cascadia Mono", "Consolas", "Liberation Mono", monospace;

  --wos-text-micro: 0.6875rem;   /* 11px  — tally labels, table meta        */
  --wos-text-xs:    0.75rem;     /* 12px                                    */
  --wos-text-sm:    0.8125rem;   /* 13px                                    */
  --wos-text-base:  0.9375rem;   /* 15px  — dense operational body          */
  --wos-text-md:    1.0625rem;   /* 17px  — h3                              */
  --wos-text-lg:    1.25rem;     /* 20px  — h2                              */
  --wos-text-xl:    1.625rem;    /* 26px  — h1                              */
  --wos-text-2xl:   2.125rem;    /* 34px                                    */
  --wos-text-3xl:   2.75rem;     /* 44px                                    */
  --wos-text-4xl:   3.5rem;      /* 56px                                    */

  /* Display sizes are fluid: the operational scale above stays dense, but a
     page that is meant to be read from a distance can speak up. Ratio ~1.28. */
  --wos-display-sm: clamp(1.5rem, 2.2vw, 1.85rem);
  --wos-display-md: clamp(1.85rem, 3.3vw, 2.85rem);
  --wos-display-lg: clamp(2.85rem, 6.1vw, 5.25rem);

  --wos-lh-tight: 1.15;
  --wos-lh-snug: 1.32;
  --wos-lh-body: 1.55;

  /* Optical tracking: tighten display, open up micro copy. */
  --wos-track-display: -0.022em;
  --wos-track-head: -0.012em;
  --wos-track-micro: 0.01em;
  /* Only the fluid display sizes above go this tight; mono numerals never do. */
  --wos-track-tight: -0.038em;

  /* -- Space (4px base) -------------------------------------------------- */
  --wos-s1: 0.25rem;
  --wos-s2: 0.5rem;
  --wos-s3: 0.75rem;
  --wos-s4: 1rem;
  --wos-s5: 1.25rem;
  --wos-s6: 1.5rem;
  --wos-s8: 2rem;
  --wos-s10: 2.5rem;
  --wos-s12: 3rem;
  --wos-s16: 4rem;
  --wos-s20: 5rem;

  /* -- Radius: hierarchy, not one value everywhere ----------------------- */
  --wos-r-data: 3px;    /* tables, code, inputs — machine surfaces are sharp */
  --wos-r-ctl: 6px;     /* buttons, chips                                    */
  --wos-r-card: 10px;   /* cards, panels                                     */
  --wos-r-shell: 14px;  /* modals, palette                                   */
  --wos-r-pill: 999px;

  /* -- Motion ------------------------------------------------------------ */
  --wos-t-fast: 110ms;
  --wos-t: 190ms;
  --wos-t-slow: 320ms;
  --wos-ease: cubic-bezier(0.2, 0.7, 0.3, 1);
  --wos-ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  /* -- Layout ------------------------------------------------------------ */
  --wos-rail: 268px;
  --wos-rail-collapsed: 72px;
  --wos-topbar: 58px;
  --wos-measure: 68ch;

  /* -- Fixed ink on solid fills (same in both themes) -------------------- */
  --wos-on-accent: #ffffff;      /* on --wos-accent #2563eb: 5.17:1       */
  --wos-on-solid: #ffffff;       /* on every --wos-*-solid fill: >= 4.83:1 */
  --wos-on-warn-fill: #0f172a;   /* on --wos-warn-fill #f59e0b: 8.31:1     */

  /* Solid status fills for buttons, filled headers and .bg-* utilities.
     Deliberately identical in both themes so a green "Start" or a red
     "Delete" button never changes meaning or contrast with the theme. */
  --wos-ok-solid: #15803d;       /* white 5.02:1 */
  --wos-warn-solid: #b45309;     /* white 5.02:1 */
  --wos-crit-solid: #dc2626;     /* white 4.83:1 */
  --wos-info-solid: #0369a1;     /* white 5.93:1 */
  --wos-idle-solid: #475569;     /* white 7.58:1 */
  --wos-warn-fill: #f59e0b;      /* light amber fill, carries dark ink     */
  --wos-code-bg: #0b1220;        /* terminal / output panels, both themes  */
  --wos-code-fg: #e2e8f0;        /* 15.6:1 on --wos-code-bg                */
}

/* ==========================================================================
   PALETTE — light theme (default)
   Neutrals are a cool slate, the single interactive accent is blue-600.
   Contrast (WCAG 2.1) measured on --wos-surface #fff / --wos-surface-3:
     fg 17.85 · fg-dim 7.58 / 6.74 · fg-mute 5.89 / 5.24 · accent-ink 6.70
     control border (--wos-ctl) 3.64:1 · focus ring 5.17:1
   ========================================================================== */
:root,
[data-theme="light"] {
  color-scheme: light;

  --wos-bg: #f5f7fb;
  --wos-surface: #ffffff;
  --wos-surface-2: #f8fafc;
  --wos-surface-3: #eef2f7;
  --wos-line: #e2e8f0;           /* decorative dividers                     */
  --wos-line-strong: #cbd5e1;    /* card/table edges                        */
  --wos-ctl: #7a879b;            /* input/checkbox boundaries, >= 3:1       */

  --wos-fg: #0f172a;
  --wos-fg-dim: #475569;
  --wos-fg-mute: #5a6578;
  --wos-fg-invert: #ffffff;

  --wos-accent: #2563eb;
  --wos-accent-hover: #1d4ed8;
  --wos-accent-active: #1e40af;
  --wos-accent-ink: #1d4ed8;     /* links & accent text: 6.70 on white      */
  --wos-accent-ink-hover: #1e40af; /* link hover: 8.72 on white             */
  --wos-accent-wash: #eaf1fe;    /* selected rows, active nav (ink 5.91)    */
  --wos-accent-line: #bfd3fb;

  --wos-focus: #2563eb;
  --wos-selection: #cfe0fd;
  --wos-scrim: rgba(15, 23, 42, 0.45);

  /* Status signal colours (bars, dots, borders: >= 3:1 on white) */
  --wos-ok: #16a34a;
  --wos-warn: #d97706;
  --wos-crit: #dc2626;
  --wos-info: #0284c7;
  --wos-idle: #64748b;
  /* Status text */
  --wos-ok-ink: #166534;         /* 6.76 on its wash */
  --wos-warn-ink: #92400e;       /* 6.68 on its wash */
  --wos-crit-ink: #b91c1c;       /* 5.91 on its wash */
  --wos-info-ink: #075985;       /* 7.09 on its wash */
  --wos-idle-ink: #475569;       /* 6.92 on its wash */
  /* Status tints */
  --wos-ok-wash: #ecfdf3;
  --wos-warn-wash: #fff7ed;
  --wos-crit-wash: #fef2f2;
  --wos-info-wash: #f0f9ff;
  --wos-idle-wash: #f1f5f9;

  --wos-elev-1: 0 1px 2px rgba(15, 23, 42, 0.06);
  --wos-elev-2: 0 1px 2px rgba(15, 23, 42, 0.06), 0 10px 24px -14px rgba(15, 23, 42, 0.25);
  --wos-elev-3: 0 2px 4px rgba(15, 23, 42, 0.06), 0 24px 56px -20px rgba(15, 23, 42, 0.30);
  --wos-inset-hi: inset 0 1px 0 rgba(255, 255, 255, 0.9);

  --wos-grid-line: rgba(15, 23, 42, 0.04);

  /* Server-rendered SVG charts (includes/ChartSvg.php) read these. Series
     colours are >= 3:1 against the card surface (graphical objects). */
  --chart-muted: var(--wos-surface-3);
  --chart-text: var(--wos-fg-dim);
  --chart-1: #2563eb;
  --chart-2: #16a34a;
  --chart-3: #ea580c;
  --chart-4: #dc2626;
  --chart-5: #0891b2;
  --chart-6: #7c3aed;
  --chart-7: #a16207;
  --chart-8: #0d9488;
}

/* ==========================================================================
   PALETTE — dark theme
   Same hues, re-weighted for an ink-navy ground (shared with the public
   landing page: --bg #0a0f1c). Measured on --wos-surface #111a2e / s-3:
     fg 14.77 · fg-dim 9.37 / 8.00 · fg-mute 7.09 / 6.05 · accent-ink 6.82
     control border 3.40:1 · focus ring 6.82:1
   ========================================================================== */
[data-theme="dark"] {
  color-scheme: dark;

  --wos-bg: #0a0f1c;
  --wos-surface: #111a2e;
  --wos-surface-2: #16203a;
  --wos-surface-3: #1c2742;
  --wos-line: #24304d;
  --wos-line-strong: #34426a;
  --wos-ctl: #5d6e93;

  --wos-fg: #e8edf7;
  --wos-fg-dim: #b4bfd4;
  --wos-fg-mute: #9aa6bf;
  --wos-fg-invert: #0a0f1c;

  --wos-accent: #2563eb;         /* button fill: white 5.17:1               */
  --wos-accent-hover: #2b66ec;   /* a touch brighter on dark: white 4.98:1  */
  --wos-accent-active: #1d4ed8;
  --wos-accent-ink: #60a5fa;     /* links & accent text: 6.82 on surface    */
  --wos-accent-ink-hover: #93c5fd; /* link hover: 9.69 on surface           */
  --wos-accent-wash: #172a52;    /* ink on wash 5.55:1                      */
  --wos-accent-line: #2b4a8a;

  --wos-focus: #60a5fa;
  --wos-selection: #1e3a75;
  --wos-scrim: rgba(2, 6, 16, 0.66);

  --wos-ok: #22c55e;
  --wos-warn: #f59e0b;
  --wos-crit: #ef4444;
  --wos-info: #38bdf8;
  --wos-idle: #8592ad;
  --wos-ok-ink: #4ade80;
  --wos-warn-ink: #fbbf24;
  --wos-crit-ink: #f87171;
  --wos-info-ink: #38bdf8;
  --wos-idle-ink: #a5b1c7;
  --wos-ok-wash: #0f2a20;
  --wos-warn-wash: #2d2112;
  --wos-crit-wash: #2e1619;
  --wos-info-wash: #0c2537;
  --wos-idle-wash: #1a2339;

  --wos-elev-1: 0 1px 2px rgba(2, 5, 13, 0.6);
  --wos-elev-2: 0 1px 2px rgba(2, 5, 13, 0.6), 0 12px 28px -16px rgba(2, 5, 13, 0.9);
  --wos-elev-3: 0 2px 6px rgba(2, 5, 13, 0.7), 0 28px 64px -20px rgba(2, 5, 13, 0.95);
  --wos-inset-hi: inset 0 1px 0 rgba(255, 255, 255, 0.035);

  --wos-grid-line: rgba(255, 255, 255, 0.03);

  --chart-muted: #24304d;
  --chart-text: var(--wos-fg-dim);
  --chart-1: #60a5fa;
  --chart-2: #4ade80;
  --chart-3: #fb923c;
  --chart-4: #f87171;
  --chart-5: #22d3ee;
  --chart-6: #a78bfa;
  --chart-7: #facc15;
  --chart-8: #2dd4bf;
}

/* ==========================================================================
   2. BOOTSTRAP RE-TOKENISATION
   Every legacy page uses Bootstrap utilities. Re-point Bootstrap's own custom
   properties so those pages adopt the palette without touching their markup.
   ========================================================================== */

:root,
[data-theme] {
  --bs-body-font-family: var(--wos-font-ui);
  --bs-body-font-size: var(--wos-text-base);
  --bs-body-line-height: var(--wos-lh-body);
  --bs-body-bg: var(--wos-bg);
  --bs-body-color: var(--wos-fg);
  --bs-emphasis-color: var(--wos-fg);
  --bs-secondary-color: var(--wos-fg-dim);
  --bs-tertiary-color: var(--wos-fg-mute);
  --bs-secondary-bg: var(--wos-surface-2);
  --bs-tertiary-bg: var(--wos-surface-3);
  --bs-border-color: var(--wos-line);
  --bs-border-color-translucent: var(--wos-line);
  --bs-heading-color: var(--wos-fg);

  --bs-border-radius: var(--wos-r-card);
  --bs-border-radius-sm: var(--wos-r-data);
  --bs-border-radius-lg: var(--wos-r-shell);
  --bs-border-radius-xl: var(--wos-r-shell);
  --bs-border-radius-pill: var(--wos-r-pill);

  --bs-primary: var(--wos-accent);
  --bs-link-color: var(--wos-accent-ink);
  --bs-link-hover-color: var(--wos-accent-ink-hover);
  --bs-code-color: var(--wos-accent-ink);
  --bs-font-monospace: var(--wos-font-mono);
  --bs-highlight-bg: var(--wos-warn-wash);
  --bs-highlight-color: var(--wos-fg);
  --bs-focus-ring-color: color-mix(in srgb, var(--wos-focus) 35%, transparent);
  --bs-form-valid-color: var(--wos-ok-ink);
  --bs-form-valid-border-color: var(--wos-ok);
  --bs-form-invalid-color: var(--wos-crit-ink);
  --bs-form-invalid-border-color: var(--wos-crit);

  --bs-success: var(--wos-ok-solid);
  --bs-warning: var(--wos-warn-fill);
  --bs-danger: var(--wos-crit-solid);
  --bs-info: var(--wos-info-solid);
  --bs-secondary: var(--wos-idle-solid);
  --bs-light: var(--wos-surface-2);
  --bs-dark: var(--wos-code-bg);

  /* The *-rgb triplets drive .bg-*, .border-*, .text-bg-* and .link-*. They
     must match the solid fills above or those utilities paint stock Bootstrap
     hues that belong to no palette. */
  --bs-primary-rgb: 37, 99, 235;      /* #2563eb */
  --bs-success-rgb: 21, 128, 61;      /* #15803d */
  --bs-danger-rgb: 220, 38, 38;       /* #dc2626 */
  --bs-warning-rgb: 245, 158, 11;     /* #f59e0b */
  --bs-info-rgb: 3, 105, 161;         /* #0369a1 */
  --bs-secondary-rgb: 71, 85, 105;    /* #475569 */
  --bs-dark-rgb: 11, 18, 32;          /* #0b1220 */
  --bs-link-color-rgb: 29, 78, 216;   /* #1d4ed8 */
  --bs-link-hover-color-rgb: 30, 64, 175;

  --bs-primary-text-emphasis: var(--wos-accent-ink);
  --bs-success-text-emphasis: var(--wos-ok-ink);
  --bs-warning-text-emphasis: var(--wos-warn-ink);
  --bs-danger-text-emphasis: var(--wos-crit-ink);
  --bs-info-text-emphasis: var(--wos-info-ink);
  --bs-secondary-text-emphasis: var(--wos-idle-ink);
  --bs-primary-bg-subtle: var(--wos-accent-wash);
  --bs-success-bg-subtle: var(--wos-ok-wash);
  --bs-warning-bg-subtle: var(--wos-warn-wash);
  --bs-danger-bg-subtle: var(--wos-crit-wash);
  --bs-info-bg-subtle: var(--wos-info-wash);
  --bs-secondary-bg-subtle: var(--wos-idle-wash);
  --bs-primary-border-subtle: var(--wos-accent-line);
  --bs-success-border-subtle: color-mix(in srgb, var(--wos-ok) 40%, var(--wos-line));
  --bs-warning-border-subtle: color-mix(in srgb, var(--wos-warn) 40%, var(--wos-line));
  --bs-danger-border-subtle: color-mix(in srgb, var(--wos-crit) 40%, var(--wos-line));
  --bs-info-border-subtle: color-mix(in srgb, var(--wos-info) 40%, var(--wos-line));
  --bs-secondary-border-subtle: var(--wos-line-strong);
}

[data-theme="dark"] {
  --bs-link-color-rgb: 96, 165, 250;   /* #60a5fa */
  --bs-link-hover-color-rgb: 147, 197, 253;
  --bs-body-bg-rgb: 10, 15, 28;
  --bs-body-color-rgb: 232, 237, 247;
}
:root, [data-theme="light"] {
  --bs-body-bg-rgb: 245, 247, 251;
  --bs-body-color-rgb: 15, 23, 42;
}

/* Legacy `.bg-light` / `.bg-white` / `.text-dark` in old markup must not punch
   white holes through a dark console. Re-map them to real surfaces. */
.bg-light { background-color: var(--wos-surface-2) !important; }
.bg-white { background-color: var(--wos-surface) !important; }
.bg-body,
.bg-body-tertiary { background-color: var(--wos-surface-2) !important; }
.text-dark { color: var(--wos-fg) !important; }
.text-muted,
.text-body-secondary { color: var(--wos-fg-dim) !important; }

/* Solid fills. Whatever sits on them reads white, unless markup asks for a
   specific .text-* colour (those are !important and win). */
.bg-primary, .bg-success, .bg-danger, .bg-info, .bg-secondary, .bg-dark,
.text-bg-primary, .text-bg-success, .text-bg-danger, .text-bg-info, .text-bg-secondary { color: var(--wos-on-solid); }
.text-bg-primary { background-color: var(--wos-accent) !important; color: var(--wos-on-accent) !important; }
.text-bg-success { background-color: var(--wos-ok-solid) !important; color: var(--wos-on-solid) !important; }
.text-bg-danger  { background-color: var(--wos-crit-solid) !important; color: var(--wos-on-solid) !important; }
.text-bg-info    { background-color: var(--wos-info-solid) !important; color: var(--wos-on-solid) !important; }

/* Legacy gradient utilities used by a few KPI cards. */
.bg-gradient-primary { background: linear-gradient(135deg, var(--wos-accent), var(--wos-accent-active)) !important; color: var(--wos-on-accent); }
.bg-gradient-success { background: linear-gradient(135deg, var(--wos-ok-solid), #166534) !important; color: var(--wos-on-solid); }
.bg-gradient-info    { background: linear-gradient(135deg, var(--wos-info-solid), #075985) !important; color: var(--wos-on-solid); }
.bg-gradient-warning { background: linear-gradient(135deg, var(--wos-warn-solid), #92400e) !important; color: var(--wos-on-solid); }
.bg-gradient-danger  { background: linear-gradient(135deg, var(--wos-crit-solid), #991b1b) !important; color: var(--wos-on-solid); }

/* `.text-white` is real white only where there is a solid fill underneath.
   Old markup also puts it on plain cards, where white-on-white was invisible,
   so outside a fill it falls back to the body ink. */
.text-white { color: var(--wos-fg) !important; }
:is(.bg-primary, .bg-success, .bg-danger, .bg-info, .bg-secondary, .bg-dark,
    .bg-gradient-primary, .bg-gradient-success, .bg-gradient-info, .bg-gradient-warning, .bg-gradient-danger,
    .btn-primary, .btn-success, .btn-danger, .btn-info, .btn-warning).text-white,
:is(.bg-primary, .bg-success, .bg-danger, .bg-info, .bg-secondary, .bg-dark,
    .bg-gradient-primary, .bg-gradient-success, .bg-gradient-info, .bg-gradient-warning, .bg-gradient-danger) .text-white {
  color: #ffffff !important;
}
.text-white-50 { color: var(--wos-fg-mute) !important; }
:is(.bg-primary, .bg-success, .bg-danger, .bg-info, .bg-secondary, .bg-dark,
    .bg-gradient-primary, .bg-gradient-success, .bg-gradient-info, .bg-gradient-warning, .bg-gradient-danger) .text-white-50 {
  color: rgba(255, 255, 255, 0.86) !important;
}

/* A heading inside a filled block takes the block's colour, not body ink. */
.text-white h1, .text-white h2, .text-white h3,
.text-white h4, .text-white h5, .text-white h6,
.text-white .h1, .text-white .h2, .text-white .h3,
.text-white .h4, .text-white .h5, .text-white .h6,
.text-light h1, .text-light h2, .text-light h3,
.text-light h4, .text-light h5, .text-light h6,
:is(.bg-primary, .bg-success, .bg-danger, .bg-info, .bg-secondary, .bg-dark,
    .bg-gradient-primary, .bg-gradient-success, .bg-gradient-info, .bg-gradient-warning, .bg-gradient-danger) :is(h1, h2, h3, h4, h5, h6) { color: inherit; }

/* Amber is the one light fill: it carries dark ink (8.31:1) in both themes.
   Declared after .text-white so it wins on `.bg-warning.text-white`. */
.bg-warning, .text-bg-warning { background-color: var(--wos-warn-fill) !important; color: var(--wos-on-warn-fill) !important; }
.bg-warning h1, .bg-warning h2, .bg-warning h3,
.bg-warning h4, .bg-warning h5, .bg-warning h6,
.bg-warning .text-dark, .bg-warning .text-muted, .bg-warning .text-white,
.bg-warning small, .bg-warning a { color: inherit !important; }

/* Bootstrap's `.text-*` utilities read --bs-*-rgb (the solid fills), which are
   too dark for text on the dark theme. Text uses the *-ink variants, AA on
   every surface of both themes. */
.text-primary { color: var(--wos-accent-ink) !important; }
.text-info { color: var(--wos-info-ink) !important; }
.text-success { color: var(--wos-ok-ink) !important; }
.text-warning { color: var(--wos-warn-ink) !important; }
.text-danger { color: var(--wos-crit-ink) !important; }
.text-secondary { color: var(--wos-fg-dim) !important; }

/* Subtle tints (`bg-* bg-opacity-10`) keep the hue but read the right ink. */
.bg-opacity-10.bg-primary { background-color: var(--wos-accent-wash) !important; color: var(--wos-accent-ink); }
.bg-opacity-10.bg-success { background-color: var(--wos-ok-wash) !important; color: var(--wos-ok-ink); }
.bg-opacity-10.bg-danger  { background-color: var(--wos-crit-wash) !important; color: var(--wos-crit-ink); }
.bg-opacity-10.bg-warning { background-color: var(--wos-warn-wash) !important; color: var(--wos-warn-ink) !important; }
.bg-opacity-10.bg-info    { background-color: var(--wos-info-wash) !important; color: var(--wos-info-ink); }
.bg-opacity-10.bg-secondary { background-color: var(--wos-idle-wash) !important; color: var(--wos-idle-ink); }

/* Terminal / output panels (`.bg-dark .text-light`): one dark code surface in
   both themes, light ink 15.6:1. Generic <code> chips inside inherit. */
.bg-dark { background-color: var(--wos-code-bg) !important; color: var(--wos-code-fg); }
.text-light { color: var(--wos-code-fg) !important; }
.bg-dark pre,
.bg-dark code,
.bg-dark pre code { background: transparent; border: 0; color: inherit; }

.border { border-color: var(--wos-line) !important; }
.border-top { border-top-color: var(--wos-line) !important; }
.border-bottom { border-bottom-color: var(--wos-line) !important; }
.border-start { border-left-color: var(--wos-line) !important; }
.border-end { border-right-color: var(--wos-line) !important; }
.border-secondary { border-color: var(--wos-line-strong) !important; }
.border-primary { border-color: var(--wos-accent) !important; }
.border-success { border-color: var(--wos-ok) !important; }
.border-danger { border-color: var(--wos-crit) !important; }
.border-warning { border-color: var(--wos-warn) !important; }
.border-info { border-color: var(--wos-info) !important; }
.shadow-sm { box-shadow: var(--wos-elev-1) !important; }
.shadow { box-shadow: var(--wos-elev-2) !important; }
.shadow-lg { box-shadow: var(--wos-elev-3) !important; }

/* ==========================================================================
   3. BASE
   ========================================================================== */

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

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

body {
  margin: 0;
  min-height: 100vh;
  background-color: var(--wos-bg);
  color: var(--wos-fg);
  font-family: var(--wos-font-ui);
  font-size: var(--wos-text-base);
  line-height: var(--wos-lh-body);
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* No page-level horizontal scroll at any width. */
  overflow-x: clip;
}

::selection { background: var(--wos-selection); color: var(--wos-fg); }

h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
  font-family: var(--wos-font-ui);
  color: var(--wos-fg);
  font-weight: 600;
  line-height: var(--wos-lh-snug);
  letter-spacing: var(--wos-track-head);
  margin-top: 0;
}

h1, .h1 { font-size: var(--wos-text-xl); }
h2, .h2 { font-size: var(--wos-text-lg); }
h3, .h3 { font-size: var(--wos-text-md); }
h4, .h4 { font-size: var(--wos-text-base); }
h5, .h5, h6, .h6 { font-size: var(--wos-text-sm); }

p { max-width: var(--wos-measure); }

a { color: var(--wos-accent-ink); text-decoration-thickness: 1px; text-underline-offset: 0.18em; }
a:hover { color: var(--wos-accent-ink-hover); }

hr { border-color: var(--wos-line); opacity: 1; }

img, svg, video, canvas { max-width: 100%; height: auto; }

/* Machine data. Mono is informational here: "this is a value you can copy." */
code, kbd, samp, pre, .mono, .wos-mono {
  font-family: var(--wos-font-mono);
  font-variant-ligatures: none;
  font-size: 0.92em;
}

code {
  background: var(--wos-surface-3);
  border: 1px solid var(--wos-line);
  border-radius: var(--wos-r-data);
  padding: 0.1em 0.36em;
  color: var(--wos-fg);
}

pre {
  background: var(--wos-surface-3);
  border: 1px solid var(--wos-line);
  border-radius: var(--wos-r-data);
  padding: var(--wos-s4);
  overflow-x: auto;
  max-width: 100%;
}

kbd {
  font-family: var(--wos-font-mono);
  font-size: var(--wos-text-micro);
  background: var(--wos-surface-3);
  border: 1px solid var(--wos-line-strong);
  border-bottom-width: 2px;
  border-radius: var(--wos-r-data);
  padding: 0.12em 0.4em;
  color: var(--wos-fg-dim);
}

/* Tabular numerals everywhere a number can change in place. */
.wos-num,
td.wos-num,
.metric-value,
.stat-big,
.wos-stat__value { font-variant-numeric: tabular-nums; }

/* ==========================================================================
   4. FOCUS & SKIP LINK  (WCAG 2.1 AA — 2.4.7, 2.4.1)
   ========================================================================== */

:focus { outline: none; }

:focus-visible,
.btn:focus-visible,
.form-control:focus-visible,
.form-select:focus-visible,
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--wos-focus);
  outline-offset: 2px;
  border-radius: var(--wos-r-data);
}

/* Bootstrap's own ring, restated in the palette. */
.form-control:focus,
.form-select:focus,
.form-check-input:focus {
  border-color: var(--wos-accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--wos-accent) 26%, transparent);
}

.wos-skip {
  position: absolute;
  left: var(--wos-s4);
  top: -100px;
  z-index: 2000;
  padding: var(--wos-s3) var(--wos-s5);
  background: var(--wos-accent);
  color: var(--wos-on-accent);
  border-radius: var(--wos-r-ctl);
  font-weight: 600;
  text-decoration: none;
  box-shadow: var(--wos-elev-3);
  transition: top var(--wos-t) var(--wos-ease);
}
.wos-skip:focus {
  top: var(--wos-s4);
  color: var(--wos-on-accent);
}

/* ==========================================================================
   5. THE STATE TALLY — the signature component
   Four simultaneous signals: bar pattern, glyph shape, text, colour.
   Never colour alone (WCAG 1.4.1 Use of Colour).
   ========================================================================== */

.tally {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.18rem 0.5rem 0.18rem 0.3rem;
  border: 1px solid var(--wos-line);
  border-radius: var(--wos-r-ctl);
  background: var(--wos-surface-2);
  font-size: var(--wos-text-micro);
  font-weight: 600;
  letter-spacing: var(--wos-track-micro);
  line-height: 1.4;
  white-space: nowrap;
  vertical-align: middle;
}

.tally__bar {
  flex: 0 0 auto;
  width: 4px;
  height: 14px;
  border-radius: 1px;
  background: currentColor;
}

.tally__glyph {
  font-size: 0.7em;
  line-height: 1;
  transform: translateY(-0.5px);
}

.tally__label { color: var(--wos-fg); }

/* -- Online: solid bar, filled disc ------------------------------------- */
.tally--ok { color: var(--wos-ok-ink); border-color: color-mix(in srgb, var(--wos-ok) 42%, var(--wos-line)); background: var(--wos-ok-wash); }
.tally--ok .tally__bar { background: var(--wos-ok); }

/* -- Warning: half-height bar, triangle --------------------------------- */
.tally--warn { color: var(--wos-warn-ink); border-color: color-mix(in srgb, var(--wos-warn) 42%, var(--wos-line)); background: var(--wos-warn-wash); }
.tally--warn .tally__bar {
  background: linear-gradient(to top, var(--wos-warn) 0 55%, color-mix(in srgb, var(--wos-warn) 22%, transparent) 55% 100%);
}

/* -- Critical / offline: hatched bar, square ---------------------------- */
.tally--crit { color: var(--wos-crit-ink); border-color: color-mix(in srgb, var(--wos-crit) 42%, var(--wos-line)); background: var(--wos-crit-wash); }
.tally--crit .tally__bar {
  background: repeating-linear-gradient(
    135deg,
    var(--wos-crit) 0 2px,
    color-mix(in srgb, var(--wos-crit) 25%, transparent) 2px 4px
  );
}

/* -- Unknown / idle: dotted bar, dash ----------------------------------- */
.tally--idle { color: var(--wos-idle-ink); border-color: var(--wos-line); background: var(--wos-idle-wash); }
.tally--idle .tally__bar {
  background: repeating-linear-gradient(
    to bottom,
    var(--wos-idle) 0 2px,
    transparent 2px 4px
  );
}

/* Compact tally for table cells. */
.tally--sm { padding: 0.08rem 0.4rem 0.08rem 0.22rem; font-size: 10px; }
.tally--sm .tally__bar { height: 11px; width: 3px; }

/* A live server pulses its bar; stopped states never move. */
@media (prefers-reduced-motion: no-preference) {
  .tally--ok.is-live .tally__bar { animation: wos-pulse 2.4s var(--wos-ease) infinite; }
}
@keyframes wos-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

/* Legacy status dots in old markup get the same discipline. */
.status-dot, .led, .dot.status {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--wos-idle);
  border: 1px solid color-mix(in srgb, var(--wos-fg) 20%, transparent);
  vertical-align: middle;
}
.status-dot.online, .led.online, .led.on { background: var(--wos-ok); }
.status-dot.offline, .led.offline, .led.off { background: var(--wos-crit); border-radius: 1px; }
.status-dot.warning, .led.warning { background: var(--wos-warn); clip-path: polygon(50% 0, 100% 100%, 0 100%); border-radius: 0; }

/* ==========================================================================
   6. BUTTONS
   ========================================================================== */

/* -- Standalone base -----------------------------------------------------
   The public page and the sign-in screen load this stylesheet WITHOUT
   Bootstrap, so the components they use must stand on their own. These rules
   read the same --bs-btn-* custom properties Bootstrap uses, which means the
   two agree wherever both are present and this file is sufficient where
   Bootstrap is absent. */
.btn {
  --bs-btn-bg: transparent;
  --bs-btn-color: var(--wos-fg);
  --bs-btn-border-color: transparent;
  --bs-btn-hover-bg: var(--wos-surface-3);
  --bs-btn-hover-color: var(--wos-fg);
  --bs-btn-hover-border-color: transparent;

  padding: var(--bs-btn-padding-y, 0.44rem) var(--bs-btn-padding-x, 0.85rem);
  background-color: var(--bs-btn-bg);
  color: var(--bs-btn-color);
  border: 1px solid var(--bs-btn-border-color);
  border-radius: var(--bs-btn-border-radius, var(--wos-r-ctl));
  font-family: var(--bs-btn-font-family, var(--wos-font-ui));
  font-size: var(--bs-btn-font-size, var(--wos-text-sm));
  font-weight: var(--bs-btn-font-weight, 600);
  line-height: var(--bs-btn-line-height, 1.45);
  text-align: center;
  text-decoration: none;
  vertical-align: middle;
  cursor: pointer;
  user-select: none;
}
.btn:hover {
  background-color: var(--bs-btn-hover-bg);
  color: var(--bs-btn-hover-color);
  border-color: var(--bs-btn-hover-border-color);
}
.btn:active {
  background-color: var(--bs-btn-active-bg, var(--bs-btn-hover-bg));
  color: var(--bs-btn-active-color, var(--bs-btn-hover-color));
  border-color: var(--bs-btn-active-border-color, var(--bs-btn-hover-border-color));
}

.btn {
  --bs-btn-font-family: var(--wos-font-ui);
  --bs-btn-font-size: var(--wos-text-sm);
  --bs-btn-font-weight: 600;
  --bs-btn-border-radius: var(--wos-r-ctl);
  --bs-btn-padding-y: 0.44rem;
  --bs-btn-padding-x: 0.85rem;
  --bs-btn-line-height: 1.45;
  letter-spacing: 0.002em;
  transition: background-color var(--wos-t-fast) var(--wos-ease),
              border-color var(--wos-t-fast) var(--wos-ease),
              color var(--wos-t-fast) var(--wos-ease),
              box-shadow var(--wos-t-fast) var(--wos-ease),
              transform var(--wos-t-fast) var(--wos-ease);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
}

.btn:active { transform: translateY(1px); }
.btn:disabled, .btn.disabled { opacity: 0.5; cursor: not-allowed; }

.btn-lg { --bs-btn-font-size: var(--wos-text-base); --bs-btn-padding-y: 0.62rem; --bs-btn-padding-x: 1.15rem; }
.btn-sm { --bs-btn-font-size: var(--wos-text-xs); --bs-btn-padding-y: 0.28rem; --bs-btn-padding-x: 0.6rem; }

.btn-primary {
  --bs-btn-bg: var(--wos-accent);
  --bs-btn-border-color: var(--wos-accent);
  --bs-btn-color: var(--wos-on-accent);
  --bs-btn-hover-bg: var(--wos-accent-hover);
  --bs-btn-hover-border-color: var(--wos-accent-hover);
  --bs-btn-hover-color: var(--wos-on-accent);
  --bs-btn-active-bg: var(--wos-accent-active);
  --bs-btn-active-border-color: var(--wos-accent-active);
  --bs-btn-active-color: var(--wos-on-accent);
  --bs-btn-disabled-bg: var(--wos-accent);
  --bs-btn-disabled-border-color: var(--wos-accent);
  --bs-btn-disabled-color: var(--wos-on-accent);
  box-shadow: var(--wos-inset-hi);
}

.btn-secondary,
.btn-light,
.btn-outline-secondary {
  --bs-btn-bg: var(--wos-surface);
  --bs-btn-border-color: var(--wos-line-strong);
  --bs-btn-color: var(--wos-fg);
  --bs-btn-hover-bg: var(--wos-surface-3);
  --bs-btn-hover-border-color: var(--wos-line-strong);
  --bs-btn-hover-color: var(--wos-fg);
  --bs-btn-active-bg: var(--wos-surface-3);
  --bs-btn-active-border-color: var(--wos-line-strong);
  --bs-btn-active-color: var(--wos-fg);
  --bs-btn-disabled-bg: var(--wos-surface);
  --bs-btn-disabled-border-color: var(--wos-line);
  --bs-btn-disabled-color: var(--wos-fg-mute);
}

.btn-outline-primary {
  --bs-btn-color: var(--wos-accent-ink);
  --bs-btn-border-color: var(--wos-accent-line);
  --bs-btn-bg: transparent;
  --bs-btn-hover-bg: var(--wos-accent-wash);
  --bs-btn-hover-border-color: var(--wos-accent);
  --bs-btn-hover-color: var(--wos-accent-ink);
  --bs-btn-active-bg: var(--wos-accent-wash);
  --bs-btn-active-color: var(--wos-accent-ink);
  --bs-btn-active-border-color: var(--wos-accent);
}

.btn-success, .btn-warning, .btn-danger, .btn-info {
  --bs-btn-color: var(--wos-on-solid);
  --bs-btn-hover-color: var(--wos-on-solid);
  --bs-btn-active-color: var(--wos-on-solid);
  --bs-btn-disabled-color: var(--wos-on-solid);
  --bs-btn-border-color: var(--bs-btn-bg);
  --bs-btn-hover-border-color: var(--bs-btn-hover-bg);
  --bs-btn-active-border-color: var(--bs-btn-active-bg);
  --bs-btn-disabled-bg: var(--bs-btn-bg);
  --bs-btn-disabled-border-color: var(--bs-btn-bg);
}
.btn-success { --bs-btn-bg: var(--wos-ok-solid);   --bs-btn-hover-bg: #166534; --bs-btn-active-bg: #14532d; }
.btn-warning { --bs-btn-bg: var(--wos-warn-solid); --bs-btn-hover-bg: #92400e; --bs-btn-active-bg: #78350f; }
.btn-danger  { --bs-btn-bg: var(--wos-crit-solid); --bs-btn-hover-bg: #b91c1c; --bs-btn-active-bg: #991b1b; }
.btn-info    { --bs-btn-bg: var(--wos-info-solid); --bs-btn-hover-bg: #075985; --bs-btn-active-bg: #0c4a6e; }

.btn-outline-success { --bs-btn-color: var(--wos-ok-ink); --bs-btn-border-color: color-mix(in srgb, var(--wos-ok) 45%, var(--wos-line)); --bs-btn-hover-bg: var(--wos-ok-wash); --bs-btn-hover-color: var(--wos-ok-ink); --bs-btn-hover-border-color: var(--wos-ok); --bs-btn-active-bg: var(--wos-ok-wash); --bs-btn-active-color: var(--wos-ok-ink); }
.btn-outline-warning { --bs-btn-color: var(--wos-warn-ink); --bs-btn-border-color: color-mix(in srgb, var(--wos-warn) 45%, var(--wos-line)); --bs-btn-hover-bg: var(--wos-warn-wash); --bs-btn-hover-color: var(--wos-warn-ink); --bs-btn-hover-border-color: var(--wos-warn); --bs-btn-active-bg: var(--wos-warn-wash); --bs-btn-active-color: var(--wos-warn-ink); }
.btn-outline-danger  { --bs-btn-color: var(--wos-crit-ink); --bs-btn-border-color: color-mix(in srgb, var(--wos-crit) 45%, var(--wos-line)); --bs-btn-hover-bg: var(--wos-crit-wash); --bs-btn-hover-color: var(--wos-crit-ink); --bs-btn-hover-border-color: var(--wos-crit); --bs-btn-active-bg: var(--wos-crit-wash); --bs-btn-active-color: var(--wos-crit-ink); }
.btn-outline-info    { --bs-btn-color: var(--wos-info-ink); --bs-btn-border-color: color-mix(in srgb, var(--wos-info) 45%, var(--wos-line)); --bs-btn-hover-bg: var(--wos-info-wash); --bs-btn-hover-color: var(--wos-info-ink); --bs-btn-hover-border-color: var(--wos-info); --bs-btn-active-bg: var(--wos-info-wash); --bs-btn-active-color: var(--wos-info-ink); }
.btn-outline-light   { --bs-btn-color: var(--wos-fg); --bs-btn-border-color: var(--wos-line-strong); --bs-btn-hover-bg: var(--wos-surface-3); --bs-btn-hover-color: var(--wos-fg); --bs-btn-hover-border-color: var(--wos-line-strong); }
.btn-outline-dark    { --bs-btn-color: var(--wos-fg); --bs-btn-border-color: var(--wos-line-strong); --bs-btn-hover-bg: var(--wos-surface-3); --bs-btn-hover-color: var(--wos-fg); --bs-btn-hover-border-color: var(--wos-line-strong); }

.btn-link {
  --bs-btn-color: var(--wos-accent-ink);
  --bs-btn-hover-color: var(--wos-accent-ink-hover);
  --bs-btn-active-color: var(--wos-accent-ink-hover);
  --bs-btn-hover-bg: transparent;
  --bs-btn-disabled-color: var(--wos-fg-mute);
  text-decoration: none;
}

/* Ghost: a quiet toolbar action. Text-only until hovered. */
.btn-ghost {
  --bs-btn-bg: transparent;
  --bs-btn-border-color: transparent;
  --bs-btn-color: var(--wos-fg-dim);
  --bs-btn-hover-bg: var(--wos-surface-3);
  --bs-btn-hover-border-color: transparent;
  --bs-btn-hover-color: var(--wos-fg);
  --bs-btn-active-bg: var(--wos-accent-wash);
  --bs-btn-active-color: var(--wos-accent-ink);
}

/* Selected / pressed toggles read as the accent, never as a status. */
.btn-check:checked + .btn,
.btn.active,
.btn[aria-pressed="true"]:not([data-wos-theme-toggle]) {
  background-color: var(--wos-accent-wash);
  border-color: var(--wos-accent);
  color: var(--wos-accent-ink);
}
.btn-primary.active, .btn-check:checked + .btn-primary { background-color: var(--wos-accent-active); color: var(--wos-on-accent); }

/* Destructive actions carry a hairline warning edge so they never read as
   routine in a dense toolbar. */
.btn-danger::after,
.btn-outline-danger::after { content: none; }

/* Button showing a running operation. */
.btn.is-busy { pointer-events: none; position: relative; color: transparent !important; }
.btn.is-busy::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 1em;
  height: 1em;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  color: var(--bs-btn-color);
  animation: wos-spin 620ms linear infinite;
}
.btn-primary.is-busy::after, .btn-danger.is-busy::after, .btn-success.is-busy::after,
.btn-warning.is-busy::after, .btn-info.is-busy::after { color: var(--wos-on-solid); }

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

/* ==========================================================================
   7. FORMS
   ========================================================================== */

/* display/width are stated here rather than inherited from Bootstrap: the
   public page and the sign-in screen load this file on its own, and without
   them a <label> sits inline on top of its field and an <input> keeps its
   default intrinsic width. */
.form-label {
  display: block;
  font-size: var(--wos-text-sm);
  font-weight: 600;
  color: var(--wos-fg);
  margin-bottom: 0.3rem;
}

.form-control,
.form-select {
  display: block;
  width: 100%;
  max-width: 100%;
}

.form-control,
.form-select,
.input-group-text {
  background-color: var(--wos-surface);
  border: 1px solid var(--wos-ctl);
  border-radius: var(--wos-r-data);
  color: var(--wos-fg);
  font-size: var(--wos-text-base);
  padding: 0.46rem 0.7rem;
  transition: border-color var(--wos-t-fast) var(--wos-ease), box-shadow var(--wos-t-fast) var(--wos-ease);
}

.form-control::placeholder { color: var(--wos-fg-mute); opacity: 1; }
.form-control:disabled, .form-select:disabled { background-color: var(--wos-surface-3); color: var(--wos-fg-mute); }

.input-group-text { background-color: var(--wos-surface-3); color: var(--wos-fg-dim); }
.form-control:hover:not(:disabled):not(:focus), .form-select:hover:not(:disabled):not(:focus) { border-color: var(--wos-fg-mute); }

.form-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%235a6578' stroke-width='1.8' stroke-linecap='round'%3E%3Cpath d='M4 6.5 8 10.5l4-4'/%3E%3C/svg%3E");
  background-size: 15px;
}
[data-theme="dark"] .form-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%239aa6bf' stroke-width='1.8' stroke-linecap='round'%3E%3Cpath d='M4 6.5 8 10.5l4-4'/%3E%3C/svg%3E");
}

textarea.form-control { min-height: 6rem; line-height: 1.5; }
textarea.form-control.mono, textarea.wos-code { font-family: var(--wos-font-mono); font-size: var(--wos-text-sm); }

/* Checkbox and radio, self-contained for the Bootstrap-less pages. */
.form-check { display: flex; align-items: center; gap: 0.5rem; min-height: 1.4rem; }
.form-check-input {
  appearance: none;
  -webkit-appearance: none;
  flex: 0 0 auto;
  width: 1rem;
  height: 1rem;
  margin: 0;
  background-color: var(--wos-surface);
  border: 1px solid var(--wos-ctl);
  border-radius: var(--wos-r-data);
  background-repeat: no-repeat;
  background-position: center;
  background-size: 0.72rem;
  cursor: pointer;
  transition: background-color var(--wos-t-fast) var(--wos-ease), border-color var(--wos-t-fast) var(--wos-ease);
}
.form-check-input[type="radio"] { border-radius: 50%; }
.form-check-input:checked {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 8.5 6.5 11.5 12.5 4.5'/%3E%3C/svg%3E");
}
.form-check-input[type="radio"]:checked {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='3.5' fill='%23fff'/%3E%3C/svg%3E");
}

.form-check-input {
  background-color: var(--wos-surface);
  border-color: var(--wos-ctl);
}
.form-check-input:disabled { opacity: 0.5; cursor: not-allowed; }
.form-switch .form-check-input:not(:checked) { --bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%237a879b'/%3e%3c/svg%3e"); }
.form-check-input:checked {
  background-color: var(--wos-accent);
  border-color: var(--wos-accent);
}
.form-check-label { color: var(--wos-fg); font-size: var(--wos-text-sm); }

.form-text, .field-hint {
  display: block;
  font-size: var(--wos-text-xs);
  color: var(--wos-fg-dim);
  margin-top: 0.3rem;
  max-width: 56ch;
}

.required-field::after,
.form-label.required::after {
  content: "*";
  color: var(--wos-crit-ink);
  margin-left: 0.22em;
  font-weight: 700;
}

.optional-badge {
  font-size: var(--wos-text-micro);
  font-weight: 600;
  color: var(--wos-fg-mute);
  border: 1px solid var(--wos-line);
  border-radius: var(--wos-r-pill);
  padding: 0.02rem 0.42rem;
  margin-left: 0.4rem;
  vertical-align: middle;
}

.is-invalid, .form-control.is-invalid, .form-select.is-invalid { border-color: var(--wos-crit) !important; }
.invalid-feedback, .form-error, .error { color: var(--wos-crit-ink); font-size: var(--wos-text-xs); }
.is-valid, .form-control.is-valid { border-color: var(--wos-ok) !important; }

/* iOS zooms any input under 16px on focus. Keep the visual size but stop the
   zoom by bumping only on coarse pointers. */
@media (max-width: 767.98px) {
  .form-control, .form-select, textarea.form-control { font-size: 16px; }
}

/* ==========================================================================
   8. CARDS & PANELS
   ========================================================================== */

.card,
.wos-card,
.panel {
  --bs-card-bg: var(--wos-surface);
  --bs-card-border-color: var(--wos-line);
  --bs-card-border-radius: var(--wos-r-card);
  --bs-card-inner-border-radius: calc(var(--wos-r-card) - 1px);
  --bs-card-cap-bg: var(--wos-surface-2);
  --bs-card-color: var(--wos-fg);
  --bs-card-spacer-y: var(--wos-s5);
  --bs-card-spacer-x: var(--wos-s5);
  background-color: var(--wos-surface);
  border: 1px solid var(--wos-line);
  border-radius: var(--wos-r-card);
  box-shadow: var(--wos-elev-1), var(--wos-inset-hi);
}

.card-header,
.panel-header,
.wizard-panel-header {
  background-color: var(--wos-surface-2);
  border-bottom: 1px solid var(--wos-line);
  color: var(--wos-fg);
  font-weight: 600;
  font-size: var(--wos-text-sm);
  padding: var(--wos-s3) var(--wos-s5);
  display: flex;
  align-items: center;
  gap: var(--wos-s3);
  flex-wrap: wrap;
}

.card-footer { background-color: var(--wos-surface-2); border-top: 1px solid var(--wos-line); }
.card-body, .panel-body, .wizard-panel-body { padding: var(--wos-s5); }
.card-title { font-size: var(--wos-text-md); margin-bottom: var(--wos-s2); }

/* A card that is an interactive target earns motion; a static one does not. */
a.card, .card.is-actionable, .wos-card--link {
  text-decoration: none;
  transition: border-color var(--wos-t) var(--wos-ease), transform var(--wos-t) var(--wos-ease), box-shadow var(--wos-t) var(--wos-ease);
}
a.card:hover, .card.is-actionable:hover, .wos-card--link:hover {
  border-color: var(--wos-accent-line);
  transform: translateY(-2px);
  box-shadow: var(--wos-elev-2);
}

/* -- Stat tile: the number is the content, the label is the caption ------ */
.wos-stat,
.stat-card {
  position: relative;
  background: var(--wos-surface);
  border: 1px solid var(--wos-line);
  border-radius: var(--wos-r-card);
  padding: var(--wos-s4) var(--wos-s5);
  box-shadow: var(--wos-elev-1), var(--wos-inset-hi);
  overflow: hidden;
}

/* Left edge carries the state. */
.wos-stat::before,
.stat-card::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--wos-line-strong);
}
.wos-stat--ok::before, .stat-card.ok::before { background: var(--wos-ok); }
.wos-stat--warn::before, .stat-card.warning::before { background: var(--wos-warn); }
.wos-stat--crit::before, .stat-card.critical::before { background: var(--wos-crit); }
.wos-stat--accent::before { background: var(--wos-accent); }

.wos-stat__label,
.stat-card .label {
  display: block;
  font-size: var(--wos-text-xs);
  color: var(--wos-fg-dim);
  font-weight: 500;
  margin-bottom: 0.15rem;
}

.wos-stat__value,
.stat-big,
.stat-card .val {
  display: block;
  font-family: var(--wos-font-mono);
  font-size: var(--wos-text-2xl);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: var(--wos-track-display);
  color: var(--wos-fg);
  font-variant-numeric: tabular-nums;
}

.wos-stat__unit { font-size: 0.5em; color: var(--wos-fg-mute); font-weight: 500; margin-left: 0.15em; }
.wos-stat__meta { font-size: var(--wos-text-xs); color: var(--wos-fg-mute); margin-top: 0.25rem; }

.stat-badge {
  font-size: var(--wos-text-micro);
  font-weight: 600;
  padding: 0.1rem 0.4rem;
  border-radius: var(--wos-r-pill);
  background: var(--wos-surface-3);
  color: var(--wos-fg-dim);
}

/* ==========================================================================
   9. BADGES & CHIPS
   ========================================================================== */

.badge {
  font-family: var(--wos-font-ui);
  font-size: var(--wos-text-micro);
  font-weight: 600;
  letter-spacing: var(--wos-track-micro);
  padding: 0.24em 0.55em;
  border-radius: var(--wos-r-ctl);
  border: 1px solid transparent;
  vertical-align: middle;
}

/* Badges are tinted, not saturated blocks — colour stays available for state. */
.badge.bg-success   { background: var(--wos-ok-wash) !important;   color: var(--wos-ok-ink) !important;   border-color: color-mix(in srgb, var(--wos-ok) 38%, var(--wos-line)); }
.badge.bg-warning   { background: var(--wos-warn-wash) !important; color: var(--wos-warn-ink) !important; border-color: color-mix(in srgb, var(--wos-warn) 38%, var(--wos-line)); }
.badge.bg-danger    { background: var(--wos-crit-wash) !important; color: var(--wos-crit-ink) !important; border-color: color-mix(in srgb, var(--wos-crit) 38%, var(--wos-line)); }
.badge.bg-info      { background: var(--wos-info-wash) !important; color: var(--wos-info-ink) !important; border-color: color-mix(in srgb, var(--wos-info) 38%, var(--wos-line)); }
.badge.bg-primary   { background: var(--wos-accent-wash) !important; color: var(--wos-accent-ink) !important; border-color: var(--wos-accent-line); }
.badge.bg-secondary { background: var(--wos-idle-wash) !important; color: var(--wos-idle-ink) !important;  border-color: var(--wos-line); }
.badge.bg-light     { background: var(--wos-surface-3) !important; color: var(--wos-fg-dim) !important;    border-color: var(--wos-line); }
.badge.bg-dark      { background: var(--wos-surface-3) !important; color: var(--wos-fg) !important;        border-color: var(--wos-line-strong); }

.wos-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: var(--wos-text-xs);
  font-weight: 500;
  padding: 0.18rem 0.55rem;
  border: 1px solid var(--wos-line);
  border-radius: var(--wos-r-pill);
  background: var(--wos-surface-2);
  color: var(--wos-fg-dim);
}
.wos-chip--mono { font-family: var(--wos-font-mono); font-size: var(--wos-text-micro); }

/* ==========================================================================
   10. TABLES — dense, operational, and usable on a phone
   ========================================================================== */

.table {
  --bs-table-bg: transparent;
  --bs-table-color: var(--wos-fg);
  --bs-table-border-color: var(--wos-line);
  --bs-table-striped-bg: var(--wos-surface-2);
  --bs-table-striped-color: var(--wos-fg);
  --bs-table-hover-bg: var(--wos-surface-2);
  --bs-table-hover-color: var(--wos-fg);
  --bs-table-active-bg: var(--wos-surface-3);
  font-size: var(--wos-text-sm);
  margin-bottom: 0;
}

.table > thead th {
  background: var(--wos-surface-2);
  color: var(--wos-fg-dim);
  font-weight: 600;
  font-size: var(--wos-text-xs);
  letter-spacing: var(--wos-track-micro);
  border-bottom: 1px solid var(--wos-line-strong);
  padding: 0.6rem 0.75rem;
  white-space: nowrap;
  position: sticky;
  top: 0;
  z-index: 2;
}

.table > tbody td, .table > tbody th {
  padding: 0.55rem 0.75rem;
  border-bottom: 1px solid var(--wos-line);
  vertical-align: middle;
  color: var(--wos-fg);
}

.table > tbody tr:last-child td { border-bottom: 0; }
.table-hover > tbody > tr:hover > * { background-color: var(--wos-surface-2); }
.table > tbody > tr.selected > *, .table > tbody > tr.table-active > *, .table-active { background-color: var(--wos-accent-wash) !important; color: var(--wos-fg); }
.table-primary, .table-info { --bs-table-bg: var(--wos-accent-wash); --bs-table-color: var(--wos-fg); }
.table-success { --bs-table-bg: var(--wos-ok-wash); --bs-table-color: var(--wos-fg); }
.table-warning { --bs-table-bg: var(--wos-warn-wash); --bs-table-color: var(--wos-fg); }
.table-danger { --bs-table-bg: var(--wos-crit-wash); --bs-table-color: var(--wos-fg); }
.table-light, .table-secondary { --bs-table-bg: var(--wos-surface-2); --bs-table-color: var(--wos-fg); }
.table-dark { --bs-table-bg: var(--wos-surface-3); --bs-table-color: var(--wos-fg); }

/* Monospace any column that holds machine data. */
.table td.mono, .table td .mono, .table .wos-mono { font-family: var(--wos-font-mono); font-size: var(--wos-text-xs); }

.table-responsive,
.wos-table-scroll {
  border: 1px solid var(--wos-line);
  border-radius: var(--wos-r-data);
  overflow-x: auto;
  overflow-y: visible;
  background: var(--wos-surface);
  -webkit-overflow-scrolling: touch;
  max-width: 100%;
}
.table-responsive > .table, .wos-table-scroll > .table { margin-bottom: 0; }

/* Fade hint that there is more table to the right. */
.wos-table-scroll { position: relative; }

/* -- Phone: every row becomes a record card, no horizontal scrolling ----- */
@media (max-width: 767.98px) {
  .table.stack-on-mobile,
  .table.wos-table--stack {
    display: block;
    border: 0;
  }
  .table.stack-on-mobile thead,
  .table.wos-table--stack thead {
    position: absolute;
    width: 1px; height: 1px;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
    white-space: nowrap;
  }
  .table.stack-on-mobile tbody,
  .table.wos-table--stack tbody { display: block; }
  .table.stack-on-mobile tbody tr,
  .table.wos-table--stack tbody tr {
    display: block;
    background: var(--wos-surface);
    border: 1px solid var(--wos-line);
    border-left: 3px solid var(--wos-line-strong);
    border-radius: var(--wos-r-data);
    margin-bottom: var(--wos-s3);
    padding: var(--wos-s2) var(--wos-s3);
  }
  .table.stack-on-mobile tbody td,
  .table.wos-table--stack tbody td {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--wos-s4);
    border: 0;
    border-bottom: 1px dashed var(--wos-line);
    padding: 0.4rem 0;
    text-align: right;
  }
  .table.stack-on-mobile tbody td:last-child,
  .table.wos-table--stack tbody td:last-child { border-bottom: 0; }
  .table.stack-on-mobile tbody td::before,
  .table.wos-table--stack tbody td::before {
    content: attr(data-label);
    flex: 0 0 auto;
    text-align: left;
    font-size: var(--wos-text-micro);
    font-weight: 600;
    color: var(--wos-fg-mute);
    letter-spacing: var(--wos-track-micro);
  }
  .table.stack-on-mobile tbody td:empty { display: none; }
  .table-responsive:has(.table.stack-on-mobile),
  .table-responsive:has(.wos-table--stack) { border: 0; background: transparent; overflow: visible; }
}

/* ==========================================================================
   11. THE SHELL — rail, topbar, content
   ========================================================================== */

.wrapper { min-height: 100vh; align-items: stretch; }

.main-content {
  min-width: 0;              /* the flexbox rule that prevents overflow      */
  max-width: 100%;
  display: flex;
  flex-direction: column;
  background:
    linear-gradient(var(--wos-grid-line) 1px, transparent 1px) 0 0 / 100% 56px,
    var(--wos-bg);
}

main.p-4, .wos-main {
  flex: 1 1 auto;
  min-width: 0;
  padding: var(--wos-s6) var(--wos-s6) var(--wos-s10) !important;
}

/* -- Navigation rail ---------------------------------------------------- */
#sidebar,
.sidebar {
  flex: 0 0 var(--wos-rail);
  width: var(--wos-rail);
  max-width: 84vw;
  background: var(--wos-surface) !important;
  border-right: 1px solid var(--wos-line);
  color: var(--wos-fg) !important;
  display: flex;
  flex-direction: column;
  height: 100vh;
  position: sticky;
  top: 0;
  overflow: hidden;
  transition: width var(--wos-t) var(--wos-ease), flex-basis var(--wos-t) var(--wos-ease);
  z-index: 1040;
}

.sidebar-header {
  flex: 0 0 auto;
  padding: var(--wos-s4) var(--wos-s5) !important;
  border-bottom: 1px solid var(--wos-line) !important;
}
.sidebar-header a { color: var(--wos-fg) !important; display: flex; align-items: center; gap: 0.6rem; text-decoration: none; }
.sidebar-header .fw-bold {
  font-size: var(--wos-text-base);
  font-weight: 700;
  letter-spacing: var(--wos-track-head);
}

.server-selector-wrapper {
  flex: 0 0 auto;
  padding: var(--wos-s3) var(--wos-s5);
  border-bottom: 1px solid var(--wos-line);
  background: var(--wos-surface-2);
}
.server-selector-wrapper .form-label { font-size: var(--wos-text-micro); color: var(--wos-fg-mute) !important; margin-bottom: 0.25rem; }
.server-selector-wrapper .form-select { font-size: var(--wos-text-sm); padding: 0.34rem 2rem 0.34rem 0.55rem; }

#sidebar > .nav,
.sidebar > .nav {
  flex: 1 1 auto;
  /* Bootstrap's .nav wraps. In a column inside a 100vh rail that means the
     list spills into a second column instead of scrolling once the window is
     shorter than the menu. The rail scrolls; it never wraps. */
  flex-wrap: nowrap;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--wos-s3) var(--wos-s3) var(--wos-s10) !important;
  scrollbar-width: thin;
  scrollbar-color: var(--wos-line-strong) transparent;
}
#sidebar > .nav::-webkit-scrollbar { width: 8px; }
#sidebar > .nav::-webkit-scrollbar-thumb { background: var(--wos-line-strong); border-radius: 4px; }

.sidebar .nav-link {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.44rem 0.6rem;
  margin-bottom: 1px;
  border-radius: var(--wos-r-ctl);
  color: var(--wos-fg-dim) !important;
  font-size: var(--wos-text-sm);
  font-weight: 500;
  line-height: 1.35;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: background-color var(--wos-t-fast) var(--wos-ease), color var(--wos-t-fast) var(--wos-ease);
}
.sidebar .nav-link i { flex: 0 0 1.1rem; font-size: 1rem; text-align: center; opacity: 0.9; }
.sidebar .nav-link:hover { background: var(--wos-surface-3); color: var(--wos-fg) !important; }

/* Active item: the accent bar states *where you are*, not decoration. */
.sidebar .nav-link.active,
.sidebar .nav-link.active.bg-primary {
  background: var(--wos-accent-wash) !important;
  color: var(--wos-accent-ink) !important;
  font-weight: 600;
  position: relative;
}
.sidebar .nav-link.active::before {
  content: "";
  position: absolute;
  left: -0.6rem;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 1.1rem;
  border-radius: 0 2px 2px 0;
  background: var(--wos-accent);
}

.nav-section {
  margin: var(--wos-s5) 0 var(--wos-s2) !important;
  padding: 0 0.6rem !important;
  font-size: var(--wos-text-micro) !important;
  font-weight: 700;
  color: var(--wos-fg-mute) !important;
  letter-spacing: var(--wos-track-micro);
  display: flex;
  align-items: center;
  gap: 0.5rem;
  text-transform: none;
}
.nav-section::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: var(--wos-line);
}
.nav-item:first-child .nav-section, .nav-section:first-child { margin-top: var(--wos-s1) !important; }

/* Collapsed rail (desktop) */
@media (min-width: 992px) {
  #sidebar.collapsed { flex-basis: var(--wos-rail-collapsed); width: var(--wos-rail-collapsed); }
  #sidebar.collapsed .sidebar-header .fw-bold,
  #sidebar.collapsed .server-selector-wrapper,
  #sidebar.collapsed .nav-link span,
  #sidebar.collapsed .nav-section { display: none; }
  #sidebar.collapsed .nav-link { justify-content: center; padding-inline: 0; font-size: 0; gap: 0; }
  #sidebar.collapsed .nav-link i { font-size: 1.15rem; flex-basis: auto; }
  #sidebar.collapsed .nav-link.active::before { left: 0; }
}

/* -- Topbar ------------------------------------------------------------- */
.wos-navbar,
.navbar.wos-navbar {
  flex: 0 0 auto;
  min-height: var(--wos-topbar);
  background: color-mix(in srgb, var(--wos-surface) 88%, transparent) !important;
  backdrop-filter: saturate(150%) blur(10px);
  -webkit-backdrop-filter: saturate(150%) blur(10px);
  border-bottom: 1px solid var(--wos-line) !important;
  position: sticky;
  top: 0;
  z-index: 1030;
  padding-inline: var(--wos-s5) !important;
}
.wos-navbar .btn-link { color: var(--wos-fg-dim) !important; text-decoration: none; }
.wos-navbar .btn-link:hover { color: var(--wos-fg) !important; }
.wos-navbar .dropdown-toggle { color: var(--wos-fg) !important; font-size: var(--wos-text-sm); font-weight: 500; }

.dropdown-menu {
  --bs-dropdown-bg: var(--wos-surface);
  --bs-dropdown-border-color: var(--wos-line);
  --bs-dropdown-link-color: var(--wos-fg-dim);
  --bs-dropdown-link-hover-bg: var(--wos-surface-3);
  --bs-dropdown-link-hover-color: var(--wos-fg);
  --bs-dropdown-link-active-bg: var(--wos-accent-wash);
  --bs-dropdown-link-active-color: var(--wos-accent-ink);
  --bs-dropdown-border-radius: var(--wos-r-card);
  --bs-dropdown-font-size: var(--wos-text-sm);
  box-shadow: var(--wos-elev-3);
  padding: 0.3rem;
}
.dropdown-item { border-radius: var(--wos-r-ctl); padding: 0.42rem 0.6rem; }
.dropdown-divider { border-color: var(--wos-line); }

/* -- Page header -------------------------------------------------------- */
.wos-pagehead {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--wos-s4);
  padding-bottom: var(--wos-s4);
  margin-bottom: var(--wos-s6);
  border-bottom: 1px solid var(--wos-line);
}
.wos-pagehead h1, .wos-pagehead .h1 { margin: 0; }
.wos-pagehead__sub { color: var(--wos-fg-dim); font-size: var(--wos-text-sm); margin: 0.25rem 0 0; }
.wos-pagehead__actions { display: flex; flex-wrap: wrap; gap: var(--wos-s2); }

/* -- Footer ------------------------------------------------------------- */
.wos-footer, footer.border-top {
  flex: 0 0 auto;
  background: var(--wos-surface) !important;
  border-top: 1px solid var(--wos-line) !important;
  color: var(--wos-fg-mute);
  padding: var(--wos-s4) var(--wos-s6) !important;
  font-size: var(--wos-text-xs);
}
.wos-footer a { color: var(--wos-fg-dim); }

/* -- Mobile navigation -------------------------------------------------- */
.mobile-menu-btn {
  display: none;
  position: fixed;
  left: var(--wos-s4);
  bottom: var(--wos-s4);
  z-index: 1060;
  width: 52px;
  height: 52px;
  border-radius: var(--wos-r-pill);
  border: 1px solid var(--wos-accent-hover);
  background: var(--wos-accent);
  color: var(--wos-on-accent);
  font-size: 1.4rem;
  line-height: 1;
  box-shadow: var(--wos-elev-3);
  cursor: pointer;
  align-items: center;
  justify-content: center;
  transition: transform var(--wos-t) var(--wos-ease);
}
.mobile-menu-btn:active { transform: scale(0.94); }

.sidebar-overlay {
  position: fixed;
  inset: 0;
  z-index: 1035;
  background: var(--wos-scrim);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--wos-t) var(--wos-ease), visibility var(--wos-t);
}
.sidebar-overlay.show { opacity: 1; visibility: visible; }

@media (max-width: 991.98px) {
  .mobile-menu-btn { display: inline-flex; }
  #sidebar, .sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    transform: translateX(-100%);
    transition: transform var(--wos-t-slow) var(--wos-ease-out);
    box-shadow: var(--wos-elev-3);
  }
  #sidebar.show, .sidebar.show { transform: translateX(0); }
  main.p-4, .wos-main { padding: var(--wos-s5) var(--wos-s4) var(--wos-s16) !important; }
  .wos-navbar { padding-inline: var(--wos-s4) !important; }
}

@media (max-width: 575.98px) {
  main.p-4, .wos-main { padding: var(--wos-s4) var(--wos-s3) var(--wos-s16) !important; }
  .wos-navbar { padding-inline: var(--wos-s3) !important; }
  .card-body, .panel-body { padding: var(--wos-s4); }
  .wos-pagehead { margin-bottom: var(--wos-s5); }
  .wos-pagehead__actions { width: 100%; }
  .wos-pagehead__actions .btn { flex: 1 1 auto; }
}

/* ==========================================================================
   12. COMMAND PALETTE — one shortcut reaches any function
   ========================================================================== */

.wos-palette {
  position: fixed;
  inset: 0;
  z-index: 1080;
  display: none;
  padding: max(8vh, var(--wos-s8)) var(--wos-s4) var(--wos-s4);
  background: var(--wos-scrim);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}
.wos-palette[open], .wos-palette.is-open { display: block; }

.wos-palette__box {
  max-width: 640px;
  margin: 0 auto;
  background: var(--wos-surface);
  border: 1px solid var(--wos-line-strong);
  border-radius: var(--wos-r-shell);
  box-shadow: var(--wos-elev-3);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  max-height: min(72vh, 560px);
}

.wos-palette__search {
  display: flex;
  align-items: center;
  gap: var(--wos-s3);
  padding: var(--wos-s4) var(--wos-s5);
  border-bottom: 1px solid var(--wos-line);
  background: var(--wos-surface-2);
}
.wos-palette__search i { color: var(--wos-fg-mute); font-size: 1rem; }
.wos-palette__search input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--wos-fg);
  font-family: var(--wos-font-ui);
  font-size: var(--wos-text-md);
  padding: 0;
}
.wos-palette__search input:focus { outline: none; }
.wos-palette__search input::placeholder { color: var(--wos-fg-mute); }

.wos-palette__list {
  list-style: none;
  margin: 0;
  padding: var(--wos-s2);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.wos-palette__item {
  display: flex;
  align-items: center;
  gap: var(--wos-s3);
  padding: 0.5rem 0.65rem;
  border-radius: var(--wos-r-ctl);
  color: var(--wos-fg-dim);
  text-decoration: none;
  font-size: var(--wos-text-sm);
  cursor: pointer;
}
.wos-palette__item i { flex: 0 0 1.1rem; text-align: center; color: var(--wos-fg-mute); }
.wos-palette__item[aria-selected="true"],
.wos-palette__item:hover {
  background: var(--wos-accent-wash);
  color: var(--wos-accent-ink);
}
.wos-palette__item[aria-selected="true"] i, .wos-palette__item:hover i { color: var(--wos-accent-ink); }
.wos-palette__group {
  margin-left: auto;
  font-size: var(--wos-text-micro);
  color: var(--wos-fg-mute);
  white-space: nowrap;
}
.wos-palette__foot {
  display: flex;
  gap: var(--wos-s4);
  padding: var(--wos-s2) var(--wos-s5);
  border-top: 1px solid var(--wos-line);
  background: var(--wos-surface-2);
  font-size: var(--wos-text-micro);
  color: var(--wos-fg-mute);
  flex-wrap: wrap;
}
.wos-palette__empty { padding: var(--wos-s8) var(--wos-s5); text-align: center; color: var(--wos-fg-mute); font-size: var(--wos-text-sm); }

.wos-kbdhint {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  border: 1px solid var(--wos-line-strong);
  border-radius: var(--wos-r-ctl);
  background: var(--wos-surface-2);
  color: var(--wos-fg-mute);
  font-size: var(--wos-text-xs);
  padding: 0.26rem 0.55rem;
  cursor: pointer;
  transition: border-color var(--wos-t-fast) var(--wos-ease), color var(--wos-t-fast) var(--wos-ease);
}
.wos-kbdhint:hover { border-color: var(--wos-accent-line); color: var(--wos-fg-dim); }
@media (max-width: 767.98px) { .wos-kbdhint kbd { display: none; } }

/* ==========================================================================
   13. TOASTS & FLASH
   ========================================================================== */

.md-toast-container,
.toast-container.wos {
  position: fixed;
  right: var(--wos-s4);
  bottom: var(--wos-s4);
  z-index: 1090;
  display: flex;
  flex-direction: column;
  gap: var(--wos-s2);
  max-width: min(380px, calc(100vw - 2rem));
}

.md-toast,
.wos-toast {
  display: flex;
  align-items: flex-start;
  gap: var(--wos-s3);
  padding: 0.7rem 0.9rem;
  background: var(--wos-surface);
  border: 1px solid var(--wos-line-strong);
  border-left: 3px solid var(--wos-idle);
  border-radius: var(--wos-r-ctl);
  box-shadow: var(--wos-elev-3);
  color: var(--wos-fg);
  font-size: var(--wos-text-sm);
  animation: wos-toast-in var(--wos-t-slow) var(--wos-ease-out) both;
}
.md-toast.success, .wos-toast--ok { border-left-color: var(--wos-ok); }
.md-toast.error, .md-toast.danger, .wos-toast--crit { border-left-color: var(--wos-crit); }
.md-toast.warning, .wos-toast--warn { border-left-color: var(--wos-warn); }
.md-toast.info, .wos-toast--info { border-left-color: var(--wos-info); }
.md-toast.leaving, .wos-toast.leaving { animation: wos-toast-out var(--wos-t) var(--wos-ease) both; }

@keyframes wos-toast-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes wos-toast-out { to { opacity: 0; transform: translateY(6px); } }

.alert {
  --bs-alert-border-radius: var(--wos-r-card);
  border: 1px solid var(--wos-line);
  border-left-width: 3px;
  background: var(--wos-surface);
  color: var(--wos-fg);
  font-size: var(--wos-text-sm);
  padding: 0.75rem 1rem;
}
.alert-success { border-left-color: var(--wos-ok); background: var(--wos-ok-wash); color: var(--wos-ok-ink); }
.alert-warning { border-left-color: var(--wos-warn); background: var(--wos-warn-wash); color: var(--wos-warn-ink); }
.alert-danger  { border-left-color: var(--wos-crit); background: var(--wos-crit-wash); color: var(--wos-crit-ink); }
.alert-primary { border-left-color: var(--wos-accent); background: var(--wos-accent-wash); color: var(--wos-fg); }
.alert-info { border-left-color: var(--wos-info); background: var(--wos-info-wash); color: var(--wos-fg); }
.alert-success, .alert-warning, .alert-danger { color: var(--wos-fg); }
.alert-success > i:first-child, .alert-success .bi:first-child { color: var(--wos-ok-ink); }
.alert-warning > i:first-child, .alert-warning .bi:first-child { color: var(--wos-warn-ink); }
.alert-danger > i:first-child, .alert-danger .bi:first-child { color: var(--wos-crit-ink); }
.alert-info > i:first-child, .alert-info .bi:first-child { color: var(--wos-info-ink); }
.alert .alert-link, .alert a { color: var(--wos-accent-ink); font-weight: 600; }
.alert-secondary, .alert-light { border-left-color: var(--wos-line-strong); background: var(--wos-surface-2); color: var(--wos-fg-dim); }
.alert .btn-close { filter: none; }
[data-theme="dark"] .btn-close { filter: invert(1) grayscale(1) brightness(1.6); }

/* ==========================================================================
   14. EMPTY STATES, SKELETONS, PROGRESS
   ========================================================================== */

.wos-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--wos-s3);
  padding: var(--wos-s12) var(--wos-s5);
  border: 1px dashed var(--wos-line-strong);
  border-radius: var(--wos-r-card);
  background: var(--wos-surface-2);
}
.wos-empty__icon {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: var(--wos-r-card);
  background: var(--wos-surface-3);
  border: 1px solid var(--wos-line);
  color: var(--wos-fg-mute);
  font-size: 1.3rem;
}
.wos-empty__title { font-size: var(--wos-text-md); font-weight: 600; margin: 0; color: var(--wos-fg); }
.wos-empty__body { margin: 0; max-width: 48ch; font-size: var(--wos-text-sm); color: var(--wos-fg-dim); }

.wos-skeleton {
  position: relative;
  overflow: hidden;
  background: var(--wos-surface-3);
  border-radius: var(--wos-r-data);
  min-height: 0.85rem;
}
.wos-skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--wos-fg) 8%, transparent), transparent);
  animation: wos-shimmer 1.3s infinite;
}
@keyframes wos-shimmer { to { transform: translateX(100%); } }
.wos-skeleton--line { height: 0.85rem; margin-bottom: 0.5rem; }
.wos-skeleton--line:nth-child(3n) { width: 72%; }
.wos-skeleton--line:nth-child(3n + 2) { width: 88%; }
.wos-skeleton--title { height: 1.4rem; width: 40%; margin-bottom: 0.9rem; }
.wos-skeleton--block { height: 6rem; }

.progress {
  --bs-progress-bg: var(--wos-surface-3);
  --bs-progress-border-radius: var(--wos-r-pill);
  --bs-progress-height: 6px;
  --bs-progress-bar-bg: var(--wos-accent);
  border: 1px solid var(--wos-line);
}
.progress-bar { transition: width var(--wos-t-slow) var(--wos-ease); }
.progress-bar.bg-success { background: var(--wos-ok) !important; }
.progress-bar.bg-warning { background: var(--wos-warn) !important; }
.progress-bar.bg-danger  { background: var(--wos-crit) !important; }
.progress-bar.bg-info    { background: var(--wos-info) !important; }
.progress-bar.bg-primary { background: var(--wos-accent) !important; }

/* -- Long operation tracker --------------------------------------------- */
.wos-op {
  border: 1px solid var(--wos-line);
  border-left: 3px solid var(--wos-accent);
  border-radius: var(--wos-r-card);
  background: var(--wos-surface);
  padding: var(--wos-s4);
  display: grid;
  gap: var(--wos-s2);
}
.wos-op__head { display: flex; align-items: center; justify-content: space-between; gap: var(--wos-s3); }
.wos-op__title { font-size: var(--wos-text-sm); font-weight: 600; margin: 0; }
.wos-op__elapsed { font-family: var(--wos-font-mono); font-size: var(--wos-text-xs); color: var(--wos-fg-mute); font-variant-numeric: tabular-nums; }
.wos-op__track { height: 5px; border-radius: var(--wos-r-pill); background: var(--wos-surface-3); overflow: hidden; }
.wos-op__fill { height: 100%; width: 0; background: var(--wos-accent); border-radius: inherit; transition: width var(--wos-t-slow) var(--wos-ease); }
.wos-op--indeterminate .wos-op__fill {
  width: 38%;
  animation: wos-indet 1.15s var(--wos-ease) infinite;
}
@keyframes wos-indet {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(285%); }
}
.wos-op__status { font-size: var(--wos-text-xs); color: var(--wos-fg-dim); margin: 0; }
.wos-op--ok { border-left-color: var(--wos-ok); }
.wos-op--ok .wos-op__fill { background: var(--wos-ok); }
.wos-op--crit { border-left-color: var(--wos-crit); }
.wos-op--crit .wos-op__fill { background: var(--wos-crit); }

/* Legacy overlay from app.js */
.api-loading-overlay {
  position: fixed;
  inset: 0;
  z-index: 1085;
  display: none;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, var(--wos-bg) 72%, transparent);
  backdrop-filter: blur(2px);
}
.api-loading-spinner {
  padding: var(--wos-s5);
  border-radius: var(--wos-r-card);
  background: var(--wos-surface);
  border: 1px solid var(--wos-line);
  box-shadow: var(--wos-elev-3);
}
.spinner-border { --bs-spinner-border-width: 2px; color: var(--wos-accent); }

/* ==========================================================================
   15. MODALS, PAGINATION, TABS, LISTS
   ========================================================================== */

.modal-content {
  background: var(--wos-surface);
  border: 1px solid var(--wos-line-strong);
  border-radius: var(--wos-r-shell);
  box-shadow: var(--wos-elev-3);
  color: var(--wos-fg);
}
.modal-header { border-bottom: 1px solid var(--wos-line); padding: var(--wos-s4) var(--wos-s5); }
.modal-title { font-size: var(--wos-text-md); font-weight: 600; }
.modal-body { padding: var(--wos-s5); }
.modal-footer { border-top: 1px solid var(--wos-line); padding: var(--wos-s3) var(--wos-s5); background: var(--wos-surface-2); border-radius: 0 0 var(--wos-r-shell) var(--wos-r-shell); }
.modal-backdrop { --bs-backdrop-bg: #020617; --bs-backdrop-opacity: 0.5; }
.modal-backdrop.show { opacity: 0.5; }

.pagination {
  --bs-pagination-bg: var(--wos-surface);
  --bs-pagination-color: var(--wos-fg-dim);
  --bs-pagination-border-color: var(--wos-line);
  --bs-pagination-hover-bg: var(--wos-surface-3);
  --bs-pagination-hover-color: var(--wos-fg);
  --bs-pagination-hover-border-color: var(--wos-line-strong);
  --bs-pagination-focus-bg: var(--wos-surface-3);
  --bs-pagination-focus-color: var(--wos-fg);
  --bs-pagination-active-bg: var(--wos-accent);
  --bs-pagination-active-border-color: var(--wos-accent);
  --bs-pagination-active-color: var(--wos-on-accent);
  --bs-pagination-disabled-bg: var(--wos-surface-2);
  --bs-pagination-disabled-color: var(--wos-fg-mute);
  --bs-pagination-disabled-border-color: var(--wos-line);
  --bs-pagination-border-radius: var(--wos-r-ctl);
  --bs-pagination-font-size: var(--wos-text-sm);
  --bs-pagination-padding-x: 0.65rem;
  --bs-pagination-padding-y: 0.32rem;
  gap: 2px;
  flex-wrap: wrap;
}
.page-link { border-radius: var(--wos-r-ctl) !important; }

.wos-pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--wos-s4);
  flex-wrap: wrap;
  padding-top: var(--wos-s4);
}
.wos-pager__count { font-size: var(--wos-text-xs); color: var(--wos-fg-mute); font-variant-numeric: tabular-nums; }

.nav-tabs {
  --bs-nav-tabs-border-color: var(--wos-line);
  --bs-nav-tabs-link-active-bg: var(--wos-surface);
  --bs-nav-tabs-link-active-color: var(--wos-fg);
  --bs-nav-tabs-link-active-border-color: var(--wos-line) var(--wos-line) var(--wos-surface);
  --bs-nav-link-color: var(--wos-fg-dim);
  --bs-nav-link-hover-color: var(--wos-fg);
  --bs-nav-link-font-size: var(--wos-text-sm);
  font-weight: 600;
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
}
.nav-tabs::-webkit-scrollbar { display: none; }
.nav-tabs .nav-link { white-space: nowrap; border-radius: var(--wos-r-ctl) var(--wos-r-ctl) 0 0; }

.nav-pills {
  --bs-nav-pills-border-radius: var(--wos-r-ctl);
  --bs-nav-pills-link-active-bg: var(--wos-accent);
  --bs-nav-pills-link-active-color: var(--wos-on-accent);
  --bs-nav-link-color: var(--wos-fg-dim);
  --bs-nav-link-font-size: var(--wos-text-sm);
}

.list-group {
  --bs-list-group-bg: var(--wos-surface);
  --bs-list-group-border-color: var(--wos-line);
  --bs-list-group-color: var(--wos-fg);
  --bs-list-group-action-hover-bg: var(--wos-surface-2);
  --bs-list-group-action-hover-color: var(--wos-fg);
  --bs-list-group-active-bg: var(--wos-accent-wash);
  --bs-list-group-active-border-color: var(--wos-accent-line);
  --bs-list-group-active-color: var(--wos-accent-ink);
  --bs-list-group-border-radius: var(--wos-r-card);
  font-size: var(--wos-text-sm);
}

.accordion {
  --bs-accordion-bg: var(--wos-surface);
  --bs-accordion-border-color: var(--wos-line);
  --bs-accordion-color: var(--wos-fg);
  --bs-accordion-btn-color: var(--wos-fg);
  --bs-accordion-btn-bg: var(--wos-surface-2);
  --bs-accordion-active-bg: var(--wos-accent-wash);
  --bs-accordion-active-color: var(--wos-accent-ink);
  --bs-accordion-border-radius: var(--wos-r-card);
  --bs-accordion-btn-focus-box-shadow: 0 0 0 3px color-mix(in srgb, var(--wos-accent) 26%, transparent);
}

.offcanvas { background: var(--wos-surface); color: var(--wos-fg); border-color: var(--wos-line); }

/* ==========================================================================
   16. APP-SPECIFIC COMPONENTS (ported from the legacy sheets)
   ========================================================================== */

/* -- Terminal ----------------------------------------------------------- */
.terminal {
  background: var(--wos-bg);
  border: 1px solid var(--wos-line-strong);
  border-radius: var(--wos-r-card);
  overflow: hidden;
  box-shadow: var(--wos-elev-2);
}
.terminal-header {
  display: flex;
  align-items: center;
  gap: var(--wos-s3);
  padding: var(--wos-s2) var(--wos-s4);
  background: var(--wos-surface-2);
  border-bottom: 1px solid var(--wos-line);
  font-size: var(--wos-text-xs);
  color: var(--wos-fg-dim);
}
.terminal-body {
  font-family: var(--wos-font-mono);
  font-size: var(--wos-text-sm);
  line-height: 1.6;
  padding: var(--wos-s4);
  min-height: 18rem;
  max-height: 60vh;
  overflow: auto;
  color: var(--wos-fg);
  white-space: pre-wrap;
  word-break: break-word;
}
.terminal-prompt { color: var(--wos-ok-ink); font-weight: 600; }
.terminal-input {
  font-family: var(--wos-font-mono);
  background: transparent;
  border: 0;
  color: var(--wos-fg);
  width: 100%;
  padding: 0;
}
.terminal-input:focus { outline: none; }
.terminal .output-error { color: var(--wos-crit-ink); }
.terminal .output-ok { color: var(--wos-ok-ink); }

.quick-cmd {
  font-family: var(--wos-font-mono);
  font-size: var(--wos-text-xs);
  padding: 0.22rem 0.5rem;
  border: 1px solid var(--wos-line);
  border-radius: var(--wos-r-data);
  background: var(--wos-surface-2);
  color: var(--wos-fg-dim);
  cursor: pointer;
  transition: border-color var(--wos-t-fast) var(--wos-ease), color var(--wos-t-fast) var(--wos-ease);
}
.quick-cmd:hover { border-color: var(--wos-accent-line); color: var(--wos-accent-ink); }

/* -- Charts ------------------------------------------------------------- */
.chart-card, .chart-container, .chart-svg-wrap {
  background: var(--wos-surface);
  border: 1px solid var(--wos-line);
  border-radius: var(--wos-r-card);
  padding: var(--wos-s4);
  min-width: 0;
}
.chart-container { position: relative; height: 260px; }
.chart-container > canvas { max-height: 100%; }

/* A chart card is a column: title, then a plot that takes the remaining
   height. Without this the grid stretches every card to the tallest one and
   the short charts sit in a pool of empty space. */
.chart-card { display: flex; flex-direction: column; gap: var(--wos-s3); }
.chart-card > h6 { margin: 0; display: flex; align-items: baseline; gap: 0.45rem; flex-wrap: wrap; }
.chart-card > h6 .chart-subtitle { margin: 0; }
.chart-body { display: flex; flex-direction: column; gap: var(--wos-s3); flex: 1 1 auto; min-height: 0; }
.chart-svg-wrap { flex: 1 1 auto; display: flex; align-items: center; justify-content: center; min-height: 0; }
.chart-svg { width: 100%; height: auto; max-height: 230px; }
.chart-subtitle { font-size: var(--wos-text-xs); color: var(--wos-fg-mute); margin: 0 0 var(--wos-s3); }
.chart-legend { display: flex; flex-wrap: wrap; gap: var(--wos-s3); font-size: var(--wos-text-xs); color: var(--wos-fg-dim); }
.chart-legend-item { display: inline-flex; align-items: center; gap: 0.35rem; }
.chart-legend-dot { width: 8px; height: 8px; border-radius: 2px; background: var(--wos-accent); }
.chart-legend-value { font-family: var(--wos-font-mono); color: var(--wos-fg); font-variant-numeric: tabular-nums; }
/* Four charts. auto-fit used to produce three across and one orphan, leaving
   two thirds of a row empty; a fixed 2-up (4-up on wide screens) never orphans. */
.charts-grid { display: grid; gap: var(--wos-s4); grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 767.98px) { .charts-grid { grid-template-columns: 1fr; } }
@media (min-width: 1600px) { .charts-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* -- Metric bars -------------------------------------------------------- */
.metric-label { font-size: var(--wos-text-xs); color: var(--wos-fg-dim); display: flex; justify-content: space-between; gap: var(--wos-s3); margin-bottom: 0.25rem; }
.metric-bar, .disk-usage-bar {
  height: 6px;
  border-radius: var(--wos-r-pill);
  background: var(--wos-surface-3);
  border: 1px solid var(--wos-line);
  overflow: hidden;
}
.metric-bar > .fill, .disk-usage-fill {
  display: block;
  height: 100%;
  background: var(--wos-accent);
  border-radius: inherit;
  transition: width var(--wos-t-slow) var(--wos-ease);
}
.metric-bar.ok > .fill, .disk-usage-fill.ok { background: var(--wos-ok); }
.metric-bar.warn > .fill, .disk-usage-fill.warning { background: var(--wos-warn); }
.metric-bar.crit > .fill, .disk-usage-fill.critical { background: var(--wos-crit); }

/* -- Server / disk / adapter cards --------------------------------------- */
.server-card, .disk-card, .network-adapter-card, .account-card,
.startup-card, .test-card, .operation-card, .install-type-card,
.os-option, .dns-preset, .printer-type-card {
  background: var(--wos-surface);
  border: 1px solid var(--wos-line);
  border-radius: var(--wos-r-card);
  padding: var(--wos-s4);
  min-width: 0;
  transition: border-color var(--wos-t) var(--wos-ease), transform var(--wos-t) var(--wos-ease), box-shadow var(--wos-t) var(--wos-ease);
}
.server-card:hover, .disk-card:hover, .network-adapter-card:hover {
  border-color: var(--wos-accent-line);
  box-shadow: var(--wos-elev-2);
}
.os-option, .dns-preset, .install-type-card, .printer-type-card, .operation-card { cursor: pointer; }
.os-option.selected, .dns-preset.selected, .install-type-card.selected,
.printer-type-card.selected, .operation-card.selected, .os-option.active {
  border-color: var(--wos-accent);
  background: var(--wos-accent-wash);
  box-shadow: 0 0 0 1px var(--wos-accent);
}
.server-metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(84px, 1fr)); gap: var(--wos-s3); }
.disk-icon { color: var(--wos-fg-mute); font-size: 1.4rem; }

/* -- Alert feed --------------------------------------------------------- */
.alert-item {
  display: flex;
  gap: var(--wos-s3);
  align-items: flex-start;
  padding: var(--wos-s3) var(--wos-s4);
  border: 1px solid var(--wos-line);
  border-left: 3px solid var(--wos-idle);
  border-radius: var(--wos-r-card);
  background: var(--wos-surface);
  margin-bottom: var(--wos-s2);
}
.alert-item.critical { border-left-color: var(--wos-crit); }
.alert-item.warning { border-left-color: var(--wos-warn); }
.alert-item.info { border-left-color: var(--wos-info); }
.alert-icon { flex: 0 0 auto; font-size: 1.05rem; color: var(--wos-fg-mute); }
.alert-content { flex: 1 1 auto; min-width: 0; }
.alert-title { font-weight: 600; font-size: var(--wos-text-sm); margin: 0; }
.alert-message { font-size: var(--wos-text-sm); color: var(--wos-fg-dim); margin: 0.1rem 0 0; word-break: break-word; }
.alert-meta { font-size: var(--wos-text-micro); color: var(--wos-fg-mute); margin-top: 0.25rem; display: flex; flex-wrap: wrap; gap: var(--wos-s3); }
.alert-actions { flex: 0 0 auto; display: flex; gap: var(--wos-s1); }

/* -- Log lines ---------------------------------------------------------- */
.log-entry {
  font-family: var(--wos-font-mono);
  font-size: var(--wos-text-xs);
  line-height: 1.65;
  padding: 0.18rem 0.5rem;
  border-radius: var(--wos-r-data);
  display: flex;
  gap: var(--wos-s3);
  word-break: break-word;
}
.log-entry:nth-child(odd) { background: var(--wos-surface-2); }
.log-time { flex: 0 0 auto; color: var(--wos-fg-mute); }
.log-entry.error { color: var(--wos-crit-ink); }
.log-entry.warning { color: var(--wos-warn-ink); }

/* -- Rack illustration & topology (login / landing) ---------------------- */
.rack-wrap, .topology-wrap { display: grid; place-items: center; min-width: 0; }
.rack { max-width: 100%; height: auto; }
.rack-bar { fill: var(--wos-accent); }
.topo-node { fill: var(--wos-surface-3); stroke: var(--wos-line-strong); }
.topo-link { stroke: var(--wos-line-strong); stroke-width: 1.5; fill: none; }

/* -- Context menu ------------------------------------------------------- */
.context-menu {
  position: absolute;
  z-index: 1070;
  min-width: 180px;
  padding: 0.3rem;
  background: var(--wos-surface);
  border: 1px solid var(--wos-line-strong);
  border-radius: var(--wos-r-card);
  box-shadow: var(--wos-elev-3);
}
.context-menu-item {
  display: flex;
  align-items: center;
  gap: var(--wos-s2);
  padding: 0.4rem 0.6rem;
  border-radius: var(--wos-r-ctl);
  font-size: var(--wos-text-sm);
  color: var(--wos-fg-dim);
  cursor: pointer;
}
.context-menu-item:hover { background: var(--wos-surface-3); color: var(--wos-fg); }
.context-menu-item.danger { color: var(--wos-crit-ink); }

/* -- OS scoping helpers ------------------------------------------------- */
.windows-only, .linux-only { display: none; }
[data-os="windows"] .windows-only, [data-os="linux"] .linux-only { display: block; }
[data-os="windows"] .windows-only.d-inline, [data-os="linux"] .linux-only.d-inline { display: inline; }

.os-windows { color: var(--wos-accent-ink); }
.os-linux { color: var(--wos-warn-ink); }

.cursor-pointer { cursor: pointer; }

.test-result {
  border: 1px solid var(--wos-line);
  border-left: 3px solid var(--wos-idle);
  border-radius: var(--wos-r-card);
  background: var(--wos-surface-2);
  padding: var(--wos-s3) var(--wos-s4);
  font-size: var(--wos-text-sm);
}
.test-result.success, .test-result.ok { border-left-color: var(--wos-ok); }
.test-result.error, .test-result.failed { border-left-color: var(--wos-crit); }

.review-section {
  border-top: 1px solid var(--wos-line);
  padding-top: var(--wos-s4);
  margin-top: var(--wos-s4);
}
.review-section:first-child { border-top: 0; margin-top: 0; padding-top: 0; }

/* ==========================================================================
   17. MOTION — one orchestrated entrance, then motion only answers actions
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {
  .wos-reveal {
    opacity: 0;
    transform: translateY(12px);
  }
  .wos-reveal.is-in {
    opacity: 1;
    transform: none;
    transition: opacity var(--wos-t-slow) var(--wos-ease-out),
                transform var(--wos-t-slow) var(--wos-ease-out);
  }
  .wos-reveal:nth-child(1).is-in { transition-delay: 0ms; }
  .wos-reveal:nth-child(2).is-in { transition-delay: 45ms; }
  .wos-reveal:nth-child(3).is-in { transition-delay: 90ms; }
  .wos-reveal:nth-child(4).is-in { transition-delay: 135ms; }
  .wos-reveal:nth-child(5).is-in { transition-delay: 180ms; }
  .wos-reveal:nth-child(n + 6).is-in { transition-delay: 210ms; }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  html { scroll-behavior: auto; }
  .wos-reveal { opacity: 1 !important; transform: none !important; }
}

/* ==========================================================================
   18. UTILITIES
   ========================================================================== */

/* A short list of Bootstrap utilities restated so the Bootstrap-less pages
   behave. Values match Bootstrap 5.3 exactly, so nothing changes in the
   console where both stylesheets are present. */
.visually-hidden,
.visually-hidden-focusable:not(:focus):not(:focus-within) {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

.d-flex { display: flex !important; }
.d-grid { display: grid !important; }
.d-none { display: none !important; }
.d-block { display: block !important; }
.d-inline-flex { display: inline-flex !important; }
.flex-wrap { flex-wrap: wrap !important; }
.flex-column { flex-direction: column !important; }
.flex-grow-1 { flex-grow: 1 !important; }
.align-items-center { align-items: center !important; }
.align-items-start { align-items: flex-start !important; }
.justify-content-between { justify-content: space-between !important; }
.justify-content-center { justify-content: center !important; }
.ms-auto { margin-left: auto !important; }
.me-auto { margin-right: auto !important; }
.mx-auto { margin-left: auto !important; margin-right: auto !important; }
.w-100 { width: 100% !important; }
.h-100 { height: 100% !important; }
.text-center { text-align: center !important; }

.gap-1 { gap: 0.25rem !important; }
.gap-2 { gap: 0.5rem !important; }
.gap-3 { gap: 1rem !important; }
.gap-4 { gap: 1.5rem !important; }
.gap-5 { gap: 3rem !important; }

.mt-1 { margin-top: 0.25rem !important; }
.mt-2 { margin-top: 0.5rem !important; }
.mt-3 { margin-top: 1rem !important; }
.mt-4 { margin-top: 1.5rem !important; }
.mb-0 { margin-bottom: 0 !important; }
.mb-1 { margin-bottom: 0.25rem !important; }
.mb-2 { margin-bottom: 0.5rem !important; }
.mb-3 { margin-bottom: 1rem !important; }
.mb-4 { margin-bottom: 1.5rem !important; }
.ms-1 { margin-left: 0.25rem !important; }
.ms-2 { margin-left: 0.5rem !important; }
.me-1 { margin-right: 0.25rem !important; }
.me-2 { margin-right: 0.5rem !important; }

.wos-grid { display: grid; gap: var(--wos-s4); }
.wos-grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); }
.wos-grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); }
.wos-grid--4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr)); }

.wos-stack { display: flex; flex-direction: column; gap: var(--wos-s4); }
.wos-row { display: flex; flex-wrap: wrap; gap: var(--wos-s3); align-items: center; }
.wos-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.wos-break { word-break: break-word; overflow-wrap: anywhere; }
.wos-measure { max-width: var(--wos-measure); }
.wos-dim { color: var(--wos-fg-dim); }
.wos-mute { color: var(--wos-fg-mute); }
.wos-hairline { border: 0; border-top: 1px solid var(--wos-line); margin: var(--wos-s5) 0; }

/* Long, unbreakable machine strings (paths, hashes, connection strings) must
   never push the layout wider than the viewport. */
td, th, .card-body, .alert, .wos-break-all { overflow-wrap: anywhere; }
.text-nowrap.wos-scrollcell { overflow-x: auto; max-width: 100%; display: block; }

/* ==========================================================================
   19. PRINT
   ========================================================================== */

@media print {
  #sidebar, .wos-navbar, .mobile-menu-btn, .sidebar-overlay,
  .wos-palette, .md-toast-container, .wos-pagehead__actions,
  .btn, .pagination { display: none !important; }
  body, .main-content { background: #fff !important; color: #000 !important; }
  .card, .table-responsive { border-color: #ccc !important; box-shadow: none !important; break-inside: avoid; }
  a[href]::after { content: " (" attr(href) ")"; font-size: 0.75em; color: #555; }
}
