/* ╔═══════════════════════════════════════════════════════════════════╗
   ║  SENTINEL V1.3 — SHARED DESIGN SYSTEM                              ║
   ║                                                                    ║
   ║  This stylesheet is loaded by every Sentinel page. It defines:     ║
   ║    · design tokens (colors, type, shadows)                         ║
   ║    · the three-column shell (sidebar + focus + optional detail)    ║
   ║    · mobile bar + drawer chrome                                    ║
   ║    · core atoms (pills, iconbtns, toggles, fresh-pill, sections,   ║
   ║      cell rows, blink, spin, skeletons, timeline)                  ║
   ║    · responsive breakpoints + safe-area-insets                     ║
   ║                                                                    ║
   ║  Page-specific styles live in <page>.css and load AFTER this file. ║
   ║                                                                    ║
   ║  Class prefix convention:                                          ║
   ║    .v4-* — Sentinel internals (kept for code-archaeology reasons;  ║
   ║            "v4" is the internal version number that became         ║
   ║            Sentinel V1.3 externally).                              ║
   ╚═══════════════════════════════════════════════════════════════════╝ */

/* ═════════════════════════════════════════════════════════════════════
   DESIGN TOKENS
   ═════════════════════════════════════════════════════════════════════ */
.cc-v4 {
  /* Surfaces */
  --v4-tray:       #EAEAEA;
  --v4-panel-l:    #0A0A0A;     /* left sidebar (dark) */
  --v4-panel-c:    #FFFFFF;     /* center (white)      */
  --v4-panel-r:    #E2E2E2;     /* right detail (grey) */
  --v4-card:       #FFFFFF;
  --v4-recess:     #F4F4F4;
  --v4-border:     #E5E5E5;
  --v4-border-2:   #D5D5D5;

  /* Ink */
  --v4-ink:        #0A0A0A;
  --v4-ink-2:      #4A4A4A;
  --v4-ink-3:      #888888;
  --v4-ink-4:      #B0B0B0;
  --v4-ink-soft:   var(--v4-ink-3, #888888);  /* alias: muted secondary text (acq + marketing shared CSS) */
  --v4-on-dark:    #FFFFFF;
  --v4-on-dark-2:  rgba(255, 255, 255, 0.62);
  --v4-on-dark-3:  rgba(255, 255, 255, 0.32);

  /* Accents */
  --v4-lime:       #C8FF3D;
  --v4-lime-2:     #B4EA28;
  --v4-lime-tint:  rgba(200, 255, 61, 0.16);
  --v4-purple:     #7C5CFF;
  --v4-purple-2:   #6244E8;
  --v4-purple-tint:rgba(124, 92, 255, 0.16);

  /* Status */
  --v4-pos:        #00C896;
  --v4-pos-tint:   rgba(0, 200, 150, 0.14);
  --v4-neg:        #FF5555;
  --v4-neg-tint:   rgba(255, 85, 85, 0.12);
  --v4-warn:       #FFB020;
  --v4-warn-tint:  rgba(255, 176, 32, 0.14);
  /* Dark "ink" variants of the semantic colors — for TEXT on white or on the
     light *-tint chip backgrounds, where the bright fills above read at only
     ~2:1. These clear AA on white and on their own tint. Use for chip/label
     text; keep the bright tokens for fills, pins, bars, borders. */
  --v4-pos-ink:    #0a7c30;
  --v4-neg-ink:    #c0271f;
  --v4-warn-ink:   #9a5b08;

  /* ── V2 "Instrument" family — dark data-cards floating on the light
       workspace (graduated from the landing canvases). Lime is a signal
       color ON DARK ONLY — on light surfaces use the -ink tokens above. */
  --ins-bg:        #0E0E12;                      /* instrument card ground */
  --ins-bg-2:      #15151B;                      /* nested surface */
  --ins-glass:     rgba(20, 20, 24, 0.82);       /* floating chip ground */
  --ins-line:      rgba(255, 255, 255, 0.09);
  --ins-line-2:    rgba(255, 255, 255, 0.14);
  --ins-ink:       #FFFFFF;
  --ins-ink-2:     rgba(255, 255, 255, 0.66);
  --ins-ink-3:     rgba(255, 255, 255, 0.40);    /* mono micro-labels — floor, don't go fainter */
  --ins-lime:      #C8FF3D;
  --ins-purple:    #7C5CFF;
  --ins-purple-2:  #6244E8;
  --ins-pos:       #00C896;                      /* semantics read well on dark at full brightness */
  --ins-warn:      #FFB020;
  --ins-neg:       #FF5555;
  --ins-shadow:    0 24px 60px -18px rgba(10, 10, 10, 0.28), 0 8px 24px -12px rgba(10, 10, 10, 0.14);

  /* Type */
  --v4-sans:       'Inter', -apple-system, system-ui, sans-serif;
  --v4-mono:       'JetBrains Mono', ui-monospace, monospace;

  /* Shadows */
  --v4-shadow-sm:  0 1px 2px rgba(10, 10, 10, 0.04);
  --v4-shadow-md:  0 8px 24px -8px rgba(10, 10, 10, 0.10), 0 2px 6px rgba(10, 10, 10, 0.04);
  --v4-shadow-lg:  0 24px 48px -12px rgba(10, 10, 10, 0.18);

  /* ─── Legacy token aliases ─────────────────────────────────────
     Older JS files (reputation.js, etc.) emit inline styles using
     pre-V4 variable names. Those names existed in admin.css but
     admin.css doesn't load on user-facing pages, so the legacy refs
     resolved to nothing — every dynamically-styled triage row,
     coverage banner, SLA pill, KPI tile rendered with default browser
     colors. Aliasing here makes those calls work everywhere
     sentinel.css loads. New code should use the --v4-* tokens directly. */
  --alert:        var(--v4-neg);
  --warn:         var(--v4-warn);
  --ok:           var(--v4-pos);
  --text:         var(--v4-ink);
  --text-bright:  var(--v4-ink);
  --text-muted:   var(--v4-ink-3, #6b6b6b);
  --text-dim:     var(--v4-ink-4, #999);
  --blue-bright:  var(--v4-purple);
  --border-soft:  var(--v4-border);
  --border-faint: rgba(0, 0, 0, 0.04);
  --bg-elevated:  var(--v4-recess);
  --v4-ink-2:     #3a3a3a;
  --v4-ink-3:     #6b6b6b;
  --v4-ink-4:     #808080;   /* faintest label tone — nudged from #999 so micro-labels clear AA-large (~4:1) on white */
  --v4-border-2:  #d9d9d9;
}

/* ═════════════════════════════════════════════════════════════════════
   BODY + SHELL
   ═════════════════════════════════════════════════════════════════════ */
body.cc-v4 {
  margin: 0;
  background: var(--v4-panel-l);  /* avoid white flash if sidebar shorter than viewport */
  color: var(--v4-ink);
  font-family: var(--v4-sans);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: 'cv11', 'ss01';
  min-height: 100vh;
}
body.cc-v4 * { box-sizing: border-box; }
body.cc-v4 ::selection { background: var(--v4-lime); }

.v4-shell {
  min-height: 100vh;
  padding-left: 264px;             /* room for the fixed sidebar */
  display: grid;
  grid-template-columns: 1fr 372px;
  background: var(--v4-tray);
}
/* Single-column shell — pages without a detail panel set
   data-shell="single" so the focus column owns the full width. */
.v4-shell[data-shell="single"] {
  grid-template-columns: 1fr;
}
/* Compose mode override — the campaigns.php compose flow has no
   selectable items so the right detail panel sits empty showing "Select
   an item". Hide it + give the form full page width. Sends and
   Subscribers modes both rely on the detail panel for drill-down and
   stay on the 1fr/372px split.

   The min-width: 100% guarantees the shell fills the viewport even at
   wide breakpoints where the white focus column would otherwise leave
   the black body background showing on the right edge. Also stamps
   the body background gray so any 1-pixel rounding-error sliver reads
   as part of the tray, not a black stripe. */
body[data-compose-mode="1"] {
  background: var(--v4-tray) !important;
}
body[data-compose-mode="1"] .v4-shell {
  grid-template-columns: 1fr !important;
  min-width: 100%;
}
body[data-compose-mode="1"] .v4-context {
  display: none !important;
}
/* The cross-page status banner places itself with `grid-column: focus`,
   which works in the default 2-column shell because `focus` matches the
   implicit name of the first track. When compose-mode collapses to a
   single 1fr column, that named-line reference makes the browser
   auto-create extra implicit tracks, squeezing the focus column to a
   sliver. Force a full-row span so the banner stacks above the content
   instead of fighting the grid for column space. */
body[data-compose-mode="1"] .v4-status-banner {
  grid-column: 1 / -1 !important;
}
body[data-compose-mode="1"] .v4-focus {
  grid-column: 1 / -1 !important;
}

@media (max-width: 1380px) {
  .v4-shell { padding-left: 240px; grid-template-columns: 1fr 340px; }
  .v4-shell[data-shell="single"] { grid-template-columns: 1fr; }
}
@media (max-width: 1080px) {
  .v4-shell { padding-left: 220px; grid-template-columns: 1fr; }
}
@media (max-width: 900px) {
  .v4-shell { padding-left: 0; }
}

/* ═════════════════════════════════════════════════════════════════════
   SIDEBAR (left column — dark, fixed)
   ═════════════════════════════════════════════════════════════════════ */
.v4-nav {
  position: fixed;
  top: 0; left: 0; bottom: 0;
  width: 264px;
  z-index: 5;
  background: var(--v4-panel-l);
  color: var(--v4-on-dark);
  padding: 22px 14px 18px;
  display: flex;
  flex-direction: column;
  gap: 22px;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.15) transparent;
}
.v4-nav::-webkit-scrollbar { width: 6px; }
.v4-nav::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.12); border-radius: 999px; }
@media (max-width: 1380px) { .v4-nav { width: 240px; } }
@media (max-width: 1080px) { .v4-nav { width: 220px; } }
@media (max-width: 900px)  { .v4-nav { width: min(290px, 86vw); } }

/* ─── Brand mark + wordmark ─── */
.v4-nav__brand {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 8px;
  text-decoration: none;
  color: var(--v4-on-dark);
}
.v4-nav__brand-mark {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px; height: 38px;
  border-radius: 10px;
  background: var(--v4-lime);
  color: var(--v4-ink);
  overflow: hidden;
  flex-shrink: 0;
  animation: v4-brand-breathe 4.2s ease-in-out infinite;
}
.v4-nav__brand-sweep {
  transform-origin: 16px 16px;
  animation: v4-brand-radar 3.6s linear infinite;
}
@keyframes v4-brand-radar { to { transform: rotate(360deg); } }
@keyframes v4-brand-breathe {
  0%, 100% { box-shadow: 0 0 0 0 rgba(200, 255, 61, 0); }
  50%      { box-shadow: 0 0 14px 0 rgba(200, 255, 61, 0.55); }
}
.v4-nav__brand-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.v4-nav__brand-name {
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1;
  color: var(--v4-on-dark);
}
.v4-nav__brand-version {
  margin-top: 3px;
  font-family: var(--v4-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--v4-lime);
  opacity: 0.85;
}

/* ─── Workspace switcher (Marketing | Acquisitions) ─── */
.v4-nav__mode {
  display: flex;
  gap: 2px;
  margin: 14px 0 4px;
  padding: 3px;
  border-radius: 9px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.08);
}
.v4-nav__mode-seg {
  flex: 1 1 0;
  text-align: center;
  padding: 6px 8px;
  border-radius: 6px;
  font-family: var(--v4-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--v4-on-dark);
  opacity: 0.55;
  transition: background 0.15s ease, opacity 0.15s ease, color 0.15s ease;
  cursor: pointer;
  white-space: nowrap;
}
a.v4-nav__mode-seg:hover {
  opacity: 0.9;
  background: rgba(255, 255, 255, 0.06);
}
.v4-nav__mode-seg.is-active {
  background: var(--v4-purple);
  color: #fff;
  opacity: 1;
  cursor: default;
  box-shadow: 0 1px 6px rgba(124, 92, 255, 0.4);
}
.v4-nav__mode-seg:focus-visible {
  outline: 2px solid var(--v4-lime);
  outline-offset: 1px;
}

/* ─── Nav groups (PULSE / CREATE / GROW / ADMIN) ─── */
.v4-nav__list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  /* The list is the rail's scroll region — brand/switcher pin to the top,
     the promo + profile footer pin to the bottom (flex-shrink:0), and a long
     tool list scrolls here instead of compressing the promo card. */
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.15) transparent;
}
.v4-nav__list::-webkit-scrollbar { width: 5px; }
.v4-nav__list::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.12); border-radius: 999px; }
.v4-nav__group {
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.v4-nav__group + .v4-nav__group {
  margin-top: 4px;
  padding-top: 6px;
  border-top: 1px solid rgba(255, 255, 255, 0.05);
}
.v4-nav__group-label {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px 4px;
  font-family: var(--v4-mono);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.v4-nav__group-bar {
  width: 14px;
  height: 2px;
  border-radius: 2px;
  flex-shrink: 0;
  display: inline-block;
}
.v4-nav__group[data-group="pulse"]  .v4-nav__group-bar { background: var(--v4-lime); }
.v4-nav__group[data-group="create"] .v4-nav__group-bar { background: var(--v4-purple); }
.v4-nav__group[data-group="grow"]   .v4-nav__group-bar { background: #FF8A4C; }
.v4-nav__group[data-group="admin"]  .v4-nav__group-bar { background: #888; }
.v4-nav__group-name { color: rgba(255, 255, 255, 0.62); }
.v4-nav__group[data-group="pulse"]  .v4-nav__group-name { color: var(--v4-lime); }
.v4-nav__group[data-group="create"] .v4-nav__group-name { color: #B6A2FF; }
.v4-nav__group[data-group="grow"]   .v4-nav__group-name { color: #FFB088; }
.v4-nav__group[data-group="admin"]  .v4-nav__group-name { color: #BBB; }
.v4-nav__group-hint {
  margin-left: auto;
  font-family: var(--v4-mono);
  font-size: 8.5px;
  letter-spacing: 0.06em;
  text-transform: none;
  font-weight: 400;
  color: rgba(255, 255, 255, 0.28);
}

/* ─── Collapsible group (admin) ─────────────────────────────────
   Reuses the same .v4-nav__group-label rules but as a button,
   plus a chev that rotates and an overall data-state that hides
   the items list. The .v4-nav__group-items wrapper around items
   keeps the hide-toggle scoped to a single rule. */
.v4-nav__group-items {
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.v4-nav__group-label--collapsible {
  background: none;
  border: none;
  width: 100%;
  cursor: pointer;
  text-align: left;
  border-radius: 6px;
  transition: background 0.15s;
}
.v4-nav__group-label--collapsible:hover {
  background: rgba(255, 255, 255, 0.04);
}
.v4-nav__group-label--collapsible:hover .v4-nav__group-name {
  color: var(--v4-on-dark);
}
.v4-nav__group-chev {
  flex-shrink: 0;
  margin-left: 4px;
  color: rgba(255, 255, 255, 0.42);
  transition: transform 0.2s ease, color 0.15s;
}
.v4-nav__group-label--collapsible:hover .v4-nav__group-chev {
  color: rgba(255, 255, 255, 0.7);
}
.v4-nav__group[data-collapsed="true"] .v4-nav__group-chev {
  transform: rotate(-90deg);
}
.v4-nav__group[data-collapsed="true"] .v4-nav__group-items {
  display: none;
}

/* Section divider inside a group — clusters related items
   (e.g. "Setup" / "Data sources" inside Admin) without breaking
   the single-group structure. Non-interactive, semantic label only. */
.v4-nav__subheading {
  font-family: var(--v4-mono, ui-monospace, "SF Mono", monospace);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.32);
  padding: 12px 14px 4px;
  margin: 0;
  user-select: none;
}
/* First subheading in a group doesn't need its top padding — the
   group label already provides the gap. */
.v4-nav__group-items > .v4-nav__subheading:first-child {
  padding-top: 4px;
}

.v4-nav__item {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 8px 12px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 10px;
  color: var(--v4-on-dark-2);
  font-family: var(--v4-sans);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.15s, color 0.15s, border-color 0.15s, transform 0.15s;
  width: 100%;
  text-align: left;
}
.v4-nav__item:hover {
  background: rgba(255, 255, 255, 0.04);
  color: var(--v4-on-dark);
  transform: translateX(2px);
}
.v4-nav__item--active {
  background: rgba(255, 255, 255, 0.04);
  color: var(--v4-on-dark);
  border-color: var(--v4-lime);
}
.v4-nav__item--active svg:not(.v4-nav__chev) {
  color: var(--v4-lime);
}
.v4-nav__item svg:not(.v4-nav__chev) {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  color: rgba(255, 255, 255, 0.5);
}
.v4-nav__chev {
  margin-left: auto;
  color: var(--v4-on-dark-3);
}
.v4-nav__badge {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  background: var(--v4-purple);
  color: white;
  border-radius: 999px;
  font-family: var(--v4-mono);
  font-size: 10.5px;
  font-weight: 600;
}

/* ═══════════════════════════════════════════════════════════════════
   Sidebar promo card — premium "instrument card" treatment.
   ───────────────────────────────────────────────────────────────────
   What's animated (all subtle, all respecting prefers-reduced-motion):
     · v4-nav__promo-halo  — radial glow behind the rings, breathes
     · v4-ring--{top|mid|bottom} — each ring scale-breathes on its own
                                   tempo (3.6 / 4.4 / 4.0s)
     · v4-nav__promo-live-dot — pulse signaling "AI online"
     · v4-nav__promo-sheen — diagonal specular highlight sweeps every 7s
     · v4-nav__promo:hover — card lifts; arrow nudges right; rings
                             warm up; halo brightens; sheen fires once
   ═══════════════════════════════════════════════════════════════════ */
.v4-nav__promo {
  --promo-ink: #0A0A0A;
  --promo-bg:  var(--v4-lime, #C8FF3D);
  margin-top: auto;
  flex-shrink: 0;                 /* never compress — its content (art+title+CTA) must show in full */
  display: flex;
  flex-direction: column;
  align-items: stretch;
  background: var(--promo-bg);
  /* Soft inner gradient gives the card a more dimensional finish than
     a flat fill — barely perceptible but sells the "premium product"
     feel when paired with the breathing halo. */
  background-image:
    radial-gradient(120% 80% at 30% 0%, rgba(255, 255, 255, 0.18) 0%, transparent 60%),
    radial-gradient(80% 60% at 100% 100%, rgba(0, 0, 0, 0.06) 0%, transparent 70%);
  color: var(--promo-ink);
  border-radius: 18px;
  padding: 18px;
  text-decoration: none;
  position: relative;
  overflow: hidden;
  isolation: isolate;
  cursor: pointer;
  transition: transform 0.32s cubic-bezier(0.2, 0.8, 0.2, 1),
              box-shadow 0.32s cubic-bezier(0.2, 0.8, 0.2, 1);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.35) inset,
              0 8px 22px -10px rgba(200, 255, 61, 0.30),
              0 2px 4px rgba(10, 10, 10, 0.04);
}
.v4-nav__promo:hover {
  transform: translateY(-2px);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.4) inset,
              0 18px 32px -12px rgba(200, 255, 61, 0.45),
              0 4px 8px rgba(10, 10, 10, 0.06);
}

/* ─── Live indicator (top-right) ─── */
.v4-nav__promo-live {
  position: absolute;
  top: 12px;
  right: 14px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 8px 3px 6px;
  background: rgba(10, 10, 10, 0.10);
  border: 1px solid rgba(10, 10, 10, 0.12);
  border-radius: 999px;
  font-family: var(--v4-mono);
  font-size: 8.5px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(10, 10, 10, 0.7);
  z-index: 3;
  pointer-events: none;
}
.v4-nav__promo-live-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #00C896;
  box-shadow: 0 0 0 0 rgba(0, 200, 150, 0.55);
  animation: v4-promo-live-pulse 1.8s ease-out infinite;
}
@keyframes v4-promo-live-pulse {
  0%   { transform: scale(1);    box-shadow: 0 0 0 0   rgba(0, 200, 150, 0.55); }
  70%  { transform: scale(1.05); box-shadow: 0 0 0 6px rgba(0, 200, 150, 0); }
  100% { transform: scale(1);    box-shadow: 0 0 0 0   rgba(0, 200, 150, 0); }
}

/* ─── Art container + breathing halo ─── */
.v4-nav__promo-art {
  position: relative;
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 10px;
  filter: drop-shadow(0 8px 14px rgba(10, 10, 10, 0.15));
}
.v4-nav__promo-art svg { color: rgba(10, 10, 10, 0.88); position: relative; z-index: 1; }

/* The halo — soft radial glow centered on the ring stack, scale-breathes
   to give the card a "powered up" feel without obvious motion. */
.v4-nav__promo-halo {
  position: absolute;
  inset: -12px;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(
    50% 45% at 50% 50%,
    rgba(255, 255, 255, 0.55) 0%,
    rgba(255, 255, 255, 0.18) 35%,
    transparent 70%
  );
  filter: blur(2px);
  animation: v4-promo-halo 4.4s ease-in-out infinite;
}
@keyframes v4-promo-halo {
  0%, 100% { opacity: 0.75; transform: scale(1); }
  50%      { opacity: 1;    transform: scale(1.08); }
}

/* ─── Rings — each on its own breathing tempo ─── */
/* SVG transforms work best around the element's own bounding box, so we
   set transform-origin as a percentage relative to each ellipse. The
   tempos are deliberately uneven — 3.6 / 4.4 / 4.0 sec — so the rings
   never come back into perfect lockstep, which reads as "alive." */
.v4-nav__promo-rings { will-change: transform; }
.v4-ring {
  transform-origin: 50% 50%;
  transform-box: fill-box;
  animation: v4-ring-breath var(--ring-dur, 4s) ease-in-out infinite;
}
.v4-ring--top    { --ring-dur: 3.6s; animation-delay: -0.4s; }
.v4-ring--mid    { --ring-dur: 4.4s; animation-delay: -1.2s; }
.v4-ring--bottom { --ring-dur: 4.0s; animation-delay: -2.0s; }
@keyframes v4-ring-breath {
  0%, 100% { transform: scale(1);     opacity: 0.92; }
  50%      { transform: scale(1.035); opacity: 1; }
}

/* On hover: speed the rings up subtly + brighten halo. */
.v4-nav__promo:hover .v4-ring         { animation-duration: 2.4s, 2.8s, 2.6s; }
.v4-nav__promo:hover .v4-nav__promo-halo { animation-duration: 2.6s; }

/* ─── Diagonal specular sheen ─── */
/* Periodically (every 7s) a thin, soft-edged highlight sweeps across
   the whole card. Single, slow, never repeating fast enough to feel
   like a loading state. Pseudo-element so it doesn't intercept clicks. */
.v4-nav__promo-sheen {
  position: absolute;
  inset: -20%;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(
    115deg,
    transparent 30%,
    rgba(255, 255, 255, 0.35) 48%,
    rgba(255, 255, 255, 0.55) 50%,
    rgba(255, 255, 255, 0.35) 52%,
    transparent 70%
  );
  transform: translateX(-110%);
  mix-blend-mode: overlay;
  animation: v4-promo-sheen 7.6s ease-in-out infinite;
  animation-delay: 1.4s;
}
@keyframes v4-promo-sheen {
  0%   { transform: translateX(-110%); }
  18%  { transform: translateX(110%); }
  100% { transform: translateX(110%); }    /* idle pause until next loop */
}
.v4-nav__promo:hover .v4-nav__promo-sheen { animation-duration: 1.6s; animation-delay: 0s; }

/* ─── Body typography ─── */
.v4-nav__promo-body { position: relative; z-index: 2; }
.v4-nav__promo-eyebrow {
  font-family: var(--v4-mono);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.20em;
  text-transform: uppercase;
  color: rgba(10, 10, 10, 0.58);
  margin-bottom: 4px;
  text-align: center;
}
.v4-nav__promo-title {
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.012em;
  color: var(--promo-ink);
  text-align: center;
  line-height: 1.1;
}
.v4-nav__promo-sub {
  font-family: var(--v4-mono);
  font-size: 9.5px;
  letter-spacing: 0.06em;
  color: rgba(10, 10, 10, 0.5);
  text-align: center;
  margin-top: 5px;
  margin-bottom: 14px;
}

/* ─── CTA pill ─── */
.v4-nav__promo-cta {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 18px 10px 20px;
  background: var(--promo-ink);
  color: var(--promo-bg);
  border-radius: 999px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.02em;
  align-self: center;
  z-index: 2;
  transition: background 0.18s ease, transform 0.18s ease,
              box-shadow 0.18s ease, padding 0.22s ease;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06) inset,
              0 4px 10px -2px rgba(10, 10, 10, 0.20);
}
.v4-nav__promo-cta-arrow {
  transition: transform 0.22s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.v4-nav__promo:hover .v4-nav__promo-cta {
  background: #1a1a1a;
  padding-right: 22px;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.08) inset,
              0 6px 14px -2px rgba(10, 10, 10, 0.30);
}
.v4-nav__promo:hover .v4-nav__promo-cta-arrow { transform: translateX(3px); }

/* Pressed state — subtle inset pop so the click feels tactile. */
.v4-nav__promo:active { transform: translateY(0); transition-duration: 0.05s; }
.v4-nav__promo:active .v4-nav__promo-cta {
  transform: scale(0.98);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06) inset,
              0 2px 4px rgba(10, 10, 10, 0.18);
}

/* ─── Reduced motion — kill every animation, keep the rest ─── */
@media (prefers-reduced-motion: reduce) {
  .v4-nav__promo,
  .v4-nav__promo-halo,
  .v4-nav__promo-live-dot,
  .v4-nav__promo-sheen,
  .v4-ring {
    animation: none !important;
    transition: none !important;
  }
  .v4-nav__promo-sheen { display: none; }
}

/* ─── Global reduced-motion catch-all ───────────────────────────────
   Every animation / transition / smooth-scroll across the whole app honours
   the user's "reduce motion" preference — including stylesheets that don't
   carry their own guard. 0.01ms (not 0) keeps animationend/transitionend
   events firing for JS that depends on them. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ─── Sidebar bottom: profile pill + utility row ─── */
.v4-nav__bottom {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-top: 14px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  flex-shrink: 0;                 /* profile + AI-spend + icon row always pinned + intact */
}
.v4-nav__profile {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 12px;
}
.v4-nav__profile-avatar {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--v4-purple);
  color: white;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.04em;
  flex-shrink: 0;
  /* overflow: visible — was hidden, but the img already clips itself
     via border-radius:inherit and we need the rotating ring to bleed
     out beyond the avatar bounds. */
  overflow: visible;
  text-decoration: none;
  transition: box-shadow 0.15s, transform 0.12s;
  isolation: isolate;
}
/* Crop the avatar img to a circle independent of the parent's overflow.
   The inner img sits ABOVE the ::after ring (z-index: 1). */
.v4-nav__profile-avatar > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
  display: block;
  position: relative;
  z-index: 1;
}
.v4-nav__profile-avatar:hover {
  box-shadow: 0 0 0 2px rgba(255,255,255,0.18);
  transform: translateY(-1px);
}
.v4-nav__profile-avatar--img {
  background: transparent;
  letter-spacing: 0;
}

/* ─── Animated theme-color tail around the avatar ───────────────────
   A short lime-green arc (~55deg) rotates slowly around the avatar's
   perimeter. Built as a conic-gradient masked to a 1.5px ring so only
   the trace shows — the interior of the avatar (photo or initials)
   sits cleanly on top.
   Understated by design: thin stroke, low max-opacity, 5s rotation.
   Respects prefers-reduced-motion. */
.v4-nav__profile-avatar::after {
  content: '';
  position: absolute;
  inset: -3px;                      /* ring extends 3px past the avatar */
  border-radius: 50%;
  padding: 1.5px;                   /* ring thickness */
  background: conic-gradient(
    from 0deg,
    rgba(200, 255, 61, 0) 0deg,
    rgba(200, 255, 61, 0) 280deg,
    rgba(200, 255, 61, 0.95) 335deg,
    rgba(200, 255, 61, 0) 360deg
  );
  /* Mask everything except the padding ring — the standard CSS gradient
     border trick. background paints the full element including padding;
     the mask leaves ONLY the padding visible by XORing the content-box
     fill against the full fill. */
  -webkit-mask:
    linear-gradient(#000, #000) content-box,
    linear-gradient(#000, #000);
  -webkit-mask-composite: xor;
          mask:
            linear-gradient(#000, #000) content-box,
            linear-gradient(#000, #000);
          mask-composite: exclude;
  pointer-events: none;
  z-index: 0;
  animation: v4-avatar-spin 5s linear infinite;
}
@keyframes v4-avatar-spin {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .v4-nav__profile-avatar::after { animation: none; }
}
.v4-nav__profile-meta {
  flex: 1;
  min-width: 0;
}
.v4-nav__profile-name {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--v4-on-dark);
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.v4-nav__profile-role {
  margin-top: 1px;
  font-family: var(--v4-mono);
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.42);
}
.v4-nav__profile-status {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px; height: 14px;
}
.v4-nav__profile-status-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  /* Theme lime — matches the avatar tail + online-dock dot for visual
     consistency. Was using `--v4-pos` (a teal-leaning green) which
     looked like a different "online" signal than the rest of the app. */
  background: var(--v4-lime);
  box-shadow: 0 0 0 0 currentColor;
  color: var(--v4-lime);
  animation: v4-live-blink 1.6s ease-in-out infinite;
}
.v4-nav__profile-status-dot[data-tone="warn"]  { background: var(--v4-warn); color: var(--v4-warn); }
.v4-nav__profile-status-dot[data-tone="alert"] { background: var(--v4-neg);  color: var(--v4-neg); }
@keyframes v4-live-blink {
  0%, 100% { box-shadow: 0 0 0 0 currentColor; opacity: 1; }
  50%      { box-shadow: 0 0 0 4px rgba(255,255,255,0); opacity: 0.55; }
}

/* ─── AI spend-today widget (master-only, sidebar bottom) ─────── */
.v4-nav__spend {
  margin: 4px 0 8px;
  padding: 8px 10px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.05);
  border-radius: 9px;
  font-family: var(--v4-mono);
  font-size: 10px;
  letter-spacing: 0.04em;
  cursor: help;
  transition: border-color 0.18s, background 0.18s;
}
.v4-nav__spend-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 5px;
  white-space: nowrap;
}
.v4-nav__spend-label {
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 8.5px;
  color: rgba(255, 255, 255, 0.45);
}
.v4-nav__spend-amt {
  font-size: 10.5px;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.88);
  font-variant-numeric: tabular-nums;
}
.v4-nav__spend-cap { color: rgba(255, 255, 255, 0.4); font-weight: 500; }
.v4-nav__spend-bar {
  height: 3px;
  background: rgba(255, 255, 255, 0.06);
  border-radius: 2px;
  overflow: hidden;
}
.v4-nav__spend-bar-fill {
  height: 100%;
  width: 0%;
  background: var(--v4-pos);
  transition: width 0.5s ease, background 0.18s;
  border-radius: 2px;
}
.v4-nav__spend[data-tone="warn"]    .v4-nav__spend-bar-fill { background: var(--v4-warn); }
.v4-nav__spend[data-tone="alert"]   .v4-nav__spend-bar-fill { background: var(--v4-neg); }
.v4-nav__spend[data-tone="alert"],
.v4-nav__spend[data-tone="blocked"] {
  border-color: rgba(255, 85, 85, 0.45);
  background: rgba(255, 85, 85, 0.08);
}
.v4-nav__spend[data-tone="blocked"] .v4-nav__spend-bar-fill {
  background: var(--v4-neg);
  animation: v4-spend-pulse 1.4s ease-in-out infinite;
}
.v4-nav__spend[data-tone="blocked"] .v4-nav__spend-amt { color: var(--v4-neg); }
@keyframes v4-spend-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}

.v4-nav__util {
  display: flex;
  align-items: center;
  gap: 6px;
}
.v4-nav__utilbtn {
  position: relative;
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 34px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.05);
  border-radius: 9px;
  color: rgba(255, 255, 255, 0.65);
  text-decoration: none;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.v4-nav__utilbtn:hover {
  background: rgba(255, 255, 255, 0.07);
  color: var(--v4-on-dark);
  border-color: rgba(255, 255, 255, 0.1);
}
/* button reset for refresh-all (which is a <button>, not <a>) */
button.v4-nav__utilbtn {
  font: inherit;
  padding: 0;
}
/* "Refresh All" — distinct treatment + spin animation while in flight */
.v4-nav__utilbtn--refresh:hover {
  background: var(--v4-lime);
  color: var(--v4-ink);
  border-color: var(--v4-lime);
}
.v4-nav__utilbtn--refresh.is-spinning {
  background: var(--v4-lime);
  color: var(--v4-ink);
  border-color: var(--v4-lime);
  cursor: wait;
}
.v4-nav__utilbtn--refresh.is-spinning svg {
  animation: v4-refresh-spin 1s linear infinite;
}
@keyframes v4-refresh-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
.v4-nav__utilbtn-badge {
  position: absolute;
  top: -3px; right: -3px;
  min-width: 16px;
  height: 14px;
  padding: 0 4px;
  background: var(--v4-purple);
  color: white;
  border-radius: 999px;
  border: 1.5px solid var(--v4-panel-l);
  font-family: var(--v4-mono);
  font-size: 9px;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.v4-nav__utilbtn-dot {
  position: absolute;
  top: 6px; right: 8px;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--v4-neg);
  box-shadow: 0 0 0 1.5px var(--v4-panel-l);
}

/* ═════════════════════════════════════════════════════════════════════
   FOCUS COLUMN (white, scrolls)
   The page-specific content lives inside <main class="v4-focus">.
   Pages can use the shared header / actions atoms below.
   ═════════════════════════════════════════════════════════════════════ */
.v4-focus {
  background: var(--v4-panel-c);
  padding: 28px 36px 60px;
  display: flex;
  flex-direction: column;
  gap: 24px;
  min-width: 0;
}
.v4-focus__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
}
.v4-focus__identity {
  display: flex;
  align-items: center;
  gap: 14px;
}
.v4-focus__identity-mark {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 56px; height: 56px;
  border-radius: 50%;
  background: var(--v4-purple);
  color: white;
  flex-shrink: 0;
}
.v4-focus__identity-name {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--v4-ink);
}
.v4-focus__identity-sub {
  margin-top: 2px;
  font-size: 13px;
  color: var(--v4-ink-3);
  display: flex;
  align-items: center;
  gap: 6px;
}
.v4-focus__metrics {
  display: flex;
  align-items: center;
  gap: 22px;
}
.v4-focus__metric { text-align: right; }
.v4-focus__metric-label {
  font-family: var(--v4-mono);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--v4-ink-4);
  margin-bottom: 5px;
}
.v4-focus__metric-value {
  font-size: 32px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--v4-ink);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.v4-focus__metric-sub {
  margin-top: 4px;
  font-family: var(--v4-mono);
  font-size: 10.5px;
  color: var(--v4-ink-3);
  letter-spacing: 0.02em;
}
.v4-focus__metric-sep {
  width: 1px;
  height: 38px;
  background: var(--v4-border-2);
  flex-shrink: 0;
}

.v4-focus__actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* ═════════════════════════════════════════════════════════════════════
   ATOMS — Pills, iconbtns, fresh-pill, toggles
   ═════════════════════════════════════════════════════════════════════ */
.v4-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 11px 18px;
  background: var(--v4-card);
  border: 1px solid var(--v4-border);
  border-radius: 999px;
  color: var(--v4-ink);
  font-family: var(--v4-sans);
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, transform 0.1s;
}
.v4-pill:hover { background: var(--v4-recess); }
.v4-pill:active { transform: scale(0.98); }
.v4-pill:disabled { opacity: 0.6; cursor: progress; }
.v4-pill--primary {
  background: var(--v4-lime);
  border-color: var(--v4-lime);
  color: var(--v4-ink);
  font-weight: 600;
}
.v4-pill--primary:hover { background: var(--v4-lime-2); border-color: var(--v4-lime-2); }
.v4-pill--ghost {
  /* Secondary/ghost pill on the LIGHT content surface (its dominant use across
     the acquisitions pages). Dark surfaces — e.g. .rep-bulk-bar — scope their
     own .v4-pill colors, so they're unaffected. */
  background: transparent;
  border-color: var(--v4-border-2, #d9d9d9);
  color: var(--v4-ink-2, #3a3a3a);
}
.v4-pill--ghost:hover { border-color: var(--v4-ink-3, #6b6b6b); color: var(--v4-ink, #0a0a0a); }

.v4-iconbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px; height: 38px;
  background: var(--v4-recess);
  border: none;
  border-radius: 999px;
  color: var(--v4-ink-2);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.v4-iconbtn:hover { background: var(--v4-border); color: var(--v4-ink); }
.v4-iconbtn--has-dot { position: relative; }
.v4-iconbtn--has-dot::after {
  content: '';
  position: absolute;
  top: 8px; right: 9px;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--v4-neg);
  box-shadow: 0 0 0 1.5px var(--v4-recess);
}

.v4-fresh-pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 0 14px;
  height: 38px;
  background: var(--v4-recess);
  border-radius: 999px;
  font-family: var(--v4-mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--v4-ink-3);
  white-space: nowrap;
}
.v4-fresh-pill__dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--v4-pos);
  animation: v4-live-blink 1.6s ease-in-out infinite;
  color: var(--v4-pos);
}
.v4-fresh-pill__dot[data-tone="warn"]  { background: var(--v4-warn); color: var(--v4-warn); }
.v4-fresh-pill__dot[data-tone="alert"] { background: var(--v4-neg);  color: var(--v4-neg); }

.v4-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  background: var(--v4-card);
  border: 1px solid var(--v4-border);
  border-radius: 999px;
  font-family: var(--v4-sans);
  font-size: 11.5px;
  font-weight: 500;
  color: var(--v4-ink-2);
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.v4-toggle:hover { background: var(--v4-recess); }
.v4-toggle__dot {
  width: 14px; height: 14px;
  border-radius: 50%;
  background: white;
  border: 1px solid var(--v4-border-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
}
.v4-toggle--active {
  background: var(--v4-lime);
  border-color: var(--v4-lime);
  color: var(--v4-ink);
}
.v4-toggle--active .v4-toggle__dot {
  background: var(--v4-ink);
  border-color: var(--v4-ink);
}
.v4-toggle--active .v4-toggle__dot::after {
  content: '';
  width: 6px; height: 3px;
  border-left: 1.4px solid var(--v4-lime);
  border-bottom: 1.4px solid var(--v4-lime);
  transform: rotate(-45deg) translate(0px, -1px);
}

/* ═════════════════════════════════════════════════════════════════════
   SECTION — generic page section (header + body)
   ═════════════════════════════════════════════════════════════════════ */
.v4-section {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.v4-section__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.v4-section__title {
  font-size: 16px;
  font-weight: 600;
  color: var(--v4-ink);
  letter-spacing: -0.01em;
  margin: 0;
}
.v4-section__sub {
  font-size: 12.5px;
  color: var(--v4-ink-3);
  margin-top: 2px;
}
.v4-section__meta {
  font-family: var(--v4-mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  color: var(--v4-ink-3);
}

/* ═════════════════════════════════════════════════════════════════════
   CELL ROW — compact action card (inside cells, lists, etc.)
   ═════════════════════════════════════════════════════════════════════ */
.v4-cell-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  background: white;
  border: 1px solid var(--v4-border);
  border-radius: 11px;
  text-decoration: none;
  color: var(--v4-ink);
  cursor: pointer;
  transition: border-color 0.15s, transform 0.1s;
  min-width: 0;
  text-align: left;
  font-family: var(--v4-sans);
}
.v4-cell-row:hover { border-color: var(--v4-border-2); transform: translateX(2px); }
.v4-cell-row__icon {
  flex-shrink: 0;
  width: 26px; height: 26px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 700;
}
.v4-cell-row__icon[data-tone="alert"] { background: rgba(232, 61, 53, 0.12); color: var(--v4-neg); }
.v4-cell-row__icon[data-tone="warn"]  { background: rgba(225, 145, 11, 0.14); color: var(--v4-warn); }
.v4-cell-row__icon[data-tone="info"]  { background: rgba(124, 92, 255, 0.12); color: var(--v4-purple); }
.v4-cell-row__icon[data-tone="ok"]    { background: rgba(31, 154, 96, 0.12); color: var(--v4-pos); }
.v4-cell-row__body { flex: 1; min-width: 0; }
.v4-cell-row__title {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--v4-ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.v4-cell-row__sub {
  margin-top: 1px;
  font-size: 11px;
  color: var(--v4-ink-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.v4-cell-row__cta {
  flex-shrink: 0;
  font-family: var(--v4-mono);
  font-size: 9.5px;
  font-weight: 600;
  color: var(--v4-ink-3);
  letter-spacing: 0.06em;
}

/* ═════════════════════════════════════════════════════════════════════
   TIMELINE — generic activity / event list
   ═════════════════════════════════════════════════════════════════════ */
.v4-timeline {
  display: flex;
  flex-direction: column;
  gap: 0;
  position: relative;
}
.v4-timeline__row {
  display: grid;
  grid-template-columns: 24px 1fr auto;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--v4-border);
  position: relative;
}
.v4-timeline__row:last-child { border-bottom: none; }
.v4-timeline__dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--v4-pos);
  margin-top: 6px;
  position: relative;
  z-index: 1;
}
.v4-timeline__dot[data-tone="warn"]  { background: var(--v4-warn); }
.v4-timeline__dot[data-tone="alert"] { background: var(--v4-neg); }
.v4-timeline__dot[data-tone="info"]  { background: var(--v4-purple); }
.v4-timeline__row::before {
  content: '';
  position: absolute;
  left: 11px;
  top: 16px;
  bottom: -1px;
  width: 1px;
  background: var(--v4-border);
}
.v4-timeline__row:last-child::before { display: none; }
.v4-timeline__title {
  font-size: 13px;
  font-weight: 500;
  color: var(--v4-ink);
}
.v4-timeline__sub {
  font-size: 11.5px;
  color: var(--v4-ink-3);
  margin-top: 2px;
}
.v4-timeline__time {
  font-family: var(--v4-mono);
  font-size: 10.5px;
  color: var(--v4-ink-4);
  letter-spacing: 0.04em;
}

/* ═════════════════════════════════════════════════════════════════════
   RIGHT DETAIL PANEL (light grey)
   Empty by default; populates with click-loaded content.
   ═════════════════════════════════════════════════════════════════════ */
.v4-context {
  background: var(--v4-panel-r);
  padding: 22px 22px 28px;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(0, 0, 0, 0.15) transparent;
}
.v4-context::-webkit-scrollbar { width: 6px; }
.v4-context::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.12); border-radius: 999px; }
.v4-context[data-state="empty"]  .v4-detail       { display: none; }
.v4-context[data-state="active"] .v4-detail-empty { display: none; }

.v4-detail-empty {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  text-align: center;
  padding: 28px 16px;
  color: var(--v4-ink-3);
}
.v4-detail-empty__art {
  color: var(--v4-purple);
  opacity: 0.85;
  animation: v4-empty-spin 14s linear infinite;
}
@keyframes v4-empty-spin { to { transform: rotate(360deg); } }
.v4-detail-empty__title {
  font-size: 16px;
  font-weight: 600;
  color: var(--v4-ink);
  letter-spacing: -0.01em;
}
.v4-detail-empty__sub {
  max-width: 280px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--v4-ink-3);
}
.v4-detail-empty__hints {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
  margin-top: 4px;
}
.v4-detail-empty__hint {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  background: var(--v4-card);
  border: 1px solid var(--v4-border);
  border-radius: 999px;
  font-family: var(--v4-mono);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--v4-ink-3);
}

.v4-detail {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.v4-detail__close {
  align-self: flex-end;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 10px 5px 8px;
  background: var(--v4-card);
  border: 1px solid var(--v4-border);
  border-radius: 999px;
  font-family: var(--v4-mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--v4-ink-3);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.v4-detail__close:hover { background: var(--v4-recess); color: var(--v4-ink); }

/* ═════════════════════════════════════════════════════════════════════
   STATUS HELPERS — blink, spin, skeletons
   ═════════════════════════════════════════════════════════════════════ */
.v4-blink {
  animation: v4-blink-anim 1.6s ease-out;
  border-radius: 6px;
}
@keyframes v4-blink-anim {
  0%   { background-color: rgba(200, 255, 61, 0.35); box-shadow: 0 0 0 6px rgba(200, 255, 61, 0.18); }
  100% { background-color: transparent;              box-shadow: 0 0 0 0   rgba(200, 255, 61, 0); }
}
.v4-spin { animation: v4-spin 1s linear infinite; transform-origin: center; }
@keyframes v4-spin { to { transform: rotate(360deg); } }

.v4-workspace__skel {
  background: linear-gradient(120deg, var(--v4-recess) 0%, #ECECEC 50%, var(--v4-recess) 100%);
  background-size: 200% 100%;
  height: 240px;
  border-radius: 14px;
  animation: v4-shimmer 1.6s ease-in-out infinite;
}
.v4-list__skel {
  height: 60px;
  border-radius: 13px;
  background: linear-gradient(120deg, var(--v4-recess) 0%, #ECECEC 50%, var(--v4-recess) 100%);
  background-size: 200% 100%;
  animation: v4-shimmer 1.6s ease-in-out infinite;
}
@keyframes v4-shimmer {
  0%   { background-position: 200% 50%; }
  100% { background-position: -200% 50%; }
}

@media (prefers-reduced-motion: reduce) {
  .v4-spin, .v4-list__skel, .v4-workspace__skel { animation: none !important; }
  .v4-blink { animation: none !important; }
  .v4-nav__brand-mark, .v4-nav__brand-sweep { animation: none !important; }
  .v4-nav__profile-status-dot, .v4-fresh-pill__dot { animation: none !important; }
  .v4-detail-empty__art { animation: none !important; }
}

/* ═════════════════════════════════════════════════════════════════════
   ACCESSIBILITY — focus rings, skip link
   ═════════════════════════════════════════════════════════════════════
   :focus-visible (vs :focus) is keyboard-only; mouse clicks don't
   trigger the ring. Lime ring on light surfaces, white-tinted ring
   on dark. Offset = 2px so the ring sits OUTSIDE the element.
*/
:where(.cc-v4) :focus { outline: none; }   /* baseline reset */

:where(.cc-v4) .v4-pill:focus-visible,
:where(.cc-v4) .v4-iconbtn:focus-visible,
:where(.cc-v4) .v4-toggle:focus-visible,
:where(.cc-v4) .v4-fresh-pill:focus-visible,
:where(.cc-v4) .v4-detail__close:focus-visible,
:where(.cc-v4) .cc-btn:focus-visible {
  outline: 2px solid var(--v4-purple);
  outline-offset: 2px;
}
/* On dark sidebar / mobile bar, lime is more visible than purple */
:where(.cc-v4) .v4-nav__item:focus-visible,
:where(.cc-v4) .v4-nav__utilbtn:focus-visible,
:where(.cc-v4) .v4-nav__promo:focus-visible,
:where(.cc-v4) .v4-nav__brand:focus-visible,
:where(.cc-v4) .v4-mobile-bar__btn:focus-visible,
:where(.cc-v4) .v4-mobile-bar__avatar:focus-visible,
:where(.cc-v4) .v4-nav__group-label--collapsible:focus-visible {
  outline: 2px solid var(--v4-lime);
  outline-offset: 2px;
}
/* Card-shaped clickables get a contained ring instead of an outset
   one (otherwise their inset positioning collides with neighbors) */
:where(.cc-v4) .v4-cell-row:focus-visible,
:where(.cc-v4) .v4-list__row:focus-visible,
:where(.cc-v4) .v4-cell:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--v4-purple), var(--v4-shadow-sm);
}

/* Skip-to-content link — visually hidden until focused, then a clear
   lime pill in the top-left so keyboard users jump past the sidebar. */
.v4-skip {
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 200;
  padding: 8px 14px;
  background: var(--v4-lime);
  color: var(--v4-ink);
  font-family: var(--v4-sans);
  font-size: 13px;
  font-weight: 600;
  border-radius: 8px;
  text-decoration: none;
  box-shadow: var(--v4-shadow-md);
  transform: translateY(-150%);
  transition: transform 0.18s;
}
.v4-skip:focus {
  transform: translateY(0);
  outline: 2px solid var(--v4-ink);
  outline-offset: 2px;
}

/* ═════════════════════════════════════════════════════════════════════
   EMPTY STATE + ERROR STATE — reusable atoms for "no data" / "failed"
   ═════════════════════════════════════════════════════════════════════
   Drop these into any list/feed/grid:
     <div class="s-empty">
       <div class="s-empty__icon" data-tone="ok">✓</div>
       <div class="s-empty__title">All caught up</div>
       <div class="s-empty__sub">No items need attention right now.</div>
       <a class="v4-pill" href="...">Open something →</a>
     </div>
*/
.s-empty,
.s-error {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 10px;
  padding: 40px 24px;
  background: var(--v4-recess);
  border: 1px solid var(--v4-border);
  border-radius: 14px;
  color: var(--v4-ink-3);
  font-size: 13px;
  line-height: 1.5;
}
.s-empty__icon,
.s-error__icon {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--v4-card);
  font-size: 24px;
  font-weight: 700;
  color: var(--v4-ink-3);
  margin-bottom: 4px;
}
.s-empty__icon[data-tone="ok"]    { background: var(--v4-pos-tint);    color: var(--v4-pos); }
.s-empty__icon[data-tone="info"]  { background: var(--v4-purple-tint); color: var(--v4-purple); }
.s-empty__icon[data-tone="warn"]  { background: var(--v4-warn-tint);   color: var(--v4-warn); }
.s-error__icon {
  background: var(--v4-neg-tint);
  color: var(--v4-neg);
}
.s-empty__title,
.s-error__title {
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--v4-ink);
}
.s-empty__sub,
.s-error__sub {
  max-width: 360px;
  color: var(--v4-ink-3);
}

/* Shared empty-state CTAs — used by /missions, /vault, /newsletter,
   /referrals, and other surfaces. Two variants:
     .s-empty__cta            — primary action (purple pill)
     .s-empty__cta--ghost     — secondary action (outlined)
   Renders as either <button> or <a> with identical styling. */
.s-empty__cta-row {
  display: flex;
  gap: 8px;
  justify-content: center;
  flex-wrap: wrap;
  margin-top: 14px;
}
.s-empty__cta {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.005em;
  padding: 8px 16px;
  border-radius: 999px;
  border: 1px solid var(--v4-purple);
  background: var(--v4-purple);
  color: #fff;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.15s ease, transform 0.12s ease, box-shadow 0.15s ease;
}
.s-empty__cta:hover:not(:disabled) {
  background: var(--v4-purple-2, #6244E8);
  border-color: var(--v4-purple-2, #6244E8);
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(124, 92, 255, 0.28);
}
.s-empty__cta:disabled {
  opacity: 0.7;
  cursor: progress;
}
.s-empty__cta--ghost {
  background: transparent;
  color: var(--v4-ink-2);
  border-color: var(--v4-border-2, #D5D5D5);
}
.s-empty__cta--ghost:hover:not(:disabled) {
  background: var(--v4-recess);
  color: var(--v4-ink);
  border-color: var(--v4-ink-3);
  box-shadow: none;
}
.s-error__detail {
  margin-top: 8px;
  padding: 10px 14px;
  background: var(--v4-card);
  border: 1px solid var(--v4-border);
  border-radius: 8px;
  font-family: var(--v4-mono);
  font-size: 11px;
  color: var(--v4-ink-2);
  max-width: 480px;
  word-break: break-word;
}

/* ═════════════════════════════════════════════════════════════════════
   PRINT — hide chrome, give focus column the page
   ═════════════════════════════════════════════════════════════════════ */
@media print {
  body.cc-v4 {
    background: white !important;
    color: black !important;
  }
  .v4-shell {
    padding-left: 0 !important;
    grid-template-columns: 1fr !important;
    background: white !important;
  }
  .v4-nav,
  .v4-mobile-bar,
  .v4-nav-backdrop,
  .v4-context,
  .v4-focus__actions,
  .v4-iconbtn,
  .v4-pill,
  .v4-skip { display: none !important; }
  .v4-focus {
    padding: 0 !important;
    background: white !important;
  }
  /* Cards and tables look better with thin borders, no shadows */
  .cc-card,
  .cc-panel,
  .v4-cell,
  .v4-section,
  .cc-comp-card,
  .cc-mission,
  .cc-gbp-card {
    background: white !important;
    border: 1px solid #ccc !important;
    box-shadow: none !important;
    page-break-inside: avoid;
  }
  .cc-table {
    border: 1px solid #ccc;
  }
  .cc-table thead th { background: #f3f3f3 !important; color: #333 !important; }
  /* Show URLs after links so printed pages preserve the destination */
  a[href^="http"]::after,
  a[href^="/"]::after {
    content: " (" attr(href) ")";
    font-family: var(--v4-mono);
    font-size: 9px;
    color: #777;
  }
  /* Animations off; pin/sweep/bracket overlays hidden */
  .v4-map__brackets,
  .v4-map__sweep,
  .v4-map__pin-pulse { display: none !important; }
  /* Headings get a darker tone in print */
  .v4-focus__identity-name,
  .admin-page-title,
  .cc-panel-title { color: black !important; }
}

/* ╔═════════════════════════════════════════════════════════════════════╗
   ║ MOBILE / TABLET RESPONSIVE                                          ║
   ║  ≤1080px : right detail panel becomes a click-overlay               ║
   ║  ≤900px  : hamburger nav, mobile bar visible, sidebar = drawer      ║
   ║  ≤640px  : aggressively-tightened focus column                      ║
   ╚═════════════════════════════════════════════════════════════════════╝ */
.v4-mobile-bar { display: none; }
.v4-nav-backdrop { display: none; }

@media (max-width: 1080px) {
  .v4-context {
    position: fixed;
    top: 0; right: 0; bottom: 0;
    width: min(440px, 100vw);
    height: 100dvh;
    z-index: 90;
    transform: translateX(110%);
    transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.2, 1);
    pointer-events: none;
    box-shadow: -8px 0 28px rgba(0, 0, 0, 0.18);
    padding-bottom: calc(28px + env(safe-area-inset-bottom));
  }
  .v4-context[data-state="active"] {
    transform: translateX(0);
    pointer-events: auto;
  }
  .v4-context[data-state="empty"] { display: none; }
}

@media (max-width: 900px) {
  .v4-mobile-bar {
    position: sticky;
    top: 0;
    z-index: 70;
    display: flex;
    align-items: center;
    gap: 10px;
    height: calc(56px + env(safe-area-inset-top));
    padding: env(safe-area-inset-top) 12px 0;
    background: var(--v4-panel-l);
    color: var(--v4-on-dark);
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
    box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.4);
  }
  .v4-mobile-bar__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px; height: 38px;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.07);
    border-radius: 10px;
    color: var(--v4-on-dark);
    cursor: pointer;
    flex-shrink: 0;
    transition: background 0.15s;
  }
  .v4-mobile-bar__btn:active { background: rgba(255, 255, 255, 0.12); }
  .v4-mobile-bar__brand {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 9px;
    min-width: 0;
  }
  .v4-mobile-bar__title {
    font-size: 15px;
    font-weight: 700;
    letter-spacing: -0.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .v4-mobile-bar__ver {
    font-family: var(--v4-mono);
    font-size: 8.5px;
    font-weight: 600;
    letter-spacing: 0.16em;
    color: var(--v4-lime);
    margin-left: 4px;
    text-transform: uppercase;
  }
  .v4-nav__brand-mark--mini {
    width: 30px;
    height: 30px;
    border-radius: 8px;
    animation: none;
  }
  .v4-mobile-bar__avatar {
    background: var(--v4-purple);
    border-color: var(--v4-purple);
    font-family: var(--v4-mono);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.04em;
  }

  .v4-nav-backdrop {
    display: block;
    position: fixed; inset: 0;
    background: rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(2px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s;
    z-index: 75;
  }
  body.v4-nav-open .v4-nav-backdrop {
    opacity: 1;
    pointer-events: auto;
  }

  .v4-nav {
    transform: translateX(-100%);
    transition: transform 0.28s cubic-bezier(0.2, 0.7, 0.2, 1);
    z-index: 80;
    box-shadow: 8px 0 30px rgba(0, 0, 0, 0.4);
    padding-top: calc(22px + env(safe-area-inset-top));
    padding-bottom: calc(18px + env(safe-area-inset-bottom));
  }
  body.v4-nav-open .v4-nav {
    transform: translateX(0);
  }

  body.v4-nav-open,
  body.v4-detail-open { overflow: hidden; }

  .v4-context {
    top: auto;
    right: 0; left: 0; bottom: 0;
    width: 100vw;
    max-width: 100vw;
    height: calc(100dvh - 36px);
    border-radius: 18px 18px 0 0;
    transform: translateY(100%);
    transition: transform 0.32s cubic-bezier(0.2, 0.7, 0.2, 1);
    box-shadow: 0 -6px 30px rgba(0, 0, 0, 0.28);
  }
  .v4-context[data-state="active"] {
    transform: translateY(0);
  }
  .v4-detail__close {
    position: sticky;
    top: 8px;
    z-index: 1;
    background: var(--v4-card);
  }

  .v4-focus {
    padding: 18px 16px 56px;
    gap: 20px;
  }
  .v4-focus__head {
    flex-direction: column;
    align-items: stretch;
    gap: 14px;
  }
  .v4-focus__metrics {
    width: 100%;
    justify-content: space-between;
    gap: 14px;
  }
  .v4-focus__metric { text-align: left; }
  .v4-focus__metric:last-child { text-align: right; }
  .v4-focus__metric-value { font-size: 26px; }
  .v4-focus__metric-sep { display: none; }

  .v4-focus__actions {
    flex-wrap: wrap;
    gap: 8px;
  }
  .v4-pill { padding: 10px 14px; font-size: 13px; }
  .v4-fresh-pill { height: 34px; padding: 0 12px; font-size: 10px; }
  .v4-iconbtn { display: none; }

  .v4-section__head { flex-wrap: wrap; gap: 10px; }

  .v4-detail { padding: 12px 14px 18px; }
}

@media (max-width: 640px) {
  .v4-focus { padding: 14px 12px 48px; gap: 16px; }
  .v4-focus__identity-mark { width: 44px; height: 44px; }
  .v4-focus__identity-name { font-size: 18px; }
  .v4-focus__identity-sub  { font-size: 12px; }
  .v4-section__title { font-size: 14.5px; }
  .v4-section__sub   { font-size: 11.5px; }
  .v4-cell-row { padding: 8px; }
  .v4-cell-row__title { font-size: 12px; }
  .v4-cell-row__sub   { font-size: 10.5px; }
  .v4-cell-row__icon  { width: 24px; height: 24px; font-size: 12px; }
  .v4-mobile-bar__title { font-size: 14px; }
}

/* ═══════════════════════════════════════════════════════════════
   Comp Workflow strip — instrument-panel feel.
   Six-step nav (Discover → Manage → Review → Our Rent → Advisor →
   Analyze) shared across pricing pages. Live counts come from the
   PHP include; this stylesheet handles all visual states.

   Design intent:
   · Single dark rail (instrument bar) — not 6 separate cards
   · Mono "01–06" digits sit on the rail like control-panel labels
   · A continuous lime "progress wire" runs through the digits
     showing how far along the workflow has been completed
   · Active step is *dark* (inverted) with a lime digit + lime
     underline — the instrument's selected channel
   · Pending-review state injects a small amber pulse on the digit
   ═══════════════════════════════════════════════════════════════ */
.cw-strip {
  --cw-rail:        #111111;
  --cw-rail-edge:   #1F1F1F;
  --cw-ink-on-rail: #EAEAEA;
  --cw-ink-dim:     #6B6B6B;
  --cw-accent:      var(--v4-lime, #C8FF3D);
  --cw-accent-dim:  rgba(200, 255, 61, 0.22);

  position: relative;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 0;
  padding: 0;
  margin: 0 0 22px;
  background: var(--cw-rail);
  border: 1px solid var(--cw-rail-edge);
  border-radius: 14px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.04),
    0 8px 24px -12px rgba(0, 0, 0, 0.4);
  overflow: hidden;
  isolation: isolate;
}

/* The "progress wire" — a thin lime line that runs across the rail at
   the digit's vertical center. Drawn under the steps via ::before so
   it looks continuous; each step's left-edge gradient picks it up. */
.cw-strip::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 26px;             /* aligns with center of digit pucks */
  height: 1px;
  background: linear-gradient(
    to right,
    transparent 0,
    rgba(200, 255, 61, 0.18) 8%,
    rgba(200, 255, 61, 0.10) 50%,
    rgba(200, 255, 61, 0.04) 92%,
    transparent 100%
  );
  pointer-events: none;
  z-index: 0;
}

/* Steps are inert blocks on the rail — they own their digit, label, hint.
   Reset all <button>/<a> defaults so the rail feels seamless. */
.cw-step {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto auto;
  grid-template-areas:
    'num label'
    'num hint';
  column-gap: 12px;
  row-gap: 1px;
  align-items: center;
  padding: 14px 16px 13px;
  background: transparent;
  border: 0;
  border-right: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 0;
  text-align: left;
  text-decoration: none;
  color: var(--cw-ink-dim);
  cursor: pointer;
  font: inherit;
  outline: none;
  transition: background 0.18s ease, color 0.18s ease;
}
.cw-step:last-of-type { border-right: 0; }
.cw-step:hover { background: rgba(255, 255, 255, 0.03); color: var(--cw-ink-on-rail); }
.cw-step:focus-visible { background: rgba(255, 255, 255, 0.05); color: var(--cw-ink-on-rail); }

/* The digit puck — mono, monospace, uppercase, sits on the rail.
   Border softens against the dark background; lime accent indicates
   "you've completed (or are at) this step." */
.cw-step__num {
  grid-area: num;
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.04);
  color: var(--cw-ink-dim);
  font-family: var(--v4-mono, ui-monospace, monospace);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  border: 1px solid rgba(255, 255, 255, 0.08);
  font-variant-numeric: tabular-nums;
  position: relative;
  transition: background 0.18s, color 0.18s, border-color 0.18s, box-shadow 0.18s;
}
.cw-step:hover .cw-step__num {
  color: var(--cw-ink-on-rail);
  border-color: rgba(255, 255, 255, 0.18);
}

/* Step labels + hints — mono accent on the label like an instrument
   knob, sans hint underneath. Tabular nums on counts so they line up
   when running across all six steps. */
.cw-step__body {
  display: contents;          /* allow grid areas above to control layout */
}
.cw-step__label {
  grid-area: label;
  font-family: var(--v4-mono, ui-monospace, monospace);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--cw-ink-on-rail);
  line-height: 1;
}
.cw-step__hint {
  grid-area: hint;
  font-family: var(--v4-sans, system-ui);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--cw-ink-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.35;
}
.cw-step__hint strong {
  color: var(--cw-ink-on-rail);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Active step — the instrument's "tuned to this channel" state.
   Lime digit, slim lime underline, brighter ink across the row.
   Subtle inset so it sits on the rail rather than floating. */
.cw-step.is-active {
  background:
    linear-gradient(180deg, rgba(200, 255, 61, 0.06), rgba(200, 255, 61, 0) 80%),
    rgba(255, 255, 255, 0.03);
  color: var(--cw-ink-on-rail);
}
.cw-step.is-active::after {
  content: '';
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 0;
  height: 2px;
  background: var(--cw-accent);
  border-radius: 2px 2px 0 0;
  box-shadow: 0 0 12px var(--cw-accent-dim);
}
.cw-step.is-active .cw-step__num {
  background: var(--cw-accent);
  color: #0A0A0A;
  border-color: var(--cw-accent);
  box-shadow:
    0 0 0 3px rgba(200, 255, 61, 0.10),
    0 0 14px rgba(200, 255, 61, 0.30);
}
.cw-step.is-active .cw-step__label { color: var(--cw-accent); }

/* Pending-review state — the queue has snapshots waiting on a human.
   Subtle pulsing ring on the digit; takes lower priority than active. */
.cw-step--has-pending:not(.is-active) .cw-step__num {
  background: rgba(255, 176, 32, 0.12);
  color: var(--v4-warn, #FFB020);
  border-color: rgba(255, 176, 32, 0.45);
  box-shadow: 0 0 0 3px rgba(255, 176, 32, 0.06);
}
.cw-step--has-pending:not(.is-active) .cw-step__hint strong {
  color: var(--v4-warn, #FFB020);
}
.cw-step--has-pending:not(.is-active) .cw-step__num::after {
  content: '';
  position: absolute;
  top: -3px;
  right: -3px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--v4-warn, #FFB020);
  box-shadow: 0 0 0 2px var(--cw-rail);
  animation: cw-pulse 1.8s ease-out infinite;
}
@keyframes cw-pulse {
  0%   { transform: scale(1);    opacity: 1; }
  70%  { transform: scale(1.25); opacity: 0; }
  100% { transform: scale(1);    opacity: 0; }
}

/* The "→" between steps from the PHP include is a separate inline span;
   on the new instrument bar we don't need it (the rail dividers do the
   job and the progress wire conveys flow). Hide it visually but keep
   the element so reading-order stays intact for screen readers. */
.cw-step__arrow {
  display: none;
}

/* Responsive — collapse to a vertical stack on narrow screens. The
   instrument feel doesn't survive a 320-wide column, so we drop back
   to a clean list. */
@media (max-width: 860px) {
  .cw-strip { grid-auto-flow: row; }
  .cw-strip::before { display: none; }
  .cw-step { border-right: 0; border-bottom: 1px solid rgba(255, 255, 255, 0.06); }
  .cw-step:last-of-type { border-bottom: 0; }
  .cw-step.is-active::after {
    left: 0;
    right: auto;
    top: 0;
    bottom: 0;
    width: 2px;
    height: auto;
    border-radius: 0 2px 2px 0;
  }
}
@media (max-width: 540px) {
  .cw-step__hint { white-space: normal; }
}

/* ═══════════════════════════════════════════════════════════════
   Refresh All confirmation modal — itemized cost preview before
   the actual fan-out fires. Built directly in JS via DOM.append, so
   no PHP partial. Z-indexed above everything (200).
   ═══════════════════════════════════════════════════════════════ */
.rax-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(10, 10, 10, 0.55);
  backdrop-filter: blur(2px);
  display: grid;
  place-items: center;
  padding: 20px;
  animation: rax-fade-in 0.18s ease-out;
}
@keyframes rax-fade-in { from { opacity: 0; } to { opacity: 1; } }

.rax-modal {
  width: 100%;
  max-width: 640px;
  max-height: 90vh;
  background: var(--v4-card);
  border: 1px solid var(--v4-border);
  border-radius: 16px;
  box-shadow: 0 20px 60px rgba(0,0,0,0.25);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: rax-pop-in 0.22s cubic-bezier(.2,.7,.3,1.3);
}
@keyframes rax-pop-in { from { transform: scale(0.94); opacity: 0; } to { transform: scale(1); opacity: 1; } }

.rax-modal__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
  padding: 18px 22px 14px;
  border-bottom: 1px solid var(--v4-border);
}
.rax-modal__title {
  font-size: 17px;
  font-weight: 700;
  color: var(--v4-ink);
  letter-spacing: -0.015em;
}
.rax-modal__sub {
  font-family: var(--v4-mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  color: var(--v4-ink-3);
  margin-top: 4px;
}
.rax-modal__close {
  flex-shrink: 0;
  width: 32px; height: 32px;
  display: grid;
  place-items: center;
  background: transparent;
  border: 1px solid var(--v4-border);
  border-radius: 8px;
  color: var(--v4-ink-3);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.rax-modal__close:hover { background: var(--v4-recess); color: var(--v4-ink); }

.rax-modal__body {
  padding: 14px 22px 18px;
  overflow-y: auto;
  flex: 1;
  min-height: 0;
}

.rax-list {
  list-style: none;
  margin: 0 0 14px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.rax-row {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas:
    "job cost"
    "rationale rationale";
  gap: 2px 14px;
  padding: 10px 12px;
  border-radius: 8px;
  background: var(--v4-recess);
  border-left: 3px solid var(--v4-border);
}
.rax-row--free      { border-left-color: var(--v4-pos); }
.rax-row--ai-light  { border-left-color: var(--v4-purple); }
.rax-row--ai        { border-left-color: var(--v4-warn); }
.rax-row__job {
  grid-area: job;
  font-size: 13px;
  font-weight: 600;
  color: var(--v4-ink);
}
.rax-row__rationale {
  grid-area: rationale;
  font-family: var(--v4-mono);
  font-size: 10.5px;
  color: var(--v4-ink-3);
  letter-spacing: 0.02em;
}
.rax-row__cost {
  grid-area: cost;
  font-family: var(--v4-mono);
  font-size: 12px;
  font-weight: 700;
  color: var(--v4-ink);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  align-self: center;
}

.rax-total {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  margin: 14px 0 10px;
  background: var(--v4-ink);
  color: white;
  border-radius: 10px;
}
.rax-total__label {
  font-family: var(--v4-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.75;
}
.rax-total__amt {
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.rax-total__sep {
  margin: 0 4px;
  opacity: 0.45;
}

.rax-cap {
  padding: 10px 14px;
  border-radius: 8px;
  font-size: 12.5px;
  line-height: 1.5;
  margin-bottom: 10px;
}
.rax-cap--ok {
  background: var(--v4-pos-tint);
  color: var(--v4-ink-2);
  border: 1px solid rgba(0, 200, 150, 0.32);
}
.rax-cap--ok strong { color: var(--v4-ink); font-variant-numeric: tabular-nums; }
.rax-cap--blocked {
  background: var(--v4-neg-tint);
  color: var(--v4-ink-2);
  border: 1px solid rgba(255, 85, 85, 0.32);
}
.rax-cap--blocked strong { color: var(--v4-neg); }
.rax-cap--info {
  background: var(--v4-recess);
  color: var(--v4-ink-3);
  border: 1px solid var(--v4-border);
  font-style: italic;
}
.rax-cap code {
  padding: 1px 5px;
  background: rgba(0, 0, 0, 0.06);
  border-radius: 4px;
  font-family: var(--v4-mono);
  font-size: 11.5px;
  color: var(--v4-ink);
}

.rax-foot {
  margin: 10px 0 0;
  padding: 10px 12px;
  background: var(--v4-recess);
  border-radius: 8px;
  font-size: 11.5px;
  color: var(--v4-ink-3);
  line-height: 1.55;
}

.rax-modal__foot {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 8px;
  padding: 14px 22px;
  border-top: 1px solid var(--v4-border);
  background: var(--v4-recess);
}

/* Force re-run checkbox sits on the left, buttons stay on the right */
.rax-force {
  margin-right: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--v4-ink-2);
  cursor: pointer;
  user-select: none;
}
.rax-force input[type="checkbox"] {
  margin: 0;
  cursor: pointer;
}

@media (max-width: 540px) {
  .rax-modal { max-height: 100vh; border-radius: 0; }
  .rax-row { grid-template-columns: 1fr; grid-template-areas: "job" "rationale" "cost"; }
  .rax-row__cost { align-self: start; }
}

/* ─── Comp Workflow tab panels (intel.php only) ────────────────
   The strip on intel.php runs in tab mode: clicking Discover/Manage
   reveals a hidden panel below it (each containing a lazy-loaded
   iframe of the corresponding admin page rendered with ?embed=1).
   The Analyze panel holds the original intel content. */
.cw-strip--tabs .cw-step { cursor: pointer; }
.cw-panel { display: contents; }
.cw-panel[hidden] { display: none; }
.cw-iframe {
  display: block;
  width: 100%;
  min-height: calc(100vh - 200px);
  border: 0;
  border-radius: 14px;
  background: var(--v4-card);
  box-shadow: 0 1px 0 rgba(0,0,0,0.02), 0 4px 14px rgba(0,0,0,0.04);
}

/* ═══════════════════════════════════════════════════════════════
   Sentinel.confirm() / Sentinel.prompt() shared modal
   ═══════════════════════════════════════════════════════════════ */
.sn-modal {
  position: fixed;
  inset: 0;
  z-index: 250;
  display: grid;
  place-items: center;
  animation: sn-modal-in 0.15s ease-out;
}
.sn-modal[hidden] { display: none; }
.sn-modal__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(10, 10, 14, 0.45);
}
.sn-modal__panel {
  position: relative;
  background: white;
  border-radius: 14px;
  width: min(440px, 92vw);
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.3);
  overflow: hidden;
}
.sn-modal__head { padding: 18px 22px 8px; }
.sn-modal__title { margin: 0; font-size: 15px; color: var(--v4-ink); font-weight: 600; }
.sn-modal__body { padding: 0 22px 16px; color: var(--v4-ink-2); font-size: 13px; line-height: 1.5; }
.sn-modal__body p { margin: 0 0 8px; }
.sn-modal__body p:last-child { margin-bottom: 0; }
.sn-modal__foot {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 14px 22px;
  background: var(--v4-recess);
  border-top: 1px solid var(--v4-border);
}
.sn-modal__ok.is-danger {
  background: #DC2626;
  border-color: #DC2626;
  color: white;
}
.sn-modal__ok.is-danger:hover { background: #B91C1C; border-color: #B91C1C; }
@keyframes sn-modal-in { from { opacity: 0; } to { opacity: 1; } }

/* ═══════════════════════════════════════════════════════════════
   Refresh All — live progress phase (per SYSTEMS.md §6.3.1)
   Same modal, swapped body/foot. The row pills mirror the cron
   status semantics: queued / running / done / failed / cancelled.
   ═══════════════════════════════════════════════════════════════ */
.rax-firing {
  text-align: center;
  padding: 36px 24px;
  color: var(--v4-ink-2);
  font-size: 13.5px;
}
.rax-prog-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.rax-prog-row {
  display: grid;
  grid-template-columns: 28px 1fr auto auto;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  background: var(--v4-recess);
  border: 1px solid var(--v4-border);
  border-radius: 8px;
  font-size: 12.5px;
  transition: background 0.15s, border-color 0.15s;
}
.rax-prog-row[data-status="running"]   { background: rgba(99, 102, 241, 0.07); border-color: rgba(99, 102, 241, 0.30); }
.rax-prog-row[data-status="done"]      { background: rgba(16, 185, 129, 0.07); border-color: rgba(16, 185, 129, 0.30); }
.rax-prog-row[data-status="failed"]    { background: rgba(220, 38, 38, 0.07); border-color: rgba(220, 38, 38, 0.30); }
.rax-prog-row[data-status="cancelled"] { background: rgba(107, 114, 128, 0.10); border-color: rgba(107, 114, 128, 0.30); opacity: 0.7; }

.rax-prog-row__pill {
  /* flex-shrink + box-sizing locks the pill size regardless of which
     glyph sits inside it — ⚡ has different metrics than ✓, which on
     the first ship pushed the cached pill ~2px wider than the done
     pill and broke vertical row alignment across the list. */
  flex-shrink: 0;
  box-sizing: border-box;
  width: 24px; height: 24px;
  min-width: 24px; min-height: 24px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-family: var(--v4-mono);
  font-size: 12px;     /* trimmed from 13px so emoji glyphs fit cleanly */
  line-height: 1;
  font-weight: 700;
  /* All glyph-character pills share the same baseline + horizontal
     centering. Without these, ✓ optically sits higher than ⚡. */
  text-align: center;
  font-feature-settings: "tnum" 1;
}
/* ⚡ (cached) and ⊘ (cancelled/skipped) are wide emoji-class glyphs
   that render larger than the line-art symbols; pull them down a
   touch and shrink slightly so the optical weight matches ✓ / ✗. */
.rax-prog-row__pill--cached,
.rax-prog-row__pill--cancelled,
.rax-prog-row__pill--skipped { font-size: 11px; }
.rax-prog-row__pill--queued    { background: var(--v4-recess); color: var(--v4-ink-3); border: 1px solid var(--v4-border); }
.rax-prog-row__pill--running   { background: rgba(99, 102, 241, 0.15); color: #4338CA; border: 1px solid rgba(99, 102, 241, 0.4); animation: rax-spin 1s linear infinite; }
.rax-prog-row__pill--done      { background: rgba(16, 185, 129, 0.18); color: #047857; border: 1px solid rgba(16, 185, 129, 0.45); }
.rax-prog-row__pill--failed    { background: rgba(220, 38, 38, 0.15); color: #B91C1C; border: 1px solid rgba(220, 38, 38, 0.4); }
.rax-prog-row__pill--cancelled { background: rgba(107, 114, 128, 0.15); color: #4B5563; border: 1px solid rgba(107, 114, 128, 0.4); }
@keyframes rax-spin { from { transform: rotate(0); } to { transform: rotate(360deg); } }

.rax-prog-row__job  { font-weight: 600; color: var(--v4-ink); font-family: var(--v4-mono); font-size: 11.5px; letter-spacing: 0.02em; }
.rax-prog-row__sub  { color: var(--v4-ink-3); font-size: 11.5px; }
.rax-prog-row__time { color: var(--v4-ink-3); font-family: var(--v4-mono); font-size: 11px; min-width: 50px; text-align: right; }

/* ═══════════════════════════════════════════════════════════════
   Refresh-All modal — V2 polish pass (May 12)
   Replaces the single-line ".rax-prog-row__sub" wall of text with a
   compressed-chip rendering. Adds:
     · two-line header (counts on top, money on bottom)
     · top-of-body progress bar (done + running fills)
     · per-row mini progress bar (multi-pass crons)
     · pulse animation on running rows
     · expandable detail panel with raw summary + retry button
     · sticky reopen pill (separate selector below)
   ═══════════════════════════════════════════════════════════════ */

/* Two-line header inside .rax-modal__sub. The container drops the
   single-line monospace styling — each line now controls its own
   typography. */
.rax-modal__sub:has(.rax-sub-line) {
  font-family: inherit;
  font-size: 12px;
  letter-spacing: normal;
  margin-top: 6px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.rax-sub-line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 12px;
  color: var(--v4-ink-2);
}
.rax-sub-line--top { font-size: 12.5px; }
.rax-sub-line--bot { font-size: 11.5px; }
.rax-sub-line strong { color: var(--v4-ink); font-variant-numeric: tabular-nums; }
.rax-sub-line a {
  margin-left: auto;
  color: var(--v4-purple);
  font-family: var(--v4-mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
}

.rax-tag {
  font-family: var(--v4-mono);
  font-size: 10.5px;
  padding: 1px 7px;
  border-radius: 999px;
  letter-spacing: 0.04em;
}
.rax-tag--running   { background: rgba(99, 102, 241, 0.12); color: #4338CA; }
.rax-tag--queued    { background: var(--v4-recess);         color: var(--v4-ink-3); }
.rax-tag--failed    { background: rgba(220, 38, 38, 0.12);  color: #B91C1C; }
.rax-tag--cancelled { background: rgba(107, 114, 128, 0.15);color: #4B5563; }

.rax-eta {
  font-family: var(--v4-mono);
  font-size: 10.5px;
  color: var(--v4-purple);
  background: rgba(99, 102, 241, 0.08);
  padding: 1px 7px;
  border-radius: 999px;
}

.rax-saved {
  font-family: var(--v4-mono);
  font-size: 10.5px;
  color: #047857;
  background: rgba(16, 185, 129, 0.10);
  padding: 1px 7px;
  border-radius: 999px;
}

/* Top-of-body progress bar — two side-by-side fills: done (solid) +
   running (pulsing). Flex layout so they auto-stack without us having
   to compute "running starts at <done>%" from JS. */
.rax-progbar {
  display: flex;
  height: 4px;
  background: var(--v4-recess);
  border-radius: 999px;
  margin: 0 0 14px;
  overflow: hidden;
}
.rax-progbar__done {
  flex: 0 0 auto;
  background: linear-gradient(90deg, #10B981, #059669);
  transition: width 0.4s cubic-bezier(.2,.7,.3,1);
}
.rax-progbar__running {
  flex: 0 0 auto;
  background: linear-gradient(90deg, rgba(99,102,241,0.55), rgba(99,102,241,0.85));
  transition: width 0.4s cubic-bezier(.2,.7,.3,1);
  animation: rax-progbar-pulse 1.4s ease-in-out infinite;
}
@keyframes rax-progbar-pulse {
  0%, 100% { opacity: 0.65; }
  50%      { opacity: 1.00; }
}

/* Per-row layout: main row + (optional) mini bar + (optional) detail. */
.rax-prog-row {
  display: flex;
  flex-direction: column;
  padding: 9px 12px;
  cursor: pointer;
}
.rax-prog-row__main {
  display: grid;
  grid-template-columns: 28px 1fr auto auto;
  align-items: center;
  gap: 10px;
}
.rax-prog-row__bar {
  margin-top: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
  height: 6px;
  position: relative;
}
.rax-prog-row__bar[hidden] { display: none; }
.rax-prog-row__bar-fill {
  flex: 1;
  height: 4px;
  background: linear-gradient(90deg, rgba(99,102,241,0.55), rgba(99,102,241,0.85));
  border-radius: 999px;
  transition: width 0.5s cubic-bezier(.2,.7,.3,1);
}
.rax-prog-row__bar-label {
  font-family: var(--v4-mono);
  font-size: 10px;
  color: var(--v4-ink-3);
  white-space: nowrap;
  min-width: 64px;
  text-align: right;
}

.rax-prog-row__detail {
  display: none;
  margin-top: 10px;
  padding: 10px 12px;
  background: rgba(0,0,0,0.025);
  border-radius: 6px;
  font-size: 11.5px;
  color: var(--v4-ink-2);
  cursor: default;
}
.rax-prog-row.is-expanded .rax-prog-row__detail { display: block; }
.rax-prog-row.is-expanded { background: rgba(0,0,0,0.02); }
.rax-prog-row__desc {
  color: var(--v4-ink);
  margin-bottom: 6px;
  font-style: italic;
}
.rax-prog-row__summary {
  font-family: var(--v4-mono);
  font-size: 10.5px;
  color: var(--v4-ink-2);
  white-space: pre-wrap;
  word-break: break-word;
  background: var(--v4-recess);
  padding: 6px 8px;
  border-radius: 4px;
  margin-bottom: 6px;
}
.rax-prog-row__avg {
  font-family: var(--v4-mono);
  font-size: 10px;
  color: var(--v4-ink-3);
  margin-bottom: 6px;
}

/* Compressed-chip rendering for the per-row summary. Zeros dim down,
   non-zero counts bold up, errors flag red. */
.rax-chip { display: inline; }
.rax-chip strong { font-weight: 700; color: var(--v4-ink); font-variant-numeric: tabular-nums; }
.rax-chip--zero  { color: var(--v4-ink-3); opacity: 0.55; }
.rax-chip--err   { color: #B91C1C; }
.rax-chip--err strong { color: #B91C1C; }
.rax-chip--note  { color: var(--v4-ink-3); font-style: italic; }
.rax-chip-sep {
  color: var(--v4-ink-3);
  opacity: 0.55;
  margin: 0 4px;
}
.rax-chip-sep--major {
  margin: 0 6px;
  color: var(--v4-ink-3);
}

/* Pulse on the actively-running row */
.rax-prog-row[data-status="running"] {
  animation: rax-row-pulse 2.2s ease-in-out infinite;
}
@keyframes rax-row-pulse {
  0%, 100% { background: rgba(99, 102, 241, 0.06); }
  50%      { background: rgba(99, 102, 241, 0.14); }
}

.rax-prog-row[data-status="cached"]    { background: rgba(99, 102, 241, 0.04); border-color: rgba(99, 102, 241, 0.20); }
.rax-prog-row__pill--cached            { background: rgba(99, 102, 241, 0.12); color: #4338CA; border: 1px solid rgba(99, 102, 241, 0.30); }
.rax-prog-row[data-status="skipped"]   { background: rgba(107, 114, 128, 0.08); border-color: rgba(107, 114, 128, 0.25); opacity: 0.8; }
.rax-prog-row__pill--skipped           { background: rgba(107, 114, 128, 0.15); color: #4B5563; border: 1px solid rgba(107, 114, 128, 0.4); }

/* Cancel-remaining button — gets a real-button treatment so it doesn't
   look disabled. Previously rendered as ghost-button which read as off. */
.rax-cancel-btn {
  color: var(--v4-neg);
  border-color: rgba(220, 38, 38, 0.35);
  background: rgba(220, 38, 38, 0.04);
}
.rax-cancel-btn:hover:not(:disabled) {
  background: rgba(220, 38, 38, 0.10);
  border-color: rgba(220, 38, 38, 0.55);
}
.rax-cancel-btn[hidden] { display: none; }

.rax-retry-btn {
  margin-top: 4px;
}

/* ─── Sticky reopen pill (modal closed while batch still running) ── */
.sentinel-reopen-pill {
  position: fixed;
  bottom: 18px;
  right: 18px;
  z-index: 180;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  background: var(--v4-card, #fff);
  border: 1px solid var(--v4-border);
  border-radius: 999px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.18), 0 1px 0 rgba(0,0,0,0.04);
  font-size: 12.5px;
  color: var(--v4-ink);
  animation: rax-pill-rise 0.24s cubic-bezier(.2,.7,.3,1.3);
  max-width: 360px;
}
@keyframes rax-pill-rise {
  from { transform: translateY(8px); opacity: 0; }
  to   { transform: translateY(0);   opacity: 1; }
}
.sentinel-reopen-pill[data-tone="running"] {
  border-color: rgba(99, 102, 241, 0.35);
  background: linear-gradient(180deg, rgba(99,102,241,0.04), rgba(99,102,241,0.02));
}
.sentinel-reopen-pill[data-tone="ok"] {
  border-color: rgba(16, 185, 129, 0.45);
  background: linear-gradient(180deg, rgba(16,185,129,0.06), rgba(16,185,129,0.02));
}
.sentinel-reopen-pill[data-tone="warn"] {
  border-color: rgba(245, 158, 11, 0.45);
  background: linear-gradient(180deg, rgba(245,158,11,0.08), rgba(245,158,11,0.02));
}
.sentinel-reopen-pill__icon {
  font-size: 14px;
  display: grid;
  place-items: center;
}
.sentinel-reopen-pill__icon--spin {
  animation: rax-spin 1s linear infinite;
  color: var(--v4-purple);
}
.sentinel-reopen-pill__label {
  font-weight: 600;
  white-space: nowrap;
}
.sentinel-reopen-pill__meta {
  font-family: var(--v4-mono);
  font-size: 10.5px;
  color: var(--v4-ink-3);
  white-space: nowrap;
}
.sentinel-reopen-pill__btn {
  border: 1px solid var(--v4-border);
  background: var(--v4-card);
  color: var(--v4-ink);
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.sentinel-reopen-pill__btn:hover { background: var(--v4-recess); }
.sentinel-reopen-pill__close {
  background: transparent;
  border: 0;
  color: var(--v4-ink-3);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  padding: 4px;
  margin-left: 2px;
}
.sentinel-reopen-pill__close:hover { color: var(--v4-ink); }

@media (max-width: 540px) {
  .sentinel-reopen-pill { bottom: 12px; right: 12px; left: 12px; max-width: none; }
  .sentinel-reopen-pill__label { font-size: 11.5px; }
}

/* ═══════════════════════════════════════════════════════════════
   Cross-page status banner (SYSTEMS.md §5.6.4)
   Sits at the top of the focus column, above page content.
   Per-session dismissible.
   ═══════════════════════════════════════════════════════════════ */
.v4-status-banner {
  /* Span the full grid row regardless of the underlying shell template.
     The previous `grid-column: focus` referenced a named line that only
     exists on a subset of pages; on the dashboard's `1fr 372px` shell
     the browser auto-created an implicit "focus" track and collapsed
     the focus column to 72px wide (which broke every wide-viewport
     dashboard render). `1 / -1` spans every column explicitly. */
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  margin: 12px 16px 0;
  border-radius: 10px;
  font-size: 12.5px;
  line-height: 1.5;
  background: rgba(99, 102, 241, 0.06);
  border: 1px solid rgba(99, 102, 241, 0.25);
  color: var(--v4-ink);
}
.v4-status-banner--warn  { background: rgba(245, 158, 11, 0.10); border-color: rgba(245, 158, 11, 0.35); color: #B45309; }
.v4-status-banner--alert { background: rgba(220, 38, 38, 0.08);  border-color: rgba(220, 38, 38, 0.35);  color: #B91C1C; }
.v4-status-banner__icon { flex-shrink: 0; font-size: 14px; opacity: 0.85; }
.v4-status-banner__msg  { flex: 1; }
.v4-status-banner__msg a { color: inherit; text-decoration: underline; }
.v4-status-banner__dismiss {
  flex-shrink: 0;
  background: transparent;
  border: none;
  color: inherit;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  opacity: 0.55;
  padding: 4px 6px;
}
.v4-status-banner__dismiss:hover { opacity: 1; }

/* ════════════════════════════════════════════════════════════════════
   SIDEBAR FOOTER — Online users dock + Notifications popover
   ════════════════════════════════════════════════════════════════════
   Both shipped May 11 as part of the dark-footer interactivity pass.
   The dock surfaces presence (who else is using the app right now);
   the popover surfaces actionable signals (P1 reviews, AI drafts,
   failed crons, AI spend, vacate pressure). */

/* ─── Online-users dock ─── */
.v4-nav__online {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 10px;
  margin: 6px 0 4px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 10px;
  text-decoration: none;
  color: var(--v4-on-dark);
  font-size: 11px;
  transition: background 0.15s, border-color 0.15s;
}
/* `display: flex` overrides the default `hidden` attribute styling, so
   `dock.hidden = true` in JS alone isn't enough — this rule restores
   the expected hide-when-attribute-set behavior. Same gotcha that bit
   the notifications panel earlier today. */
.v4-nav__online[hidden] { display: none !important; }
.v4-nav__online:hover {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.10);
}
/* Solo state — dimmer + grey dot so it doesn't fight for attention
   when nobody else is online. As soon as a real avatar appears,
   `data-solo=0` kicks back in and the chip lights up. */
.v4-nav__online[data-solo="1"] { opacity: 0.55; }
.v4-nav__online[data-solo="1"] .v4-nav__online-dot {
  background: rgba(255, 255, 255, 0.25);
  animation: none;
  box-shadow: none;
}
.v4-nav__online-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--v4-mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.68);
  white-space: nowrap;
}
.v4-nav__online-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--v4-lime, #C8FF3D);
  box-shadow: 0 0 0 2px rgba(200, 255, 61, 0.30);
  animation: v4-nav__pulse 2.2s ease-in-out infinite;
}
@keyframes v4-nav__pulse {
  0%, 100% { box-shadow: 0 0 0 2px rgba(200, 255, 61, 0.30); }
  50%      { box-shadow: 0 0 0 5px rgba(200, 255, 61, 0); }
}
.v4-nav__online-stack {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
}
.v4-nav__online-chip {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  overflow: hidden;
  margin-left: -6px;
  border: 2px solid #1a1a1a;       /* matches dark nav bg so chips look stacked */
  font-family: var(--v4-mono);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.02em;
  color: white;
  background: var(--v4-purple);
  cursor: pointer;
  transition: transform 0.12s;
}
.v4-nav__online-chip:first-child { margin-left: 0; }
.v4-nav__online-chip:hover { transform: translateY(-1px); z-index: 1; }
.v4-nav__online-chip--more {
  background: rgba(255, 255, 255, 0.10);
  color: rgba(255, 255, 255, 0.75);
  font-size: 9px;
}

/* ─── Bell button count badge (numeric, sits beside the red dot) ─── */
.v4-nav__utilbtn-count {
  position: absolute;
  top: -3px;
  right: -3px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--v4-neg, #dc2626);
  color: white;
  font-family: var(--v4-mono);
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 0 0 2px #1a1a1a;
  pointer-events: none;
}
.v4-nav__utilbtn-dot[data-severity="warn"]  { background: var(--v4-warn, #f59e0b); }
.v4-nav__utilbtn-dot[data-severity="info"]  { background: var(--v4-blue, #3b82f6); }
.v4-nav__utilbtn-dot[data-severity="alert"] { background: var(--v4-neg, #dc2626); }

/* ─── Notifications popover ─── */
/* Pinned to the viewport (NOT the sidebar) so the 380px wide panel
   can extend beyond the narrow sidebar bounds. Bottom-left anchor
   sits just above the bell icon's row, slightly right of the sidebar
   so it spills onto the main canvas like a real dropdown. */
.v4-notif-panel {
  position: fixed;
  left: 16px;
  bottom: 56px;
  width: 380px;
  max-width: calc(100vw - 32px);
  max-height: min(520px, calc(100vh - 96px));
  display: flex;
  flex-direction: column;
  background: white;
  color: var(--v4-ink, #111);
  border: 1px solid var(--v4-border, rgba(0,0,0,0.10));
  border-radius: 14px;
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.22), 0 4px 12px rgba(0, 0, 0, 0.10);
  z-index: 1001;            /* must be above the dimmer backdrop (z=1000) */
  overflow: hidden;
  animation: v4-notif-enter 0.18s ease-out;
}
/* CRITICAL — the panel uses `display: flex`, which overrides the
   default `hidden` attribute styling. Without this rule, setting
   `panel.hidden = true` in JS has no visual effect (the panel stays
   visible) — explaining the "X button doesn't close" bug. */
.v4-notif-panel[hidden] { display: none !important; }
/* On wider screens, slide the panel further right so it doesn't
   crowd the sidebar's icon row. */
@media (min-width: 720px) {
  .v4-notif-panel {
    left: 280px;            /* just past the 264px sidebar */
    bottom: 24px;
  }
}
@keyframes v4-notif-enter {
  from { opacity: 0; transform: translateY(6px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.v4-notif-panel__head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--v4-border, rgba(0,0,0,0.06));
  background: linear-gradient(180deg, rgba(0,0,0,0.02), transparent);
}
.v4-notif-panel__head strong {
  font-size: 13.5px;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.v4-notif-panel__meta {
  margin-left: auto;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--v4-ink-3, #666);
}
.v4-notif-panel__close {
  background: transparent;
  border: 0;
  cursor: pointer;
  padding: 4px;
  border-radius: 6px;
  color: var(--v4-ink-3);
  transition: background 0.12s, color 0.12s;
}
.v4-notif-panel__close:hover { background: rgba(0,0,0,0.05); color: var(--v4-ink); }
.v4-notif-panel__list {
  flex: 1;
  overflow-y: auto;
  padding: 6px 0;
}
.v4-notif-panel__empty {
  padding: 36px 24px;
  text-align: center;
  font-size: 13px;
  color: var(--v4-ink-3);
}
.v4-notif-panel__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 14px;
  border-top: 1px solid var(--v4-border, rgba(0,0,0,0.06));
  background: linear-gradient(0deg, rgba(0,0,0,0.02), transparent);
  font-size: 11px;
}
.v4-notif-panel__hint {
  color: var(--v4-ink-4);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.v4-notif-panel__refresh {
  background: transparent;
  border: 1px solid var(--v4-border, rgba(0,0,0,0.08));
  border-radius: 6px;
  padding: 4px 8px;
  font-size: 11px;
  font-family: var(--v4-mono);
  color: var(--v4-ink-2);
  cursor: pointer;
  transition: all 0.12s;
}
.v4-notif-panel__refresh:hover { background: rgba(0,0,0,0.04); color: var(--v4-ink); }

/* ─── Notification items ─── */
.v4-notif-item {
  display: grid;
  grid-template-columns: 28px 1fr;
  gap: 10px;
  padding: 11px 14px;
  border-left: 3px solid transparent;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  transition: background 0.12s;
}
.v4-notif-item:hover { background: rgba(0,0,0,0.03); }
.v4-notif-item--alert { border-left-color: var(--v4-neg, #dc2626); }
.v4-notif-item--warn  { border-left-color: var(--v4-warn, #f59e0b); }
.v4-notif-item--info  { border-left-color: var(--v4-blue, #3b82f6); }
.v4-notif-item__icon {
  width: 28px; height: 28px;
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  margin-top: 1px;
}
.v4-notif-item--alert .v4-notif-item__icon { background: rgba(220, 38, 38, 0.10);  color: var(--v4-neg, #dc2626); }
.v4-notif-item--warn  .v4-notif-item__icon { background: rgba(245, 158, 11, 0.12); color: var(--v4-warn, #f59e0b); }
.v4-notif-item--info  .v4-notif-item__icon { background: rgba(59, 130, 246, 0.10); color: var(--v4-blue, #3b82f6); }
.v4-notif-item__body { min-width: 0; }
.v4-notif-item__title {
  font-size: 13px;
  font-weight: 600;
  color: var(--v4-ink);
  letter-spacing: -0.01em;
  line-height: 1.3;
}
.v4-notif-item__detail {
  margin-top: 2px;
  font-size: 11.5px;
  color: var(--v4-ink-3);
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.v4-notif-item__ts {
  margin-top: 4px;
  font-family: var(--v4-mono);
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--v4-ink-4);
  text-transform: uppercase;
}

/* The footer chrome wrapping these — v4-nav__bottom — needs to be a
   positioning context so the popover anchors correctly. */
.v4-nav__bottom { position: relative; }
