/*
 * cortex.css -- Cortex Design System
 * Shared tokens, reset, and component library for all Cortex dashboards.
 * Each page links this file and adds only page-specific styles in its own <style> block.
 * ops-guide.html is intentionally excluded (light/print theme).
 *
 * Last updated: 2026-04-29
 */

/* ============================================================
   DESIGN TOKENS
   ============================================================ */
:root {
  color-scheme: dark;

  /* Surfaces */
  --bg:    #141620;

  /* Navigation surface. The sidebar paints with these three stops and the page's
     background blooms are anchored to the same indigo family, so the two read as
     one continuous ground rather than a dark panel sitting on a purple page. */
  --nav-top: #201d44;
  --nav-mid: #191730;
  --nav-bot: #121119;
  --nav-accent: #6366f1;
  --surf:  #1e2130;
  --surf2: #252840;
  --surf3: #2d3148;

  /* Borders */
  --bdr:  rgba(255,255,255,0.10);
  --bdr2: rgba(255,255,255,0.06);

  /* Text scale (white at descending opacity) */
  --t1: #ffffff;
  --t2: #ffffff;
  --t3: rgba(255,255,255,0.82);
  --t4: rgba(255,255,255,0.62);
  --t5: rgba(255,255,255,0.46);

  /* Semantic colors -- base (borders/icons) + tint (text) + bg (fills) */
  --green:    #22c55e; --green-t:  #4ade80; --green-bg:  rgba(34,197,94,0.10);
  --red:      #ef4444; --red-t:    #f87171; --red-bg:    rgba(239,68,68,0.10);
  --amber:    #f59e0b; --amber-t:  #fbbf24; --amber-bg:  rgba(245,158,11,0.10);
  --blue:     #3b82f6; --blue-t:   #60a5fa; --blue-bg:   rgba(59,130,246,0.10);
  --gray:     #6b7280; --gray-t:   #9ca3af;

  /* Elevation */
  --card-shadow: 0 1px 0 rgba(255,255,255,0.1) inset, 0 4px 24px rgba(0,0,0,0.5), 0 1px 3px rgba(0,0,0,0.3);
}


/* ============================================================
   RESET & BASE
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html { font-size: 14px; }
body {
  font-family: 'Inter', -apple-system, sans-serif;
  background: var(--bg);
  color: var(--t1);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}

/* Global select — dark theme. appearance:none strips the OS chrome so our
   background/color actually apply on Windows Chrome/Edge. The SVG chevron
   replaces the native arrow. Pages can override padding/font-size as needed. */
select {
  appearance: none;
  -webkit-appearance: none;
  background-color: var(--surf2);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath fill='%23ffffff' fill-opacity='0.35' d='M0 0l5 6 5-6z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  border: 1px solid var(--bdr);
  border-radius: 7px;
  color: var(--t1);
  font-family: inherit;
  font-size: 13px;
  outline: none;
  padding: 7px 30px 7px 10px;
  cursor: pointer;
  transition: border-color 0.15s;
}
select:focus { border-color: var(--blue-t); }
select:hover { border-color: rgba(255,255,255,0.22); }
option       { background: #ffffff; color: #111111; }


/* ============================================================
   ANIMATED GRADIENT BACKGROUND
   ============================================================ */
/* No hue-rotate. The old keyframes swept the blooms 0deg -> 95deg and 20deg -> 110deg,
   which is why the page wandered from indigo through magenta to teal and never matched
   the sidebar: the hue was a moving target. Drift is now position and scale only, so
   the colour is fixed and only the shape of the light moves. Durations are long and
   the amplitudes small enough that the motion reads as ambient, not as animation. */
@keyframes bg-breathe {
  0%   { transform: scale(1.00) translate( 0%,  0%); }
  25%  { transform: scale(1.04) translate( 1.5%,  1%); }
  50%  { transform: scale(1.02) translate(-1%,  2%); }
  75%  { transform: scale(1.05) translate( 1%, -1%); }
  100% { transform: scale(1.00) translate( 0%,  0%); }
}
@keyframes bg-breathe-2 {
  0%   { transform: scale(1.00) translate(  0%,  0%); opacity: 0.78; }
  50%  { transform: scale(1.05) translate( -2%, -1.5%); opacity: 1.00; }
  100% { transform: scale(1.00) translate(  0%,  0%); opacity: 0.78; }
}
@keyframes spin   { to { transform: rotate(360deg); } }
@keyframes fadeIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

body::before {
  content: '';
  position: fixed;
  inset: -15%;
  background:
    /* indigo-500 (#6366f1, the accent and the sidebar's glyph/active colour) */
    radial-gradient(ellipse 75% 65% at  5%  5%, rgba( 99,102,241,0.26) 0%, transparent 60%),
    /* indigo-700, deepening toward the far corner */
    radial-gradient(ellipse 55% 50% at 92% 88%, rgba( 67, 56,202,0.18) 0%, transparent 55%),
    radial-gradient(ellipse 40% 35% at 50% 50%, rgba( 99,102,241,0.06) 0%, transparent 50%);
  pointer-events: none;
  z-index: 0;
  animation: bg-breathe 80s ease-in-out infinite;
}
body::after {
  content: '';
  position: fixed;
  inset: -15%;
  background:
    /* blue-500, the same hue as the wordmark's "tex" */
    radial-gradient(ellipse 60% 55% at 95%  5%, rgba( 59,130,246,0.13) 0%, transparent 55%),
    radial-gradient(ellipse 45% 40% at 10% 90%, rgba( 79, 70,229,0.11) 0%, transparent 50%);
  pointer-events: none;
  z-index: 0;
  animation: bg-breathe-2 64s ease-in-out infinite;
}


/* ============================================================
   AUTH OVERLAY
   ============================================================ */
#auth-overlay {
  position: fixed; inset: 0;
  background: var(--bg);
  display: flex; align-items: center; justify-content: center;
  z-index: 1000;
}
.auth-box {
  background: var(--surf); border: 1px solid var(--bdr); border-radius: 14px;
  padding: 40px; width: 340px; text-align: center; box-shadow: var(--card-shadow);
}
.auth-title { font-size: 20px; font-weight: 700; color: var(--t1); margin-bottom: 6px; }
.auth-sub   { font-size: 13px; color: var(--t4); margin-bottom: 24px; }
.auth-box input {
  width: 100%; padding: 11px 14px;
  background: rgba(255,255,255,0.06); border: 1px solid var(--bdr); border-radius: 8px;
  color: var(--t1); font-size: 14px; margin-bottom: 12px; outline: none; font-family: inherit;
}
.auth-box input:focus { border-color: var(--blue-t); }
.auth-btn {
  width: 100%; padding: 11px;
  background: var(--blue); color: #fff; border: none; border-radius: 8px;
  font-size: 14px; font-weight: 600; cursor: pointer; font-family: inherit;
  transition: filter 0.15s;
}
.auth-btn:hover { filter: brightness(1.15); }
.auth-err { color: var(--red-t); font-size: 13px; margin-top: 10px; display: none; }

/* Hidden until auth passes */
#main { display: none; }


/* ============================================================
   HEADER
   ============================================================ */
.header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(18,19,28,0.92);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--bdr);
  padding: 0 28px; height: 56px;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
}
.header-left  { display: flex; align-items: center; gap: 12px; }
.header-brand { font-size: 19px; font-weight: 700; color: var(--t1); letter-spacing: 0.01em; }
.header-brand span { color: var(--t4); font-weight: 300; font-size: 13px; margin-left: 12px; vertical-align: middle; }
.header-brand .brand-tex { color: var(--blue-t); font-size: inherit; font-weight: inherit; margin-left: 0; vertical-align: baseline; }
.header-vr    { color: var(--t4); font-size: 16px; line-height: 1; flex-shrink: 0; }
.header-vr::after { content: '|'; }
.header-sub   { font-size: 12px; color: var(--t4); }

/* ── Dashboard switcher dropdown ── */
.dash-sw      { position:relative; display:inline-flex; align-items:center; }
.dash-sw-btn  {
  display:inline-flex; align-items:center; gap:5px;
  background:none; border:none; cursor:pointer; font-family:inherit;
  color:var(--t4); font-size:13px; font-weight:300;
  padding:3px 8px; border-radius:6px;
  transition:background 0.12s, color 0.12s;
}
.dash-sw-btn:hover, .dash-sw-btn.open { background:rgba(255,255,255,0.07); color:var(--t2); }
.dash-sw-chev { font-size:11px; opacity:0.75; transition:transform 0.15s; line-height:1; }
.dash-sw-btn.open .dash-sw-chev { transform:rotate(180deg); }
.dash-sw-menu {
  display:none; position:absolute; top:calc(100% + 7px); left:0;
  background:var(--surf); border:1px solid var(--bdr);
  border-radius:10px; box-shadow:var(--card-shadow);
  min-width:195px; padding:5px; z-index:300;
}
.dash-sw-menu.open { display:block; }
.dash-sw-item {
  display:block; padding:8px 12px; border-radius:7px;
  color:var(--t2); font-size:13px; text-decoration:none;
  transition:background 0.1s; white-space:nowrap;
}
.dash-sw-item:hover  { background:rgba(255,255,255,0.06); }
.dash-sw-item.active { color:var(--blue-t); font-weight:500; }
.dash-sw-item.disabled { color:var(--t5); cursor:default; }
.dash-sw-item.disabled:hover { background:none; }
.dash-sw-sep  { border:none; border-top:1px solid var(--bdr); margin:4px 0; }
/* Static (no other destinations): render the label as plain text. */
.dash-sw.static .dash-sw-btn { cursor:default; }
.dash-sw.static .dash-sw-btn:hover, .dash-sw.static .dash-sw-btn.open { background:none; color:var(--t4); }
.dash-sw.static .dash-sw-chev { display:none; }
/* grid-column is pinned so the account/bell/gear cluster stays hard right even when the
   centre cell is absent. Pages with no polling (interface maps) set .poll-wrap{display:none},
   which removes it from the grid flow entirely — without this the cluster falls back into
   the middle 'auto' column and reads as centred. A no-op on pages that do poll. */
.header-right { display: flex; align-items: center; gap: 12px; justify-self: end; grid-column: 3; }
.clock        { font-size: 13px; color: var(--t3); font-variant-numeric: tabular-nums; justify-self: center; text-align: center; }

/* ── Access-request bell — admin-only, lives in the shared header (item 8a) ── */
.hdr-bell { position: relative; display: inline-flex; align-items: center; justify-content: center;
            width: 30px; height: 30px; border-radius: 8px; color: var(--t4); cursor: pointer;
            text-decoration: none; transition: background 0.12s, color 0.12s; }
.hdr-bell:hover { background: rgba(255,255,255,0.06); color: var(--t2); }
.hdr-bell.has   { color: var(--amber-t); }
.hdr-bell-badge { position: absolute; top: 1px; right: -1px; min-width: 15px; height: 15px;
                  border-radius: 8px; background: var(--red-t); color: #fff; font-size: 9px;
                  font-weight: 700; line-height: 15px; text-align: center; padding: 0 3px; box-sizing: border-box; }

/* ── Per-dashboard config gear — manage-gated, lives in the shared header (item 8c) ── */
.hdr-gear { display: inline-flex; align-items: center; justify-content: center;
            width: 30px; height: 30px; border-radius: 8px; color: var(--t4); cursor: pointer;
            text-decoration: none; transition: background 0.12s, color 0.12s; }
.hdr-gear:hover { background: rgba(255,255,255,0.06); color: var(--t2); }

/* ── Account button (shared across all dashboards) ── */
.acct-btn {
  display: none; align-items: center; gap: 10px;
  padding: 6px 14px 6px 7px; border-radius: 10px;
  background: rgba(59,130,246,0.08); border: 1px solid rgba(59,130,246,0.22);
  cursor: pointer; font-family: inherit; flex-shrink: 0; text-align: left;
  transition: background 0.15s, border-color 0.15s;
}
.acct-btn:hover { background: rgba(59,130,246,0.15); border-color: rgba(59,130,246,0.42); }
.acct-btn.visible { display: inline-flex; }
.acct-icon {
  width: 34px; height: 34px; border-radius: 8px; flex-shrink: 0;
  background: rgba(59,130,246,0.18); border: 1px solid rgba(59,130,246,0.32);
  color: var(--blue-t); display: flex; align-items: center; justify-content: center;
}
.acct-text     { display: flex; flex-direction: column; gap: 2px; }
.acct-username { font-size: 10px; font-weight: 400; color: var(--t4); line-height: 1; white-space: nowrap; }
.acct-fullname { font-size: 13px; font-weight: 600; color: var(--t1); line-height: 1.2; white-space: nowrap; }

/* ── User menu dropdown ── */
.user-menu-wrap { position: relative; }
.user-menu {
  display: none; position: absolute; top: calc(100% + 6px); right: 0;
  background: var(--surf2); border: 1px solid var(--bdr); border-radius: 10px;
  padding: 6px; min-width: 160px; z-index: 200;
  box-shadow: 0 8px 24px rgba(0,0,0,0.35);
}
.user-menu.open { display: block; }
.user-menu-item {
  display: block; width: 100%; text-align: left;
  padding: 8px 12px; border-radius: 7px; border: none; cursor: pointer;
  background: none; font-family: inherit; font-size: 13px; color: var(--t3);
  transition: background 0.12s, color 0.12s;
}
.user-menu-item:hover  { background: rgba(255,255,255,0.07); color: var(--t1); }
.user-menu-item.danger { color: var(--red-t); }
.user-menu-item.danger:hover { background: rgba(239,68,68,0.08); color: var(--red-t); }

.header-nav { display: flex; gap: 2px; }
.header-nav a {
  font-size: 12px; padding: 5px 13px; border-radius: 6px;
  color: var(--t3); text-decoration: none; white-space: nowrap;
  transition: color 0.12s, background 0.12s;
}
.header-nav a:hover      { color: var(--t2); background: rgba(255,255,255,0.05); }
.header-nav a.active     { color: var(--t1); background: rgba(255,255,255,0.09); font-weight: 500; }
.header-nav a.lock-link  { color: var(--t4); }
.header-nav a.lock-link:hover { color: var(--t2); background: rgba(255,255,255,0.05); }

/* Poll status indicator */
.poll-wrap { display: flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 20px; }
.poll-wrap.state-ok  { background: rgba(34,197,94,0.08);   border: 1px solid rgba(34,197,94,0.2); }
.poll-wrap.state-err { background: rgba(239,68,68,0.08);   border: 1px solid rgba(239,68,68,0.2); }
.poll-wrap.state-    { background: rgba(255,255,255,0.04); border: 1px solid var(--bdr); }
.poll-dot  { width: 6px; height: 6px; border-radius: 50%; background: var(--gray); transition: background 0.3s; }
/* Derive the dot from the pill's state so a page only has to set .poll-wrap.
   Only floor.html and printers.html ever set .poll-dot.ok/.err themselves, which
   left the dot grey inside a green pill everywhere else - the dot is the part you
   read at a glance from across the room, so it has to agree with the pill. */
.poll-wrap.state-ok  .poll-dot { background: var(--green); }
.poll-wrap.state-err .poll-dot { background: var(--red); }
.poll-dot.ok  { background: var(--green); }
.poll-dot.err { background: var(--red); }
.poll-label { font-size: 11px; color: var(--t3); }

/* Sound toggle icon */
.sound-icon { color: var(--t4); flex-shrink: 0; opacity: 0.75; display: block; }

/* Utility ghost buttons (sound, refresh, expand-all, etc.) */
.sound-btn, .refresh-btn, .expand-all-btn {
  font-size: 11px; padding: 4px 10px;
  background: none; border: 1px solid var(--bdr); border-radius: 5px;
  color: var(--t4); cursor: pointer;
  transition: color 0.12s, background 0.12s; font-family: inherit; white-space: nowrap;
}
.sound-btn:hover, .refresh-btn:hover, .expand-all-btn:hover {
  color: var(--t2); background: rgba(255,255,255,0.05);
}
.sound-btn.muted { color: var(--t5); }


/* ============================================================
   TABS
   ============================================================ */
.tabs {
  display: flex; background: rgba(0,0,0,0.2); border-bottom: 1px solid var(--bdr);
  padding: 0 28px; position: relative; z-index: 1;
}
.tab {
  padding: 14px 20px; font-size: 13px; color: var(--t4);
  cursor: pointer; border-bottom: 2px solid transparent;
  transition: color 0.15s, border-color 0.15s; white-space: nowrap;
  font-family: inherit; background: none;
  border-left: none; border-right: none; border-top: none;
}
.tab.active { color: var(--t1); border-bottom-color: var(--blue); }
.tab:hover  { color: var(--t2); }

.tab-content { display: none; position: relative; z-index: 1; }
.tab-content.active { display: block; }


/* ============================================================
   PAGE LAYOUT
   ============================================================ */
.page-content {
  position: relative; z-index: 1;
  max-width: 1420px; margin: 0 auto;
  padding: 28px 28px 64px;
}


/* ============================================================
   TABLES
   ============================================================ */
.table-wrap {
  background: var(--surf); border: 1px solid var(--bdr);
  border-radius: 10px; overflow: hidden; box-shadow: var(--card-shadow);
}
.data-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.data-table th {
  text-align: left; padding: 10px 16px; color: var(--t4);
  font-size: 10px; font-weight: 500; text-transform: uppercase;
  letter-spacing: 0.06em; border-bottom: 1px solid var(--bdr); white-space: nowrap;
}
.data-table td {
  padding: 10px 16px; border-bottom: 1px solid var(--bdr2);
  vertical-align: middle; color: var(--t2);
}
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr:hover td { background: rgba(255,255,255,0.02); }


/* ============================================================
   BUTTONS
   All pages use this system. .save-btn is retired -- use .btn.btn-primary.
   ============================================================ */
.btn {
  padding: 7px 16px; border-radius: 7px; font-size: 13px; font-weight: 600;
  cursor: pointer; border: none; transition: background 0.15s, filter 0.15s;
  font-family: inherit;
}
.btn-primary             { background: var(--blue); color: #fff; }
.btn-primary:hover       { filter: brightness(1.1); }
.btn-secondary           { background: rgba(255,255,255,0.06); color: var(--t3); border: 1px solid var(--bdr); }
.btn-secondary:hover     { background: rgba(255,255,255,0.10); color: var(--t1); }
.btn-danger              { background: transparent; color: var(--red-t); border: 1px solid rgba(239,68,68,0.30); }
.btn-danger:hover        { background: rgba(239,68,68,0.10); }
.btn-success             { background: rgba(34,197,94,0.12); color: var(--green-t); border: 1px solid rgba(34,197,94,0.25); }
.btn-success:hover       { background: rgba(34,197,94,0.22); }
/* Quietest variant: a deliberate, low-drama disposition ("Known" / park it) that must not compete visually with
   the action buttons beside it. Reads as available, never as the thing to click. */
.btn-ghost               { background: transparent; color: var(--t5); border: 1px dashed var(--bdr); }
.btn-ghost:hover         { background: rgba(255,255,255,0.05); color: var(--t3); border-style: solid; }
.btn-sm                  { padding: 4px 11px; font-size: 12px; font-weight: 500; }
.btn-add {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 16px; border-radius: 7px; font-size: 13px; font-weight: 600;
  cursor: pointer; background: rgba(59,130,246,0.10); color: var(--blue-t);
  border: 1px solid rgba(59,130,246,0.25); font-family: inherit; transition: background 0.15s;
}
.btn-add:hover { background: rgba(59,130,246,0.18); }


/* ============================================================
   TOGGLE SWITCH
   Wrap with .toggle-row + .toggle-label for label alongside.
   ============================================================ */
.toggle { display: inline-flex; align-items: center; flex-shrink: 0; cursor: pointer; }
.toggle input { display: none; }   /* hide via display:none — label handles clicks,
                                      :checked selector still works, no browser chrome */
.toggle-slider {
  /* Hardcode dimensions directly — avoids % height issues in label/flex contexts */
  display: block; width: 44px; height: 24px; flex-shrink: 0;
  position: relative;
  background: rgba(255,255,255,0.15);
  border-radius: 24px; cursor: pointer;
  transition: background 0.2s;
}
.toggle-slider:before {
  content: '';
  position: absolute; width: 18px; height: 18px;
  left: 3px; top: 3px;
  background: #fff; border-radius: 50%;
  box-shadow: 0 1px 4px rgba(0,0,0,0.4);
  transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}
.toggle input:checked + .toggle-slider { background: var(--blue); }
.toggle input:checked + .toggle-slider:before { transform: translateX(20px); }
.toggle-row   { display: flex; align-items: center; gap: 10px; }
.toggle-label { font-size: 13px; color: var(--t3); }


/* ============================================================
   BADGES
   ============================================================ */
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; font-weight: 600; padding: 3px 8px;
  border-radius: 20px; white-space: nowrap;
}
.badge-ok       { background: rgba(34,197,94,0.12);   color: var(--green-t); }
.badge-active   { background: rgba(34,197,94,0.10);   color: var(--green-t); border: 1px solid rgba(34,197,94,0.25); }
.badge-warn     { background: rgba(245,158,11,0.12);  color: var(--amber-t); }
.badge-running  { background: rgba(245,158,11,0.12);  color: var(--amber-t); }
.badge-error    { background: rgba(239,68,68,0.12);   color: var(--red-t); }
.badge-crit     { background: rgba(239,68,68,0.12);   color: var(--red-t); }
.badge-inactive { background: rgba(255,255,255,0.04); color: var(--t5); }
.badge-never    { background: rgba(255,255,255,0.06); color: var(--t4); }
.badge-blue     { background: rgba(59,130,246,0.12);  color: var(--blue-t); }
.badge-grey     { background: rgba(255,255,255,0.06); color: var(--t4); }
.badge-no-query { background: rgba(245,158,11,0.10);  color: var(--amber-t); border: 1px solid rgba(245,158,11,0.25); }
.spin-dot {
  width: 7px; height: 7px; border-radius: 50%;
  border: 2px solid var(--amber-t); border-top-color: transparent;
  animation: spin 0.8s linear infinite; display: inline-block;
}


/* ============================================================
   FORMS
   ============================================================ */
.form-group { display: flex; flex-direction: column; gap: 5px; margin-bottom: 14px; }
.form-group label { font-size: 11px; color: var(--t4); text-transform: uppercase; letter-spacing: 0.05em; }
.form-group input,
.form-group select,
.form-group textarea {
  padding: 9px 12px;
  background: rgba(255,255,255,0.06); border: 1px solid var(--bdr); border-radius: 7px;
  color: var(--t1); font-size: 13px; outline: none; font-family: inherit;
}
.form-group select { padding-right: 30px; }
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus { border-color: var(--blue-t); }
.form-group textarea {
  font-family: 'Consolas', 'Courier New', monospace;
  font-size: 12px; resize: vertical; min-height: 160px; line-height: 1.5;
}
.form-row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.form-hint  { font-size: 11px; color: var(--t5); margin-top: 3px; }
.check-row  { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.check-row input  { width: 15px; height: 15px; accent-color: var(--green); cursor: pointer; }
.check-row label  { font-size: 13px; color: var(--t3); cursor: pointer; }


/* ============================================================
   MODAL (shared structure -- size set per page)
   ============================================================ */
.modal-backdrop {
  display: none; position: fixed; inset: 0;
  background: rgba(0,0,0,0.75); z-index: 500;
  align-items: center; justify-content: center;
  backdrop-filter: blur(4px);
}
.modal-backdrop.open { display: flex; }
.modal-box {
  background: var(--surf); border: 1px solid var(--bdr); border-radius: 14px;
  padding: 28px; box-shadow: var(--card-shadow);
  max-height: 85vh; display: flex; flex-direction: column;
}
.modal-title { font-size: 16px; font-weight: 600; color: var(--t1); margin-bottom: 18px; flex-shrink: 0; }
.modal-body  { flex: 1; overflow-y: auto; }
.modal-body::-webkit-scrollbar { width: 4px; }
.modal-body::-webkit-scrollbar-thumb { background: var(--bdr); border-radius: 2px; }
.modal-actions {
  display: flex; gap: 10px; justify-content: flex-end;
  margin-top: 20px; flex-shrink: 0;
  padding-top: 16px; border-top: 1px solid var(--bdr);
}


/* ============================================================
   INFO CARD
   ============================================================ */
.info-card {
  background: rgba(59,130,246,0.06); border: 1px solid rgba(59,130,246,0.18);
  border-radius: 8px; padding: 13px 16px; margin-bottom: 20px;
  font-size: 13px; color: var(--t3); line-height: 1.6;
}
.info-card strong { color: var(--t2); }
.info-card code {
  background: rgba(255,255,255,0.08); border: 1px solid var(--bdr);
  border-radius: 4px; padding: 1px 6px; font-size: 12px; color: var(--blue-t);
}


/* ============================================================
   SECTION HEADERS
   ============================================================ */
.section-hdr {
  font-size: 10px; font-weight: 600; color: var(--t5);
  text-transform: uppercase; letter-spacing: 0.08em;
  margin-bottom: 12px; padding-bottom: 8px; border-bottom: 1px solid var(--bdr2);
}
.section-gap { margin-top: 32px; }

/* ── Collapsible sections + the at-a-glance health strip ──────────────────────
   Shared by every board (drive them with CortexShell.collapsible / .statCell /
   .healthLead). Pages keep their own .section-hdr layout; only the collapse and
   strip primitives live here, because those are what kept getting re-hand-rolled.

   The strip belongs OUTSIDE .section-body on purpose: collapsing hides the
   detail, never the verdict, so a collapsed section still answers "is this
   fine?". Keep it that way. */
.section-hdr.collapsible { cursor: pointer; user-select: none; }
.section-hdr.collapsible:hover .section-title { color: var(--t1); }
.section-chevron { font-size: 9px; color: var(--t5); transition: transform 0.2s; display: inline-block; margin-left: 2px; }
.section-hdr.collapsible.collapsed .section-chevron { transform: rotate(-90deg); }
.section-body.collapsed { display: none; }

.health-strip { display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
  background: var(--surf); border: 1px solid var(--bdr); border-radius: 10px; padding: 11px 16px; box-shadow: var(--card-shadow); }
.health-lead { display: flex; align-items: center; gap: 9px; font-size: 12px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; white-space: nowrap; }
.health-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.health-lead.ok   { color: var(--green-t); } .health-lead.ok   .health-dot { background: var(--green); }
.health-lead.warn { color: var(--amber-t); } .health-lead.warn .health-dot { background: var(--amber); }
.health-lead.crit { color: var(--red-t);   } .health-lead.crit .health-dot { background: var(--red); }
.health-sep { width: 1px; align-self: stretch; background: var(--bdr); }
.health-stat { display: flex; flex-direction: column; gap: 1px; }
.health-val { font-size: 16px; font-weight: 700; color: var(--t1); line-height: 1.15; font-variant-numeric: tabular-nums; }
/* A zero recedes and a non-zero problem shouts - so the eye lands only on what is actually wrong. */
.health-val.zero { color: var(--t4); font-weight: 600; }
.health-val.bad  { color: var(--red-t); }
.health-val.warnv{ color: var(--amber-t); }
.health-val.small { font-size: 13px; font-weight: 600; color: var(--t2); }
.health-lbl { font-size: 9px; text-transform: uppercase; letter-spacing: .05em; color: var(--t5); white-space: nowrap; }
.health-note { margin-left: auto; font-size: 11px; color: var(--t5); }


/* ============================================================
   CONFIG INPUTS (generic key-value config tables)
   ============================================================ */
.config-input {
  padding: 7px 11px;
  background: rgba(255,255,255,0.06); border: 1px solid var(--bdr); border-radius: 6px;
  color: var(--t1); font-size: 13px; outline: none; font-family: inherit;
}
.config-input:focus { border-color: var(--blue-t); }
.config-input.wide       { min-width: 340px; }
.config-input.time-input { width: 110px; font-family: monospace; }
.config-desc { font-size: 11px; color: var(--t4); margin-top: 3px; }


/* ============================================================
   TOAST NOTIFICATIONS
   ============================================================ */
.toast {
  position: fixed; bottom: 24px; right: 24px;
  background: var(--surf2); border: 1px solid var(--bdr); border-radius: 10px;
  padding: 13px 18px; font-size: 13px; color: var(--t2);
  z-index: 2000; display: none; max-width: 360px; box-shadow: var(--card-shadow);
}
.toast.show { display: block; }
.toast.err  { border-color: rgba(239,68,68,0.4); color: var(--red-t); }


/* ============================================================
   FOOTER
   ============================================================ */
.footer {
  position: relative; z-index: 1;
  border-top: 1px solid var(--bdr);
  padding: 16px 28px; font-size: 11px; color: var(--t5);
}


/* ============================================================
   PREFS ITEMS
   Shared drag-list row styles for layout customization modals.
   Modal wrapper uses the standard .modal-backdrop / .modal-box system.
   Requires SortableJS for drag-drop reordering.
   ============================================================ */
.prefs-hint { font-size: 12px; color: var(--t4); margin-bottom: 16px; line-height: 1.55; }

.prefs-item {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border-radius: 8px; margin-bottom: 6px;
  background: var(--surf2); border: 1px solid var(--bdr);
  user-select: none; cursor: default; transition: border-color 0.12s;
}
.prefs-item:last-child { margin-bottom: 0; }
.prefs-item.sortable-ghost  { opacity: 0.30; background: var(--surf3); }
.prefs-item.sortable-chosen { box-shadow: 0 6px 24px rgba(0,0,0,0.55); border-color: rgba(255,255,255,0.20); }

.prefs-drag-handle {
  color: var(--t5); cursor: grab; font-size: 13px;
  flex-shrink: 0; line-height: 1; padding: 2px 4px; transition: color 0.12s;
}
.prefs-drag-handle:hover  { color: var(--t3); }
.prefs-drag-handle:active { cursor: grabbing; }

.prefs-item-label { flex: 1; font-size: 13px; color: var(--t2); }
.prefs-item.hidden-panel .prefs-item-label { color: var(--t5); text-decoration: line-through; }

.prefs-save-msg { font-size: 12px; color: var(--green-t); }
.prefs-save-msg.err { color: var(--red-t); }


/* ============================================================
   ACCOUNT VIEW  (profile / settings overlay — shared by all pages)
   ============================================================ */
.account-view      { display: none; position: fixed; inset: 0; z-index: 500; overflow-y: auto; background: var(--bg); }
.account-view.open { display: block; }
.account-view-body { max-width: 860px; margin: 0 auto; padding: 32px 28px 64px; }
.acct-hdr          { display: flex; align-items: center; gap: 12px; margin-bottom: 28px; }
.acct-back-btn     { background: none; border: 1px solid var(--bdr); color: var(--t3); border-radius: 7px; padding: 5px 13px; font-size: 12px; cursor: pointer; font-family: inherit; transition: color 0.12s, border-color 0.12s, background 0.12s; }
.acct-back-btn:hover { color: var(--t1); border-color: rgba(255,255,255,0.2); background: rgba(255,255,255,0.04); }
.acct-title        { font-size: 18px; font-weight: 700; color: var(--t1); }
.acct-hdr-user     { font-size: 12px; color: var(--t4); margin-left: auto; }
.acct-section      { background: var(--surf); border: 1px solid var(--bdr); border-radius: 12px; padding: 22px 24px; box-shadow: var(--card-shadow); margin-bottom: 16px; }
.acct-section-title { font-size: 11px; font-weight: 600; color: var(--t4); text-transform: uppercase; letter-spacing: 0.07em; margin-bottom: 16px; }
.acct-field-row    { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.acct-field-label  { font-size: 13px; color: var(--t3); min-width: 110px; }
.acct-field-input  { flex: 1; min-width: 180px; max-width: 280px; padding: 8px 12px; background: rgba(255,255,255,0.05); border: 1px solid var(--bdr); border-radius: 7px; color: var(--t1); font-size: 13px; font-family: inherit; outline: none; }
.acct-field-input:focus { border-color: rgba(59,130,246,0.5); background: rgba(59,130,246,0.04); }
.acct-save-btn     { padding: 7px 15px; border-radius: 7px; font-size: 12px; font-weight: 600; background: rgba(59,130,246,0.12); border: 1px solid rgba(59,130,246,0.3); color: var(--blue-t); cursor: pointer; font-family: inherit; transition: background 0.15s, border-color 0.15s; }
.acct-save-btn:hover { background: rgba(59,130,246,0.22); border-color: rgba(59,130,246,0.5); }
.acct-msg          { font-size: 11px; color: var(--t4); }
.acct-msg.ok       { color: var(--green-t); }
.acct-msg.err      { color: var(--red-t); }
/* Avatar picker */
.avatar-picker     { display: flex; flex-wrap: wrap; gap: 6px; }
.avatar-opt        { width: 38px; height: 38px; border-radius: 8px; display: flex; align-items: center; justify-content: center; border: 2px solid var(--bdr); background: var(--surf2); cursor: pointer; font-size: 20px; transition: border-color 0.12s, background 0.12s; color: var(--t3); }
.avatar-opt:hover  { border-color: rgba(59,130,246,0.4); background: rgba(59,130,246,0.07); }
.avatar-opt.selected { border-color: var(--blue-t); background: rgba(59,130,246,0.12); }
.avatar-opt-default { font-size: 18px; }
/* Light mode account view overrides */
html[data-theme="light"] .acct-back-btn:hover { border-color: rgba(0,0,0,0.20); background: rgba(0,0,0,0.04); }
html[data-theme="light"] .acct-field-input    { background: rgba(0,0,0,0.04); }
/* Layout button */
.acct-layout-btn { display: inline-flex; align-items: center; gap: 8px; padding: 8px 15px; border-radius: 8px; font-size: 13px; border: 1px solid var(--bdr); background: rgba(255,255,255,0.04); color: var(--t2); cursor: pointer; font-family: inherit; transition: background 0.15s, border-color 0.15s, color 0.15s; }
.acct-layout-btn:hover { background: rgba(255,255,255,0.08); border-color: rgba(255,255,255,0.15); color: var(--t1); }
html[data-theme="light"] .acct-layout-btn       { background: rgba(0,0,0,0.03); }
html[data-theme="light"] .acct-layout-btn:hover { background: rgba(0,0,0,0.07); border-color: rgba(0,0,0,0.15); }
/* Notification preference groups */
.notif-group { border: 1px solid var(--bdr); border-radius: 8px; overflow: hidden; margin-bottom: 8px; }
.notif-group:last-child { margin-bottom: 0; }
.notif-group-hdr { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; cursor: pointer; user-select: none; background: rgba(255,255,255,0.02); transition: background 0.12s; }
.notif-group-hdr:hover { background: rgba(255,255,255,0.04); }
.notif-group-title { font-size: 12px; font-weight: 600; color: var(--t2); }
.notif-group-chevron { font-size: 9px; color: var(--t5); transition: transform 0.18s; }
.notif-group-hdr.open .notif-group-chevron { transform: rotate(180deg); }
.notif-group-body { display: none; border-top: 1px solid var(--bdr); }
.notif-group-body.open { display: block; }
/* Alert subscription grid */
.alert-sub-table { width: 100%; border-collapse: collapse; table-layout: fixed; }
.alert-sub-table th { text-align: center; padding: 8px 12px; font-size: 10px; font-weight: 500; color: var(--t4); text-transform: uppercase; letter-spacing: 0.06em; border-bottom: 1px solid var(--bdr); }
.alert-sub-table th:first-child { text-align: left; }
.alert-sub-table th:not(:first-child) { width: 90px; }
.alert-sub-table td { padding: 9px 12px; border-bottom: 1px solid var(--bdr2); text-align: center; vertical-align: middle; }
.alert-sub-table td:first-child { text-align: left; font-size: 13px; color: var(--t2); }
.alert-sub-table tbody tr:last-child td { border-bottom: none; }
.alert-sub-table tbody tr:hover td { background: rgba(255,255,255,0.02); }
.sub-toggle { width: 16px; height: 16px; cursor: pointer; accent-color: var(--blue); }
/* Quiet hours */
.qh-enable-row { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.qh-enable-lbl { font-size: 13px; color: var(--t2); cursor: pointer; user-select: none; }
.qh-fields { display: none; flex-direction: column; gap: 12px; }
.qh-fields.visible { display: flex; }
.qh-time-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.qh-time-lbl  { font-size: 13px; color: var(--t3); min-width: 36px; }
.qh-time-input { padding: 7px 11px; background: rgba(255,255,255,0.05); border: 1px solid var(--bdr); border-radius: 7px; color: var(--t1); font-size: 13px; font-family: inherit; outline: none; width: 110px; }
.qh-time-input:focus { border-color: rgba(59,130,246,0.5); background: rgba(59,130,246,0.04); }
.qh-day-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.qh-day-btn { padding: 4px 9px; border-radius: 5px; font-size: 11px; font-weight: 500; border: 1px solid var(--bdr); background: none; color: var(--t3); cursor: pointer; font-family: inherit; transition: background 0.12s, border-color 0.12s, color 0.12s; }
.qh-day-btn.active { background: rgba(59,130,246,0.12); border-color: rgba(59,130,246,0.35); color: var(--blue-t); }
.qh-preset-btn { padding: 4px 10px; border-radius: 5px; font-size: 11px; border: 1px solid var(--bdr2); background: rgba(255,255,255,0.04); color: var(--t4); cursor: pointer; font-family: inherit; transition: color 0.12s, background 0.12s; }
.qh-preset-btn:hover { color: var(--t2); background: rgba(255,255,255,0.07); }
.qh-preview-text { font-size: 12px; color: var(--t4); font-style: italic; padding: 6px 0 4px; min-height: 1.6em; }
/* Help & Documentation section */
.help-item { border: 1px solid var(--bdr); border-radius: 9px; overflow: hidden; margin-bottom: 8px; }
.help-item:last-child { margin-bottom: 0; }
.help-item-hdr { display: flex; align-items: center; gap: 10px; padding: 13px 16px; cursor: pointer; user-select: none; transition: background 0.12s; }
.help-item-hdr:hover { background: rgba(255,255,255,0.03); }
.help-item-title { font-size: 13px; font-weight: 600; color: var(--t2); flex: 1; }
.help-item-meta  { font-size: 11px; color: var(--t5); }
.help-chevron { font-size: 9px; color: var(--t5); transition: transform 0.18s; }
.help-item-hdr.open .help-chevron { transform: rotate(180deg); }
.help-item-body { display: none; border-top: 1px solid var(--bdr); padding: 20px; }
.help-item-body.open { display: block; }
.help-subsection { margin-bottom: 20px; }
.help-subsection:last-child { margin-bottom: 0; }
.help-sub-title { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--t4); margin-bottom: 10px; padding-bottom: 6px; border-bottom: 1px solid var(--bdr); }
.help-p { font-size: 13px; color: var(--t3); line-height: 1.65; margin-bottom: 10px; }
.help-p:last-child { margin-bottom: 0; }
.help-p strong { color: var(--t2); font-weight: 600; }
.help-callout { border-radius: 7px; padding: 11px 14px; margin-bottom: 12px; font-size: 12px; line-height: 1.55; }
.help-callout:last-child { margin-bottom: 0; }
.help-callout strong { font-weight: 600; }
.help-callout-blue  { background: rgba(59,130,246,0.08);  border-left: 3px solid rgba(59,130,246,0.4);  color: var(--blue-t);  }
.help-callout-amber { background: rgba(245,158,11,0.07);  border-left: 3px solid rgba(245,158,11,0.35); color: var(--amber-t); }
.help-callout-green { background: rgba(34,197,94,0.07);   border-left: 3px solid rgba(34,197,94,0.35);  color: var(--green-t); }
.help-rows { display: flex; flex-direction: column; gap: 7px; }
.help-row { display: flex; align-items: flex-start; gap: 12px; background: rgba(255,255,255,0.025); border: 1px solid var(--bdr2); border-radius: 7px; padding: 10px 14px; }
.help-row-icon { font-size: 15px; flex-shrink: 0; margin-top: 1px; line-height: 1; }
.help-row-dot  { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; margin-top: 4px; }
.help-row-lbl  { font-size: 12px; font-weight: 600; min-width: 148px; flex-shrink: 0; }
.help-row-desc { font-size: 12px; color: var(--t3); line-height: 1.5; }
.help-row-desc strong { color: var(--t2); font-weight: 600; }
.help-steps { counter-reset: hstep; display: flex; flex-direction: column; gap: 7px; }
.help-step { counter-increment: hstep; display: flex; gap: 12px; align-items: flex-start; background: rgba(255,255,255,0.025); border: 1px solid var(--bdr2); border-radius: 7px; padding: 10px 14px; }
.help-step-num { width: 20px; height: 20px; border-radius: 50%; background: rgba(255,255,255,0.09); color: var(--t2); font-size: 11px; font-weight: 700; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.help-step-num::before { content: counter(hstep); }
.help-step-body { font-size: 12px; color: var(--t3); line-height: 1.55; flex: 1; }
.help-step-body strong { color: var(--t2); font-weight: 600; }
.help-btn-mock { display: inline-block; padding: 1px 8px; border-radius: 4px; font-size: 11px; font-weight: 600; border: 1px solid; vertical-align: middle; margin: 0 2px; }
.help-btn-amber { background: rgba(245,158,11,0.1); border-color: rgba(245,158,11,0.4); color: var(--amber-t); }
.help-btn-grey  { background: rgba(107,114,128,0.1); border-color: rgba(107,114,128,0.3); color: var(--t4); }
.help-btn-x     { background: transparent; border-color: var(--bdr); color: var(--t4); }
.help-ref-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.help-ref-table th { text-align: left; padding: 7px 12px; background: rgba(255,255,255,0.04); border: 1px solid var(--bdr); font-weight: 600; color: var(--t4); font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em; }
.help-ref-table td { padding: 8px 12px; border: 1px solid var(--bdr2); vertical-align: top; color: var(--t3); }
.help-ref-table tbody tr:hover td { background: rgba(255,255,255,0.02); }
.help-guide-link { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--blue-t); text-decoration: none; margin-top: 16px; padding: 6px 12px; border-radius: 6px; border: 1px solid rgba(59,130,246,0.25); background: rgba(59,130,246,0.06); transition: background 0.12s, border-color 0.12s; }
.help-guide-link:hover { background: rgba(59,130,246,0.12); border-color: rgba(59,130,246,0.4); }


/* ============================================================
   THEME PICKER  (used in account-view Appearance section)
   ============================================================ */
.theme-picker {
  display: flex; gap: 10px;
}
.theme-opt {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 16px 12px; border-radius: 10px; cursor: pointer; font-family: inherit;
  background: var(--surf2); border: 2px solid var(--bdr);
  transition: border-color 0.15s, background 0.15s;
}
.theme-opt:hover  { border-color: var(--blue); }
.theme-opt.active { border-color: var(--blue); background: var(--blue-bg); }
.theme-opt-icon  { font-size: 24px; line-height: 1; }
.theme-opt-label { font-size: 13px; font-weight: 500; color: var(--t2); }


/* ============================================================
   LIGHT MODE  (html[data-theme="light"])
   Override design tokens then fix hardcoded dark-only values.
   ============================================================ */
html[data-theme="light"] {
  color-scheme: light;

  /* Surfaces — cool blue-indigo tint, echoes the dark palette */
  --bg:    #d8e0ef;
  --surf:  #e6ecf8;
  --surf2: #dde5f4;
  --surf3: #d4dced;

  /* Borders */
  --bdr:  rgba(0,0,0,0.10);
  --bdr2: rgba(0,0,0,0.06);

  /* Text — bumped opacity at t3–t5 for readability on tinted surfaces */
  --t1: #0d1117;
  --t2: #0d1117;
  --t3: rgba(13,17,23,0.80);
  --t4: rgba(13,17,23,0.62);
  --t5: rgba(13,17,23,0.50);

  /* Semantic tints — darker variants for legibility on light surfaces */
  --green-t:  #15803d;
  --red-t:    #dc2626;
  --amber-t:  #b45309;
  --blue-t:   #2563eb;

  /* Elevation */
  --card-shadow: 0 1px 0 rgba(255,255,255,0.55) inset, 0 2px 12px rgba(0,0,0,0.09), 0 1px 3px rgba(0,0,0,0.06);
}

/* Gradient blobs — light greens / blues */
html[data-theme="light"] body::before {
  background:
    radial-gradient(ellipse 75% 65% at  5%  5%, rgba(34,197,94,0.14)   0%, transparent 60%),
    radial-gradient(ellipse 55% 50% at 92% 88%, rgba(16,185,129,0.09)  0%, transparent 55%),
    radial-gradient(ellipse 40% 35% at 50% 50%, rgba(59,130,246,0.05)  0%, transparent 50%);
}
html[data-theme="light"] body::after {
  background:
    radial-gradient(ellipse 60% 55% at 95%  5%, rgba(59,130,246,0.10)  0%, transparent 55%),
    radial-gradient(ellipse 45% 40% at 10% 90%, rgba(6,182,212,0.07)   0%, transparent 50%);
}

/* Header stays night-mode even in light theme */
html[data-theme="light"] .header {
  background: rgba(18,19,28,0.92);
  --t1: #ffffff;
  --t2: #ffffff;
  --t3: rgba(255,255,255,0.82);
  --t4: rgba(255,255,255,0.62);
  --t5: rgba(255,255,255,0.46);
  --bdr:  rgba(255,255,255,0.10);
  --bdr2: rgba(255,255,255,0.06);
  --surf:  #1e2130;
  --surf2: #252840;
}
html[data-theme="light"] .header .dash-sw-btn:hover,
html[data-theme="light"] .header .dash-sw-btn.open    { background: rgba(255,255,255,0.07); color: #ffffff; }
html[data-theme="light"] .header .user-menu-item:hover { background: rgba(255,255,255,0.07); color: rgba(255,255,255,0.82); }
html[data-theme="light"] .header .poll-wrap.state-    { background: rgba(255,255,255,0.04); border-color: rgba(255,255,255,0.10); }

/* Toggle slider unchecked state */
html[data-theme="light"] .toggle-slider { background: rgba(0,0,0,0.14); }
/* Restore dark-mode slider track inside the dark header in light mode */
html[data-theme="light"] .header .toggle-slider { background: rgba(255,255,255,0.15); }

/* Select chevron — swap white arrow for dark one */
html[data-theme="light"] select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath fill='%23000000' fill-opacity='0.40' d='M0 0l5 6 5-6z'/%3E%3C/svg%3E");
}

/* Form inputs */
html[data-theme="light"] .form-group input,
html[data-theme="light"] .form-group select,
html[data-theme="light"] .form-group textarea,
html[data-theme="light"] .config-input,
html[data-theme="light"] .auth-box input { background: rgba(0,0,0,0.04); }

/* Nav / dropdown hover */
html[data-theme="light"] .dash-sw-btn:hover,
html[data-theme="light"] .dash-sw-btn.open    { background: rgba(0,0,0,0.06); color: var(--t1); }
html[data-theme="light"] .header-nav a:hover  { background: rgba(0,0,0,0.05); }
html[data-theme="light"] .header-nav a.active { background: rgba(0,0,0,0.07); }
html[data-theme="light"] .user-menu-item:hover { background: rgba(0,0,0,0.06); }
html[data-theme="light"] .user-menu { box-shadow: 0 8px 24px rgba(0,0,0,0.12); }

/* Tables */
html[data-theme="light"] .data-table tbody tr:hover td { background: rgba(0,0,0,0.02); }

/* Tabs */
html[data-theme="light"] .tabs { background: rgba(0,0,0,0.04); }

/* Badges with hardcoded white-based fills */
html[data-theme="light"] .badge-inactive,
html[data-theme="light"] .badge-never,
html[data-theme="light"] .badge-grey { background: rgba(0,0,0,0.06); }

/* Poll indicator neutral state */
html[data-theme="light"] .poll-wrap.state- { background: rgba(0,0,0,0.04); }

/* Buttons */
html[data-theme="light"] .btn-secondary           { background: rgba(0,0,0,0.05); }
html[data-theme="light"] .btn-secondary:hover      { background: rgba(0,0,0,0.09); color: var(--t1); }
html[data-theme="light"] .sound-btn,
html[data-theme="light"] .refresh-btn,
html[data-theme="light"] .expand-all-btn          { color: var(--t4); }
html[data-theme="light"] .sound-btn:hover,
html[data-theme="light"] .refresh-btn:hover,
html[data-theme="light"] .expand-all-btn:hover    { background: rgba(0,0,0,0.05); color: var(--t2); }

/* Prefs sortable */
html[data-theme="light"] .prefs-item.sortable-chosen {
  box-shadow: 0 6px 24px rgba(0,0,0,0.15);
  border-color: rgba(0,0,0,0.20);
}


/* ============================================================
   SIDEBAR NAVIGATION  (replaces the 20-item dropdown)
   ------------------------------------------------------------
   Fixed element + body padding, deliberately. Every page defines its own
   `.page { max-width; margin: 0 auto }`, so padding the body shrinks the
   available width and each page re-centres inside it with NO per-page edit.
   The sticky header and the footer live inside body too, so they inset for
   free. Built by cortex-shell.js; grouping follows the module map in CLAUDE.md.
   ============================================================ */

:root { --cx-side: 236px; }
/* Padding is OPT-IN, applied only once the shell has actually built the nav. The
   obvious inverse - pad by default, unpad when there is no nav - shifts every page
   sideways on load and snaps back, because the nav is built after auth resolves. */
body.cx-nav { padding-left: var(--cx-side); transition: padding-left .18s ease; }
body.cx-rail { --cx-side: 58px; }

.cx-side {
  position: fixed; left: 0; top: 0; bottom: 0; width: var(--cx-side);
  z-index: 101;                      /* above the fixed background layers (z-0) and the header (z-100) */
  background: linear-gradient(180deg, var(--nav-top) 0%, var(--nav-mid) 42%, var(--nav-bot) 100%);
  border-right: 1px solid rgba(255,255,255,.07);
  padding: 8px 8px 14px; overflow-y: auto; overflow-x: hidden;
  display: flex; flex-direction: column;
  transition: width .18s ease;
}
.cx-side::-webkit-scrollbar { width: 8px; }
.cx-side::-webkit-scrollbar-thumb { background: rgba(255,255,255,.10); border-radius: 4px; }

.cx-top { display: flex; align-items: center; gap: 9px; padding: 6px 8px 12px; }
.cx-glyph {
  width: 27px; height: 27px; border-radius: 7px; background: var(--nav-accent); flex: none;
  display: grid; place-items: center;
}
.cx-glyph svg { width: 16px; height: 16px; stroke: var(--t1); fill: none; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.cx-wm { font-size: 15px; font-weight: 700; color: var(--t1); letter-spacing: -.02em; white-space: nowrap; }
/* Same token the header brand uses - one wordmark, one blue. */
.cx-wm span { color: var(--blue-t); }

.cx-grp {
  font-size: 10px; letter-spacing: .06em; text-transform: uppercase;
  /* Same token the wordmark paints "tex" with, and the header brand uses for it -
     one blue across the chrome rather than a third neutral. */
  color: var(--blue-t); font-weight: 500; padding: 12px 10px 5px; white-space: nowrap;
}

.cx-i {
  display: flex; align-items: center; gap: 10px; padding: 7px 9px; margin-bottom: 1px;
  border-radius: 7px; color: var(--t3); font-size: 13px; text-decoration: none;
  position: relative; white-space: nowrap;
}
.cx-i:hover { background: rgba(255,255,255,.06); color: var(--t1); }
.cx-i.on { background: rgba(99,102,241,.22); color: var(--t1); box-shadow: inset 2px 0 0 var(--nav-accent); }
.cx-i svg { width: 17px; height: 17px; flex: none; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.cx-i .cx-lbl { flex: 1; overflow: hidden; text-overflow: ellipsis; }

/* Live-status badge. Empty by default and only painted once a count arrives, so
   a quiet system shows a clean nav rather than a column of zeros. */
.cx-badge { flex: none; font-size: 10.5px; font-weight: 600; line-height: 1; font-variant-numeric: tabular-nums; }
.cx-badge.on {
  padding: 2.5px 6px; border-radius: 99px;
  background: rgba(255,255,255,.10); color: var(--t3);
}
.cx-badge.lvl-crit { background: var(--red-bg);   color: var(--red-t); }
.cx-badge.lvl-warn { background: var(--amber-bg); color: var(--amber-t); }
.cx-badge.lvl-info { background: var(--blue-bg);  color: var(--blue-t); }

/* Collapsed rail: there is no room for a number beside a centred icon, so the
   badge becomes a dot pinned to the icon's corner - presence and severity still
   read, the exact count is one click away. */
body.cx-rail .cx-badge { display: none; }
body.cx-rail .cx-badge.on {
  display: block; position: absolute; top: 5px; right: 9px;
  width: 7px; height: 7px; padding: 0; border-radius: 50%;
  text-indent: -9999px; overflow: hidden;
  box-shadow: 0 0 0 2px var(--nav-mid);
}
/* A dot has no text to carry the colour, so it needs the SOLID token - the pill's
   10%-alpha fill is invisible at 7px. */
body.cx-rail .cx-badge.lvl-crit { background: var(--red); }
body.cx-rail .cx-badge.lvl-warn { background: var(--amber); }
body.cx-rail .cx-badge.lvl-info { background: var(--blue); }
.cx-i:focus-visible { outline: 2px solid var(--blue-t); outline-offset: -2px; }

.cx-foot { margin-top: auto; padding-top: 10px; }
.cx-toggle {
  display: flex; align-items: center; gap: 10px; width: 100%; padding: 7px 9px;
  border: 0; border-radius: 7px; background: transparent; color: var(--t4);
  font-family: inherit; font-size: 12.5px; cursor: pointer; white-space: nowrap;
}
.cx-toggle:hover { background: rgba(255,255,255,.06); color: var(--t1); }
.cx-toggle svg { width: 16px; height: 16px; flex: none; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; transition: transform .18s ease; }
body.cx-rail .cx-toggle svg { transform: rotate(180deg); }

/* ── collapsed rail ──
   Labels go, icons centre, and the item keeps its full hit area. A title
   attribute carries the name, since the label is no longer on screen. */
body.cx-rail .cx-side { padding: 8px 7px 14px; }
body.cx-rail .cx-i { justify-content: center; padding: 9px 0; gap: 0; }
body.cx-rail .cx-i .cx-lbl { display: none; }
body.cx-rail .cx-wm { display: none; }
body.cx-rail .cx-top { justify-content: center; padding: 6px 0 12px; }
body.cx-rail .cx-grp {
  /* A hairline instead of a word - the group still separates, without a cramped label. */
  font-size: 0; padding: 7px 6px; margin: 2px 0;
  border-top: 1px solid rgba(255,255,255,.08);
}
/* Adjacent-sibling, NOT :first-of-type - that matches the first element of a TAG
   among siblings, and the first div here is .cx-top, so it never matched a group
   and the first one kept a stray hairline under the logo. */
body.cx-rail .cx-top + .cx-grp { border-top: 0; }
body.cx-rail .cx-toggle { justify-content: center; padding: 9px 0; gap: 0; }
body.cx-rail .cx-toggle span { display: none; }

/* ── the header's hamburger: only useful on narrow screens ── */
.cx-burger {
  display: none; align-items: center; justify-content: center;
  width: 32px; height: 32px; border: 0; border-radius: 8px;
  background: transparent; color: var(--t3); cursor: pointer; flex: none;
}
.cx-burger:hover { background: rgba(255,255,255,.07); color: var(--t1); }
.cx-burger svg { width: 19px; height: 19px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; }

.cx-backdrop { display: none; }

/* ── narrow: off-canvas, opened from the header ── */
@media (max-width: 900px) {
  body.cx-nav, body.cx-rail { padding-left: 0; }
  .cx-side { width: 236px; transform: translateX(-100%); transition: transform .2s ease; box-shadow: 0 0 40px rgba(0,0,0,.5); }
  body.cx-open .cx-side { transform: none; }
  /* The rail makes no sense off-canvas - if it opens, it opens with labels. */
  body.cx-rail .cx-i { justify-content: flex-start; padding: 7px 9px; gap: 10px; }
  body.cx-rail .cx-i .cx-lbl { display: block; }
  body.cx-rail .cx-wm { display: block; }
  body.cx-rail .cx-top { justify-content: flex-start; padding: 6px 8px 12px; }
  body.cx-rail .cx-grp { font-size: 10px; padding: 12px 10px 5px; border-top: 0; }
  body.cx-rail .cx-badge.on { position: static; width: auto; height: auto;
    padding: 2.5px 6px; border-radius: 99px; text-indent: 0; box-shadow: none; }
  /* The collapse toggle is meaningless off-canvas in EITHER state - the drawer
     is always full width here - so hide the whole foot, not just the railed one. */
  .cx-foot { display: none; }
  /* Only when a sidebar actually exists - a user with one dashboard gets no nav,
     and an un-gated burger would be a button that opens nothing. */
  body.cx-nav .cx-burger { display: flex; }
  body.cx-open .cx-backdrop {
    display: block; position: fixed; inset: 0; z-index: 100;
    background: rgba(0,0,0,.5); backdrop-filter: blur(2px);
  }
}

/* The switcher becomes a plain label once the sidebar owns navigation: no chevron,
   no hover, no pointer, and disabled must not grey the text out - it is a label. */
.dash-sw.static .dash-sw-chev { display: none; }
.dash-sw.static .dash-sw-btn,
.dash-sw.static .dash-sw-btn:hover,
.dash-sw.static .dash-sw-btn:disabled {
  cursor: default; background: transparent; border-color: transparent;
  opacity: 1; color: var(--t1);
}

html[data-theme="light"] .cx-side {
  /* The sidebar keeps its own dark identity in both themes - it is the tray's
     surface, not the page's. Only the hairlines soften. */
  border-right-color: rgba(0,0,0,.14);
}

/* ============================================================
   REDUCED MOTION
   ------------------------------------------------------------
   Scoped deliberately to the decorative motion rather than a blanket `*` clamp.
   A global animation-duration override also hits the spinners - .spin-dot here and
   .spinner on the login page - and a frozen spinner is a broken progress indicator,
   not a calmer one. What stops here is the background drift and the chrome's
   transitions; colours, layout and every progress signal are unchanged.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  /* Hold the gradient at its 0% keyframe - the composition the palette was picked against. */
  body::before, body::after { animation: none; }

  /* Sidebar chrome: collapse still works, it just arrives instantly. */
  body.cx-nav { transition: none; }
  .cx-side { transition: none; }
  .cx-toggle svg { transition: none; }
}
