/* Mission Control — Summit Launchpad palette.
   Mobile-first. Dusk ground, cream text, one green accent (#2E5E3A, sampled
   from the Summit logo). No animation except the Done strike-through and the
   Launchpad entrance reveal.

   The dashboard was originally near-white. Everything below the token block is
   unchanged by that switch: components read their colours from these variables,
   so flipping the values flips the whole surface. The handful of places that
   had hardcoded light values are converted to tokens here too, and each is
   named in the commit that did it. */

:root {
  /* --- Launchpad brand tokens (source: Notion Mission build/index.html) --- */
  --forest:     #2E5E3A;  /* Sales tile */
  --sage:       #3d7049;  /* Service tile */
  --dark-green: #26361f;  /* Marketing tile */
  --rust:       #B0492A;  /* accent line + Operations tile */
  --orange:     #E07B2C;  /* Finance tile */
  --cream:      #F3ECDC;  /* primary text */
  --brown:      #412402;  /* text on the orange tile */
  --sky:        #182516;  /* dusk sky — card surfaces */
  --page-bg:    #101711;  /* page ground */

  /* --- Dashboard semantic tokens, now pointing at the brand --- */
  --accent: var(--forest);
  --accent-soft: rgba(46, 94, 58, 0.22);
  --accent-line: rgba(46, 94, 58, 0.55);

  --bg: var(--page-bg);
  --surface: var(--sky);
  --raised: #1e2c1b;                     /* was #fafaf9 / #fcfcfb / #efefec */
  --line: rgba(243, 236, 220, 0.10);
  --line-strong: rgba(243, 236, 220, 0.22);

  --text: var(--cream);
  --text-2: rgba(243, 236, 220, 0.68);
  --text-3: rgba(243, 236, 220, 0.44);
  --on-danger: #ffffff;

  /* Danger has to invert: #b42318 on cream is legible, on dusk it is not. */
  --danger: #f2836f;
  --danger-bg: rgba(176, 73, 42, 0.20);
  --danger-line: rgba(176, 73, 42, 0.62);
  --danger-text: #f7b4a6;

  /* Warning trio — was #fffaeb / #fedf89 / #b54708 in three places. */
  --warn-bg: rgba(224, 123, 44, 0.16);
  --warn-line: rgba(224, 123, 44, 0.50);
  --warn-text: #f0b070;

  --header-bg: rgba(16, 23, 17, 0.92);

  --radius: 8px;
  --gap: 20px;

  --font: 'Montserrat', -apple-system, BlinkMacSystemFont, 'Segoe UI', Inter, Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
}

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

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* Projects — the Operations operating window. */
.projects-page { min-height: 100vh; }
.projects-top { max-width: 1440px; margin: 0 auto; padding: 42px 24px 22px; display: grid; grid-template-columns: 180px 1fr auto; gap: 24px; align-items: end; border-bottom: 1px solid var(--line); }
.projects-back { color: var(--cream); text-decoration: none; align-self: start; font-size: 12px; letter-spacing: .08em; }
.projects-kicker { color: var(--orange); letter-spacing: .18em; font-size: 10px; font-weight: 800; margin: 0 0 7px; }
.projects-top h1 { font-size: clamp(32px, 5vw, 58px); margin: 0; letter-spacing: -.04em; }
.projects-intro { color: var(--text-2); margin: 7px 0 0; max-width: 680px; }
.projects-main { max-width: 1440px; margin: 0 auto; padding: 18px 24px 56px; }
.projects-meta { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; color: var(--text-3); font-size: 11px; margin-bottom: 16px; }
.projects-board { display: grid; grid-template-columns: repeat(4, minmax(230px, 1fr)); gap: 14px; align-items: start; }
.project-lane { min-width: 0; }
.project-lane-head { font-size: 11px; letter-spacing: .13em; text-transform: uppercase; color: var(--text-2); margin: 0 0 9px; display: flex; justify-content: space-between; }
.project-lane-head span { color: var(--cream); }
.project-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); margin-bottom: 10px; overflow: hidden; }
.project-card[data-flagged] { border-color: var(--warn-line); }
.project-summary { padding: 15px; cursor: pointer; list-style: none; }
.project-summary::-webkit-details-marker { display: none; }
.project-summary h3 { margin: 13px 0 12px; font-size: 15px; line-height: 1.35; }
.project-card-top { display: flex; align-items: center; gap: 7px; font-size: 9px; letter-spacing: .08em; text-transform: uppercase; }
.project-rank { width: 23px; height: 23px; display: grid; place-items: center; border: 1px solid var(--line-strong); border-radius: 50%; }
.project-status { color: var(--orange); }
.project-owner { color: var(--text-3); margin-left: auto; text-align: right; }
.project-phase, .project-next, .project-blocker, .project-flags { margin: 0; font-size: 12px; color: var(--text-2); }
.project-phase { margin-bottom: 7px; color: var(--text-3); }
.project-phase span, .project-next span, .receipt-label { color: var(--text-3); font-size: 9px; letter-spacing: .12em; font-weight: 800; }
.project-blocker, .project-flags { margin-top: 9px; color: var(--warn-text); }
.project-receipts { border-top: 1px solid var(--line); padding: 13px 15px; background: var(--raised); color: var(--text-2); font-size: 10px; overflow-wrap: anywhere; }
.project-receipts p { margin: 0 0 7px; }
.project-empty { border: 1px dashed var(--line); padding: 15px; color: var(--text-3); font-size: 11px; }
.projects-error { max-width: 1440px; margin: 16px auto 0; padding: 13px 24px; color: var(--danger-text); background: var(--danger-bg); border-block: 1px solid var(--danger-line); font-size: 12px; font-weight: 600; }
@media (max-width: 980px) { .projects-board { grid-template-columns: repeat(2, 1fr); } .projects-top { grid-template-columns: 1fr auto; } .projects-back { grid-column: 1 / -1; } }
@media (max-width: 580px) { .projects-board { grid-template-columns: 1fr; } .projects-top { padding-top: 24px; } }

/* ------------------------------------------------------------------ header */

.header {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--header-bg);
  backdrop-filter: saturate(180%) blur(8px);
  border-bottom: 1px solid var(--line);
}

.header-inner {
  max-width: 1240px;
  margin: 0 auto;
  padding: 14px 18px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

.brand {
  display: flex;
  align-items: center;
  gap: 11px;
  min-width: 0;
}

.brand-mark {
  width: 26px;
  height: 26px;
  color: var(--accent);
  flex-shrink: 0;
}

.brand-text h1 {
  margin: 0;
  font-size: 17px;
  font-weight: 650;
  letter-spacing: -0.02em;
}

.brand-sub {
  margin: 0;
  font-size: 12px;
  color: var(--text-3);
  letter-spacing: 0.01em;
}

.sync {
  display: flex;
  align-items: center;
  gap: 12px;
}

.sync-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  line-height: 1.25;
}

.sync-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-3);
}

.sync-time {
  font-size: 13px;
  color: var(--text-2);
  font-variant-numeric: tabular-nums;
}

/* When the last attempt failed, freshness is not something to state quietly. */
.sync-time.stale {
  color: var(--danger);
  font-weight: 600;
}

.refresh {
  font: inherit;
  font-size: 13px;
  font-weight: 550;
  color: var(--accent);
  background: var(--surface);
  border: 1px solid var(--accent-line);
  border-radius: 6px;
  padding: 7px 14px;
  cursor: pointer;
}

.refresh:hover {
  background: var(--accent-soft);
}

.refresh:disabled {
  opacity: 0.5;
  cursor: default;
}

.refresh:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ------------------------------------------------------------------ banner */

.banner {
  background: var(--danger-bg);
  border-bottom: 1px solid var(--danger-line);
}

.banner-inner {
  max-width: 1240px;
  margin: 0 auto;
  padding: 14px 18px;
  border-left: 3px solid var(--danger);
}

.banner-title {
  display: block;
  color: var(--danger);
  font-size: 14px;
  font-weight: 650;
}

.banner-message {
  margin: 5px 0 0;
  color: var(--danger-text);
  font-size: 13.5px;
  overflow-wrap: anywhere;
}

.banner-detail {
  margin: 6px 0 0;
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--danger-text);
}

/* -------------------------------------------------------------------- main */

.main {
  max-width: 1240px;
  margin: 0 auto;
  padding: var(--gap) 18px 56px;
}

.loading,
.failure {
  padding: 40px 4px;
  color: var(--text-3);
  font-size: 14px;
}

.failure-title {
  margin: 0;
  color: var(--danger);
  font-weight: 650;
  font-size: 15px;
}

.failure-sub {
  margin: 6px 0 0;
  max-width: 62ch;
  color: var(--text-2);
  font-size: 13.5px;
}

/* ------------------------------------------------------------------- strip */

.strip {
  margin-bottom: var(--gap);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.strip-toggle {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 11px 14px;
  font: inherit;
  font-size: 13px;
  color: var(--text-2);
  background: none;
  border: 0;
  border-radius: var(--radius);
  cursor: pointer;
  text-align: left;
}

.strip-toggle:hover {
  background: var(--raised);
}

.strip-toggle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.strip-counts {
  display: flex;
  gap: 18px;
  flex-wrap: wrap;
}

.strip-counts b {
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.strip-chevron {
  color: var(--text-3);
  font-size: 11px;
}

.strip-toggle[aria-expanded='true'] .strip-chevron {
  transform: rotate(180deg);
}

.strip-body {
  padding: 4px 14px 14px;
  border-top: 1px solid var(--line);
  display: grid;
  gap: 18px;
}

.strip-group-title {
  margin: 12px 0 8px;
  font-size: 11px;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-3);
}

/* ------------------------------------------------------------------- board */

.board {
  display: grid;
  gap: var(--gap);
  grid-template-columns: 1fr;
}

@media (min-width: 900px) {
  .board {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: start;
  }
}

.column-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 12px;
  padding: 0 2px;
  font-size: 12px;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-2);
}

.column-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 18px;
  padding: 0 6px;
  border-radius: 9px;
  background: var(--raised);
  color: var(--text-2);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

.column-body {
  display: grid;
  gap: 10px;
}

.done-hidden {
  margin: 12px 2px 0;
  font-size: 12px;
  color: var(--text-3);
}

/* An empty column says so in words. Blankness is never the message. */
.empty {
  padding: 18px 14px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
  color: var(--text-3);
  font-size: 13px;
  text-align: center;
}

/* ------------------------------------------------------------------- stale */

/* A failed refresh keeps the last real data on screen and flags it hard
   (rulebook Rule 8). Dimmed, desaturated, and struck with a repeating STALE
   rule so it can never be mistaken for a current board -- including at a
   glance across the room, which is how a wall dashboard is actually read. */

.board.stale,
.strip.stale {
  position: relative;
  /* Reserves room for the ribbon so it can never overlap the first column
     heading on a narrow screen. */
  margin-top: 26px;
  padding-top: 10px;
  border-top: 2px solid var(--danger);
  opacity: 0.55;
  filter: saturate(0.45);
}

/* position:absolute keeps this out of grid flow -- a static ::before on a
   grid container would become a grid item and claim a cell. */
.board.stale::before,
.strip.stale::before {
  content: 'STALE — NOT CURRENT';
  position: absolute;
  top: -24px;
  left: 0;
  right: 0;
  z-index: 2;
  padding: 3px 8px;
  border-radius: 4px 4px 0 0;
  background: var(--danger);
  color: var(--on-danger);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-align: center;
}

.strip.stale {
  border-color: var(--danger-line);
}

/* Cards stay tappable while stale. The receipt records where the displayed
   data came from and when it was last edited — which is exactly what you need
   in order to check it against Notion. Blocking it would remove traceability
   at the moment traceability matters most. */

/* -------------------------------------------------------------------- card */

.card {
  position: relative;
  width: 100%;
  display: block;
  text-align: left;
  font: inherit;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 13px 14px;
  cursor: pointer;
}

.card:hover {
  border-color: var(--line-strong);
}

.card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.card-title {
  position: relative;
  display: inline;
  font-size: 14px;
  font-weight: 550;
  letter-spacing: -0.006em;
  color: var(--text);
  overflow-wrap: anywhere;
}

.card-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 9px;
}

.badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.01em;
}

.badge[data-area='Sales']     { background: rgba(176, 73, 42, 0.20);  color: #f2a08c; }
.badge[data-area='Servicing'] { background: rgba(46, 94, 58, 0.30);   color: #8fd4a1; }
.badge[data-area='Marketing'] { background: rgba(105, 65, 198, 0.24); color: #bda9f2; }
.badge[data-area='Ads']       { background: rgba(193, 21, 116, 0.22); color: #f09ac8; }
.badge[data-area='Admin']     { background: rgba(243, 236, 220, 0.10); color: rgba(243, 236, 220, 0.72); }

/* Unrecognised Area, or none set — shown literally, marked as not-a-known-value. */
.badge[data-area='__unknown'] {
  background: var(--surface);
  color: var(--text-3);
  border: 1px dashed var(--line-strong);
}

.assigned {
  font-size: 12px;
  color: var(--text-2);
}

.due {
  font-size: 12px;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}

.due.overdue {
  color: var(--danger);
  font-weight: 600;
}

/* Priority: a small dot, colour-coded, with the word for anyone not reading colour. */
.prio {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  color: var(--text-3);
}

.prio::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

.prio[data-prio='High']   { color: #ff7a6e; }
.prio[data-prio='Medium'] { color: var(--warn-text); }
.prio[data-prio='Low']    { color: rgba(243, 236, 220, 0.45); }

/* --------------------------------------------------------- agent treatment */

.card.agent {
  background: linear-gradient(0deg, var(--accent-soft), var(--accent-soft));
  border-color: var(--accent-line);
  border-left: 3px solid var(--accent);
}

.agent-hint {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 7px;
  border-radius: 4px;
  background: var(--surface);
  border: 1px solid var(--accent-line);
  color: var(--accent);
  font-size: 11px;
  font-weight: 600;
}

/* ---------------------------------------------------------- done treatment */

/* The one permitted animation: the strike-through drawing itself. */
.card.done {
  background: var(--raised);
}

.card.done .card-title {
  color: var(--text-2);
}

.card.done .card-title::after {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  height: 1px;
  background: var(--text-2);
  width: 100%;
  animation: strike 260ms ease-out both;
}

@keyframes strike {
  from { width: 0; }
  to   { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .card.done .card-title::after {
    animation: none;
    width: 100%;
  }
}

.edited {
  font-size: 12px;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------------- flags */

.flag {
  display: inline-block;
  padding: 2px 7px;
  border-radius: 4px;
  background: var(--warn-bg);
  border: 1px solid var(--warn-line);
  color: var(--warn-text);
  font-size: 11px;
  font-weight: 600;
}

/* ----------------------------------------------------------------- receipt */

/* Tapping a card swaps faces. An instant state change, not a transition --
   the strike-through is the only animation on the board. */
.card .receipt {
  display: none;
}

.card.flipped .front {
  display: none;
}

.card.flipped .receipt {
  display: block;
}

.receipt-title {
  font-size: 10px;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--accent);
  margin-bottom: 8px;
}

.receipt-row {
  display: grid;
  grid-template-columns: 84px 1fr;
  gap: 8px;
  padding: 3px 0;
  font-size: 11.5px;
}

.receipt-key {
  color: var(--text-3);
}

.receipt-val {
  font-family: var(--mono);
  color: var(--text-2);
  overflow-wrap: anywhere;
}

.receipt-hint {
  margin-top: 9px;
  font-size: 11px;
  color: var(--text-3);
}

/* ------------------------------------------------------------------ footer */

.footer {
  max-width: 1240px;
  margin: 0 auto;
  padding: 0 18px 32px;
  font-size: 11.5px;
  color: var(--text-3);
}

/* =========================================================== pulse cards ===
   Module cards above the board. Each owns its own sync stamp and failure state
   (CLAUDE.md §1) — one card failing must not visually implicate the others.
   Reuses the existing tokens and the Summit accent; no new palette. */

.pulse {
  display: grid;
  gap: var(--gap);
  grid-template-columns: 1fr;
  margin-bottom: var(--gap);
}

@media (min-width: 900px) {
  .pulse {
    grid-template-columns: repeat(3, 1fr);
    align-items: start;
  }
}

/* The CAC card spans the strip: it holds two month columns side by side. */
.pulse-card--wide {
  grid-column: 1 / -1;
}

/* The two CAC month panels — one column on phones, two on wide screens. */
.cac-months {
  display: grid;
  gap: var(--gap);
  grid-template-columns: 1fr;
  align-items: start;
}

@media (min-width: 720px) {
  .cac-months {
    grid-template-columns: 1fr 1fr;
  }
}

.cac-month {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 10px 12px;
  min-width: 0;
}

.pulse-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 15px 12px;
  min-width: 0;
}

.pulse-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}

.pulse-title {
  margin: 0;
  font-size: 13px;
  font-weight: 650;
  letter-spacing: -0.01em;
  min-width: 0;
}

.pulse-week {
  display: block;
  font-size: 11.5px;
  font-weight: 500;
  color: var(--text-2);
  letter-spacing: 0;
}

.pulse-sync {
  font-size: 11px;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  flex-shrink: 0;
}

.pulse-sync.stale {
  color: var(--danger);
  font-weight: 600;
}

.pulse-foot {
  margin: 12px 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--line);
  font-size: 10.5px;
  line-height: 1.45;
  color: var(--text-3);
}

/* Stale card: dimmed and desaturated, exactly like the stale board, plus the
   banner above it. Colour alone is never the message (rulebook Rule 8). */
.pulse-card.stale .pulse-body,
.pulse-card.stale .pulse-foot {
  opacity: 0.5;
  filter: saturate(0.4);
}

/* ----------------------------------------------------------- card alerts */

.pulse-alert {
  background: var(--danger-bg);
  border: 1px solid var(--danger-line);
  border-radius: 6px;
  padding: 9px 11px;
  margin-bottom: 12px;
}

.alert-title {
  display: block;
  font-size: 12px;
  color: var(--danger);
}

.alert-msg {
  margin: 4px 0 0;
  font-size: 11.5px;
  color: var(--text);
  overflow-wrap: anywhere;
}

.alert-detail {
  margin: 5px 0 0;
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--text-2);
  overflow-wrap: anywhere;
}

/* ------------------------------------------------------------------ stats */

.stat-block {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.stat-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 5px 0;
  border-bottom: 1px solid var(--bg);
}

.stat-row:last-child {
  border-bottom: none;
}

.stat-label {
  font-size: 12.5px;
  color: var(--text-2);
  min-width: 0;
  overflow-wrap: anywhere;
}

.stat-value-wrap {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  text-align: right;
}

.stat-value {
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.stat-value.big {
  font-size: 20px;
  font-weight: 660;
  letter-spacing: -0.02em;
}

/* "no data" is never rendered as 0 — it reads as absent, and looks it. */
.stat-value.missing {
  font-weight: 500;
  font-size: 12px;
  color: var(--text-3);
  font-style: italic;
}

.group-head {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 16px 0 7px;
  font-size: 10.5px;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-3);
}

.group-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 16px;
  padding: 0 5px;
  border-radius: 8px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  color: var(--accent);
  font-size: 10px;
  letter-spacing: 0;
}

.note {
  margin: 8px 0 0;
  font-size: 11px;
  line-height: 1.45;
  color: var(--text-3);
}

/* The machine-revenue source line: the basis stated in words on the card
   face (ruled 2026-08-15) — quiet but always visible, never tooltip-only. */
.source-note {
  color: var(--text-2);
}

/* A ⚑ note: unavailable audit days, divergence, a failed machine fetch.
   Colour plus the flag character itself, so it survives greyscale. */
.flag-note {
  color: var(--warn-text);
}

.more {
  margin: 7px 0 0;
  font-size: 11px;
  color: var(--text-3);
}

/* ------------------------------------------------------- verified badges */

.vbadge {
  display: inline-block;
  padding: 2px 7px;
  border-radius: 4px;
  font-size: 10.5px;
  font-weight: 650;
  white-space: nowrap;
}

.vbadge[data-kind='ok'] {
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  color: var(--accent);
}

.vbadge[data-kind='warn'] {
  background: var(--warn-bg);
  border: 1px solid var(--warn-line);
  color: var(--warn-text);
}

.vbadge[data-kind='bad'] {
  background: var(--danger-bg);
  border: 1px solid var(--danger-line);
  color: var(--danger);
}

/* ------------------------------------------- audit verdict chips (Sales) */
/* One chip per audited day: date + verdict, per-metric strings in the
   tooltip. Pass = green family, Needs Ruling = amber, Discrepancy = red —
   the brief's palette via the existing semantic tokens. An unknown verdict
   renders neutral with its literal value (Rule 6 pattern). */

.audit-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
}

.achip {
  display: inline-flex;
  flex-direction: column;
  gap: 2px;
  padding: 7px 11px;
  border-radius: 4px;
  border: 1px solid var(--line);
  background: var(--bg);
  cursor: help;
}

.achip-date {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.06em;
  color: var(--text-3);
}

.achip-verdict {
  font-size: 11.5px;
  font-weight: 700;
  white-space: nowrap;
}

.achip[data-verdict='pass'] {
  background: var(--accent-soft);
  border-color: var(--accent-line);
}
.achip[data-verdict='pass'] .achip-verdict { color: #8fd4a1; }

.achip[data-verdict='needs-ruling'] {
  background: var(--warn-bg);
  border-color: var(--warn-line);
}
.achip[data-verdict='needs-ruling'] .achip-verdict { color: var(--warn-text); }

.achip[data-verdict='discrepancy'] {
  background: var(--danger-bg);
  border-color: var(--danger-line);
}
.achip[data-verdict='discrepancy'] .achip-verdict { color: var(--danger-text); }

.achip[data-verdict='other'] .achip-verdict { color: var(--text-2); font-style: italic; }

/* A failed audit fetch is a visible error row, never an empty space. */
.audit-err {
  padding: 10px 14px;
  border-left: 3px solid var(--danger);
  background: var(--danger-bg);
  color: var(--danger-text);
  font-size: 12.5px;
  line-height: 1.5;
}

/* -------------------------------------------------------------- chip row */

.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 8px;
  border-radius: 5px;
  background: var(--bg);
  border: 1px solid var(--line);
  font-size: 11.5px;
  color: var(--text-2);
}

.chip b {
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

.chip[data-kind='warn'] {
  background: var(--warn-bg);
  border-color: var(--warn-line);
  color: var(--warn-text);
}

/* ------------------------------------------------------------- lead rows */

.row-list {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.row {
  position: relative;
  width: 100%;
  display: block;
  text-align: left;
  font: inherit;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 8px 10px;
  cursor: pointer;
}

.row:hover {
  border-color: var(--line-strong);
}

.row:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.row-front {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.row-main {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.row-name {
  font-size: 12.5px;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.row-sub {
  font-size: 11px;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}

.row-tail {
  display: flex;
  align-items: center;
  gap: 5px;
  flex-shrink: 0;
  flex-wrap: wrap;
  justify-content: flex-end;
}

.row-phone {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--text-3);
  white-space: nowrap;
}

/* Same instant face-swap as the board cards. */
.row .receipt {
  display: none;
}

.row.flipped .row-front {
  display: none;
}

.row.flipped .receipt {
  display: block;
}

/* --------------------------------------------------------------- sales */

.sales-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}

.sales-range {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--text-3);
}

/* ========================================================== launchpad ======
   Ported from "Notion Mission build/index.html". Class prefix is .launch, not
   .banner — .banner is already this page's red error strip.

   Everything below the tokens is the spec as-built: dusk scene, rust sun,
   pull quote, five tiles, 900px collapse, reduced-motion. */

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

.wrap {
  max-width: 1160px;
  margin: 0 auto;
  padding: 0 28px;
}

/* --- entrance reveal ------------------------------------------------------
   THE FILL MODE IS LOAD-BEARING. It must be `backwards`, never `both` or
   `forwards`.

   A fill of `both` keeps applying the animation's final frame after it ends.
   Animation styles outrank normal rules, so a finished `rise` holding
   `transform: translateY(0)` would permanently override `.tile:hover`'s lift —
   and hover would silently stop working, with nothing visibly wrong on load.

   `backwards` fills only the delay BEFORE the animation starts, then lets go
   and hands the transform back to normal CSS.

   (`.card.done .card-title::after` legitimately uses `both`: that strike-through
   must hold its final frame, and nothing there has a hover transform to lose.
   The guard test targets .reveal specifically for this reason.) */
@keyframes rise {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}

.reveal {
  animation: rise 400ms ease-out backwards;
  animation-delay: var(--delay, 0ms);
}

/* --- banner scene --------------------------------------------------------- */

.launch {
  position: relative;
  min-height: 460px;
  overflow: hidden;
  display: flex;
  align-items: stretch;
}

.launch__scene {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

.launch__content {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 1160px;
  margin: 0 auto;
  padding: 56px 28px 40px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.accent-line {
  width: 52px;
  height: 3px;
  background: var(--rust);
  margin-bottom: 26px;
}

/* Serif on purpose — the contrast is what makes this read as a pull quote
   rather than as body text. */
.quote {
  margin: 0;
  font-family: Georgia, 'Times New Roman', serif;
  font-style: italic;
  color: var(--cream);
  line-height: 1.25;
  max-width: 16em;
  font-size: clamp(27px, 4vw, 50px);
}

.attribution {
  margin: 20px 0 0;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(243, 236, 220, 0.55);
}

.lockup {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 60px;
}

.lockup__name {
  font-size: 22px;
  font-weight: 800;
  letter-spacing: 0.42em;
  color: var(--cream);
}

.lockup__tag {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(243, 236, 220, 0.45);
}

@keyframes twinkle {
  0%, 100% { opacity: 0.22; }
  50%      { opacity: 0.75; }
}

.star {
  animation: twinkle 4s ease-in-out infinite;
}

/* Only the outermost of the three sun circles breathes, across a range narrow
   enough that the banner feels alive without anything visibly moving. */
@keyframes sunPulse {
  0%, 100% { opacity: 0.09; }
  50%      { opacity: 0.17; }
}

.sun-halo {
  animation: sunPulse 8s ease-in-out infinite;
}

/* --- greeting + quick bar ------------------------------------------------- */

.greeting {
  padding-top: 32px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: rgba(243, 236, 220, 0.45);
}

.quickbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  padding-top: 18px;
  padding-bottom: 6px;
}

.quickbar__label {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: rgba(243, 236, 220, 0.38);
  margin-right: 8px;
}

.pill {
  display: inline-block;
  padding: 9px 18px;
  border: 1px solid rgba(243, 236, 220, 0.15);
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  color: rgba(243, 236, 220, 0.8);
  transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
}

.pill:hover {
  border-color: rgba(243, 236, 220, 0.42);
  background: rgba(243, 236, 220, 0.07);
  color: var(--cream);
}

.pill:focus-visible,
.tile:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 3px;
}

/* --- tiles ---------------------------------------------------------------- */

.grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 20px;
  padding-top: 26px;
  padding-bottom: 56px;
}

.tile--third { grid-column: span 2; }
.tile--half  { grid-column: span 3; }

/* The anchor IS the tile, so the whole rectangle is clickable. */
.tile {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 215px;
  padding: 26px 28px 28px;
  border-radius: 22px;
  overflow: hidden;
  color: var(--cream);
  transition: transform 0.25s ease, filter 0.25s ease, box-shadow 0.25s ease;
}

.tile:hover {
  transform: translateY(-4px);
  filter: brightness(1.12);
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.34);
}

.tile__mark {
  position: absolute;
  top: 24px;
  left: 28px;
  width: 42px;
  opacity: 0.45;
}

.tile__key {
  position: absolute;
  top: 22px;
  right: 26px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.06em;
  opacity: 0.35;
  transition: opacity 0.25s ease;
}

.tile:hover .tile__key {
  opacity: 0.7;
}

/* Marks a tile that leaves the page for Notion, so a tile that is not a live
   section never looks like one. */
.tile__out {
  position: absolute;
  bottom: 26px;
  right: 26px;
  font-size: 15px;
  opacity: 0.4;
}

/* The live number on the Sales tile. Fed from the leads payload the card
   below already receives — no separate fetch, no cache. */
.tile__stat {
  margin-bottom: 8px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.85;
  font-variant-numeric: tabular-nums;
}

.tile__name {
  font-size: 30px;
  font-weight: 800;
  letter-spacing: 0.01em;
  line-height: 1.1;
}

.tile__sub {
  margin-top: 8px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.05em;
  opacity: 0.68;
}

/* The one light tile: this cascades to the name, the sub and the ridge mark. */
.tile--finance {
  color: var(--brown);
}

/* --- in-page tile targets -------------------------------------------------
   The live-data header is sticky, so an anchor jump would otherwise land the
   section underneath it. */
html {
  scroll-behavior: smooth;
}

#card-leads,
#card-sales,
#board {
  scroll-margin-top: 84px;
}

/* --- responsive ----------------------------------------------------------- */

@media (max-width: 900px) {
  .tile--third,
  .tile--half { grid-column: span 6; }

  .tile { min-height: 165px; }
  .launch { min-height: 400px; }
  .launch__content { padding: 40px 22px 32px; }
  .wrap { padding: 0 20px; }
}

@media (prefers-reduced-motion: reduce) {
  .star { animation: none; opacity: 0.4; }
  .tile, .pill, .sc { transition: none; }
  .tile:hover { transform: none; }
  .sc:hover { transform: none; }
  html { scroll-behavior: auto; }

  /* Removing the animation also removes the `backwards` fill that was holding
     these invisible during their delay, so they simply render fully visible. */
  .reveal   { animation: none; }
  .sun-halo { animation: none; }
}

/* The Sales tile's live number, dimmed when its feed is stale. Keeping the last
   real value and marking it beats replacing it with a fresh-looking guess. */
.tile__stat.stale {
  opacity: 0.4;
  font-style: italic;
}

/* ==========================================================================
   LEADS TABLE — all channels (Attribution v2)
   Approved direction: projects/design/decision-2026-08-06-leads-table.md

   Ported from leads-table-v1.html. The mockup carried its own :root block;
   every colour it used already exists as a token here, so nothing below
   introduces a hue. The three channel scales live in app.js because they are
   presentation of DATA (a channel name -> a colour), not page furniture.

   One rule governs every choice in this block: an untagged lead must be
   impossible to ignore. If a future change makes one quieter, it is a
   regression however much cleaner it looks.
   ========================================================================== */

.leads {
  max-width: 1240px;
  margin: 0 auto 40px;
  padding: 0 var(--gap);
}

.leads-head { margin-bottom: 8px; }

.leads-title {
  margin: 0;
  font-size: clamp(26px, 3.4vw, 38px);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1;
}

.leads-lede {
  margin: 12px 0 0;
  font-size: 15px;
  line-height: 1.6;
  color: var(--text-2);
  max-width: 62ch;
}

.leads-note {
  margin: 18px 0 0;
  font-size: 13px;
  line-height: 1.7;
  color: var(--text-3);
  max-width: 78ch;
}
.leads-note b { color: var(--text-2); font-weight: 600; }

/* --- the alarm ------------------------------------------------------------
   Rendered only when untagged > 0. There is deliberately no green "all clear"
   variant: a slot that is usually reassuring is a slot the eye learns to skip,
   and this one has to still work on the day it matters. */

.leads-alarm {
  display: flex;
  align-items: center;
  gap: 22px;
  margin-top: 28px;
  padding: 24px 28px;
  flex-wrap: wrap;
  background: linear-gradient(100deg, rgba(176, 73, 42, 0.26), rgba(176, 73, 42, 0.06) 72%);
  border-left: 3px solid var(--danger);
}

@keyframes leadPing {
  0%, 100% { transform: scale(1); opacity: 1; }
  50%      { transform: scale(1.4); opacity: 0.45; }
}

.alarm-dot {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--danger);
  flex-shrink: 0;
  box-shadow: 0 0 20px rgba(242, 131, 111, 0.75);
  animation: leadPing 2.4s ease-in-out infinite;
}

.alarm-body { flex: 1; min-width: 260px; }

.alarm-title {
  margin: 0;
  font-size: 25px;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.15;
}

.alarm-msg {
  margin: 10px 0 0;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--text-2);
  max-width: 60ch;
}

/* --- the held notice (R-39, displayed per the 2026-08-12 ruling) -----------
   Amber, deliberately NOT the red alarm. Held is a different fact from
   untagged: the machine looked and refuses to guess; a person rules. It must
   not borrow the alarm's urgency and it must not be silent. No pulse — the
   machine already answered; nothing here is being missed, it is being ruled. */

.leads-held {
  display: flex;
  align-items: center;
  gap: 22px;
  margin-top: 14px;
  padding: 18px 28px;
  flex-wrap: wrap;
  background: linear-gradient(100deg, rgba(224, 123, 44, 0.20), rgba(224, 123, 44, 0.05) 72%);
  border-left: 3px solid var(--orange);
}

.held-body { flex: 1; min-width: 260px; }

.held-title {
  margin: 0;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.25;
  color: var(--warn-text);
}

.held-msg {
  margin: 8px 0 0;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-2);
  max-width: 62ch;
}

/* --- coverage ------------------------------------------------------------- */

.leads-coverage { margin-top: 34px; }

.cov-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}

.cov-big {
  font-size: clamp(28px, 3.2vw, 38px);
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.cov-pct {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  color: var(--text-3);
}

.cov-meta { text-align: right; }

/* The machine/human provenance split (R-36) — payload numbers, never
   recomputed client-side. */
.cov-split {
  margin-top: 6px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  color: var(--text-2);
}

.cov-bar { display: flex; gap: 3px; height: 32px; }

.cov-seg {
  position: relative;
  border-radius: 2px;
  min-width: 3px;
  transition: filter 0.25s ease, transform 0.25s ease;
}
.cov-seg:hover { filter: brightness(1.2); transform: translateY(-2px); }

/* The untagged segment is HATCHED, not merely red, so it reads as damage in a
   greyscale print, in a screenshot, and to a colour-blind reader. Colour alone
   is not a message. */
.cov-seg[data-untagged],
.cov-sw.hatch {
  background: repeating-linear-gradient(135deg, #B0492A 0 7px, #5c2113 7px 14px);
  box-shadow: 0 0 0 1px var(--danger) inset;
}

/* Held (R-39) is deliberately NOT hatched: the hatch means "damage — nobody
   knows". Held is answered damage — the machine wrote down why and a person
   rules. Amber fill + heavy inset ring keeps it distinct from both the flat
   channel segments and the hatched untagged one, in colour and in greyscale
   (ring weight ≠ hatch ≠ flat). */
.cov-seg[data-held],
.cov-sw.held {
  background: rgba(224, 123, 44, 0.38);
  box-shadow: 0 0 0 2px var(--orange) inset;
}

.cov-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  margin-top: 16px;
}

.cov-li {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  color: var(--text-2);
}
.cov-li b { font-variant-numeric: tabular-nums; color: var(--text); font-weight: 650; }
.cov-li[data-untagged] { color: var(--danger-text); }
.cov-li[data-untagged] b { color: var(--danger-text); }
.cov-li[data-held] { color: var(--warn-text); }
.cov-li[data-held] b { color: var(--warn-text); }

.cov-sw { width: 11px; height: 11px; border-radius: 2px; flex-shrink: 0; }

/* --- filter chips --------------------------------------------------------- */

.leads-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 26px 0 18px;
}

.fchip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 15px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: none;
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-3);
  cursor: pointer;
  transition: border-color 0.25s ease, color 0.25s ease, background 0.25s ease;
}
.fchip:hover { border-color: var(--line-strong); color: var(--text); }
.fchip[aria-pressed='true'] {
  background: rgba(243, 236, 220, 0.07);
  border-color: var(--line-strong);
  color: var(--text);
}
.fchip b { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--text-2); }
.fchip-sw { width: 9px; height: 9px; border-radius: 2px; }

.fchip[data-untagged] {
  border-color: var(--danger-line);
  color: var(--danger-text);
  background: rgba(176, 73, 42, 0.14);
}
.fchip[data-untagged] b { color: var(--text); }
.fchip[data-untagged][aria-pressed='true'] { background: rgba(176, 73, 42, 0.34); }

.fchip[data-held] {
  border-color: var(--warn-line);
  color: var(--warn-text);
  background: rgba(224, 123, 44, 0.12);
}
.fchip[data-held] b { color: var(--text); }
.fchip[data-held][aria-pressed='true'] { background: rgba(224, 123, 44, 0.30); }

/* --- table ---------------------------------------------------------------- */

.leads-tbl {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: 3px;
  overflow: hidden;
}

.leads-thead,
.lcells {
  display: grid;
  grid-template-columns: 2.1fr 1.25fr 1fr 0.55fr 0.95fr 0.8fr;
  gap: 16px;
}

.leads-thead {
  padding: 12px 20px;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}
.leads-thead span {
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-3);
}
.leads-thead .num { text-align: right; }

.lrow {
  display: block;
  width: 100%;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-left: 3px solid transparent;
  background: var(--bg);
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 0.22s ease;
}
.lrow:last-child { border-bottom: 0; }
.lrow:hover { background: var(--surface); }
.lrow:focus-visible { outline: 2px solid var(--orange); outline-offset: -2px; }

.lcells { align-items: center; padding: 15px 20px; }

.lname {
  display: block;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.012em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lsub {
  display: block;
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.06em;
  color: var(--text-3);
  margin-top: 4px;
}
.lcell { font-size: 13px; color: var(--text-2); }
.lcell.num { text-align: right; font-variant-numeric: tabular-nums; font-family: var(--mono); font-size: 12px; }
.lcell.dim { color: var(--text-3); }

/* Source chip. Warm = paid for, green = earned — the legend teaches something
   every time it is read, which arbitrary per-channel hues would not. */
.schip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 11px;
  border-radius: 3px;
  font-size: 11.5px;
  font-weight: 650;
  letter-spacing: 0.02em;
  white-space: nowrap;
  background: var(--c-bg, rgba(243, 236, 220, 0.06));
  border: 1px solid var(--c-ln, var(--line));
  color: var(--c-fg, var(--text-3));
}
.schip-dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex-shrink: 0; }
/* A channel outside the locked taxonomy: literal value, muted, never coerced. */
.schip[data-unknown] { font-style: italic; }

/* Provenance mark on a sourced chip (R-36): M = machine, H = human. Null
   Source By renders H — pre-v3 rows are unmarked and unmarked reads as human.
   The tooltip names it in words; the letter is the at-a-glance form. */
.schip-prov {
  font-family: var(--mono);
  font-size: 8px;
  font-weight: 700;
  line-height: 1;
  padding: 2px 4px;
  border-radius: 2px;
  border: 1px solid currentColor;
  opacity: 0.85;
}
.schip-prov[data-prov='machine'] { background: rgba(243, 236, 220, 0.10); }
.schip-prov[data-prov='unknown'] { font-style: italic; border-style: dashed; }

/* --- THE EMPTY STATE. Not a dash. Not a blank. An open job. --------------- */

.lrow[data-untagged] {
  border-left-color: var(--danger);
  background:
    repeating-linear-gradient(135deg, rgba(176, 73, 42, 0.13) 0 9px, transparent 9px 18px),
    rgba(176, 73, 42, 0.10);
}
.lrow[data-untagged]:hover {
  background:
    repeating-linear-gradient(135deg, rgba(176, 73, 42, 0.19) 0 9px, transparent 9px 18px),
    rgba(176, 73, 42, 0.16);
}

@keyframes leadFlash { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }

.nosrc {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border-radius: 3px;
  background: var(--danger);
  color: #3a0f04;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
}
.nosrc-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #3a0f04;
  animation: leadFlash 1.8s ease-in-out infinite;
}

/* --- HELD ⚑ (R-39) — a ruled queue, not the untagged alarm ---------------
   Distinct in colour (amber vs red) AND in monochrome (solid tint + a chip
   reading "Held ⚑" vs hatched rows + "No source"): the words carry the
   difference where colour cannot. No pulse — the machine already answered. */

.lrow[data-held] {
  border-left-color: var(--orange);
  background: rgba(224, 123, 44, 0.09);
}
.lrow[data-held]:hover { background: rgba(224, 123, 44, 0.15); }
.lrow[data-held] .lrec-title { color: var(--warn-text); }

.heldsrc {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border-radius: 3px;
  background: var(--orange);
  color: var(--brown);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
}
.heldsrc-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--brown);
}

.lrec-fix--held {
  background: rgba(224, 123, 44, 0.16);
  border-left-color: var(--orange);
}
.lrec-fix--held .lrec-btn {
  border-color: var(--warn-line);
  color: var(--warn-text);
}

/* --- receipt drawer ------------------------------------------------------- */

.lrec {
  display: none;
  padding: 0 20px 20px;
  border-top: 1px dashed var(--line-strong);
  margin-top: 2px;
}
.lrow.open .lrec { display: block; padding-top: 18px; }

.lrec-title {
  display: block;
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #8fd4a1;
  margin-bottom: 13px;
}
.lrow[data-untagged] .lrec-title { color: var(--danger-text); }

.lrec-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 10px 28px;
}
.lrec-row { display: grid; grid-template-columns: 104px 1fr; gap: 12px; padding: 3px 0; }
.lrec-key {
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-3);
}
.lrec-val { font-family: var(--mono); font-size: 11px; color: var(--text-2); overflow-wrap: anywhere; }
.lrec-val[data-danger] { color: var(--danger-text); }

.lrec-fix {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 18px;
  padding: 14px 18px;
  background: rgba(176, 73, 42, 0.18);
  border-left: 2px solid var(--danger);
}
.lrec-fix p { margin: 0; font-size: 13px; color: var(--text-2); flex: 1; min-width: 240px; }

.lrec-btn {
  padding: 9px 16px;
  border: 1px solid rgba(242, 131, 111, 0.55);
  border-radius: 3px;
  font-size: 12px;
  font-weight: 600;
  color: var(--danger-text);
  white-space: nowrap;
  text-decoration: none;
}
.lrec-btn:hover { background: rgba(242, 131, 111, 0.15); }

/* Said in words rather than rendered as a dead button. */
.lrec-nolink { font-family: var(--mono); font-size: 10px; color: var(--danger-text); }

.lrec-hint {
  display: block;
  margin-top: 15px;
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.1em;
  color: var(--text-3);
}

/* --- stale (rulebook Rule 8) ---------------------------------------------- */

/* The card above carries the error text; this says the same thing visually so
   the loudest surface on the page cannot look current while its own card says
   STALE. Colour is not the message — the card's banner is. */
.leads.stale { opacity: 0.55; filter: saturate(0.6); }

/* --- responsive ----------------------------------------------------------- */

@media (max-width: 1000px) {
  .leads-thead { display: none; }
  .lcells { grid-template-columns: 1fr auto; gap: 10px 14px; }
  .lcells > *:nth-child(n + 3) { grid-column: span 2; }
  .lcell.num { text-align: left; }
}

@media (prefers-reduced-motion: reduce) {
  /* Every colour and the hatch survive; only the motion goes. The hatch is
     what carries the meaning in the first place. */
  .alarm-dot,
  .nosrc-dot { animation: none; }
  .cov-seg,
  .fchip,
  .lrow { transition: none; }
  .cov-seg:hover { transform: none; }
}

/* ------------------------------------------------- access layer (2026-08-11) */
/* Login page + the rep-only sales page. New rules only — nothing above changes. */

.login {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 28px;
  padding: 24px;
}

.login-lockup {
  align-items: center;
  text-align: center;
}

.login-card {
  width: 100%;
  max-width: 360px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 24px;
  display: flex;
  flex-direction: column;
}

.login-title {
  margin: 0;
  font-size: 20px;
  font-weight: 800;
  letter-spacing: 0.01em;
}

.login-sub {
  margin: 4px 0 18px;
  font-size: 13px;
  color: var(--text-2);
}

.login-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-2);
  margin-bottom: 6px;
}

.login-input {
  font: inherit;
  font-size: 15px;
  color: var(--text);
  background: var(--raised);
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  padding: 9px 12px;
  margin-bottom: 16px;
}

.login-input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.login-btn {
  margin-top: 4px;
  padding: 10px 14px;
  font-size: 14px;
}

/* A failed login is stated in words, in the danger palette — never a silent no-op. */
.login-error {
  margin: 14px 0 0;
  padding: 10px 12px;
  font-size: 13px;
  color: var(--danger-text);
  background: var(--danger-bg);
  border: 1px solid var(--danger-line);
  border-radius: 6px;
}

/* Sales page: one card, centered, readable — not a three-column grid with two holes. */
.pulse.pulse--single {
  max-width: 560px;
  margin-inline: auto;
  grid-template-columns: 1fr; /* outranks the 900px three-column media rule above */
}

/* The logout link borrows the .refresh button look; being an <a>, it needs these. */
.logout-link {
  text-decoration: none;
  display: inline-block;
  line-height: normal;
}

/* ==========================================================================
   APP-SWAP NAVIGATION (ruled build 2026-08-14 — click-through mockup A)

   The page is a set of [data-view] blocks; app.js's hash router shows one at
   a time. Everything below reuses the frozen brand tokens — no new hues.
   ========================================================================== */

/* The router manages visibility with the hidden attribute; grid/flex display
   rules must never override it. */
[hidden] { display: none !important; }

/* --- sections + breadcrumbs ---------------------------------------------- */

.section { padding-bottom: 64px; }
.section--flush { padding-bottom: 8px; }

.crumb {
  display: inline-block;
  margin: 26px 0 0;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--text-2);
}
.crumb:hover { color: var(--cream); }
.crumb:focus-visible { outline: 2px solid var(--orange); outline-offset: 3px; }

.section-head { margin: 18px 0 24px; }

.kicker {
  margin: 0 0 7px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--orange);
}

.section-title {
  margin: 0;
  font-size: clamp(32px, 5vw, 58px);
  letter-spacing: -0.04em;
  line-height: 1.05;
}
.section-title--sm { font-size: clamp(24px, 3vw, 34px); }

.section-sub {
  margin: 8px 0 0;
  color: var(--text-2);
  font-size: 13px;
  max-width: 640px;
}

/* The header brand mark doubles as a home link on section views. */
.brand-home { display: inline-flex; }
.brand-home:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }

/* An inline link inside a note — readable as a link without shouting. */
.inlink { color: var(--warn-text); border-bottom: 1px solid var(--warn-line); }
.inlink:hover { color: var(--cream); }

/* --- scorecards ----------------------------------------------------------- */

.sc-grid {
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  align-items: stretch;
}

.sc-group-head { margin: 28px 0 12px; }

.sc {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px 17px;
  min-width: 0;
  transition: transform 0.2s ease, border-color 0.2s ease;
}
.sc:hover { transform: translateY(-3px); border-color: var(--line-strong); }
.sc:focus-visible { outline: 2px solid var(--orange); outline-offset: 3px; }

/* A flagged scorecard wears the danger border — the flag is the message. */
.sc--flag { border-color: var(--danger-line); }

.sc__top {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 12px;
}

.sc__label {
  font-size: 10.5px;
  font-weight: 650;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-3);
  min-width: 0;
}

.sc__badge {
  display: inline-flex;
  gap: 5px;
  flex-shrink: 0;
}

.sc__value {
  font-size: 32px;
  font-weight: 660;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

/* "no data" / "withheld" read as absent, never as a number. */
.sc__value.missing {
  font-size: 22px;
  font-weight: 500;
  color: var(--text-3);
}

.sc__sub {
  margin-top: 8px;
  font-size: 11px;
  line-height: 1.45;
  color: var(--text-3);
}

/* The audit scorecard's verdict dots — same families as the .achip chips. */
.audit-dots { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 2px; }
.audit-dot {
  width: 24px;
  height: 24px;
  border-radius: 6px;
  border: 1px solid var(--line-strong);
  background: var(--bg);
  cursor: help;
}
.audit-dot[data-verdict='pass'] { background: var(--accent-soft); border-color: var(--accent-line); }
.audit-dot[data-verdict='needs-ruling'] { background: var(--warn-bg); border-color: var(--warn-line); }
.audit-dot[data-verdict='discrepancy'] { background: var(--danger-bg); border-color: var(--danger-line); }

/* --- detail views --------------------------------------------------------- */

.detail-body { max-width: 640px; }

.detail-value {
  margin: 4px 0 10px;
  font-size: clamp(44px, 8vw, 84px);
  font-weight: 660;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.detail-value.missing {
  color: var(--text-3);
  font-weight: 500;
  font-size: clamp(28px, 5vw, 44px);
}

/* Quarantine / withheld reasoning — bordered in rust, stated in words. */
.flagnote {
  margin: 16px 0 0;
  padding: 10px 12px;
  border-left: 3px solid var(--danger);
  background: var(--danger-bg);
  border-radius: 0 6px 6px 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text);
}

/* A rehomed pulse card standing alone in a section: one readable column. */
.pulse--column {
  grid-template-columns: 1fr;
  max-width: 760px;
}

/* --- badge kinds the click-through adds ----------------------------------- */

/* Filled rust: a withheld/quarantined number. Louder than [data-kind='bad']
   because the flag IS the rendered value, not an annotation beside one. */
.vbadge[data-kind='flag'] {
  background: var(--rust);
  border: 1px solid var(--rust);
  color: var(--cream);
}

/* Dashed neutral: an unwired slot or a ruled constant — not a live claim. */
.vbadge[data-kind='dim'] {
  background: none;
  border: 1px dashed var(--line-strong);
  color: var(--text-3);
}

/* --- per-feed staleness (rulebook Rule 8, section scope) ------------------ */

/* Stated in words first — colour alone is never the message. */
.stale-note {
  margin: 0 0 18px;
  padding: 10px 14px;
  border-left: 3px solid var(--danger);
  background: var(--danger-bg);
  color: var(--danger-text);
  font-size: 12.5px;
  line-height: 1.5;
}

/* And the numbers themselves dim, exactly like the stale board. */
.section.feed-stale .sc-grid,
.section.feed-stale .detail-body {
  opacity: 0.55;
  filter: saturate(0.45);
}

/* The two live tile stats keep .tile__stat.stale from the earlier build. */

/* ==========================================================================
   SCOREBOARD (M1, 2026-08-16) — Aidan's huddle page. One column of six
   tiles, big numerals, readable on a phone. Reuses the frozen brand tokens;
   no charts, no decoration. State is said in words AND colour, never colour
   alone (Rule 8 discipline).
   ========================================================================== */

.sb-main { max-width: 760px; margin-inline: auto; }

.sb-summary {
  margin: 0 0 14px;
  font-size: 12px;
  color: var(--text-2);
  letter-spacing: .02em;
}

.sb-tiles { display: grid; grid-template-columns: 1fr; gap: 14px; }

.sb-tile {
  background: var(--surface);
  border: 1px solid var(--line);
  border-left-width: 4px;
  border-radius: var(--radius);
  padding: 14px 16px 12px;
  min-width: 0;
}
.sb-tile--ok { border-left-color: var(--forest); }
.sb-tile--flagged { border-left-color: var(--orange); }
.sb-tile--unavailable { border-left-color: var(--danger-line); }

.sb-tile__head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  margin-bottom: 8px;
}
.sb-tile__title { margin: 0; font-size: 15px; font-weight: 650; letter-spacing: -.01em; }

.sb-state {
  font-size: 10.5px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase;
  padding: 3px 8px; border-radius: 999px; white-space: nowrap; flex-shrink: 0;
}
.sb-state--ok { color: #bfe3c6; background: rgba(46, 94, 58, .35); border: 1px solid var(--accent-line); }
.sb-state--flagged { color: var(--warn-text); background: var(--warn-bg); border: 1px solid var(--warn-line); }
.sb-state--unavailable { color: var(--danger-text); background: var(--danger-bg); border: 1px solid var(--danger-line); }

.sb-figs { display: flex; flex-wrap: wrap; gap: 14px 26px; margin: 6px 0 8px; }
.sb-fig { display: flex; flex-direction: column; min-width: 0; }
.sb-fig__label { font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-3); }
.sb-fig__value {
  font-size: clamp(30px, 8vw, 44px); font-weight: 800; line-height: 1.05; letter-spacing: -.03em;
  font-variant-numeric: tabular-nums; color: var(--cream); overflow-wrap: anywhere;
}
.sb-fig__value--none { font-size: 16px; font-weight: 600; color: var(--warn-text); padding-top: 8px; }
.sb-fig__sub { font-size: 11px; color: var(--text-2); margin-top: 2px; }

.sb-line { margin: 4px 0; font-size: 12.5px; line-height: 1.45; overflow-wrap: anywhere; }
.sb-line--why {
  color: var(--danger-text); background: var(--danger-bg); border: 1px solid var(--danger-line);
  border-radius: 6px; padding: 8px 10px; font-weight: 600;
}
.sb-line--flag { color: var(--warn-text); }
.sb-line--context { color: var(--cream); font-weight: 600; }
.sb-line--muted { color: var(--text-3); font-size: 11px; }

.sb-tile__source { margin: 10px 0 0; padding-top: 8px; border-top: 1px solid var(--line); font-size: 11px; color: var(--text-2); line-height: 1.45; }
.sb-tile__source strong { color: var(--text); font-weight: 650; }
.sb-tile__asof { margin: 2px 0 0; font-size: 10.5px; color: var(--text-3); font-variant-numeric: tabular-nums; }

.sb-footer { margin: 18px 0 0; font-size: 11.5px; color: var(--text-2); text-align: center; }

/* Stale (Rule 8): the ribbon in words, then the dim. */
.sb-stale {
  margin: 0 0 12px; padding: 8px 12px; text-align: center; font-weight: 800; letter-spacing: .14em;
  color: var(--danger-text); background: var(--danger-bg); border: 1px solid var(--danger-line); border-radius: 6px;
}
.sb-tiles.stale { opacity: .5; filter: saturate(.4); }

/* ==========================================================================
   PLAYBOOKS (2026-08-18, redesigned same day to the design brief) — how
   Summit does things. Phone-first, one column, big type; a reading column of
   ~880px on desktop. Department tiles borrow the launcher's tile language
   (one brand colour each, corner count, key hint, mountain glyph, whole tile
   clickable, staggered `.reveal` entrance, hover lift). A playbook reads
   like a document: kicker, big title, one thin rust rule, the chain, two
   media buttons, then numbered step cards a tech can read in a truck.
   Nothing decorative beyond the glyph and the rust rule. Stale is said in
   words AND colour (Rule 8). Field/admin logins get this page and this
   stylesheet only.
   ========================================================================== */

/* Page ground stays the app-wide --bg so the header and every other page match; the brand dark green lives in the tiles. */
.pb-main { max-width: 880px; margin-inline: auto; padding: 22px 18px 64px; }
.pb-header .brand-text h1 { font-size: 20px; font-weight: 800; letter-spacing: -.02em; }
.pb-wordmark { margin: 0 0 1px; font-size: 10px; font-weight: 800; letter-spacing: .32em; color: var(--cream); }
.pb-wordmark span { font-weight: 600; letter-spacing: .18em; text-transform: uppercase; color: rgba(243, 236, 220, .45); font-size: 9px; margin-left: 6px; }
.pb-header .brand-mark { color: var(--forest); }
.pb-header .sync-time { max-width: 60vw; text-align: right; overflow-wrap: anywhere; }
.pb-pagefoot { text-align: center; }

/* --- shared type ---------------------------------------------------------- */
.pb-kicker { margin: 0 0 8px; font-size: 11px; font-weight: 800; letter-spacing: .2em; text-transform: uppercase; color: var(--orange); }
.pb-kicker--danger { color: var(--danger); }
.pb-lead { margin: 0; font-size: 16px; line-height: 1.5; color: var(--text-2); max-width: 46ch; }
.pb-h3 { margin: 30px 0 12px; font-size: 11px; font-weight: 800; letter-spacing: .2em; text-transform: uppercase; color: var(--text-3); }
.pb-none { margin: 0; color: var(--text-3); font-size: 15px; }
.pb-back { display: inline-block; margin: 0 0 20px; font-size: 12px; font-weight: 700; letter-spacing: .08em; color: rgba(243, 236, 220, .7); text-transform: uppercase; }
.pb-back:hover { color: var(--cream); }
.pb-glyph { position: absolute; top: 20px; left: 22px; width: 40px; opacity: .45; }

/* --- view 1 · department tiles ------------------------------------------- */
.pb-home { margin: 6px 0 22px; }
.pb-tiles { display: grid; grid-template-columns: 1fr; gap: 16px; }
.pb-tile {
  position: relative; display: flex; flex-direction: column; justify-content: flex-end;
  min-height: 168px; padding: 24px 24px 24px; border-radius: 22px; overflow: hidden;
  color: var(--cream); background: var(--forest);
  transition: transform .25s ease, filter .25s ease, box-shadow .25s ease;
}
.pb-tile:hover { transform: translateY(-4px); filter: brightness(1.12); box-shadow: 0 14px 34px rgba(0, 0, 0, .34); }
.pb-tile:focus-visible { outline: 2px solid var(--orange); outline-offset: 3px; }
.pb-tile--sales { background: var(--forest); }
.pb-tile--field { background: var(--rust); }
.pb-tile--admin { background: var(--orange); color: var(--brown); }
.pb-tile--everyone { background: transparent; border: 1.5px solid rgba(243, 236, 220, .55); }
.pb-tile--everyone:hover { background: rgba(243, 236, 220, .06); border-color: var(--cream); }
.pb-tile--error { box-shadow: inset 0 0 0 2px var(--danger); }
.pb-tile__count {
  position: absolute; top: 18px; right: 22px; font-size: 30px; font-weight: 800; letter-spacing: -.03em; line-height: 1;
  font-variant-numeric: tabular-nums; opacity: .92;
}
.pb-tile__key { position: absolute; bottom: 20px; right: 22px; font-size: 11px; font-weight: 800; letter-spacing: .06em; opacity: .38; transition: opacity .25s ease; }
.pb-tile:hover .pb-tile__key { opacity: .75; }
.pb-tile__body { display: flex; flex-direction: column; }
.pb-tile__name { font-size: 30px; font-weight: 800; letter-spacing: .01em; line-height: 1.1; }
.pb-tile__sub { margin-top: 8px; font-size: 12px; font-weight: 600; letter-spacing: .05em; opacity: .72; padding-right: 28px; }
.pb-tile__sub--error { opacity: 1; color: var(--danger-text); }
.pb-tile--admin .pb-tile__sub--error { color: #5a1a0c; }

/* --- view 2 · one department --------------------------------------------- */
.pb-dept-head { margin: 0 0 22px; }
.pb-dept-title { margin: 0; font-size: clamp(34px, 8vw, 52px); font-weight: 800; letter-spacing: -.035em; line-height: 1.02; }
.pb-dept-sub { margin: 10px 0 0; font-size: 14px; color: var(--text-2); }

.pb-start {
  display: flex; flex-direction: column; gap: 6px; padding: 20px 22px; margin: 0 0 8px;
  border-radius: 16px; background: var(--surface); border: 1px solid var(--line); border-left: 4px solid var(--orange);
  color: var(--cream); transition: transform .2s ease, border-color .2s ease, background .2s ease;
}
.pb-start:hover { transform: translateY(-2px); border-color: var(--line-strong); border-left-color: var(--orange); background: var(--raised); }
.pb-start__kicker { font-size: 10.5px; font-weight: 800; letter-spacing: .2em; text-transform: uppercase; color: var(--orange); }
.pb-start__title { font-size: 22px; font-weight: 800; letter-spacing: -.02em; line-height: 1.2; }
.pb-start__meta { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: center; font-size: 12.5px; color: var(--text-2); }

.pb-rows { display: grid; gap: 10px; }
.pb-row {
  display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 18px 20px;
  border-radius: 14px; background: var(--surface); border: 1px solid var(--line); color: var(--cream);
  transition: transform .2s ease, border-color .2s ease, background .2s ease;
}
.pb-row:hover { transform: translateY(-2px); border-color: var(--line-strong); background: var(--raised); }
.pb-row:focus-visible, .pb-start:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
.pb-row__main { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.pb-row__title { font-size: 19px; font-weight: 700; letter-spacing: -.01em; line-height: 1.25; }
.pb-row__meta { display: flex; flex-wrap: wrap; gap: 6px 12px; align-items: center; font-size: 12.5px; color: var(--text-2); }
.pb-row__go { flex-shrink: 0; font-size: 18px; color: var(--text-3); transition: color .2s ease, transform .2s ease; }
.pb-row:hover .pb-row__go { color: var(--orange); transform: translateX(3px); }
.pb-dot { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; color: #bfe3c6; }
.pb-dot::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: #6fbf85; box-shadow: 0 0 0 3px rgba(111, 191, 133, .18); }

.pb-badge { display: inline-block; font-size: 10.5px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; padding: 3px 9px; border-radius: 999px; }
.pb-badge--stale { color: var(--warn-text); background: var(--warn-bg); border: 1px solid var(--warn-line); }
.pb-doc-head .pb-badge { margin-top: 14px; }

.pb-empty {
  margin: 10px 0 0; padding: 22px 20px; border: 1px dashed var(--line-strong); border-radius: 14px;
  color: var(--text-2); font-size: 15px; line-height: 1.5; text-align: left;
}
.pb-empty strong { color: var(--cream); font-weight: 700; }

/* --- error / not-loaded — in-system, still LOUD ---------------------------- */
.pb-error {
  margin: 4px 0 20px; padding: 20px 22px; border-radius: 14px;
  background: var(--danger-bg); border: 1px solid var(--danger-line); border-left: 4px solid var(--danger);
}
.pb-error--page { margin-top: 12px; padding: 26px 24px; }
.pb-error__title { margin: 0; font-size: 20px; font-weight: 800; letter-spacing: -.02em; color: var(--danger); }
.pb-error__msg { margin: 8px 0 0; font-size: 15px; line-height: 1.5; color: var(--cream); overflow-wrap: anywhere; }
.pb-error__stage { margin: 10px 0 0; font-family: var(--mono); font-size: 12px; color: var(--danger-text); overflow-wrap: anywhere; }
.pb-problem { margin: 16px 0 0; padding: 12px 14px; border-radius: 10px; font-size: 13px; line-height: 1.5; color: var(--danger-text); background: var(--danger-bg); border: 1px solid var(--danger-line); overflow-wrap: anywhere; }
.pb-problem strong { color: var(--danger); }

/* --- view 3 · one playbook, read like a document -------------------------- */
.pb-doc { max-width: 720px; }
.pb-doc-head { margin: 0 0 22px; }
.pb-title { margin: 0; font-size: clamp(30px, 8vw, 46px); font-weight: 800; letter-spacing: -.035em; line-height: 1.05; }
.pb-rule { display: block; width: 52px; height: 3px; background: var(--rust); margin-top: 18px; }
.pb-who { display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline; margin: 16px 0 0; font-size: 15px; line-height: 1.45; color: var(--text-2); }
.pb-who__label { font-size: 10px; font-weight: 800; letter-spacing: .18em; text-transform: uppercase; color: var(--text-3); }

.pb-chain {
  display: grid; grid-template-columns: 1fr; gap: 6px; align-items: stretch;
  padding: 14px 16px; margin: 0 0 14px; border-radius: 14px; background: var(--surface); border: 1px solid var(--line);
}
.pb-chain__cell { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.pb-chain__cell--this .pb-chain__value { color: var(--cream); font-weight: 800; }
.pb-chain__label { font-size: 10px; font-weight: 800; letter-spacing: .18em; text-transform: uppercase; color: var(--text-3); }
.pb-chain__value { font-size: 14.5px; line-height: 1.4; color: var(--text-2); overflow-wrap: anywhere; }
.pb-chain__value--none { color: var(--text-3); }
.pb-chain__arrow { color: var(--text-3); font-size: 16px; line-height: 1; padding: 2px 0; }
@media (min-width: 640px) {
  .pb-chain { grid-template-columns: 1fr auto 1fr auto 1fr; gap: 14px; }
  .pb-chain__arrow { align-self: center; padding: 0; }
}

.pb-media-row { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 6px; }
.pb-media {
  display: inline-flex; align-items: center; gap: 10px; min-height: 48px; padding: 0 20px 0 16px; border-radius: 12px;
  font-size: 15px; font-weight: 700; color: var(--cream); background: var(--forest); border: 1px solid transparent;
  transition: transform .2s ease, filter .2s ease;
}
.pb-media:hover { transform: translateY(-2px); filter: brightness(1.12); }
.pb-media__glyph { font-size: 13px; opacity: .9; }
.pb-media--none { background: transparent; color: var(--text-3); border: 1px dashed var(--line-strong); font-weight: 600; cursor: default; }
.pb-media--none:hover { transform: none; filter: none; }

.pb-note { margin: 12px 0 0; font-size: 16px; line-height: 1.55; color: var(--text-2); }

.pb-section { margin: 4px 0 0; }
.pb-steps { margin: 0; padding: 0; list-style: none; display: grid; gap: 10px; counter-reset: none; }
.pb-step {
  display: grid; grid-template-columns: 44px 1fr; gap: 14px; align-items: start;
  padding: 18px 20px 18px 18px; border-radius: 16px; background: var(--surface); border: 1px solid var(--line);
}
.pb-step__n { font-size: 26px; font-weight: 800; letter-spacing: -.03em; line-height: 1; color: var(--orange); font-variant-numeric: tabular-nums; padding-top: 1px; }
.pb-step__text { font-size: 18px; line-height: 1.5; color: var(--cream); overflow-wrap: anywhere; }

.pb-bullets { margin: 0; padding: 0 0 0 20px; display: grid; gap: 8px; font-size: 16px; line-height: 1.5; color: var(--cream); }
.pb-watchout { padding: 4px 0 4px 18px; border-left: 3px solid var(--rust); }
.pb-watchout .pb-h3 { color: var(--rust); margin-top: 26px; }
.pb-better .pb-bullets { color: var(--text-2); font-size: 15px; }
.pb-transcript-section { margin-top: 30px; }
.pb-transcript { border: 1px solid var(--line); border-radius: 14px; background: var(--surface); }
.pb-transcript summary { cursor: pointer; padding: 14px 18px; font-weight: 700; font-size: 15px; color: var(--cream); list-style: none; display: flex; justify-content: space-between; align-items: center; }
.pb-transcript summary::-webkit-details-marker { display: none; }
.pb-transcript summary::after { content: '+'; color: var(--text-3); font-size: 18px; }
.pb-transcript[open] summary::after { content: '−'; }
.pb-transcript__body { padding: 0 18px 16px; font-size: 15.5px; line-height: 1.6; color: var(--text-2); }
.pb-transcript__body p { margin: 0 0 12px; }

.pb-source { display: flex; flex-direction: column; gap: 4px; margin: 34px 0 0; padding-top: 14px; border-top: 1px solid var(--line); font-size: 12px; color: var(--text-3); line-height: 1.5; overflow-wrap: anywhere; }
.pb-source__path { color: var(--text-2); font-family: var(--mono); font-size: 11.5px; }
.pb-foot { margin: 34px 0 0; font-size: 11.5px; color: var(--text-3); text-align: center; line-height: 1.6; overflow-wrap: anywhere; }

/* Links inside rendered markdown */
.pb-link { color: var(--cream); font-weight: 700; text-decoration: none; border-bottom: 2px solid var(--orange); }
.pb-link:hover { color: var(--orange); }
.pb-view a[target="_blank"]:not(.pb-media) { color: var(--warn-text); }
.pb-unwritten, .pb-elsewhere {
  display: inline-block; font-size: 10.5px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 999px; vertical-align: middle; margin-left: 4px;
}
.pb-unwritten { color: var(--warn-text); background: var(--warn-bg); border: 1px solid var(--warn-line); }
.pb-elsewhere { color: var(--text-3); border: 1px dashed var(--line-strong); }
.pb-text { color: var(--text-2); }
.pb-view code { font-family: var(--mono); font-size: .92em; padding: 1px 5px; border-radius: 4px; background: rgba(243, 236, 220, .08); }

/* Stale (Rule 8): the ribbon in words, then the dim. */
.pb-view.stale { opacity: .55; filter: saturate(.4); }

/* --- responsive + motion -------------------------------------------------- */
@media (min-width: 640px) {
  .pb-tiles { grid-template-columns: repeat(2, 1fr); gap: 20px; }
  .pb-tile { min-height: 200px; padding: 26px 28px 28px; }
  .pb-main { padding-top: 34px; }
  .pb-step__text { font-size: 17.5px; }
}
@media (prefers-reduced-motion: reduce) {
  .pb-tile, .pb-start, .pb-row, .pb-media, .pb-row__go, .pb-tile__key { transition: none; }
  .pb-tile:hover, .pb-start:hover, .pb-row:hover, .pb-media:hover { transform: none; }
  .pb-row:hover .pb-row__go { transform: none; }
}

/* --- search + Map (2026-08-18, ASG-20260818-03) ---------------------------- */
/* The box sits above the view slot so it keeps focus while hits replace the
   tiles/list. Same dark surface, cream type, orange focus ring as the rest of
   the page. Zero hits → an in-system card whose "Flag it" button is DISABLED
   (no inbox ruled, no write grant) and says so in words, not just in grey. */
.pb-search { margin: 0 0 22px; }
.pb-search__label { display: block; margin: 0 0 8px; font-size: 11px; font-weight: 800; letter-spacing: .2em; text-transform: uppercase; color: var(--text-3); }
.pb-search__box { position: relative; display: flex; align-items: center; }
.pb-search__input {
  width: 100%; min-height: 54px; padding: 0 48px 0 18px; border-radius: 14px; font: inherit; font-size: 17px; font-weight: 600;
  color: var(--cream); background: var(--surface); border: 1px solid var(--line-strong); outline: none; -webkit-appearance: none; appearance: none;
  transition: border-color .2s ease, background .2s ease;
}
.pb-search__input::placeholder { color: var(--text-3); font-weight: 500; }
.pb-search__input:focus { border-color: var(--orange); background: var(--raised); }
.pb-search__input::-webkit-search-cancel-button { display: none; }
.pb-search__clear {
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%); width: 36px; height: 36px; border-radius: 10px; border: 0;
  font: inherit; font-size: 22px; line-height: 1; color: var(--text-2); background: transparent; cursor: pointer;
}
.pb-search__clear:hover { color: var(--cream); background: rgba(243, 236, 220, .08); }
.pb-search__hint { margin: 8px 2px 0; font-size: 12px; color: var(--text-3); line-height: 1.5; }
.pb-results-head { margin: 0 0 14px; }
.pb-hit .pb-row__title { font-size: 18px; }
.pb-hit__snippet { display: block; font-size: 14px; line-height: 1.5; color: var(--text-2); overflow-wrap: anywhere; }
.pb-hit__snippet mark, .pb-hit .pb-row__title mark { background: rgba(232, 143, 40, .28); color: var(--cream); border-radius: 3px; padding: 0 2px; }
.pb-zero {
  margin: 4px 0 0; padding: 24px 22px 22px; border-radius: 16px; background: var(--surface); border: 1px solid var(--line);
  border-left: 4px solid var(--orange); display: flex; flex-direction: column; gap: 10px;
}
.pb-zero__title { margin: 0; font-size: 22px; font-weight: 800; letter-spacing: -.02em; color: var(--cream); }
.pb-zero__sub { margin: 0; font-size: 15px; line-height: 1.5; color: var(--text-2); }
.pb-flag {
  align-self: flex-start; min-height: 46px; padding: 0 20px; border-radius: 12px; border: 1px solid var(--line-strong); font: inherit; font-size: 15px; font-weight: 700;
  color: var(--text-3); background: transparent; cursor: not-allowed; margin-top: 4px;
}
.pb-flag:disabled { opacity: .7; }
.pb-zero__note { margin: 0; font-size: 12.5px; color: var(--warn-text); line-height: 1.5; }

/* the Map */
.pb-mapdept { margin: 0 0 8px; }
.pb-h3--dept { color: var(--orange); font-size: 12px; margin-top: 34px; }
.pb-h3--gaps { color: var(--warn-text); }
.pb-maplabel { margin: 18px 0 8px; font-size: 12px; font-weight: 700; letter-spacing: .04em; color: var(--text-3); }
.pb-chainlist { display: grid; gap: 6px; padding: 12px 12px 10px; margin: 0 0 12px; border-radius: 16px; background: var(--surface); border: 1px solid var(--line); }
.pb-chainlist__foot { margin: 6px 4px 0; font-size: 11.5px; color: var(--text-3); }
.pb-node {
  display: grid; grid-template-columns: 26px 1fr auto; align-items: center; gap: 8px; padding: 12px 12px 12px 8px; border-radius: 12px;
  color: var(--cream); border: 1px solid transparent; min-width: 0;
}
.pb-node--link { background: var(--raised); border-color: var(--line); transition: transform .2s ease, border-color .2s ease; }
.pb-node--link:hover { transform: translateX(3px); border-color: var(--line-strong); }
.pb-node--link:hover .pb-row__go { color: var(--orange); }
.pb-node--gap { border: 1px dashed var(--warn-line); }
.pb-node__arrow { font-size: 18px; color: var(--orange); text-align: center; line-height: 1; }
.pb-node--first .pb-node__arrow::before { content: '•'; color: var(--text-3); }
.pb-node__main { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.pb-node__title { font-size: 17px; font-weight: 700; line-height: 1.25; letter-spacing: -.01em; overflow-wrap: anywhere; }
.pb-node--gap .pb-node__title { color: var(--text-2); font-weight: 600; }
.pb-node__meta { font-size: 12px; color: var(--text-3); }
.pb-node__meta .pb-unwritten, .pb-node__meta .pb-elsewhere { margin-left: 0; }
.pb-row--tight { padding: 14px 18px; }
.pb-row--tight .pb-row__title { font-size: 17px; }
.pb-row--map { border-left: 4px solid var(--orange); margin-top: 16px; }
.pb-gapcount { color: var(--warn-text); font-weight: 700; }

.pb-gap { display: grid; grid-template-columns: 34px 1fr; gap: 12px; padding: 16px 18px 16px 14px; margin: 0 0 10px; border-radius: 14px; background: var(--surface); border: 1px solid var(--warn-line); }
.pb-gap__rank { font-size: 24px; font-weight: 800; letter-spacing: -.03em; color: var(--warn-text); line-height: 1; padding-top: 2px; font-variant-numeric: tabular-nums; }
.pb-gap__main { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.pb-gap__title { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; font-size: 18px; font-weight: 700; letter-spacing: -.01em; line-height: 1.25; color: var(--cream); }
.pb-gap__title .pb-unwritten { margin-left: 0; }
.pb-gap__count { font-size: 12.5px; font-weight: 700; color: var(--warn-text); }
.pb-gap__by { font-size: 13.5px; line-height: 1.6; color: var(--text-2); overflow-wrap: anywhere; }
.pb-gap__bylabel { color: var(--text-3); }
.pb-gap__rel { color: var(--text-3); font-size: 12px; }

.pb-idea { display: flex; flex-direction: column; gap: 6px; padding: 14px 18px; margin: 0 0 10px; border-radius: 14px; background: var(--surface); border: 1px solid var(--line); border-left: 3px solid var(--forest); }
.pb-idea__text { font-size: 15.5px; line-height: 1.5; color: var(--cream); overflow-wrap: anywhere; }
.pb-idea__from { font-size: 12.5px; color: var(--text-3); }
@media (prefers-reduced-motion: reduce) {
  .pb-node--link, .pb-search__input { transition: none; }
  .pb-node--link:hover { transform: none; }
}

/* Scoreboard · follow-up gaps who list (2026-08-18) */
.sb-who { margin: 8px 0 0; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); }
.sb-who summary { cursor: pointer; padding: 9px 12px; font-size: 12.5px; font-weight: 650; color: var(--cream); }
.sb-who__list { margin: 0; padding: 0 12px 10px; list-style: none; display: grid; gap: 8px; }
.sb-who__row { display: flex; flex-direction: column; gap: 2px; font-size: 12.5px; }
.sb-who__name { color: var(--cream); font-weight: 650; }
a.sb-who__name { border-bottom: 1px solid var(--orange); text-decoration: none; }
.sb-who__meta { font-size: 11px; color: var(--text-2); overflow-wrap: anywhere; }


/* Playbooks PWA install banner */
.pb-install {
  margin: 0 0 16px;
}
.pb-install__card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px 16px;
  border: 1.5px solid var(--forest);
  border-radius: 12px;
  background: rgba(38, 54, 31, 0.85);
  color: var(--cream);
}
.pb-install__text {
  margin: 0;
  font-size: 14px;
  line-height: 1.45;
  color: var(--cream);
}
.pb-install__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
}
.pb-install__btn {
  appearance: none;
  border: 0;
  border-radius: 8px;
  padding: 10px 14px;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .02em;
  background: var(--forest);
  color: var(--cream);
  cursor: pointer;
}
.pb-install__btn:hover { filter: brightness(1.1); }
.pb-install__dismiss {
  appearance: none;
  border: 0;
  background: transparent;
  color: rgba(243, 236, 220, 0.7);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  padding: 8px 4px;
}
.pb-install__dismiss:hover { color: var(--cream); }

/* ---------------------------------------------------------------- Ready-to-Book (2026-08-24) */
.rtb-scroll { overflow-x: auto; }
.rtb-tbl { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.rtb-tbl th { text-align: left; font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase; font-weight: 800; color: var(--text-3); padding: 6px 10px 8px; border-bottom: 1px solid var(--line-strong); white-space: nowrap; }
.rtb-tbl td { padding: 9px 10px; border-bottom: 1px solid var(--line); vertical-align: top; }
.rtb-tbl .rtb-when { font-weight: 700; white-space: nowrap; }
.rtb-tbl .mono { font-family: var(--mono); font-size: 11.5px; }
