/* =============================================================================
   VO CRM - "Operations Console" cockpit design-system layer
   Source of truth: docs/design/cockpit-concepts/d-hybrid.html (Concept D)
   Refactored into the reusable .cpx-* instrument component kit.

   Division of labor: Tailwind CDN owns LAYOUT (flex/grid/spacing/responsive);
   this file owns the INSTRUMENT LOOK via semantic .cpx-* classes. Pure CSS, so
   styling survives htmx partial swaps with no JS dependency.

   Color discipline (two metals, two jobs):
     --gold (structural)      = ambient chrome: instrument frames, hero numerals,
                                donut/funnel/gauge ink, panel corner accents. Faint,
                                STATIC, everywhere. "This is an instrument."
     --signal-priority (amber)= the needs-you SIGNAL: a near deadline, an awaiting
                                reply, a focal node, a selection ring. Scarce and the
                                ONLY glow that animates. "This needs you."
   Gold and amber are kept as separate tokens on purpose; do not collapse them.
   --signal-nominal (green) = nominal/healthy. --signal-critical (red) = critical.
   --signal-dream (purple) = dream-client marker. Never decorative amber.
   ============================================================================= */

/* ---------------------------------------------------------------------------
   Self-hosted fonts (no external CDN - offline-capable, self-hostable on VPS)
   --------------------------------------------------------------------------- */
/* Faces are self-hosted via @font-face in cc_base.html (/static/fonts/*.woff2);
   no external CDN so the app stays offline-capable. Weights 400/600 (Saira) and
   400/500 (Spline Sans Mono) are bundled; 500/700/800 synthesize until self-hosted. */

/* ---------------------------------------------------------------------------
   Design tokens
   Text runs BRIGHT by user preference: --txt is pure white, --txt-dim is a
   near-white light gray. Higher contrast on the dark substrate = strictly more
   accessible; do not darken these back down.
   --------------------------------------------------------------------------- */
:root{
  /* substrate - base shifted toward the command-center deep teal-black field
     (mockup --field hsl(203 25% 4.5%)) so the translucent glass panels read over
     a cooler ground. The lighter substrate steps are unchanged. */
  --ink:hsl(203 25% 4.5%); --charcoal:#15161a; --gunmetal:#23252b; --steel:#2e3138;

  /* signal logic - amber=priority/attention, green=nominal, red=critical, info=muted accent */
  --signal-priority:#f5b301; --signal-priority-2:#ffcf4d;
  --signal-nominal:#3f9956; --signal-critical:#c2453a; --signal-info:#b3bec9;
  --signal-critical-2:#ff2d2d;  /* vivid red for emphasis (demo-mode indicator) */
  /* Bright green, the readable-on-dark partner to --signal-nominal, exactly as
     --signal-priority-2 partners --signal-priority. This value was already the
     de facto token for green TEXT and gradient highlights but had never been
     declared, so it sits hard-coded in roughly 40 places across the per-page
     stylesheets. New code uses this token; those sites can migrate as they are
     touched. */
  --nominal-2:#5fcf87;
  /* The readable-on-dark partner to --signal-info, completing the pattern
     --signal-priority/-2 and --signal-nominal/--nominal-2 already follow. Used
     for the muted "automated / system" text that sits on --info-dim. */
  --info-2:#aeb9c7;
  /* Text that sits ON a gold fill. Nearly black with a warm cast so it reads as
     part of the gold rather than a hole punched in it. Always paired with
     --gold-gradient or --gold-2; never use it on a dark ground. */
  --on-gold:#1a1300;

  /* text - bright by user preference: white primary, near-white dim */
  --txt:#ffffff; --txt-dim:#e6eaf0;

  /* structure */
  --bezel:#34373f; --hairline:#23252b; --inset:#0e0f12;

  /* panel glass surface - the translucent ground the cyber-city map reads
     through. --panel-bg is the default lit glass; --panel-bg-solid is an
     opt-in denser surface (.cpx-panel--solid) for content-heavy pages that
     must win over the background without touching the background itself. */
  --panel-bg:rgba(10,16,24,0.74);
  --panel-bg-solid:rgba(10,16,24,0.93);

  /* ---------------------------------------------------------------------------
     STRUCTURAL GOLD (chrome) - ported from the command-center mockup (Concept E).
     This is ambient *structure*: faint, static gold for instrument frames, hero
     numerals, donut/funnel/gauge ink, and panel corner accents. It is NOT the
     amber needs-you signal. Gold = "this is an instrument"; amber
     (--signal-priority, below) = "this needs you". Keep them separate: gold never
     animates or pulses, amber does. (See the design-system doc, "Gold as ambient
     structure vs amber as signal".)
     --------------------------------------------------------------------------- */
  --gold:hsl(48 84% 50%); --gold-2:hsl(46 96% 62%); --gold-deep:hsl(42 72% 34%);
  --gold-gradient:linear-gradient(180deg, var(--gold-2), var(--gold) 52%, var(--gold-deep));
  --gold-ambient:rgba(235,178,30,0.09);     /* faint gold fill behind structural chips */
  --gold-edge:rgba(245,200,90,0.40);        /* the structural gold hairline / corner tick */
  --gold-edge-soft:rgba(245,200,90,0.16);   /* softest gold hairline (lead rules) */

  /* GLOW utilities (chrome bloom vs the loud needs-you signal) */
  --glow-bloom:drop-shadow(0 0 6px rgba(245,200,66,.30)) drop-shadow(0 0 15px rgba(245,200,66,.13)); /* soft gold bloom for hero instruments (static); restrained to match the reference */
  --glow-bezel:inset 0 1px 0 rgba(160,190,220,0.05);  /* faint inner top highlight on lit glass */
  --glow-amber-signal:0 0 8px rgba(255,207,77,0.5), 0 0 18px -2px rgba(255,207,77,0.6); /* the LOUD amber signal glow - needs-you only, the only glow that animates */

  /* gauge backplate - recessed tinted well behind reply-rate / score tapes */
  --gauge-backplate:rgba(245,200,90,0.05);

  /* ---------------------------------------------------------------------------
     BACKDROP / TEAL FIELD - the luminous cyber-city map substrate ONLY. Teal is
     a backdrop color, never a data color. Used by .cpx-body__city / __field /
     __vignette and the rail/panel field-bleed. --blue-map is the desaturated teal
     the contour map is stroked in; the edges are translucent tints of it.
     --------------------------------------------------------------------------- */
  --blue-map:#6fb0c8;                       /* desaturated teal the city map glows in */
  --blue-edge:rgba(111,176,200,0.14);       /* teal field-bleed at the rail / panel edge */
  --blue-haze:rgba(40,98,128,0.20);         /* teal atmospheric haze under the top bar */
  --teal-edge:var(--blue-edge);             /* alias: the teal hairline edge tint */
  --rail-glass:rgba(15,21,27,0.40);         /* translucent left-rail veil - the cyber-city reads crisply through the rail (no blur); lower the alpha to show more city, raise it for more nav-label contrast */

  /* derived signal tints (translucent, for fills/glows) */
  --priority-dim:rgba(245,179,1,.12);
  --nominal-dim:rgba(63,153,86,.14);
  --critical-dim:rgba(194,69,58,.16);
  --info-dim:rgba(91,100,114,.14);

  /* dream-client designation - a SPECIAL category marker, NOT a health signal.
     The only purple in the system; kept outside amber/green/red so it never reads
     as priority/nominal/critical. */
  --signal-dream:#a779e8; --signal-dream-2:#d4b8ff; --dream-dim:rgba(167,121,232,.18);

  /* warmth ramp: engagement recency on the relationship graph, hot (orange) to cold
     (blue) in 5 steps. A data spectrum (heatmap convention), distinct from the amber
     priority signal. 4=hot recent contact ... 0=cold/never (may need re-introduction). */
  --warmth-4:#ff8a4c; --warmth-3:#f4b15e; --warmth-2:#a9b1bd; --warmth-1:#6699d6; --warmth-0:#4070b5;

  /* ---------------------------------------------------------------------------
     INSTRUMENT DATA RAMP - the single gold->bronze->steel monochrome chart palette
     for the dashboard instruments (funnel bands, audition donut). It is ambient
     gold STRUCTURE, not the amber needs-you signal: it never animates. Ordered
     ramp-1 (brightest gold) .. ramp-5 (cool steel). (See the design-system doc,
     "Instrument data ramp".)
     --------------------------------------------------------------------------- */
  --ramp-1:hsl(46 96% 62%); --ramp-2:hsl(44 84% 50%); --ramp-3:hsl(38 70% 44%);
  --ramp-4:hsl(34 40% 42%); --ramp-5:hsl(205 12% 44%);
  /* desaturated steel-blue greys (decorative instrument substrate) */
  --steel-info:hsl(203 14% 67%);
  /* soft amber text-shadow for hero instrument numerals (static, not the signal) */
  --num-bloom:0 0 8px rgba(245,200,66,.20), 0 0 4px rgba(255,236,170,.14);

  --font-display:"Saira",sans-serif; --font-mono:"Spline Sans Mono",monospace;
  --r:6px; --gap:16px;
  /* --- Type scale (role-named, never value-named) -------------------------
     Seven roles, two bands. Mono (label / chip / meta) reads optically larger
     than display at the same pixel size, which is why the codebase drifted mono
     downward; the bands therefore scale independently. Adjust a ROLE here, never
     a raw px in a page stylesheet. */
  --fs-label:8.5px;      /* uppercase tracked micro-label (__k, __lbl) */
  --fs-chip:9px;         /* chips, badges, counts */
  --fs-meta:10px;        /* timestamps, secondary meta */
  --fs-caption:11px;     /* captions, inputs, small controls */
  --fs-control:12px;     /* buttons and control labels */
  --fs-secondary:12.5px; /* secondary prose */
  --fs-body:13px;        /* primary value text (__v) */
}

/* Reader text-size presets. Server-rendered onto <html> from app_state, so there
   is no flash: every script in cc_base's head is deferred and could not apply a
   size before first paint. Mono grows ~12% then ~24%, display ~5% then ~13%.
   Values are explicit per preset rather than a multiplier so each state is an
   exact, screenshotable thing with no rounding to reason about. */
html[data-text-size="larger"]{
  --fs-label:9.5px; --fs-chip:10px; --fs-meta:11px; --fs-caption:12px;
  --fs-control:12.5px; --fs-secondary:13px; --fs-body:14px;
}
html[data-text-size="largest"]{
  --fs-label:10.5px; --fs-chip:11px; --fs-meta:12px; --fs-caption:13px;
  --fs-control:13.5px; --fs-secondary:14px; --fs-body:15px;
}

/* ---------------------------------------------------------------------------
   Substrate - body background, phosphor grid, scanline (decorative, not signal)
   --------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------
   Scrollbars - the standard properties, which are the ones that actually render.

   The old -webkit-scrollbar block was copy-pasted into 15 stylesheets as 22
   near-identical copies that drifted on width (7 / 8 / 9px) and radius (4 / 5px).
   Every one of them was DEAD CODE, which is exactly why the drift went unnoticed
   for so long: nothing rendered differently, so nothing looked wrong.

   Chrome ignores ALL -webkit-scrollbar pseudo-elements on an element whose
   standard `scrollbar-color` is set, and `scrollbar-color` INHERITS. `.cc-main`
   sets it on every page, so it reaches every scrollable descendant and switches
   the whole app onto the standard properties. Measured directly in Chrome 151:
   identical webkit rules give an 8px thumb alone, and the 17px browser default
   under an inherited scrollbar-color.

   Two traps for anyone extending this:
     - `scrollbar-color` inherits; `scrollbar-width` does NOT.
     - the standard width takes auto / thin / none only, never a pixel value, so
       a request like "make them 8px" cannot be expressed here.

   Deliberate variants, all already on the standard properties:
     .cpx-dash .cpx-panel__body            scrollbar-width:none (hidden)
     .cpx-area-priorities .cpx-panel__body thin + --steel thumb
     .cpx-panel__body--scroll              thin + gold thumb (cc-extra.css)
   --------------------------------------------------------------------------- */
.cc-root{ scrollbar-color:var(--hairline) transparent; }
/* scrollbar-width does not inherit, so it has to be applied per element rather
   than once at the root. This is the slim thumb all 22 dead rules were reaching
   for (they asked for 7-9px; `thin` is the nearest the standard property offers).
   .cpx-dash (none) and the thin variants above are all at higher specificity and
   still win. */
.cc-root, .cc-root *{ scrollbar-width:thin; }

.cpx-body{
  /* The UA default body margin (8px) has to die here, not only in cc-extra.css.
     That file carries `body{margin:0}` for the cc_ shell, but a page can load
     this stylesheet WITHOUT the shell layer (the pre-auth sign-in page does), and
     it was previously Tailwind's preflight that zeroed it. Without this, every
     such page shifts 8px down and right. */
  margin:0;
  background:
    radial-gradient(1200px 700px at 78% -8%, var(--priority-dim), transparent 60%),
    radial-gradient(1000px 640px at 6% 112%, var(--charcoal) 0%, transparent 58%),
    var(--ink);
  color:var(--txt);
  font-family:var(--font-display);
  font-size:var(--fs-body);
  line-height:1.45;
  -webkit-font-smoothing:antialiased;
}
/* Headings inherit rather than taking UA sizes: also previously supplied by
   Tailwind's preflight, and load-bearing for any heading on a preflight-free
   page (the sign-in page's visually-hidden <h1> was jumping to 26px/700).
   Deliberately does NOT reset margin. At (0,1,1) this outranks the (0,1,0)
   .sr-only utility, so a margin:0 here silently overrides .sr-only's margin:-1px
   wherever the two meet. The cc_ pages never had preflight, so their headings
   already live without a margin reset; only the size/weight inherit is needed
   for parity. */
.cpx-body h1, .cpx-body h2, .cpx-body h3,
.cpx-body h4, .cpx-body h5, .cpx-body h6{ font-size:inherit; font-weight:inherit; }
/* faint phosphor grid texture */
.cpx-body::before{
  content:""; position:fixed; inset:0; z-index:0; pointer-events:none;
  background-image:
    linear-gradient(rgba(154,161,171,0.018) 1px, transparent 1px),
    linear-gradient(90deg, rgba(154,161,171,0.018) 1px, transparent 1px);
  background-size:33px 33px;
  -webkit-mask-image:radial-gradient(120% 100% at 50% 4%, #000 52%, transparent 100%);
  mask-image:radial-gradient(120% 100% at 50% 4%, #000 52%, transparent 100%);
}
/* subtle scanline + vignette */
.cpx-body::after{
  content:""; position:fixed; inset:0; z-index:9999; pointer-events:none;
  background:repeating-linear-gradient(0deg, rgba(0,0,0,0.10) 0px, rgba(0,0,0,0.10) 1px, transparent 1px, transparent 3px);
  opacity:0.30; mix-blend-mode:multiply;
}

.cpx-mono{ font-family:var(--font-mono); font-variant-numeric:tabular-nums; }

/* ===========================================================================
   .cpx-statusbar - persistent top telemetry bar
   =========================================================================== */
.cpx-statusbar{
  display:flex; align-items:center; gap:18px; min-height:48px; padding:0 20px;
  border-bottom:1px solid var(--hairline);
  background:linear-gradient(180deg, #16181d, #101216);
  box-shadow:0 1px 0 rgba(255,255,255,0.02) inset, 0 8px 18px -12px #000;
  font-size:var(--fs-caption); position:relative; z-index:5; flex-wrap:wrap;
}
.cpx-statusbar__brand{
  font-family:var(--font-display); font-weight:600; letter-spacing:.16em; text-transform:uppercase;
  color:var(--txt); font-size:var(--fs-control); display:flex; align-items:center; gap:8px; white-space:nowrap;
}
.cpx-statusbar__brand b{ color:var(--signal-nominal); }
.cpx-statusbar__online{
  display:flex; align-items:center; gap:7px; color:var(--signal-nominal);
  font-family:var(--font-mono); letter-spacing:.14em; font-size:var(--fs-meta);
}
.cpx-statusbar__online .cpx-lamp{
  width:8px; height:8px; border-radius:50%; background:var(--signal-nominal);
  box-shadow:0 0 8px var(--signal-nominal), 0 0 2px var(--txt) inset;
}
.cpx-statusbar__div{ width:1px; height:18px; background:var(--hairline); }
.cpx-statusbar__stat{
  display:flex; align-items:center; gap:7px; font-family:var(--font-mono);
  color:var(--txt-dim); letter-spacing:.1em; font-size:var(--fs-meta); white-space:nowrap;
}
.cpx-statusbar__stat b{ color:var(--txt); }
.cpx-statusbar__stat b.cpx-am{ color:var(--signal-priority); }   /* amber = attention metric */
.cpx-statusbar__right{ margin-left:auto; display:flex; align-items:center; gap:14px; }
.cpx-clock{
  font-family:var(--font-mono); color:var(--txt); letter-spacing:.06em; font-size:var(--fs-control);
  padding:5px 11px; border:1px solid var(--hairline); border-radius:5px; background:var(--inset);
  box-shadow:0 0 0 1px rgba(0,0,0,0.4) inset;
}
.cpx-clock .cpx-z{ color:var(--txt-dim); }

/* ===========================================================================
   .cpx-cmdbar - command-line bar with phosphor caret + quick-jump
   =========================================================================== */
.cpx-cmdbar{
  border:1px solid var(--bezel); border-radius:8px; overflow:hidden;
  background:linear-gradient(180deg, #14161b, #0b0c0f);
  box-shadow:0 1px 0 rgba(255,255,255,0.03) inset, 0 16px 30px -24px #000, 0 0 0 1px rgba(0,0,0,0.5);
}
.cpx-cmdbar__top{
  display:flex; align-items:center; gap:8px; padding:7px 13px; border-bottom:1px solid var(--hairline);
  font-family:var(--font-mono); font-size:var(--fs-chip); letter-spacing:.2em; color:var(--txt-dim); background:var(--inset);
}
.cpx-cmdbar__top .cpx-corner{ color:var(--gold-2); }
.cpx-cmdbar__preview{ margin-left:auto; color:var(--signal-info); letter-spacing:.18em; }
.cpx-cmdbar__line{ display:flex; align-items:center; gap:13px; padding:14px 18px; }
.cpx-cmdbar__chev{
  color:var(--gold-2); font-family:var(--font-mono); font-size:20px; font-weight:700; line-height:1;
  text-shadow:0 0 10px rgba(245,200,66,.5);
}
.cpx-cmdbar__input{
  flex:1 1 auto; min-width:0; background:transparent; border:0; outline:none;
  font-family:var(--font-mono); font-size:16px; color:var(--txt); letter-spacing:.01em;
}
.cpx-cmdbar__input::placeholder{ color:var(--txt-dim); }
/* static prompt fallback when no <input> is used */
.cpx-cmdbar__prompt{ font-family:var(--font-mono); font-size:16px; color:var(--txt); letter-spacing:.01em; white-space:nowrap; }
.cpx-cmdbar__prompt .cpx-q{ color:var(--txt-dim); }
.cpx-caret{
  display:inline-block; width:9px; height:19px; vertical-align:-3px; margin-left:2px;
  background:var(--gold-2); box-shadow:0 0 9px var(--gold-2);
}
.cpx-cmdbar__kbd{ margin-left:auto; display:flex; gap:6px; }
.cpx-cmdbar__kbd span{
  font-family:var(--font-mono); font-size:var(--fs-meta); color:var(--txt-dim);
  border:1px solid var(--bezel); border-radius:3px; padding:3px 7px; background:var(--charcoal);
}
/* quick-jump results dropdown */
.cpx-cmdbar__results{
  list-style:none; margin:0; padding:4px; border-top:1px solid var(--hairline); background:var(--inset);
}
.cpx-cmdbar__results:empty{ display:none; }
.cpx-cmdbar__result{
  display:flex; align-items:center; gap:10px; padding:8px 11px; border-radius:5px;
  font-family:var(--font-display); font-size:var(--fs-body); color:var(--txt-dim); cursor:pointer;
}
.cpx-cmdbar__result:hover{ background:var(--charcoal); color:var(--txt); }
/* Keyboard selection must be clearly visible, and distinguishable from hover:
   Enter routes to the selected row, so an invisible selection makes Enter a
   guess. --charcoal alone is only 7 points off --inset (the list background),
   which read as unstyled on the palette. --gunmetal plus an inset ring is
   legible without borrowing amber, which stays reserved for needs-you. */
.cpx-cmdbar__result[aria-selected="true"]{
  background:var(--gunmetal); color:var(--txt);
  box-shadow:inset 0 0 0 1px var(--steel);
}
.cpx-cmdbar__result .cpx-mono{ margin-left:auto; font-size:var(--fs-meta); color:var(--txt-dim); }

/* ===========================================================================
   .cpx-rail / .cpx-rail-group / .cpx-rail-item - grouped ops-console nav
   =========================================================================== */
.cpx-rail{
  border-right:1px solid var(--hairline);
  background:var(--rail-glass);    /* translucent glass: the lit cyber-city reads crisply through the rail (no blur) */
  display:flex; flex-direction:column; position:relative;
  flex:0 0 auto;  /* fixed-width sidebar - never shrink, regardless of main-content width */
}
.cpx-rail::after{
  content:""; position:absolute; top:0; right:-1px; bottom:0; width:1px;
  background:linear-gradient(180deg, transparent, rgba(245,179,1,.22), transparent);
}
.cpx-rail__brand{
  padding:16px 16px 14px; border-bottom:1px solid var(--hairline);
  display:flex; flex-direction:column; gap:9px;
}
.cpx-rail__brand h1{
  font-family:var(--font-display); font-weight:600; font-size:var(--fs-body); letter-spacing:.13em; line-height:1; color:var(--txt);
}
.cpx-rail__brand span{
  font-size:var(--fs-chip); letter-spacing:.26em; color:var(--txt-dim); text-transform:uppercase;
}
.cpx-rail__tag{
  font-family:var(--font-mono); font-size:var(--fs-label); letter-spacing:.22em; color:var(--signal-priority);
  border:1px solid rgba(245,179,1,.32); background:var(--priority-dim);
  padding:3px 6px; align-self:flex-start; border-radius:2px;
}
.cpx-rail-group{ padding:13px 11px 6px; }
.cpx-rail-group__lbl{
  font-family:var(--font-mono); font-size:var(--fs-chip); letter-spacing:.24em; color:var(--txt-dim); padding:0 8px 8px;
}
.cpx-rail-item{
  display:flex; align-items:center; gap:11px;
  padding:8px 10px; margin:1px 0; border-radius:5px;
  color:var(--txt-dim); text-decoration:none;
  font-family:var(--font-display); font-weight:400; letter-spacing:.03em; font-size:var(--fs-body);
  border:1px solid transparent; position:relative;
  transition:background .15s, color .15s, border-color .15s;
}
.cpx-rail-item .cpx-ic{ width:15px; height:15px; flex:0 0 auto; opacity:.72; stroke:currentColor; fill:none; stroke-width:1.6; }
.cpx-rail-item:hover{ background:var(--gunmetal); color:var(--txt); border-color:var(--steel); }
.cpx-rail-item:focus-visible{ outline:2px solid var(--signal-priority); outline-offset:1px; }
.cpx-rail-item--active{
  background:linear-gradient(90deg, rgba(63,153,86,0.15), rgba(63,153,86,0.02));
  color:var(--txt); border-color:rgba(63,153,86,.24);
}
.cpx-rail-item--active::before{
  content:""; position:absolute; left:-11px; top:6px; bottom:6px; width:2px;
  background:var(--signal-nominal); box-shadow:0 0 8px var(--signal-nominal);
}
.cpx-rail-item--active .cpx-ic{ opacity:1; color:var(--signal-nominal); }
.cpx-rail-item--locked{ color:var(--txt-dim); cursor:not-allowed; opacity:.72; }
.cpx-rail-item--locked .cpx-ic{ opacity:.4; }
.cpx-rail-item--locked:hover{ background:transparent; border-color:transparent; }
.cpx-rail-item__ver{
  margin-left:auto; font-family:var(--font-mono); font-size:var(--fs-label); letter-spacing:.14em; color:var(--signal-priority);
  border:1px solid rgba(245,179,1,.32); padding:2px 5px; border-radius:2px; background:var(--priority-dim);
}
.cpx-rail__sep{ height:1px; background:var(--hairline); margin:8px 9px; }

/* ===========================================================================
   .cpx-panel - framed bezel instrument panel (+ corner brackets, header, tag)
   =========================================================================== */
/* Command-center glass: a lit translucent rectangle. The cyber-city map field
   (z0) reads THROUGH the rgba background, so the panel reads as glass over a
   brighter teal ground. One thin hairline, faint inner top highlight, a small
   radius, and a single faint gold corner tick (top-left via ::after). Ported from
   the mockup .panel. Templates may still add four .cpx-panel__bracket corner ticks;
   both coexist. */
.cpx-panel{
  position:relative; border:1px solid var(--hairline); border-radius:var(--r);
  background:
    radial-gradient(120% 70% at 50% -10%, rgba(245,200,90,0.03), transparent 60%),
    var(--panel-bg);
  backdrop-filter:blur(5px) saturate(115%); -webkit-backdrop-filter:blur(5px) saturate(115%);
  box-shadow:
    var(--glow-bezel),               /* faint inner top highlight - lit glass */
    0 14px 30px -26px #000;
  overflow:hidden;
}
/* Solid variant: a denser glass surface so content wins over the cyber-city
   map on text-heavy pages (e.g. /rates). The background field is untouched;
   only the panel's own opacity rises via --panel-bg-solid. */
.cpx-panel--solid{
  background:
    radial-gradient(120% 70% at 50% -10%, rgba(245,200,90,0.03), transparent 60%),
    var(--panel-bg-solid);
  backdrop-filter:blur(7px) saturate(108%); -webkit-backdrop-filter:blur(7px) saturate(108%);
}
/* Deliberate gold chrome: opt-in only (quiet pass 2). The default panel border
   is hairline; the gold corner tick marks a hero/priority panel a page
   explicitly chooses via .cpx-panel--gold. */
.cpx-panel--gold::after{
  content:""; position:absolute; top:-1px; left:-1px; width:14px; height:14px;
  pointer-events:none; z-index:3;
  border-top:1px solid var(--gold-edge); border-left:1px solid var(--gold-edge);
  border-top-left-radius:var(--r); opacity:.7;
}
.cpx-panel__bracket{ position:absolute; width:11px; height:11px; border:1.5px solid rgba(245,179,1,.42); pointer-events:none; }
.cpx-panel__bracket--tl{ top:-1px; left:-1px; border-right:0; border-bottom:0; }
.cpx-panel__bracket--tr{ top:-1px; right:-1px; border-left:0; border-bottom:0; }
.cpx-panel__bracket--bl{ bottom:-1px; left:-1px; border-right:0; border-top:0; }
.cpx-panel__bracket--br{ bottom:-1px; right:-1px; border-left:0; border-top:0; }
.cpx-panel__hd{ display:flex; align-items:center; gap:10px; padding:11px 14px; border-bottom:1px solid var(--hairline); }

/* Solid single-surface page wrapper (Andy 2026-07-11: many small boxes cause
   visual fatigue). Wrap a column of .cpx-panel sections in .cc-solid and the
   panels flatten into ONE card: the wrapper carries the panel chrome, the
   children lose their borders/glass/corner brackets and separate with a plain
   hairline instead. Opt-in per page; markup inside the panels is untouched. */
.cc-solid{
  position:relative; border:1px solid var(--hairline); border-radius:var(--r);
  background:
    radial-gradient(120% 70% at 50% -10%, rgba(245,200,90,0.03), transparent 60%),
    rgba(10,16,24,0.74);
  backdrop-filter:blur(5px) saturate(115%); -webkit-backdrop-filter:blur(5px) saturate(115%);
  box-shadow:var(--glow-bezel), 0 14px 30px -26px #000;
  display:flex; flex-direction:column;
}
.cc-solid .cpx-panel{
  border:0; border-radius:0; background:transparent;
  backdrop-filter:none; -webkit-backdrop-filter:none; box-shadow:none;
}
.cc-solid .cpx-panel + .cpx-panel{ border-top:1px solid var(--hairline); }
.cc-solid .cpx-panel > .cc-pbr{ display:none; }
.cc-solid .cpx-panel__hd{ border-bottom:0; padding-bottom:4px; }
/* Readable helper prose (settings quiet pass, 2026-07-11). Any full-sentence
   helper/explainer text uses this instead of tracked-uppercase mono; mono CAPS
   stays reserved for labels, values, column headers, and telemetry. */
.cpx-prose{ font-size:var(--fs-body); line-height:1.6; color:var(--txt); max-width:70ch;
  letter-spacing:normal; text-transform:none; }
.cpx-panel__hd .cpx-dot{ width:6px; height:6px; flex:0 0 auto; border-radius:50%; background:var(--signal-info); box-shadow:0 0 6px var(--signal-info); }
.cpx-panel__hd .cpx-dot--none{ display:none; }
.cpx-panel__hd .cpx-dot--am{ background:var(--signal-priority); box-shadow:0 0 6px var(--signal-priority); }
.cpx-panel__title{
  font-family:var(--font-display); font-weight:600; letter-spacing:.12em; text-transform:uppercase; font-size:15px; color:var(--txt);
  white-space:nowrap;  /* headers stay on one row; never wrap to a second line */
}
.cpx-panel__hd{ flex-wrap:nowrap; }
.cpx-panel__hd .cpx-panel__sub{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0; }
.cpx-panel__sub{ font-family:var(--font-mono); font-size:var(--fs-meta); letter-spacing:.14em; color:var(--txt-dim); text-transform:uppercase; }
.cpx-panel__tag{
  margin-left:auto; font-family:var(--font-mono); font-weight:500; font-size:var(--fs-chip); letter-spacing:.14em; color:var(--signal-priority);
  border:1px solid rgba(245,179,1,.45); padding:2px 6px; border-radius:2px; background:var(--priority-dim);
}
/* ---- collapsible panel (native details/summary; multiple can be open) ---- */
details.cpx-panel--fold > summary{ list-style:none; cursor:pointer; }
details.cpx-panel--fold > summary::-webkit-details-marker{ display:none; }
details.cpx-panel--fold > summary:hover{ background:var(--gold-ambient); }
details.cpx-panel--fold > summary:focus-visible{ outline:2px solid var(--signal-priority); outline-offset:-2px; }
details.cpx-panel--fold:not([open]) > summary{ border-bottom:0; }
/* inside a .cc-solid list the collapsed rows keep symmetric padding (the wrapper's
   4px header tuck is for always-open panels) */
.cc-solid details.cpx-panel--fold:not([open]) > summary.cpx-panel__hd{ padding-bottom:11px; }
.cpx-fold__chev{ width:7px; height:7px; flex:0 0 auto; margin-left:10px;
  border-right:1.5px solid var(--txt-dim); border-bottom:1.5px solid var(--txt-dim);
  transform:rotate(45deg); transition:transform .15s ease; }
details.cpx-panel--fold[open] > summary .cpx-fold__chev{ transform:rotate(-135deg); }
@media (prefers-reduced-motion: reduce){ .cpx-fold__chev{ transition:none; } }

/* info + nominal chips brightened/saturated so they pop as readouts (amber stays the loudest) */
.cpx-panel__tag--info{ color:var(--info-2); border-color:rgba(174,185,199,.5); background:rgba(174,185,199,.14); }
.cpx-panel__tag--nominal{ color:var(--nominal-2); border-color:rgba(95,207,135,.5); background:rgba(95,207,135,.16); }
/* Dream-client chip - the single dream indicator. ~1.5x the standard chip, purple
   (the special-designation color, never amber), with margin for breathing room. The
   "shimmer" is a SATURATION wave: a band of richer purple drifts across the chip
   BEHIND the text (a z-index:-1 ::before, so it never overlays or washes out the
   label) once per ~2.4s. No white at any point, so the text stays readable. */
.cpx-panel__tag--dream{
  position:relative; overflow:hidden; isolation:isolate;
  margin:3px 0 3px auto;
  font-size:var(--fs-body); font-weight:600; letter-spacing:.08em; padding:3px 11px; border-radius:5px;
  text-transform:none; color:var(--signal-dream-2);
  border:1px solid var(--signal-dream); background:var(--dream-dim);
  box-shadow:0 0 11px rgba(167,121,232,.28), 0 0 2px rgba(212,184,255,.4) inset;
}
.cpx-panel__tag--dream::before{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:linear-gradient(110deg, transparent 34%, rgba(159,84,242,.6) 50%, transparent 66%);
  transform:translateX(-130%);
  animation:cpx-dream-sat 2.4s ease-in-out infinite;
}
@keyframes cpx-dream-sat{ 0%{ transform:translateX(-130%); } 60%,100%{ transform:translateX(130%); } }
/* Reduced motion: stop the wave, park the band off-chip -> a clean, evenly purple
   chip (no movement, no overlay). The border + glow still mark it as special. */
@media (prefers-reduced-motion: reduce){ .cpx-panel__tag--dream::before{ animation:none; } }
.cpx-panel__body{ padding:14px; }

/* ===========================================================================
   .cpx-annunciator - status lamp (label + state shape, never color-only)
   =========================================================================== */
.cpx-annunciator{
  border:1px solid var(--hairline); border-radius:5px; padding:9px 10px;
  background:var(--inset); display:flex; flex-direction:column; gap:6px;
  box-shadow:0 0 0 1px rgba(0,0,0,.4) inset;
}
.cpx-annunciator__row{ display:flex; align-items:center; gap:7px; }
.cpx-annunciator__lamp{ width:9px; height:9px; border-radius:2px; flex:0 0 auto; background:#252a30; }
.cpx-annunciator__name{ font-family:var(--font-display); font-weight:600; font-size:var(--fs-meta); letter-spacing:.07em; color:var(--txt); text-transform:uppercase; }
.cpx-annunciator__state{ font-family:var(--font-mono); font-size:var(--fs-chip); letter-spacing:.06em; color:var(--txt-dim); }
.cpx-annunciator__state b{ color:var(--txt); }
/* states */
.cpx-annunciator--nominal .cpx-annunciator__lamp{ background:var(--signal-nominal); box-shadow:0 0 8px var(--signal-nominal); }
.cpx-annunciator--priority .cpx-annunciator__lamp{ background:var(--signal-priority); box-shadow:0 0 8px var(--signal-priority); }
.cpx-annunciator--critical .cpx-annunciator__lamp{ background:var(--signal-critical); box-shadow:0 0 8px var(--signal-critical); }

/* ===========================================================================
   .cpx-readout - segmented monospace value-with-units
   =========================================================================== */
.cpx-readout{
  background:linear-gradient(180deg, var(--charcoal), #0e1114); padding:13px 14px;
  display:flex; flex-direction:column; gap:7px; min-height:90px;
}
.cpx-readout__k{
  font-family:var(--font-mono); font-size:var(--fs-meta); letter-spacing:.16em; text-transform:uppercase; color:var(--txt-dim);
  display:flex; justify-content:space-between; align-items:center;
}
.cpx-readout__k .cpx-u{ color:var(--txt-dim); letter-spacing:.05em; }
.cpx-readout__val{ font-family:var(--font-mono); font-weight:500; font-size:27px; color:var(--txt); line-height:1; }
.cpx-readout__val .cpx-u2{ font-size:var(--fs-control); color:var(--txt-dim); font-weight:400; }
.cpx-readout--lg .cpx-readout__val{ font-size:34px; }
.cpx-readout--priority .cpx-readout__val{ color:var(--signal-priority); }
.cpx-readout--nominal .cpx-readout__val{ color:var(--signal-nominal); }
.cpx-readout--critical .cpx-readout__val{ color:var(--signal-critical); }
.cpx-readout__delta{ font-family:var(--font-mono); font-size:var(--fs-meta); letter-spacing:.03em; color:var(--txt-dim); }
.cpx-readout__delta .cpx-up{ color:var(--signal-nominal); }
.cpx-readout__delta .cpx-dn{ color:var(--signal-critical); }
/* grid wrapper for readout clusters (hairline-separated) */
.cpx-readouts{
  display:grid; grid-template-columns:repeat(2,1fr); gap:1px; background:var(--hairline);
  border:1px solid var(--hairline); border-radius:5px; overflow:hidden;
}
/* contact-card Relationship Vitals: 3 across so 5 cells read 3 + (1 + wide) */
.cpx-readouts--vitals { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 640px) { .cpx-readouts--vitals { grid-template-columns: repeat(2, 1fr); } }
/* reply-rate gauge tape with target marker */
.cpx-gauge{ position:relative; width:100%; height:8px; border-radius:4px; background:var(--inset); border:1px solid var(--hairline); overflow:hidden; }
.cpx-gauge__fill{ position:absolute; left:0; top:0; bottom:0; width:0; background:linear-gradient(90deg, var(--signal-nominal), var(--nominal-2)); box-shadow:0 0 8px var(--signal-nominal); }
.cpx-gauge__ticks{ position:absolute; inset:0; background-image:repeating-linear-gradient(90deg, transparent 0 9px, rgba(11,11,13,.7) 9px 10px); }
.cpx-gauge__target{ position:absolute; top:-3px; bottom:-3px; width:2px; background:var(--signal-priority); box-shadow:0 0 6px var(--signal-priority); }
.cpx-readout__gmini{ font-family:var(--font-mono); font-size:var(--fs-label); color:var(--txt-dim); display:flex; justify-content:space-between; }
.cpx-readout__gmini .cpx-tgt{ color:var(--signal-priority); }

/* ===========================================================================
   .cpx-tape - segmented funnel / gauge bar (the Pipeline Command instrument)
   =========================================================================== */
.cpx-funnel{ display:flex; flex-direction:column; gap:13px; }
.cpx-tape-row{ display:grid; grid-template-columns:130px 1fr 48px; gap:13px; align-items:center; }
.cpx-tape-row__nm{ display:flex; flex-direction:column; gap:2px; }
.cpx-tape-row__nm .cpx-s{ font-family:var(--font-display); font-weight:600; letter-spacing:.1em; text-transform:uppercase; font-size:var(--fs-caption); color:var(--txt); }
.cpx-tape-row__nm .cpx-c{ font-family:var(--font-mono); font-size:var(--fs-chip); color:var(--txt-dim); letter-spacing:.1em; }
.cpx-tape{
  height:24px; border:1px solid var(--hairline); border-radius:3px; background:var(--inset); position:relative; overflow:hidden;
  box-shadow:0 0 0 1px rgba(0,0,0,.4) inset;
}
.cpx-tape__scale{ position:absolute; inset:0; background-image:repeating-linear-gradient(90deg, transparent 0 23px, rgba(255,255,255,.05) 23px 24px); }
.cpx-tape__fill{
  position:absolute; top:0; left:0; bottom:0; border-radius:2px 0 0 2px; width:0;
  background:repeating-linear-gradient(90deg, var(--bar, var(--signal-info)) 0 8px, color-mix(in srgb, var(--bar, var(--signal-info)) 62%, #000) 8px 10px);
  box-shadow:0 0 18px -4px var(--bar, var(--signal-info)) inset;
}
.cpx-tape__pct{ position:absolute; right:8px; top:50%; transform:translateY(-50%); font-family:var(--font-mono); font-size:var(--fs-meta); color:var(--txt-dim); }
.cpx-tape-row__v{ font-family:var(--font-mono); font-weight:500; font-size:18px; text-align:right; color:var(--txt); }
/* segment fills: neutral steel through to nominal at the booked end; amber only at attention stage */
.cpx-tape-row--s1{ --bar:#6b7882; } .cpx-tape-row--s2{ --bar:#8a949b; }
.cpx-tape-row--s3{ --bar:var(--signal-priority); }
.cpx-tape-row--s4{ --bar:var(--signal-nominal); }
.cpx-tape-row--s4 .cpx-tape-row__v{ color:var(--signal-nominal); }
/* pinch - the steepest interior fall-off, flagged for attention (amber = signal) */
.cpx-tape-row--pinch{ --bar:var(--signal-priority); }
.cpx-tape-row--pinch .cpx-tape-row__nm .cpx-s{ color:var(--signal-priority); }
.cpx-tape-row--pinch .cpx-tape-row__v{ color:var(--signal-priority); }
.cpx-funnel__pinch{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  font-family:var(--font-mono); font-size:var(--fs-caption); color:var(--txt-dim);
  margin-top:12px; padding:9px 11px; border:1px solid rgba(245,179,1,.28);
  border-left:2px solid var(--signal-priority); border-radius:3px; background:var(--priority-dim);
}
.cpx-funnel__pinch b{ color:var(--txt); }
.cpx-funnel__pinch .cpx-mono{ color:var(--signal-priority); }
.cpx-funnel__pinch-k{
  font-family:var(--font-display); font-weight:600; letter-spacing:.14em; font-size:var(--fs-chip);
  color:var(--signal-priority); border:1px solid rgba(245,179,1,.4); padding:1px 6px; border-radius:2px;
}
.cpx-funnel__foot{
  display:flex; justify-content:space-between; gap:8px; flex-wrap:wrap; font-family:var(--font-mono); font-size:var(--fs-meta); color:var(--txt-dim);
  margin-top:12px; border-top:1px solid var(--hairline); padding-top:11px;
}
.cpx-funnel__foot b{ color:var(--txt); }
.cpx-funnel__foot b.cpx-ok{ color:var(--signal-nominal); }
.cpx-funnel__foot b.cpx-am{ color:var(--signal-priority); }
/* annunciator lamp cluster wrapper */
.cpx-lampcluster{ display:grid; grid-template-columns:repeat(4,1fr); gap:8px; padding:14px 0 2px; }

/* ===========================================================================
   .htmx-indicator - loading cue toggled by htmx during in-flight requests.
   Hidden by default; htmx adds .htmx-request to the element (and/or an
   ancestor) while a request runs, which flips it to visible. Token-driven:
   colour follows --txt-dim, typography follows --font-mono. Used by the
   Rate Assist chat (READING... / THINKING...) and any future htmx loader.
   =========================================================================== */
.htmx-indicator{ display:none; }
.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator{ display:inline; }

/* ===========================================================================
   .cpx-pill - status pill (the upgraded priority_pill macro)
   =========================================================================== */
.cpx-pill{
  display:inline-flex; align-items:center; gap:5px;
  font-family:var(--font-mono); font-size:var(--fs-chip); letter-spacing:.14em; text-transform:uppercase;
  padding:3px 7px; border-radius:2px; border:1px solid var(--hairline);
  color:var(--txt-dim); background:var(--inset); white-space:nowrap;
}
.cpx-pill--priority{ color:var(--signal-priority); border-color:rgba(245,179,1,.4); background:var(--priority-dim); }
.cpx-pill--nominal{ color:var(--nominal-2); border-color:rgba(63,153,86,.4); background:var(--nominal-dim); }
.cpx-pill--critical{ color:var(--signal-critical); border-color:rgba(194,69,58,.42); background:var(--critical-dim); }
.cpx-pill--info{ color:var(--signal-info); border-color:rgba(91,100,114,.4); background:var(--info-dim); }
/* Neutral chips for low-salience categorical states, so a column reads as consistent
   chips without spending a signal color. Two steps for a cold->warm ramp:
   --ghost (faintest, no fill: e.g. relationship Lead) and --muted (filled grey: Prospect). */
.cpx-pill--ghost{ color:var(--txt-dim); border-color:var(--hairline); background:transparent; opacity:.62; }
.cpx-pill--muted{ color:var(--txt); border-color:var(--hairline); background:var(--inset); }

/* .cpx-note - framed multi-line note block; tone variant tints the frame (mirrors .cpx-pill tones). */
.cpx-note{ font-family:var(--font-mono); font-size:var(--fs-control); line-height:1.5; color:var(--txt-dim); border:1px solid var(--hairline); border-radius:var(--r); padding:10px 12px; }
.cpx-note--priority{ border-color:rgba(245,179,1,.4); background:var(--priority-dim); }

/* ===========================================================================
   .cpx-row - annunciator action-queue row
   =========================================================================== */
.cpx-row{
  display:grid; grid-template-columns:26px 92px 1fr auto; gap:12px; align-items:center;
  padding:11px 13px; border-radius:7px; position:relative; overflow:hidden;
  background:linear-gradient(90deg, var(--charcoal), #0f1114); border:1px solid var(--hairline);
  margin:3px 0;
}
.cpx-row__rank{ font-family:var(--font-mono); font-size:var(--fs-control); color:var(--txt-dim); text-align:center; }
.cpx-row__annun{
  font-family:var(--font-display); font-weight:600; letter-spacing:.07em; font-size:var(--fs-meta);
  text-align:center; padding:5px 4px; border-radius:4px; text-transform:uppercase; border:1px solid transparent; line-height:1.05;
}
.cpx-row__annun--critical{ color:var(--txt); background:var(--signal-critical); box-shadow:0 0 14px -2px var(--signal-critical); }
.cpx-row__annun--priority{ color:var(--ink); background:var(--signal-priority); box-shadow:0 0 14px -2px var(--signal-priority); }
.cpx-row__annun--warn{ color:var(--signal-priority-2); background:var(--priority-dim); border-color:rgba(245,179,1,.32); }
.cpx-row__annun--info{ color:var(--signal-nominal); background:var(--nominal-dim); border-color:rgba(63,153,86,.4); }
.cpx-row__body .cpx-row__name{ font-family:var(--font-display); font-weight:600; font-size:14.5px; color:var(--txt); letter-spacing:.01em; }
.cpx-row__body .cpx-row__name .cpx-role{ color:var(--txt-dim); font-weight:400; font-size:var(--fs-secondary); }
.cpx-row__body .cpx-row__meta{ font-family:var(--font-mono); font-size:var(--fs-meta); color:var(--txt-dim); margin-top:3px; letter-spacing:.01em; }
.cpx-row__chip{ font-family:var(--font-mono); font-size:var(--fs-caption); color:var(--txt-dim); text-align:right; white-space:nowrap; }
.cpx-row__chip b{ display:block; font-size:14px; margin-top:2px; color:var(--txt); }
.cpx-row__chip b.cpx-t-crit{ color:var(--signal-critical); }
.cpx-row__chip b.cpx-t-warn{ color:var(--signal-priority-2); }
.cpx-row__chip b.cpx-t-ok{ color:var(--signal-nominal); }
/* left edge accent */
.cpx-row::before{ content:""; position:absolute; left:0; top:0; bottom:0; width:3px; background:transparent; }
.cpx-row--critical::before{ background:var(--signal-critical); box-shadow:0 0 12px var(--signal-critical); }
.cpx-row--priority::before{ background:var(--signal-priority); box-shadow:0 0 12px var(--signal-priority); }

/* ===========================================================================
   Briefing header
   =========================================================================== */
.cpx-briefing{ display:flex; align-items:flex-end; justify-content:space-between; gap:24px; padding:2px; flex-wrap:wrap; }
.cpx-briefing__h{ font-family:var(--font-display); font-weight:600; font-size:30px; letter-spacing:.01em; color:var(--txt); line-height:1.05; }
.cpx-briefing__h .cpx-sub{ color:var(--txt-dim); font-weight:400; }
.cpx-briefing__line{ margin-top:8px; font-family:var(--font-mono); font-size:var(--fs-secondary); color:var(--txt-dim); letter-spacing:.01em; }
.cpx-briefing__line .cpx-b{ color:var(--txt); font-weight:600; }
.cpx-briefing__line .cpx-am{ color:var(--signal-priority); }
.cpx-briefing__line .cpx-ok{ color:var(--signal-nominal); }
.cpx-briefing__stamp{ text-align:right; font-family:var(--font-mono); font-size:var(--fs-meta); color:var(--txt-dim); letter-spacing:.08em; line-height:1.8; }
.cpx-briefing__stamp b{ color:var(--txt); }
.cpx-briefing__stamp b.cpx-hi{ color:var(--signal-nominal); }

/* ===========================================================================
   .cpx-radar - Opportunity Radar (v3 PREVIEW). Cyan-free: uses --signal-info.
   =========================================================================== */
.cpx-radar__strip{
  font-family:var(--font-mono); font-size:var(--fs-meta); color:var(--txt-dim); padding:10px 14px;
  border-bottom:1px solid var(--hairline); letter-spacing:.06em; display:flex; align-items:center; gap:9px;
}
.cpx-radar__strip .cpx-scan-lamp{ width:8px; height:8px; border-radius:50%; background:var(--signal-nominal); box-shadow:0 0 9px var(--signal-nominal); animation:cpx-scan-pulse 2.4s ease-in-out infinite; }
.cpx-radar__strip b{ color:var(--nominal-2); }
.cpx-radar__list{ display:flex; flex-direction:column; }
.cpx-radar__item{ display:grid; grid-template-columns:34px 1fr auto; gap:13px; align-items:center; padding:14px 14px; border-bottom:1px solid var(--hairline); border-left:2px solid transparent; position:relative; transition:background .15s ease; }
.cpx-radar__item:last-child{ border-bottom:0; }
a.cpx-radar__item:hover{ background:rgba(255,255,255,.025); }
.cpx-radar__ic{ width:30px; height:30px; flex:0 0 auto; position:relative; display:grid; place-items:center; border-radius:50%; }
.cpx-radar__ic svg{ width:26px; height:26px; stroke:var(--signal-info); fill:none; stroke-width:1.5; opacity:.95; }
.cpx-radar__txt{ font-size:var(--fs-body); color:var(--txt-dim); line-height:1.45; }
.cpx-radar__txt .cpx-k{ font-family:var(--font-display); font-weight:600; letter-spacing:.1em; text-transform:uppercase; font-size:var(--fs-meta); color:var(--signal-info); margin-right:8px; padding:1px 6px; border:1px solid currentColor; border-radius:2px; }
.cpx-radar__txt b{ color:var(--txt); font-weight:600; }
.cpx-radar__txt .cpx-when, .cpx-radar__when{ display:block; margin-top:3px; font-family:var(--font-mono); font-size:var(--fs-meta); color:var(--txt-dim); letter-spacing:.06em; }
.cpx-radar__txt .cpx-am{ color:var(--signal-priority); }
.cpx-radar__age{ font-family:var(--font-mono); font-size:var(--fs-meta); color:var(--txt-dim); white-space:nowrap; letter-spacing:.1em; }

/* row differentiation by kind - amber = audition DEADLINE (priority), info = follow-up */
.cpx-radar__item--priority{ border-left-color:var(--signal-priority); }
.cpx-radar__item--priority .cpx-k{ color:var(--signal-priority); }
.cpx-radar__item--priority .cpx-radar__ic{ background:var(--priority-dim); }
.cpx-radar__item--priority .cpx-radar__ic svg{ stroke:var(--signal-priority); opacity:1; }
.cpx-radar__item--info{ border-left-color:var(--signal-info); }
.cpx-radar__item--info .cpx-radar__ic{ background:rgba(174,185,199,.12); }
.cpx-radar__item--info .cpx-radar__ic svg{ stroke:var(--info-2); opacity:1; }
.cpx-radar__age--live{ color:var(--nominal-2); font-weight:500; }
.cpx-radar__age--live::before{ content:"●"; margin-right:5px; font-size:var(--fs-label); vertical-align:middle; }
.cpx-radar__item--future{ opacity:.5; border-left-color:var(--bezel); }
/* overflow affordances - "+N more -> breakout page" when a capped section truncates */
.cpx-radar__more, .cpx-queue__more{
  display:block; text-decoration:none; text-align:center;
  font-family:var(--font-mono); font-size:var(--fs-meta); letter-spacing:.1em; text-transform:uppercase;
  color:var(--txt-dim); padding:10px 14px; border-top:1px solid var(--hairline);
  transition:color .15s, background .15s;
}
.cpx-radar__more:hover, .cpx-queue__more:hover{ color:var(--signal-priority); background:rgba(255,255,255,.025); }

/* ===========================================================================
   .cpx-tip - hover/focus tooltip that defines a term (e.g. audition status).
   CSS-only; aria-label carries the same text for screen readers.
   =========================================================================== */
.cpx-tip{ position:relative; display:inline-block; cursor:help; outline:none; }
.cpx-tip[data-tip]::after{
  content:attr(data-tip);
  position:absolute; left:50%; bottom:calc(100% + 9px); transform:translateX(-50%) translateY(4px);
  width:max-content; max-width:250px; white-space:normal; text-align:left;
  background:var(--gunmetal); color:var(--txt); border:1px solid var(--bezel); border-radius:5px;
  padding:8px 10px; font-family:var(--font-mono); font-size:var(--fs-caption); line-height:1.5; letter-spacing:.01em;
  box-shadow:0 12px 26px -12px #000; z-index:60;
  opacity:0; pointer-events:none; transition:opacity .14s ease, transform .14s ease;
}
.cpx-tip[data-tip]::before{   /* arrow */
  content:""; position:absolute; left:50%; bottom:calc(100% + 4px); transform:translateX(-50%) rotate(45deg);
  width:9px; height:9px; background:var(--gunmetal); border-right:1px solid var(--bezel); border-bottom:1px solid var(--bezel);
  z-index:61; opacity:0; pointer-events:none; transition:opacity .14s ease;
}
.cpx-tip[data-tip]:hover::after, .cpx-tip[data-tip]:focus-visible::after{ opacity:1; transform:translateX(-50%) translateY(0); }
.cpx-tip[data-tip]:hover::before, .cpx-tip[data-tip]:focus-visible::before{ opacity:1; }
@media (prefers-reduced-motion: reduce){ .cpx-tip[data-tip]::after{ transition:opacity .14s ease; } }
@keyframes cpx-scan-pulse{ 0%,100%{ opacity:1; } 50%{ opacity:.4; } }

/* ===========================================================================
   .cpx-advisor - Strategic Advisor (rule-based analyst briefing)
   =========================================================================== */
.cpx-advisor__strip{ font-family:var(--font-mono); font-size:var(--fs-chip); color:var(--txt-dim); padding:9px 14px; border-bottom:1px solid var(--hairline); letter-spacing:.06em; }
.cpx-advisor__strip b{ color:var(--signal-priority); }
.cpx-advisor__row{ display:grid; grid-template-columns:24px 1fr auto; gap:11px; padding:13px 14px; border-bottom:1px solid var(--hairline); align-items:start; }
.cpx-advisor__row:last-child{ border-bottom:0; }
.cpx-advisor__gly{
  width:24px; height:24px; border-radius:50%; display:grid; place-items:center; margin-top:1px; flex:0 0 auto;
  border:1px solid var(--signal-nominal); color:var(--signal-nominal); font-family:var(--font-mono); font-size:var(--fs-meta);
  box-shadow:0 0 10px -4px var(--signal-nominal) inset;
}
.cpx-advisor__row--flag .cpx-advisor__gly{ border-color:rgba(245,179,1,.5); color:var(--signal-priority); box-shadow:0 0 10px -4px var(--signal-priority) inset; }
.cpx-advisor__txt{ font-size:var(--fs-secondary); color:var(--txt-dim); line-height:1.5; }
.cpx-advisor__txt b{ color:var(--txt); font-weight:600; }
.cpx-advisor__txt .cpx-am{ color:var(--signal-priority); font-family:var(--font-mono); }
.cpx-advisor__txt .cpx-ph{ color:var(--signal-nominal); font-family:var(--font-mono); }
.cpx-advisor__foot{ padding:9px 14px; border-top:1px solid var(--hairline); font-family:var(--font-mono); font-size:var(--fs-chip); color:var(--txt-dim); letter-spacing:.06em; display:flex; align-items:center; gap:8px; }
.cpx-advisor__foot .cpx-lamp{ width:6px; height:6px; border-radius:50%; background:var(--signal-nominal); box-shadow:0 0 7px var(--signal-nominal); }

/* ===========================================================================
   .cpx-pipeline - kanban stage board (composes panel/tape/mono tokens)
   Sortable.js drag is preserved via .kanban-col / .kanban-card hooks.
   =========================================================================== */
.cpx-pipeline{ display:flex; gap:12px; overflow-x:auto; padding-bottom:6px; }
.cpx-pipeline__col{ flex:0 0 248px; display:flex; flex-direction:column; min-width:0; }
.cpx-pipeline__head{
  border:1px solid var(--hairline); border-radius:6px 6px 0 0; border-bottom:0;
  background:linear-gradient(180deg, var(--gunmetal), var(--charcoal));
  padding:9px 11px 11px; box-shadow:0 0 0 1px rgba(0,0,0,.4) inset;
}
.cpx-pipeline__head-top{ display:flex; align-items:center; gap:8px; margin-bottom:8px; }
.cpx-pipeline__stage-nm{
  font-family:var(--font-display); font-weight:600; letter-spacing:.1em; text-transform:uppercase;
  font-size:var(--fs-caption); color:var(--txt);
}
.cpx-pipeline__stage-ct{ margin-left:auto; font-size:18px; font-weight:500; color:var(--txt-dim); }
.cpx-pipeline__head--won .cpx-pipeline__stage-ct{ color:var(--signal-nominal); }
/* drop zone - Sortable.js target */
.cpx-pipeline__zone{
  border:1px solid var(--hairline); border-radius:0 0 6px 6px;
  background:var(--inset); padding:8px; min-height:180px;
  display:flex; flex-direction:column; gap:8px; flex:1 1 auto;
}
.cpx-pipeline__empty{
  font-family:var(--font-mono); font-size:var(--fs-meta); letter-spacing:.18em; color:var(--txt-dim);
  text-align:center; padding:18px 0; opacity:.5;
}
/* card tile */
.cpx-pipeline__card{ cursor:grab; }
.cpx-pipeline__card:active{ cursor:grabbing; }
.cpx-pipeline__card--ghost{ opacity:.4; }
.cpx-pipeline__card-body{ padding:10px 11px; display:flex; flex-direction:column; gap:3px; }
.cpx-pipeline__card-name{
  font-family:var(--font-display); font-weight:600; font-size:var(--fs-body); letter-spacing:.01em;
  color:var(--txt); text-decoration:none;
}
.cpx-pipeline__card-name:hover{ color:var(--signal-priority); }   /* amber = active focus */
.cpx-pipeline__card-name:focus-visible{ outline:2px solid var(--signal-priority); outline-offset:2px; }
.cpx-pipeline__card-role{ font-family:var(--font-display); font-size:var(--fs-caption); color:var(--txt-dim); letter-spacing:.01em; }
.cpx-pipeline__card-email{ font-size:var(--fs-meta); color:var(--txt-dim); letter-spacing:.01em; word-break:break-all; }

/* ===========================================================================
   Layout helpers (light - Tailwind still owns most layout)
   =========================================================================== */
.cpx-shell{ position:relative; z-index:2; display:flex; min-height:100vh; }
.cpx-main{ display:flex; flex-direction:column; min-width:0; flex:1 1 auto; }

/* recessed instrument well for the d3 relationship graph (positioning ctx for its floating card) */
.cpx-graph-canvas{
  position:relative; border:1px solid var(--hairline); border-radius:5px; overflow:hidden;
  background:var(--inset); box-shadow:0 0 0 1px rgba(0,0,0,.4) inset;
  background-image:
    linear-gradient(rgba(63,153,86,0.022) 1px, transparent 1px),
    linear-gradient(90deg, rgba(63,153,86,0.022) 1px, transparent 1px);
  background-size:33px 33px;
}
.cpx-canvas{ padding:18px 20px 22px; display:flex; flex-direction:column; gap:15px; }
/* ===========================================================================
   .cpx-ticker - bottom "Intel Feed" marquee (Concept B revival). Amber label
   tab + seamless scrolling mono track (rendered twice -> translateX(-50%)).
   Amber text is reserved for deadlines; green for wins.
   =========================================================================== */
.cpx-ticker{
  display:flex; align-items:stretch; height:34px; margin-top:14px; min-width:0; max-width:100%;
  border:1px solid var(--bezel); border-radius:5px; background:var(--inset); overflow:hidden; position:relative;
}
.cpx-ticker__lbl{
  flex:0 0 auto; display:flex; align-items:center; padding:0 14px; z-index:2;
  font-family:var(--font-display); font-weight:600; letter-spacing:.2em; font-size:var(--fs-meta);
  color:var(--ink); background:var(--signal-priority);
}
.cpx-ticker__win{ flex:1 1 auto; min-width:0; overflow:hidden; position:relative; display:flex; align-items:center;
  -webkit-mask-image:linear-gradient(90deg, transparent 0, #000 36px, #000 calc(100% - 36px), transparent 100%);
          mask-image:linear-gradient(90deg, transparent 0, #000 36px, #000 calc(100% - 36px), transparent 100%); }
.cpx-ticker__track{
  display:flex; white-space:nowrap; align-items:center; will-change:transform;
  animation:cpx-ticker-scroll 48s linear infinite;
  font-family:var(--font-mono); font-size:var(--fs-caption); color:var(--txt-dim); letter-spacing:.04em;
}
.cpx-ticker__track span{ padding:0 16px; }
.cpx-ticker__track span::before{ content:"\203A"; margin-right:16px; color:var(--bezel); }
.cpx-ticker__track .am{ color:var(--signal-priority); }
.cpx-ticker__track .gn{ color:var(--nominal-2); }
.cpx-ticker:hover .cpx-ticker__track{ animation-play-state:paused; }
@keyframes cpx-ticker-scroll{ from{ transform:translateX(0); } to{ transform:translateX(-50%); } }
@media (prefers-reduced-motion: reduce){ .cpx-ticker__track{ animation:none; } }

.cpx-footer-note{ font-family:var(--font-mono); font-size:var(--fs-chip); color:var(--txt-dim); letter-spacing:.1em; text-align:center; padding:10px 0 0; opacity:.7; }

/* secure-terminal login substrate */
.cpx-login{ min-height:100vh; display:grid; place-items:center; padding:24px; position:relative; z-index:2; }
.cpx-login__panel{ width:380px; max-width:100%; }

/* Sign-in form. login.html is standalone and pre-auth: it does NOT render inside
   .cc-root, so it never inherits that shell's border-box reset and must declare
   its own. That is load-bearing, not tidiness: the inputs are width:100% with
   12px side padding and a 1px border, so under content-box they overflow their
   350px column by 26px.

   These rules replace the 19 Tailwind utilities (plus one arbitrary drop-shadow)
   that this page relied on while tailwind.css was still loaded. The values are
   the utilities' exact computed values, measured off the rendered page before
   the swap, because this is a port and not a restyle.

   Two values are knowingly off the design-system scale and left alone: the 4px
   radius (--r is 6px) and the 12px/14px sizes (the scale is 12.5/14.5). Both are
   already inside the near-miss drift clusters the design sweep reported, and
   belong to that global decision rather than being quietly changed here. */
.cpx-login, .cpx-login *, .cpx-login *::before, .cpx-login *::after{ box-sizing:border-box; }
.cpx-login__logo{
  display:block; width:96px; height:96px; margin:0 auto 20px;
  filter:drop-shadow(0 0 16px rgba(245,179,1,.25));
}
.cpx-login__form{ display:flex; flex-direction:column; gap:var(--gap); margin:0; }
.cpx-login__label{
  display:block; margin:0 0 4px; font-size:var(--fs-control); line-height:16px;
  letter-spacing:.1em; text-transform:uppercase; color:var(--txt-dim);
}
.cpx-login__input{
  width:100%; padding:8px 12px; border-radius:4px; font-size:14px; line-height:20px;
  background:var(--inset); border:1px solid var(--steel); color:var(--txt);
}
.cpx-login__input:focus-visible{ outline:2px solid var(--signal-info); outline-offset:1px; }
.cpx-login__submit{
  width:100%; padding:8px 0; border:0; border-radius:4px; cursor:pointer;
  font-family:inherit; font-size:14px; line-height:20px; font-weight:600;
  letter-spacing:.1em; text-transform:uppercase;
  background:var(--signal-priority); color:var(--ink);
}
.cpx-login__error{ width:100%; justify-content:center; margin-bottom:16px; padding-top:8px; padding-bottom:8px; }

/* ===========================================================================
   Power-on boot reveal + self-test sweep
   Default (reduced motion / no JS): everything is fully visible & static.
   =========================================================================== */
#cpx-boot{ display:none; }
#cpx-sweep{ display:none; }

/* ---------------------------------------------------------------------------
   MOTION - all animations gated behind prefers-reduced-motion: no-preference
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference){
  /* breathing online + advisor lamps */
  .cpx-statusbar__online .cpx-lamp{ animation:cpx-breathe 2.4s ease-in-out infinite; }
  .cpx-advisor__foot .cpx-lamp{ animation:cpx-breathe 2.4s ease-in-out infinite; }
  @keyframes cpx-breathe{ 0%,100%{ opacity:1; } 50%{ opacity:.4; } }

  /* command-bar caret blink */
  .cpx-caret{ animation:cpx-blink 1.05s step-end infinite; }
  @keyframes cpx-blink{ 50%{ opacity:0; } }

  /* radar passive-scan lamp pulse */
  .cpx-radar__strip .cpx-scan-lamp{ animation:cpx-scanpulse 2.2s ease-in-out infinite; }
  @keyframes cpx-scanpulse{ 0%,100%{ opacity:.35; } 50%{ opacity:1; } }

  /* radar sweep ring */
  .cpx-radar__ic::after{
    content:""; position:absolute; inset:0; border-radius:50%;
    background:conic-gradient(from 0deg, rgba(91,100,114,.32), transparent 32%);
    animation:cpx-sweep 3.4s linear infinite;
  }
  @keyframes cpx-sweep{ to{ transform:rotate(360deg); } }

  /* segmented tape fill animates to its target width */
  .cpx-tape__fill{ transition:width 1.1s cubic-bezier(.2,.8,.2,1); }
  .cpx-gauge__fill{ transition:width 1s ease; }

  /* amber edge-pulse - top-priority attention row ONLY (signal, not decoration) */
  .cpx-row--priority{ animation:cpx-amber-edge 2.6s ease-in-out infinite; }
  .cpx-annunciator--priority.cpx-annunciator--attn{ animation:cpx-amber-edge 2.6s ease-in-out infinite; }
  @keyframes cpx-amber-edge{
    0%,100%{ box-shadow:inset 0 0 0 1px rgba(245,179,1,0.0); }
    50%{ box-shadow:inset 0 0 26px -10px rgba(245,179,1,0.5); }
  }

  /* one-time-per-session power-on reveal: staggered panel illumination.
     cockpit.js adds .cpx-boot to <body> only when the session flag is unset. */
  .cpx-boot .cpx-boot-stagger{ opacity:0; animation:cpx-panel-on .7s cubic-bezier(.2,.7,.2,1) forwards; }
  @keyframes cpx-panel-on{
    0%{ opacity:0; transform:translateY(8px); filter:brightness(.3) blur(1px); }
    55%{ opacity:1; filter:brightness(1.45); }
    100%{ opacity:1; transform:translateY(0); filter:brightness(1) blur(0); }
  }
  .cpx-boot .cpx-d1{ animation-delay:.04s; } .cpx-boot .cpx-d2{ animation-delay:.14s; }
  .cpx-boot .cpx-d3{ animation-delay:.24s; } .cpx-boot .cpx-d4{ animation-delay:.34s; }
  .cpx-boot .cpx-d5{ animation-delay:.44s; } .cpx-boot .cpx-d6{ animation-delay:.54s; }
  .cpx-boot .cpx-d7{ animation-delay:.64s; } .cpx-boot .cpx-d8{ animation-delay:.74s; }

  /* boot terminal overlay + self-test sweep (only shown during boot, by JS) */
  .cpx-boot #cpx-boot{
    display:flex; position:fixed; inset:0; z-index:9500; background:var(--ink);
    align-items:center; justify-content:center; font-family:var(--font-mono);
  }
  #cpx-boot .cpx-boot__lines{ width:540px; max-width:90vw; }
  #cpx-boot .cpx-boot__hd{ color:var(--signal-priority); letter-spacing:.24em; font-size:var(--fs-caption); margin-bottom:18px; text-transform:uppercase; }
  #cpx-boot .cpx-boot__l{ font-size:var(--fs-control); color:var(--txt-dim); letter-spacing:.04em; margin:6px 0; display:flex; justify-content:space-between; opacity:0; transition:opacity .25s; }
  #cpx-boot .cpx-boot__l .cpx-ok{ color:var(--signal-nominal); }
  #cpx-boot.cpx-done{ opacity:0; pointer-events:none; transition:opacity .5s ease; }
  .cpx-boot #cpx-sweep{
    display:block; position:fixed; inset:0; z-index:9400; pointer-events:none;
    background:linear-gradient(180deg, transparent 0%, rgba(63,153,86,0.10) 48%, rgba(63,153,86,0.18) 50%, rgba(63,153,86,0.10) 52%, transparent 100%);
    transform:translateY(-100%); opacity:0;
  }
  #cpx-sweep.cpx-run{ animation:cpx-scan-sweep 1.1s ease-in forwards; }
  @keyframes cpx-scan-sweep{ from{ transform:translateY(-100%); opacity:1; } to{ transform:translateY(100%); opacity:0; } }
}

/* === Pipeline Phase A: state-forward tile === */
.cpx-tile{
  position:relative; display:flex; gap:9px; align-items:flex-start;
  background:linear-gradient(180deg,var(--charcoal),#0d0e11);
  border:1px solid var(--hairline); border-left:3px solid var(--steel);
  border-radius:6px; padding:9px 11px 9px 10px; margin-bottom:8px; cursor:grab;
}
.cpx-tile:active{ cursor:grabbing; }
.cpx-tile--priority{ border-left-color:var(--signal-priority); }
.cpx-tile--nominal{ border-left-color:var(--signal-nominal); }
.cpx-tile--info{ border-left-color:var(--signal-info); }
.cpx-tile--muted{ border-left-color:var(--steel); opacity:.78; }
.cpx-tile--ghost{ opacity:.35; }
.cpx-tile__mono{
  flex:0 0 26px; height:26px; display:grid; place-items:center;
  background:var(--inset); border:1px solid var(--hairline); border-radius:5px;
  font-family:var(--font-mono); font-size:var(--fs-control); font-weight:600; color:var(--txt-dim);
}
.cpx-tile--priority .cpx-tile__mono{ color:var(--signal-priority); border-color:rgba(245,179,1,.35); }
.cpx-tile--nominal .cpx-tile__mono{ color:var(--signal-nominal); border-color:rgba(63,153,86,.35); }
.cpx-tile__main{ min-width:0; display:flex; flex-direction:column; gap:2px; }
.cpx-tile__name{ font-family:var(--font-display); font-size:14.5px; font-weight:600;
  color:var(--txt); text-decoration:none; letter-spacing:.01em;
  display:inline-block; min-height:24px; padding-block:3px; }
.cpx-tile__name:hover{ color:var(--signal-priority); }
.cpx-tile__name:focus-visible{ outline:2px solid var(--signal-priority); outline-offset:2px; }
.cpx-tile__role{ font-family:var(--font-display); font-size:var(--fs-secondary); color:var(--txt-dim); }
.cpx-tile__state{ font-size:var(--fs-meta); letter-spacing:.05em; margin-top:2px; color:var(--txt-dim); }
.cpx-tile--priority .cpx-tile__state{ color:var(--signal-priority); }
.cpx-tile--nominal .cpx-tile__state{ color:var(--signal-nominal); }
.cpx-tile__name:hover ~ .cpx-tile__state{ color:inherit; }
/* Link tiles (the settings hub cards are <a class="cpx-tile">): pin the anchor's
   color so the UA default link palette (visited purple) can never leak into
   descendants via color:inherit on hover, and give the card a readable hover
   affordance (edge lift, not a text-color swap). */
a.cpx-tile{ color:var(--txt); cursor:pointer; }
a.cpx-tile:hover{ border-color:var(--gold-edge); }
a.cpx-tile:focus-visible{ outline:2px solid var(--signal-priority); outline-offset:2px; }
@keyframes cpx-tile-pulse{ 0%,100%{ box-shadow:0 0 0 0 rgba(245,179,1,0); } 50%{ box-shadow:0 0 0 2px rgba(245,179,1,.18); } }
.cpx-tile--priority{ animation:cpx-tile-pulse 2.4s ease-in-out infinite; }

.cpx-pipeline__need{ font-size:var(--fs-chip); letter-spacing:.16em; text-transform:uppercase;
  color:var(--signal-priority); margin-bottom:8px; }
.cpx-pipeline__need--idle{ color:var(--txt-dim); opacity:.5; }

/* --- keyboard-accessible stage move control (a11y equivalent of the drag) --- */
/* visually-hidden but still in the tab/AT tree.
   .sr-only is the same utility under the name templates already use. It used to
   come from tailwind.css, which the cc_ shell does NOT load, so screen-reader-only
   text was rendering VISIBLY on every cc_ page that used it. Aliased here rather
   than duplicated so the two names can never drift apart. */
.cpx-vh, .sr-only{ position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden;
  clip:rect(0,0,0,0); white-space:nowrap; border:0; }
/* subtle by default; reveals on hover or keyboard focus so it stays out of the way */
.cpx-tile__move{ position:absolute; top:7px; right:7px; max-width:88px; min-height:24px;
  background:var(--inset); color:var(--txt-dim); border:1px solid var(--hairline);
  border-radius:4px; font-family:var(--font-mono); font-size:var(--fs-meta); padding:2px 4px;
  opacity:0; transition:opacity .15s ease; cursor:pointer; }
.cpx-tile:hover .cpx-tile__move{ opacity:.85; }
.cpx-tile__move:focus{ opacity:1; }
.cpx-tile__move:focus-visible{ outline:2px solid var(--signal-priority); outline-offset:1px; }

/* ── Timeline filter chips ───────────────────────────────────────────────
   Selection state for the company timeline's All/Communications/Work filter.
   Selection is informational, NOT a needs-you signal, so it uses --signal-info,
   never amber. Inactive chips are plain .cpx-pill--info. */
/* The selected state is `.is-on`, set by the company dossier's own script, and it
   is styled per category in contact-detail-extra.css. An `.is-active` rule lived
   here matching nothing, because no element ever carried both classes. (#1658) */
.cpx-tl-filter { cursor: pointer; }

/* ── Rate review queue: per-row inline figure editor (#1359) ──────────────
   The Edit control is a JS-free <details> disclosure. Its sibling .rq-edit-form
   expands IN FLOW below the row's action buttons (pushing later rows down),
   revealed via :has() on the open disclosure. It never overlays the next row and
   never widens the review column: the fields wrap within the column that the
   Edit/Approve/Reject row already establishes. Info-toned frame, never amber. */
.rq-review { display: flex; flex-direction: column; gap: 6px; align-items: flex-end; }
.rq-actions { display: flex; gap: 6px; justify-content: flex-end; align-items: center; }
.rq-editdisc { display: inline; }
.rq-editdisc > summary {
  cursor: pointer; list-style: none; padding: 5px 10px;
  border: 1px solid var(--hairline); border-radius: 4px; color: var(--txt-dim);
  font-size:var(--fs-meta); letter-spacing: .1em; text-transform: uppercase;
}
.rq-editdisc > summary::-webkit-details-marker { display: none; }
.rq-edit-form { display: none; }
.rq-review:has(.rq-editdisc[open]) .rq-edit-form {
  display: flex; flex-direction: column; gap: 6px; align-items: stretch;
  text-align: left; padding: 8px; background: var(--inset);
  border: 1px solid var(--signal-info); border-radius: 6px;
}
.rq-edit-label { font-size:var(--fs-chip); letter-spacing: .14em; text-transform: uppercase; color: var(--txt-dim); }
.rq-edit-fields { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }

/* ── Readability override: lift stray Tailwind grays to the bright text tokens ──
   Some pages (bookings, auditions, agents, etc.) set text color with raw Tailwind
   utilities instead of our tokens, so the global token bump misses them. Remap them
   here so NO body text stays dim, on any page. !important because these override a
   third-party utility framework on purpose. Light grays -> white, mediums -> dim. */
.text-gray-100, .text-gray-200, .text-gray-300, .text-white\/90 { color: var(--txt) !important; }
.text-gray-400, .text-gray-500, .text-gray-600 { color: var(--txt-dim) !important; }

/* ===========================================================================
   Command-center BACKDROP layers - the luminous cyber-city map (ported from the
   mockup's .bg-city / .bg-field / .bg-vignette). Fixed full-viewport, behind the
   panels (z0/z1), mix-blend-mode:screen so they GLOW, pointer-events:none, masked
   so they bleed strongest at the corners/left rail and stay faint behind content.
   Teal here is the FIELD only, never a data color.

   These DIVs are wired into base.html in a later task; the CSS is defined now so
   the markup lands against a ready theme. They sit behind .cpx-shell (z2).
   =========================================================================== */
.cpx-body__city{
  position:fixed; inset:0; z-index:0; pointer-events:none;
  background:url(/static/cyber-city-bg.jpg) left bottom / auto 122% no-repeat;
  mix-blend-mode:screen; opacity:0.92;
  -webkit-mask-image:radial-gradient(150% 155% at 22% 70%, #000 22%, rgba(0,0,0,0.5) 64%, rgba(0,0,0,0.16) 100%);
          mask-image:radial-gradient(150% 155% at 22% 70%, #000 22%, rgba(0,0,0,0.5) 64%, rgba(0,0,0,0.16) 100%);
}
/* a second teal contour / measurement field, brightest at the edges */
.cpx-body__field{
  position:fixed; inset:0; z-index:0; pointer-events:none;
  mix-blend-mode:screen; opacity:.9;
  background-image:
    linear-gradient(rgba(111,176,200,0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(111,176,200,0.05) 1px, transparent 1px),
    repeating-linear-gradient(0deg, rgba(111,176,200,0.05) 0 1px, transparent 1px 110px),
    repeating-linear-gradient(26deg, rgba(111,176,200,0.045) 0 1px, transparent 1px 240px);
  background-size:34px 34px, 34px 34px, 100% 100%, 100% 100%;
  -webkit-mask-image:radial-gradient(132% 122% at 50% 40%, rgba(0,0,0,0.55) 28%, #000 100%);
          mask-image:radial-gradient(132% 122% at 50% 40%, rgba(0,0,0,0.55) 28%, #000 100%);
}
/* atmospheric corner vignette + a faint scanline overlay (above the map, below panels) */
.cpx-body__vignette{
  position:fixed; inset:0; z-index:1; pointer-events:none;
  background:
    radial-gradient(138% 108% at 50% 44%, transparent 58%, rgba(0,0,0,0.46) 100%),
    repeating-linear-gradient(0deg, rgba(255,255,255,0.022) 0 1px, transparent 1px 2px);
}

/* ===========================================================================
   GLOW utilities - structural gold bloom (static chrome) and the gauge backplate.
   .cpx-bloom puts the wide soft gold bloom on a hero instrument (radar/donut/
   gauge). .cpx-backplate is the recessed tinted well behind a gauge/score tape.
   The LOUD animated --glow-amber-signal is reserved for needs-you signals only
   (it rides on .cpx-row--priority and the like), so it is intentionally NOT a
   utility class you sprinkle on decoration.
   =========================================================================== */
.cpx-bloom{ filter:var(--glow-bloom); }
.cpx-backplate{
  background:var(--gauge-backplate); border:1px solid var(--hairline);
  border-radius:3px; overflow:hidden;
}

/* ===========================================================================
   DASHBOARD COMMAND-CENTER GRID + INSTRUMENTS  (ported from the v10 mockup,
   docs/design/cockpit-concepts/e-command-center-mockup.html, into .cpx-* names).
   The dashboard renders as one dense single-screen grid of glass .cpx-panel
   instruments. All colour is tokenised; the gold data ramp is ambient structure,
   amber stays the needs-you signal. Motion is gated behind prefers-reduced-motion
   at the foot of this block.
   =========================================================================== */

/* ---- single-screen grid: fills the canvas height below the status/command bars,
   three dense bands. On narrow viewports it relaxes to a flowing column. ---- */
.cpx-dash{
  display:grid;
  grid-template-columns:repeat(12, 1fr);
  grid-template-rows:minmax(200px,1fr) minmax(220px,1fr) minmax(220px,1.1fr);
  gap:var(--gap);
  min-height:0;
}
.cpx-dash--fit{ height:calc(100vh - 132px); }
.cpx-dash__area{ min-width:0; min-height:0; }
/* band 1 */
.cpx-area-priorities{ grid-column:1 / 4;  grid-row:1; }
.cpx-area-radar{      grid-column:4 / 7;  grid-row:1; }
.cpx-area-pipeline{   grid-column:7 / 10; grid-row:1; }
.cpx-area-schedule{   grid-column:10 / 13;grid-row:1; }
/* band 2 */
.cpx-area-revenue{    grid-column:1 / 5;  grid-row:2; }
.cpx-area-auditions{  grid-column:5 / 8;  grid-row:2; }
.cpx-area-outreach{   grid-column:8 / 10; grid-row:2; }
.cpx-area-advisor{    grid-column:10 / 13;grid-row:2; }
/* band 3 */
.cpx-area-gauge{      grid-column:1 / 3;  grid-row:3; }
.cpx-area-leads{      grid-column:3 / 7;  grid-row:3; }
.cpx-area-activity{   grid-column:7 / 9;  grid-row:3; }
.cpx-area-reconnect{  grid-column:9 / 11; grid-row:3; }
.cpx-area-ops{        grid-column:11 / 13;grid-row:3; }

@media (max-width:1100px){
  .cpx-dash{ grid-template-columns:repeat(2, 1fr); grid-auto-rows:minmax(220px,auto); grid-template-rows:none; }
  .cpx-dash--fit{ height:auto; }
  .cpx-dash__area{ grid-column:auto !important; grid-row:auto !important; }
}
@media (max-width:640px){
  .cpx-dash{ grid-template-columns:1fr; }
}

/* dashboard panels stretch to fill their grid cell and scroll internally so the
   page itself does not scroll on a normal viewport */
.cpx-dash .cpx-panel{ height:100%; display:flex; flex-direction:column; overflow:hidden; }
.cpx-dash .cpx-panel__hd{ flex:0 0 auto; }
.cpx-dash .cpx-panel__body{ flex:1 1 auto; min-height:0; overflow:auto; scrollbar-width:none; }
.cpx-panel__foot{ display:flex; align-items:center; justify-content:space-between; gap:10px; padding:7px 14px 9px 16px; }
.cpx-dash .cpx-panel__foot{ flex:0 0 auto; }

/* Today's Priorities: the queue holds the top 8 of N, but band 1 is short and the
   global rule hides the scrollbar, so only ~1 row showed. Compact the rows so several
   are visible by default (matching the reference's filled list) and reveal a thin
   scrollbar for THIS panel so the rest of the queue is discoverable (the foot also
   links out with the total). */
.cpx-area-priorities .cpx-row{ grid-template-columns:20px 72px 1fr auto; gap:8px; padding:5px 9px; margin:2px 0; }
.cpx-area-priorities .cpx-row__annun{ font-size:var(--fs-chip); padding:3px 3px; letter-spacing:.04em; }
.cpx-area-priorities .cpx-row__body{ min-width:0; overflow:hidden; }
.cpx-area-priorities .cpx-row__body .cpx-row__name{ font-size:var(--fs-secondary); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.cpx-area-priorities .cpx-row__body .cpx-row__meta{ margin-top:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.cpx-area-priorities .cpx-row__chip{ font-size:var(--fs-chip); }
.cpx-area-priorities .cpx-row__chip b{ font-size:var(--fs-caption); }
.cpx-area-priorities .cpx-panel__body{ scrollbar-width:thin; scrollbar-color:var(--steel) transparent; }

/* slim greeting command bar (greeting + flanking readouts + clock) */
.cpx-dashbar{
  display:flex; align-items:center; gap:14px; min-height:42px; padding:6px 4px 12px;
}
.cpx-dashbar__chip{ display:flex; align-items:center; gap:6px; font-family:var(--font-mono); white-space:nowrap; }
.cpx-dashbar__chip .cpx-k{ font-size:var(--fs-label); letter-spacing:.14em; color:var(--txt-dim); text-transform:uppercase; }
.cpx-dashbar__chip .cpx-v{ font-size:var(--fs-body); color:var(--txt); }
.cpx-dashbar__chip .cpx-v.am{ color:var(--signal-priority-2); text-shadow:0 0 9px rgba(255,207,77,0.4); }
.cpx-dashbar__chip .cpx-v.dr{ color:var(--signal-dream-2); }
.cpx-dashbar__chip .cpx-br{ color:var(--gold-edge); font-size:var(--fs-control); }
.cpx-dashbar__div{ width:1px; height:18px; background:var(--hairline); }
.cpx-dashbar__greet{ flex:1 1 auto; text-align:center; min-width:120px; }
.cpx-dashbar__greet h1{ font-family:var(--font-display); font-weight:500; font-size:15px; letter-spacing:.02em; color:var(--txt); text-shadow:0 0 12px rgba(245,200,66,.14); }
.cpx-dashbar__greet h1 .cpx-nm{ font-weight:600; }
.cpx-dashbar__greet p{ font-family:var(--font-display); font-size:var(--fs-caption); color:var(--txt-dim); }
.cpx-dashbar__greet p b{ color:var(--signal-priority-2); font-family:var(--font-mono); }

/* inert drag-grip glyph in panel headers (Phase 2 wires it) */
.cpx-grip{
  flex:0 0 auto; width:9px; height:14px; display:grid; grid-template-columns:repeat(2,3px);
  grid-template-rows:repeat(3,3px); gap:2px; opacity:.4; cursor:grab; margin-right:2px;
}
.cpx-grip i{ width:3px; height:3px; border-radius:50%; background:var(--gold-2); }
.cpx-panel__hd:hover .cpx-grip{ opacity:.8; }
.cpx-grip:focus-visible{ outline:2px solid var(--signal-priority); outline-offset:2px; }

/* ---------------------------------------------------------------------------
   INSTRUMENT: pipeline funnel (.cpx-inst-funnel)
   --------------------------------------------------------------------------- */
.cpx-inst-funnel{ flex:1 1 auto; min-height:0; display:flex; }
.cpx-inst-funnel svg{ width:100%; height:100%; display:block; filter:drop-shadow(0 6px 12px rgba(0,0,0,0.4)); }
.cpx-inst-funnel__band polygon{ stroke:rgba(0,0,0,0.45); stroke-width:0.4; }
.cpx-inst-funnel__band--steel polygon{ fill:var(--ramp-5); }
.cpx-inst-funnel__band--bronze polygon{ fill:var(--ramp-3); }
.cpx-inst-funnel__band--gold polygon{ fill:var(--ramp-1); }
.cpx-inst-funnel__band.is-won polygon{ stroke:var(--gold-edge); stroke-width:0.6; }
.cpx-inst-funnel__lbl{ font-family:var(--font-display); font-weight:800; font-size:4.6px; letter-spacing:.06em; fill:var(--on-gold); }
.cpx-inst-funnel__band--steel .cpx-inst-funnel__lbl{ fill:#e6edf4; }
.cpx-inst-funnel__ct{ font-family:var(--font-mono); font-weight:700; font-size:6px; fill:#ffe8a0; }
.cpx-inst-funnel__pinch{ flex:0 0 auto; font-size:var(--fs-chip); letter-spacing:.03em; color:var(--txt-dim); text-align:center; padding-top:4px; }
.cpx-inst-empty{ color:var(--txt-dim); padding:8px 2px; }

/* ---------------------------------------------------------------------------
   INSTRUMENT: opportunity radar (.cpx-inst-radar)
   --------------------------------------------------------------------------- */
.cpx-inst-radar{ display:flex; flex-direction:column; align-items:center; height:100%; }
.cpx-inst-radar__stage{ position:relative; flex:1 1 auto; min-height:0; width:100%; display:grid; place-items:center; }
.cpx-inst-radar__stage::before{
  content:""; position:absolute; width:90%; aspect-ratio:1; border-radius:50%;
  background:radial-gradient(circle, rgba(245,200,66,.12) 0%, rgba(245,200,66,.06) 46%, transparent 70%);
  mix-blend-mode:screen; filter:blur(6px); pointer-events:none;
}
.cpx-inst-radar__scope{ height:100%; max-height:100%; width:auto; aspect-ratio:1; display:block; position:relative;
  filter:drop-shadow(0 0 5px rgba(245,200,66,.30)) drop-shadow(0 0 14px rgba(245,200,66,.15)); }
.cpx-inst-radar__ring{ fill:none; stroke:var(--gold-edge-soft); stroke-width:1; opacity:.55; }
.cpx-inst-radar__ring--out{ stroke:var(--gold-edge); opacity:.85; stroke-width:1.3; }
.cpx-inst-radar__ring--mid{ stroke:rgba(245,200,66,0.38); }
.cpx-inst-radar__cross{ stroke:rgba(245,200,66,0.30); stroke-width:.8; }
.cpx-inst-radar__tick{ stroke:var(--gold-2); stroke-width:1; opacity:.6; }
.cpx-inst-radar__sector{ font-family:var(--font-mono); font-size:7px; letter-spacing:.1em; fill:var(--txt-dim); }
.cpx-inst-radar__sweep{ transform-origin:85px 85px; }
.cpx-inst-radar__sweep-line{ stroke:rgba(245,200,66,0.5); stroke-width:1.4; stroke-linecap:round; filter:drop-shadow(0 0 5px rgba(245,200,66,.6)); }
.cpx-inst-radar__center{ fill:var(--gold-2); filter:drop-shadow(0 0 7px var(--gold-2)); }
.cpx-inst-radar__blip.is-priority circle{ fill:url(#cpxBlipPriority); filter:drop-shadow(0 0 8px var(--signal-priority-2)); }
.cpx-inst-radar__blip.is-info circle{ fill:url(#cpxBlipInfo); filter:drop-shadow(0 0 5px rgba(245,200,66,.6)); }
.cpx-inst-radar__blip.is-dream circle{ fill:url(#cpxBlipDream); filter:drop-shadow(0 0 10px var(--signal-dream)); }

/* ---------------------------------------------------------------------------
   INSTRUMENT: audition donut (.cpx-inst-donut)
   --------------------------------------------------------------------------- */
.cpx-inst-donut{ display:flex; align-items:center; justify-content:center; gap:18px; height:100%; flex-wrap:wrap; }
.cpx-inst-donut__box{ position:relative; width:118px; height:118px; flex:0 0 auto; filter:var(--glow-bloom); }
.cpx-inst-donut__ring{ width:118px; height:118px; transform:rotate(-90deg); }
.cpx-inst-donut__hole{ fill:none; stroke:var(--inset); stroke-width:4; }
.cpx-inst-donut__seg{ fill:none; stroke:currentColor; stroke-width:4; }
.cpx-inst-donut__seg.is-r1{ color:var(--ramp-1); filter:drop-shadow(0 0 6px rgba(245,200,66,.55)); }
.cpx-inst-donut__seg.is-r2{ color:var(--ramp-3); }
.cpx-inst-donut__seg.is-r3{ color:var(--ramp-4); }
.cpx-inst-donut__seg.is-steel{ color:var(--ramp-5); }
.cpx-inst-donut__center{ position:absolute; inset:0; display:grid; place-items:center; align-content:center; text-align:center; filter:none; }
.cpx-inst-donut__n{ font-family:var(--font-display); font-weight:500; letter-spacing:-.01em; font-size:34px; color:var(--txt); line-height:1; text-shadow:var(--num-bloom); }
.cpx-inst-donut__l{ font-family:var(--font-display); font-weight:500; font-size:7px; letter-spacing:.2em; color:var(--txt-dim); text-transform:uppercase; margin-top:2px; }
.cpx-inst-donut__legend{ list-style:none; display:flex; flex-direction:column; gap:6px; flex:0 0 auto; margin:0; padding:0; }
.cpx-inst-donut__legend li{ display:flex; align-items:center; gap:8px; font-family:var(--font-mono); font-size:var(--fs-meta); color:var(--txt-dim); }
.cpx-inst-donut__sw{ width:7px; height:7px; border-radius:50%; flex:0 0 auto; }
.cpx-inst-donut__sw.is-r1{ background:var(--ramp-1); } .cpx-inst-donut__sw.is-r2{ background:var(--ramp-3); }
.cpx-inst-donut__sw.is-r3{ background:var(--ramp-4); } .cpx-inst-donut__sw.is-steel{ background:var(--ramp-5); }
/* semantic outcome tones (booked=green, in-flight=amber, passed=info, other=muted) */
.cpx-inst-donut__seg.is-nominal{ color:var(--signal-nominal); filter:drop-shadow(0 0 6px rgba(63,153,86,.5)); }
.cpx-inst-donut__seg.is-priority{ color:var(--signal-priority); filter:drop-shadow(0 0 6px rgba(245,179,1,.5)); }
.cpx-inst-donut__seg.is-info{ color:var(--steel-info); }
.cpx-inst-donut__seg.is-muted{ color:var(--steel); }
.cpx-inst-donut__sw.is-nominal{ background:var(--signal-nominal); }
.cpx-inst-donut__sw.is-priority{ background:var(--signal-priority); }
.cpx-inst-donut__sw.is-info{ background:var(--steel-info); }
.cpx-inst-donut__sw.is-muted{ background:var(--steel); }
.cpx-inst-donut__legend b{ margin-left:auto; color:var(--txt); font-weight:500; }

/* ---------------------------------------------------------------------------
   INSTRUMENT: circular arc gauge (.cpx-inst-gauge)
   --------------------------------------------------------------------------- */
.cpx-inst-gauge{ display:flex; flex-direction:column; align-items:center; justify-content:center; height:100%; gap:6px; }
.cpx-inst-gauge__svg{ position:relative; width:118px; height:118px; flex:0 0 auto; }
.cpx-inst-gauge__svg::before{
  content:""; position:absolute; inset:-12%; border-radius:50%;
  background:radial-gradient(circle, rgba(245,200,66,.13), transparent 65%);
  mix-blend-mode:screen; filter:blur(4px); pointer-events:none;
}
.cpx-inst-gauge__svg svg{ width:100%; height:100%; display:block; filter:var(--glow-bloom); position:relative; }
.cpx-inst-gauge__track{ fill:none; stroke:var(--inset); stroke-width:6; }
.cpx-inst-gauge__arc{ fill:none; stroke-width:6; stroke-linecap:round; }
.cpx-inst-gauge__arc--amber{ stroke:var(--gold-2); }
.cpx-inst-gauge__arc--bronze{ stroke:var(--ramp-3); }
.cpx-inst-gauge__target{ fill:none; stroke:var(--signal-priority); stroke-width:7; }
.cpx-inst-gauge__center{ position:absolute; inset:0; display:grid; place-items:center; align-content:center; text-align:center; }
.cpx-inst-gauge__n{ font-family:var(--font-display); font-weight:500; letter-spacing:-.01em; font-size:26px; color:var(--txt); line-height:1; text-shadow:var(--num-bloom); }
.cpx-inst-gauge__n small{ font-size:15px; color:var(--gold-2); }
.cpx-inst-gauge__lbl{ font-family:var(--font-display); font-weight:500; font-size:7px; letter-spacing:.18em; color:var(--txt-dim); text-transform:uppercase; margin-top:2px; }
.cpx-inst-gauge__cap{ font-family:var(--font-mono); font-size:var(--fs-label); letter-spacing:.02em; color:var(--txt-dim); text-align:center; }
/* empty / no-data gauge (e.g. 0 sent): dim the value and drop the bloom + halo so an empty
   dial reads as "no data yet" rather than a confident reading. The arc itself is omitted in
   the partial when pct is 0, so there is no stray round-cap dot either. */
.cpx-inst-gauge.is-empty .cpx-inst-gauge__n{ color:var(--txt-dim); text-shadow:none; }
.cpx-inst-gauge.is-empty .cpx-inst-gauge__svg{ filter:none; }
.cpx-inst-gauge.is-empty .cpx-inst-gauge__svg::before{ display:none; }

/* ---------------------------------------------------------------------------
   INSTRUMENT: revenue two-month compare (.cpx-inst-rev)
   --------------------------------------------------------------------------- */
.cpx-inst-rev{ display:flex; flex-direction:column; gap:6px; }
.cpx-inst-rev svg{ width:100%; height:auto; max-height:168px; display:block; }
.cpx-inst-rev__axis{ stroke:var(--hairline); stroke-width:1; }
.cpx-inst-rev__bar{ rx:1.5; }
.cpx-inst-rev__bar--steel{ fill:var(--ramp-5); opacity:.7; }
.cpx-inst-rev__bar--gold{ fill:var(--gold-2); filter:drop-shadow(0 0 6px rgba(245,200,66,0.5)); }
.cpx-inst-rev__xlbl{ font-family:var(--font-mono); font-size:6px; letter-spacing:.06em; fill:var(--txt-dim); }
.cpx-inst-rev__xlbl.is-now{ fill:var(--signal-priority-2); }
.cpx-inst-rev__vlbl{ font-family:var(--font-mono); font-size:6.8px; font-weight:700; fill:var(--gold-2); }
.cpx-inst-rev__meta{ display:flex; justify-content:space-between; gap:8px; font-size:var(--fs-chip); color:var(--txt-dim); padding-top:5px; border-top:1px solid var(--hairline); }
.cpx-inst-rev__meta b{ color:var(--txt); }
.cpx-inst-rev__preview{ font-size:7px; letter-spacing:.12em; text-transform:uppercase; color:var(--gold-2); border:1px solid var(--gold-edge); background:var(--gold-ambient); padding:1px 5px; border-radius:2px; }
.cpx-inst-rev__note{ font-size:var(--fs-label); letter-spacing:.02em; color:var(--txt-dim); }
.cpx-inst-rev__fig{ margin:0; }
.cpx-inst-rev__empty-t{ font-family:var(--font-mono); font-size:var(--fs-label); fill:var(--txt-dim); letter-spacing:.04em; }
/* revenue D/W/M/Y period toggle */
.cpx-rev-seg{ display:flex; gap:3px; justify-content:flex-end; }
.cpx-rev-seg__btn{ font-family:var(--font-mono); font-size:var(--fs-chip); letter-spacing:.04em; color:var(--txt-dim); background:rgba(10,16,24,0.5); border:1px solid var(--hairline); border-radius:3px; padding:2px 7px; cursor:pointer; transition:color .12s, background .12s, border-color .12s; }
.cpx-rev-seg__btn:hover{ color:var(--txt); border-color:var(--steel); }
.cpx-rev-seg__btn.is-on{ color:var(--ink); background:var(--gold-2); border-color:var(--gold-2); font-weight:700; }
.cpx-rev-seg__btn:focus-visible{ outline:2px solid var(--signal-priority); outline-offset:1px; }

/* dashboard simple list/feed/table instruments (rethemed existing panels) */
.cpx-feed{ display:flex; flex-direction:column; }
.cpx-feed__item{ display:grid; grid-template-columns:1fr auto; gap:9px; align-items:center; padding:5px 1px; border-bottom:1px solid var(--hairline); }
.cpx-feed__item:last-child{ border-bottom:0; }
.cpx-feed__txt{ font-size:var(--fs-control); color:var(--txt-dim); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.cpx-feed__txt b{ color:var(--txt); font-weight:600; }
.cpx-feed__when{ font-family:var(--font-mono); font-size:var(--fs-chip); color:var(--txt-dim); white-space:nowrap; }
.cpx-feed--wrap .cpx-feed__item{ grid-template-columns:1fr; }
.cpx-feed--wrap .cpx-feed__txt{ white-space:normal; overflow:visible; font-size:var(--fs-caption); line-height:1.35; }
.cpx-feed__txt.cpx-am{ color:var(--signal-priority); font-family:var(--font-mono); }
.cpx-feed__txt.cpx-ph{ color:var(--signal-nominal); font-family:var(--font-mono); }

/* dashboard health-dot variants + the panel-foot link button */
.cpx-panel__hd .cpx-dot--ok{ background:var(--signal-nominal); box-shadow:0 0 6px var(--signal-nominal); }
.cpx-linkbtn{ font-family:var(--font-mono); font-size:var(--fs-label); letter-spacing:.12em; text-transform:uppercase; color:var(--txt-dim); text-decoration:none; border:1px solid var(--hairline); border-radius:5px; padding:4px 9px; background:rgba(10,16,24,0.5); white-space:nowrap; }
.cpx-linkbtn:hover{ color:var(--txt); border-color:var(--gold-edge); }
.cpx-linkbtn:focus-visible{ outline:2px solid var(--signal-priority); outline-offset:1px; }
.cpx-dashbar__clock{ flex:0 0 auto; }

.cpx-reconnect{ display:flex; flex-direction:column; gap:6px; }
.cpx-reconnect__row{ display:grid; grid-template-columns:30px 1fr auto; gap:9px; align-items:center; padding:5px 9px; border:1px solid var(--hairline); border-radius:4px; background:rgba(10,16,24,0.5); }
.cpx-reconnect__avatar{ width:30px; height:30px; border-radius:50%; display:grid; place-items:center; font-family:var(--font-display); font-weight:600; font-size:var(--fs-caption); color:var(--gold-2); border:1px solid var(--gold-edge); background:radial-gradient(circle at 50% 30%, rgba(245,200,66,.14), rgba(10,16,24,0.6)); }
.cpx-reconnect__nm{ font-family:var(--font-display); font-weight:600; font-size:var(--fs-control); color:var(--txt); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.cpx-reconnect__meta{ font-family:var(--font-mono); font-size:var(--fs-chip); color:var(--txt-dim); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.cpx-reconnect__meta .stale{ color:var(--signal-priority-2); }
.cpx-reconnect__meta .crit{ color:var(--signal-critical); }
.cpx-reconnect__btn{ font-family:var(--font-mono); font-size:var(--fs-label); letter-spacing:.1em; text-transform:uppercase; color:var(--gold-2); border:1px solid var(--gold-edge); border-radius:5px; padding:5px 9px; background:var(--gold-ambient); text-decoration:none; white-space:nowrap; }
.cpx-reconnect__btn:hover{ background:var(--priority-dim); color:var(--signal-priority-2); }
.cpx-reconnect__btn:focus-visible{ outline:2px solid var(--signal-priority); outline-offset:1px; }

/* quick-actions icon-tile cluster */
.cpx-qa{ display:grid; grid-template-columns:repeat(2,1fr); gap:6px; }
.cpx-qa__tile{ display:flex; align-items:center; gap:8px; padding:8px 10px; border:1px solid var(--hairline); border-radius:5px; background:rgba(14,22,32,0.5); color:var(--txt-dim); text-decoration:none; font-size:var(--fs-caption); }
.cpx-qa__tile:hover{ border-color:var(--gold-edge); color:var(--txt); }
.cpx-qa__tile:focus-visible{ outline:2px solid var(--signal-priority); outline-offset:1px; }

/* labelled v3 PREVIEW advisor / ask stub */
.cpx-ask{ display:flex; align-items:center; gap:8px; padding:6px 10px; margin-bottom:8px; border:1px dashed var(--gold-edge); border-radius:5px; background:linear-gradient(180deg, rgba(245,200,66,.045), rgba(10,16,24,0.5)); opacity:.65; cursor:not-allowed; }
.cpx-ask__txt{ flex:1 1 auto; font-size:var(--fs-caption); color:var(--txt-dim); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.cpx-ask__tag{ font-family:var(--font-mono); font-size:7px; letter-spacing:.14em; text-transform:uppercase; color:var(--gold-2); border:1px solid var(--gold-edge); background:var(--gold-ambient); padding:1px 5px; border-radius:2px; }

/* motion (gated): radar sweep rotation + priority blip pulse. Gold structure does
   not animate; only the radar sweep (atmosphere) and the amber-toned blips do. */
@media (prefers-reduced-motion: no-preference){
  .cpx-inst-radar__sweep{ animation:cpx-radar-sweep 4.6s linear infinite; }
  @keyframes cpx-radar-sweep{ to{ transform:rotate(360deg); } }
  .cpx-inst-radar__blip.is-priority circle{ animation:cpx-blip-pulse 2.4s ease-in-out infinite; }
  @keyframes cpx-blip-pulse{ 0%,100%{ r:3.2; } 50%{ r:4; } }
}

/* .cpx-toast - dismissible error toast surfaced by cc-htmx-errors.js when an htmx
   request fails (5xx / network), so a failed swap is no longer silent. Lives here
   in the command-center stylesheet because cc-htmx-errors.js loads only in the cc_
   shell (cc_base.html), which loads cockpit-cc.css (not cockpit.css). Tokens used
   are all defined in this file's :root (--gap, --r, --gunmetal, --txt, --txt-dim,
   --signal-critical, --font-display); the 13px size is the body type tier. */
.cpx-toast{ position:fixed; right:var(--gap); bottom:var(--gap); z-index:1000; max-width:360px; padding:var(--gap); display:flex; gap:var(--gap); align-items:flex-start; border-radius:var(--r); background:var(--gunmetal); color:var(--txt); border:1px solid var(--signal-critical); box-shadow:0 8px 28px rgba(0,0,0,.45); font-family:var(--font-display); font-size:var(--fs-body); }
.cpx-toast--error{ border-color:var(--signal-critical); }
.cpx-toast--ok{ border-color:var(--signal-nominal); }
.cpx-toast__x{ margin-left:auto; background:none; border:0; color:var(--txt-dim); cursor:pointer; font-family:var(--font-display); font-size:var(--fs-body); }

/* .cc-navprogress - slim top progress bar shown during a boosted htmx nav
   (see cc-nav-progress.js). Fixed at the very top of the viewport so it is
   visible above the cc-top bar; an indeterminate sweep, no fixed duration
   because request time is unknown. Driven by .cc-navigating on <html>,
   which survives whole-body swaps. */
.cc-navprogress{ position:fixed; top:0; left:0; width:100%; height:2px; z-index:2000;
  background:var(--gold-edge-soft); overflow:hidden; opacity:0; pointer-events:none;
  transition:opacity .15s ease; }
.cc-navprogress::before{ content:""; position:absolute; top:0; left:0; height:100%; width:40%;
  background:var(--gold-gradient); animation:cc-navprogress-sweep 1.1s ease-in-out infinite; }
html.cc-navigating .cc-navprogress{ opacity:1; }
@keyframes cc-navprogress-sweep{
  0%   { transform:translateX(-100%); }
  100% { transform:translateX(350%); }
}
@media (prefers-reduced-motion: reduce){
  .cc-navprogress::before{ animation:none; width:100%; }
}

/* ===== Demo-mode indicators (demo/real toggle) =====
   Red (--signal-critical) = you are viewing the demo database, not real data.
   Replaces the retired full-width demo banner. The dot mirrors the
   .cpx-statusbar__online .cpx-lamp glow pattern. */
.cc-demoflag{
  display:inline-flex; align-items:center; gap:6px;
  font-family:var(--font-mono); color:var(--signal-critical-2);
  font-size:var(--fs-meta); font-weight:700; letter-spacing:.1em;
  text-transform:uppercase; white-space:nowrap;
}
.cc-demoflag__dot{
  width:8px; height:8px; border-radius:50%; background:var(--signal-critical-2);
  box-shadow:0 0 8px var(--signal-critical-2);
}
/* Slow glow breath so the demo state is unmissable without blinking. This is a
   deliberate exception to the amber-only-animates rule (§3a): the red pulse only
   exists in demo mode, never in John's normal real-data view, so it does not
   dilute the scarce amber signal. Gated on reduced-motion like every animation. */
@media (prefers-reduced-motion: no-preference){
  .cc-demoflag__dot{ animation:cc-demopulse 2.8s ease-in-out infinite; }
  @keyframes cc-demopulse{
    0%,100%{ box-shadow:0 0 4px var(--signal-critical-2); opacity:.55; }
    50%{ box-shadow:0 0 14px 2px var(--signal-critical-2); opacity:1; }
  }
}
/* In demo mode the customize button is tinted red to tie it to the flag. */
.cc-iconbtn--demo{ color:var(--signal-critical-2); border-color:var(--signal-critical-2); }

/* Data mode switch inside the customize drawer. */
.cc-customize__datamode{
  display:flex; align-items:center; gap:10px;
  padding:8px 12px; margin-bottom:8px;
  border:1px solid var(--hairline); border-radius:6px;
}
.cc-customize__dmlbl{
  font-family:var(--font-mono); font-size:var(--fs-caption); letter-spacing:.12em;
  text-transform:uppercase; color:var(--txt-dim);
}
.cc-customize__dmstate{ font-size:var(--fs-control); font-weight:700; color:var(--signal-nominal); }
.cc-customize__datamode.is-demo .cc-customize__dmstate{ color:var(--signal-critical); }
.cc-customize__dmbtn{
  margin-left:auto; font-family:var(--font-mono); font-size:var(--fs-caption);
  letter-spacing:.1em; text-transform:uppercase; padding:5px 12px;
  border-radius:4px; cursor:pointer; border:1px solid var(--hairline);
  background:transparent; color:var(--txt);
}
.cc-customize__datamode.is-demo .cc-customize__dmbtn{ border-color:var(--signal-critical); color:var(--signal-critical); }

/* ── Settings sub-nav tabs ────────────────────────────────────────────────
   The shared /settings/* section switcher (data-settings-subnav). The base
   .cpx-pill is sized for status chips (9px) and reads as decoration here, so
   the nav chips get real tab affordance: larger type, more padding, and a
   filled info-toned active state. Selection is informational, never amber. */
[data-settings-subnav] .cpx-pill{
  font-size:var(--fs-caption); padding:8px 16px; border-radius:4px; cursor:pointer;
  opacity:1; color:var(--txt); border-color:var(--hairline);
}
[data-settings-subnav] .cpx-pill--ghost:hover{ border-color:var(--signal-info); color:var(--txt); }
[data-settings-subnav] .cpx-pill.is-on{
  color:var(--txt); background:var(--info-dim);
  border-color:var(--signal-info); font-weight:700;
}

/* Instrument toggle (quiet pass 2): a styled checkbox for on/off settings.
   Track + knob from existing tokens; :checked reads nominal green. */
.cpx-toggle{ appearance:none; -webkit-appearance:none; width:30px; height:16px; border-radius:8px;
  background:var(--inset); border:1px solid var(--hairline); position:relative; cursor:pointer;
  transition:background .15s ease; vertical-align:middle; }
.cpx-toggle::after{ content:""; position:absolute; top:1px; left:1px; width:12px; height:12px;
  border-radius:50%; background:var(--txt-dim); transition:transform .15s ease; }
.cpx-toggle:checked{ background:var(--nominal-dim); border-color:var(--signal-nominal); }
.cpx-toggle:checked::after{ transform:translateX(14px); background:var(--signal-nominal); }
.cpx-toggle:focus-visible{ outline:2px solid var(--signal-priority); outline-offset:2px; }
@media (prefers-reduced-motion: reduce){ .cpx-toggle, .cpx-toggle::after{ transition:none; } }

/* ===========================================================================
   .cpx-btn - the button component. ONE primary per state: --primary is the
   single info-blue call to action; --secondary and --ghost carry everything
   else so co-equal primaries never compete. Full state set: hover, focus,
   active, disabled, and an htmx in-flight state (hx-disabled-elt sets
   [disabled] during the request). Amber stays reserved for needs-you, so no
   button variant uses it.
   =========================================================================== */
.cpx-btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  padding:9px 15px; border-radius:5px; border:1px solid transparent; cursor:pointer;
  font-family:var(--font-display); font-weight:600; font-size:var(--fs-control);
  letter-spacing:.1em; text-transform:uppercase; text-decoration:none;
  transition:background .16s ease, border-color .16s ease, color .16s ease, opacity .16s ease;
}
.cpx-btn:focus-visible{ outline:2px solid var(--signal-info); outline-offset:2px; }
.cpx-btn[disabled], .cpx-btn:disabled{ opacity:.5; cursor:progress; }
.cpx-btn--block{ width:100%; }
.cpx-btn--sm{ padding:6px 12px; font-size:var(--fs-meta); }
.cpx-btn--lg{ padding:11px 18px; }
.cpx-btn--primary{ background:var(--signal-info); color:var(--ink); font-weight:700; }
.cpx-btn--primary:hover{ background:#c8d1da; }
.cpx-btn--primary:active{ background:#9aa6b2; }
.cpx-btn--secondary{ background:transparent; color:var(--txt); border-color:var(--bezel); }
.cpx-btn--secondary:hover{ background:var(--gunmetal); border-color:var(--steel); }
.cpx-btn--secondary:active{ background:var(--steel); }
.cpx-btn--ghost{ background:transparent; color:var(--txt-dim); border-color:var(--hairline); }
.cpx-btn--ghost:hover{ background:var(--inset); color:var(--txt); }

/* Segmented radio control. A real <form> with radios so it works with JS off;
   the radio itself is visually hidden but stays in the tab and AT tree. */
.cpx-seg{ display:inline-flex; align-items:center; gap:4px; padding:4px;
  border:1px solid var(--hairline); border-radius:var(--r); background:var(--inset); }
.cpx-seg__opt{ position:relative; }
.cpx-seg__opt input{ position:absolute; opacity:0; width:100%; height:100%;
  margin:0; cursor:pointer; }
.cpx-seg__opt span{ display:block; padding:6px 13px; border-radius:4px;
  font-size:var(--fs-control); color:var(--txt-dim); }
.cpx-seg__opt input:checked + span{ background:var(--gold-gradient);
  color:var(--on-gold); font-weight:600; }
.cpx-seg__opt input:focus-visible + span{ outline:2px solid var(--signal-info);
  outline-offset:2px; }
.cpx-seg .cpx-btn{ margin-left:6px; }

/* .cpx-extlink - a link that leaves the app. Body-text white (not the low-
   contrast info-blue), with a trailing external-link glyph so the reader knows
   it opens elsewhere. Underline appears on hover/focus only. */
.cpx-extlink{ color:var(--txt); text-decoration:none; display:inline-flex; align-items:center; gap:4px; }
.cpx-extlink:hover, .cpx-extlink:focus-visible{ text-decoration:underline; }
.cpx-extlink .cc-ic{ width:11px; height:11px; flex:0 0 auto; opacity:.75; }

/* ===========================================================================
   .cpx-skeleton - loading placeholder for content that takes a beat to arrive
   (e.g. the ~10s Suggest Rate advisor call). A subtle saturation sweep, not a
   spinner; reduced-motion parks it as a flat block.
   =========================================================================== */
.cpx-skeleton{ display:flex; flex-direction:column; gap:10px; }
/* When the skeleton doubles as an htmx-indicator, the htmx-request state (added
   to the hx-indicator target during the call) drives visibility; idle stays
   hidden. The two-class selectors beat the bare .cpx-skeleton display. */
.htmx-indicator.cpx-skeleton{ display:none; }
.htmx-request .htmx-indicator.cpx-skeleton,
.htmx-request.htmx-indicator.cpx-skeleton{ display:flex; }
.cpx-skeleton__line{
  height:14px; border-radius:4px; background:var(--inset);
  border:1px solid var(--hairline); position:relative; overflow:hidden;
}
.cpx-skeleton__line--wide{ height:44px; }
.cpx-skeleton__line--tall{ height:96px; }
@media (prefers-reduced-motion: no-preference){
  .cpx-skeleton__line::after{
    content:""; position:absolute; inset:0;
    background:linear-gradient(90deg, transparent 30%, rgba(179,190,201,.10) 50%, transparent 70%);
    transform:translateX(-100%); animation:cpx-skeleton-sweep 1.3s ease-in-out infinite;
  }
  @keyframes cpx-skeleton-sweep{ 100%{ transform:translateX(100%); } }
}

/* ===========================================================================
   .cpx-quote-region - the /rates workspace: the build-up card persists on the
   left while the confirm form and letter preview render into the action pane
   beside it, so the floor/recommended/stretch figure strip never vanishes
   mid-flow. Collapses to a single column when the compose column is narrow.
   =========================================================================== */
.cpx-quote-region{ display:grid; grid-template-columns:1fr; gap:14px; align-items:start; }
/* The card fills the width until the action pane has content; then the region
   splits so confirm/letter sit beside the persistent card. */
.cpx-quote-region:has(.cpx-quote-region__action:not(:empty)){
  grid-template-columns:minmax(0,1fr) minmax(300px,380px);
}
.cpx-quote-region__action:empty{ display:none; }
/* Left column: advisor guidance note (when present) stacked above the build-up
   card, so both share the first grid track and the action pane stays in column 2. */
.cpx-quote-region__main{ display:flex; flex-direction:column; gap:14px; min-width:0; }
@media (max-width:1080px){
  .cpx-quote-region:has(.cpx-quote-region__action:not(:empty)){ grid-template-columns:1fr; }
}
/* Page frame for /rates: a compose column (lookup + quote workspace) beside a
   persistent rail (Describe The Job + Past Conversations), so a populated quote
   card never evicts the chat below the fold. Stacks the rail under the compose
   column on narrow viewports. */
.cpx-rates{ max-width:1360px; width:100%; margin:0 auto; }
/* (Legacy two-column grid helpers kept for reuse; the #1436 canvas layout is a
   single full-width column with the Past Conversations drawer overlaying it.) */
.cpx-rates__grid{ display:grid; grid-template-columns:minmax(0,1fr) 340px; gap:14px; align-items:start; }
.cpx-rates__compose{ display:flex; flex-direction:column; gap:14px; min-width:0; }
.cpx-rates__rail{ display:flex; flex-direction:column; gap:14px; min-width:0; }
@media (max-width:1100px){
  .cpx-rates__grid{ grid-template-columns:1fr; }
}
/* Top bar carries the collapsed manual-lookup affordance at the top right (#1437). */
.cpx-rates__topbar{ display:flex; justify-content:flex-end; }
.is-lookup-collapsed .cpx-rates__topbar{ margin-bottom:10px; }

/* Combined intake panel (#1437): describe-the-job is the hero; the manual job-type
   lookup is the secondary path (.cpx-lookup-manual), set off by a labelled rule and
   collapsed to the top-right button once a chat intake is active. */
.cpx-lookup-manual{ display:flex; flex-direction:column; gap:12px; margin-top:16px;
  padding-top:14px; border-top:1px solid var(--hairline); }
.cpx-lookup-manual__sep{ display:flex; align-items:center; gap:10px; font-family:var(--font-mono);
  font-size:var(--fs-meta); letter-spacing:.14em; text-transform:uppercase; color:var(--txt-dim); }
.cpx-lookup-manual__sep::before, .cpx-lookup-manual__sep::after{ content:""; height:1px;
  background:var(--hairline); flex:1; }
.cpx-lookup-manual__row{ display:flex; gap:12px; flex-wrap:wrap; align-items:flex-end; }
/* Collapse: the manual lookup hides and its affordance moves to the top-right button. */
#lookup-reopen{ display:none; }
.is-lookup-collapsed #lookup-form-region{ display:none; }
.is-lookup-collapsed #lookup-reopen{ display:inline-flex; }

/* .cpx-drawer (#1438): Past Conversations as a right-edge pull-out. Closed to a
   slim vertical handle; a pure-CSS checkbox toggle slides the panel in over the
   content, so the quoting canvas stays maximal. The list inside still loads via
   htmx and refreshes on refreshChats. */
/* The checkbox IS the keyboard control for this drawer (the handle is a <label>, which
   is not focusable). position:fixed, not absolute: with no offsets it would sit at its
   static position at the foot of the document, and focusing it would scroll the quoting
   canvas away. Visually hidden, but deliberately still focusable and still in the a11y
   tree; it carries aria-label because its two <label for> elements would otherwise
   concatenate into the accessible name. */
.cpx-drawer__cb{ position:fixed; top:50%; right:0; width:1px; height:1px; opacity:0; pointer-events:none; }
.cpx-drawer__cb:focus-visible ~ .cpx-drawer__handle{ outline:2px solid var(--signal-info); outline-offset:2px; }
.cpx-drawer__handle{ position:fixed; top:50%; right:0; transform:translateY(-50%); z-index:44;
  display:flex; align-items:center; writing-mode:vertical-rl; cursor:pointer;
  padding:14px 7px; border:1px solid var(--hairline); border-right:0;
  border-radius:6px 0 0 6px; background:var(--panel-bg-solid); color:var(--txt);
  font-family:var(--font-mono); font-size:var(--fs-meta); letter-spacing:.18em; text-transform:uppercase;
  box-shadow:0 8px 24px -14px #000; transition:right .22s ease, background .16s ease; }
.cpx-drawer__handle:hover{ background:var(--gunmetal); }
.cpx-drawer__handle-txt{ transform:rotate(180deg); }
.cpx-drawer__panel{ position:fixed; top:0; right:0; height:100dvh; width:min(360px,88vw); z-index:45;
  display:flex; flex-direction:column; border-left:1px solid var(--bezel); border-radius:0;
  /* Closed-state a11y (#1466). visibility:hidden takes the panel's links out of the
     tab order AND the a11y tree; transitioning visibility keeps the slide, because any
     in-between value resolves to `visible`. But that same window leaves the panel
     FOCUSABLE for the whole .22s close, so a Tab within 220ms of closing lands inside
     it and is destroyed when visibility flips (focus lost to BODY, measured).
     interactivity:inert is deliberately NOT in the transition list: it flips instantly,
     so the panel stops being focusable the moment it starts closing while still painting
     the slide. Do NOT move `transition` onto the :checked rule below; that selector is
     (0,3,0) and would beat the (0,1,0) `transition:none` in the reduced-motion block. */
  visibility:hidden; interactivity:inert;
  transform:translateX(100%); transition:transform .22s ease, visibility .22s; overflow:hidden; }
.cpx-drawer__hd{ display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:12px 14px; border-bottom:1px solid var(--hairline); }
.cpx-drawer__close{ display:inline-flex; padding:5px; border-radius:5px; cursor:pointer;
  color:var(--txt-dim); border:1px solid var(--hairline); }
.cpx-drawer__close:hover{ color:var(--txt); background:var(--gunmetal); }
.cpx-drawer__body{ padding:14px; overflow-y:auto; }
.cpx-drawer__cb:checked ~ .cpx-drawer__panel{ transform:translateX(0); visibility:visible; interactivity:auto; }
.cpx-drawer__cb:checked ~ .cpx-drawer__handle{ right:min(360px,88vw); }
@media (prefers-reduced-motion: reduce){
  .cpx-drawer__panel, .cpx-drawer__handle{ transition:none; }
}

/* .cpx-dialog - modal confirmation/content dialog (components/dialog.html).
   Ported from shadcn-htmx (vendor/shadcn-htmx/dialog.html): native <dialog>
   opened via Invoker Commands (command="show-modal"/"close"), no JS. Panel
   chrome matches .cpx-panel: solid glass, bezel border, gold hairline. */
.cpx-dialog{
  position:fixed; inset:0; margin:auto; z-index:50;
  width:calc(100% - 2rem); max-width:480px;
  display:none; gap:var(--gap);
  border:1px solid var(--bezel); border-radius:var(--r);
  background:var(--panel-bg-solid); color:var(--txt);
  padding:20px;
  box-shadow:0 18px 50px rgba(0,0,0,.55), var(--glow-bezel);
}
.cpx-dialog[open]{ display:grid; }
.cpx-dialog::backdrop{ background:rgba(5,8,12,.68); backdrop-filter:blur(2px); }
.cpx-dialog::before{
  content:""; position:absolute; top:0; left:14px; right:14px; height:1px;
  background:var(--gold-edge);
}
/* Quick-jump palette. A bare <dialog> shell only: the .cpx-cmdbar inside already
   carries the full instrument look, so this contributes position and width and
   nothing else. Sits higher than .cpx-dialog (top layer ordering is by open
   order, but the z-index keeps it above non-dialog overlays) and anchors toward
   the top of the viewport the way a command palette is expected to, rather than
   dead-centre like a confirm dialog. */
.cpx-cmd-dialog{
  position:fixed; inset:0; margin:10vh auto auto; z-index:60;
  width:calc(100% - 2rem); max-width:560px;
  display:none; padding:0; border:0; background:none; overflow:visible;
}
.cpx-cmd-dialog[open]{ display:block; }
.cpx-cmd-dialog::backdrop{ background:rgba(5,8,12,.68); backdrop-filter:blur(2px); }

.cpx-dialog__hd{ display:flex; flex-direction:column; gap:6px; text-align:left; }
.cpx-dialog__title{
  margin:0; font-family:var(--font-display); font-weight:600;
  font-size:15px; letter-spacing:.06em; text-transform:uppercase; color:var(--txt);
}
.cpx-dialog__desc{ margin:0; font-size:var(--fs-secondary); line-height:1.5; color:var(--txt-dim); }
.cpx-dialog__ft{ display:flex; gap:10px; justify-content:flex-end; flex-wrap:wrap; }
.cpx-dialog__close{
  position:absolute; top:12px; right:12px;
  display:inline-flex; align-items:center; justify-content:center;
  width:26px; height:26px; border:0; border-radius:var(--r);
  background:transparent; color:var(--txt-dim); opacity:.7; cursor:pointer;
}
.cpx-dialog__close:hover{ background:var(--info-dim); color:var(--txt); opacity:1; }
.cpx-dialog__close:focus-visible{ outline:2px solid var(--signal-info); outline-offset:2px; opacity:1; }
.cpx-dialog__close svg{ width:15px; height:15px; }

/* .cpx-popover - anchored floating panel (components/popover.html).
   Ported from shadcn-htmx (vendor/shadcn-htmx/popover.html): native Popover API
   (popover="auto"), so outside-click dismiss, Escape, top-layer stacking, and
   focus restoration come from the browser with no JS. Replaces the <details> +
   position:absolute idiom, which had none of those.
   Placement is CSS anchor positioning (trigger sets anchor-name inline, panel
   sets position-anchor inline). A popover lives in the top layer, so the old
   ancestor-relative absolute positioning cannot work here. Browsers without
   anchor positioning fall back to the UA-centered popover placement, which is
   plain but not broken. */
.cpx-popover{
  margin:0; padding:14px;
  min-width:320px; max-width:calc(100vw - 32px);
  border:1px solid var(--hairline); border-radius:8px;
  background:var(--ink); color:var(--txt);
  box-shadow:0 8px 32px rgba(0,0,0,.5);
}
@supports (position-area: bottom){
  .cpx-popover{ position:fixed; inset:auto; position-try-fallbacks:flip-block; }
  /* Keywords must stay all-physical: mixing physical (bottom) with logical
     (span-inline-start) is invalid and silently computes to position-area:none,
     dropping the panel at the UA-centered default. */
  .cpx-popover--bottom{ position-area:bottom span-left; margin-top:6px; }
  .cpx-popover--top{ position-area:top span-left; margin-bottom:6px; }
}
.cpx-popover__hd{
  font-family:var(--font-mono); font-size:var(--fs-meta); letter-spacing:.14em;
  text-transform:uppercase; color:var(--txt-dim); margin-bottom:10px;
}

/* Native date/time pickers on the dark theme (#1479). The UA calendar/clock indicator
   glyph (the "checkmark"-looking icon on the right of the field) is a dark icon, invisible
   on our dark --inset inputs, and the empty-state mm/dd/yyyy placeholder runs muted. Lighten
   both so the control is discoverable without tabbing to it. Applies wherever these native
   inputs are used: the Log a Booking popover and the calendar event editor. */
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator,
input[type="datetime-local"]::-webkit-calendar-picker-indicator{
  filter:invert(0.85); opacity:.65; cursor:pointer;
}
input[type="date"]::-webkit-calendar-picker-indicator:hover,
input[type="time"]::-webkit-calendar-picker-indicator:hover,
input[type="datetime-local"]::-webkit-calendar-picker-indicator:hover{ opacity:1; }
input[type="date"]::-webkit-datetime-edit,
input[type="time"]::-webkit-datetime-edit,
input[type="datetime-local"]::-webkit-datetime-edit{ color:var(--txt-dim); }

/* ===== Help prose (.cpx-help) - Feature #1564 =====
   Markdown-rendered help topics. Scoped so rendered HTML needs no classes.
   NOT .cpx-prose: that name is already used ad hoc in templates. */
.cpx-help { max-width: 70ch; font-size: 14px; line-height: 1.65; color: var(--txt); }
.cpx-help h1 { display: none; }               /* page chrome already shows the title */
.cpx-help h2 { font-family: var(--font-display); font-size: 15px; letter-spacing: .08em;
               text-transform: uppercase; color: var(--txt); margin: 22px 0 8px; }
.cpx-help h3 { font-size:var(--fs-body); font-weight: 600; margin: 16px 0 6px; }
.cpx-help p  { margin: 0 0 12px; }
.cpx-help ul, .cpx-help ol { margin: 0 0 12px 20px; }
.cpx-help li { margin-bottom: 4px; }
.cpx-help a  { color: var(--signal-info); text-decoration: none; }
.cpx-help a:hover { text-decoration: underline; }
.cpx-help code { font-family: var(--font-mono); font-size:var(--fs-control);
                 background: color-mix(in srgb, var(--txt) 8%, transparent);
                 padding: 1px 5px; border-radius: 4px; }
.cpx-help table { border-collapse: collapse; margin: 0 0 12px; }
.cpx-help th, .cpx-help td { padding: 6px 10px; border-bottom: 1px solid var(--hairline);
                             text-align: left; font-size:var(--fs-body); }
.cpx-help__changelog { margin-top: 20px; padding-top: 12px;
                       border-top: 1px solid var(--hairline);
                       font-size:var(--fs-caption); color: var(--txt-dim); }
.cpx-help__changelog h2 { font-size:var(--fs-meta); letter-spacing: .14em; text-transform: uppercase;
                          margin: 0 0 6px; color: var(--txt-dim); }
.cpx-help__changelog ul { list-style: none; margin: 0; padding: 0; }
.cpx-help__changelog li { margin-bottom: 2px; }

/* ===== Info icon (.cpx-info-icon) - Feature #1564 =====
   Quiet contextual help link next to a control. Dim by default, brightens on
   hover/focus. Never amber (amber = needs-you only). */
.cpx-info-icon { display: inline-flex; align-items: center; vertical-align: middle;
                 margin-left: 6px; color: var(--txt-dim); transition: color .15s ease; }
.cpx-info-icon:hover, .cpx-info-icon:focus-visible { color: var(--txt); }

/* ===========================================================================
   .cpx-runstrip - automation panel run history strip (settings_automations).
   Ten fixed slots, oldest to newest; constant width so "only three runs so
   far" is visible. Variants honour the amber reserve: warn is the ONLY
   priority-coloured tick and means a failure John can fix. Healthy runs use
   --steel, an unfilled slot is a dashed placeholder.
   =========================================================================== */
/* Three columns since #1775: body, run strip, controls. A two-column grid
   wrapped the control cluster onto its own line under the meta text, which
   destroyed the alignment the toggles depend on.

   The control track is a FIXED width, not auto, for two measured reasons: an
   auto track sizes to its own row's content, so the wider "Mining page ->"
   link pulled that row's run strip 25px out of line, and the not_wired rows,
   which have no controls at all, pushed their strips 141px right of every
   other row. A fixed track makes every run strip land on the same x. */
.cpx-row--auto{ grid-template-columns:1fr 168px; }
.cpx-runstrip{ display:flex; gap:2px; align-items:flex-end; margin-top:6px;
               flex-wrap:nowrap; }
.cpx-runstrip__t{ width:5px; height:14px; border-radius:1px; flex:none;
                  background:var(--signal-nominal); }
/* Outcome, read left to right as history. Green ran clean, amber ran but hit
   problems, red did not run. WHO can fix a failure is deliberately not encoded
   here; that is the row's left edge (--priority vs --critical), which is a far
   louder signal than one mark among fifty. */
.cpx-runstrip__t--partial{ background:var(--signal-priority); }
.cpx-runstrip__t--fail{ background:var(--signal-critical); }
/* A deliberate no-op (sending fenced off, nothing due) is neither success nor
   failure and must never read green. It must still read as a MARK, though:
   --inset on the row gradient was indistinguishable from an empty slot, which
   made a healthy automation look like it had no history at all. With sending
   disabled, drip sends skips on every tick, so that was the common case. */
.cpx-runstrip__t--skip{ background:var(--steel); }
.cpx-runstrip__t--run{ background:transparent; border:1px solid var(--steel); }
/* An unfilled slot: this automation has not run this many times yet. */
.cpx-runstrip__t--none{ background:transparent; border:1px dashed var(--hairline); }

/* ===========================================================================
   .cpx-autoctl - per-automation controls (settings_automations).
   Sits right of the run strip, past a hairline divider, so every toggle lines
   up in ONE vertical column and "what is switched off right now" is a single
   glance down the page rather than a read of every row.

   Green (--signal-nominal / --nominal-2) appears ONLY inside the switch, never
   on the row itself, so the amber reserve is untouched: amber still means
   "John needs to act" and nothing else. A switched-off row dims via opacity
   and takes NO accent edge, because off is a normal state, not a warning.

   The On/Off word under each switch is not decoration: a bare switch on a dark
   ground is ambiguous about which side means on.
   =========================================================================== */
.cpx-autoctl{ display:flex; align-items:center; gap:12px; justify-content:flex-end; }
.cpx-autoctl__sep{ width:1px; height:22px; background:var(--hairline); flex:none; }

.cpx-runbtn{ font-family:var(--font-mono); font-size:var(--fs-control); letter-spacing:.06em;
             text-transform:uppercase; color:var(--txt-dim); background:var(--inset);
             border:1px solid var(--bezel); border-radius:4px; padding:4px 10px;
             cursor:pointer; white-space:nowrap; }
.cpx-runbtn:hover, .cpx-runbtn:focus-visible{ color:var(--txt); border-color:var(--steel); }
.cpx-runbtn--busy, .cpx-runbtn[disabled]{ color:var(--gold-2); border-color:var(--gold); cursor:default; }

.cpx-runlink{ font-family:var(--font-mono); font-size:var(--fs-control); letter-spacing:.06em;
              color:var(--txt-dim); text-decoration:none; white-space:nowrap;
              border-bottom:1px solid var(--hairline); padding-bottom:1px; }
.cpx-runlink:hover, .cpx-runlink:focus-visible{ color:var(--gold-2); border-color:var(--gold); }

.cpx-sw-wrap{ display:flex; flex-direction:column; align-items:center; gap:3px; }
.cpx-sw{ width:38px; height:20px; border-radius:11px; position:relative; flex:none; padding:0;
         background:var(--inset); border:1px solid var(--bezel); cursor:pointer; }
.cpx-sw::after{ content:""; position:absolute; top:2px; left:2px; width:14px; height:14px;
                border-radius:50%; background:var(--steel);
                transition:left .15s ease, background .15s ease; }
.cpx-sw--on{ border-color:var(--signal-nominal); background:rgba(63,153,86,.18); }
.cpx-sw--on::after{ left:20px; background:var(--nominal-2); }
/* .14em, not .18em: 17 existing sites share this exact mono/uppercase/--fs-label
   signature at .14em, and the design sweep flags a new value as drift. */
.cpx-sw__lbl{ font-family:var(--font-mono); font-size:var(--fs-label); letter-spacing:.14em;
              text-transform:uppercase; color:var(--txt-dim); }

@media (prefers-reduced-motion: reduce){
  .cpx-sw::after{ transition:none; }
}

/* ===========================================================================
   Run-tick hover tooltip and the picked-run detail panel.

   The tooltip is pure CSS (content: attr(data-tip)) so it appears instantly
   rather than after the OS title-attribute delay, which matters when you are
   scrubbing along fifty marks looking for when something broke.

   It is positioned ABOVE the tick and INSIDE the row on purpose: .cpx-row sets
   overflow:hidden (it clips the ::before state edge to the rounded corner), so
   a tooltip that escaped the row would simply be cut off.
   =========================================================================== */
.cpx-runstrip__t{ position:relative; }
.cpx-runstrip__t::after{
  content:attr(data-tip); position:absolute; bottom:calc(100% + 5px); left:50%;
  transform:translateX(-50%); white-space:nowrap; pointer-events:none;
  font-family:var(--font-mono); font-size:var(--fs-meta); letter-spacing:.02em;
  color:var(--txt); background:var(--ink); border:1px solid var(--bezel);
  border-radius:3px; padding:3px 7px; opacity:0; transition:opacity .1s ease;
  z-index:5;
}
.cpx-runstrip__t:hover::after, .cpx-runstrip__t:focus-visible::after{ opacity:1; }
/* The leftmost and rightmost ticks would push their tooltip out of the row and
   be clipped, so they anchor to their own edge instead of centring. */
.cpx-runstrip__t:first-child::after{ left:0; transform:none; }
.cpx-runstrip__t:last-child::after{ left:auto; right:0; transform:none; }

/* Only runs with a story are clickable; a clean run says all it has in its
   tooltip. Ticks are buttons only when clickable, so the strip adds a handful
   of tab stops rather than fifty. */
.cpx-runstrip__t.is-clickable{ padding:0; cursor:pointer; }
.cpx-runstrip__t.is-clickable:hover{ outline:1px solid var(--txt-dim); outline-offset:1px; }
.cpx-runstrip__t.is-picked{ outline:1px solid var(--txt); outline-offset:1px; }

/* The picked run, both registers at once: raw on the left for whoever is
   debugging, plain language on the right for John. */
.cpx-runpick{
  display:grid; grid-template-columns:minmax(0,1.1fr) minmax(0,1fr); gap:18px;
  padding:10px 13px 12px; border-top:1px solid var(--hairline);
}
.cpx-runpick__h{
  margin:0 0 6px; font-family:var(--font-mono); font-size:var(--fs-label);
  letter-spacing:.14em; text-transform:uppercase; color:var(--txt-dim); font-weight:400;
}
.cpx-runpick__dl{ margin:0; display:grid; grid-template-columns:auto 1fr; gap:2px 10px; }
.cpx-runpick__dl dt{
  font-family:var(--font-mono); font-size:var(--fs-meta); color:var(--txt-dim);
}
.cpx-runpick__dl dd{
  margin:0; font-family:var(--font-mono); font-size:var(--fs-meta); color:var(--txt);
  word-break:break-word;
}
.cpx-runpick__say{ margin:0; font-size:var(--fs-secondary); color:var(--txt); }
.cpx-runpick__next{ margin:6px 0 0; font-size:var(--fs-secondary); color:var(--txt-dim); }

@media (max-width: 700px){
  .cpx-runpick{ grid-template-columns:1fr; gap:12px; }
}
@media (prefers-reduced-motion: reduce){
  .cpx-runstrip__t::after{ transition:none; }
}
