/* ============================================================
   DEFCOR — Command Center Design System V3 (Aug 2026)
   Dark ops-console. Re-cut from the DEFCOR placard mark:
   black field -> white frame -> indigo field -> white type.
   V1 was amber (#ffb020); V2 was GTOA coral (#f0475c). Both retired
   from chrome. Amber survives as ADVISORY only; red as CRITICAL only.

   ------------------------------------------------------------
   LAW 1 — HUE ENCODES CATEGORY; LUMINANCE AND FILL ENCODE STATE.
   LAW 2 — PILLARS NEVER FILL.
       Taxonomy  = transparent ground + 1px steel border
                   + 3px hue rail + 2-letter mono code.
                   The hue is 3px wide and never touches the text.
       Condition = the GROUND is the signal. Fill progression.
                   Never a rail, never a code.
     If it has a rail and a code it is a CATEGORY.
     If its ground is doing the talking it is a STATE.
   ------------------------------------------------------------
   CHROME / CONTENT FIREWALL — do not cross it.
   The hexes below style the APP. They must never reach generated
   content. GTOA's real colours live in BRAND_LOCK (assets/js/app.js)
   and in pages/explainer.html's canvas renderer, and #5457e8 /
   #8b90f8 are on GTOA's forbiddenColors list precisely so the
   content path rejects this accent. See CLAUDE.md rule 4.
============================================================ */

:root {
  /* ---- Layer 1 of the mark. The eye's black reference. -------------
     Used ONLY behind the lockup (sidebar plinth, auth, 404). Against
     real black, #08090c reads as deliberate near-black rather than
     drifting toward generic dark-SaaS grey. Do not repurpose. */
  --ink-true: #000000;

  /* ---- Surfaces ---- */
  --bg-base:     #08090c;
  --bg-surface:  #0e1015;
  --bg-elevated: #14171f;
  --bg-panel:    #1a1e28;
  --bg-hover:    #222736;
  --bg-inset:    #050609;

  /* ---- Borders. Structure is carried by frames, not by lightness. --
     border-subtle/default are DECORATIVE separators (1.4-1.5:1) and
     must never be the sole boundary of an interactive control.
     Anything focusable or clickable uses --border-frame (>=3.45:1 on
     every surface in the ramp -> clears WCAG 1.4.11). */
  --border-subtle:    #1c202c;
  --border-default:   #2a3040;
  --border-strong:    #414a61;
  --border-frame:     #6e7a94;
  --border-frame-hot: #cfd6e6;
  --border-dashed:    #333b4d;

  /* ---- Text. --text-faint is NOT a text colour: it is reserved for
     the version stamp and divider glyphs, which carry no information.
     Every eyebrow that means something uses --text-tertiary. */
  --text-primary:   #f2f4f8;
  --text-secondary: #a3acc2;
  --text-tertiary:  #7d8aa4;
  --text-faint:     #737f96;   /* lifted from #646f88 — measured 3.78:1 in the sidebar, now clears AA */
  --on-accent:      #ffffff;

  /* ============================================================
     THE ACCENT — SPLIT IN TWO. THIS IS LOAD-BEARING.

     --accent-field #5457e8 measures 3.70:1 as TEXT on --bg-base.
     IT FAILS AA. It is a BACKGROUND, a BORDER, or a 2px RULE.
     Never `color: var(--accent-field)`. Never.

     --accent-ink #8b90f8 is the ONLY blue permitted as text (7.06:1).

     Deploy checklist: grep for `color:\s*var\(--accent-field\)`
     and `color:\s*var\(--accent\)` — both must return zero hits.
     ============================================================ */
  --accent-field:       #5457e8;  /* GROUND ONLY — 3.70:1 as text, fails AA */
  --accent-field-hover: #5d60ee;  /* white on it = 4.80:1, still AA */
  --accent-field-down:  #4a4dd6;  /* white on it = 6.32:1 */
  --accent-deep:        #3b3fbf;
  --accent-ink:         #8b90f8;  /* TEXT — 7.06:1 on base */
  --accent-ink-hover:   #a3a8ff;  /* 9.10:1 on base */

  /* Derived washes use color-mix on the token, never fresh rgba().
     color-mix is already in production here (app.css:936,
     generate.html:49/240). This makes the next accent change a
     one-line edit instead of a 20-file grep. */
  --accent-soft: color-mix(in srgb, var(--accent-field) 14%, transparent);
  --accent-line: color-mix(in srgb, var(--accent-field) 38%, transparent);

  /* Secondary accent — RETIRED FROM CHROME. Retained solely as the
     J Solutions brand dot. A second cool accent anywhere structural
     dilutes the indigo and destroys the scarcity this system runs on. */
  --accent-2: #2bc4d4;

  /* ============================================================
     CONDITION LADDER — one ordered escalation scale, four rungs.
     Warm hue is QUARANTINED to escalation. Nothing decorative is
     ever warm, so warmth appearing on screen is information by
     itself: a calm board is a blue board.
     Retune escalation HERE and nowhere else.
     ============================================================ */
  --ready-5: #00d68f;            /* ALL-CLEAR */
  --ready-4: var(--accent-field);/* NOMINAL   — resting state */
  --ready-3: #ffb020;            /* ADVISORY  */
  --ready-1: #ff4d6a;            /* CRITICAL  */
  --ready-0: var(--border-frame);/* UNKNOWN   — no condition data. NOT nominal. */

  /* Status tokens are ALIASES onto the ladder, not independent hues. */
  --status-success: var(--ready-5);
  --status-warning: var(--ready-3);
  --status-danger:  var(--ready-1);
  --status-error:   var(--ready-1);  /* was referenced at spend.html:56 and never defined — live bug, now fixed */
  --status-info:    var(--accent-ink); /* info IS the system talking. One blue, one meaning. */

  /* ============================================================
     TAXONOMY (pillars). Blue is EVICTED from the categorical
     palette: nothing sits within 53 degrees of the accent, so the
     265-335 deg arc is reserved outright. All four are DESATURATED
     relative to every signal (chroma 34-42 vs 58-85), which is what
     lets the accent read as the only high-chroma hue in the chrome.
     Per LAW 2 these appear ONLY as a 3px rail — never as fill,
     never as text.
     ============================================================ */

  /* ---- CLIENT BRAND COLOURS — CONTENT VALUES, MIRRORED HERE ONLY
     so brand dots can show a client's real colour inside a blue app.
     THESE ARE NOT CHROME. Never rebrand them. --brand-gtoa mirrors
     BRAND_LOCK.gtoa.brandColor. */
  --brand-gtoa:       #d63a50;
  --brand-jsolutions: #2bc4d4;

  /* ---- Geometry. The mark has sharp corners and a hard frame. ---- */
  --r-sm:   2px;
  --r-md:   3px;
  --r-lg:   4px;
  --r-xl:   5px;
  --r-pill: 2px;   /* placards do not have lozenges */

  /* ---- Type ---- */
  --font-sans:    'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-display: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono:    'JetBrains Mono', 'SF Mono', Monaco, monospace;
  --track-tight:   -0.03em;
  --track-label:    0.14em;
  --track-placard:  0.06em;

  /* ---- Depth. Zero gradients, zero softness, zero glow. ---------
     NOTE: --accent-glow and --shadow-glow are DELETED, not zeroed.
     All 7 consumers are removed in the same pass (see change list).
     Do not reintroduce them. */
  --shadow-sm: 0 1px 0 rgba(0,0,0,0.6);
  --shadow-md: 0 2px 0 rgba(0,0,0,0.5);
  --shadow-lg: 0 0 0 1px var(--border-frame), 0 24px 60px rgba(0,0,0,0.72);
  --ring-frame:     0 0 0 1px var(--border-frame);
  --ring-frame-hot: 0 0 0 1px var(--border-frame-hot);
  --ring-focus:     0 0 0 2px var(--bg-base), 0 0 0 4px var(--border-frame-hot);
  --hair-top:  inset 0 1px 0 rgba(255,255,255,0.06);
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body {
  background: var(--bg-base);
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
}

body { background: var(--bg-base); }

/* CHASSIS — the whole app sits inside a placard. z-index 1200 keeps it above
   toast (1000) and the modals (1000) so the frame never vanishes mid-flow;
   pointer-events:none means it can never eat a click. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  border: 1px solid var(--border-frame);
  pointer-events: none;
  z-index: 1200;
}

/* ---------- LAYOUT ---------- */
.app {
  display: grid;
  grid-template-columns: 220px 1fr;
  min-height: 100vh;
}

.sidebar {
  background: var(--bg-surface);
  border-right: 1px solid var(--border-subtle);
  padding: 20px 0;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

/* LOCKUP — layer 1 of the mark (true black) bled to the sidebar edges, with the
   badge itself sitting on it. This is the only place the full four-layer
   construction appears, so every other blue in the app reads as a fragment of it. */
.sidebar-brand {
  background: var(--ink-true);
  margin: -20px 0 14px;
  padding: 20px 20px 18px;
  border-bottom: 1px solid var(--border-subtle);
  text-align: center;
}

.sidebar-brand-logo {
  display: inline-block;
  background: var(--accent-field);
  border: 2px solid #fff;
  border-radius: 1px;
  padding: 7px 12px 8px;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 19px;
  line-height: 1;
  letter-spacing: var(--track-tight);
  text-transform: uppercase;
  color: var(--on-accent);
}

.sidebar-brand-sub {
  font-size: 11px;
  color: var(--text-tertiary);
  margin-top: 4px;
  font-family: var(--font-mono);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 0 12px;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-radius: var(--r-sm);
  color: var(--text-secondary);
  text-decoration: none;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.15s;
  border: 1px solid transparent;
}

.nav-item:hover {
  background: var(--bg-elevated);
  color: var(--text-primary);
}

.nav-item.active {
  background: var(--accent-field);
  color: var(--on-accent);
  border-color: var(--border-frame-hot);
  font-weight: 600;
}

.nav-section {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-tertiary);
  padding: 16px 12px 6px;
  font-family: var(--font-mono);
}

.main {
  padding: 24px 32px;
  max-width: 1400px;
}

/* ---------- HEADERS ---------- */
.page-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 24px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--border-subtle);
}

.page-title {
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.page-subtitle {
  color: var(--text-secondary);
  font-size: 13px;
  margin-top: 4px;
}

/* ---------- BUTTONS ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: var(--r-sm);
  font-size: 13px;
  font-weight: 500;
  border: 1px solid var(--border-default);
  background: var(--bg-elevated);
  color: var(--text-primary);
  cursor: pointer;
  transition: all 0.15s;
  font-family: inherit;
  white-space: nowrap;
}

.btn:hover {
  background: var(--bg-hover);
  border-color: var(--border-strong);
}


.btn-primary {
  background: var(--accent-field);
  color: var(--on-accent);
  border: 1px solid var(--border-frame-hot);
  border-radius: var(--r-sm);
  font-family: var(--font-display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: var(--track-placard);
  text-shadow: none;
  box-shadow: var(--hair-top);
}

.btn-primary:hover {
  background: var(--accent-field-hover);
  border-color: #fff;
  box-shadow: var(--hair-top), 0 0 0 3px var(--accent-soft);
  transform: none;
}

.btn-primary:active {
  background: var(--accent-field-down);
  transform: none;
  box-shadow: inset 0 2px 4px rgba(0,0,0,.35);
}

.btn-ghost {
  background: transparent;
  border-color: transparent;
}

.btn-ghost:hover {
  background: var(--bg-elevated);
}

.btn-danger {
  color: var(--status-danger);
  border-color: rgba(255,77,106,0.2);
}

.btn-danger:hover {
  background: rgba(255,77,106,0.1);
  border-color: var(--status-danger);
}

.btn-sm { padding: 5px 10px; font-size: 12px; }
.btn-lg { padding: 11px 20px; font-size: 14px; }

/* ---------- CARDS ---------- */
.card {
  background: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--r-md);
  padding: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border-subtle);
}

.card-title {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.card-subtitle {
  font-size: 12px;
  color: var(--text-tertiary);
  font-family: var(--font-mono);
}

/* ---------- FORMS ---------- */
.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 16px;
}

.label {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-family: var(--font-mono);
}

.label-help {
  font-size: 11px;
  color: var(--text-tertiary);
  text-transform: none;
  letter-spacing: 0;
  font-family: var(--font-sans);
  margin-top: -2px;
}

.input, .textarea, .select {
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  border-radius: var(--r-sm);
  padding: 9px 12px;
  color: var(--text-primary);
  font-size: 13px;
  font-family: inherit;
  width: 100%;
  transition: border-color 0.15s;
}

.input:focus, .textarea:focus, .select:focus {
  outline: none;
  border-color: var(--accent-field);
  background: var(--bg-panel);
}

.textarea {
  resize: vertical;
  min-height: 80px;
  line-height: 1.5;
  font-family: var(--font-sans);
}

.textarea-mono {
  font-family: var(--font-mono);
  font-size: 12px;
}

/* ---------- BADGES / TAGS ---------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 8px;
  border-radius: var(--r-sm);
  font-size: 11px;
  font-weight: 500;
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background: var(--bg-elevated);
  color: var(--text-secondary);
  border: 1px solid var(--border-subtle);
}

/* LAW 2 — taxonomy NEVER fills. The hue is a 3px rail that never touches the
   text, so category survives colour-blindness and thumbnail size; the two-letter
   code carries the meaning. Contrast with .status-tag above, where the GROUND is
   the signal. If it has a rail and a code it is a category; if its ground is
   doing the talking it is a state. */
.chip-pillar {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  position: relative;
  padding: 3px 8px 3px 11px;
  background: transparent;
  color: var(--text-secondary);
  border: 1px solid var(--border-default);
  border-radius: var(--r-sm);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: var(--track-placard);
  text-transform: uppercase;
  line-height: 1.4;
  overflow: hidden;
}
.chip-pillar::before {
  content: '';
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--rail, var(--border-strong));
}
.chip-code { font-style: normal; font-weight: 600; color: var(--text-primary); letter-spacing: 0.02em; }

.stat-cell { border-left: 2px solid var(--rail, var(--border-default)); padding-left: 9px; }
.stat-cell .stat-label { color: var(--text-tertiary); }

/* ---------- UTILS ---------- */
.row { display: flex; gap: 12px; align-items: center; }
.col { display: flex; flex-direction: column; gap: 12px; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px; }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.spacer { flex: 1; }
.hide { display: none !important; }

.text-mono { font-family: var(--font-mono); }
.text-sm { font-size: 12px; }
.text-xs { font-size: 11px; }
.text-secondary { color: var(--text-secondary); }
.text-tertiary { color: var(--text-tertiary); }
.text-accent { color: var(--accent-ink); }

/* ---------- SCROLLBAR ---------- */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: var(--bg-base); }
::-webkit-scrollbar-thumb { background: var(--border-default); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: var(--border-strong); }

/* ---------- TOAST ---------- */
.toast {
  position: fixed;
  top: 20px;
  right: 20px;
  background: var(--bg-panel);
  border: 1px solid var(--border-default);
  border-left: 3px solid var(--accent-field);
  padding: 12px 16px;
  border-radius: var(--r-sm);
  font-size: 13px;
  box-shadow: var(--shadow-lg);
  z-index: 1000;
  animation: slideIn 0.2s ease;
}

.toast.success { border-left-color: var(--status-success); }
.toast.error { border-left-color: var(--status-danger); }

@keyframes slideIn {
  from { transform: translateX(20px); opacity: 0; }
  to { transform: translateX(0); opacity: 1; }
}

/* ---------- AUTH PAGE ---------- */
.auth-wrap {
  display: grid;
  place-items: center;
  min-height: 100vh;
  padding: 20px;
}

.auth-card {
  width: 100%;
  max-width: 400px;
  background: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--r-lg);
  padding: 40px 32px;
  text-align: center;
}

.auth-logo {
  display: inline-block;
  background: var(--accent-field);
  border: 2px solid #fff;
  border-radius: 1px;
  padding: 10px 17px 11px;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 26px;
  line-height: 1;
  letter-spacing: var(--track-tight);
  text-transform: uppercase;
  color: var(--on-accent);
}

.auth-sub {
  color: var(--text-tertiary);
  font-size: 12px;
  font-family: var(--font-mono);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin-bottom: 32px;
}

.auth-tagline {
  color: var(--text-secondary);
  font-size: 13px;
  margin-bottom: 32px;
  line-height: 1.6;
}

.auth-btn {
  width: 100%;
  padding: 12px;
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  border-radius: var(--r-sm);
  color: var(--text-primary);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  transition: all 0.15s;
}

.auth-btn:hover {
  background: var(--bg-hover);
  border-color: var(--border-strong);
}

/* ---------- BRAND CARD (on brands page) ---------- */
.brand-card {
  background: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--r-md);
  overflow: hidden;
  transition: border-color 0.15s;
}

.brand-card:hover { border-color: var(--border-default); }

.brand-card-header {
  padding: 16px 20px;
  border-bottom: 1px solid var(--border-subtle);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.brand-color-dot {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  display: inline-block;
}

.brand-card-body {
  padding: 16px 20px;
}

.brand-card-footer {
  padding: 12px 20px;
  border-top: 1px solid var(--border-subtle);
  background: var(--bg-base);
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  color: var(--text-tertiary);
  font-family: var(--font-mono);
}

/* Pillar mix bar */
.mix-bar {
  display: flex;
  height: 6px;
  border-radius: 3px;
  overflow: hidden;
  background: var(--bg-elevated);
}

.mix-bar-segment { height: 100%; }

/* Pillar editor */
.pillar-row {
  display: grid;
  grid-template-columns: 12px 1fr 80px 32px;
  gap: 12px;
  align-items: center;
  padding: 8px 12px;
  background: var(--bg-elevated);
  border-radius: var(--r-sm);
  margin-bottom: 6px;
}

.pillar-color-dot {
  width: 10px;
  height: 10px;
  border-radius: 3px;
}


/* ============================================================
   POLISH PASS — refined interactions + missing states
   Added 2026-05-27 to bring everything to "super clean" level.
============================================================ */

/* ---------- LOADING / SKELETON ---------- */
@keyframes shimmer {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}

.loading-shimmer,
.skeleton-line {
  background: linear-gradient(
    90deg,
    var(--bg-elevated) 0%,
    var(--bg-panel) 50%,
    var(--bg-elevated) 100%
  );
  background-size: 200% 100%;
  animation: shimmer 1.6s ease-in-out infinite;
  border-radius: var(--r-sm);
}

.skeleton-line {
  height: 12px;
  margin-bottom: 8px;
}
.skeleton-line:last-child { margin-bottom: 0; }
.skeleton-line.short { width: 60%; }
.skeleton-line.tall { height: 32px; margin-bottom: 14px; }

.spinner-sm {
  width: 14px;
  height: 14px;
  border: 2px solid var(--border-default);
  border-top-color: var(--accent-ink);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
  display: inline-block;
  vertical-align: middle;
}

/* ---------- LAYOUT: sidebar gets a footer slot ---------- */
.sidebar {
  display: flex;
  flex-direction: column;
}

.sidebar-footer {
  margin-top: auto;
  padding: 14px 20px;
  border-top: 1px solid var(--border-subtle);
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.sidebar-footer-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.sidebar-footer-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--status-success);
}

/* ---------- NAV: left-edge accent on active ---------- */
.nav-item {
  position: relative;
}

/* ---------- FOCUS RINGS (subtle, keyboard-friendly, polished) ---------- */
.btn:focus-visible,
.nav-item:focus-visible,
.filter-btn:focus-visible,
.copy-btn:focus-visible {
  outline: none;
  box-shadow: var(--ring-focus);
  outline-offset: 2px;
}

.input:focus,
.textarea:focus,
.select:focus {
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* ---------- CARD / ROW HOVER (subtle lift across surfaces) ---------- */
.brand-card,
.queue-card,
.brand-row,
.history-item {
  transition: transform 0.15s ease, border-color 0.15s ease, box-shadow 0.18s ease;
}

.brand-card:hover,
.queue-card:hover,
.brand-row:hover {
  border-color: var(--border-default);
}

/* ---------- EMPTY STATES (unified, used everywhere now) ---------- */
.empty-state {
  background: var(--bg-surface);
  border: 1px dashed var(--border-default);
  border-radius: var(--r-md);
  padding: 60px 24px;
  text-align: center;
  color: var(--text-tertiary);
  font-size: 13px;
  line-height: 1.6;
}

.empty-state-title {
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-tertiary);
  margin-bottom: 10px;
}

.empty-state a { color: var(--accent-ink); text-decoration: none; }
.empty-state a:hover { text-decoration: underline; }

/* ---------- STATUS TAGS (shared, refined) ---------- */
.status-tag {
  display: inline-block;
  padding: 2px 7px;
  border: 1px solid transparent;   /* rungs below set only border-color */
  border-radius: var(--r-sm);
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 500;
  line-height: 1.4;
}
.status-tag.status-idea      { background: transparent;         color: var(--text-tertiary);  border: 1px dashed var(--border-dashed); }
.status-tag.status-script    { background: transparent;         color: var(--text-secondary); border-color: var(--border-strong); }
.status-tag.status-asset     { background: var(--bg-panel);     color: var(--text-primary);   border-color: var(--border-frame); }
.status-tag.status-scheduled { background: var(--accent-field); color: var(--on-accent);      border-color: var(--border-frame-hot); font-weight: 600; }
.status-tag.status-posted    { background: var(--bg-elevated);  color: var(--text-tertiary);  border-color: var(--border-subtle); }

/* ---------- TILE refinement (data-first typography) ---------- */
.tile-value {
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.025em;
}

/* ---------- BUTTONS — refined ---------- */
.btn-primary {
  box-shadow: 0 1px 0 rgba(255,255,255,0.08) inset, var(--shadow-sm);
}
.btn-primary:active {
  transform: translateY(0);
}

/* ---------- COPY BUTTON (used in generate + queue) ---------- */
.copy-btn {
  background: transparent;
  border: 1px solid var(--border-subtle);
  color: var(--text-tertiary);
  font-size: 10px;
  font-family: var(--font-mono);
  padding: 3px 8px;
  border-radius: 3px;
  cursor: pointer;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  transition: all 0.12s ease;
}
.copy-btn:hover {
  border-color: var(--accent-field);
  color: var(--accent-ink);
  background: var(--accent-soft);
}

/* ---------- MIX BAR (grows slightly on hover for visual feedback) ---------- */
.mix-bar { transition: height 0.18s ease; }
.brand-card:hover .mix-bar { height: 8px; }

/* ---------- MODAL POLISH ---------- */
.modal-overlay {
  animation: fadeIn 0.18s ease;
}
.modal-detail {
  box-shadow: var(--shadow-lg);
  animation: slideUp 0.22s ease;
}

@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes slideUp {
  from { transform: translateY(12px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}

/* ---------- PAGE FADE-IN ---------- */
.main {
  animation: fadeIn 0.22s ease;
}

/* ---------- TOAST refined (slightly larger, longer breathing room) ---------- */
.toast {
  font-family: var(--font-sans);
  min-width: 240px;
  max-width: 380px;
  font-weight: 500;
}

/* ---------- SCROLLBAR refined ---------- */
::-webkit-scrollbar-thumb {
  background: var(--border-default);
  border-radius: 4px;
  border: 2px solid var(--bg-base);
}
::-webkit-scrollbar-thumb:hover { background: var(--border-strong); }

/* Brand dot: the client's real colour, flat. A GTOA red dot inside a blue app
   is correct — it identifies whose row this is; it is not a chrome leak. */
.brand-row:hover .brand-color-dot,
.brand-card:hover .brand-color-dot {
  box-shadow: 0 0 0 1px var(--border-frame);
}

/* ---------- POST FORMAT TAG REFINEMENTS (Generate v2 chips) ---------- */
.post-format-tags .format-tag {
  font-variant: tabular-nums;
}

/* ---------- LINKS (subtle accent on hover) ---------- */
a {
  color: var(--accent-ink);
  text-decoration: none;
  transition: color 0.12s;
}
/* INK, never field — and scoped off button-shaped anchors, because a:hover
   (0,1,1) outranks .btn-primary (0,1,0) and would repaint their labels. */
a:not(.btn):not(.nav-item):hover { color: var(--accent-ink-hover); }
.btn:hover, .btn-primary:hover, .nav-item:hover { color: inherit; }
.btn-primary, .btn-primary:hover { color: var(--on-accent); }
.nav-item.active, .nav-item.active:hover { color: var(--on-accent); }

/* ---------- SELECTION ---------- */
::selection {
  background: var(--accent-field);
  color: #fff;
}

/* ---------- TEXT ACCENT helper ---------- */
.text-accent { color: var(--accent-ink); }
.text-accent-dim { color: var(--accent-deep); }

/* ---------- KBD (keyboard shortcut hint) ---------- */
kbd {
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  border-bottom-width: 2px;
  border-radius: 3px;
  padding: 1px 6px;
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-secondary);
  line-height: 1.4;
}


/* ============================================================
   V2 ADDITIONS (Aug 2026)
============================================================ */

/* NEW tag in the sidebar nav (teal so it doesn't fight the coral accent) */
.nav-badge {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--accent-2);
  background: color-mix(in srgb, var(--accent-2) 10%, transparent);
  border: 1px solid rgba(43,196,212,0.25);
  padding: 1px 6px;
  border-radius: var(--r-pill);
  margin-left: auto;
}

/* Preset chips (Explainer Studio series presets) */
.preset-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.preset-chip {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.03em;
  color: var(--text-secondary);
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  padding: 5px 11px;
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: all 0.13s ease;
}
.preset-chip:hover { border-color: var(--accent-field); color: var(--accent-ink); background: var(--accent-soft); }
.preset-chip.active { border-color: var(--accent-field); color: var(--accent-ink); background: var(--accent-soft); }

/* Slide strip previews (Explainer Studio) */
.slide-strip {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 10px;
}
.slide-thumb {
  border: 1px solid var(--border-subtle);
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--bg-elevated);
  position: relative;
}
.slide-thumb img { width: 100%; display: block; }
.slide-thumb .n {
  position: absolute; top: 6px; left: 6px;
  font-family: var(--font-mono); font-size: 9px; color: #fff;
  background: rgba(0,0,0,0.65); padding: 1px 6px; border-radius: var(--r-pill);
}


/* ---------- SCENARIO PROPOSER (Aug 2026) ---------- */
.idea-list { display: flex; flex-direction: column; gap: 10px; }
.idea-card {
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  border-radius: var(--r-sm);
  padding: 13px 15px;
  cursor: pointer;
  transition: border-color 0.14s, transform 0.14s, background 0.14s;
}
.idea-card:hover { border-color: var(--accent-field); background: var(--accent-soft); }
.idea-card.rec { border-color: color-mix(in srgb, var(--accent-field) 45%, var(--border-default)); }
.idea-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 7px; }
.idea-title { font-size: 13.5px; font-weight: 700; letter-spacing: -0.01em; }
.idea-pick {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--accent-ink); background: var(--accent-soft); border: 1px solid color-mix(in srgb, var(--accent-field) 40%, transparent);
  padding: 2px 7px; border-radius: var(--r-pill); white-space: nowrap;
}
.idea-obj {
  font-size: 12px; font-style: italic; color: var(--text-secondary);
  border-left: 2px solid var(--accent-field); padding-left: 9px; margin-bottom: 7px; line-height: 1.5;
}
.idea-open { font-size: 12.5px; color: var(--text-primary); line-height: 1.5; margin-bottom: 5px; }
.idea-angle { font-size: 11.5px; color: var(--text-tertiary); line-height: 1.5; }
.idea-why {
  font-family: var(--font-mono); font-size: 10.5px; color: var(--accent-ink);
  margin-top: 8px; padding-top: 7px; border-top: 1px solid var(--border-subtle); line-height: 1.5;
}


/* ---------- MOVE 9: hover has a body, and the spinner that never spun ----------
   @keyframes spin previously existed only inside generate.html and explainer.html,
   so .spinner-sm animated on those two pages and sat frozen everywhere else, and
   .spinner was used (spend, generate, explainer) without ever being defined here. */
@keyframes spin { to { transform: rotate(360deg); } }

.spinner {
  width: 22px; height: 22px;
  border: 2px solid var(--border-default);
  border-top-color: var(--accent-ink);   /* ink: at 2px the field vanishes into the track */
  border-radius: 50%;
  animation: spin .7s linear infinite;
  display: inline-block;
}
.spinner-sm { border-top-color: var(--accent-ink); }

/* With zero glow, zero lift and zero gradient, hover would collapse to a border
   tint and read as unresponsive. Three flat bits instead: surface step, frame
   brightening, and a 1px inset top hairline. */
.card:hover, .brand-card:hover, .queue-card:hover, .brand-row:hover, .runs tbody tr:hover {
  transform: none;
  background: var(--bg-hover);
  border-color: var(--border-frame);
  box-shadow: var(--hair-top);
}

/* ---------- MOVE 8: wordmark numerals + telemetry figures ----------
   The mark's defining property is weight, not hue — this is what makes the
   rebrand survive a greyscale screenshot. tabular-nums stops columns jittering
   between renders; slashed-zero disambiguates 0 from O in run IDs and costs. */
.tile-value, .kpi-value, .cadence-cell .num {
  font-family: var(--font-display);
  font-weight: 800;
  letter-spacing: var(--track-tight);
}
.kpi-value.accent { color: var(--accent-ink); }

.text-mono, .badge, .chip-pillar, .status-tag, kbd, code,
.tile-value, .kpi-value, .runs td.num, .bar-val, .cadence-cell .num {
  font-variant-numeric: tabular-nums slashed-zero;
  font-feature-settings: 'tnum' 1, 'zero' 1;
}

.page-title {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 19px;
  text-transform: uppercase;
  letter-spacing: 0.005em;
}

.tile-label, .kpi-label, .nav-section, .stat-label,
.empty-state-title, .sidebar-footer, .runs th {
  letter-spacing: var(--track-label);
}
.sidebar-footer span:last-child { color: var(--text-faint); }

/* ---------- MOVE 5: the readiness rule ----------
   Warm hue is quarantined to escalation, so a calm board is a blue board.
   Default is STEEL, not nominal — the app never claims a health state it
   doesn't have data for. Wired from setReady() in app.js. */
.main { position: relative; padding-top: 26px; }
.main::before {
  content: '';
  position: absolute; top: 0; left: 0; right: 0;
  height: 2px;
  background: var(--ready-0);
  transition: background .25s ease;
}
.main[data-ready="5"]::before { background: var(--ready-5); }
.main[data-ready="4"]::before { background: var(--ready-4); }
.main[data-ready="3"]::before { background: var(--ready-3); }
.main[data-ready="1"]::before { background: var(--ready-1); }

/* ---------- MOVE 2/7: frame edges, inputs, chips ---------- */
.sidebar { border-right: 1px solid var(--border-frame); }
.page-header { border-bottom: 1px solid var(--border-frame); }

.input, .textarea, .select { border: 1px solid var(--border-frame); border-radius: var(--r-sm); }
.input:focus, .textarea:focus, .select:focus {
  outline: none;
  border-color: var(--accent-ink);
  box-shadow: 0 0 0 1px var(--accent-ink);
  background: var(--bg-panel);
}

.nav-badge {
  color: var(--text-primary);
  background: transparent;
  border: 1px solid var(--border-frame);
  letter-spacing: var(--track-placard);
}

.preset-chip.active, .filter-btn.active {
  background: var(--accent-field);
  color: var(--on-accent);
  border-color: var(--border-frame-hot);
}

.empty-state { border: 1px dashed var(--border-dashed); border-radius: var(--r-md); }
::selection { background: var(--accent-field); color: var(--on-accent); }
::-webkit-scrollbar-thumb { border-radius: 0; background: var(--border-strong); }
::-webkit-scrollbar-track { background: var(--bg-base); }
html { scrollbar-color: var(--border-strong) var(--bg-base); }  /* Firefox was unstyled */

/* Card titles get the logo's 3px tick — structural, not ornament. */
.card-title { position: relative; padding-left: 11px; font-weight: 700; }
.card-title::before {
  content: '';
  position: absolute; left: 0; top: 2px; bottom: 2px;
  width: 3px;
  background: var(--accent-field);
}

/* Slide thumbs frame GENERATED CONTENT — kept steel so the frame around a
   preview can never imply DEFCOR blue is part of the artwork. */
.slide-thumb { border: 1px solid var(--border-default); }

/* Mix bar: hue only, framed, hard segment divisions — no lozenge ends. */
.mix-bar { height: 8px; border-radius: 0; border: 1px solid var(--border-default); background: var(--bg-inset); overflow: hidden; }
.mix-bar-segment + .mix-bar-segment { border-left: 1px solid var(--bg-base); }
.brand-card:hover .mix-bar { height: 8px; }

/* Spend service bars get their own neutral steel ramp, independent of both the
   pillar taxonomy and the accent — only the accent marks the expensive one. */
.bar-track { background: var(--bg-inset); border-radius: 0; }
.bar-fill              { background: var(--border-strong); border-radius: 0; }
.bar-fill.s-veo        { background: var(--accent-field); }
.bar-fill.s-openai     { background: var(--border-frame); }
.bar-fill.s-elevenlabs { background: var(--text-tertiary); }
.bar-fill.s-anthropic  { background: var(--text-secondary); }

/* A job with no content type for the current format is not a valid choice —
   say so on the row rather than letting the type list come back empty. */
.pillar-balance-row.unavailable { opacity: .55; }   /* readable: it's a redirect, not a dead row */
.pillar-balance-row.unavailable .name::after {
  content: '\2192 ' attr(data-elsewhere);
  margin-left: 7px;
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: var(--track-label);
  color: var(--text-tertiary);
}

/* GRADE STRIP — the only manual input in the whole tracking loop. Three taps on
   a posted piece that has had a week to perform, plus one toggle for the one
   outcome that matters most in a referral business: somebody reached out. */
.grade-strip {
  display: flex; align-items: center; gap: 6px;
  margin-top: 10px; padding-top: 9px;
  border-top: 1px solid var(--border-subtle);
}
.grade-label {
  font-family: var(--font-mono); font-size: 9px;
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--text-tertiary); margin-right: auto;
}
.grade-btn {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .06em;
  padding: 3px 7px; cursor: pointer;
  background: transparent; color: var(--text-tertiary);
  border: 1px solid var(--border-default); border-radius: var(--r-sm);
}
.grade-btn:hover { border-color: var(--border-frame); color: var(--text-primary); }
.grade-btn.on.g-top  { background: var(--status-success); color: var(--bg-base); border-color: var(--status-success); }
.grade-btn.on.g-fine { background: var(--bg-panel);       color: var(--text-primary); border-color: var(--border-frame); }
.grade-btn.on.g-dud  { background: var(--bg-elevated);    color: var(--text-tertiary); border-color: var(--border-subtle); }
.grade-btn.inbound.on { background: var(--accent-field); color: var(--on-accent); border-color: var(--border-frame-hot); }

/* Categories the current format can't carry sit below this divider rather than
   greyed out among the live ones — the mix figures stay visible, but the top of
   the list is always actionable. */
.park-divider {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
  padding: 10px 2px 4px;
  border-top: 1px dashed var(--border-dashed);
  margin-top: 6px;
}

/* ---------- GATE B — QA verdict on a rendered image ----------
   Advisory, not a gate: a paid render is labelled, never discarded. Sits at the
   bottom of the frame so it never covers the composited headline it is judging. */
.qa-badge {
  position: absolute; left: 8px; bottom: 8px; z-index: 3;
  font-family: var(--font-mono); font-size: 9px; letter-spacing: var(--track-placard);
  text-transform: uppercase; padding: 3px 7px; border-radius: var(--r-sm);
  border: 1px solid transparent; backdrop-filter: blur(10px);
}
.qa-badge.qa-pass     { background: rgba(5,6,9,.82); color: var(--status-success); border-color: color-mix(in srgb, var(--status-success) 40%, transparent); }
.qa-badge.qa-warn     { background: rgba(5,6,9,.86); color: var(--status-warning); border-color: color-mix(in srgb, var(--status-warning) 45%, transparent); }
.qa-badge.qa-fail     { background: rgba(5,6,9,.9);  color: var(--status-danger);  border-color: color-mix(in srgb, var(--status-danger) 55%, transparent); }
.qa-badge.qa-checking { background: rgba(5,6,9,.82); color: var(--text-tertiary); border-color: var(--border-default); }

.qa-panel {
  position: absolute; left: 8px; right: 8px; bottom: 30px; z-index: 3;
  background: rgba(5,6,9,.94); border: 1px solid var(--border-frame);
  border-radius: var(--r-sm); padding: 8px 10px;
  font-size: 11px; line-height: 1.5; color: var(--text-secondary);
  max-height: 46%; overflow-y: auto;
}
.qa-panel ul { margin: 0; padding-left: 15px; }
.qa-panel li { margin-bottom: 4px; }
.qa-panel b { color: var(--text-primary); font-family: var(--font-mono); font-size: 10px; }
.qa-where { color: var(--text-tertiary); }
