/* ============================================
   Ops Hub — Studio SaaS Components
   Extracted from: static/prototypes/proto-3b-studio-saas.html
   Requires: tokens.css loaded first.
   Every color here is a var(--token) — no raw hex.
   Self-contained reusable patterns mirroring the approved prototype.
   ============================================ */

/* --------------------------------------------
   Base / resets the prototype relies on
   -------------------------------------------- */
.mono {
  font-family: var(--font-mono);
  font-feature-settings: 'tnum' 1;
}

/* ============================================
   APP SHELL
   ============================================ */

/* -- Sidebar (desktop, >= 720px) -- */
.sidebar {
  display: none; /* shown via media query in app layout */
  position: fixed;
  top: 0; left: 0; bottom: 0;
  width: var(--sidebar-w);
  padding: var(--sp-8) var(--sp-6);
  background: var(--surface);
  border-right: 1px solid var(--border);
  flex-direction: column;
  z-index: 30;
}

.sidebar__brand {
  display: flex; align-items: center; gap: 0.625rem;
  padding: 0 var(--sp-3) var(--sp-8);
}

/* Brand mark — dark rounded square with initials */
.sidebar__mark {
  display: grid; place-items: center;
  width: 32px; height: 32px;
  border-radius: var(--r-md);
  background: var(--ink-900); color: var(--white);
  font-size: 0.78rem; font-weight: var(--weight-bold); letter-spacing: var(--tracking-mono);
  flex: 0 0 auto;
}
.sidebar__name {
  font-size: var(--text-2xl); font-weight: var(--weight-semibold);
  color: var(--ink-900); letter-spacing: var(--tracking-tight);
}

.sidebar__nav { display: flex; flex-direction: column; gap: 2px; }

/* Nav link + states */
.navlink {
  display: flex; align-items: center; gap: var(--sp-4);
  padding: 0.625rem var(--sp-4);
  border-radius: var(--r-md);
  color: var(--ink-600); font-weight: var(--weight-medium); font-size: var(--text-xl);
  transition: background var(--ease-default), color var(--ease-default);
}
.navlink:hover { background: var(--surface-2); color: var(--ink-800); }
.navlink.is-active {
  background: var(--accent-soft);
  color: var(--accent-strong);
  font-weight: var(--weight-semibold);
}
/* Locked nav item — a future-phase tab shown but unreachable until its lifecycle
   phase opens (the portal's hard gating). Grayed + unclickable. The .is-active
   reset is explicit so a locked item can never also read as the live/active tab. */
.navlink.is-locked {
  opacity: 0.4;
  pointer-events: none;
  cursor: not-allowed;
}
.navlink.is-locked.is-active {
  background: transparent;
  color: var(--ink-600);
  font-weight: var(--weight-medium);
}
.navlink svg { flex: none; }

/* Sidebar foot — date + profile */
.sidebar__foot { margin-top: auto; padding: var(--sp-4) var(--sp-3) 0; }
.sidebar__date {
  font-family: var(--font-mono);
  font-size: var(--text-2xs); font-weight: var(--weight-medium); letter-spacing: var(--tracking-date);
  color: var(--ink-400);
  padding-bottom: 0.85rem; margin-bottom: 0.85rem;
  border-bottom: 1px solid var(--border-soft);
}
.sidebar__profile { display: flex; align-items: center; gap: 0.6rem; }
.sidebar__profile .avatar { width: 30px; height: 30px; font-size: var(--text-2xs); }
.sidebar__who { display: flex; flex-direction: column; line-height: var(--leading-snug); min-width: 0; }
.sidebar__who b { font-size: var(--text-lg); font-weight: var(--weight-semibold); color: var(--ink-800); }
.sidebar__who span { font-size: var(--text-xs); color: var(--ink-400); }

/* -- Mobile top bar (< 720px) -- */
.topbar {
  display: none; /* shown via media query in app layout */
  align-items: center; gap: 0.65rem;
  padding: calc(env(safe-area-inset-top) + 0.75rem) var(--sp-6) var(--sp-4);
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: saturate(180%) blur(12px);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 20;
}
.topbar__mark {
  display: grid; place-items: center;
  width: 28px; height: 28px;
  border-radius: var(--r-sm);
  background: var(--ink-900); color: var(--white);
  font-size: var(--text-xs); font-weight: var(--weight-bold);
}
.topbar__title {
  font-size: var(--text-3xl); font-weight: var(--weight-bold);
  color: var(--ink-900); letter-spacing: var(--tracking-tight);
}

/* -- Mobile bottom nav (< 720px) -- */
.bottomnav {
  display: none; /* shown via media query in app layout */
  position: fixed; left: 0; right: 0; bottom: 0;
  height: calc(var(--bottomnav-h) + env(safe-area-inset-bottom));
  padding-bottom: env(safe-area-inset-bottom);
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: saturate(180%) blur(12px);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  border-top: 1px solid var(--border);
  z-index: 30;
}
.bottomnav__link {
  flex: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  color: var(--ink-400); font-size: 11px; font-weight: var(--weight-semibold);
}
.bottomnav__link.is-active { color: var(--accent-strong); }
/* Locked future-phase tab on mobile — mirrors .navlink.is-locked (hard gating). */
.bottomnav__link.is-locked { opacity: 0.4; pointer-events: none; cursor: not-allowed; }

/* -- Main + view container -- */
.main { min-height: 100vh; }
.view {
  max-width: var(--view-max);
  margin: 0 auto;
  padding: var(--sp-12) var(--sp-10) 5rem;
}

/* ============================================
   VIEW HEADER + CONTROLS
   ============================================ */
.view-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-6); margin-bottom: var(--sp-9); flex-wrap: wrap;
}
.view-head h2 {
  font-size: var(--text-h2); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tightest); color: var(--ink-900);
}
.view-head__ctl { display: flex; align-items: center; gap: var(--sp-4); }

/* -- Segmented control + active -- */
.seg {
  display: flex; gap: 2px;
  background: var(--surface-2); padding: 3px; border-radius: var(--r-md);
}
.seg__opt {
  font: inherit; font-size: var(--text-base); font-weight: var(--weight-medium);
  padding: 0.32rem var(--sp-3); border-radius: 7px;
  border: none; background: transparent; color: var(--ink-600); cursor: pointer;
  transition: background var(--ease-default), color var(--ease-default);
}
.seg__opt.is-active {
  background: var(--surface); color: var(--ink-900); box-shadow: var(--shadow-sm);
}
.seg__opt:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Icon-only option (e.g. the Gallery/Calendar view switch): glyph centered, base padding. */
.seg__opt--icon { display: inline-flex; align-items: center; justify-content: center; }
.seg__opt--icon svg { width: 16px; height: 16px; display: block; }

/* ============================================
   BUTTONS
   ============================================ */
.btn-primary {
  font: inherit; font-size: var(--text-lg); font-weight: var(--weight-medium);
  display: inline-flex; align-items: center; gap: 0.35rem;
  padding: var(--sp-3) 0.95rem;
  background: var(--ink-900); color: var(--white);
  border: none; border-radius: var(--r-md); cursor: pointer;
  transition: opacity var(--ease-default), transform var(--ease-fast);
}
.btn-primary:hover { opacity: 0.88; }
.btn-primary:active { transform: translateY(1px); }
.btn-primary svg { width: 13px; height: 13px; }

/* Secondary / ghost button — outlined neutral, matching the shell's restraint */
.btn-secondary {
  font: inherit; font-size: var(--text-lg); font-weight: var(--weight-medium);
  display: inline-flex; align-items: center; gap: 0.35rem;
  padding: var(--sp-3) 0.95rem;
  background: var(--surface); color: var(--ink-800);
  border: 1px solid var(--border); border-radius: var(--r-md); cursor: pointer;
  transition: background var(--ease-default), border-color var(--ease-default), color var(--ease-default);
}
.btn-secondary:hover { background: var(--surface-2); border-color: var(--border-strong); }
.btn-secondary:active { transform: translateY(1px); }
.btn-secondary svg { width: 13px; height: 13px; }

/* ============================================
   SECTION LABELS
   ============================================ */
.section-label {
  font-family: var(--font-mono);
  font-size: var(--text-2xs); font-weight: var(--weight-medium); letter-spacing: var(--tracking-label);
  text-transform: uppercase; color: var(--ink-400);
  margin: 0 0 var(--sp-5);
}

/* ============================================
   STEP INDICATOR — "Step N of 3" + progress dots
   Lightweight onboarding progress marker: a mono label + a row of dots
   (done = accent, current = accent-strong, upcoming = border-strong). Token-only.
   ============================================ */
.step-indicator {
  display: flex; align-items: center; gap: var(--sp-3);
  margin-bottom: var(--sp-6);
}
.step-indicator__label {
  font-family: var(--font-mono);
  font-size: var(--text-2xs); font-weight: var(--weight-medium); letter-spacing: var(--tracking-label);
  text-transform: uppercase; color: var(--ink-400);
}
.step-indicator__dots { display: flex; align-items: center; gap: var(--sp-2); }
.step-indicator__dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--border-strong);
}
.step-indicator__dot.is-done { background: var(--accent); }
.step-indicator__dot.is-current { background: var(--accent-strong); }

/* ============================================
   PILL SYSTEM
   Base pill + each data-type variant.
   ============================================ */
.pill {
  display: inline-flex; align-items: center; gap: 0.35rem;
  font-size: var(--text-sm); font-weight: var(--weight-medium); line-height: 1;
  padding: 0.32rem var(--sp-3);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  color: var(--ink-600);
  white-space: nowrap;
}
.pill svg { width: 12px; height: 12px; flex: 0 0 auto; }

/* Location pill — flag image + place name */
.pill--loc { background: var(--surface-2); color: var(--ink-800); padding-left: 0.32rem; }
.pill--loc img {
  width: 18px; height: 13px; border-radius: 2.5px; display: block;
  object-fit: cover; background: var(--surface-2);
  box-shadow: var(--flag-ring);
}

/* Dates pill — calendar icon + date range, muted icon */
.pill--dates svg { color: var(--ink-400); }

/* Type pills — soft tint background keyed to trip type, icon = currentColor */
.pill--type-shoot    { background: var(--type-shoot-bg);    color: var(--type-shoot); }
.pill--type-work     { background: var(--type-work-bg);     color: var(--type-work); }
.pill--type-vacation { background: var(--type-vacation-bg); color: var(--type-vacation); }
.pill--type-transit  { background: var(--type-transit-bg);  color: var(--type-transit); }
.pill--type-shoot svg, .pill--type-work svg,
.pill--type-vacation svg, .pill--type-transit svg { color: currentColor; }

/* Episode pill — neutral graphite project reference (blue reserved for Work type) */
/* Episode pill reads BRANDED (accent tint), not neutral — a makeover has to be
   tellable from a plain trip at a glance (Liam's v4 ask). */
.pill--ep { background: var(--accent-soft); color: var(--accent-strong); }
.pill--ep svg { color: var(--accent-strong); }
.pill--ep b { font-weight: var(--weight-semibold); color: var(--accent-strong); }

/* Category pill — neutral chip; the category glyph carries the hue (six-hue
   vocabulary), so the colored icon is the at-a-glance signal and the canvas
   stays quiet (same idea as the graphite episode pill). */
.pill--cat { background: var(--surface-2); color: var(--ink-800); }
.pill--cat-flights svg       { color: var(--st-blue); }
.pill--cat-accommodation svg { color: var(--st-purple); }
.pill--cat-food svg          { color: var(--st-amber); }
.pill--cat-transport svg     { color: var(--st-green); }
.pill--cat-activities svg    { color: var(--st-slate); }
.pill--cat-gear svg          { color: var(--ink-400); }
.pill--cat-misc svg          { color: var(--ink-400); }

/* Area pill — neutral chip for an org-level to-do's area; the leading status dot
   carries the hue (six-hue vocabulary), same quiet-canvas idea as the ep + cat
   pills. The dot sizing/color come from the canonical .sdot classes. */
.pill--area { background: var(--surface-2); color: var(--ink-800); }

/* Edit-week tag — no episode, dashed outline */
.pill--editweek {
  background: var(--surface-2); color: var(--ink-600);
  border: 1px dashed var(--border-strong);
}

/* Tiny note chip — dashed mono italic (inline tag variant) */
.chip-note {
  display: inline-flex; align-items: center;
  font-family: var(--font-mono);
  font-size: var(--text-2xs); font-weight: var(--weight-regular); font-style: italic;
  padding: 0.28rem var(--sp-3);
  border-radius: var(--r-sm);
  background: transparent;
  border: 1px dashed var(--ink-300);
  color: var(--ink-400);
  white-space: nowrap;
}

/* ============================================
   STATUS — pill + dot (deal funnel)
   ============================================ */

/* Status pill — used as hero overlay (absolute) or inline (override position) */
.status-pill {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-family: var(--font-mono);
  font-size: var(--text-xs); font-weight: var(--weight-medium); letter-spacing: var(--tracking-status);
  text-transform: uppercase;
  color: var(--ink-800);
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--r-full);
  padding: 0.3rem 0.6rem 0.3rem 0.55rem;
  box-shadow: var(--shadow-sm);
}
/* Inline variant (e.g. inside an archive row head) */
.status-pill--inline { position: static; box-shadow: none; }

/* Status dot — base + every funnel stage */
.sdot {
  width: 7.5px; height: 7.5px; border-radius: 50%; flex: 0 0 auto;
  background: var(--st-grey);
}
.sdot--grey   { background: var(--st-grey); }   /* discussing */
.sdot--slate  { background: var(--st-slate); }  /* planned */
.sdot--amber  { background: var(--st-amber); }  /* verbal yes */
.sdot--blue   { background: var(--st-blue); }   /* dates locked */
.sdot--green  { background: var(--st-green); }  /* villa locked */
.sdot--purple { background: var(--st-purple); } /* post-production */
.sdot--red    { background: var(--prio-high); } /* blocked status / high priority */

/* ============================================
   STEP ROW — a progress-checklist row (status indicator + title/sub + chevron).
   States: done (green check, muted title), current (accent-soft fill + accent bar +
   chevron — the one thing to do now), upcoming (grey .sdot), locked (lock icon, muted).
   Built from .sdot + tokens; the caller wraps it in a button/link for interactivity.
   ============================================ */
.step-row {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3); border-radius: var(--r-md);
  border-bottom: 1px solid var(--border-soft);
}
.step-row__ind { flex: 0 0 auto; display: flex; align-items: center; justify-content: center; width: 18px; }
.step-row__body { flex: 1 1 auto; min-width: 0; }
.step-row__title { font-weight: var(--weight-medium); color: var(--ink-900); }
.step-row__sub { font-size: var(--text-sm); color: var(--ink-400); margin-top: 1px; }
.step-row__chev { flex: 0 0 auto; display: flex; color: var(--ink-300); }
.step-row--done .step-row__title { color: var(--ink-600); }
.step-row--current {
  background: var(--accent-soft); border-bottom-color: transparent;
  box-shadow: inset 3px 0 0 var(--accent);
}
.step-row--current .step-row__title { color: var(--accent-strong); }
.step-row--current .step-row__chev { color: var(--accent-strong); }
.step-row--locked .step-row__title { color: var(--ink-600); }

/* ============================================
   CREW AVATARS — single, overlapping stack, ring
   ============================================ */
.avatar {
  width: 24px; height: 24px; border-radius: 50%;
  display: grid; place-items: center;
  color: var(--white); font-size: var(--text-3xs); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-mono);
  box-shadow: 0 0 0 2px var(--surface); /* ring separating overlapped avatars from canvas */
  flex: 0 0 auto;
}
.avatar--liam  { background: var(--p-liam); }
.avatar--shaan { background: var(--p-shaan); }
.avatar--emil  { background: var(--p-emil); }
.avatar--jake  { background: var(--p-jake); }

/* Overlapping stack */
.crew__stack { display: flex; }
.crew__stack .avatar:not(:first-child) { margin-left: -8px; }

/* Crew block — stack + names */
.crew { display: flex; align-items: center; gap: var(--sp-3); margin-top: 0.7rem; }
.crew__names { font-size: var(--text-md); color: var(--ink-400); }

/* ============================================
   FLAG CHIP (standalone, over imagery)
   ============================================ */
.flag-chip {
  display: inline-flex; align-items: center;
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.9);
  border-radius: var(--r-sm);
  padding: 4px;
  box-shadow: var(--shadow-sm);
}
.flag-chip img {
  width: 22px; height: 16px; border-radius: 3px; display: block;
  object-fit: cover; background: var(--surface-2);
  box-shadow: var(--flag-ring-soft);
}

/* ============================================
   TRIP CARD (hero band + body + tasks)
   ============================================ */
.trip-card {
  display: flex; flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--ease-spring), border-color var(--ease-card), transform var(--ease-spring);
}
/* Lift on hover with shadow + border only — NO transform. A transform (even
   translateY(-2px)) makes the card a containing block + stacking context, which
   traps the card's position:fixed status dropdown inside the card (clipped by the
   hero's overflow:hidden, painted behind the next card). The shadow carries the lift. */
.trip-card:hover {
  box-shadow: var(--shadow-lg);
  border-color: var(--border-strong);
}

/* Task drag-reassign affordance on the home grid (mirrors .board-col.is-drop):
   a card lights up as a drop target, the dragged task row dims as the source. */
.trip-card.is-drop, .trip-row.is-drop { outline: 2px solid var(--accent); outline-offset: -2px; }
.trip-card .task.is-dragging-src, .trip-row .task.is-dragging-src { opacity: 0.4; }

/* -- Hero band -- (photo placeholder; live app fills with a location photo) */
.hero {
  position: relative;
  aspect-ratio: 16 / 9; min-height: var(--hero-h);
  overflow: hidden;
  display: flex; align-items: flex-end;
  padding: var(--sp-4) var(--sp-5) var(--sp-4);
}
/* Drained near-white type-tint duotones — paper dominates, hue is a faint key */
.hero--shoot    { background: linear-gradient(150deg, var(--tint-shoot-1) 0%, var(--tint-shoot-2) 100%); }
.hero--work     { background: linear-gradient(150deg, var(--tint-work-1) 0%, var(--tint-work-2) 100%); }
.hero--vacation { background: linear-gradient(150deg, var(--tint-vacation-1) 0%, var(--tint-vacation-2) 100%); }
.hero--transit  { background: linear-gradient(150deg, var(--tint-transit-1) 0%, var(--tint-transit-2) 100%); }
/* faint texture sheen so the duotone reads as a surface, not a flat fill */
.hero::before {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(120% 90% at 85% 0%, rgba(255, 255, 255, 0.55), rgba(255, 255, 255, 0) 55%);
  pointer-events: none;
}
/* Hero text stack — headline (place or makeover name) + optional sub-line */
.hero__text {
  position: relative; z-index: 1;
  /* Headline sits bottom-left, the status pill top-right, so they don't collide —
     let the headline use the full width and only wrap when it genuinely must. */
  max-width: 100%;
  display: flex; flex-direction: column; gap: 0.12rem;
}
.hero__place {
  display: flex; align-items: center; gap: 0.4rem;
  font-size: var(--text-hero); font-weight: var(--weight-semibold); letter-spacing: var(--tracking-tighter);
  line-height: var(--leading-tight); color: var(--ink-900);
}
.hero__sub {
  display: flex; align-items: center; gap: 0.35rem;
  font-size: var(--text-md); font-weight: var(--weight-medium);
  line-height: var(--leading-tight); color: var(--ink-400);
}
/* Inline flag riding the place/sub text (replaces the old corner chip) */
.hero__flag-inline {
  width: 20px; height: 14px; flex: 0 0 auto;
  border-radius: 3px; object-fit: cover;
  box-shadow: var(--flag-ring-soft);
}
/* On a photo the wash is dark, so the headline + sub-line flip to light. */
.hero--photo .hero__place { color: var(--white); }
.hero--photo .hero__sub { color: var(--ink-inverse-soft); }
/* Status pill overlaid top-right of hero */
.hero__status {
  position: absolute; top: 0.7rem; right: 0.7rem; z-index: 2;
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-family: var(--font-mono);
  font-size: var(--text-xs); font-weight: var(--weight-medium); letter-spacing: var(--tracking-status);
  text-transform: uppercase;
  color: var(--ink-800);
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--r-full);
  padding: 0.3rem 0.6rem 0.3rem 0.55rem;
  box-shadow: var(--shadow-sm);
}
/* Editable variant (gallery cards): just the corner position; the status select
   trigger inside carries the same white-capsule pill look as the static pill, so
   the card reads identically until you click it to change the stage. */
.hero__status-edit { position: absolute; top: 0.7rem; right: 0.7rem; z-index: 2; }

/* -- Card body -- */
.body { padding: var(--sp-5) var(--sp-6) var(--sp-3); }

/* Pill row */
.pills { display: flex; flex-wrap: wrap; gap: var(--sp-2); }

/* Note caption sitting just above the tasks (e.g. "villa pending") */
.body-note {
  display: flex; align-items: center; gap: 0.3rem;
  margin-top: 0.7rem;
  font-family: var(--font-mono);
  font-size: var(--text-2xs); font-weight: var(--weight-regular); font-style: italic;
  color: var(--ink-400);
}
.body-note svg { width: 11px; height: 11px; color: var(--ink-300); }

/* ============================================
   ARCHIVE TRIP ROW (compact "Past" variant)
   ============================================ */
.trips-past { margin-top: 2.75rem; opacity: 0.78; }
.trips-past .section-label { color: var(--ink-300); }
.trips-past-list { display: flex; flex-direction: column; gap: var(--sp-6); }

.trip-row {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--ease-card), border-color var(--ease-card);
}
.trip-row:hover { box-shadow: var(--shadow-md); border-color: var(--border-strong); }
.trip-row__head {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.55rem;
  padding: 0.85rem var(--sp-6);
}
.trip-row__flag img {
  width: 24px; height: 17px; border-radius: 3px; display: block;
  object-fit: cover; background: var(--surface-2);
  box-shadow: var(--flag-ring);
}
.trip-row__place {
  font-size: var(--text-2xl); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight); color: var(--ink-900);
}
.trip-row__crew { display: flex; align-items: center; gap: var(--sp-3); margin-left: auto; }
.trip-row .tasks {
  margin-top: 0;
  border-top: 1px solid var(--border-soft);
  padding: 0.1rem var(--sp-6) 0.4rem;
}

/* ============================================
   TASK LIST + ROW
   ============================================ */
.tasks {
  margin-top: var(--sp-5);
  border-top: 1px solid var(--border-soft);
  padding-top: 0.35rem;
  display: flex; flex-direction: column;
}
/* Group subhead inside the task list (e.g. "Makeover" vs "Trip") */
.tasks-group__label {
  display: flex; align-items: center; gap: 0.3rem;
  padding: var(--sp-3) 0.3rem var(--sp-2);
  font-family: var(--font-mono);
  font-size: var(--text-2xs); font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-status); text-transform: uppercase;
  color: var(--ink-400);
}
.tasks-group__label:first-child { padding-top: 0; }
.tasks-group__label svg { width: 12px; height: 12px; color: var(--ink-300); }
.task {
  display: flex; align-items: center; gap: 0.6rem;
  padding: var(--sp-3) 0.3rem;
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background var(--ease-task);
}
.task:hover { background: var(--bg); }

/* Circular checkbox — empty / checked */
.check {
  width: 17px; height: 17px; flex: 0 0 auto;
  border: 1.6px solid var(--ink-300);
  border-radius: 50%;
  position: relative;
  /* Click cursor on the tick target even when the row itself is draggable
     (the board rows set cursor: grab). The tick is a click, not a drag handle. */
  cursor: pointer;
  transition: border-color var(--ease-task), background var(--ease-task);
}
.task:hover .check { border-color: var(--ink-400); }
.check--done { background: var(--accent); border-color: var(--accent); }
.check--done::after {
  content: ''; position: absolute;
  left: 5px; top: 2px;
  width: 4px; height: 8px;
  border: solid var(--white); border-width: 0 1.6px 1.6px 0;
  transform: rotate(45deg);
}

/* Consent / agreement checkbox row — a native checkbox (accent fill) + a label, used for
   contract consent and any agree-to-terms list. Single-sourced via OpsUI.consentCheck(). */
.check-row {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  padding: var(--sp-2) 0; cursor: pointer;
}
.check-input {
  flex: 0 0 auto; width: 18px; height: 18px; margin-top: 1px;
  accent-color: var(--accent); cursor: pointer;
}
.check-row__label {
  font-size: var(--text-sm); line-height: var(--leading-body); color: var(--ink-800);
}

/* Task title + done/struck state */
.task__title {
  flex: 1 1 auto; min-width: 0;
  font-size: var(--text-tasktitle); font-weight: var(--weight-regular);
  color: var(--ink-800); letter-spacing: var(--tracking-snug);
}
.task--done .task__title {
  color: var(--ink-400);
  text-decoration: line-through;
  text-decoration-color: var(--ink-300);
}

/* Task meta cluster */
.task__meta { display: flex; align-items: center; gap: 0.45rem; flex: 0 0 auto; }

/* Hover quick actions (duplicate/delete) — hidden until the row is hovered or
   focused; the Inbox pane uses them for fast triage. They render BEFORE the meta
   cluster, so the due chip keeps the row's right edge and the buttons appear to
   its left. pointer-events guards the invisible state from catching stray clicks. */
.task__actions { display: flex; align-items: center; gap: var(--sp-1); opacity: 0; pointer-events: none; }
.task:hover .task__actions, .task:focus-within .task__actions { opacity: 1; pointer-events: auto; }
.task__action {
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; background: transparent; color: var(--ink-300);
  padding: var(--sp-1); border-radius: var(--r-sm); cursor: pointer;
  transition: color var(--ease-default), background var(--ease-default);
}
.task__action:hover { color: var(--ink-800); background: var(--surface-2); }
.task__action--danger:hover { color: var(--due-urgent); }
.task__action svg { width: 14px; height: 14px; display: block; }

/* Priority flag glyph — high / med / low */
.prio { display: inline-flex; align-items: center; }
.prio svg { width: 13px; height: 13px; display: block; }
.prio--high svg { color: var(--prio-high); }
.prio--med svg  { color: var(--prio-med); }
.prio--low svg  { color: var(--prio-low); }

/* Due chip — normal / urgent */
.due {
  display: inline-flex; align-items: center; gap: 0.25rem;
  font-family: var(--font-mono);
  font-size: var(--text-2xs); font-weight: var(--weight-medium);
  color: var(--ink-400);
  white-space: nowrap;
}
.due svg { width: 11px; height: 11px; }
.due--urgent { color: var(--due-urgent); }

/* ============================================
   +ADD TASK ROW (card footer)
   ============================================ */
.add-task {
  display: flex; align-items: center; gap: var(--sp-3);
  width: 100%; font: inherit;
  font-size: var(--text-base); font-weight: var(--weight-medium);
  color: var(--ink-400); background: transparent; text-align: left;
  border: none; border-top: 1px solid var(--border-soft);
  padding: 0.7rem var(--sp-6); cursor: pointer;
  transition: background var(--ease-default), color var(--ease-default);
}
.add-task:hover { background: var(--surface-2); color: var(--accent-strong); }
.add-task svg { width: 13px; height: 13px; }

/* ============================================
   LOAD REVEAL — staggered entrance
   Apply inline `style="animation-delay: 0.04s"` (and increments)
   for the staggered cascade used in the prototype.
   ============================================ */
.reveal {
  opacity: 0; transform: translateY(14px);
  animation: rise var(--ease-reveal) forwards;
}
@keyframes rise { to { opacity: 1; transform: translateY(0); } }

@media (prefers-reduced-motion: reduce) {
  .reveal { animation: none; opacity: 1; transform: none; }
}

/* ============================================
   FORM CONTROLS — field / input / textarea / select-menu
   Canonical tokens; focus ring uses accent-soft.
   ============================================ */
.field { margin-bottom: var(--sp-5); }
.field__label {
  display: block;
  font-size: var(--text-md); font-weight: var(--weight-medium);
  color: var(--ink-600); margin-bottom: var(--sp-2);
}
.input, .textarea {
  width: 100%; font: inherit;
  font-size: var(--text-lg); color: var(--ink-900);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-4);
  transition: border-color var(--ease-default), box-shadow var(--ease-default);
}
.input::placeholder, .textarea::placeholder { color: var(--ink-400); }
.input:focus, .textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.textarea { min-height: 96px; resize: vertical; line-height: var(--leading-body); }

/* Disabled form controls — a gated/not-yet-reachable field or a deferred one
   (Phase-1 socials). Muted recessed fill, no focus ring, not-allowed cursor.
   Mirrors the existing .chat-panel__input:disabled treatment. Token-only. */
.input:disabled, .textarea:disabled {
  background: var(--surface-2);
  color: var(--ink-400);
  border-color: var(--border);
  cursor: not-allowed;
}
.input:disabled::placeholder, .textarea:disabled::placeholder { color: var(--ink-300); }
.select-menu.is-disabled .select-menu__trigger {
  background: var(--surface-2);
  color: var(--ink-400);
  border-color: var(--border);
  cursor: not-allowed;
  pointer-events: none;
}
.btn-primary:disabled, .btn-secondary:disabled, .btn-danger:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
.btn-primary:disabled:hover { opacity: 0.45; }
.btn-secondary:disabled:hover { background: var(--surface); border-color: var(--border); }
.btn-danger:disabled:hover { background: var(--surface); border-color: var(--border); }

/* -- Location search: a text input + an async geocode results dropdown. Picking a
   result stores the structured place (country/lat/lng/region) on the trip; the
   country code drives the flag. List is absolute (the field isn't in an overflow
   scroller), unlike the select-menu's fixed popup. -- */
.loc-search { position: relative; }
/* Leading flag inside the input — the picked place's country. */
.loc-search__flag-lead { position: absolute; left: var(--sp-3); top: 50%; transform: translateY(-50%); z-index: 1; display: inline-flex; }
.loc-search__flag-lead img { width: 20px; height: 14px; border-radius: 2.5px; object-fit: cover; box-shadow: var(--flag-ring); display: block; }
.loc-search--has-flag .loc-search__input { padding-left: calc(var(--sp-4) + 24px); }
.loc-search__list {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 30;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); box-shadow: var(--shadow-lg);
  padding: var(--sp-2); max-height: 280px; overflow-y: auto;
}
.loc-search__opt {
  display: flex; align-items: center; gap: var(--sp-3); width: 100%;
  font: inherit; font-size: var(--text-sm); color: var(--ink-800);
  background: transparent; border: none; border-radius: var(--r-sm);
  padding: var(--sp-3); cursor: pointer; text-align: left;
  transition: background var(--ease-default), color var(--ease-default);
}
.loc-search__opt:hover { background: var(--surface-2); color: var(--ink-900); }
.loc-search__opt-text { display: flex; flex-direction: column; gap: 0.05rem; min-width: 0; }
.loc-search__opt-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.loc-search__sub { font-size: var(--text-2xs); color: var(--ink-400); }
.loc-search__flag {
  width: 20px; height: 14px; flex: 0 0 auto; border-radius: 2.5px;
  object-fit: cover; box-shadow: var(--flag-ring);
}
.loc-search__flag--none { background: var(--surface-2); box-shadow: var(--flag-ring); }
.loc-search__empty { padding: var(--sp-3); font-size: var(--text-sm); color: var(--ink-400); }

/* -- Select-menu: the canonical styled dropdown (replaces the native OS select).
   A visually-hidden native <select> holds the value and fires `change`; the styled
   trigger + popup are driven by the global delegated controller in app.js. -- */
.select-menu { position: relative; display: block; width: 100%; }
.select-menu__native {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  pointer-events: none;
}
.select-menu__trigger {
  width: 100%; font: inherit;
  font-size: var(--text-lg); color: var(--ink-900);
  display: inline-flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  background: var(--surface);
  border: 1px solid var(--border-strong); border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-4); cursor: pointer; text-align: left;
  transition: border-color var(--ease-default), box-shadow var(--ease-default);
}
.select-menu__trigger:hover { border-color: var(--ink-400); }
.select-menu.is-open .select-menu__trigger {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.select-menu__trigger > svg { width: 14px; height: 14px; color: var(--ink-400); flex: 0 0 auto; transition: transform var(--ease-default); }
.select-menu.is-open .select-menu__trigger > svg { transform: rotate(180deg); }
.select-menu__label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.select-menu__list {
  /* position:fixed + JS-set top/left so the popup escapes the board column's
     overflow:hidden and the modal's scroll clip (app.js openSelectMenu). */
  position: fixed; z-index: 60;
  max-height: 280px; overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--r-md);
  box-shadow: var(--shadow-lg); padding: var(--sp-2);
}
.select-menu__list[hidden] { display: none; }
.select-menu__option {
  width: 100%; font: inherit;
  font-size: var(--text-base); color: var(--ink-800);
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3); border: none; background: transparent; border-radius: var(--r-sm);
  cursor: pointer; text-align: left; white-space: nowrap;
  transition: background var(--ease-default), color var(--ease-default);
}
.select-menu__option:hover { background: var(--surface-2); color: var(--ink-900); }
.select-menu__option.is-active { background: var(--accent-soft); color: var(--accent-strong); }
/* Leading media slot — mirrored onto the trigger on pick. Holds a status dot, an
   icon, a country flag, or a crew avatar. Empty slots collapse (no phantom gap). */
.select-menu__media { display: inline-flex; align-items: center; flex: 0 0 auto; }
.select-menu__media:empty { display: none; }
.select-menu__media > svg { width: 14px; height: 14px; color: var(--ink-400); }
.select-menu__media .opt-flag {
  width: 18px; height: 13px; border-radius: 2.5px; object-fit: cover; display: block;
  box-shadow: var(--flag-ring);
}
.select-menu__opt-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* Status select — the deal-stage control. The closed trigger (a status pill)
   and the open menu options share ONE typographic treatment, defined here once
   so they can't drift apart: mono, uppercase, status tracking, + the funnel dot.
   This is the canonical look of the status select, trigger and menu alike. */
.select-menu--status { display: inline-block; width: auto; }
.select-menu__trigger--status,
.select-menu--status .select-menu__option {
  font-family: var(--font-mono);
  font-size: var(--text-xs); font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-status); text-transform: uppercase;
  color: var(--ink-800);
}
.select-menu__trigger--status {
  width: auto; gap: var(--sp-2);
  border: 1px solid var(--border-soft); border-radius: var(--r-full);
  padding: 0.3rem 0.5rem 0.3rem 0.55rem;
  box-shadow: var(--shadow-sm);
}
.select-menu__trigger--status:hover { border-color: var(--border-strong); }
.select-menu__trigger--status > svg { width: 11px; height: 11px; }
.select-menu--status .select-menu__option.is-active { color: var(--accent-strong); }

/* ============================================
   BUTTON — danger variant (delete actions)
   ============================================ */
.btn-danger {
  font: inherit; font-size: var(--text-lg); font-weight: var(--weight-medium);
  display: inline-flex; align-items: center; gap: 0.35rem;
  padding: var(--sp-3) 0.95rem;
  background: var(--surface); color: var(--prio-high);
  border: 1px solid var(--border); border-radius: var(--r-md); cursor: pointer;
  transition: background var(--ease-default), border-color var(--ease-default);
}
.btn-danger:hover { background: var(--surface-2); border-color: var(--prio-high); }
.btn-danger:active { transform: translateY(1px); }
.btn-danger svg { width: 13px; height: 13px; }

/* ============================================
   MODAL — backdrop + bottom-sheet / centered panel
   ============================================ */
.modal-backdrop {
  position: fixed; inset: 0; z-index: 40;
  background: var(--scrim);
  display: flex; align-items: flex-end; justify-content: center;
}
.modal {
  width: 100%; max-width: var(--view-max);
  background: var(--surface);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  padding: var(--sp-6) var(--sp-6) calc(var(--sp-6) + env(safe-area-inset-bottom));
  box-shadow: var(--shadow-lg);
  max-height: 88vh; overflow-y: auto;
}
.modal__title {
  font-size: var(--text-3xl); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight); color: var(--ink-900);
  margin-bottom: var(--sp-5);
}
/* Explanatory body copy for a confirm/destructive modal (no form fields). */
.modal__text {
  font-size: var(--text-base); line-height: var(--leading-body);
  color: var(--ink-600); margin: 0 0 var(--sp-3);
}
.modal__text:last-of-type { margin-bottom: 0; }
.modal__actions {
  display: flex; gap: var(--sp-3); justify-content: flex-end;
  margin-top: var(--sp-6);
}
.modal__actions .btn-danger { margin-right: auto; }
@media (min-width: 720px) {
  .modal-backdrop { align-items: center; padding: var(--sp-6); }
  .modal { border-radius: var(--r-lg); max-width: 540px; }
  /* Wider variant for a two-pane modal (e.g. the trip + makeover create form). */
  .modal--wide { max-width: 880px; }
}

/* ============================================
   FILTER CHIPS + QUICK-ADD
   ============================================ */
.chiprow {
  display: flex; gap: var(--sp-2);
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  padding-bottom: var(--sp-2);
  scrollbar-width: none;
}
.chiprow::-webkit-scrollbar { display: none; }
.chip {
  font: inherit; font-size: var(--text-sm); font-weight: var(--weight-medium);
  white-space: nowrap;
  padding: 0.32rem var(--sp-4);
  border-radius: var(--r-full);
  border: 1px solid var(--border);
  background: var(--surface); color: var(--ink-600);
  cursor: pointer;
  transition: background var(--ease-default), color var(--ease-default), border-color var(--ease-default);
}
.chip:hover { background: var(--surface-2); color: var(--ink-800); }
.chip.is-active { background: var(--ink-900); color: var(--white); border-color: var(--ink-900); }

.quickadd { display: flex; gap: var(--sp-3); align-items: center; }
.quickadd .input { flex: 1 1 auto; }
.quickadd .select-menu { flex: 0 0 auto; width: auto; min-width: 120px; }
.quickadd .btn-primary { flex: 0 0 auto; }

/* ============================================
   KANBAN BOARD — horizontal columns (Makeovers)
   ============================================ */
.board {
  display: flex; gap: var(--sp-6);
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  padding-bottom: var(--sp-3);
  scroll-snap-type: x proximity;
  scrollbar-width: none;
}
.board::-webkit-scrollbar { display: none; }
.board-col {
  flex: 0 0 86vw; max-width: var(--board-col-w);
  display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--shadow-sm);
  scroll-snap-align: start;
  max-height: calc(100dvh - 188px); overflow: hidden;
}
.board-col__head { padding: var(--sp-5); border-bottom: 1px solid var(--border); }
.board-col__name {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  font-size: var(--text-2xl); font-weight: var(--weight-semibold);
  color: var(--ink-900); letter-spacing: var(--tracking-tight);
  margin-bottom: var(--sp-3);
}
.board-col__ep { flex: 0 0 auto; }
.board-col__pills { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.board-col__tasks { flex: 1; overflow-y: auto; padding: 0 var(--sp-4); }
.board-col__tasks .task { cursor: grab; }
.board-col__tasks .task:active { cursor: grabbing; }
.board-col__tasks .task.is-dragging-src { opacity: 0.4; }
.board-col.is-drop { outline: 2px solid var(--accent); outline-offset: -2px; }
.board-col.is-drop .board-col__head { background: var(--accent-soft); }
.board-col__empty { padding: var(--sp-5); color: var(--ink-400); font-size: var(--text-sm); }
.board-col__done {
  width: 100%; text-align: left; font: inherit;
  font-family: var(--font-mono);
  font-size: var(--text-2xs); font-weight: var(--weight-medium); letter-spacing: var(--tracking-label);
  text-transform: uppercase; color: var(--ink-400);
  background: transparent; border: none; border-top: 1px solid var(--border-soft);
  padding: var(--sp-3) var(--sp-5); cursor: pointer;
}
.board-col__done:hover { color: var(--ink-800); }
.board-col__add {
  display: flex; align-items: center; gap: var(--sp-3);
  width: 100%; font: inherit; font-size: var(--text-base); font-weight: var(--weight-medium);
  color: var(--ink-400); background: transparent; text-align: left;
  border: none; border-top: 1px solid var(--border-soft);
  padding: var(--sp-3) var(--sp-5); cursor: pointer;
  transition: background var(--ease-default), color var(--ease-default);
}
.board-col__add:hover { background: var(--surface-2); color: var(--accent-strong); }
.board-col__add svg { width: 13px; height: 13px; }
.board-col__addrow { padding: var(--sp-3) var(--sp-5); border-top: 1px solid var(--border-soft); }

/* ============================================
   COLLAPSIBLE SECTION
   Foldable group (To-dos hub: org areas, trips, makeovers). Mirrors the
   report-drop collapse — chevron rotates, body animates via grid-rows 0fr→1fr,
   reduced-motion guarded. Layout from tokens only.
   ============================================ */
.collapsible-section { border-top: 1px solid var(--border-soft); }
.collapsible-section:first-of-type { border-top: 0; }
.collapsible-section__head {
  display: flex; align-items: center; gap: var(--sp-3);
  width: 100%; padding: var(--sp-3) 0;
  background: none; border: 0; cursor: pointer; text-align: left;
  font-family: inherit;
}
/* Rows read denser inside a section than on a card (the v2 layout pass). */
.collapsible-section .task { padding-top: var(--sp-2); padding-bottom: var(--sp-2); }
/* The section head already divides — kill the task list's own top rule + gap so a
   section body doesn't read as a double divider with dead air (the v3 cleanup). */
.collapsible-section .tasks { margin-top: 0; border-top: 0; padding-top: 0; }
.collapsible-section__chev { display: inline-flex; color: var(--ink-400); transition: transform var(--ease-default); }
.collapsible-section.is-open .collapsible-section__chev { transform: rotate(90deg); }
/* The label is a flex row with a real gap: a rich header (location pill + Ep pill)
   needs clearance so a pill's hover ring (outline + offset) can't cut into its
   neighbor. Plain text labels are unaffected. */
.collapsible-section__label {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-size: var(--text-tasktitle); font-weight: var(--weight-medium); color: var(--ink-900);
  letter-spacing: var(--tracking-tight);
}
.collapsible-section__count { margin-left: auto; font-size: var(--text-2xs); color: var(--ink-400); }
.collapsible-section__body { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--ease-reveal); }
.collapsible-section.is-open .collapsible-section__body { grid-template-rows: 1fr; }
.collapsible-section__inner { overflow: hidden; min-height: 0; }
.collapsible-section__empty { padding: var(--sp-2) 0 var(--sp-3); color: var(--ink-400); font-size: var(--text-sm); }
.collapsible-section__addrow { padding: var(--sp-2) 0 var(--sp-3); }
/* Drag-to-file: a section lights up as a drop target (mirrors .board-col.is-drop),
   the dragged row dims as the source. Ghost sections (empty areas, task-less
   upcoming trips/makeovers) stay hidden until an ancestor carries
   .is-todo-dragging — a drag in flight — then materialize as muted targets. */
.collapsible-section.is-drop { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: var(--r-sm); }
.collapsible-section.is-drop .collapsible-section__head { background: var(--accent-soft); }
.collapsible-section .task.is-dragging-src { opacity: 0.4; }
.collapsible-section--ghost { display: none; }
.is-todo-dragging .collapsible-section--ghost { display: block; }
.collapsible-section--ghost .collapsible-section__label { color: var(--ink-400); }
/* Header pills navigate (trip pill → trip page, Ep pill → makeover page); give
   them the click affordance inside the fold-toggle head. */
.collapsible-section__head .pill--loc, .collapsible-section__head .pill--ep { cursor: pointer; }
.collapsible-section__head .pill--loc:hover, .collapsible-section__head .pill--ep:hover {
  outline: 1.5px solid var(--accent); outline-offset: 1px;
}
@media (prefers-reduced-motion: reduce) {
  .collapsible-section__chev, .collapsible-section__body { transition: none; }
}

/* ============================================
   TRIAGE TILES (To-dos hub file-to targets)
   A grid of compact drop targets in the triage pane: dashed until a dragged row
   hovers (.is-drop, the accent vocabulary shared with board-col/sections).
   ============================================ */
.triage-grid { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.triage-tile {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--ink-800);
  background: var(--surface-2); border: 1px dashed var(--border-strong);
  border-radius: var(--r-md); padding: var(--sp-2) var(--sp-4);
}
.triage-tile b { font-weight: var(--weight-semibold); }
.triage-tile .opt-flag {
  width: 18px; height: 13px; border-radius: 2.5px; object-fit: cover; display: block;
  box-shadow: var(--flag-ring);
}
.triage-tile.is-drop { border-style: solid; border-color: var(--accent); background: var(--accent-soft); }

/* ============================================
   MONTH-GRID CALENDAR
   Look is canonical; drag/resize behavior lives in calendar.js.
   ============================================ */
.cal-head__month {
  font-size: var(--text-3xl); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight); color: var(--ink-900);
  min-width: 168px; text-align: center;
}
/* The month label sits between the prev/next arrows, with Today after — one
   centered cluster (the Trips view-head slots it into the heading row). Wraps +
   re-centers on a narrow phone so the cluster never overflows the header row. */
.cal-nav { display: flex; gap: var(--sp-3); align-items: center; flex-wrap: wrap; justify-content: center; }
.cal-nav__btn {
  width: 34px; height: 34px; display: grid; place-items: center;
  border-radius: var(--r-md); border: 1px solid var(--border-strong);
  background: var(--surface); color: var(--ink-800); cursor: pointer;
  transition: background var(--ease-default);
}
.cal-nav__btn:hover { background: var(--surface-2); }
.cal-nav__btn svg { width: 16px; height: 16px; }

.cal-grid {
  border: 1px solid var(--border); border-radius: var(--r-lg); overflow: hidden;
  background: var(--surface); box-shadow: var(--shadow-sm);
}
.cal-weekdays { display: grid; grid-template-columns: repeat(7, 1fr); background: var(--surface-2); border-bottom: 1px solid var(--border); }
.cal-weekdays span {
  padding: 7px 0; text-align: center;
  font-family: var(--font-mono);
  font-size: var(--text-2xs); font-weight: var(--weight-medium); letter-spacing: var(--tracking-date);
  text-transform: uppercase; color: var(--ink-400);
}
.cal-week { position: relative; border-bottom: 1px solid var(--border); }
.cal-week:last-child { border-bottom: none; }
.cal-week__cells { display: grid; grid-template-columns: repeat(7, 1fr); height: 100%; position: absolute; inset: 0; }
.cal-cell { border-right: 1px solid var(--border); padding: 4px; position: relative; min-width: 0; }
.cal-cell:last-child { border-right: none; }
.cal-cell.is-outside { background: var(--bg); }
.cal-cell__num {
  font-family: var(--font-mono); font-size: var(--text-2xs); font-weight: var(--weight-medium);
  color: var(--ink-600); display: inline-grid; place-items: center; width: 22px; height: 20px;
}
.cal-cell.is-outside .cal-cell__num { color: var(--ink-400); opacity: 0.6; }
.cal-cell.is-today .cal-cell__num {
  background: var(--accent); color: var(--white); border-radius: var(--r-full);
  width: 20px; height: 20px; font-weight: var(--weight-bold);
}
.cal-cell__tasks {
  position: absolute; bottom: 3px; right: 4px;
  font-family: var(--font-mono); font-size: var(--text-2xs); font-weight: var(--weight-medium); color: var(--ink-400);
  background: var(--surface-2); border-radius: var(--r-full); padding: 1px 6px; cursor: pointer;
}
.cal-cell__tasks:hover { background: var(--accent-soft); color: var(--accent-strong); }
.cal-week__spacer { width: 100%; }
.cal-bars { position: absolute; inset: 0; pointer-events: none; }
.cal-bar {
  position: absolute; height: 20px; min-width: 22px; display: flex; align-items: center;
  padding: 0 7px; border-radius: var(--r-sm);
  font-size: var(--text-2xs); font-weight: var(--weight-medium); color: var(--white);
  white-space: nowrap; overflow: hidden; cursor: grab;
  pointer-events: auto; box-shadow: var(--shadow-sm);
  touch-action: none; user-select: none; -webkit-user-select: none;
}
.cal-bar:focus-visible { outline: 2px solid var(--ink-900); outline-offset: 1px; }
.cal-bar:active { cursor: grabbing; }
.cal-bar.dragging { opacity: 0.85; box-shadow: var(--shadow-lg); z-index: 30; }
.cal-bar.is-ghost { opacity: 0.45; }
.cal-bar:not(.is-start) { border-top-left-radius: 0; border-bottom-left-radius: 0; }
.cal-bar:not(.is-end) { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.cal-bar--shoot { background: var(--type-shoot); }
.cal-bar--vacation { background: var(--type-vacation); }
.cal-bar--transit { background: var(--type-transit); }
.cal-bar--work { background: var(--type-work); }
.cal-bar__label { overflow: hidden; text-overflow: ellipsis; flex: 1; }
.cal-bar__handle { position: absolute; top: 0; bottom: 0; width: 8px; cursor: ew-resize; }
.cal-bar__handle--l { left: 0; }
.cal-bar__handle--r { right: 0; }
.cal-bar:not(.is-start) .cal-bar__handle--l { display: none; }
.cal-bar:not(.is-end) .cal-bar__handle--r { display: none; }

/* ============================================
   AVATAR — sizes + photo variant (CRM)
   Base .avatar (24px) stays the crew/stack size; these add scale + image.
   ============================================ */
.avatar--sm { width: 24px; height: 24px; font-size: var(--text-3xs); }
.avatar--md { width: 32px; height: 32px; font-size: var(--text-2xs); }
.avatar--lg { width: 56px; height: 56px; font-size: var(--text-lg); }
.avatar--img { overflow: hidden; background: var(--surface-2); }
.avatar--img img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Brand badge — a 32px circular AI-chat-export source mark (ChatGPT / Claude), sized like the
   social avatar. Neutral surface circle + the brand glyph tinted via --pf-<brand> (glyph-on-neutral,
   like .icon-links), so the export source reads at a glance without a colored fill. */
.brand-badge {
  width: 32px; height: 32px; border-radius: 50%;
  display: grid; place-items: center; flex: 0 0 auto;
  background: var(--surface-2); box-shadow: 0 0 0 2px var(--surface);
}
.brand-badge svg { width: 19px; height: 19px; }
.brand-badge--chatgpt { color: var(--pf-chatgpt); }
.brand-badge--claude { color: var(--pf-claude); }

/* Source icon — the leading circular badge on a "what you've shared" row (website / document /
   note). Same neutral circle + sizing as the avatar/brand-badge; --link makes it a clickable
   anchor (open the URL) with the one accent hover state. */
.source-icon {
  width: 32px; height: 32px; border-radius: 50%;
  display: grid; place-items: center; flex: 0 0 auto;
  background: var(--surface-2); box-shadow: 0 0 0 2px var(--surface);
  color: var(--ink-400);
}
.source-icon svg { width: 18px; height: 18px; }
.source-icon--link { cursor: pointer; transition: color var(--ease-default), background var(--ease-default); }
.source-icon--link:hover { color: var(--accent); background: var(--accent-soft); }

/* Row action — a small inline icon button on a list row (retry / remove). The --danger trash
   reads faintly red (prio-high at half opacity) and brightens on hover; neutral otherwise. */
.row-action {
  background: none; border: 0; cursor: pointer; padding: 4px;
  display: inline-flex; align-items: center; color: var(--ink-400);
  border-radius: var(--r-sm); transition: color var(--ease-default), background var(--ease-default), opacity var(--ease-default);
}
.row-action svg { width: 16px; height: 16px; }
.row-action:hover { background: var(--surface-2); color: var(--ink-900); }
.row-action--danger { color: var(--prio-high); opacity: 0.5; }
.row-action--danger:hover { color: var(--prio-high); background: var(--surface-2); opacity: 1; }

/* ============================================
   HERO PHOTO LAYER — sits behind flag/status/place overlays
   ============================================ */
.hero__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0; }
/* When a photo is present, a soft bottom wash keeps the dark place name legible */
.hero--photo::after {
  content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: linear-gradient(to top, var(--hero-photo-scrim) 0%, transparent 64%);
}

/* ============================================
   CRM — person card, profile header, makeover header, attendee
   ============================================ */
.person-card {
  display: flex; align-items: center; gap: var(--sp-4);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--shadow-sm);
  padding: var(--sp-4) var(--sp-5); cursor: pointer;
  transition: box-shadow var(--ease-card), border-color var(--ease-card);
}
.person-card:hover { box-shadow: var(--shadow-md); border-color: var(--border-strong); }
.person-card__main { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; flex: 1 1 auto; }
.person-card__name { font-size: var(--text-2xl); font-weight: var(--weight-semibold); color: var(--ink-900); letter-spacing: var(--tracking-tight); }
.person-card__sub { font-size: var(--text-md); color: var(--ink-400); }
.person-card__pills { display: flex; align-items: center; gap: var(--sp-2); flex: 0 0 auto; }

.profile { display: flex; align-items: center; gap: var(--sp-6); flex-wrap: wrap; }
.profile__main { display: flex; flex-direction: column; gap: var(--sp-2); min-width: 0; flex: 1 1 0; }
/* Edit action pinned to the header's top-right; wraps under on a narrow card. */
.profile__edit { margin-left: auto; align-self: flex-start; }
.profile__name { font-size: var(--text-hero); font-weight: var(--weight-semibold); color: var(--ink-900); letter-spacing: var(--tracking-tighter); line-height: var(--leading-tight); }
.profile__line { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
.profile__meta { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--ink-400); }
.profile__contacts { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-2); }

/* contact pill — neutral .pill carrying an icon + value (link or static) */
.pill--contact { color: var(--ink-800); }
.pill--contact svg { color: var(--ink-400); }
a.pill--contact:hover { background: var(--surface-2); color: var(--accent-strong); }

.makeover-header { display: flex; align-items: center; gap: var(--sp-5); flex-wrap: wrap; }
.makeover-header__main { display: flex; flex-direction: column; gap: var(--sp-3); min-width: 0; }
.makeover-header__name { font-size: var(--text-hero); font-weight: var(--weight-semibold); color: var(--ink-900); letter-spacing: var(--tracking-tighter); }
.makeover-header__ep { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--ink-400); }

.attendee { display: flex; align-items: center; gap: var(--sp-4); padding: var(--sp-3) 0; border-bottom: 1px solid var(--border-soft); }
.attendee:last-child { border-bottom: none; }
.attendee__name { font-size: var(--text-tasktitle); font-weight: var(--weight-medium); color: var(--ink-800); flex: 1 1 auto; min-width: 0; }
.attendee__detach {
  font: inherit; background: transparent; border: none; cursor: pointer;
  color: var(--ink-300); padding: var(--sp-2); border-radius: var(--r-sm); line-height: 1;
  display: inline-flex; align-items: center;
  transition: color var(--ease-default), background var(--ease-default);
}
.attendee__detach svg { width: 14px; height: 14px; }
.attendee__detach:hover { color: var(--prio-high); background: var(--surface-2); }

/* System map (control panel home) — node chrome; ring geometry is in styles.css */
.system-map__center,
.system-map__node {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--sp-2); text-align: center; text-decoration: none;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
}
.system-map__node {
  width: 116px; height: 116px; padding: var(--sp-4); color: var(--ink-600); cursor: pointer;
  transition: border-color var(--ease-default), box-shadow var(--ease-default), color var(--ease-default);
}
.system-map__node:hover {
  border-color: var(--border-strong); box-shadow: var(--shadow-md); color: var(--ink-900);
}
.system-map__node-icon svg { width: 24px; height: 24px; }
.system-map__node-label { font-size: var(--text-base); font-weight: var(--weight-medium); color: var(--ink-800); }
.system-map__center {
  width: 144px; height: 144px; padding: var(--sp-5);
  border-color: var(--ink-900); box-shadow: var(--shadow-md);
}
.system-map__center-icon { color: var(--ink-900); }
.system-map__center-icon svg { width: 30px; height: 30px; }
.system-map__center-label {
  font-size: var(--text-lg); font-weight: var(--weight-semibold);
  color: var(--ink-900); letter-spacing: var(--tracking-tight);
}

/* Statcard — a boxed KPI: a labelled headline number with an optional leading icon.
   The canonical top-of-page dashboard stat; lay several out in a .statcard-row. */
.statcard-row {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--sp-5); margin-bottom: var(--sp-6);
}
.statcard {
  display: flex; align-items: center; gap: var(--sp-4); min-width: 0;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: var(--sp-5);
}
.statcard__icon {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: var(--r-md);
  background: var(--surface-2); color: var(--ink-600);
}
.statcard__icon svg { width: 19px; height: 19px; }
.statcard__body { display: flex; flex-direction: column; gap: var(--sp-1); min-width: 0; }
.statcard__value {
  font-size: var(--text-hero); color: var(--ink-900); font-weight: var(--weight-semibold);
  line-height: 1.15; letter-spacing: var(--tracking-tight); white-space: nowrap;
}
.statcard__label { font-size: var(--text-2xs); color: var(--ink-400); text-transform: uppercase; letter-spacing: var(--tracking-label); }
.statcard__sub { font-size: var(--text-xs); color: var(--ink-600); }

/* Coming-soon placeholder panel (a tab a later plan fills in) */
.coming-soon { text-align: center; padding: var(--sp-9) var(--sp-5); color: var(--ink-400); }
.coming-soon__title {
  font-size: var(--text-h2); font-weight: var(--weight-semibold);
  color: var(--ink-900); letter-spacing: var(--tracking-tight); margin-bottom: var(--sp-3);
}
.coming-soon__plan {
  font-family: var(--font-mono); font-size: var(--text-2xs);
  text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--ink-400);
}
.coming-soon__blurb {
  margin: var(--sp-4) auto 0; max-width: 42ch; color: var(--ink-600);
  font-size: var(--text-base); line-height: var(--leading-body);
}

/* ============================================
   CRM — founder-research enrichment
   research bar · summary block · link pills + editor · business cards
   Quiet canvas: white surfaces, thin warm borders; state reads from the
   small leading icon hue, never a filled background.
   ============================================ */

/* Research bar — a status strip the founder-research employee drives. */
.research-bar {
  display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap;
  padding: var(--sp-4) var(--sp-5);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md);
}
.research-bar.is-done { border-color: var(--border-strong); }
/* A live run's bar is the panel re-entry point (people.js binds the click). */
.research-bar.is-running, .research-bar.is-cancelling { cursor: pointer; }
.research-bar__ctl { margin-left: auto; display: inline-flex; gap: var(--sp-2); }
.research-bar__icon { display: inline-flex; }
.research-bar__icon svg { width: 16px; height: 16px; }
.research-bar__icon--done { color: var(--st-green); }
.research-bar__icon--error { color: var(--prio-high); }
.research-bar__icon--cancelled { color: var(--ink-400); }
.research-bar__msg { font-size: var(--text-base); color: var(--ink-800); }
.research-bar__msg--hint { color: var(--ink-400); }
.research-bar__btn { margin-left: auto; }
.research-bar__doc {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-size: var(--text-sm); color: var(--accent-strong); text-decoration: none;
}
.research-bar__doc:hover { text-decoration: underline; }
.research-bar__doc svg { width: 14px; height: 14px; }
.research-bar__path { font-size: var(--text-2xs); color: var(--ink-400); }
.research-bar__spinner {
  width: 14px; height: 14px; border-radius: var(--r-full);
  border: 2px solid var(--border-strong); border-top-color: var(--accent);
  animation: research-spin 0.7s linear infinite;
}
@keyframes research-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .research-bar__spinner { animation: none; } }

/* ============================================
   RESEARCH PANEL (right slide-out run trace) + RUN-EVENT stream rows
   Mirrors the modal scrim idiom; the rail slides in on .is-open. Mounted at
   document.body (survives the router clearing #view). Bottom-sheet < 720px.
   ============================================ */
.research-panel {
  position: fixed; inset: 0; z-index: 45;
  background: var(--scrim);
  opacity: 0; pointer-events: none;
  transition: opacity var(--ease-card);
}
.research-panel.is-open { opacity: 1; pointer-events: auto; }
.research-panel__rail {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: var(--research-panel-w); max-width: 100%;
  display: flex; flex-direction: column;
  background: var(--surface); box-shadow: var(--shadow-lg);
  transform: translateX(100%);
  transition: transform var(--ease-spring);
}
.research-panel.is-open .research-panel__rail { transform: translateX(0); }
.research-panel__head {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-5) var(--sp-6);
  border-bottom: 1px solid var(--border);
}
.research-panel__title {
  flex: 1 1 auto; min-width: 0;
  font-size: var(--text-lg); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight); color: var(--ink-900);
}
.research-panel__close {
  flex: 0 0 auto; display: inline-flex; padding: var(--sp-2);
  background: none; border: none; border-radius: var(--r-sm);
  color: var(--ink-400); cursor: pointer;
}
.research-panel__close:hover { color: var(--ink-800); background: var(--surface-2); }
.research-panel__body { flex: 1 1 auto; overflow-y: auto; }
.research-panel__body:empty::before {
  content: 'Waiting for the run to start…';
  display: block; padding: var(--sp-6); color: var(--ink-400); font-size: var(--text-sm);
}
.research-panel__foot:not(:empty) { border-top: 1px solid var(--border); }
.research-panel__foot-row {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-3);
  padding: var(--sp-5) var(--sp-6); font-size: var(--text-base); color: var(--ink-800);
}
.research-panel__foot-row svg { width: 16px; height: 16px; }
.research-panel__foot-row--done .research-panel__icon-done { color: var(--st-green); display: inline-flex; }
.research-panel__foot-row--error { color: var(--prio-high); }
.research-panel__foot-row--cancelled svg { color: var(--ink-400); }
.research-panel__foot-btn { margin-left: auto; }
.research-panel__totals { margin-left: auto; color: var(--ink-400); font-size: var(--text-xs); }
@media (prefers-reduced-motion: reduce) {
  .research-panel, .research-panel__rail { transition: none; }
}
@media (max-width: 720px) {
  .research-panel__rail {
    top: auto; width: 100%; height: 82vh;
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    transform: translateY(100%);
  }
  .research-panel.is-open .research-panel__rail { transform: translateY(0); }
}

/* RUN-EVENT: one streamed row (mirrors the .ledger-row anatomy): leading icon,
   label, optional mono detail, optional time. Variants tint only the icon. */
.run-event {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-6);
  border-bottom: 1px solid var(--border);
}
.run-event__icon { flex: 0 0 auto; display: inline-flex; margin-top: 1px; color: var(--ink-400); }
.run-event__icon svg { width: 15px; height: 15px; }
.run-event__main { flex: 1 1 auto; min-width: 0; }
.run-event__label { font-size: var(--text-sm); color: var(--ink-800); line-height: var(--leading-body); }
.run-event__detail {
  margin-top: var(--sp-1); font-size: var(--text-2xs); color: var(--ink-400);
  white-space: pre-wrap; word-break: break-word;
}
.run-event__time { flex: 0 0 auto; font-size: var(--text-2xs); color: var(--ink-400); }
.run-event--active .run-event__icon { color: var(--accent); }
.run-event--done .run-event__icon { color: var(--st-green); }
.run-event--error .run-event__icon { color: var(--prio-high); }

/* ============================================
   CHAT-PANEL: turn-based agent session rail (mirrors .research-panel: fixed right
   rail on --research-panel-w, scrim layer, bottom-sheet < 720px). chat.js owns the
   behavior; status gates the foot.
   ============================================ */
.chat-panel {
  position: fixed; inset: 0; z-index: 45;
  background: var(--scrim);
  opacity: 0; pointer-events: none;
  transition: opacity var(--ease-card);
}
.chat-panel.is-open { opacity: 1; pointer-events: auto; }
.chat-panel__rail {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: var(--research-panel-w); max-width: 100%;
  display: flex; flex-direction: column;
  background: var(--surface); box-shadow: var(--shadow-lg);
  transform: translateX(100%);
  transition: transform var(--ease-spring);
}
.chat-panel.is-open .chat-panel__rail { transform: translateX(0); }
.chat-panel__head {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-5) var(--sp-6);
  border-bottom: 1px solid var(--border);
}
.chat-panel__title {
  flex: 1 1 auto; min-width: 0;
  font-size: var(--text-lg); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight); color: var(--ink-900);
}
.chat-panel__close {
  flex: 0 0 auto; display: inline-flex; padding: var(--sp-2);
  background: none; border: none; border-radius: var(--r-sm);
  color: var(--ink-400); cursor: pointer;
}
.chat-panel__close:hover { color: var(--ink-800); background: var(--surface-2); }
.chat-panel__body { flex: 1 1 auto; overflow-y: auto; display: flex; flex-direction: column; }
.chat-panel__messages { display: flex; flex-direction: column; gap: var(--sp-3); padding: var(--sp-5) var(--sp-6); }
.chat-panel__trace { border-top: 1px solid var(--border); }
.chat-panel__trace-toggle {
  padding: var(--sp-3) var(--sp-6); cursor: pointer;
  font-size: var(--text-xs); color: var(--ink-400);
}
.chat-panel__trace-body { max-height: 200px; overflow-y: auto; }
.chat-panel__foot { border-top: 1px solid var(--border); padding: var(--sp-4) var(--sp-6); }
.chat-panel__state { font-size: var(--text-xs); color: var(--ink-400); padding-bottom: var(--sp-2); }
.chat-panel__state--error { color: var(--prio-high); }
.chat-panel__state--done { color: var(--st-green); }
.chat-panel__inputrow { display: flex; gap: var(--sp-3); align-items: flex-end; }
.chat-panel__input {
  flex: 1 1 auto; resize: none;
  font: inherit; font-size: var(--text-sm); color: var(--ink-900);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: var(--sp-3);
}
.chat-panel__input:disabled { background: var(--surface-2); color: var(--ink-400); }

/* CHAT-MSG: one transcript bubble. User right-aligned on accent-soft; assistant
   left-aligned on surface-2. Time mirrors run-event__time. */
.chat-msg { display: flex; flex-direction: column; max-width: 85%; }
.chat-msg--user { align-self: flex-end; align-items: flex-end; }
.chat-msg--assistant { align-self: flex-start; align-items: flex-start; }
.chat-msg__bubble {
  padding: var(--sp-3) var(--sp-4); border-radius: var(--r-md);
  font-size: var(--text-sm); color: var(--ink-900); line-height: var(--leading-body);
  white-space: pre-wrap; word-break: break-word;
}
.chat-msg--user .chat-msg__bubble { background: var(--accent-soft); }
.chat-msg--assistant .chat-msg__bubble { background: var(--surface-2); }
.chat-msg__role { margin-bottom: var(--sp-1); font-size: var(--text-2xs); font-weight: var(--weight-medium); color: var(--ink-400); }
.chat-msg__bubble code { font-family: var(--font-mono); font-size: 0.9em; background: var(--surface); padding: 0 var(--sp-1); border-radius: var(--r-sm); }
.chat-msg__time { margin-top: var(--sp-1); font-size: var(--text-2xs); color: var(--ink-400); }
@media (prefers-reduced-motion: reduce) {
  .chat-panel, .chat-panel__rail { transition: none; }
}
@media (max-width: 720px) {
  .chat-panel__rail {
    top: auto; width: 100%; height: 82vh;
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    transform: translateY(100%);
  }
  .chat-panel.is-open .chat-panel__rail { transform: translateY(0); }
}

/* ============================================
   CAPTURE-CARD: per-shoot-day capture status on the makeover page (Build Hub
   plan 04). Three layers (recap / transcripts / analysis), each carrying its
   state on a small dot (st-green done, ink-300 missing, accent spinner busy —
   the research-bar spinner treatment); the canvas stays quiet. makeover.js
   owns the actions (data-cap-* hooks) and the drag-drop is-dragover toggle.
   ============================================ */
.capture-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: var(--sp-4);
}
.capture-card {
  display: flex; flex-direction: column; gap: var(--sp-2);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: var(--sp-4);
  transition: border-color var(--ease-card), background var(--ease-card);
}
.capture-card.is-dragover { background: var(--accent-soft); border-color: var(--accent); }
.capture-card__head { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-1); }
.capture-card__day {
  font-size: var(--text-md); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight); color: var(--ink-900);
}
.capture-card__layer { display: flex; align-items: center; gap: var(--sp-2); min-height: 30px; }
.capture-card__dot {
  flex: 0 0 auto; width: 8px; height: 8px; border-radius: var(--r-full);
  background: var(--ink-300);
}
.capture-card__layer--done .capture-card__dot { background: var(--st-green); }
.capture-card__layer--busy .capture-card__dot {
  width: 12px; height: 12px; background: transparent;
  border: 2px solid var(--border-strong); border-top-color: var(--accent);
  animation: research-spin 0.7s linear infinite;
}
.capture-card__label { flex: 0 0 auto; font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--ink-800); }
.capture-card__detail {
  flex: 1 1 auto; min-width: 0; font-size: var(--text-xs); color: var(--ink-400);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.capture-card__act {
  flex: 0 0 auto; margin-left: auto;
  font-size: var(--text-xs); padding: var(--sp-1) var(--sp-3);
}
@media (prefers-reduced-motion: reduce) {
  .capture-card__layer--busy .capture-card__dot { animation: none; }
}

/* Summary block — the qualification brief (people.summary), pre-wrapped. */
.summary-block { display: flex; flex-direction: column; gap: var(--sp-2); }
.summary-block__head { display: flex; align-items: center; gap: var(--sp-3); }
.summary-block__edit {
  background: transparent; border: none; cursor: pointer; padding: var(--sp-1);
  color: var(--ink-300); border-radius: var(--r-sm); line-height: 1; display: inline-flex;
  transition: color var(--ease-default), background var(--ease-default);
}
.summary-block__edit:hover { color: var(--ink-600); background: var(--surface-2); }
.summary-block__body {
  white-space: pre-wrap; font-size: var(--text-base); color: var(--ink-800);
  line-height: var(--leading-body);
}
.summary-block__body--empty { color: var(--ink-400); }

/* Link pills — the add/removable contact-pill row + its remove control. */
.link-pills { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; margin-top: var(--sp-2); }
.link-pills__empty { font-size: var(--text-sm); color: var(--ink-400); }
.link-pills__item { display: inline-flex; align-items: center; gap: var(--sp-1); }
.link-pills__rm {
  background: transparent; border: none; cursor: pointer; padding: var(--sp-1);
  color: var(--ink-300); border-radius: var(--r-sm); line-height: 1; display: inline-flex;
  transition: color var(--ease-default), background var(--ease-default);
}
.link-pills__rm:hover { color: var(--prio-high); background: var(--surface-2); }

/* Link editor — compact add row (type select + label + url + Add). */
.link-editor { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; margin-top: var(--sp-3); }
.link-editor .input { flex: 1 1 12ch; min-width: 10ch; }
.link-editor .select-menu { flex: 0 0 auto; }

/* ICON-LINKS: Instagram-style round link chips (the personal row + each business's
   row). The chip stays neutral (surface-2 fill, thin border); the platform brand
   accent (--pf-<key>) tints ONLY the glyph, the count-pill vocabulary. The remove
   x rides the chip's corner and shows on hover; the + chip is dashed and toggles
   the scope's inline adder (.icon-link-adder, the link-editor anatomy). */
.icon-links { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; margin-top: var(--sp-2); }
.icon-link-wrap { position: relative; display: inline-flex; }
.icon-link {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: var(--r-full);
  background: var(--surface-2); border: 1px solid var(--border);
  color: var(--ink-600); cursor: pointer;
  transition: border-color var(--ease-default);
}
.icon-link svg { width: 15px; height: 15px; }
.icon-link:hover { border-color: var(--border-strong); }
.icon-link--instagram { color: var(--pf-instagram); }
.icon-link--youtube { color: var(--pf-youtube); }
.icon-link--x { color: var(--pf-x); }
.icon-link--tiktok { color: var(--pf-tiktok); }
.icon-link--linkedin { color: var(--pf-linkedin); }
.icon-link--website { color: var(--pf-website); }
.icon-link--add { background: none; border-style: dashed; color: var(--ink-400); }
.icon-link--add:hover { color: var(--accent-strong); }
/* Counted variant: the platform link pill carrying its follower count (research reach
   folded onto the link itself, so there's no separate Reach row). Icon keeps the
   platform tint; the count is neutral, mirroring .count-pill. */
.icon-link--counted { width: auto; gap: var(--sp-2); padding: 0 var(--sp-3); font-size: var(--text-sm); }
.icon-link__count { font-feature-settings: 'tnum' 1; color: var(--ink-900); font-weight: var(--weight-medium); }
.icon-link__verified { display: inline-flex; color: var(--st-blue); }
.icon-link__verified svg { width: 11px; height: 11px; }
.icon-link__rm {
  position: absolute; top: -5px; right: -5px; z-index: 1;
  display: none; align-items: center; justify-content: center;
  width: 16px; height: 16px; padding: 0; border-radius: var(--r-full);
  background: var(--surface); border: 1px solid var(--border-strong);
  color: var(--ink-400); cursor: pointer;
}
.icon-link-wrap:hover .icon-link__rm { display: inline-flex; }
.icon-link__rm:hover { color: var(--prio-high); }
.icon-link-adder[hidden] { display: none; }

/* Business cards — a founder's companies. */
.business-list { display: flex; flex-direction: column; gap: var(--sp-3); }
.business-card {
  display: flex; align-items: flex-start; gap: var(--sp-3); padding: var(--sp-4);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md);
}
.business-card__icon { color: var(--ink-400); display: inline-flex; padding-top: 1px; }
.business-card__main { display: flex; flex-direction: column; gap: var(--sp-2); min-width: 0; flex: 1 1 auto; }
.business-card__head { display: flex; align-items: baseline; gap: var(--sp-3); flex-wrap: wrap; }
.business-card__name { font-size: var(--text-lg); font-weight: var(--weight-semibold); color: var(--ink-900); letter-spacing: var(--tracking-tight); }
.business-card__role { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--ink-400); }
.business-card__blurb { font-size: var(--text-base); color: var(--ink-600); line-height: var(--leading-body); }
.business-card__links { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.business-card__rm {
  background: transparent; border: none; cursor: pointer; padding: var(--sp-2);
  color: var(--ink-300); border-radius: var(--r-sm); line-height: 1; display: inline-flex; align-self: flex-start;
  transition: color var(--ease-default), background var(--ease-default);
}
.business-card__rm:hover { color: var(--prio-high); background: var(--surface-2); }

/* Reach count pills — a neutral pill carrying a brand-tinted platform icon + a mono
   follower count (+ a verified tick). The brand color (--pf-<key>) lives ONLY on the
   icon (the splash); the pill stays on the surface-2 ramp like every other data chip. */
.count-row { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; margin-top: var(--sp-2); }
.count-pill {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-3); background: var(--surface-2);
  border: 1px solid var(--border); border-radius: var(--r-full);
  font-size: var(--text-sm); color: var(--ink-800);
}
.count-pill__icon { display: inline-flex; color: var(--ink-400); }
.count-pill__icon svg { width: 13px; height: 13px; }
.count-pill__value { font-feature-settings: 'tnum' 1; color: var(--ink-900); font-weight: var(--weight-medium); }
.count-pill__verified { display: inline-flex; color: var(--st-blue); }
.count-pill__verified svg { width: 11px; height: 11px; }
.count-pill--instagram .count-pill__icon { color: var(--pf-instagram); }
.count-pill--youtube .count-pill__icon { color: var(--pf-youtube); }
.count-pill--x .count-pill__icon { color: var(--pf-x); }
.count-pill--tiktok .count-pill__icon { color: var(--pf-tiktok); }
.count-pill--facebook .count-pill__icon { color: var(--pf-facebook); }
.count-pill--linkedin .count-pill__icon { color: var(--pf-linkedin); }
.count-pill--website .count-pill__icon { color: var(--pf-website); }

/* Social profile card — the rich "what you've shared" row for a scraped social source
   (Phase-2 socials). Layout-only: it composes the canonical avatar (photo-or-initials),
   the count-pill (brand-tinted reach), and a status-pill; the secondary stats + scrape
   feedback ("N following · M posts · scraped K · ~T tokens") ride a quiet mono sub-line.
   No new hues — neutrals + the existing --pf-<key> glyph tint only. */
.social-card {
  display: flex; align-items: center; gap: var(--sp-4);
  padding: var(--sp-3) 0; border-bottom: 1px solid var(--border-soft);
}
.social-card__main { flex: 1 1 auto; min-width: 0; }
.social-card__handle {
  color: var(--ink-900);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.social-card__name { color: var(--ink-400); }
.social-card__kind {
  font-size: var(--text-3xs); text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--ink-400); border: 1px solid var(--border); border-radius: var(--r-sm);
  padding: 1px 5px; margin-left: var(--sp-2); vertical-align: middle;
}
.social-card__sub { font-size: var(--text-2xs); color: var(--ink-400); margin-top: 2px; }

/* Dropzone — a click-or-drag file target (multi-file). The dashed frame reads as "drop here";
   the accent-soft wash + accent border on .is-dragover is the one charged state. Token-only;
   the app wires the click->file-input + drop handlers. */
.dropzone {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--sp-2); text-align: center; cursor: pointer;
  padding: var(--sp-7) var(--sp-5);
  border: 1.5px dashed var(--border); border-radius: var(--r-md);
  background: var(--surface-2); color: var(--ink-400);
  transition: border-color .15s ease, background .15s ease, color .15s ease;
}
.dropzone:hover { border-color: var(--ink-300); color: var(--ink-800); }
.dropzone.is-dragover { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-strong); }
.dropzone__icon { display: inline-flex; color: var(--ink-300); }
.dropzone__icon svg { width: 22px; height: 22px; }
.dropzone.is-dragover .dropzone__icon { color: var(--accent); }
.dropzone__hint { font-size: var(--text-sm); }
.dropzone__hint b { color: var(--ink-800); font-weight: var(--weight-medium); }
.dropzone__types { font-size: var(--text-2xs); color: var(--ink-300); letter-spacing: .02em; }

/* Bundle profile — the typed discovery context bundle rendered as labelled rows on the durable
   Overview ("company-OS home"). Layout-only, token-only: each grounded leaf shows its value + a
   provenance chip (its source citations), so the founder sees the picture the build reads from
   and where each fact came from. Composed in OpsUI.bundleProfile from the bundle_json. */
.bundle-profile { display: flex; flex-direction: column; gap: var(--sp-5); }
.bundle-section { display: flex; flex-direction: column; gap: var(--sp-1); }
.bundle-row {
  display: flex; align-items: baseline; gap: var(--sp-3);
  padding: var(--sp-2) 0; border-bottom: 1px solid var(--border-soft);
}
.bundle-row__label { flex: 0 0 130px; color: var(--ink-400); font-size: var(--text-2xs); }
.bundle-row__val { flex: 1 1 auto; min-width: 0; color: var(--ink-900); }
.bundle-row__sub { color: var(--ink-400); }
.provenance-chip {
  display: inline-block; margin-left: var(--sp-2);
  font-size: var(--text-2xs); color: var(--ink-300);
}

/* Report drop-down — the collapsible distilled founder report. Collapsed by default so
   the glanceable data (counts, links, summary) leads; the deep report sits one click
   down. Chevron rotates on open; the body animates open via the grid-rows 0fr→1fr trick
   (one overflow-hidden inner child), with the reduced-motion guard. */
.report-drop { border: 1px solid var(--border); border-radius: var(--r-md); background: var(--surface); margin-top: var(--sp-2); }
.report-drop--empty { padding: var(--sp-4); }
.report-drop__empty { font-size: var(--text-sm); color: var(--ink-400); }
.report-drop__head {
  display: flex; align-items: center; gap: var(--sp-2); width: 100%;
  padding: var(--sp-3) var(--sp-4); background: transparent; border: none; cursor: pointer;
  font-size: var(--text-base); font-weight: var(--weight-medium); color: var(--ink-800); text-align: left;
}
.report-drop__chevron { display: inline-flex; color: var(--ink-400); transition: transform var(--ease-default); }
.report-drop.is-open .report-drop__chevron { transform: rotate(90deg); }
.report-drop__body { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--ease-reveal); }
.report-drop.is-open .report-drop__body { grid-template-rows: 1fr; }
.report-drop__inner { overflow: hidden; min-height: 0; }
.report-drop.is-open .report-drop__inner { padding: 0 var(--sp-4) var(--sp-4); }
.report-drop__inner h2 {
  font-size: var(--text-2xl); font-weight: var(--weight-semibold); color: var(--ink-900);
  letter-spacing: var(--tracking-tight); margin: var(--sp-4) 0 var(--sp-2);
}
.report-drop__inner h3 {
  font-size: var(--text-lg); font-weight: var(--weight-semibold); color: var(--ink-900);
  margin: var(--sp-3) 0 var(--sp-1);
}
.report-drop__inner h2:first-child, .report-drop__inner h3:first-child { margin-top: 0; }
.report-drop__inner p { font-size: var(--text-base); color: var(--ink-800); line-height: var(--leading-body); margin: var(--sp-2) 0; }
.report-drop__inner ul, .report-drop__inner ol { margin: var(--sp-2) 0; padding-left: var(--sp-6); }
.report-drop__inner li { font-size: var(--text-base); color: var(--ink-800); line-height: var(--leading-body); margin: var(--sp-1) 0; }
.report-drop__inner strong { font-weight: var(--weight-semibold); color: var(--ink-900); }
.report-drop__inner a { color: var(--accent); text-decoration: none; }
.report-drop__inner a:hover { text-decoration: underline; }
.report-drop__inner code {
  font-family: var(--font-mono); font-size: var(--text-sm);
  background: var(--surface-2); padding: 0 var(--sp-1); border-radius: var(--r-sm);
}
@media (prefers-reduced-motion: reduce) {
  .report-drop__chevron, .report-drop__body { transition: none; }
}

/* ============================================
   EXPENSE ROW (business-finance reconciliation)
   A trip-expense line: leading wallet glyph, merchant + meta, a mono amount,
   and the reconciliation controls (trip/category selects + an action button).
   The amount is pre-formatted by App.fmtMoney; the component stays pure. A
   refund (spend opposite sign) reads money-back green via --refund.
   ============================================ */
.expense-row {
  display: flex; align-items: center; gap: var(--sp-4);
  padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--border-soft);
  flex-wrap: wrap;
}
.expense-row:last-child { border-bottom: none; }
.expense-row__lead { display: inline-flex; align-items: center; color: var(--ink-300); flex: 0 0 auto; }
.expense-row__lead svg { width: 16px; height: 16px; }
.expense-row__main { display: flex; flex-direction: column; gap: var(--sp-1); flex: 1 1 200px; min-width: 0; }
.expense-row__merchant {
  font-size: var(--text-tasktitle); font-weight: var(--weight-medium);
  color: var(--ink-800); letter-spacing: var(--tracking-snug);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.expense-row__meta { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2); }
.expense-row__date { font-family: var(--font-mono); font-size: var(--text-2xs); color: var(--ink-400); }
.expense-row__hint {
  font-family: var(--font-mono); font-size: var(--text-2xs); color: var(--ink-300);
  text-transform: uppercase; letter-spacing: var(--tracking-status);
}
.expense-row__amount {
  font-family: var(--font-mono); font-feature-settings: 'tnum' 1;
  font-size: var(--text-tasktitle); font-weight: var(--weight-semibold);
  color: var(--ink-900);
  flex: 0 0 auto; text-align: right; white-space: nowrap;
}
.expense-row--refund .expense-row__amount { color: var(--st-green); }

/* ============================================
   BUILD HUB — SYSTEM MAP (plan 06)
   The System Map page: a Cytoscape canvas + change feed off the makeover page.
   No bare `.system-map` rule: the control-panel home (#/home) already owns
   `.system-map` (radial widget) and `.sysmap-*` (pan/zoom chrome); this page
   reuses the disjoint __canvas/__list children only, so the two never collide.
   Tokens only; node colors live in --sys-* and are read by getComputedStyle.
   ============================================ */
.system-map__canvas {
  width: 100%; height: var(--sysmap-canvas-h);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); overflow: hidden;
}
.system-map__list { display: flex; flex-direction: column; gap: var(--sp-4); }
.system-map__list-group { display: flex; flex-direction: column; gap: var(--sp-2); }
.system-map__list-row {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md);
  cursor: pointer; transition: border-color var(--ease-card);
}
.system-map__list-row:hover { border-color: var(--border-strong); }
.system-map__list-name {
  flex: 1 1 auto; min-width: 0; font-size: var(--text-tasktitle);
  font-weight: var(--weight-medium); color: var(--ink-900);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.system-map__feed { margin-top: var(--sp-8); }
/* On a phone the canvas is never instantiated (system-map.js renders the list). */
@media (max-width: 719px) { .system-map__canvas { display: none; } }
@media (min-width: 720px) { .system-map__list { display: none; } }

/* SYSMAP-LAYOUT (plan 05): map 2/3 + chat 1/3. New class, not `.system-map`
   (the home tab owns that). Stacks on a phone. */
.sysmap-layout { display: grid; grid-template-columns: 2fr 1fr; gap: var(--sp-6); align-items: start; }
.sysmap-layout__main { min-width: 0; }
@media (max-width: 719px) { .sysmap-layout { grid-template-columns: 1fr; } }

/* SYSMAP-CHAT (plan 05): the "ask the map" panel — header, scrolling message
   list, input pinned at the bottom. Aligns to the canvas height on desktop. */
.sysmap-chat {
  display: flex; flex-direction: column; height: var(--sysmap-canvas-h);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); overflow: hidden;
}
.sysmap-chat__head {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--border);
}
.sysmap-chat__title { font-size: var(--text-sm); font-weight: var(--weight-semibold); color: var(--ink-900); }
.sysmap-chat__modes { display: inline-flex; background: var(--surface-2); border-radius: var(--r-full); padding: 2px; }
.sysmap-chat__modebtn {
  font: inherit; font-size: var(--text-2xs); font-weight: var(--weight-medium);
  color: var(--ink-400); background: none; border: none; cursor: pointer;
  padding: 2px var(--sp-2); border-radius: var(--r-full);
}
.sysmap-chat__modebtn.is-active { background: var(--surface); color: var(--ink-900); box-shadow: var(--shadow-sm); }
.sysmap-chat__status { color: var(--ink-400); font-style: italic; }
.sysmap-chat__messages {
  flex: 1 1 auto; overflow-y: auto; padding: var(--sp-4);
  display: flex; flex-direction: column; gap: var(--sp-3);
}
.sysmap-chat__empty { color: var(--ink-400); font-size: var(--text-sm); line-height: var(--leading-body); margin: auto 0; }
.sysmap-chat__msg {
  font-size: var(--text-sm); line-height: var(--leading-body); white-space: pre-wrap;
  padding: var(--sp-2) var(--sp-3); border-radius: var(--r-md); max-width: 92%;
}
.sysmap-chat__msg--user { align-self: flex-end; background: var(--accent); color: var(--white); }
.sysmap-chat__msg--assistant { align-self: flex-start; background: var(--surface-2); color: var(--ink-800); }
.sysmap-chat__msg.is-streaming::after { content: "▋"; color: var(--ink-400); animation: sysmap-blink 1s steps(2) infinite; }
@keyframes sysmap-blink { 50% { opacity: 0; } }
.sysmap-chat__form { display: flex; gap: var(--sp-2); padding: var(--sp-3); border-top: 1px solid var(--border); }
.sysmap-chat__input {
  flex: 1 1 auto; resize: none; font-family: inherit; font-size: var(--text-sm);
  color: var(--ink-900); background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: var(--sp-2) var(--sp-3); line-height: var(--leading-body);
}
.sysmap-chat__input:focus { outline: none; border-color: var(--accent); }
.sysmap-chat__send {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 36px; background: var(--accent); color: var(--white);
  border: none; border-radius: var(--r-md); cursor: pointer;
}
.sysmap-chat__send:disabled { opacity: 0.5; cursor: default; }
@media (max-width: 719px) { .sysmap-chat { height: 60vh; margin-top: var(--sp-6); } }

/* MAP-TOOLBAR: filter + action strip above the canvas. Wraps on a narrow view. */
.map-toolbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}
.map-toolbar__filters { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.map-toolbar__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin-left: auto; }
.map-toolbar__actions .btn-secondary { font-size: var(--text-xs); padding: var(--sp-2) var(--sp-3); }
.map-toolbar__stale { display: inline-flex; }

/* SYS-DOT: a kind-tinted dot for the kind pill (one per system kind, the --sys-*
   family — distinct from the six-hue .sdot status dots). */
.sys-dot { display: inline-block; width: 7px; height: 7px; border-radius: var(--r-full); background: var(--sys-other); }
.sys-dot--repo { background: var(--sys-repo); }
.sys-dot--database { background: var(--sys-database); }
.sys-dot--edge-function { background: var(--sys-edge-function); }
.sys-dot--site { background: var(--sys-site); }
.sys-dot--app { background: var(--sys-app); }
.sys-dot--agent { background: var(--sys-agent); }
.sys-dot--service { background: var(--sys-service); }
.sys-dot--integration { background: var(--sys-integration); }
.sys-dot--other { background: var(--sys-other); }

/* STALENESS-CHIP: freshness pill off systems.last_analyzed. The hue rides a
   leading ::before dot; the text is relative ("3h ago"). <24h fresh, <72h amber,
   older red, null grey. Research's #1 system-map failure mode is silent staleness. */
.staleness-chip {
  display: inline-flex; align-items: center; gap: var(--sp-1);
  padding: var(--sp-1) var(--sp-3); border-radius: var(--r-full);
  background: var(--surface-2); border: 1px solid var(--border);
  font-family: var(--font-mono); font-size: var(--text-2xs);
  letter-spacing: var(--tracking-status); color: var(--ink-600); white-space: nowrap;
}
.staleness-chip::before {
  content: ''; flex: 0 0 auto; width: 6px; height: 6px;
  border-radius: var(--r-full); background: var(--st-grey);
}
.staleness-chip--fresh::before { background: var(--st-green); }
.staleness-chip--amber::before { background: var(--st-amber); }
.staleness-chip--stale::before { background: var(--prio-high); }
.staleness-chip--never::before { background: var(--st-grey); }

/* CHANGE-FEED + CHANGE-ROW: day-grouped system_changes (mirrors the ledger-row /
   run-event anatomy: leading kind icon, title, optional mono ref, time). rank 1
   leads with an accent rail; digest rows carry a collapsible markdown body. */
.change-feed { display: flex; flex-direction: column; }
.change-feed--empty { padding: var(--sp-6); color: var(--ink-400); font-size: var(--text-sm); }
.change-row {
  display: flex; align-items: baseline; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--border-soft);
}
.change-row:last-child { border-bottom: none; }
.change-row--lead { border-left: 2px solid var(--accent); padding-left: calc(var(--sp-4) - 2px); }
.change-row__icon { flex: 0 0 auto; display: inline-flex; align-self: flex-start; margin-top: 2px; color: var(--ink-400); }
.change-row__icon svg { width: 15px; height: 15px; }
.change-row__title { flex: 1 1 auto; min-width: 0; font-size: var(--text-sm); color: var(--ink-800); line-height: var(--leading-body); }
.change-row__ref {
  flex: 0 0 auto; font-family: var(--font-mono); font-size: var(--text-2xs);
  color: var(--ink-400); background: var(--surface-2);
  padding: 0 var(--sp-1); border-radius: var(--r-sm);
}
.change-row__ref--link { color: var(--accent); text-decoration: none; cursor: pointer; }
.change-row__ref--link:hover { text-decoration: underline; }
.change-row__time { flex: 0 0 auto; font-family: var(--font-mono); font-size: var(--text-2xs); color: var(--ink-400); }
/* digest row: a native <details> (no JS) holding the day's markdown summary. */
.change-row--digest { display: block; padding: 0; }
.change-row__digest { width: 100%; }
.change-row__summary {
  display: flex; align-items: baseline; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4); cursor: pointer; list-style: none;
}
.change-row__summary::-webkit-details-marker { display: none; }
.change-row__summary:hover { background: var(--surface-2); }
.change-row__digest[open] .change-row__summary { border-bottom: 1px solid var(--border-soft); }
.change-row__body { padding: var(--sp-3) var(--sp-4) var(--sp-4); }
.change-row__body p { font-size: var(--text-base); color: var(--ink-800); line-height: var(--leading-body); margin: var(--sp-2) 0; }
.change-row__body h1, .change-row__body h2, .change-row__body h3, .change-row__body h4 {
  font-size: var(--text-lg); font-weight: var(--weight-semibold); color: var(--ink-900); margin: var(--sp-3) 0 var(--sp-1);
}
.change-row__body ul, .change-row__body ol { margin: var(--sp-2) 0; padding-left: var(--sp-6); }
.change-row__body li { font-size: var(--text-base); color: var(--ink-800); line-height: var(--leading-body); margin: var(--sp-1) 0; }
.change-row__body strong { font-weight: var(--weight-semibold); color: var(--ink-900); }
.change-row__body a { color: var(--accent); text-decoration: none; }
.change-row__body a:hover { text-decoration: underline; }

/* SYS-PANEL: the node detail rail. Research-panel rail geometry without the scrim
   (the canvas stays interactive). Slides in on .is-open; bottom-sheet < 720px. */
.sys-panel {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 45;
  width: var(--research-panel-w); max-width: 100%;
  display: flex; flex-direction: column;
  background: var(--surface); box-shadow: var(--shadow-lg);
  transform: translateX(100%); pointer-events: none;
  transition: transform var(--ease-spring);
}
.sys-panel.is-open { transform: translateX(0); pointer-events: auto; }
.sys-panel__head {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  padding: var(--sp-5) var(--sp-6); border-bottom: 1px solid var(--border);
}
.sys-panel__titles { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.sys-panel__name {
  font-size: var(--text-lg); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight); color: var(--ink-900);
}
.sys-panel__pills { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.sys-panel__close {
  flex: 0 0 auto; display: inline-flex; padding: var(--sp-2);
  background: none; border: none; border-radius: var(--r-sm);
  color: var(--ink-400); cursor: pointer;
}
.sys-panel__close:hover { color: var(--ink-800); background: var(--surface-2); }
.sys-panel__body { flex: 1 1 auto; overflow-y: auto; padding: var(--sp-5) var(--sp-6); display: flex; flex-direction: column; gap: var(--sp-4); }
.sys-panel__summary { font-size: var(--text-base); color: var(--ink-800); line-height: var(--leading-body); margin: 0; }
.sys-panel__field { display: flex; flex-direction: column; gap: var(--sp-2); }
.sys-panel__flabel {
  font-family: var(--font-mono); font-size: var(--text-2xs);
  text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--ink-400);
}
.sys-panel__text { font-size: var(--text-base); color: var(--ink-800); line-height: var(--leading-body); margin: 0; }
.sys-panel__shot { margin: 0; }
.sys-panel__shot img {
  display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover;
  object-position: top; border: 1px solid var(--border); border-radius: var(--r-md);
}
.sys-panel__links { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.sys-panel__linkbtn {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3); border: 1px solid var(--border);
  border-radius: var(--r-md); font-size: var(--text-sm); font-weight: var(--weight-medium);
  color: var(--ink-800); text-decoration: none; background: var(--surface);
}
.sys-panel__linkbtn:hover { background: var(--surface-2); border-color: var(--border-strong); }
.sys-panel__linkbtn svg { flex: 0 0 auto; color: var(--ink-400); }
.sys-panel__linkbtn-mark { flex: 0 0 auto; display: inline-block; }
.sys-panel__linkbtn--primary { border-color: var(--accent); color: var(--accent); }
.sys-panel__linkbtn--primary svg { color: var(--accent); }
.sys-panel__linkbtn--primary:hover { background: var(--accent-soft); border-color: var(--accent); }
.sys-schema { width: 100%; border-collapse: collapse; }
.sys-schema caption {
  text-align: left; font-family: var(--font-mono); font-size: var(--text-xs);
  font-weight: var(--weight-medium); color: var(--ink-600); padding: var(--sp-2) 0 var(--sp-1);
}
.sys-schema td { font-size: var(--text-sm); color: var(--ink-800); padding: var(--sp-1) var(--sp-3) var(--sp-1) 0; border-bottom: 1px solid var(--border-soft); }
.sys-schema td.mono { font-family: var(--font-mono); font-size: var(--text-2xs); color: var(--ink-400); }
.sys-panel__drift { display: flex; flex-direction: column; gap: var(--sp-2); }
.sys-panel__drift-row {
  display: flex; align-items: flex-start; gap: var(--sp-2);
  font-size: var(--text-sm); color: var(--st-amber); line-height: var(--leading-body);
}
.sys-panel__drift-row svg { flex: 0 0 auto; margin-top: 2px; }
.sys-panel__foot { display: flex; gap: var(--sp-3); padding: var(--sp-4) var(--sp-6); border-top: 1px solid var(--border); }
.sys-panel__foot .btn-danger { margin-left: auto; }
@media (prefers-reduced-motion: reduce) { .sys-panel { transition: none; } }
@media (max-width: 720px) {
  .sys-panel {
    top: auto; width: 100%; height: 82vh;
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    transform: translateY(100%);
  }
  .sys-panel.is-open { transform: translateY(0); }
}
/* Controls sit inline as one compact group (trip + category selects side by side,
   then the action buttons). The selects are fixed-width so they don't stretch to
   100% and stack — that's what kept the row tall. The group wraps as a unit only
   when the row is genuinely cramped (mobile). */
.expense-row__controls { display: flex; align-items: center; gap: var(--sp-2); flex: 0 0 auto; flex-wrap: wrap; }
.expense-row__controls .select-menu { width: 160px; flex: 0 0 auto; }
.expense-row__controls .select-menu__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
