/* Spark Brain — Shell */
/* Design system tokens from Spark HQ, adapted for production */

:root {
  --navy:   #0c233f;
  --deep:   #063269;
  --bg:     #07182e;
  --gold:   #ffc82e;
  --gdim:   rgba(255,200,46,.12);
  --card:   #0d2a4f;
  --bdr:    rgba(255,200,46,.12);
  --bhi:    rgba(255,200,46,.30);
  --text:   #fff;
  --muted:  rgba(255,255,255,.50);
  --sub:    rgba(255,255,255,.06);
  --grn:    #4ade80;
  --red:    #f87171;
  --blu:    #60a5fa;
  --amb:    #fb923c;
  --pur:    #a78bfa;
  --r:      10px;
  --rsm:    6px;
  --topbar-h: 52px;
  --rx-modal-w: 880px;   /* shared width for equal-sized Atlas + Echo modals */
  --soft:   rgba(255,255,255,.80);  /* between --text and --muted: soft-but-readable */
  --raised: #11304f;                /* raised "bubble" panel, a step lighter than --navy */

  /* === TYPE SCALE ===
     One shared scale so hierarchy reads cleanly across the grid + contact page
     (section title → label → body → meta), instead of ad-hoc per-element sizes.
     Half-pixel sizes (9.5/10.5/11.5/12.5) collapse onto the nearest step. */
  --fs-display: 28px;   /* page titles */
  --fs-stat:    30px;   /* big stat numbers */
  --fs-h1:      26px;   /* contact name */
  --fs-h2:      16px;   /* page section headings, modal titles */
  --fs-title:   15px;   /* card name, role-group header */
  --fs-lg:      14px;   /* prominent body: role titles, field values, inputs */
  --fs-body:    13px;   /* default body */
  --fs-sm:      12px;   /* secondary body / meta */
  --fs-xs:      11px;   /* small meta, pills */
  --fs-eyebrow: 10px;   /* uppercase labels + tiny tags */

  /* weights */
  --fw-medium:   600;
  --fw-bold:     700;
  --fw-heavy:    800;

  /* line-heights */
  --lh-tight:   1.15;   /* large headings */
  --lh-snug:    1.35;   /* titles / multi-line UI */
  --lh-base:    1.5;    /* body (default) */
  --lh-relaxed: 1.6;    /* reading paragraphs */

  /* letter-spacing */
  --ls-tight:   -.02em; /* large headings */
  --ls-eyebrow:  .08em; /* uppercase labels */
}

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

body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: var(--bg);
  color: var(--text);
  font-size: 13px;
  line-height: 1.5;
  min-height: 100vh;
}

a { color: inherit; text-decoration: none; }

/* === TOPBAR === */
.topbar {
  background: var(--deep);
  border-bottom: 1px solid var(--bdr);
  height: var(--topbar-h);
  padding: 0 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: sticky;
  top: 0;
  z-index: 50;
}

/* Drill-path Back — page-level only (not beside the logo). Hidden until a trail exists. */
.spark-nav-back {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin: 0 0 14px;
  font-family: inherit;
  font-size: var(--fs-sm, 13px);
  font-weight: var(--fw-medium, 500);
  color: var(--muted);
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
  transition: color .15s;
}
.spark-nav-back:hover:not(:disabled) {
  color: var(--gold);
}
.spark-nav-back:disabled,
.spark-nav-back[aria-disabled="true"] {
  opacity: 0.4;
  cursor: default;
}
.spark-nav-back[hidden] { display: none !important; }
.spark-nav-back-chevron {
  font-size: 16px;
  line-height: 1;
  font-weight: 600;
}
.spark-nav-back-label { letter-spacing: 0.01em; }

.topbar-brand {
  display: flex;
  align-items: center;
}

.brand-wordmark {
  display: block;
  height: 28px;
  width: auto;
}

.brand-glow {
  position: relative;
  display: inline-block;
  line-height: 0;
}

.brand-glow::before {
  content: '';
  position: absolute;
  inset: -10px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255,200,46,.4) 0%, rgba(255,200,46,0) 65%);
  animation: brain-pulse 3s ease-in-out infinite;
  z-index: 0;
  pointer-events: none;
}

.brand-logo {
  width: 32px;
  height: 32px;
  display: block;
  position: relative;
  z-index: 1;
  animation: brain-breathe 3s ease-in-out infinite;
}

@keyframes brain-pulse {
  0%, 100% { opacity: .5; transform: scale(1); }
  50%     { opacity: 1;  transform: scale(1.15); }
}

@keyframes brain-breathe {
  0%, 100% { transform: scale(1); }
  50%     { transform: scale(1.08); }
}
.topnav {
  display: flex;
  gap: 4px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

.topnav a {
  padding: 6px 16px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
  transition: color .15s;
}

.topnav a:hover { color: var(--text); }
.topnav a.on { color: var(--gold); }

.topnav a.disabled {
  opacity: .35;
  cursor: not-allowed;
  pointer-events: none;
}

.user-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  color: var(--muted);
  background: var(--sub);
  border: 1px solid var(--bdr);
  border-radius: var(--rsm);
  padding: 6px 12px;
  transition: all .15s;
}

.user-pill:hover {
  color: var(--text);
  border-color: var(--bhi);
}

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
  animation: status-pulse 2.5s ease-in-out infinite;
}

.status-dot.amber { background: var(--amb); }
.status-dot.green { background: var(--grn); }
.status-dot.red   { background: var(--red); animation: none; }
.status-dot.gray  { background: var(--muted); animation: none; }

@keyframes status-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%     { opacity: .5; transform: scale(.85); }
}

/* === PAGE === */
.page {
  max-width: 1280px;
  margin: 0 auto;
  padding: 40px 32px 80px;
}

.section { margin-bottom: 48px; }

.section-title {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 16px;
}

/* === HERO === */
.hero { margin-bottom: 48px; }

.hero-greeting {
  font-size: 28px;
  font-weight: 800;
  letter-spacing: -.02em;
  margin-bottom: 6px;
}

.hero-sub {
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 24px;
  max-width: 680px;
  line-height: 1.6;
}

.hero-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}

.hero-card {
  background: var(--card);
  border: 1px solid var(--bdr);
  border-radius: var(--r);
  padding: 22px;
  transition: all .15s;
}

.hero-card:hover { border-color: var(--bhi); }
.hero-card.disabled { opacity: .5; }

.hero-card-label {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 14px;
}

.hero-card-value {
  font-size: 32px;
  font-weight: 800;
  letter-spacing: -.02em;
  margin-bottom: 6px;
}

.hero-card-note {
  font-size: 11px;
  color: var(--muted);
  line-height: 1.5;
}

/* === METRIC TILES === */
.metric-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 10px;
}

.metric-tile {
  background: var(--navy);
  border: 1px solid var(--bdr);
  border-radius: var(--r);
  padding: 18px 16px;
  transition: all .15s;
}

.metric-tile:hover { border-color: var(--bhi); }

.metric-label {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 14px;
}

.metric-value {
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -.02em;
  margin-bottom: 6px;
}

.metric-note {
  font-size: 10px;
  color: var(--muted);
  line-height: 1.4;
}

/* === ACTIVITY FEED === */
.activity-feed {
  background: var(--navy);
  border: 1px solid var(--bdr);
  border-radius: var(--r);
  overflow: hidden;
}

.activity-item {
  padding: 14px 18px;
  border-bottom: 1px solid var(--sub);
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 12px;
}

.activity-item:last-child { border-bottom: none; }

.activity-icon {
  font-size: 14px;
  width: 22px;
  text-align: center;
  flex-shrink: 0;
}

.activity-text { flex: 1; }

.activity-time {
  color: var(--muted);
  font-size: 11px;
  flex-shrink: 0;
}

/* === ROADMAP === */
.roadmap {
  background: var(--navy);
  border: 1px solid var(--bdr);
  border-radius: var(--r);
  padding: 8px 0;
}

.phase-item {
  padding: 13px 22px;
  display: flex;
  align-items: center;
  gap: 16px;
  font-size: 12px;
  opacity: .55;
}

.phase-item.current { opacity: 1; }

.phase-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 1.5px solid var(--muted);
  flex-shrink: 0;
}

.phase-item.current .phase-dot {
  background: var(--grn);
  border-color: var(--grn);
  box-shadow: 0 0 0 4px rgba(74,222,128,.18);
}

.phase-name { flex: 1; font-weight: 600; }
.phase-item.current .phase-name { color: var(--text); }

.phase-state { font-size: 11px; color: var(--muted); }
.phase-item.current .phase-state { color: var(--grn); font-weight: 600; }

/* === MOTION === */
@keyframes fade-up {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

.hero, .section { animation: fade-up .35s ease-out both; }
.section:nth-of-type(2) { animation-delay: .06s; }
.section:nth-of-type(3) { animation-delay: .12s; }
.section:nth-of-type(4) { animation-delay: .18s; }


/* === HAMBURGER === */
.topbar-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.menu-btn {
  display: none;
  align-items: center;
  justify-content: center;
  background: var(--sub);
  border: 1px solid var(--bdr);
  border-radius: var(--rsm);
  color: var(--muted);
  width: 32px;
  height: 32px;
  cursor: pointer;
  transition: all .15s;
  padding: 0;
}

.menu-btn:hover {
  color: var(--text);
  border-color: var(--bhi);
}

.menu-btn[aria-expanded="true"] {
  color: var(--gold);
  border-color: var(--bhi);
}

/* === RESPONSIVE === */
@media (max-width: 1100px) {
  .metric-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 768px) {
  .metric-grid { grid-template-columns: repeat(2, 1fr); }
  .hero-cards { grid-template-columns: 1fr; }
  .topbar { padding: 0 16px; }
  /* 16px matches page-specific mobile overrides (hh/cp/ma/pipeline/gw/ct) and
     brings any remaining surfaces that only use the base .page rule (notably index)
     onto the same gutter. */
  .page { padding: 24px 16px 80px; }

  .menu-btn { display: inline-flex; }

  .topnav {
    position: absolute;
    top: var(--topbar-h);
    left: 0;
    right: 0;
    transform: none;
    flex-direction: column;
    gap: 0;
    background: var(--deep);
    border-bottom: 1px solid var(--bdr);
    padding: 4px 0;
    display: none;
    box-shadow: 0 8px 24px rgba(0,0,0,.35);
  }

  .topnav.open { display: flex; }

  .topnav a {
    padding: 14px 20px;
    font-size: 11px;
    border-bottom: 1px solid var(--sub);
  }

  .topnav a:last-child { border-bottom: none; }
}


/* User pill text color matches status dot — visual identity-state link */
.user-pill.pill-green { color: var(--grn); }
.user-pill.pill-red { color: var(--red); }
.user-pill.pill-gray { color: var(--muted); }


/* User pill text colour matches status dot (granular) */
.user-pill.pill-amber { color: var(--amb); }

.value.opt-partial { color: var(--amb); }


/* =========================================================================
   CONTACT CARD REDESIGN — grid, snippet cards, fit pills, freshness, lenses
   All colours reference existing tokens; no new hex.
   ========================================================================= */

/* --- Shared equal-sized modals (Atlas + Echo) --- */
.am-panel, #cecho-modal .ce-panel { max-width: var(--rx-modal-w) !important; }

/* --- Fit pills: Strong / Possible / Stretch (per role + manager) --- */
.fit-pill {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--fs-xs); font-weight: var(--fw-bold); letter-spacing: .02em;
  padding: 2px 9px; border-radius: 999px; white-space: nowrap;
  border: 1px solid transparent; line-height: 18px;
}
.fit-pill.fit-strong   { color: var(--grn); background: rgba(74,222,128,.12);  border-color: rgba(74,222,128,.30); }
.fit-pill.fit-possible { color: var(--amb); background: rgba(251,146,60,.12);  border-color: rgba(251,146,60,.30); }
.fit-pill.fit-stretch  { color: var(--muted); background: var(--sub); border-color: rgba(255,255,255,.14); }
.fit-pill.fit-unassessed { color: var(--muted); background: transparent; border-color: rgba(255,255,255,.14); font-weight: var(--fw-medium); }

/* --- Freshness indicator (clients) --- */
.freshness { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-sm); color: var(--muted); }
.freshness-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.freshness-green .freshness-dot { background: var(--grn); }
.freshness-amber .freshness-dot { background: var(--amb); }
.freshness-red   .freshness-dot { background: var(--red); }
.freshness-none  .freshness-dot { background: rgba(255,255,255,.20); }
.freshness-red .freshness-label { color: var(--red); }

/* --- Type-coloured avatar rings --- */
.avatar-ring {
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; font-weight: var(--fw-bold); color: var(--text);
  background: var(--deep); border: 3px solid transparent; flex: none;
}
.avatar-ring.ring-candidate { border-color: var(--gold); }
.avatar-ring.ring-client    { border-color: var(--blu); }
/* dual: a gold→blue gradient ring (candidate + client). The two-layer background
   keeps the gradient on the ring (border-box) while the initials stay legible on
   the deep center (padding-box). */
.avatar-ring.ring-dual {
  border-color: transparent;
  background:
    linear-gradient(var(--deep), var(--deep)) padding-box,
    linear-gradient(135deg, var(--gold), var(--blu)) border-box;
}

/* --- Type indicator chips --- */
.type-chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: var(--fs-eyebrow); font-weight: var(--fw-bold); text-transform: uppercase; letter-spacing: .04em;
  padding: 2px 8px; border-radius: 999px;
}
.type-chip.type-candidate { color: var(--gold); background: var(--gdim); }
.type-chip.type-client    { color: var(--blu); background: rgba(96,165,250,.12); }

/* Matched type + Iris stage pills on contact header and contacts grid cards */
.c-tags .type-chip,
.c-tags .iris-stage,
.snippet-types .type-chip,
.snippet-types .iris-stage {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 5.25rem;
  height: 22px;
  padding: 0 10px;
  font-size: var(--fs-eyebrow);
  font-weight: var(--fw-bold);
  letter-spacing: .06em;
  text-transform: uppercase;
  line-height: 1;
  border-radius: 99px;
  box-sizing: border-box;
  white-space: nowrap;
}

/* --- Stage pill (candidate pipeline) --- */
.stage-pill {
  display: inline-flex; align-items: center; font-size: var(--fs-xs); font-weight: var(--fw-medium);
  padding: 2px 9px; border-radius: 999px; color: var(--text);
  background: var(--sub); border: 1px solid var(--bdr); white-space: nowrap;
}

/* =================== Surface A — contacts grid =================== */
.contacts-controls {
  display: flex; gap: 12px; flex-wrap: wrap; align-items: center;
  margin: 0 0 20px;
}
.contacts-controls .search-field { flex: 1 1 240px; min-width: 200px; }
.contacts-grid {
  display: grid; gap: 18px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
@media (max-width: 1024px) { .contacts-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px)  { .contacts-grid { grid-template-columns: 1fr; } }

.snippet-card {
  background: var(--card); border: 1px solid var(--bdr); border-radius: var(--r);
  padding: 18px; cursor: pointer; transition: border-color .15s, transform .15s;
  display: flex; flex-direction: column; gap: 12px;
  /* border-box: height includes the 36px padding. Sized to fit the worst case —
     head + up to 3 roles + the reserved recent-activity block + footer — without
     clipping, while staying uniform across cards.
     ⚠️ TWO fixed blocks below now spend this budget: .snippet-activity's 92px and
     .snippet-foot's 28px floor. .snippet-bodyhost is the only flexible child, so
     growing either one steals from the role list and clips the third role rather
     than failing visibly. #468 took the footer 18px → 28px and this stayed 324,
     which sliced that row in half (11px clipped, measured) — 336 is 335 plus a
     pixel of slack. Re-measure the worst-case tile if either block changes. */
  height: 336px; overflow: hidden;
}
.snippet-card:hover { border-color: var(--bhi); transform: translateY(-2px); }
.snippet-head { display: flex; gap: 12px; align-items: flex-start; flex: none; }
.snippet-head .avatar-ring { width: 44px; height: 44px; font-size: var(--fs-title); }
.snippet-name { font-size: var(--fs-title); font-weight: var(--fw-bold); color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.snippet-sub  { font-size: var(--fs-sm); color: var(--muted); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* top-right corner: type pills + freshness, pinned right */
.snippet-tr { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; flex: none; max-width: 56%; }
.snippet-types { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.snippet-tr .freshness { font-size: var(--fs-xs); }
/* on dual cards the type pills ARE the lens toggle */
.type-chip.clickable { cursor: pointer; }
.type-chip.is-inactive { opacity: .38; }
.type-chip.clickable:hover { opacity: 1; }

/* Name needs-review chip on contact header and contacts grid cards */
.c-name-review-chip {
  display: inline-flex; align-items: center;
  font-size: var(--fs-eyebrow); font-weight: var(--fw-bold); text-transform: uppercase; letter-spacing: .04em;
  padding: 2px 8px; border-radius: 999px;
  color: var(--amb); background: rgba(251,146,60,.13);
  cursor: pointer;
}
.c-name-review-chip:hover { background: rgba(251,146,60,.22); }

/* "Set type" / "Edit type" chip on the contact header (#510) — opens the manual
   Client / Candidate modal. A real <button>, so it needs the font + background
   reset every other chip gets for free. Sized to match the pill row it sits in
   (.c-tags .type-chip is 22px tall) without borrowing that rule's min-width. */
.c-type-set-chip {
  display: inline-flex; align-items: center; justify-content: center;
  height: 22px; padding: 0 10px; border-radius: 99px; box-sizing: border-box;
  font-family: inherit; font-size: var(--fs-eyebrow); font-weight: var(--fw-bold);
  text-transform: uppercase; letter-spacing: .06em; line-height: 1; white-space: nowrap;
  color: var(--gold); background: var(--gdim);
  border: 1px dashed rgba(255,200,46,.45);
  cursor: pointer;
}
.c-type-set-chip:hover { background: rgba(255,200,46,.18); }

/* flexible middle that holds the signal + role list; clamps so the card stays a fixed height */
.snippet-bodyhost { flex: 1 1 auto; min-height: 0; overflow: hidden; display: flex; flex-direction: column; }
.snippet-body { display: flex; flex-direction: column; gap: 10px; min-height: 0; overflow: hidden; }
.snippet-signal { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; flex: none; }
.snippet-roles { display: flex; flex-direction: column; gap: 4px; min-height: 0; overflow: hidden; }
.snippet-roles-label { font-size: var(--fs-eyebrow); font-weight: var(--fw-bold); text-transform: uppercase; letter-spacing: var(--ls-eyebrow); color: var(--muted); }
.snippet-role { display: flex; align-items: center; gap: 7px; font-size: var(--fs-sm); }
.snippet-role-icon { flex: none; font-size: var(--fs-sm); opacity: .85; }
.snippet-role-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: var(--fw-medium); color: var(--soft); }
.snippet-role .status-pill { flex: none; }
.snippet-roles-empty { font-size: var(--fs-sm); color: var(--muted); }
.snippet-more { font-size: var(--fs-xs); color: var(--gold); }

/* Recent-activity snippet — last 3 interactions (type + date).
   .snippet-bodyhost (flex:1) absorbs the slack above, pinning this block + the
   footer to the bottom. A FIXED height (not min-height) sized for the label + 3
   rows makes every block identical regardless of item count (1–3), so the
   "RECENT ACTIVITY" heading + its top border line up on every card. */
.snippet-activity { margin-top: 8px; border-top: 1px solid var(--sub); padding-top: 8px; flex: none; height: 92px; box-sizing: border-box; overflow: hidden; }
.snippet-activity-label { font-size: var(--fs-eyebrow); font-weight: var(--fw-bold); text-transform: uppercase; letter-spacing: var(--ls-eyebrow); color: var(--muted); margin-bottom: 5px; }
.snippet-activity-row { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; font-size: var(--fs-sm); padding: 1px 0; }
.snippet-activity-text { color: var(--soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.snippet-activity-date { color: var(--muted); font-size: var(--fs-xs); flex: none; }

/* The footer holds icon-only links (#468). A fixed min-height keeps the row the
   same height whether a contact has two icons, one, or none, so the reserved
   activity block above it lands on the same line across the grid. */
.snippet-foot { display: flex; align-items: center; gap: 8px; min-height: 28px; font-size: var(--fs-sm); color: var(--muted); flex: none; }
.snippet-foot a { color: var(--muted); display: inline-flex; align-items: center; gap: 4px; }
.snippet-foot a:hover { color: var(--gold); }
.snippet-foot-icon {
  /* display here rather than inherited from `.snippet-foot a`, so width/height
     apply wherever this class is used rather than only inside the footer. */
  display: inline-flex; align-items: center;
  width: 28px; height: 28px; justify-content: center; flex: none;
  border-radius: var(--rsm); border: 1px solid var(--bdr); background: var(--sub);
  transition: border-color .15s, background .15s, color .15s;
}
.snippet-foot-icon svg { width: 17px; height: 17px; display: block; }
.snippet-foot-icon:hover { border-color: var(--bhi); background: var(--raised); }
/* These are the card's only focusable children, and the card itself has no focus
   style, so without this a keyboard user gets the UA ring on dark navy. Matches
   the gold treatment .status-dropdown-option already uses. */
.snippet-foot-icon:focus-visible {
  outline: none; border-color: var(--gold); color: var(--gold);
  box-shadow: 0 0 0 2px var(--gdim);
}
.snippet-openroles { font-size: var(--fs-sm); color: var(--muted); }

/* =================== Surface B — contact page lenses =================== */
.lens-toggle { display: inline-flex; background: var(--sub); border-radius: var(--rsm); padding: 3px; gap: 2px; }
.lens-toggle button {
  background: transparent; border: none; color: var(--muted); font-family: inherit;
  font-size: var(--fs-sm); font-weight: var(--fw-medium); padding: 5px 14px; border-radius: 4px; cursor: pointer;
}
.lens-toggle button.active { background: var(--card); color: var(--text); }

.how-they-hire { background: var(--raised); border: 1px solid var(--bdr); border-radius: var(--r); padding: 18px 20px; margin-bottom: 20px; }
.how-they-hire h3 { font-size: var(--fs-body); text-transform: uppercase; letter-spacing: .04em; color: var(--gold); margin-bottom: 12px; }
.how-they-hire ul { list-style: none; display: flex; flex-direction: column; gap: 8px; }
.how-they-hire li { padding-left: 16px; position: relative; color: var(--text); font-size: var(--fs-body); }
.how-they-hire li::before { content: '›'; position: absolute; left: 0; color: var(--blu); }

/* Roles section + per-role collapsibles */
.roles-section > h2 { font-size: var(--fs-title); font-weight: var(--fw-bold); margin-bottom: 12px; }
/* ROLES is ONE container box (like the VIDEO ASSESSMENT card): the <details>
   element itself carries the border + lighter background, so opening it grows the
   box down to enclose every role row and closing shrinks it back to just the
   header. overflow: hidden clips the role rows to the box's rounded corners. */
.roles-section {
  background: var(--navy); border: 1px solid var(--bdr);
  border-radius: var(--r); overflow: hidden;
}
/* Roles dropdown header — now a plain bar INSIDE the box (no border/bg of its own).
   align-items: center vertically centers BOTH the title and the chevron on the
   bar's cross-axis, so the arrow always sits dead-center across from the title
   regardless of font/line-height. No manual pixel nudges — those cause drift. */
.roles-section-summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: 10px;
  user-select: none; padding: 14px 18px; transition: background .15s;
}
.roles-section-summary:hover { background: rgba(255,255,255,.03); }
.roles-section-summary::-webkit-details-marker { display: none; }
/* margin: 0 is critical — the base .section-title has margin-bottom: 16px, which
   becomes part of the flex item's box and pushes the text up off-center. Zeroing
   it lets align-items: center put the title dead-center, level with the chevron. */
.roles-section-summary .section-title { font-size: var(--fs-title); font-weight: var(--fw-bold); line-height: 1; margin: 0; }
/* Slim rounded chevron (matches the card-header caret). SVG mask keeps it tintable
   via background-color and lets it rotate cleanly between collapsed/open states.
   margin-left: auto pins it to the right edge; flexbox handles vertical centering. */
.roles-section-summary::after {
  content: ''; margin-left: auto; width: 16px; height: 16px; flex: none;
  background-color: var(--muted);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 6l6 6-6 6'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 6l6 6-6 6'/%3E%3C/svg%3E") center / contain no-repeat;
  transition: transform .15s; transform: rotate(0deg);
}
.roles-section[open] > .roles-section-summary::after { transform: rotate(90deg); }
/* Role rows are children of the ROLES box, so they're inset on both sides (margin
   left/right) and slightly shorter than the parent header — the size step-down +
   inset signals they're collapsible items nested inside ROLES, not siblings. */
.role-collapse { border: 1px solid var(--bdr); border-radius: var(--r); margin: 0 14px 10px; overflow: hidden; background: var(--card); }
.role-collapse:last-child { margin-bottom: 4px; }
.role-collapse.is-closed { opacity: .62; }
.role-collapse > summary {
  list-style: none; cursor: pointer; padding: 11px 14px; display: flex; align-items: center; gap : 12px;
}
.role-collapse > summary::-webkit-details-marker { display: none; }
/* Per-role chevron — same idea as the ROLES group header. margin-left: auto pins
   it right; align-items: center on the summary keeps it level with the pill/title. */
.role-collapse > summary::after {
  content: ''; margin-left: auto; width: 16px; height: 16px; flex: none;
  background-color: var(--muted);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 6l6 6-6 6'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 6l6 6-6 6'/%3E%3C/svg%3E") center / contain no-repeat;
  transition: transform .15s; transform: rotate(0deg);
}
.role-collapse[open] > summary::after { transform: rotate(90deg); }
.role-collapse summary .role-title { font-weight: var(--fw-bold); font-size: var(--fs-lg); }
.role-collapse summary .role-brief { color: var(--muted); font-size: var(--fs-sm); }
.role-collapse .role-body { padding: 4px 16px 16px; border-top: 1px solid var(--bdr); align-items: center; }

/* On phones the summary's status-pill · title · firm can't share one nowrap row —
   the title collapses to ~59px and wraps one word per line. Let the title own the
   first row (with the pill + chevron) and drop the firm onto its own line below. */
@media (max-width: 640px) {
  .role-collapse > summary { flex-wrap: wrap; row-gap: 4px; }
  .role-collapse summary .role-title { flex: 1 1 auto; min-width: 0; }
  .role-collapse summary .role-brief { order: 1; flex: 1 1 100%; }
}

/* Candidate rows inside a role */
.cand-row {
  display: flex; align-items: center; gap: 12px; padding: 9px 0;
  border-bottom: 1px solid var(--sub);
}
.cand-row:last-child { border-bottom: none; }
.cand-row .cand-name { font-weight: var(--fw-medium); font-size: var(--fs-body); flex: 1 1 auto; }
.cand-more { background: none; border: none; color: var(--gold); font-size: var(--fs-sm); cursor: pointer; padding: 8px 0; font-family: inherit; }

/* Atlas / Echo protocol pills — shared definition (ported from roles.html so
   it's defined once). Base = muted/disabled; .ready = green (Atlas);
   .rx-echo.ready = Spark gold (Echo). */
.rx-protocol {
  font-size: var(--fs-eyebrow); font-weight: var(--fw-bold); letter-spacing: var(--ls-eyebrow); text-transform: uppercase;
  padding: 6px 13px; border-radius: 999px; white-space: nowrap; font-family: inherit;
  border: 1px solid var(--bdr); color: var(--muted); background: transparent;
  opacity: .5; cursor: not-allowed; transition: all .15s;
}
.rx-protocol.ready {
  opacity: 1; color: var(--grn); cursor: pointer;
  border-color: rgba(74,222,128,.55); background: rgba(74,222,128,.10);
  box-shadow: 0 0 10px rgba(74,222,128,.35);
}
.rx-protocol.ready:hover { background: rgba(74,222,128,.16); box-shadow: 0 0 14px rgba(74,222,128,.5); }
/* Echo gets the Spark gold identity instead of green */
.rx-protocol.rx-echo.ready {
  color: var(--gold);
  border-color: rgba(255,200,46,.55); background: rgba(255,200,46,.12);
  box-shadow: 0 0 10px rgba(255,200,46,.35);
}
.rx-protocol.rx-echo.ready:hover { background: rgba(255,200,46,.18); box-shadow: 0 0 14px rgba(255,200,46,.5); }
.rx-protocol.pill-sm { font-size: var(--fs-xs); padding: 3px 10px; }

/* Status pills for roles */
.status-pill { display:inline-flex; align-items:center; font-size:var(--fs-xs); font-weight:var(--fw-bold); padding:2px 9px; border-radius:999px; }
.status-pill.st-recruiting { color: var(--grn); background: rgba(74,222,128,.12); }
.status-pill.st-onhold     { color: var(--amb); background: rgba(251,146,60,.12); }
.status-pill.st-placed     { color: var(--blu); background: rgba(96,165,250,.12); }
.status-pill.st-closed, .status-pill.st-cancelled { color: var(--muted); background: var(--sub); }

/* Spark placement history — contract end flagging */
.placement-row { display:flex; align-items:center; gap:10px; padding:8px 0; border-bottom:1px solid var(--sub); font-size:var(--fs-body); }
.placement-row .end-soon { color: var(--red); font-weight: 700; }

/* Deferred export actions */
.btn-soon { opacity: .5; cursor: not-allowed; }
.btn-soon::after { content: ' · soon'; font-size: var(--fs-eyebrow); opacity: .8; }


/* =========================================================================
   CONTACT PAGE — full profile content (#7): header actions, status line,
   what-we-know, skills, key responses, applied-to, placement, activity, timeline
   ========================================================================= */

/* header: type pills + action icons top-right, status line under the name */
.c-actions { display: flex; align-items: center; gap: 10px; justify-content: flex-end; }
.c-action-icons { display: flex; gap: 6px; }
.c-icon-btn {
  width: 30px; height: 30px; border-radius: var(--rsm); border: 1px solid var(--bdr);
  background: var(--card); color: var(--text); display: inline-flex; align-items: center; justify-content: center;
  font-size: var(--fs-lg); cursor: pointer; transition: border-color .15s, color .15s;
}
.c-icon-btn:hover { border-color: var(--bhi); color: var(--gold); }
.c-icon-btn.is-disabled { opacity: .4; cursor: not-allowed; }
.status-line { display: flex; align-items: center; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.status-note { font-size: var(--fs-sm); color: var(--muted); }
.status-pill.st-active { color: var(--grn); background: transparent; border: 1px solid rgba(74,222,128,.45); }
.status-pill.st-completed { color: var(--grn); background: transparent; border: 1px solid rgba(74,222,128,.45); }
.status-pill.st-ending { color: var(--red); background: rgba(248,113,113,.12); border: 1px solid rgba(248,113,113,.45); }

/* section labels + source tags */
.section-label { font-size: var(--fs-eyebrow); font-weight: var(--fw-bold); text-transform: uppercase; letter-spacing: var(--ls-eyebrow); color: var(--muted); margin-bottom: 10px; display: flex; align-items: center; gap: 8px; }
.src-tag { font-size: var(--fs-eyebrow); font-weight: var(--fw-bold); letter-spacing: .04em; color: var(--muted); background: var(--sub); border-radius: 4px; padding: 1px 6px; }

/* what we know */
.wwk-card { background: var(--raised); border: 1px solid var(--bdr); border-radius: var(--r); padding: 18px 20px; }
.wwk-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 16px; }
.wwk-cell .wwk-label, .wwk-block .wwk-label { display: flex; align-items: center; gap: 6px; font-size: var(--fs-eyebrow); font-weight: var(--fw-bold); text-transform: uppercase; letter-spacing: var(--ls-eyebrow); color: var(--muted); margin-bottom: 4px; }
.wwk-value { font-size: var(--fs-lg); color: var(--text); }
.wwk-block { margin-top: 16px; }

/* skills */
.skill-chips { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.skill-chip { font-size: var(--fs-sm); color: var(--soft); border: 1px solid var(--bdr); border-radius: 999px; padding: 5px 13px; }
.more-link { background: none; border: none; color: var(--gold); font-size: var(--fs-sm); cursor: pointer; font-family: inherit; padding: 4px; }

/* key responses */
.kr-card { background: var(--raised); border: 1px solid var(--bdr); border-radius: var(--r); padding: 14px 16px; margin-bottom: 10px; font-size: var(--fs-body); color: var(--soft); line-height: var(--lh-relaxed); }

/* applied to — each role is its own bubble block */
.applied-row { display: flex; align-items: center; gap: 12px; padding: 14px 16px; background: var(--raised); border: 1px solid var(--bdr); border-radius: var(--r); margin-bottom: 10px; }
/* inside the Applied-to dropdown box, inset rows to match the client role rows */
.roles-section .applied-row { margin: 0 14px 10px; }
.applied-name { flex: 1 1 auto; font-weight: var(--fw-medium); font-size: var(--fs-lg); color: var(--text); }
a.applied-link { transition: color .15s; }
a.applied-link:hover { color: var(--gold); text-decoration: underline; }

/* New-contact modal (Surface A "+ New contact") */
.nc-backdrop { position: fixed; inset: 0; background: rgba(3,10,22,.66); display: flex; align-items: center; justify-content: center; z-index: 100; padding: 20px; }
.nc-modal { background: var(--card); border: 1px solid var(--bdr); border-radius: var(--r); width: 100%; max-width: 440px; padding: 24px; box-shadow: 0 20px 60px rgba(0,0,0,.5); }
.nc-title { font-size: var(--fs-h2); font-weight: var(--fw-heavy); }
.nc-sub { font-size: var(--fs-sm); color: var(--muted); margin: 4px 0 18px; }
.nc-row { display: flex; gap: 12px; }
.nc-row .nc-field { flex: 1; }
.nc-field { margin-bottom: 14px; }
.nc-field label { display: block; font-size: var(--fs-eyebrow); font-weight: var(--fw-bold); letter-spacing: var(--ls-eyebrow); text-transform: uppercase; color: var(--muted); margin-bottom: 6px; }
.nc-field input { width: 100%; background: var(--navy); border: 1px solid var(--bdr); border-radius: var(--rsm); padding: 10px 12px; color: var(--text); font-size: var(--fs-lg); font-family: inherit; }
.nc-field input:focus { outline: none; border-color: var(--bhi); }
.nc-field input::placeholder { color: var(--muted); }
/* Guard: the rule above is meant for text inputs. A checkbox or radio dropped
   into a .nc-field would stretch to the full row and shove its own label to the
   far right — exactly what happened to the "This name is correct as it is" row.
   Resets all four declarations, not just width: with width:auto the 10px padding
   would sit outside the intrinsic box (border-box only applies to a specified
   width), leaving a native checkbox drawn on a navy rounded panel. */
.nc-field input[type="checkbox"], .nc-field input[type="radio"] {
  width: auto;
  padding: 0;
  border: 0;
  background: none;
}

/* Checkbox row in a modal. Its own block rather than a .nc-field, because
   .nc-field label is an uppercase letter-spaced eyebrow — right for a field
   caption above an input, wrong for a sentence sitting beside a checkbox. */
.nc-check { margin-bottom: 14px; }
.nc-check label {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  margin-bottom: 0;
  font-size: var(--fs-body);
  font-weight: var(--fw-medium);
  letter-spacing: normal;
  text-transform: none;
  color: var(--soft);
}
.nc-check input[type="checkbox"] {
  width: 15px;
  height: 15px;
  flex: 0 0 auto;
  margin: 0;
  padding: 0;
  accent-color: var(--gold);
}
.nc-err { font-size: var(--fs-sm); color: var(--red); margin: -4px 0 10px; min-height: 14px; }
.nc-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 4px; }
.nc-btn { font-family: inherit; font-size: var(--fs-body); font-weight: var(--fw-medium); padding: 9px 16px; border-radius: var(--rsm); cursor: pointer; border: 1px solid var(--bdr); background: var(--navy); color: var(--text); transition: border-color .15s; }
.nc-btn:hover { border-color: var(--bhi); }

/* placement history */
.placement-card { background: var(--raised); border: 1px solid var(--bdr); border-radius: var(--r); padding: 14px 16px; margin-bottom: 10px; }
.placement-card.ending-soon { border-color: rgba(248,113,113,.5); }
.placement-head { display: flex; align-items: center; gap: 12px; }
.placement-title { flex: 1 1 auto; font-weight: var(--fw-bold); font-size: var(--fs-lg); color: var(--text); }
.placement-meta { font-size: var(--fs-sm); color: var(--muted); margin-top: 4px; }

/* activity snapshot */
.snap-row { display: flex; justify-content: space-between; align-items: center; padding: 12px 0; border-bottom: 1px solid var(--sub); font-size: var(--fs-body); }
.snap-key { color: var(--muted); }
.snap-val { font-weight: var(--fw-bold); color: var(--text); }
.snap-val.snap-green { color: var(--grn); }

/* timeline */
.tl-help { font-size: var(--fs-sm); color: var(--muted); margin-bottom: 10px; }
.tl-row { display: flex; align-items: center; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--sub); font-size: var(--fs-body); }
/* Badge fills stay inside the Spark palette (blue/gold/amber/green/red +
   neutral). Where two badge types must share a hue, a lighter .16 fill vs a
   heavier .28 fill + border pulls them apart, so no two variants collapse to the
   same swatch at a glance (issue #75). Reserve the 1px border on every badge so
   bordered and borderless variants stay the same height. */
.tl-badge { font-size: var(--fs-eyebrow); font-weight: var(--fw-heavy); letter-spacing: .05em; padding: 2px 7px; border-radius: 4px; border: 1px solid transparent; flex: none; }
/* Blue — email (light) vs intake call (heavy + border). */
.tl-email { background: rgba(96,165,250,.16); color: var(--blu); }
.tl-ic { background: rgba(96,165,250,.28); color: var(--blu); border-color: rgba(96,165,250,.5); }
/* Gold — client-relationship conversations (Iris "client" stage is gold):
   check-in (light) vs debrief (heavy + border). */
.tl-chk { background: var(--gdim); color: var(--gold); border-color: var(--bhi); }
.tl-dbf { background: rgba(255,200,46,.22); color: var(--gold); border-color: var(--gold); }
/* Amber — screening call (light) vs general meeting (heavy + border). */
.tl-sht { background: rgba(251,146,60,.16); color: var(--amb); }
.tl-meet { background: rgba(251,146,60,.28); color: var(--amb); border-color: rgba(251,146,60,.5); }
/* Green — candidate materials: resume (light) vs candidate transcript (heavy + border). */
.tl-cv { background: rgba(74,222,128,.16); color: var(--grn); }
.tl-cand { background: rgba(74,222,128,.28); color: var(--grn); border-color: rgba(74,222,128,.5); }
/* Red — internal Spark only. */
.tl-int { background: rgba(248,113,113,.16); color: var(--red); }
/* Neutral — low-signal events + the OTHER category. */
.tl-booked { background: var(--sub); color: var(--muted); }
.tl-event { background: var(--sub); color: var(--muted); }
.tl-other { background: var(--sub); color: var(--muted); }
/* Neutral, dashed — the DOC fallback for an uncategorized document. */
.tl-doc { background: transparent; color: var(--muted); border-color: rgba(255,255,255,.22); border-style: dashed; }
.tl-date { color: var(--muted); flex: none; min-width: 92px; }
.tl-link { color: var(--blu); }
.tl-link.tl-plain { color: var(--text); }
.tl-type { margin-left: auto; color: var(--muted); font-size: var(--fs-sm); }

/* On phones the badge + 92px date + right-pinned type leave the title ~85px, so it
   wraps a word per line. Break the row: badge · date · type on a meta line, and the
   title on its own full-width line below. */
@media (max-width: 640px) {
  .tl-row { flex-wrap: wrap; row-gap: 3px; }
  .tl-row .tl-date { min-width: 0; }
  .tl-row .tl-link { flex: 1 1 100%; order: 3; }
  .tl-row .tl-type { order: 2; }
}

/* ==========================================================================
   SparkLive — shared loading + live-update UI (spark-live.js)
   All motion wrapped in prefers-reduced-motion fallbacks.
   Palette: existing CSS custom properties only — no new colours.
   ========================================================================== */

/* --- Skeleton shimmer --- */
@keyframes sparkShimmer {
  0%   { background-position: -200% 0; }
  100% { background-position:  200% 0; }
}
.spark-skeleton {
  display: block;
  border-radius: var(--rsm);
  background: linear-gradient(90deg,
    rgba(255,255,255,.06) 25%,
    rgba(255,255,255,.12) 50%,
    rgba(255,255,255,.06) 75%);
  background-size: 200% 100%;
  animation: sparkShimmer 1.6s ease-in-out infinite;
  min-height: 14px;
}
@media (prefers-reduced-motion: reduce) {
  .spark-skeleton { animation: none; background: rgba(255,255,255,.07); }
}

/* --- Inline spinner (gold ring) --- */
@keyframes sparkSpin {
  to { transform: rotate(360deg); }
}
.spark-spinner {
  display: inline-block;
  width: 18px; height: 18px;
  border: 2px solid rgba(255,200,46,.25);
  border-top-color: var(--gold);
  border-radius: 50%;
  animation: sparkSpin .75s linear infinite;
  vertical-align: middle;
  flex-shrink: 0;
}
.spark-spinner--sm {
  width: 13px; height: 13px;
  border-width: 2px;
}
@media (prefers-reduced-motion: reduce) {
  .spark-spinner { animation: none; border-color: var(--gold); }
}

/* --- Shared fixed wrapper: jobtray stacks ABOVE toast-stack --- */
.spark-live-stack {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 10090;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: calc(100vw - 48px);
  pointer-events: none;
}
.spark-live-stack > * { pointer-events: auto; }

/* --- Toast stack (children of .spark-live-stack, no longer fixed) --- */
.spark-toast-stack {
  position: static;
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
  max-width: 360px;
  width: 100%;
  /* z-index handled by parent wrapper */
}
.spark-toast {
  background: var(--card, #0d2a4f);
  border: 1px solid var(--bdr);
  border-left: 3px solid var(--gold);
  color: var(--text);
  border-radius: var(--r);
  padding: 11px 14px;
  font-size: var(--fs-sm);
  line-height: var(--lh-snug);
  box-shadow: 0 8px 28px rgba(0,0,0,.45);
  pointer-events: auto;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 10px;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity .25s ease, transform .25s ease;
}
.spark-toast.spark-toast--visible {
  opacity: 1;
  transform: translateY(0);
}
.spark-toast.spark-toast--ok  { border-left-color: var(--grn); }
.spark-toast.spark-toast--err { border-left-color: var(--red); }
.spark-toast-msg { flex: 1 1 auto; }
.spark-toast-action {
  flex: 0 0 auto;
  background: transparent;
  border: 1px solid var(--bdr);
  color: var(--gold);
  font-family: inherit;
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  padding: 4px 10px;
  border-radius: var(--rsm);
  cursor: pointer;
  white-space: nowrap;
}
.spark-toast-action:hover { border-color: var(--gold); background: var(--gdim); }
@media (prefers-reduced-motion: reduce) {
  .spark-toast { transition: none; opacity: 1; transform: none; }
}

/* --- Job tray (order:-1 places it above toast-stack regardless of DOM append order) --- */
.spark-jobtray {
  position: static;
  order: -1;  /* flex child: renders first (top/farther from bottom) in .spark-live-stack */
  max-width: 360px;
  width: 100%;
  /* z-index and position handled by parent wrapper */
}
.spark-jobtray-inner {
  background: var(--card, #0d2a4f);
  border: 1px solid rgba(255,200,46,.28);
  border-radius: var(--r);
  padding: 11px 14px 9px;
  box-shadow: 0 8px 28px rgba(0,0,0,.45);
  /* gap on .spark-live-stack handles spacing between jobtray and toast-stack */
}
.spark-jobtray-item {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 6px;
}
.spark-jobtray-label {
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--fs-sm);
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.spark-jobtray-bar {
  flex: 1 0 100%;
  height: 3px;
  background: rgba(255,200,46,.15);
  border-radius: 2px;
  overflow: hidden;
  margin-top: 2px;
}
.spark-jobtray-fill {
  height: 100%;
  background: var(--gold);
  border-radius: 2px;
  transition: width .4s ease;
}
.spark-jobtray-note {
  font-size: var(--fs-eyebrow);
  color: var(--muted);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  margin-top: 4px;
}
@media (prefers-reduced-motion: reduce) {
  .spark-jobtray-fill { transition: none; }
}

/* ── Themed dropdown widget (#448, relocated here by #462) ──────────────────
   Lived in pipeline-page.css, which only roles.html loads — so a <select> on
   any other page could not be themed with it, and web/js/role-picker.js grew a
   second, visually different theme of its own by injecting CSS from JS. That is
   the whole reason two themed dropdowns existed. shell.css is the one
   stylesheet every page links, so the widget belongs here and the pages keep
   only what is theirs: .toolbar-row sizing and the per-filter widths stay in
   pipeline-page.css and still win, being both later and more specific.

   Driven by window.SparkDropdown (web/js/dropdown.js). Markup contract is
   documented there. tests/statusDropdownOpenState.test.js pins the open-state
   fill AND blur together — they must match .status-dropdown-menu or the pill
   and the panel render as two shades. */

/* Once role-picker.js has enhanced a <select> it is a value holder only — the
   themed trigger beside it is the control. The module hides it with an inline
   `display:none`; stating the invariant here too means a native control can
   never be painted next to its own replacement if that inline style is ever
   lost. Keyed on the enhanced marker on purpose: an UNenhanced select still
   gets its documented fallback styling (see the .rx-control note in
   pipeline.css) for when the module is absent or stale-cached. */
select[data-rp-enhanced] { display: none; }

.status-dropdown {
  position: relative;
  flex-shrink: 0;
  width: 176px;
  z-index: 1;
}
.status-dropdown.open {
  z-index: 10001;
}
.status-dropdown-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  box-sizing: border-box;
  /* Same fill as .search-field beside it (#448) — this used to be .85, which read
     as a heavier control than its own neighbour in one toolbar row. */
  background: rgba(7,24,46,.55);
  border: 1px solid var(--bdr);
  border-radius: 999px;
  /* 12px block padding, not 11px: 13px text at 1.2 line-height + 24 + border
     lands on 41.2px, which is exactly .search-field's height. At 11px the row
     was ragged — 39.6px pills against a 41.2px search field (#448). */
  padding: 12px 14px 12px 16px;
  font-size: var(--fs-body);
  line-height: 1.2;
  color: var(--text);
  font-family: inherit;
  cursor: pointer;
  text-align: left;
  transition: border-color .2s, border-radius .15s, background .2s;
  box-shadow: inset 0 2px 8px rgba(0,0,0,.2);
}
/* The one state the widget was missing (#466 review). role-picker's refresh()
   mirrors a hidden <select>'s `disabled` onto the trigger, because the select
   itself is display:none and guards nothing — but nothing painted it, so an
   in-flight save (index.html disables the feedback status picker for exactly
   that reason) looked live and silently swallowed clicks. Every native select
   this replaced dimmed here. */
.status-dropdown-trigger:disabled {
  opacity: .5;
  cursor: default;
}

/* Keyboard focus (#512). Nothing styled this trigger's focus, so Chromium's own
   `outline: auto` painted it — on Windows a thick blue/white OS ring around a
   navy-and-gold pill, which read on Recruiting as a broken Windows control
   rather than a focused one ("a thick blue OS focus ring" on Recruiter, which
   is the trigger, not the hidden native <select>). Same gold indicator the rows
   inside the panel already use, so this adds a state, not a colour.
   :focus-visible only: SparkDropdown returns focus to the trigger after a pick,
   and a mouse user must not be left with a ring they did not ask for. */
.status-dropdown-trigger:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}
.status-dropdown-label { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.status-dropdown-chevron {
  display: inline-flex;
  flex-shrink: 0;
  color: var(--muted);
  transition: transform .25s cubic-bezier(.34,1.56,.64,1), color .2s;
}
/* Open state (#448). #436 gave this a full-strength gold border on every edge,
   which was the only 100%-gold outline on the page — gold is a fill (+ New role)
   or an accent (ticks, focus rings) everywhere else, so a bright cage read as
   "selected" or "errored" rather than "open". The open affordance is now the
   rotated gold chevron plus the panel itself; the border stays the same hairline
   the resting pill uses, one step up in opacity so the seam stays visible. */
.status-dropdown.open .status-dropdown-trigger {
  border-color: rgba(255,200,46,.28);
  /* Background AND blur must both match .status-dropdown-menu — #436 made the
     pill and the panel one surface, and tests/statusDropdownOpenState.test.js
     pins both halves. Same fill with the blur on only one side still renders as
     two shades, since only one element would be compositing what sits behind it.
     (Note .toolbar-band is a backdrop root — `isolation: isolate` plus its own
     blur — so what these two sample is the band's contents, not the board below.
     That is fine for the goal here, which is that they sample the same thing.) */
  background: rgba(7,24,46,.88);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-radius: 999px 999px 0 0;
  /* No bottom edge and no inset shadow while open: the panel paints over this
     row anyway (it sits at top: calc(100% - 1px)), and a dark inset at the seam
     works against the pill and panel reading as one surface. */
  border-bottom-color: transparent;
  box-shadow: none;
}
.status-dropdown.open .status-dropdown-chevron {
  transform: rotate(180deg);
  color: var(--gold);
}

.status-dropdown-menu {
  position: absolute;
  top: calc(100% - 1px);
  left: 0;
  width: 100%;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  list-style: none;
  /* Glass, not a slab (#448). The whole toolbar is translucent over a blurred
     .toolbar-band — search field and view toggle both sit on rgba(7,24,46,.55) —
     and this panel was the one fully opaque surface in the group, so it stopped
     belonging to the band it hangs off. Denser than the resting controls because
     option text has to stay readable; identical to the OPEN trigger because the
     two are meant to read as one surface. */
  background: rgba(7,24,46,.88);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid rgba(255,200,46,.28);
  border-top: none;
  /* Match the RESTING pill's corners (#436). The trigger measures 39.6px tall
     (11 + 11 padding + 2 border + 13 × 1.2 line), so the closed pill's 999px
     radius clamps to ~19.8px — hence 19px here. The old var(--r) (10px) left a
     round-topped, boxy-bottomed shape that didn't match the resting state.
     Note the OPEN trigger's own top corners clamp to the full height rather than
     half it (radius scaling is per side-pair), so it reads dome-topped while
     open — matching the closed pill is what the issue asked for. */
  border-radius: 0 0 19px 19px;
  box-shadow: 0 12px 32px rgba(0,0,0,.45);
  overflow: hidden;
  z-index: 10002;
}
.status-dropdown-menu[hidden] { display: none; }
.status-dropdown-option {
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: 10px 16px;
  border: none;
  background: transparent;
  color: var(--text);
  font-family: inherit;
  font-size: var(--fs-body);
  line-height: 1.2;
  text-align: left;
  cursor: pointer;
  transition: background .12s, color .12s;
}
/* Gold, not a solid blue fill (#436). The open trigger already goes gold, the
   tick is gold, and every other active control in this chrome uses the gold
   tint — a flat --blu row with white text was the only thing on the page
   painting a selection that way, which is what made the open menu read as a
   different design system from its own trigger. */
.status-dropdown-option:hover,
.status-dropdown-option:focus {
  outline: none;
  background: var(--sub);
  color: var(--text);
}
.status-dropdown-option.is-selected {
  background: var(--gdim);
  color: var(--gold);
  font-weight: var(--fw-bold);
}
.status-dropdown-option.is-selected:hover,
.status-dropdown-option.is-selected:focus {
  background: rgba(255,200,46,.18);
  color: var(--gold);
}
/* Keyboard focus ring — REQUIRED, not decoration. `outline: none` above is
   inherited from the original rule, and the old flat --blu fill was doing double
   duty as the focus indicator; the quieter hover tint that replaced it is only
   ~1.2:1 against a resting row, and on an already-selected row focus would be
   undetectable. This menu is genuinely driven by keyboard — roles.html
   deliberately restores focus to an option after every toggle rebuild
   (`refocus.focus()`), so it hands focus to these rows by design.
   Inset because the rows are full-bleed inside an overflow:hidden panel, where
   an outer ring would be clipped. Matches the file's focus idiom elsewhere
   (gold + var(--gdim) ring on .field input / .role-end-input). */
.status-dropdown-option:focus-visible {
  box-shadow: inset 0 0 0 2px var(--gold);
}

.status-dropdown-option.sd-multi { padding-left: 10px; }
.status-dropdown-option .sd-tick {
  display: inline-block;
  width: 16px;
  color: var(--gold);
  font-weight: var(--fw-bold);
}
.status-dropdown-option.sd-all { padding-left: 26px; border-bottom: 1px solid var(--bdr); }

.status-dropdown-option .rd-count {
  float: right;
  margin-left: 10px;
  color: var(--muted);
}
.status-dropdown-option:hover .rd-count,
.status-dropdown-option:focus .rd-count { color: var(--soft); }
.status-dropdown-option.is-selected .rd-count { color: rgba(255,200,46,.75); }

/* The widget moved here (#462) but its motion suppression did not: the blanket
   `*` reduced-motion reset lives in pipeline-page.css, which only roles.html and
   my-activity.html carry. So the springy chevron overshoot and the fill fades
   would run for a reduced-motion user on every page that links only shell.css —
   measured at 0.25s / 0.2s / 0.12s with the page sheet stripped. Scoped to the
   widget rather than adding another blanket reset here, so the suppression
   travels with the thing it belongs to instead of depending on each page
   happening to have a reset of its own. Found in #463 review. */
@media (prefers-reduced-motion: reduce) {
  .status-dropdown-trigger,
  .status-dropdown-chevron,
  .status-dropdown-option { transition: none; }
}

/* Visually hidden, exposed to screen readers (#435, moved here in #499).
   role-picker.js writes every themed dropdown's accessible name into a span
   with this class. That module runs on index.html, my-activity.html,
   contact.html and contacts.html as well as roles.html, but the rule used to
   live in pipeline-funnel.css — which only roles.html links — so on every other
   page the name rendered as visible text inside the trigger. It belongs here,
   with the rest of what every page needs. Also used by the funnel card's HM row,
   which is why the name is `fc-`-prefixed. */
.fc-hm-role {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
