/* Maestro Shell: design language inherited from the static board renderer of August 2026 (tokens, both themes).
   v0.4 §3: the palette is the Lean Pyramid's. Two layers of tokens:
     --lp-*      the vivid MARK colours (map squares, bars, fills, backbone bars)
     --good / --warn / --accent / --bad
                 text-safe STEPS of the same hues (labels, chart lines, chips)
   Same meaning, different step — never a different hue for the same thing.
     strategy lime   = done / good
     management orange = doing (waiting = doing, parked on a person)
     engineering cyan  = to do, and the interface accent
     risk red          = late or at risk */

:root {
  /* Lean Pyramid marks (spec §3 table) */
  --lp-strategy: #9fbf1f;
  --lp-management: #e07c0c;
  --lp-engineering: #2a93c9;
  --lp-risk: #ce2a22;
  --lp-ground: #0e1b26;
  --lp-accent: #2a93c9;
  /* brand: written by npm run brand -w maestro-shell from src/domain/brand.ts; edit it there */
  --brand-font: "Avenir Next", Avenir, "Segoe UI", system-ui, sans-serif;
  --brand-word-weight: 700;
  --brand-word-tracking: 0.16em;
  --brand-word-transform: uppercase;
  /* brand: end */

  /* Surfaces */
  --bg: #f6f7f9;
  --surface: #ffffff;
  --surface-2: #edf0f3;
  /* Transparent --surface, for panel fades: a gradient to `transparent`
     interpolates through transparent BLACK, which greys the fade. */
  --surface-0: rgba(255, 255, 255, 0);
  --ink: #1a2530;
  --ink-soft: #41505e;
  --muted: #5d6874;
  --line: #dde3e9;
  /* A field stands out from the surface it sits on (Samuel, 2026-09-28: fields
     had "almost zero contrast"). Every input, text area, select and search
     field reads these two, never a surface colour: a well a step darker than
     the sheet in the light theme, a step lighter than every surface in the
     dark one (near black cannot get darker), with a border that reads at a
     glance. */
  --field: #d9dfe6;
  --field-line: #9fadbb;

  /* Text-safe steps of the pyramid hues */
  --accent: #1b6e99;
  --accent-soft: #e2f0f9;
  --good: #556d0d;
  --good-soft: #eef4d6;
  --warn: #9a5600;
  --warn-soft: #fbeada;
  --bad: #b3241d;
  --bad-soft: #fbe3e1;
  --on-accent: #ffffff;
  --on-mark: var(--lp-ground);
  /* The core of the small light on what waits on you: the site's white on a
     dark ground, the accent's deep blue on a light one, where white is lost. */
  --wait-light-core: #1b6e99;
  /* Dependencies: a tone of their own. Blue is to do, orange is doing, green
     is done, red is late or at risk, amber is what a card still needs; violet
     is what stands between two cards, and it means nothing else anywhere. */
  --dep: #6a3fb0;
  --dep-soft: #efe8fa;
  /* What a search found: a tone of its own, magenta, worn by a found card on
     the map, the board and the backlog and meaning nothing else anywhere
     (card a-search-shows-the-card-it-found). */
  --found: #b0127a;
  --found-soft: #fbe1f1;

  /* Story map surfaces */
  --rail: #eceff2;
  --band: #eef1f4;
  --band-current: #ffffff;
  --band-hover: #dde3ea;
  --band-target: #cfdcf0;
  --sq-unready: #f7f9fb;
  --sq-line: rgba(14, 27, 38, 0.28);

  --shadow: 0 1px 3px rgba(26, 37, 48, 0.08);

  /* Chart motion — one place, both themes, all charts. easeOutCubic is the
     exact bezier of 1-(1-t)³, the curve the reference charts animate on. */
  --chart-ease: cubic-bezier(0.215, 0.61, 0.355, 1);
  --chart-draw-ms: 1100ms;   /* a line drawing itself on          */
  --chart-grow-ms: 900ms;    /* a bar growing from the baseline   */
  --chart-fade-ms: 700ms;    /* an area or band arriving          */
  --chart-pop-ms: 420ms;     /* a dot or marker landing           */
  --chart-label-ms: 420ms;   /* text settling in last             */
  --chart-label-delay: 560ms;
  --chart-bar-stagger: 34ms;
  --chart-dot-stagger: 16ms;
  --chart-band-stagger: 70ms;

  /* One board column, in both views. Four of them and their gaps fit the page
     frame, so the simple view fills it and the detail view scrolls. */
  --board-col: 17.25rem;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --lp-strategy: #b6d42b;
    --lp-management: #f0901f;
    --lp-engineering: #42b0e4;
    --lp-risk: #e5493f;
    --lp-ground: #0e1b26;
    --lp-accent: #42b0e4;

    --bg: #10161d;
    --surface: #18212b;
    --surface-2: #1f2a36;
    --surface-0: rgba(24, 33, 43, 0);
    --ink: #e8edf2;
    --ink-soft: #c3cdd6;
    --muted: #8b98a5;
    --line: #2b3844;
    --field: #2a3644;
    --field-line: #56687a;

    --accent: #42b0e4;
    --accent-soft: #14283a;
    --good: #b6d42b;
    --good-soft: #1f2a10;
    --warn: #f0901f;
    --warn-soft: #33220e;
    --bad: #f0655a;
    --bad-soft: #33191a;
    --dep: #b9a0f2;
    --dep-soft: #2a2143;
    --found: #ff5cc8;
    --found-soft: #3d1532;
    --on-accent: #0e1b26;
    --wait-light-core: #f3f6f9;
    --on-mark: #0e1b26;

    --rail: #1c2733;
    --band: #141c25;
    --band-current: #1f2a36;
    --band-hover: #2b3b4d;
    --band-target: #2a405c;
    --sq-unready: #3a4654;
    --sq-line: rgba(232, 237, 242, 0.24);

    --shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
  }
}

:root[data-theme="dark"] {
  --lp-strategy: #b6d42b;
  --lp-management: #f0901f;
  --lp-engineering: #42b0e4;
  --lp-risk: #e5493f;
  --lp-ground: #0e1b26;
  --lp-accent: #42b0e4;

  --bg: #10161d;
  --surface: #18212b;
  --surface-2: #1f2a36;
  --surface-0: rgba(24, 33, 43, 0);
  --ink: #e8edf2;
  --ink-soft: #c3cdd6;
  --muted: #8b98a5;
  --line: #2b3844;
  --field: #2a3644;
  --field-line: #56687a;

  --accent: #42b0e4;
  --accent-soft: #14283a;
  --good: #b6d42b;
  --good-soft: #1f2a10;
  --warn: #f0901f;
  --warn-soft: #33220e;
  --bad: #f0655a;
  --bad-soft: #33191a;
  --dep: #b9a0f2;
  --dep-soft: #2a2143;
  --found: #ff5cc8;
  --found-soft: #3d1532;
  --on-accent: #0e1b26;
  --wait-light-core: #f3f6f9;
  --on-mark: #0e1b26;

  --rail: #1c2733;
  --band: #141c25;
  --band-current: #1f2a36;
  --band-hover: #2b3b4d;
  --band-target: #2a405c;
  --sq-unready: #3a4654;
  --sq-line: rgba(232, 237, 242, 0.24);

  --shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  padding: 0 0.85rem 4.5rem;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--brand-font);
  line-height: 1.5;
  /* Wide content scrolls inside its own container — the page never does. */
  overflow-x: hidden;
}
.wrap { max-width: 72rem; margin: 0 auto; }
button { font: inherit; }
/* Every field takes the field tokens by default (card every-field-stands-out-
   from-the-screen-behind-it): a well set apart from the surface it sits on,
   with a border that reads at a glance. A screen's own rules size a field;
   none of them draws it on a surface colour. */
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]),
textarea,
select {
  color: var(--ink); background: var(--field); border: 1px solid var(--field-line);
}
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]):focus-visible,
textarea:focus-visible,
select:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent);
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── Header ─────────────────────────────────────────────────────────────── */
.app-header { padding: 1.1rem 0 0.4rem; }
.head-row { display: flex; align-items: center; gap: 0.6rem; }
h1 { font-size: 1.25rem; margin: 0; letter-spacing: -0.01em; flex: 1; min-width: 0; }
.live-dot {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--muted); opacity: 0.5; flex: none;
  transition: background 0.3s, opacity 0.3s;
}
.live-dot.on { background: var(--lp-strategy); opacity: 1; }

.deadlines { display: flex; gap: 0.5rem; margin: 0.6rem 0 0.2rem; overflow-x: auto; padding-bottom: 0.2rem; }
.dl {
  flex: none; display: flex; flex-direction: column; gap: 0;
  background: var(--surface); border: 1px solid var(--line); border-left: 4px solid var(--lp-engineering);
  border-radius: 8px; padding: 0.35rem 0.7rem; box-shadow: var(--shadow); min-width: 8.5rem; max-width: 16rem;
}
.dl-near { border-left-color: var(--lp-management); }
.dl-past { border-left-color: var(--muted); opacity: 0.7; }
.dl-label { font-weight: 700; font-size: 0.8rem; white-space: nowrap; }
.dl-left { font-size: 0.75rem; color: var(--accent); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.dl-near .dl-left { color: var(--warn); }
.dl-past .dl-left { color: var(--muted); }
/* Visible on touch — never hover-only. */
.dl-detail { font-size: 0.72rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ── Tabs ───────────────────────────────────────────────────────────────── */
.tabs {
  display: flex; gap: 0.25rem; margin: 0.5rem 0 0.9rem;
  background: var(--surface-2); border-radius: 10px; padding: 0.25rem;
  position: sticky; top: 0.4rem; z-index: 5;
}
.tab {
  flex: 1; text-align: center; border: 0; background: transparent; color: var(--ink-soft);
  font-weight: 600; font-size: 0.85rem; padding: 0.45rem 0.2rem; border-radius: 8px; cursor: pointer;
  min-height: 2.75rem; /* ≥44px touch target */
}
.tab[aria-selected="true"] { background: var(--surface); color: var(--ink); box-shadow: var(--shadow); }
.tab .tab-count { color: var(--muted); font-size: 0.78rem; font-variant-numeric: tabular-nums; }

/* ── Board / Flow ───────────────────────────────────────────────────────── */
/* One row of controls above the columns (Samuel's screenshot, 2026-09-26: a
   band whose only content was the view switch). The search sits at one end,
   the switch at the other, and the columns start right under them. */
.board-toolbar { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; margin: 0 0 0.6rem; flex-wrap: wrap; }
.board-find { display: flex; align-items: center; gap: 0.35rem; }
.board-search { width: 14rem; max-width: 60vw; }
/* The board scrolls sideways, as a kanban does (Samuel, 2026-09-19). Every
   column is one fixed, readable width in both views, never a fraction of the
   page frame: equal fractions squeezed the detail view's columns until each
   card was wider than its column.

   The PAGE scrolls down, and the headers stay on screen. That takes two
   strips, the same way the map does it: a box with `overflow-x: auto` is a
   scroll container on both axes, and a sticky child of one sticks to that box,
   never to the viewport. So `.board-head` sits outside the scroller and sticks
   under the tab bar, `.board-body` scrolls sideways, and views-board.js keeps
   one scrollLeft between them. `.boardbox` must stay free of any clipping of
   its own, or it becomes the scrollport. */
.boardbox { position: relative; }
/* The edge that has more columns beyond it fades, so a reader knows to scroll. */
.boardbox::before, .boardbox::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 2.2rem; z-index: 4;
  pointer-events: none; opacity: 0; transition: opacity 160ms ease;
}
.boardbox::before { left: 0; background: linear-gradient(to right, var(--bg), transparent); }
.boardbox::after { right: 0; background: linear-gradient(to left, var(--bg), transparent); }
.boardbox.more-left::before { opacity: 1; }
.boardbox.more-right::after { opacity: 1; }
.board {
  display: grid; gap: 0 0.7rem;
  grid-auto-flow: column; grid-auto-columns: 82%;
}
.board-head {
  position: sticky; top: var(--board-head-top, 3.65rem); z-index: 3;
  overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain;
  background: var(--bg);
  /* It mirrors the body's position; a bar of its own would be a second,
     lying control. */
  scrollbar-width: none;
}
.board-head::-webkit-scrollbar { display: none; }
.board-body {
  overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x proximity;
  padding-bottom: 0.5rem;
}
.board-body:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.board-body .col { scroll-snap-align: start; }
@media (min-width: 760px) {
  .board { grid-auto-columns: var(--board-col); }
  .board-body { scroll-snap-type: none; }
}
.col-head { background: var(--surface-2); border-radius: 10px 10px 0 0; padding: 0.6rem 0.6rem 0; min-width: 0; }
.col { background: var(--surface-2); border-radius: 0 0 10px 10px; padding: 0 0.6rem 0.6rem; min-width: 0; }
.col-title { display: flex; align-items: center; flex-wrap: wrap; gap: 0.45rem; font-size: 0.9rem; font-weight: 700; margin: 0 0 0.1rem; padding: 0 0.2rem; }
.col-title-btn {
  width: 100%; border: 0; background: transparent; color: var(--ink);
  cursor: pointer; text-align: left; min-height: 2.75rem; border-radius: 8px;
}
.col-title-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.col-count { font-size: 0.75rem; color: var(--muted); font-weight: 600; font-variant-numeric: tabular-nums; }
.col-cards { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.55rem; padding-top: 0.5rem; }
.col-more { font-size: 0.76rem; color: var(--muted); text-align: center; padding: 0.2rem; }

.wip-chip {
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.04em;
  color: var(--accent); background: var(--accent-soft); padding: 0.1rem 0.5rem; border-radius: 99px;
}
.wip-chip.over { color: var(--bad); background: var(--bad-soft); }

/* A band's limit, said on every column the band is drawn across. Outlined
   rather than filled, so it never reads as the column's own badge. */
.band-chip {
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.04em;
  color: var(--muted); border: 1px solid var(--line); padding: 0.1rem 0.5rem; border-radius: 99px;
}
.band-chip.over { color: var(--bad); border-color: var(--bad); }

.limit-row { display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem; }
.limit-scope { font-weight: 600; }
.limit-number { color: var(--muted); font-variant-numeric: tabular-nums; }

.card {
  background: var(--surface); border-radius: 8px; padding: 0.55rem 0.7rem;
  box-shadow: var(--shadow); border-top: 3px solid var(--line);
  cursor: pointer; text-align: left; width: 100%; border-left: 0; border-right: 0; border-bottom: 0;
  color: var(--ink); min-height: 2.75rem;
  /* A card is never wider than its column: it may shrink below its longest
     word, and a word longer than the column breaks where it must. */
  min-width: 0; max-width: 100%; overflow-wrap: anywhere;
}
.card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.card-todo { border-top-color: var(--lp-engineering); }
/* Queued but not ready to develop: the same neutral tone the map wears, white
   before blue, with the dashed edge, so the board says what is still being
   shaped without a chip. The needs chip beside it says what is missing. */
.card-todo.card-unready { border-top-color: var(--muted); border-top-style: dashed; background: var(--sq-unready); box-shadow: var(--shadow), inset 0 0 0 1px var(--line); }
.card-doing { border-top-color: var(--lp-management); }
.card-waiting { border-top-color: var(--lp-management); background: var(--warn-soft); }
.card-done { border-top-color: var(--lp-strategy); }
.card-dropped { border-top-color: var(--muted); opacity: 0.65; }
.card-aging { outline: 2px solid var(--lp-management); outline-offset: -2px; }
/* Red means late OR explicitly at risk (spec §0.4) — on cards too. */
.card-red { outline: 2px solid var(--lp-risk); outline-offset: -2px; }
.card-title { margin: 0; font-size: 0.88rem; line-height: 1.35; font-weight: 600; }
.card-note { margin: 0.3rem 0 0; font-size: 0.78rem; color: var(--ink-soft); overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.card-meta { display: flex; flex-wrap: wrap; gap: 0.35rem 0.6rem; margin-top: 0.4rem; align-items: baseline; min-width: 0; }
.card-epic {
  font-size: 0.66rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--accent); background: var(--accent-soft); padding: 0.05rem 0.45rem; border-radius: 99px;
  /* Names are the flow's own and have no length limit: the chip shortens to
     the card and carries the full name as its title. */
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.card-release {
  font-size: 0.66rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--ink-soft); background: var(--surface-2); padding: 0.05rem 0.45rem; border-radius: 99px;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Who holds the card, on the card (card everyone-can-see-who-is-working-on-what-right-now). */
.card-holder { font-size: 0.74rem; color: var(--accent); font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.card-age { font-size: 0.72rem; color: var(--muted); font-variant-numeric: tabular-nums; }
/* Aging, worn: past the column's threshold the age turns amber. */
.card-age-stale {
  font-weight: 700; color: var(--warn); background: var(--warn-soft);
  padding: 0.05rem 0.45rem; border-radius: 99px;
}
.card-state-chip {
  font-size: 0.66rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--muted); background: var(--surface-2); padding: 0.05rem 0.45rem; border-radius: 99px;
}
/* A column's count of stale cards, on its header, in the warning tone. */
.stale-chip {
  font-size: 0.68rem; font-weight: 700; color: var(--warn); background: var(--warn-soft);
  padding: 0.05rem 0.45rem; border-radius: 99px; margin-left: 0.35rem;
}
.aging-badge {
  font-size: 0.68rem; font-weight: 700; color: var(--warn); background: var(--warn-soft);
  padding: 0.05rem 0.45rem; border-radius: 99px;
}
.red-chip {
  font-size: 0.66rem; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--bad); background: var(--bad-soft); padding: 0.05rem 0.45rem; border-radius: 99px;
}
/* The readiness verdict, worn: amber, clickable, one press from the fix. */
.needs-chip {
  font-size: 0.68rem; font-weight: 700; color: var(--warn); background: var(--warn-soft);
  padding: 0.05rem 0.45rem; border-radius: 99px; cursor: pointer;
}
.needs-chip:hover, .needs-chip:focus-visible { text-decoration: underline; outline-offset: 2px; }
.sheet-needs { margin: 0 0 0.6rem; font-size: 0.8rem; font-weight: 600; color: var(--warn); }
/* Blocked by, worn: one chip per blocker, each a doorway to the blocker's sheet. */
.blocked-chip {
  font-size: 0.68rem; font-weight: 700; color: var(--bad); background: var(--bad-soft);
  padding: 0.05rem 0.45rem; border-radius: 99px; cursor: pointer;
}
.blocked-chip:hover, .blocked-chip:focus-visible { text-decoration: underline; outline-offset: 2px; }
/* The plan's order, broken: the card sits in a release and waits on work
   planned after it. Dependency tone, because it is a fact about a link; filled
   the other way round from the count so the two are never confused. */
.order-chip {
  font-size: 0.68rem; font-weight: 700; color: var(--surface); background: var(--dep);
  padding: 0.05rem 0.45rem; border-radius: 99px; max-width: 100%;
}
.sq-order { outline: 2px dashed var(--dep); outline-offset: -3px; }
.forecast-warning {
  margin: 0.2rem 0 0.8rem; padding: 0.6rem 0.8rem; border-radius: 10px; font-size: 0.86rem; line-height: 1.5;
  color: var(--ink); background: var(--dep-soft); border: 1px solid var(--dep); border-left-width: 4px;
}
.forecast-warning strong { color: var(--dep); }
.release-decisions { margin: 0.2rem 0 0.8rem; font-size: 0.84rem; color: var(--ink-soft); line-height: 1.5; }
/* What a card holds up, worn: a count in the dependency tone. On a decision it
   leads, right under the question, a size up from the other chips. */
.holds-chip {
  font-size: 0.68rem; font-weight: 700; color: var(--dep); background: var(--dep-soft);
  padding: 0.05rem 0.45rem; border-radius: 99px; max-width: 100%;
}
.holds-chip-lead { display: inline-block; font-size: 0.78rem; padding: 0.12rem 0.6rem; margin-top: 0.35rem; }
/* The same count on the map, in the card's corner; the title makes room for it. */
.sq-has-holds { padding-right: 1.35rem; }
.sq-holds {
  position: absolute; top: 2px; right: 2px; min-width: 1.05rem; height: 1.05rem; padding: 0 0.2rem;
  border-radius: 99px; background: var(--dep); color: var(--surface);
  font-size: 0.62rem; font-weight: 800; font-style: normal; line-height: 1.05rem; text-align: center;
  box-shadow: 0 0 0 1.5px var(--surface);
}
/* The sheet's dependencies block, both directions. Something open in the
   card's way: the dependency tone, an icon, and the sentence that says it
   cannot start. Only holding others up: the tone's rule, no warning. Nothing
   either way: one quiet line and the control. */
.dep-block { display: grid; gap: 0.7rem; border-radius: 10px; }
.dep-block-active {
  background: var(--dep-soft); border: 1px solid var(--dep); border-left-width: 4px;
  padding: 0.7rem 0.8rem;
}
.dep-block-holding { border-left: 4px solid var(--dep); padding: 0.1rem 0 0.1rem 0.8rem; }
.dep-block-quiet { gap: 0.3rem; }
.dep-warning { display: flex; align-items: center; gap: 0.45rem; margin: 0; font-size: 0.86rem; font-weight: 700; color: var(--dep); }
.dep-icon { color: var(--dep); font-size: 1rem; line-height: 1; margin-right: 0.3rem; }
.dep-warning .dep-icon { margin-right: 0; }
.dep-block-active .sheet-label, .dep-block-holding .sheet-label { color: var(--dep); }
.holds-block { display: grid; gap: 0.3rem; }
.dependent-release {
  font-size: 0.66rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--ink-soft); background: var(--surface-2); padding: 0.05rem 0.45rem; border-radius: 99px;
  max-width: 45%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: none;
}
.dep-block-active .dependent-release { background: var(--surface); }
/* The Blocked by half: rows that open the blocker, a remove ✕, a searchable picker that adds one. */
.blocked-block { display: grid; gap: 0.45rem; }
.blocker-list { display: grid; gap: 0.25rem; }
.blocker-row { display: flex; align-items: center; gap: 0.5rem; min-height: 2.75rem; }
.blocker-link {
  border: none; background: none; padding: 0; font: inherit; font-size: 0.86rem; font-weight: 600;
  color: var(--ink); cursor: pointer; text-align: left;
}
.blocker-link:hover, .blocker-link:focus-visible { text-decoration: underline; }
.blocker-state { font-size: 0.72rem; color: var(--muted); }
.blocker-remove {
  margin-left: auto; border: none; background: none; color: var(--muted); cursor: pointer;
  font-size: 0.8rem; padding: 0.2rem 0.4rem; line-height: 1;
}
.blocker-remove:hover, .blocker-remove:focus-visible { color: var(--bad); }
.blocker-empty { margin: 0; }

/* Notes on the card: a person's direction, worn as a quiet chip and read in the sheet. */
.notes-chip {
  font-size: 0.68rem; font-weight: 700; color: var(--ink-soft); background: var(--surface-2);
  padding: 0.05rem 0.45rem; border-radius: 99px;
}
.notes-block { display: grid; gap: 0.4rem; margin: 0.9rem 0; }
.note-list { display: grid; gap: 0.5rem; }
.note-row {
  display: grid; gap: 0.15rem; padding: 0.4rem 0.55rem;
  background: var(--surface-2); border-radius: 6px; border-left: 3px solid var(--line);
}
/* A reply sits under the note it answers, set in from its margin, on the accent (card a-note-is-answered-where-it-was-left). */
.note-row.note-reply { margin-left: 1.25rem; border-left-color: var(--accent); }
.note-author { margin: 0; font-size: 0.72rem; font-weight: 600; color: var(--muted); }
.note-text { margin: 0; font-size: 0.86rem; color: var(--ink); white-space: pre-wrap; }
.note-empty { margin: 0; }
.note-actions { justify-content: flex-end; }
.feed-note .feed-detail { color: var(--ink); }
.feed-rated .feed-detail { color: var(--ink); }

/* ── Rating attribution (backlog round, step 12) ────────────────────────── */
/* The number, its author and the line behind it, stacked under each ladder. */
.rating-row { align-items: start; }
.rating-field { display: grid; gap: 0.3rem; }
.rating-line { margin: 0; font-size: 0.74rem; color: var(--muted); }
.rating-reason { font-size: 0.82rem; }
/* The mark a backlog row wears while no person has confirmed its numbers. */
.agent-rated-dot {
  align-self: center; width: 0.5rem; height: 0.5rem; flex: 0 0 auto;
  border-radius: 99px; background: var(--accent, var(--muted));
}

/* ── Size / value / risk chips ──────────────────────────────────────────── */
/* Neutral by design: size is not a state, so it never borrows a state hue. */
.size-chip {
  font-size: 0.66rem; font-weight: 700; letter-spacing: 0.04em;
  padding: 0.05rem 0.45rem; border-radius: 4px;
  color: var(--ink-soft); background: var(--surface-2); border: 1px solid var(--line);
}
.size-xl, .size-l { border-color: var(--ink-soft); color: var(--ink); font-weight: 800; }
.size-unsized { border-style: dashed; color: var(--muted); }
.vr-chip {
  font-size: 0.68rem; font-weight: 700; color: var(--ink-soft); background: var(--surface-2);
  padding: 0.05rem 0.45rem; border-radius: 99px; font-variant-numeric: tabular-nums;
}
.vr-chip.warn { color: var(--warn); background: var(--warn-soft); }
.vr-chip.bad { color: var(--bad); background: var(--bad-soft); }

/* ── Cockpit ────────────────────────────────────────────────────────────── */
.release-row { display: flex; align-items: center; flex-wrap: wrap; gap: 0.4rem 0.6rem; margin: 0 0 0.7rem; }
.release-status { display: flex; align-items: center; flex-wrap: wrap; gap: 0.3rem 0.5rem; }
.release-forecast-inline { font-size: 0.8rem; font-weight: 600; color: var(--ink-soft); }
.release-forecast-range { font-weight: 400; color: var(--muted); }
.release-select {
  flex: 1; min-width: 0; font: inherit; font-weight: 600; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line); border-radius: 8px;
  padding: 0.55rem 0.7rem; min-height: 2.75rem;
}
.release-intent { margin: -0.4rem 0 0.8rem; font-size: 0.82rem; color: var(--ink-soft); }
.status-chip {
  flex: none; font-size: 0.72rem; font-weight: 800; letter-spacing: 0.06em;
  padding: 0.35rem 0.7rem; border-radius: 99px;
}
/* A provisional forecast passes no verdict: quiet, neither good nor bad. */
.status-provisional { color: var(--ink-soft); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line); }
.status-ok { color: var(--good); background: var(--good-soft); }
.status-risk { color: var(--warn); background: var(--warn-soft); }
.status-late { color: var(--bad); background: var(--bad-soft); box-shadow: inset 0 0 0 2px var(--lp-risk); }

.forecast-band {
  display: grid; gap: 0.7rem; margin: 0.9rem 0;
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
  padding: 0.9rem 1rem; box-shadow: var(--shadow);
}
@media (min-width: 760px) { .forecast-band { grid-template-columns: 1.2fr 1fr 1fr; } }
.band-title { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); margin-bottom: 0.3rem; }
.band-dates { display: flex; align-items: baseline; gap: 0.7rem; flex-wrap: wrap; }
.band-likely { font-size: 1.6rem; letter-spacing: -0.01em; }
.band-side { font-size: 0.78rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.vel-bar-row { display: flex; align-items: center; gap: 0.5rem; margin: 0.25rem 0; }
.vel-bar-label { width: 3rem; font-size: 0.74rem; color: var(--muted); }
.vel-bar-track { flex: 1; height: 10px; background: var(--surface-2); border-radius: 99px; overflow: hidden; }
/* Velocity bars are the one non-SVG chart — same easing, same duration, same
   gradient direction as the bars in the SVG charts. The width they grow to is
   the inline style the view sets; the keyframe only supplies the `from`. */
.vel-bar-fill {
  height: 100%; border-radius: 99px;
  background: var(--lp-engineering); /* fallback if color-mix is unavailable */
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--lp-engineering) 45%, transparent),
    var(--lp-engineering));
  animation: vel-bar-grow var(--chart-grow-ms) var(--chart-ease) backwards;
}
.vel-bar-value { font-size: 0.74rem; color: var(--ink-soft); min-width: 3rem; text-align: right; }
/* Capped, not stretched: the sparkline's axis labels live in the SVG's own
   user units, so a holder allowed to fill a wide column scales 9.5px text up
   to 20px+ — a footnote shouting over the dates it belongs to. */
.spark-holder { max-width: 20rem; }
.spark-holder svg { width: 100%; height: auto; display: block; }
.spark-line { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.spark-base { stroke: var(--line); stroke-width: 1; vector-effect: non-scaling-stroke; }
.spark-zero { fill: var(--muted); opacity: 0.55; }
.spark-end-dot { fill: var(--accent); }
/* Hollow end = the last week is still running, not a finished data point. */
.spark-end-open { fill: var(--surface); stroke: var(--accent); stroke-width: 1.5; }
.spark-text { margin: 0.3rem 0 0; font-size: 0.72rem; color: var(--muted); }
.spark-partial { color: var(--muted); }
/* The sparkline's two ends, named (metrics §3) — an unlabelled line is a shape,
   not a series. Same ink as every other axis label. */
.spark-axis-label { fill: var(--muted); font-size: 9.5px; font-variant-numeric: tabular-nums; }

.tiles { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.6rem; margin: 0.9rem 0 0.5rem; }
@media (min-width: 760px) { .tiles { grid-template-columns: repeat(6, 1fr); } }
.tile { background: var(--surface); border: 1px solid var(--line); border-radius: 10px; padding: 0.6rem 0.7rem; box-shadow: var(--shadow); }
.tile-value { font-size: 1.15rem; font-weight: 700; letter-spacing: -0.01em; }
.tile-label { font-size: 0.7rem; color: var(--muted); font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; }
.tile-warn .tile-value { color: var(--warn); }

.scope-equation { margin: 0.2rem 0 1rem; font-size: 0.9rem; color: var(--ink-soft); }
.scope-equation strong { color: var(--ink); }
/* "all work" marker — the equation never loses engineering work to the lens. */
.scope-equation-note { color: var(--muted); font-size: 0.78rem; }

.cockpit-panels { display: grid; gap: 0.9rem; margin: 0 0 0.9rem; }
@media (min-width: 760px) { .cockpit-panels { grid-template-columns: 1fr 1fr; } }
.cockpit-panel { background: var(--surface); border: 1px solid var(--line); border-radius: 10px; padding: 0.9rem 1rem; box-shadow: var(--shadow); min-width: 0; }
.cockpit-panel h2 { font-size: 0.98rem; margin: 0 0 0.5rem; }
.cockpit-panel .panel-head { margin: 0 0 0.35rem; }

/* ── Panels that cannot hide their own contents (panels spec Part 1) ──────
   A panel used to drop rows silently — closing one decision made a card that
   had never been shown appear. Three things stop that: the true open count in
   the header, a capped body that SAYS when it is hiding rows, and the record
   behind it one tap away. */

/* The count is the count of OPEN rows — title says which noun it counts. */
.panel-count {
  flex: none; font-size: 0.68rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--ink-soft); background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 999px; padding: 0.12rem 0.5rem; white-space: nowrap;
}

.panel-scroll { position: relative; }
.panel-body {
  /* Phone first (~12rem), desktop below (~18rem): the cockpit keeps its shape
     however long the list gets, and a flick inside a panel stays inside it. */
  max-height: 12rem; overflow-y: auto; overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch; scrollbar-gutter: stable;
}
@media (min-width: 760px) { .panel-body { max-height: 18rem; } }
.panel-body:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* A scrollbar is not enough on its own (spec rule 2): while rows are hidden
   below, the list fades out — "there is more" is visible at rest. JS sets
   data-more from real measurements, so it never promises rows that are not
   there, and it clears at the end of the list. */
.panel-fade {
  position: absolute; left: 0; right: 0; bottom: 0; height: 2rem; pointer-events: none;
  background: linear-gradient(180deg, var(--surface-0), var(--surface));
  opacity: 0; transition: opacity 160ms var(--chart-ease);
}
.panel-scroll[data-more="true"] .panel-fade { opacity: 1; }
/* Group captions inside a panel ("Recently shipped") — never counted rows. */
.panel-note {
  margin: 0.5rem 0 0.1rem; font-size: 0.66rem; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted);
}

/* The record behind the panel: collapsed by default, remembered per panel. */
.panel-history { border-top: 1px solid var(--line); margin: 0.3rem 0 0; }
.panel-history > summary {
  cursor: pointer; font-size: 0.78rem; font-weight: 700; color: var(--ink-soft);
  min-height: 2.75rem; display: flex; align-items: center; gap: 0.4rem;
  list-style: none; padding: 0.2rem 0;
}
.panel-history > summary::-webkit-details-marker { display: none; }
.panel-history > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.history-chevron { color: var(--muted); transition: transform 160ms var(--chart-ease); }
.panel-history[open] .history-chevron { transform: rotate(180deg); }
.history-note { margin: 0.3rem 0; font-size: 0.72rem; color: var(--muted); }
.history-empty { padding: 0.4rem 0 0.6rem; }
.history-foot { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; flex-wrap: wrap; }
.history-actions { display: flex; gap: 0.2rem; }
.point-resolution { font-size: 0.78rem; color: var(--ink-soft); overflow-wrap: anywhere; }
.point-quiet { color: var(--muted); font-style: italic; }
/* A resolved row whose card has left the board is text, never a dead button. */
.point-static { cursor: default; }

.point-row { display: flex; align-items: stretch; gap: 0.4rem; }
.point-main {
  flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 0.1rem;
  border: 0; border-top: 1px solid var(--line); background: transparent; color: var(--ink);
  text-align: left; padding: 0.5rem 0.2rem; cursor: pointer; min-height: 2.75rem; width: 100%;
}
.point-main:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.point-title { font-size: 0.86rem; font-weight: 600; }
.point-sub { font-size: 0.74rem; color: var(--muted); }
/* Risk reasons rank above age in the impediments panel (spec §6). */
.point-risk { font-size: 0.74rem; color: var(--bad); font-weight: 600; }
.pin-btn {
  flex: none; width: 2.75rem; min-height: 2.75rem; border: 0; background: transparent;
  color: var(--warn); font-size: 1.1rem; cursor: pointer; border-radius: 8px;
}
.pin-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.thumbs { display: grid; grid-template-columns: 1fr 1fr; gap: 0.6rem; margin: 0 0 0.9rem; }
.thumb {
  display: flex; flex-direction: column; align-items: flex-start; gap: 0.15rem;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 10px;
  padding: 0.7rem 0.9rem; cursor: pointer; color: var(--ink); text-align: left; min-height: 2.75rem;
}
.thumb:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.thumb-label { font-weight: 700; font-size: 0.9rem; }
.thumb-sub { font-size: 0.74rem; color: var(--muted); }

.cockpit-add { margin: 0.4rem 0 1rem; }
.cockpit-add .btn { width: 100%; }

/* ── Story map (spec §5) ────────────────────────────────────────────────── */
/* Square area encodes the size class (spec §0.5). On coarse pointers every
   class — XS included — clears 44px once the ::before hit area claims half
   the gutter on each side (size + --sq-gap); the dense scale is a desktop
   affordance. The header rows are variables too, because they are tappable
   (they open the feature/epic sheets) and so carry the same floor;
   views-map.js reads them back to scroll the current band clear of them. */
:root {
  --col-w: 208px;
  --rail-w: 132px;
  --sq-gap: 8px;
  /* The ladder's floor is a measurement, not a taste: a card is 191px wide and
     its text sets at 10.88px/12.84px, so a title wraps to two lines at ~30
     characters. Across every title in the product the worst case is two lines
     = 35.7px, and XS was 30px — which is why XS cards cut their second line in
     half. Every rung clears two lines; the ratios that make the class readable
     as a size are kept (~1.3× per step, XS:XL ≈ 1:2.7). */
  --sq-xs: 38px;
  --sq-s: 50px;
  --sq-m: 66px;
  --sq-l: 84px;
  --sq-xl: 102px;
  --h-sys: 34px;
  --h-feature: 38px;
  --h-epic: 42px;
  /* Where the backbone header parks itself: under the sticky tab bar
     (`.tabs` is `top: 0.4rem` and 3.25rem tall). views-map.js measures the
     real bar and overwrites this on the root element — the bar wraps to two
     rows on a narrow phone, and a constant would hide the epic row exactly
     there. This value is the fallback if that measurement never runs. */
  --map-sticky-top: 3.65rem;
}
@media (pointer: coarse) {
  :root {
    --col-w: 206px;
    --sq-gap: 10px;
    /* On a touch screen the floor is the 44px target rather than the second
       line of text, so the whole ladder shifts up to start there. Every class
       clears 44px on its own — the card no longer borrows hit area from the
       gutter with a pseudo-element the card's own `overflow` was clipping. */
    --sq-xs: 44px;
    --sq-s: 56px;
    --sq-m: 72px;
    --sq-l: 90px;
    --sq-xl: 110px;
    --h-feature: 44px;
    --h-epic: 44px;
  }
}

.map-toolbar {
  /* One control height for everything in the bar; see the shared rule below. */
  --map-ctl-h: 1.85rem;
  display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center; margin: 0 0 0.6rem;
  /* Samuel, 2026-09-06: the toolbar "occupies too much vertical real state".
     It wrapped to three lines and each line pushed the map down, permanently,
     because the bar is sticky. It then scrolled sideways on one line, and at
     about 900px that hid the filters, Jump to current and Add with no hint
     (Victor's QA report, 2026-10-23). Now it keeps one line by folding what
     does not fit into More (toolbar-fold.js); it wraps only when even the
     search and Add cannot share a line, and the More row opens below it. */
  overflow-x: auto; overflow-y: visible; scrollbar-width: thin;
  /* Pinned under the tab bar so Jump to current / zoom / the filters stay
     reachable however deep the map scrolls. Opaque: the map slides beneath. */
  position: sticky; top: var(--map-sticky-top); z-index: 4;
  background: var(--bg); padding: 0.4rem 0;
}

/* One control height across the whole bar (Samuel, 2026-09-06: "the buttons and
   fields here are too high, I think they need to be all of the same size and
   occupy less vertical space... One of them is also not centered vertically").
   Every control had a different box: .btn carries min-height 2.75rem for touch
   targets, .btn-sm only shrank the text inside it, the chips had no height at
   all, and <summary> is a list-item rather than a flex box, which is the one
   that sat off centre. This is a dense desktop toolbar, so it sets its own
   height once and every control in it obeys, tick included. */
.map-toolbar .btn,
.map-toolbar .map-search,
.map-toolbar .map-class-chip,
.map-toolbar .map-make > summary {
  box-sizing: border-box;
  height: var(--map-ctl-h);
  min-height: var(--map-ctl-h);
  padding-block: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}


/* The two groups the bar is made of: what narrows the view, and what makes
   something. Each keeps its own controls together so the eye reads two things
   rather than nine. */
.map-find, .map-make-menu {
  display: flex; gap: 0.35rem; align-items: center; flex: 0 0 auto;
}
.map-find { flex-wrap: wrap; flex-shrink: 1; min-width: 0; }
.map-find > * { flex: 0 0 auto; }

/* What did not fit the window, behind one control at the bar's end; opened, a
   row of the bar itself, so it sticks with the bar and wraps to any width. */
.map-more-toggle { gap: 0.3rem; white-space: nowrap; }
.map-more-toggle[aria-expanded="true"] .map-more-caret { transform: rotate(180deg); }
.map-more-drawer {
  flex: 1 0 100%; display: flex; flex-wrap: wrap; gap: 0.35rem 0.5rem; align-items: center;
  padding-top: 0.35rem; border-top: 1px solid var(--line);
}
.map-more-drawer[hidden] { display: none; }

.map-class-filter { display: inline-flex; gap: 0.15rem; align-items: center; }
.map-class-chip {
  font: inherit; font-size: 0.74rem; line-height: 1;
  border: 1px solid var(--line); background: var(--surface); color: var(--muted);
  border-radius: 999px; padding: 0.28rem 0.55rem; cursor: pointer; white-space: nowrap;
}
.map-class-chip:hover { border-color: var(--muted); }
.map-class-chip.on { background: var(--accent, var(--lp-management)); border-color: transparent; color: #fff; }

.map-filtered { font-size: 0.74rem; color: var(--muted); white-space: nowrap; }

/* What the search found when the map cannot show it: the offer to reveal the
   matches a filter is holding back, and the plain sentence when nothing on the
   board matches. Warning tone on the offer, because a reader staring at an
   empty map has already started doubting the board. */
.map-hidden-matches { white-space: nowrap; border-color: var(--warn, var(--line)); }
.map-no-match { font-size: 0.74rem; color: var(--muted); white-space: nowrap; }

/* Four create buttons behind one summary: closed, they cost one control. */
.map-make { position: relative; flex: 0 0 auto; }
.map-make > summary { list-style: none; cursor: pointer; white-space: nowrap; }
.map-make > summary::-webkit-details-marker { display: none; }
/* The menu inside its control is never shown: while open it is lifted to the
   page's top level (views-map.js liftMenu), because the toolbar is a sticky
   stacking context and a menu inside it painted under the workspace's
   sidebar, side panel and frame bar (Henrique, 2026-10-13, and the reviewer;
   card the-maps-add-menu-opens-above-everything). There it is fixed to the
   screen under its button, above the workspace's bars and panels (6 and 7)
   and below a sheet's backdrop (20). */
.map-make > .map-make-menu { display: none; }
.map-make-menu.map-make-floating {
  display: flex; position: fixed; top: 0; left: 0; z-index: 15;
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: var(--shadow); padding: 0.4rem; flex-direction: column; align-items: stretch; gap: 0.35rem;
}
.map-make-floating .btn {
  height: auto; min-height: 2rem; justify-content: flex-start;
  padding-block: 0.3rem;
}

.map-legend {
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
  padding: 0.1rem 0.9rem 0.7rem; margin: 0 0 0.7rem; box-shadow: var(--shadow);
}
/* Closed, the legend is one slim inviting line — never an empty-looking box. */
.map-legend:not([open]) { padding-bottom: 0.1rem; }
.map-legend > summary {
  cursor: pointer; font-weight: 700; font-size: 0.8rem; color: var(--ink-soft);
  padding: 0.3rem 0; min-height: 2.2rem; display: flex; align-items: center; gap: 0.4rem;
  list-style: none;
}
.map-legend > summary::-webkit-details-marker { display: none; }
.legend-caret { color: var(--accent); flex: none; }
.map-legend[open] .legend-caret { transform: rotate(90deg); }
.map-legend > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.legend-grid { display: flex; flex-wrap: wrap; gap: 0.7rem 1.6rem; }
.legend-col { display: grid; gap: 0.25rem; font-size: 0.78rem; align-content: start; color: var(--ink-soft); }
.legend-col b { font-size: 0.65rem; letter-spacing: 0.07em; text-transform: uppercase; color: var(--muted); font-weight: 700; }
.lg { display: flex; align-items: center; gap: 0.5rem; line-height: 1.2; }
.lg-bar { width: 26px; height: 14px; border-radius: 3px; flex: none; border: 1px solid var(--sq-line); }
.lg-bar-sys { background: var(--lp-ground); }
.lg-bar-feature { background: var(--lp-management); }
.lg-bar-epic { background: var(--lp-engineering); }
/* State and shape swatches are fixed-size: only the "size (area)" column
   encodes area, so those keep the map's real square dimensions. */
.lg-sq { width: 16px; height: 16px; min-height: 0; padding: 0; display: inline-block; flex: none; }

/* The map scrolls with the PAGE (spec §5). No `max-height`, no vertical
   overflow: bands grow to fit their cards, so nothing is ever cut off.

   Horizontal scrolling stays inside the map, and that is why the backbone
   header is a separate strip. A box with `overflow-x: auto` is a scroll
   container on BOTH axes (CSS Overflow 3: `visible` beside `auto` computes to
   `auto`), and a sticky child of a scroll container sticks to THAT box, not to
   the viewport — which is exactly the clipped-and-nested behaviour being
   removed here. So `.map-head` sits outside the scroller and sticks to the
   viewport, `.map-body` scrolls sideways, and views-map.js keeps one
   scrollLeft between them. `.mapbox` itself must stay overflow-free: any value
   but `visible` would make it the scrollport again. */
.mapbox {
  border: 1px solid var(--line); border-radius: 10px; background: var(--surface);
  box-shadow: var(--shadow);
}
.map-head {
  position: sticky; top: var(--map-head-top, var(--map-sticky-top)); z-index: 3;
  /* Below the toolbar (z 4) and `.tabs` (z 5), both of which it slides under. */
  overflow-x: auto; overflow-y: hidden;
  overscroll-behavior-x: contain;
  background: var(--surface); border-radius: 9px 9px 0 0;
  /* The strip mirrors the body's position; its own bar would be a second,
     lying control — and the hidden bar keeps the epic row's full height. */
  scrollbar-width: none;
}
.map-head::-webkit-scrollbar { display: none; }
.map-body {
  overflow-x: auto; overscroll-behavior-x: contain;
  border-radius: 0 0 9px 9px;
  /* Its own stacking level, under the header strip: the release labels pin
     themselves to the left with a z-index of their own, and painted after the
     strip at the same level they slid over the RELEASE / MODULE / EPIC labels
     as the map scrolled down (Victor's QA report, 2026-10-23). */
  isolation: isolate;
}
.storymap {
  --cols: 1;
  display: grid;
  grid-template-columns: var(--rail-w) repeat(var(--cols), var(--col-w));
  min-width: max-content;
}
.mcell { border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); min-width: 0; }

/* The three rows no longer stick individually: the strip that holds them is
   what sticks, and it is exactly as tall as they are. They stay positioned so
   the rail cells below can pin themselves to the left edge. */
.h-sys, .h-feature, .h-epic {
  position: relative; z-index: 2; display: flex; align-items: center; justify-content: center;
  font-weight: 700; text-align: center; padding: 0.2rem 0.4rem; border: 0; margin: 0;
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.h-sys { height: var(--h-sys); background: var(--lp-ground); color: #eef3f7; font-size: 0.78rem; letter-spacing: 0.05em; }
.h-feature { height: var(--h-feature); background: var(--lp-management); color: var(--on-mark); font-size: 0.73rem; line-height: 1.12; }
.h-epic { height: var(--h-epic); background: var(--lp-engineering); color: var(--on-mark); font-size: 0.71rem; line-height: 1.15; }
button.h-feature, button.h-epic { cursor: pointer; }
button.h-feature:focus-visible, button.h-epic:focus-visible, .r-label:focus-visible {
  outline: 2px solid var(--ink); outline-offset: -3px;
}
.h-sys.rail, .h-feature.rail, .h-epic.rail {
  position: sticky; left: 0; z-index: 4; background: var(--rail); color: var(--muted);
  font-size: 0.6rem; letter-spacing: 0.08em; text-transform: uppercase;
}
.h-none { background: var(--surface-2); color: var(--ink-soft); }

.r-label {
  position: sticky; left: 0; z-index: 3; background: var(--rail);
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
  border-top: 0; border-left: 4px solid transparent;
  padding: 0.55rem 0.55rem; text-align: left; color: var(--ink);
  display: flex; flex-direction: column; align-items: flex-start; gap: 0.05rem;
  cursor: pointer; min-height: 3.4rem;
}
.r-name { font-size: 0.76rem; font-weight: 700; line-height: 1.2; }
.r-date { font-size: 0.66rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.r-count { font-size: 0.65rem; color: var(--muted); margin-top: 0.15rem; font-variant-numeric: tabular-nums; }
.r-past .r-name, .r-past .r-date { opacity: 0.74; }
.r-current { border-left-color: var(--lp-engineering); background: var(--band-current); }
.r-chip {
  display: inline-block; margin-top: 0.25rem; font-size: 0.58rem; font-weight: 800; letter-spacing: 0.07em;
  text-transform: uppercase; padding: 0.1rem 0.4rem; border-radius: 99px;
  background: var(--accent); color: var(--on-accent);
}
.r-chip-late { background: var(--bad-soft); color: var(--bad); box-shadow: inset 0 0 0 2px var(--lp-risk); }

.band { background: var(--band); }
.band-current { background: var(--band-current); }
.band.drop-ok { outline: 2px dashed var(--accent); outline-offset: -3px; }
/* A band reads as one release: hovering any cell tints the whole row, and a
   dragged card marks the whole band it would land in, on top of the one cell
   that carries the dashed outline. Neither tone is a state or risk colour. */
.band.band-hover, .r-label.band-hover { background: var(--band-hover); }
.band.band-target, .r-label.band-target { background: var(--band-target); }
.cellwrap {
  display: flex; flex-direction: column; gap: var(--sq-gap); align-content: flex-start;
  padding: 0.5rem; min-height: 62px;
}

/* A card carries its own title: a story map you cannot read is a colour chart.
   Size class is encoded in HEIGHT (spec §0.5) so batch size stays visible while
   the text stays legible — and height stays FIXED, never content-driven: the
   sum of the card heights in a cell is what makes a band readable as batch
   mass, and a card that grew with its title would report verbosity as size.
   Fitting the text is therefore the ladder's job (see --sq-xs above), not the
   card's.

   There is deliberately no bottom fade here. The gradient this rule used to
   carry masked the last 10px of every card — three quarters of a line of text,
   which is why cards read as cut even when their text fit, and it dimmed the
   4px `.sq-red::after` risk bar to near-invisibility inside its own band. A
   chart that fades out its own risk signal is not a chart to keep. */
.sq {
  position: relative; border-radius: 3px; cursor: pointer;
  border: 1px solid var(--sq-line); background: var(--surface-2);
  touch-action: manipulation; flex: none; width: 100%;
  padding: 4px 6px; text-align: left; overflow: hidden;
  font: inherit; font-size: 0.68rem; line-height: 1.18; font-weight: 600;
  color: #11202b;
  /* Long unbroken tokens (a URL, a branch name) would otherwise run past the
     card's edge and be cut mid-glyph with no ellipsis to show for it. */
  overflow-wrap: anywhere;
  display: -webkit-box; -webkit-box-orient: vertical;
}
.sq:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.sq-done { background: var(--lp-strategy); }
.sq-todo { background: var(--lp-engineering); }
/* Queued but not yet ready: a card still missing its size, its value or its
   risk reduction wears a neutral tone, white before blue, so the board says
   what is being shaped and what can be pulled without a chip. */
.sq-todo.sq-unready { background: var(--sq-unready); color: var(--ink); box-shadow: inset 0 0 0 1px var(--line); }
.sq-doing { background: var(--lp-management); }
/* Waiting = doing, parked on a person: management orange with the inner ring. */
.sq-waiting { background: var(--lp-management); box-shadow: inset 0 0 0 2px var(--surface), inset 0 0 0 3px var(--ink-soft); }
.sq-dropped { background: var(--surface-2); opacity: 0.55; color: var(--ink-soft); }
/* Stale: past its column's aging threshold. A warning ring, and the age in the
   corner; the label carries the words. Declared after the neutral tone so a
   card that is both wears both. */
.sq.sq-stale { box-shadow: inset 0 0 0 2px var(--warn); }
.sq-todo.sq-unready.sq-stale { box-shadow: inset 0 0 0 1px var(--line), inset 0 0 0 3px var(--warn); }
.sq-age {
  position: absolute; top: 2px; right: 2px; font-size: 0.6rem; font-weight: 800;
  color: var(--warn); background: var(--warn-soft); padding: 0 0.3rem; border-radius: 99px;
  font-variant-numeric: tabular-nums;
}
/* Parked on a person: a person mark in the left corner, whatever column the
   card is in. In the risk red with a white ring, because a card waiting on a
   person is work stopped, and the first draft (ink, small) read as decoration
   (Samuel, 2026-10-01: "it doesn't demonstrate that this is impeding the
   flow"). The title makes room for it; the age and the holds count keep the
   right corner. */
/* The waiting tag (card the-map-shows-who-a-card-is-waiting-on). Samuel,
   2026-10-01, on the red circle before it: "maybe a tag would be a little bit
   more beautiful... the tone of red that you chose does not go well with the
   rest of the color palette." So it is the palette's own ink, carrying the
   person and the first name, on the card's top line, which a waiting card
   keeps clear for it. A ribbon, flush to the card's edge with a swallowtail
   where it ends: Samuel chose it over a tag and an arrow on 2026-10-02 after
   seeing the three on the live board ("let's stick with ribbon"). */
.sq-wait {
  position: absolute; top: 2px; left: 0; max-width: calc(100% - 4px); height: 13px;
  display: inline-flex; align-items: center; gap: 2px; padding: 0 9px 0 3px;
  background: var(--lp-ground); color: #fff;
  clip-path: polygon(0 0, 100% 0, calc(100% - 5px) 50%, 100% 100%, 0 100%);
  font-size: 0.6rem; font-weight: 600; line-height: 1; letter-spacing: 0.01em;
}
.sq-wait .icon { display: block; flex: none; }
.sq-wait-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sq-waits { padding-top: 19px; }
.lg-sq.sq-waits { padding: 0; }
.lg-sq .sq-wait { top: 50%; left: 50%; transform: translate(-50%, -50%); padding: 0 3px; }
/* The board and the backlog wear the same ink and the same ribbon, so the
   three screens say it one way. */
.card-waits {
  display: inline-flex; align-items: center; gap: 0.25rem; max-width: 100%; min-width: 0;
  background: var(--lp-ground); color: #fff; padding: 1px 10px 1px 4px;
  clip-path: polygon(0 0, 100% 0, calc(100% - 5px) 50%, 100% 100%, 0 100%);
  font-size: 0.74rem; font-weight: 600;
}
.card-waits .icon { flex: none; }
.card-waits-text { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
/* Red bar = late or at risk (spec §0.4). */
.sq-red::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 4px;
  background: var(--lp-risk); border-radius: 0 0 2px 2px;
}
.sq-decision { border-radius: 12px; border-style: dashed; font-style: italic; }
.sq-decision.sq-red::after { left: 8px; right: 8px; border-radius: 2px; }
/* Height carries the size class; the clamp beside it is how many lines that
   height can actually show, so a title longer than the card ends in an ellipsis
   — an honest "there is more" — instead of a razor cut mid-glyph. The old
   blanket clamp of 8 fired above what even XL could display, so its ellipsis
   was always drawn below the clip edge and never painted. The full title is
   always on the card's `title`/`aria-label` and in the item sheet. */
.sq-xs { height: var(--sq-xs); -webkit-line-clamp: 2; }
.sq-s { height: var(--sq-s); -webkit-line-clamp: 3; }
.sq-m { height: var(--sq-m); -webkit-line-clamp: 4; }
.sq-l { height: var(--sq-l); -webkit-line-clamp: 5; }
.sq-xl { height: var(--sq-xl); -webkit-line-clamp: 7; }
@media (pointer: coarse) {
  .sq-xs { -webkit-line-clamp: 2; }
  .sq-s { -webkit-line-clamp: 3; }
  .sq-m { -webkit-line-clamp: 4; }
  .sq-l { -webkit-line-clamp: 6; }
  .sq-xl { -webkit-line-clamp: 7; }
}
/* The tag takes the top line, so the title shows one line fewer, on any pointer (two classes outrank the base and the coarse rules): an honest
   ellipsis rather than a line cut through the middle. */
.sq-waits.sq-xs { -webkit-line-clamp: 1; }
.sq-waits.sq-s { -webkit-line-clamp: 2; }
.sq-waits.sq-m { -webkit-line-clamp: 3; }
.sq-waits.sq-l { -webkit-line-clamp: 4; }
.sq-waits.sq-xl { -webkit-line-clamp: 6; }
.sq-dragging { opacity: 0.4; }


/* Legend squares reuse the map's own classes at a fixed size. */
.lg .sq { cursor: default; }

/* ── Backlog / forms ────────────────────────────────────────────────────── */
.chip-groups { display: grid; gap: 0.4rem; margin: 0 0 0.8rem; }
.chips { display: flex; gap: 0.4rem; flex-wrap: wrap; }
/* A mouse does not need a 44px target, and five stacked selector rows of them
   cost more vertical space than the charts they filter. The touch floor is
   restored below for coarse pointers, where it is an accessibility floor
   rather than a default. */
.chip {
  border: 1px solid var(--line); background: var(--surface); color: var(--ink-soft);
  font-size: 0.78rem; font-weight: 600; border-radius: 99px; padding: 0.3rem 0.75rem; cursor: pointer;
  min-height: 2rem;
}
@media (pointer: coarse) {
  .chip { min-height: 2.75rem; padding: 0.4rem 0.8rem; } /* ≥44px touch target */
}
.chip[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }

.addcard { background: var(--accent-soft); border-radius: 10px; padding: 0.8rem 1rem; margin: 0 0 1rem; }
.addcard summary { cursor: pointer; font-weight: 700; color: var(--accent); font-size: 0.9rem; padding: 0.4rem 0; min-height: 2.75rem; display: flex; align-items: center; }
.addcard-form { display: grid; gap: 0.55rem; margin-top: 0.7rem; }
.addcard-form input, .addcard-form textarea, .addcard-form select, .sheet input, .sheet textarea, .sheet select {
  font: inherit; color: var(--ink); background: var(--field); border: 1px solid var(--field-line);
  border-radius: 7px; padding: 0.5rem 0.7rem; width: 100%; min-height: 2.75rem;
}
/* The one focus look every field shares: the border takes the accent and the
   ring says which field has the keyboard. */
.addcard-form input:focus-visible, .addcard-form textarea:focus-visible, .addcard-form select:focus-visible,
.sheet input:focus-visible, .sheet textarea:focus-visible, .sheet select:focus-visible,
.inline-create input:focus-visible, .inline-create textarea:focus-visible, .inline-create select:focus-visible,
.search-field:focus-visible, .mx-select-btn:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent);
}
/* ── The Maestro select ─────────────────────────────────────────────────
   Two layers. Every remaining NATIVE select gets the house closed-control
   look (borders, chevron, no OS chrome) — the open list stays the OS's.
   The rating pickers go further: .mx-select is a full listbox so each rung
   can show its words and definition (the vault's ladders). */
.sheet select, .addcard-form select, .inline-select, .release-select,
.inline-create select, .selector-field select {
  appearance: none; -webkit-appearance: none; cursor: pointer;
  background-image:
    linear-gradient(45deg, transparent 50%, #7d8894 50%),
    linear-gradient(135deg, #7d8894 50%, transparent 50%);
  background-position: calc(100% - 1.05rem) 50%, calc(100% - 0.7rem) 50%;
  background-size: 0.35rem 0.35rem;
  background-repeat: no-repeat;
  padding-right: 2rem;
}

.mx-select { position: relative; flex: 1 1 8rem; min-width: 0; }
.mx-select-btn {
  font: inherit; color: var(--ink); background: var(--field);
  border: 1px solid var(--field-line); border-radius: 7px;
  padding: 0.5rem 0.7rem; width: 100%; min-height: 2.75rem;
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
  cursor: pointer; text-align: left;
}
.mx-select-btn[aria-expanded="true"] { border-color: var(--accent); }
.mx-select-value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mx-select-caret { color: var(--muted); flex: none; transition: transform 140ms var(--chart-ease); }
.mx-select-btn[aria-expanded="true"] .mx-select-caret { transform: rotate(180deg); }
/* display:grid below would beat the UA's [hidden] rule — say it explicitly,
   or the ladder renders permanently under the field (shipped once; never again). */
.mx-select-pop[hidden] { display: none; }
.mx-select-pop {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 40;
  min-width: min(21rem, 88vw);
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 6px 24px rgba(10, 16, 22, 0.22);
  padding: 0.3rem; display: grid; gap: 2px;
  animation: chart-fade-in 140ms var(--chart-ease) backwards;
}
.mx-select.mx-up .mx-select-pop { top: auto; bottom: calc(100% + 4px); }
.mx-option { padding: 0.45rem 0.6rem; border-radius: 7px; cursor: pointer; display: grid; gap: 0.1rem; }
.mx-option:hover, .mx-option:focus { background: var(--accent-soft); outline: none; }
.mx-option.is-selected { box-shadow: inset 0 0 0 1px var(--accent); }
.mx-option-title { font-size: 0.84rem; font-weight: 700; color: var(--ink); }
.mx-option-desc { font-size: 0.74rem; color: var(--muted); line-height: 1.35; }
/* A searchable select opens on its field; what does not match leaves the list. */
.mx-search {
  width: 100%; font: inherit; font-size: 0.84rem; color: var(--ink);
  background: var(--field); border: 1px solid var(--field-line); border-radius: 7px;
  padding: 0.4rem 0.55rem; margin-bottom: 0.25rem; position: sticky; top: 0; z-index: 1;
}
.mx-search:focus { outline: none; border-color: var(--accent); }
.mx-option[hidden], .mx-group-title[hidden], .mx-nomatch[hidden] { display: none; }
.mx-nomatch { padding: 0.45rem 0.6rem; font-size: 0.8rem; color: var(--muted); }
.mx-group-title {
  padding: 0.5rem 0.6rem 0.15rem; font-size: 0.68rem; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.05em;
}
.mx-select-compact .mx-select-btn { font-size: 0.78rem; padding: 0.35rem 0.5rem; }
/* The `+ New …` sentinel reads as the command it is. */
.mx-option-action .mx-option-title { color: var(--accent); }
/* The control fills whatever field hosts it. */
.selector-field .mx-select { width: 100%; }
.release-row .mx-select { flex: 1 1 auto; min-width: 0; }
.release-row .mx-select-btn { font-weight: 600; border-radius: 8px; }
.inline-edits .mx-select { flex: 1 1 9rem; min-width: 0; }

.form-row { display: flex; gap: 0.55rem; flex-wrap: wrap; }
.form-row > * { flex: 1 1 8rem; min-width: 0; }

.backlog-list { display: grid; gap: 0.55rem; }
.backlog-row { display: flex; gap: 0.5rem; align-items: stretch; }
.backlog-main { flex: 1; min-width: 0; display: grid; gap: 0.3rem; }
/* The four inline selects under a queued card shared one line whatever the
   width, so on a phone the card was 510 pixels wide behind a 375 pixel screen
   and the whole queue scrolled sideways (found 2026-09-26 measuring the
   Backlog tab in chromium). They wrap now, two to a line on a phone, one line
   on a laptop as before. */
.inline-edits { display: flex; gap: 0.4rem; flex-wrap: wrap; min-width: 0; }
.inline-select {
  flex: 1; min-width: 0; font: inherit; font-size: 0.78rem; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line); border-radius: 7px;
  padding: 0.35rem 0.4rem; min-height: 2.75rem;
}
.reorder { display: flex; flex-direction: column; gap: 0.3rem; justify-content: center; }
.reorder button {
  border: 1px solid var(--line); background: var(--surface); color: var(--ink-soft);
  border-radius: 7px; width: 2.75rem; min-height: 2.75rem; flex: 1; cursor: pointer; font-size: 0.85rem;
}
.reorder button:disabled { opacity: 0.35; cursor: default; }

/* ── Economics (value × risk rating) ────────────────────────────────────── */
.econ { display: grid; gap: 0.9rem; }
@media (min-width: 860px) { .econ { grid-template-columns: 2fr 1fr; align-items: start; } }
.econ-hint { margin: 0 0 0.5rem; font-size: 0.78rem; color: var(--muted); }
.bubble-mid { stroke: var(--line); stroke-width: 1.5; stroke-dasharray: 4 4; }
/* Flat fill on purpose: a vertical gradient inside a circle reads as a glossy
   sphere, and the size legend mirrors this exact colour. */
.bubble-dot { fill: var(--lp-engineering); opacity: 0.55; stroke: var(--accent); stroke-width: 1.5; cursor: pointer; }
.bubble-dot:hover, .bubble-dot:focus { opacity: 0.85; }
.bubble-unsized { fill: transparent; stroke: var(--muted); stroke-dasharray: 4 3; opacity: 0.9; }
/* The bubble chart scales with its frame's width, and its words with it: at
   10.5px they were drawn at about 6px on a phone (Victor's QA report,
   2026-10-23). The frame is a size container, so the words are set larger as
   it narrows, enough that each step still draws them at 11px or more:
   font-size x width / 560 (the chart's own width) >= 11 at the step's
   narrowest. */
.bubble-frame { container-type: inline-size; }
.bubble-frame .chart-axis-label, .bubble-frame .bubble-count { font-size: 11.5px; }
.bubble-count { fill: var(--ink-soft); font-weight: 700; font-variant-numeric: tabular-nums; }
@container (max-width: 559.98px) { .bubble-frame .chart-axis-label, .bubble-frame .bubble-count { font-size: 14.5px; } }
@container (max-width: 439.98px) { .bubble-frame .chart-axis-label, .bubble-frame .bubble-count { font-size: 18.5px; } }
@container (max-width: 339.98px) { .bubble-frame .chart-axis-label, .bubble-frame .bubble-count { font-size: 23.5px; } }
@container (max-width: 269.98px) { .bubble-frame .chart-axis-label, .bubble-frame .bubble-count { font-size: 28.5px; } }
.unrated-tray { background: var(--surface-2); border-radius: 10px; padding: 0.7rem 0.8rem; }
.tray-title { margin: 0 0 0.4rem; font-size: 0.84rem; }
.tray-item {
  display: block; width: 100%; text-align: left; border: 0; border-top: 1px solid var(--line);
  background: transparent; color: var(--ink); font-size: 0.82rem; padding: 0.5rem 0.2rem;
  cursor: pointer; min-height: 2.75rem;
}
.tray-item:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ── Buttons ────────────────────────────────────────────────────────────── */
.btn {
  font-weight: 600; font-size: 0.85rem; cursor: pointer;
  background: var(--surface); color: var(--ink); border: 1px solid var(--line);
  border-radius: 7px; padding: 0.45rem 0.9rem; min-height: 2.75rem;
}
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.btn-quiet { border-color: transparent; background: transparent; color: var(--accent); }
.btn-danger { color: var(--bad); border-color: var(--bad); background: transparent; }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.btn-sm { font-size: 0.78rem; padding: 0.3rem 0.7rem; }

/* ── Metrics ────────────────────────────────────────────────────────────── */
.metrics-grid { display: grid; gap: 0.9rem; }
@media (min-width: 860px) { .metrics-grid { grid-template-columns: 1fr 1fr; } }

/* Metrics §1: the burn-up and the forecast that belongs to it, side by side —
   they are one statement at one scope, so they must never be read apart. */
.metrics-hero { display: grid; gap: 0.9rem; margin: 0 0 0.9rem; }
/* `stretch`, not `start`: the burn-up and the forecast band are one statement
   read left to right, and a short card beside a tall one left the row's
   bottom-left corner empty. The chart grows into it (its canvas is taller than
   the shared one) and the caption is pushed to the card's floor. */
@media (min-width: 860px) {
  .metrics-hero { grid-template-columns: 1.45fr 1fr; align-items: stretch; }
  .metrics-hero > .metrics-panel { display: flex; flex-direction: column; }
  .metrics-hero > .metrics-panel > :last-child { margin-bottom: 0; }
  .metrics-hero > .metrics-panel > .forecast-detail:last-child { margin-top: auto; padding-top: 0.4rem; }
}

/* Metrics §4: the two numbers a person looks for first. Large, tabular, and
   each one labelled with the body of work it counts. */
.metrics-headline { margin: 0 0 0.9rem; }
.headline-tiles { display: grid; gap: 0.6rem; grid-template-columns: 1fr; }
@media (min-width: 620px) { .headline-tiles { grid-template-columns: 1fr 1fr; } }
.headline-tile {
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
  padding: 0.85rem 1rem; box-shadow: var(--shadow); min-width: 0;
}
.headline-value {
  font-size: 2.4rem; line-height: 1.05; font-weight: 800; letter-spacing: -0.02em;
  color: var(--ink); font-variant-numeric: tabular-nums;
}
@media (min-width: 620px) { .headline-value { font-size: 2.9rem; } }
.headline-title { font-size: 0.92rem; font-weight: 700; color: var(--ink); margin-top: 0.15rem; }
/* The scope the number counts, never optional — it is the label's other half. */
.headline-scope {
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--muted); margin-top: 0.2rem;
}
.headline-detail { font-size: 0.8rem; color: var(--ink-soft); margin-top: 0.4rem; }
.headline-tile-empty .headline-title { color: var(--muted); }
.headline-equations { margin: 0.75rem 0 0; display: grid; gap: 0.1rem; }
.headline-equations .scope-equation { margin: 0; }

/* Metrics §2: one period, stated once, above every chart it governs. */
.metrics-controls {
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
  padding: 0.5rem 0.9rem 0.55rem; box-shadow: var(--shadow); margin: 0 0 0.9rem;
}
.control-rows { display: grid; gap: 0.4rem; }
@media (min-width: 860px) { .control-rows { grid-template-columns: 1fr 1fr; align-items: start; } }
/* The label rides beside its chips rather than above them: stacked, the two
   groups cost a whole row of height each and this bar sits above every chart
   on the page, pushing the charts themselves below the fold. */
.control-group { display: flex; flex-wrap: wrap; align-items: center; gap: 0.2rem 0.55rem; min-width: 0; }
.control-label {
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--muted);
}
.control-note { font-size: 0.78rem; color: var(--muted); align-self: center; }
.control-custom { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; margin-top: 0.35rem; }
.control-date {
  font: inherit; font-size: 0.82rem; color: var(--ink); background: var(--field);
  border: 1px solid var(--field-line); border-radius: 7px; padding: 0.35rem 0.5rem;
  min-height: 2.75rem; /* ≥44px touch target */ min-width: 0; flex: 1 1 9rem;
}
.control-legend { margin: 0.6rem 0 0; font-size: 0.8rem; color: var(--ink-soft); }
/* What the period does NOT touch — said next to what it does. */
.control-fixed { color: var(--muted); }

/* The forecast's own sample, under the dates it produced (metrics §3). */
.forecast-spark { margin: 0.7rem 0 0; padding-top: 0.6rem; border-top: 1px solid var(--line); }
.metrics-panel { background: var(--surface); border: 1px solid var(--line); border-radius: 10px; padding: 0.9rem 1rem; box-shadow: var(--shadow); min-width: 0; }
.metrics-panel h2 { font-size: 0.98rem; margin: 0 0 0.5rem; }
.metrics-panel svg { width: 100%; height: auto; display: block; }
/* Release sheet mini burn-up (spec §5) — compact, responsive. */
.mini-burnup { margin: 0.5rem 0 0; }
.mini-burnup svg { width: 100%; height: auto; display: block; }
.panel-head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.panel-head h2 { margin: 0; }
.table-wrap { overflow-x: auto; margin-top: 0.5rem; }
.data-table { border-collapse: collapse; width: 100%; font-size: 0.78rem; font-variant-numeric: tabular-nums; }
.data-table th, .data-table td { text-align: left; padding: 0.3rem 0.6rem 0.3rem 0; border-bottom: 1px solid var(--line); }
.data-table th { color: var(--muted); font-weight: 700; }

.forecast-dates { display: grid; gap: 0.15rem; margin: 0 0 0.5rem; }
.forecast-row { display: flex; justify-content: space-between; gap: 0.6rem; margin: 0; font-size: 0.88rem; }
.forecast-row-label { color: var(--muted); }
/* The one-line meaning of a Monte Carlo mark, under its date. */
.forecast-row-hint { margin: -0.05rem 0 0.3rem; font-size: 0.73rem; color: var(--muted); }
/* The three dates wear their series' colors — same as fan lines and markers. */
.forecast-label-best { color: var(--good); }
.forecast-label-likely { color: var(--accent); }
.forecast-label-worst { color: var(--warn); }
.forecast-caveat { margin: 0.4rem 0 0; font-size: 0.8rem; color: var(--warn); font-weight: 600; }
.forecast-detail { margin: 0.4rem 0 0; font-size: 0.8rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.forecast-explainer { margin: 0.6rem 0 0; font-size: 0.8rem; color: var(--ink-soft); }

/* ── Chart motion ───────────────────────────────────────────────────────────
   Every keyframe below declares ONLY `from`. The implicit `to` is the
   element's own static value, so: the static CSS is always the final frame,
   a browser that skips the animation still paints a correct chart, and
   nothing can be left stranded mid-transition. Chart markup is replaced
   wholesale on every render, so entrances re-run on data change by
   construction — no class flipping, no reflow trick, no JS.
   `prefers-reduced-motion: reduce` switches the lot off further down. */
@keyframes chart-draw-on { from { stroke-dashoffset: var(--dash, 0); } }
@keyframes chart-fade-in { from { opacity: 0; } }
@keyframes chart-grow-up { from { transform: scaleY(0); } }
@keyframes chart-pop-in { from { opacity: 0; transform: scale(0.35); } }
@keyframes chart-fan-open { from { opacity: 0; transform: scale(0.03); } }
@keyframes chart-label-in { from { opacity: 0; transform: translateY(4px); } }
@keyframes vel-bar-grow { from { width: 0; } }

/* A solid series drawing itself on: --dash is the polyline's own length. */
.chart-draw { animation: chart-draw-on var(--chart-draw-ms) var(--chart-ease) backwards; }
/* Gradient area under a series — it fills in behind the line, landing with it
   (380ms + 700ms ≈ the 1100ms the line takes to draw) so the fill never runs
   ahead of the stroke that defines it. */
.chart-area { animation: chart-fade-in var(--chart-fade-ms) var(--chart-ease) 380ms backwards; }
/* Reference geometry (dashed scope/planned lines, percentile lines, midlines). */
.chart-soft-in { animation: chart-fade-in var(--chart-fade-ms) var(--chart-ease) 220ms backwards; }
/* The small rounded data end every series carries. */
.chart-end-dot {
  transform-box: fill-box; transform-origin: center;
  animation: chart-pop-in var(--chart-pop-ms) var(--chart-ease) var(--delay, 900ms) backwards;
}
/* Scattered marks land in sequence; the stagger is capped in charts.js. */
.chart-dot-in {
  transform-box: fill-box; transform-origin: center;
  animation: chart-pop-in var(--chart-pop-ms) var(--chart-ease)
             calc(260ms + var(--i, 0) * var(--chart-dot-stagger)) backwards;
}
/* Text is never part of the choreography — it settles in once, at the end.
   (The accessible content does not wait for it: aria-label, <title> and the
   table view are complete and correct on the first frame.) */
.chart-labels {
  transform-box: view-box;
  animation: chart-label-in var(--chart-label-ms) var(--chart-ease) var(--chart-label-delay) backwards;
}

/* Hairlines stay hairlines however wide the SVG is scaled — the SVG answer to
   the reference charts' devicePixelRatio handling. Never applied to the two
   lines whose draw-on measures dash length in user units. */
.chart-grid-line, .chart-baseline, .bu-scope-line, .bu-planned-line,
.bu-deadline-line, .bu-target-line, .bu-fan-line, .scatter-pct, .bubble-mid,
.chart-tick, .tp-partial, .cfd-band { vector-effect: non-scaling-stroke; }

.chart-grid-line { stroke: var(--line); stroke-width: 1; shape-rendering: crispEdges; }
.chart-tick { stroke: var(--line); stroke-width: 1; shape-rendering: crispEdges; }
.chart-baseline { stroke: var(--line); stroke-width: 1; opacity: 0.9; shape-rendering: crispEdges; }
.chart-grid-label { fill: var(--muted); font-size: 10px; font-variant-numeric: tabular-nums; }
.chart-axis-label { fill: var(--muted); font-size: 10.5px; font-variant-numeric: tabular-nums; }
.chart-direct-label { fill: var(--ink); font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums; }
/* The two end labels name two lines that meet whenever a release delivered its
   whole scope, so they carry their line's own colour rather than both being
   bold white (Samuel, 2026-09-08: "change the color of the label"). Matching
   label to series by colour is what makes them readable side by side. */
.chart-label-done { fill: var(--good); }
.chart-label-scope { fill: var(--ink-soft); font-weight: 600; }

/* The delivery date is the promise every other line is measured against, not
   one deadline among several ("make the delivery date outstanding"). */
.chart-caption-delivery { fill: var(--ink); font-weight: 700; }

/* Gradient stops live in CSS so both themes are correct without re-rendering.
   Areas fade to nothing at the baseline; bars keep ~25% alpha there. */
.g-done-area-0 { stop-color: var(--lp-strategy); stop-opacity: 0.34; }
.g-done-area-1 { stop-color: var(--lp-strategy); stop-opacity: 0.12; }
.g-done-area-2 { stop-color: var(--lp-strategy); stop-opacity: 0; }
.g-done-bar-0 { stop-color: var(--lp-strategy); stop-opacity: 0.95; }
.g-done-bar-2 { stop-color: var(--lp-strategy); stop-opacity: 0.25; }
.g-accent-area-0 { stop-color: var(--lp-engineering); stop-opacity: 0.34; }
.g-accent-area-1 { stop-color: var(--lp-engineering); stop-opacity: 0.12; }
.g-accent-area-2 { stop-color: var(--lp-engineering); stop-opacity: 0; }
.g-accent-bar-0 { stop-color: var(--lp-engineering); stop-opacity: 0.9; }
.g-accent-bar-2 { stop-color: var(--lp-engineering); stop-opacity: 0.25; }

/* Executed = work that is done = strategy lime (text-safe step). */
.bu-line { fill: none; stroke: var(--good); stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round; }
.bu-end-dot { fill: var(--good); stroke: var(--surface); stroke-width: 1.5; }
.bu-scope-line { fill: none; stroke: var(--muted); stroke-width: 1.5; stroke-dasharray: 5 4; }
.bu-planned-line { stroke: var(--ink-soft); stroke-width: 1.5; stroke-dasharray: 2 4; }
/* The planned line wears the health verdict: red = even the best case misses
   the commitment, amber = the likely case does. Same thresholds as the chip. */
.bu-planned-line.bu-planned-late { stroke: var(--bad); opacity: 0.95; }
.bu-planned-line.bu-planned-risk { stroke: var(--warn); opacity: 0.95; }
/* The commitment: the release's planned delivery date. Solid enough to read
   as a wall where the goal deadlines read as mileposts, and the dot marks
   where the scope line lands on it. */
.bu-target-line { stroke: var(--ink); stroke-width: 1.8; stroke-dasharray: 6 3; opacity: 1; }
.bu-target-dot { fill: var(--surface); stroke: var(--ink); stroke-width: 2.2; }
.bu-deadline-line {
  stroke: var(--warn); stroke-width: 1; stroke-dasharray: 3 3; opacity: 0.8;
  transform-box: view-box; transform-origin: 0px var(--plot-base, 200px);
  animation: chart-grow-up var(--chart-grow-ms) var(--chart-ease)
             calc(360ms + var(--i, 0) * 60ms) backwards;
}
/* Forecast fan (spec §3): best = strategy lime, likely = engineering cyan, worst = management orange.
   The three lines open outward from today's executed position — --fan-x/--fan-y
   carry that point, in user units, from the chart. */
.bu-fan-line {
  stroke-width: 1.5;
  transform-box: view-box; transform-origin: var(--fan-x, 0px) var(--fan-y, 0px);
  animation: chart-fan-open var(--chart-grow-ms) var(--chart-ease) 300ms backwards;
}
.bu-fan-best { stroke: var(--good); stroke-dasharray: 6 4; animation-delay: 300ms; }
.bu-fan-likely { stroke: var(--accent); stroke-dasharray: 6 4; animation-delay: 370ms; }
.bu-fan-worst { stroke: var(--warn); stroke-dasharray: 6 4; animation-delay: 440ms; }
/* Fan endpoint date labels (v0.3 feedback #1) — ink, never series colors.
   They wait for the fan to be nearly out: a date must not appear before the
   line it belongs to has reached it. */
.bu-fan-label {
  fill: var(--ink-soft); font-size: 10px; font-weight: 600; font-variant-numeric: tabular-nums;
  animation: chart-fade-in var(--chart-label-ms) var(--chart-ease) 1000ms backwards;
}
.bu-release {
  fill: var(--good); cursor: pointer;
  transform-box: fill-box; transform-origin: center;
  animation: chart-pop-in var(--chart-pop-ms) var(--chart-ease)
             calc(640ms + var(--i, 0) * 70ms) backwards;
}

/* Throughput bars grow from the baseline (--plot-base, in the SVG's own user
   units). Their fill is a gradient url() on the element, so no `fill` here. */
.tp-bar {
  transform-box: view-box; transform-origin: 0px var(--plot-base, 200px);
  animation: chart-grow-up var(--chart-grow-ms) var(--chart-ease)
             calc(var(--i, 0) * var(--chart-bar-stagger)) backwards;
}
/* The ISO week still running is a running total, not a finished week. */
.tp-partial { opacity: 0.55; stroke: var(--lp-strategy); stroke-width: 1; stroke-dasharray: 3 2; }
/* Monte Carlo distribution: bars grow like throughput's; the three marker
   lines wear the fan's own colors so P10/P50/P90 here and best/likely/worst
   on the burn-up read as one statement. */
.mc-bar {
  transform-box: view-box; transform-origin: 0px var(--plot-base, 200px);
  animation: chart-grow-up var(--chart-grow-ms) var(--chart-ease)
             calc(var(--i, 0) * var(--chart-bar-stagger)) backwards;
}
.mc-mark-best { stroke: var(--good); stroke-width: 1.2; stroke-dasharray: 5 4; }
.mc-mark-likely { stroke: var(--accent); stroke-width: 1.2; stroke-dasharray: 5 4; }
.mc-mark-worst { stroke: var(--warn); stroke-width: 1.2; stroke-dasharray: 5 4; }
.mc-mark-best-label { fill: var(--good); }
.mc-mark-likely-label { fill: var(--accent); }
.mc-mark-worst-label { fill: var(--warn); }
.forecast-dist { margin-top: 0.9rem; }

/* Map search: non-matching cards dim, matches stay lit. */
/* One search field for the whole shell (search-control.js, 2026-09-26): the
   map, the board and the backlog draw this class, so a person who learned one
   has learned all three. The tab classes beside it only size it for their bar. */
.search-field {
  padding: 0.35rem 0.6rem; border-radius: 8px; border: 1px solid var(--field-line);
  background: var(--field); color: var(--ink); font: inherit; width: 11rem;
}
.search-count { font-size: 0.74rem; color: var(--muted); white-space: nowrap; }
/* Wide enough to say the shortcut that reaches it from any tab, in both languages. */
.map-search { width: 18rem; max-width: 100%; }
.sq-dim, .card-dim, .backlog-row-dim, .nextup-dim, .tray-item-dim, .bubble-dim { opacity: 0.18; }
/* A found card stands out in its own tone, on every tab, in both themes: a
   ring with a soft halo, never a change of the card's own colours, so what the
   card says about its state still reads. */
.search-found:not(circle) {
  outline: 3px solid var(--found);
  outline-offset: 2px;
  box-shadow: 0 0 0 6px var(--found-soft);
  position: relative;
  z-index: 2;
}
circle.search-found { stroke: var(--found); stroke-width: 3; }
/* Archived releases: visible on demand, unmistakably muted. */
.r-archived { opacity: 0.55; }
.r-chip-archived { background: var(--surface-2); color: var(--muted); }

/* Backlog search + person filter (2026-09-02 meeting feedback), on the header
   row since 2026-09-26. The field is the shell's shared control. */
.backlog-search { flex: 0 1 14rem; min-width: 7rem; }
.backlog-person {
  padding: 0.35rem 0.6rem; border-radius: 8px; border: 1px solid var(--field-line);
  background: var(--field); color: var(--ink); font: inherit; max-width: 12rem;
}

/* Class of service: only the non-default classes wear a chip. */
.class-chip {
  font-size: 0.68rem; padding: 0.05rem 0.4rem; border-radius: 999px;
  text-transform: uppercase; letter-spacing: 0.04em;
}
.class-enabler { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); }
.class-debt { background: color-mix(in srgb, var(--warn) 16%, transparent); color: var(--warn); }
/* Failure demand wears the risk colour: it is the class we want to see shrink. */
.class-failure { background: color-mix(in srgb, var(--bad) 16%, transparent); color: var(--bad); }

/* Evidence of done — the proof the gate collected, on the card itself. */
.evidence-block { margin: 0.75rem 0 0.25rem; }
.evidence-entry { border-left: 2px solid var(--good); padding: 0.15rem 0 0.15rem 0.65rem; margin: 0.5rem 0; }
/* A closure without evidence is allowed for humans and SAID out loud. */
.evidence-none { border-left-color: var(--warn); }
.evidence-none .evidence-note { color: var(--warn); }
.evidence-chips { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-bottom: 0.3rem; }
.evidence-chip {
  font-size: 0.72rem; padding: 0.1rem 0.45rem; border-radius: 999px;
  background: color-mix(in srgb, var(--good) 18%, transparent); color: var(--good);
}
/* The card's own criteria at the closure: a second group, labelled, with an
   uncovered criterion muted and saying so. */
.evidence-group { margin-bottom: 0.35rem; }
.evidence-group-label { display: block; font-size: 0.68rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 0.2rem; }
.criteria-chip {
  font-size: 0.72rem; padding: 0.1rem 0.45rem; border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent);
}
.criteria-chip.is-uncovered { background: color-mix(in srgb, var(--muted) 14%, transparent); color: var(--muted); }
.evidence-note { margin: 0.15rem 0; font-size: 0.85rem; line-height: 1.45; }
.evidence-line { margin: 0; font-size: 0.85rem; color: var(--ink); }
.evidence-verdict { padding: 0.2rem 0 0.2rem 0.5rem; border-left: 2px solid var(--accent); }
.evidence-verdict-head { margin: 0; font-size: 0.8rem; color: var(--muted); }
.evidence-meta { margin: 0.15rem 0 0; font-size: 0.76rem; color: var(--muted); display: flex; gap: 0.6rem; align-items: baseline; }
.evidence-link { color: var(--accent); text-decoration: none; }
.evidence-link:hover { text-decoration: underline; }

/* The dates on the wall: the burn-up's vertical markers as readable rows.
   Fills the hero row's bottom-left with the dates the room lives against —
   content, not a taller chart. */
.wall-dates { margin-top: 0.9rem; border-top: 1px solid var(--line); padding-top: 0.7rem; }
.wall-row { display: flex; justify-content: space-between; gap: 1rem; padding: 0.3rem 0; font-size: 0.87rem; }
.wall-label { color: var(--text); }
.wall-when { color: var(--muted); white-space: nowrap; }
.wall-past { opacity: 0.55; }
.wall-near .wall-when { color: var(--warn); }

/* A week that completed nothing keeps a faint tick, so the zero is visible. */
.tp-zero {
  fill: var(--muted); opacity: 0.5;
  animation: chart-fade-in var(--chart-fade-ms) var(--chart-ease)
             calc(var(--i, 0) * var(--chart-bar-stagger)) backwards;
}
.chart-bar-value {
  animation: chart-label-in var(--chart-label-ms) var(--chart-ease)
             calc(380ms + var(--i, 0) * var(--chart-bar-stagger)) backwards;
}

/* CFD: to-do band in engineering cyan, in-flight/waiting in management orange,
   done in strategy lime — the same meanings as everywhere else. Bands are
   delineated by a surface-coloured hairline, so adjacent steps read apart
   regardless of how light the tint is; the table toggle is the text version.
   Flat fills, not gradients: the legend mirrors these exact opacities, and a
   legend that drifts from its chart is a lie. */
.cfd-band { animation: chart-fade-in var(--chart-fade-ms) var(--chart-ease) calc(var(--i, 0) * var(--chart-band-stagger)) backwards; }
.cfd-backlog, .cfd-ready, .cfd-in_progress,
.cfd-awaiting_review, .cfd-awaiting_client, .cfd-done,
/* A column a flow drew itself: the stylesheet has no colour for a name it was
   never written with, so the band carries its own fill and opacity inline and
   takes only the separating stroke from here. */
.cfd-designed { stroke: var(--surface); stroke-width: 1; }
.cfd-backlog { fill: var(--lp-engineering); opacity: 0.32; }
.cfd-ready { fill: var(--lp-engineering); opacity: 0.62; }
.cfd-in_progress { fill: var(--lp-management); opacity: 1; }
.cfd-awaiting_review { fill: var(--lp-management); opacity: 0.72; }
.cfd-awaiting_client { fill: var(--lp-management); opacity: 0.42; }
.cfd-done { fill: var(--lp-strategy); opacity: 1; }

/* A chart with nothing to draw is a sentence, not a broken plot. */
.chart-empty {
  min-height: 150px; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 0.3rem; padding: 1.2rem 1rem; text-align: center;
  border: 1px dashed var(--line); border-radius: 10px; background: var(--surface-2);
  animation: chart-fade-in var(--chart-fade-ms) var(--chart-ease) backwards;
}
.chart-empty-mark {
  width: 26px; height: 2px; border-radius: 2px; background: var(--line);
  box-shadow: 0 -7px 0 -0.5px var(--line), 0 7px 0 -0.5px var(--line);
  margin-bottom: 0.55rem;
}
.chart-empty-title { margin: 0; font-size: 0.86rem; font-weight: 700; color: var(--ink-soft); }
.chart-empty-note { margin: 0; font-size: 0.78rem; color: var(--muted); max-width: 42ch; line-height: 1.45; }
/* Same sentence, sparkline footprint: a 150px box inside a band cell would
   push the panel it explains off the screen. */
.chart-empty-inline {
  min-height: 0; padding: 0.6rem 0.7rem; gap: 0.15rem; align-items: flex-start; text-align: left;
}
.chart-empty-inline .chart-empty-mark { display: none; }
.chart-empty-inline .chart-empty-title { font-size: 0.8rem; }
.chart-empty-inline .chart-empty-note { font-size: 0.74rem; }

/* ── Reduced motion ─────────────────────────────────────────────────────────
   ONE place turns every chart entrance off. Because each keyframe declares
   only `from`, dropping the animation leaves the element on its static value
   — which is the final frame. The chart is painted once, complete, still. */
@media (prefers-reduced-motion: reduce) {
  .chart-draw, .chart-area, .chart-soft-in, .chart-end-dot, .chart-labels,
  .chart-dot-in, .chart-bar-value, .tp-bar, .tp-zero, .cfd-band,
  .bu-deadline-line, .bu-fan-line, .bu-fan-label, .bu-release,
  .vel-bar-fill, .chart-empty, .tl-card,
  .chart-holder *, .spark-holder * {
    animation: none !important;
  }
  /* The panel fade and its chevron still SAY the same thing — they just stop
     easing into it. The fade is never removed: it is information. */
  .panel-fade, .history-chevron { transition: none; }
}
.legend { display: flex; flex-wrap: wrap; gap: 0.35rem 0.8rem; margin-top: 0.5rem; }
/* The cumulative flow names its bands right under them, a little apart from the sentences that follow. */
.legend-cfd { margin: 0.6rem 0 0.75rem; }
.legend-item { display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.74rem; color: var(--ink-soft); }
.legend-swatch { width: 11px; height: 11px; border-radius: 3px; display: inline-block; }
.legend-swatch-unsized { background: transparent; border: 1.5px dashed var(--muted); }
/* Throughput bars — mirror the bar gradient and the unfinished-week treatment. */
.legend-swatch-tp, .legend-swatch-tp-partial {
  background: var(--lp-strategy); /* fallback if color-mix is unavailable */
  background: linear-gradient(180deg,
    var(--lp-strategy),
    color-mix(in srgb, var(--lp-strategy) 25%, transparent));
}
.legend-swatch-tp-partial { opacity: 0.55; outline: 1px dashed var(--lp-strategy); outline-offset: -1px; }

/* Line-style legend swatches (v0.3 feedback #3) — mirror the chart classes. */
.legend-line { width: 22px; height: 0; display: inline-block; border-top: 2px solid var(--line); }
.legend-line-scope { border-top: 2px dashed var(--muted); }
.legend-line-exec { border-top: 3px solid var(--good); }
.legend-line-planned { border-top: 2px dotted var(--ink-soft); }
.legend-line-best { border-top: 2px dashed var(--good); }
.legend-line-likely { border-top: 2px dashed var(--accent); }
.legend-line-worst { border-top: 2px dashed var(--warn); }

/* Bubble-radius legend (economics lens, v0.3 feedback #3). */
.legend-bubble { display: inline-block; border-radius: 50%; background: var(--lp-engineering); opacity: 0.55; }
.legend-bubble-xs { width: 6px; height: 6px; }
.legend-bubble-s { width: 9px; height: 9px; }
.legend-bubble-m { width: 12px; height: 12px; }
.legend-bubble-l { width: 15px; height: 15px; }
.legend-bubble-xl { width: 19px; height: 19px; }
.legend-bubble-unsized { background: transparent; border: 1.5px dashed var(--muted); opacity: 0.9; }

/* Scatter (charts addendum §1) — RADIUS carries the size class, so colour is
   free to keep its usual meaning: every dot is a completed item, so every dot
   is strategy lime. `fill-opacity`, not `opacity`: the fill has to accumulate
   where bubbles overlap (density reads as darker) while the surface-coloured
   stroke stays opaque, which is what keeps overlapping bubbles countable.
   The .scatter-<size> classes stay as data hooks — they no longer paint. */
.scatter-pct { stroke: var(--muted); stroke-width: 1; stroke-dasharray: 5 4; animation-delay: 300ms; }
.scatter-dot {
  cursor: pointer;
  fill: var(--lp-strategy); fill-opacity: 0.75;
  stroke: var(--surface); stroke-width: 1;
}
/* No size class: the M radius, but dashed and unfilled — visibly missing a
   size rather than silently averaged into one. */
.scatter-unsized { fill: none; stroke: var(--muted); stroke-width: 1.5; stroke-dasharray: 3 2; }
.scatter-dot:hover, .scatter-dot:focus-visible { fill-opacity: 0.95; stroke: var(--accent); stroke-width: 2; }
/* Same focus ring as every other control in the shell — the dot is a button. */
.scatter-dot:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Scatter size key — diameters are set inline from SIZE_RADII so the key
   cannot drift from the plot, and the caption names the encoding out loud
   (the story map's cards encode size as HEIGHT; two encodings of one variable
   must not be confused for each other). */
.legend-bubbles { align-items: center; }
.legend-caption { font-size: 0.74rem; font-weight: 700; color: var(--muted); }
.legend-bubble-scatter {
  background: var(--lp-strategy); opacity: 0.75;
  border: 1px solid var(--surface); box-sizing: border-box; flex: none;
}
.legend-bubble-scatter.legend-bubble-unsized {
  background: transparent; border: 1.5px dashed var(--muted); opacity: 0.9;
}

/* ── Hover timeline card (charts addendum §2) ─────────────────────────────
   Fixed to the viewport and placed by JS (flips above/below the dot rather
   than overflowing). pointer-events:none on purpose: the card must never
   swallow the pointer-out that dismisses it. */
.tl-card {
  position: fixed; left: 0; top: 0; z-index: 30; pointer-events: none;
  width: max-content; max-width: min(26rem, calc(100vw - 16px));
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 6px 24px rgba(10, 16, 22, 0.22);
  padding: 0.55rem 0.7rem 0.6rem;
  animation: chart-fade-in 140ms var(--chart-ease) backwards;
}
.tl-card[hidden] { display: none; }

/* Burn-up hover readout — one line, tracks the cursor, same rules as the
   timeline card: fixed, placed by JS, never swallows the pointer. */
.bu-hover {
  position: fixed; left: 0; top: 0; z-index: 30; pointer-events: none;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 4px 16px rgba(10, 16, 22, 0.18);
  padding: 0.3rem 0.55rem; font-size: 0.76rem; font-weight: 600;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.bu-hover[hidden] { display: none; }

/* The verdict row under the burn-up legend: chip + reason left, the numbers
   that produce the verdict right. Wraps on narrow screens. */
.burnup-verdict {
  display: flex; justify-content: space-between; align-items: center;
  gap: 0.75rem 1.25rem; flex-wrap: wrap; margin-top: 0.55rem;
}
.burnup-verdict-left { display: flex; align-items: center; gap: 0.6rem; min-width: 0; }
.burnup-verdict-reason { font-size: 0.8rem; color: var(--ink-soft); line-height: 1.4; }
.burnup-verdict-facts { font-size: 0.8rem; color: var(--muted); white-space: nowrap; }

/* A holder that has not entered the viewport yet holds every animation at
   frame zero; JS (armChartReveal in dom.js) removes the class about a second
   after the holder scrolls into view. !important on purpose: the animation
   shorthands below would otherwise reset play-state to running whenever they
   sit later in the cascade. */
.chart-wait * { animation-play-state: paused !important; }

/* First-visit orientation — four sentences, dismissed once, gone forever. */
/* A new flow's first hour: the cockpit greets and teaches until the first card
   is done. The steps are read from the record; the next one leads. */
.onboarding { border-left: 4px solid var(--accent); margin-bottom: 1rem; }
.instruments-pending { margin: 1rem 0; }
.onboarding .panel-head { align-items: baseline; }
.onboarding-progress { font-size: 0.8rem; font-weight: 700; color: var(--muted); }
.onboarding-lead { margin: 0.2rem 0 0.8rem; font-size: 0.9rem; color: var(--ink-soft); max-width: 48rem; line-height: 1.5; }
.onboarding-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.45rem; }
.onboarding-step {
  display: grid; grid-template-columns: 1.6rem minmax(0, 1fr) auto; align-items: center; gap: 0.7rem;
  padding: 0.6rem 0.75rem; border-radius: 10px; background: var(--surface-2);
  border: 1px solid transparent;
}
.onboarding-step.is-next { background: var(--accent-soft); border-color: var(--accent); }
.onboarding-step.is-done { background: transparent; border-color: var(--line); }
.onboarding-step-mark {
  width: 1.5rem; height: 1.5rem; border-radius: 99px; border: 2px solid var(--line);
  display: grid; place-items: center; font-size: 0.85rem; font-weight: 800; color: var(--on-accent);
}
.onboarding-step.is-next .onboarding-step-mark { border-color: var(--accent); }
.onboarding-step.is-done .onboarding-step-mark { background: var(--good); border-color: var(--good); }
.onboarding-step-title { margin: 0; font-size: 0.92rem; font-weight: 700; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem; }
.onboarding-step.is-done .onboarding-step-title { color: var(--ink-soft); }
.onboarding-step-state {
  font-size: 0.66rem; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--good); background: var(--good-soft); padding: 0.05rem 0.45rem; border-radius: 99px;
}
.onboarding-step-state.is-next { color: var(--accent); background: var(--surface); }
.onboarding-step-why { margin: 0.15rem 0 0; font-size: 0.82rem; color: var(--ink-soft); line-height: 1.45; }
/* Who can do the step: served with the list, so the agent's brief says the same. */
.onboarding-step-who { margin: 0.2rem 0 0; font-size: 0.72rem; font-weight: 600; color: var(--muted); }
/* The context step's sheet: two files, answered in place. */
.setup-file { width: 100%; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.8rem; line-height: 1.45; }
.setup-unanswered ul { margin: 0.2rem 0 0.6rem; padding-left: 1.1rem; font-size: 0.82rem; color: var(--ink-soft); }
.setup-status:empty { display: none; }
.onboarding-agent {
  margin: 0.9rem 0 0; padding-top: 0.75rem; border-top: 1px solid var(--line);
  font-size: 0.84rem; color: var(--ink-soft); line-height: 1.5; max-width: 48rem;
}
@media (max-width: 34rem) {
  .onboarding-step { grid-template-columns: 1.6rem minmax(0, 1fr); }
  .onboarding-step > .btn { grid-column: 2; justify-self: start; }
}
/* An instrument with nothing to measure says so in one line. */
.instrument-pending-list { margin: 0; padding-left: 1.1rem; display: grid; gap: 0.35rem; }
.instrument-pending { font-size: 0.85rem; color: var(--ink-soft); line-height: 1.45; }
/* The first steps, folded inside the introduction of a flow that already flows. */
.onboarding-folded { margin: 0.2rem 0 0.7rem; display: grid; gap: 0.5rem; }
.onboarding-fold-toggle {
  justify-self: start; border: 0; background: transparent; padding: 0; cursor: pointer;
  font: inherit; font-size: 0.84rem; font-weight: 700; color: var(--accent); text-decoration: underline;
}
/* The Metrics tab before anything has finished. */
.metrics-pending-list { margin: 0; display: grid; gap: 0.6rem; }
.metrics-pending-row { display: grid; grid-template-columns: minmax(9rem, 14rem) minmax(0, 1fr); gap: 0.2rem 1rem; padding: 0.6rem 0; border-top: 1px solid var(--line); }
.metrics-pending-name { font-weight: 700; font-size: 0.9rem; }
.metrics-pending-row dd { margin: 0; font-size: 0.86rem; color: var(--ink-soft); line-height: 1.5; }
.metrics-pending-starts { color: var(--ink); font-weight: 600; }
@media (max-width: 34rem) { .metrics-pending-row { grid-template-columns: minmax(0, 1fr); } }
.intro-panel { margin-bottom: 1rem; border-left: 3px solid var(--accent); }
.intro-list { margin: 0 0 0.6rem; padding-left: 1.1rem; display: grid; gap: 0.3rem; }
.intro-list li { font-size: 0.84rem; color: var(--ink-soft); line-height: 1.45; }

/* TARGET MISSED — a fact, worn solid where the forecast verdicts are drawn. */
.status-chip.status-missed { background: var(--bad); color: var(--surface); }

/* Map zoom controls + the hidden-engineering disclosure chip. */
.map-zoom { display: inline-flex; align-items: center; gap: 0.3rem; }

/* Which map: one toggle at the head of the bar (card you-can-see-what-depends-on-what). */
.map-mode { display: inline-flex; gap: 0.2rem; flex: none; }
.map-mode-btn[aria-pressed="true"] { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }

/* The map of dependencies: bands per release, cards on a row grid, links in
   the gutters and row gaps. Geometry comes from deps-layout.js; this only
   paints it. */
.dep-summary { margin: 0 0 0.4rem; font-size: 0.8rem; color: var(--muted); }
.dep-legend { display: flex; flex-wrap: wrap; gap: 0.3rem 1rem; margin: 0 0 0.6rem; font-size: 0.74rem; color: var(--muted); }
.dep-legend-item { display: inline-flex; align-items: center; gap: 0.35rem; }
.dep-swatch { display: inline-block; width: 1.4rem; height: 0; border-top: 2px solid var(--accent); }
.dep-swatch-broken { border-top: 2px dashed var(--bad); }
.dep-body { overflow: auto; }
.depmap { position: relative; }
.dep-group {
  position: absolute; top: 0.6rem; height: 2rem; display: flex; align-items: baseline; gap: 0.5rem;
  padding: 0 0.2rem 0.3rem; border-bottom: 2px solid var(--line); font-size: 0.8rem; color: var(--ink-soft);
  overflow: hidden; white-space: nowrap;
}
.dep-group-name { font-weight: 700; }
.dep-group-date { color: var(--muted); font-size: 0.74rem; }
.dep-links { position: absolute; left: 0; top: 0; pointer-events: none; overflow: visible; }
.dep-edge, .dep-trunk { fill: none; stroke: var(--accent); stroke-width: 1.6; stroke-linejoin: round; stroke-linecap: round; }
.dep-edge.dep-broken { stroke: var(--bad); stroke-dasharray: 6 4; }
.dep-junction { fill: var(--accent); }
.dep-arrow { fill: var(--accent); }
.dep-arrow-broken { fill: var(--bad); }
.dep-edge.dep-lit, .dep-trunk.dep-lit { stroke-width: 2.4; }
.dep-edge.dep-dim, .dep-trunk.dep-dim, .dep-junction.dep-dim { opacity: 0.18; }
/* The wide, invisible twin of each branch takes the pointer; a hair-thin stroke is no hit target. */
.dep-hit { fill: none; stroke: transparent; stroke-width: 12; pointer-events: stroke; cursor: pointer; }
/* Resting the pointer on a card or a link: that link end to end, its trunk and both cards stay, the rest fades. */
.depmap.dep-hovering .dep-node:not(.dep-hover) { opacity: 0.3; }
.depmap.dep-hovering .dep-edge:not(.dep-hover), .depmap.dep-hovering .dep-trunk:not(.dep-hover), .depmap.dep-hovering .dep-junction { opacity: 0.12; }
.depmap.dep-hovering .dep-edge.dep-hover, .depmap.dep-hovering .dep-trunk.dep-hover { opacity: 1; stroke-width: 2.6; }
.depmap.dep-hovering .dep-node.dep-hover { opacity: 1; border-color: var(--accent); }
.dep-node {
  position: absolute; box-sizing: border-box; display: flex; flex-direction: column; justify-content: space-between;
  padding: 10px; gap: 0.2rem; text-align: left; font: inherit; color: var(--ink); cursor: pointer;
  background: var(--surface); border: 1px solid var(--line); border-radius: 8px; box-shadow: var(--shadow);
}
.dep-node:hover { border-color: var(--accent); }
.dep-node:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.dep-node.dep-decision { border-style: dashed; border-color: var(--dep); }
.dep-node.dep-selected { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.dep-node.dep-lit { border-color: var(--accent); }
.dep-node.dep-dim { opacity: 0.35; }
.dep-title { font-size: 0.82rem; font-weight: 600; line-height: 17px; overflow-wrap: anywhere; }
.dep-meta { display: flex; justify-content: space-between; align-items: center; gap: 0.4rem; font-size: 0.7rem; color: var(--muted); height: 20px; }
.dep-open { font: inherit; font-size: 0.7rem; color: var(--accent); background: none; border: 0; padding: 0; cursor: pointer; }
.dep-open:hover { text-decoration: underline; }
.dep-empty { padding: 2rem 1rem; }
.map-zoom-level { font-size: 0.74rem; color: var(--muted); min-width: 2.6rem; text-align: center; }
.r-chip-eng { color: var(--muted); background: var(--surface-2); font-weight: 600; }

/* Projected dates on the queue: quiet, tabular, right of the meta. */
.seq-date { display: block; font-size: 0.7rem; color: var(--ink-soft); margin-top: 0.15rem; }
.nextup-date { display: block; font-size: 0.72rem; color: var(--ink-soft); margin-top: 0.1rem; }
.release-notes-date { margin-left: auto; font-size: 0.74rem; color: var(--ink-soft); flex: none; }

/* Release notes on the release sheet: shipped + coming, announceable. */
.release-notes { margin: 0.6rem 0 0; }
.release-notes-epics { margin: 0.15rem 0 0.3rem; font-size: 0.76rem; color: var(--ink-soft); }
.release-notes-list { list-style: none; margin: 0.25rem 0 0; padding: 0; display: grid; gap: 0.15rem; }
.release-notes-item {
  display: flex; align-items: center; gap: 0.45rem; width: 100%; text-align: left;
  border: none; background: none; color: var(--ink); font: inherit; font-size: 0.82rem;
  padding: 0.25rem 0.2rem; border-radius: 6px; cursor: pointer;
}
.release-notes-item:hover { background: var(--accent-soft); }

/* Latest happenings — the ledger, worn as a feed. Bounded page + "Show
   more"; the cockpit stays calm. */
/* Working now: who is on the flow right now and what they hold. A row is
   facts in recency order and nothing that could read as a score. */
.presence-panel { margin: 0 0 0.9rem; }
.presence-list { display: grid; gap: 0.15rem; margin-top: 0.3rem; }
.presence-row { padding: 0.4rem 0.2rem; border-bottom: 1px solid var(--line); }
.presence-row:last-child { border-bottom: none; }
.presence-line { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; flex-wrap: wrap; }
.presence-who { font-size: 0.86rem; font-weight: 600; color: var(--ink); min-width: 0; overflow-wrap: anywhere; display: inline-flex; align-items: center; gap: 0.4rem; }
.presence-dot { width: 0.55rem; height: 0.55rem; border-radius: 50%; background: var(--good); flex: none; }
.presence-quiet .presence-dot { background: var(--muted); }
.presence-quiet .presence-who { color: var(--ink-soft); font-weight: 500; }
.presence-when { font-size: 0.72rem; color: var(--muted); flex: none; }
.presence-holds { display: flex; flex-wrap: wrap; gap: 0.3rem 0.6rem; margin-top: 0.15rem; }
.presence-card { font: inherit; font-size: 0.76rem; color: var(--ink-soft); background: none; border: 0; padding: 0; text-align: left; overflow-wrap: anywhere; }
button.presence-card { cursor: pointer; color: var(--accent); }
button.presence-card:hover { text-decoration: underline; }
button.presence-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.presence-none { color: var(--muted); }
.presence-sessions { display: grid; gap: 0.15rem; margin: 0.3rem 0 0 0.35rem; padding-left: 0.6rem; border-left: 2px solid var(--line); }
.presence-session { padding: 0.15rem 0; }
.presence-session-who { font-weight: 500; font-size: 0.8rem; }
.presence-session .presence-dot { width: 0.45rem; height: 0.45rem; }
.presence-note { margin: 0.5rem 0 0; font-size: 0.72rem; color: var(--muted); line-height: 1.4; display: flex; flex-direction: column; gap: 0.15rem; }
.hap-panel { margin: 1rem 0; }
.hap-toggles { display: flex; gap: 0.35rem; }
.hap-lane[aria-pressed="true"] { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
.hap-list { display: grid; gap: 0.15rem; margin-top: 0.5rem; }
.hap-row { padding: 0.4rem 0.2rem; border-bottom: 1px solid var(--line); }
/* Rows that lead somewhere look like it, and say so on hover. */
button.hap-row {
  display: block; width: 100%; border-top: 0; border-left: 0; border-right: 0;
  background: none; font: inherit; color: inherit; cursor: pointer; text-align: left;
}
button.hap-row:hover { background: var(--accent-soft); }
button.hap-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.hap-row:last-child { border-bottom: none; }
.hap-line { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; }
.hap-head { font-size: 0.84rem; color: var(--ink); min-width: 0; overflow-wrap: anywhere; }
.hap-when { font-size: 0.72rem; color: var(--muted); flex: none; }
.hap-detail { margin: 0.15rem 0 0; font-size: 0.76rem; color: var(--ink-soft); line-height: 1.4; }
/* Worklog entries are session cards: headline, who/when/hours, structured
   body. Collapsed unless newest — the full note is one click away. */
.hap-worklog { border-left: 3px solid var(--accent); padding-left: 0.6rem; }
details.hap-worklog > .wl-summary {
  cursor: pointer; display: flex; justify-content: flex-start; align-items: baseline;
  gap: 0.4rem; min-height: 2.2rem; list-style: none; text-align: left;
}
/* The meta rides the right edge; the title stays LEFT beside the marker. */
details.hap-worklog > .wl-summary > .hap-when { margin-left: auto; flex: none; }
details.hap-worklog > .wl-summary::-webkit-details-marker { display: none; }
details.hap-worklog > .wl-summary::before {
  content: "▸"; color: var(--accent); margin-right: 0.4rem; flex: none;
}
details[open].hap-worklog > .wl-summary::before { content: "▾"; }
.wl-title { font-size: 0.88rem; font-weight: 700; color: var(--ink); min-width: 0; }
.wl-card-ref {
  margin: 0.1rem 0 0; font-size: 0.74rem; color: var(--accent);
  border: none; background: none; padding: 0; cursor: pointer; text-align: left;
}
.wl-body { padding: 0.2rem 0 0.5rem; display: grid; gap: 0.3rem; }
.wl-section { margin: 0.45rem 0 0.05rem; font-size: 0.8rem; font-weight: 700; color: var(--ink); }
.wl-para { margin: 0; font-size: 0.8rem; color: var(--ink-soft); line-height: 1.5; }
.wl-list { margin: 0; padding-left: 1.15rem; display: grid; gap: 0.25rem; }
.wl-list li { font-size: 0.8rem; color: var(--ink-soft); line-height: 1.5; }
.wl-body code {
  font-family: ui-monospace, monospace; font-size: 0.74rem;
  background: var(--surface-2); border-radius: 4px; padding: 0.05rem 0.3rem;
}
.hap-more { margin-top: 0.5rem; }

/* Pins — the human's tracked exception to the sequence. The chip carries
   who/when/why in its title; the ✕ unpins. Drag marks show the drop edge. */
.nextup-pinned { border-left: 3px solid var(--accent); }
.pin-chip {
  display: inline-flex; align-items: center; gap: 0.3rem; margin-left: 0.45rem;
  font-size: 0.68rem; font-weight: 700; color: var(--accent);
  background: var(--accent-soft); border-radius: 99px; padding: 0.1rem 0.45rem;
  vertical-align: middle;
}
/* A pin older than its column's aging threshold asks for a review. */
.pin-chip-stale { color: var(--warn); background: var(--warn-soft); }
.pin-chip-stale .pin-unpin { color: var(--warn); }
.pin-unpin {
  border: none; background: none; color: var(--accent); cursor: pointer;
  font-size: 0.7rem; padding: 0 0.1rem; line-height: 1;
}
.nextup-draggable .nextup-row { cursor: grab; }
/* The full-length list scrolls itself, so revealing a linked row moves the
   LIST, never the page. */
.nextup-scroll { max-height: 30rem; overflow-y: auto; overscroll-behavior: contain; }
.pin-pending-chip {
  display: inline-flex; margin-left: 0.45rem; font-size: 0.68rem; font-weight: 700;
  color: var(--muted); background: var(--surface-2); border-radius: 99px; padding: 0.1rem 0.45rem;
}
.nextup-dragging { opacity: 0.45; }
.nextup-drop-before { box-shadow: 0 -2px 0 0 var(--accent); }
.nextup-drop-after { box-shadow: 0 2px 0 0 var(--accent); }
.pin-pop {
  position: fixed; z-index: 50; width: min(22rem, calc(100vw - 16px));
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 6px 24px rgba(10, 16, 22, 0.28);
  padding: 0.7rem 0.8rem; display: grid; gap: 0.5rem;
  animation: chart-fade-in 140ms var(--chart-ease) backwards;
}
.pin-pop-title { margin: 0; font-size: 0.82rem; font-weight: 700; }
.pin-pop input {
  font: inherit; color: var(--ink); background: var(--field); border: 1px solid var(--field-line);
  border-radius: 7px; padding: 0.45rem 0.6rem; width: 100%;
}
.pin-pop-note { margin: 0; font-size: 0.74rem; color: var(--muted); line-height: 1.4; }
.pin-pop-error { margin: 0; font-size: 0.74rem; color: var(--bad); }
.pin-pop-actions { display: flex; justify-content: flex-end; gap: 0.4rem; }
.sheet-pin { display: grid; gap: 0.45rem; }
details.sheet-pin {
  border: 1px solid var(--line); border-left: 4px solid var(--accent);
  border-radius: 0 9px 9px 0; padding: 0.6rem 0.8rem; margin: 0.5rem 0 0.6rem;
  background: var(--surface-2);
}
details.sheet-pin > summary {
  cursor: pointer; min-height: 2.75rem; display: flex; align-items: center; margin-bottom: 0;
}
details.sheet-pin > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.sheet-pin-line { margin: 0; font-size: 0.8rem; color: var(--ink-soft); }
.sheet-pin input[type="number"] { flex: 0 0 5.5rem; }

/* Chart ⇄ list linking (economics lens): hovering a bubble highlights the
   card's row; hovering a row lights up its dot. Highlight only — linking
   never scrolls the page. */
/* The ring, not a wash: an inset accent border makes the linked row stand
   out on the dark surface where a soft background tint disappeared. */
.nextup-row.econ-hover { box-shadow: inset 0 0 0 2px var(--accent); }
/* The dots already wear a 1.5px accent stroke, so the hover state must jump,
   never whisper: full opacity and a heavy ring. */
.bubble-dot.dot-hover { opacity: 1; stroke-width: 5; }

/* The velocity readout under the throughput bars. The bars cap at a readable
   width — a 10px track stretched across a whole panel reads as a ruler. */
.tp-velocity { margin-top: 0.6rem; }
.tp-velocity .vel-bar-row { max-width: 420px; }
.tp-velocity .band-title { margin-bottom: 0.15rem; }

/* The per-size percentile table under the cycle-time scatter. */
.per-size { margin-top: 0.55rem; }
.per-size > * + * { margin-top: 0.4rem; }
.per-size-table { border-collapse: collapse; font-size: 0.78rem; width: 100%; }
.per-size-table th, .per-size-table td {
  padding: 0.22rem 0.9rem 0.22rem 0; text-align: left; border-bottom: 1px solid var(--line);
}
.per-size-table th:last-child, .per-size-table td:last-child {
  text-align: right; padding-right: 0;
}
.per-size-table thead th {
  color: var(--muted); font-weight: 600; font-size: 0.7rem;
  text-transform: uppercase; letter-spacing: 0.04em;
}
.per-size-table tbody th { color: var(--ink); font-weight: 700; }
.per-size-table tbody td { color: var(--ink-soft); }

/* The flow readout under the CFD: three sentences, quiet, numbers tabular. */
.cfd-readout { margin-top: 0.55rem; display: grid; gap: 0.3rem; }
.cfd-readout-row { margin: 0; font-size: 0.8rem; color: var(--ink-soft); line-height: 1.45; }
.cfd-readout-row strong { color: var(--ink); }
.tl-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.tl-title { font-size: 0.84rem; font-weight: 700; overflow-wrap: anywhere; }
.tl-total { font-size: 0.84rem; font-weight: 800; color: var(--good); flex: none; }
.tl-completed { margin: 0.1rem 0 0; font-size: 0.74rem; color: var(--muted); }
.tl-note { margin: 0.45rem 0 0; font-size: 0.74rem; color: var(--muted); max-width: 34ch; line-height: 1.45; }

/* The run of states: dwell above, a rule with one dot per transition through
   the middle, state + entry date below — the reference's exact shape. */
.tl-run { display: flex; margin-top: 0.5rem; overflow-x: auto; }
/* The run is drawn to scale: each segment's flex-grow is set from the model,
   because only the model knows how long each stay was (Samuel, 2026-09-08:
   "it does not respect any scale"). The basis is zero so growth alone decides
   the share, and the minimum keeps a very short stay legible rather than
   letting true proportion squeeze it to nothing. */
.tl-seg {
  display: grid; grid-template-rows: auto 10px auto auto; align-content: start;
  min-width: 5.2rem; padding-right: 0.7rem; flex: 0 0 auto; flex-basis: 0;
}
/* The end is a moment, not a stay: it takes only the width its date needs. */
.tl-seg-end { flex: 0 0 auto; min-width: 4.4rem; padding-right: 0; }
.tl-seg-end .tl-rule { background: none; }
.tl-seg-end .tl-rule::before { background: var(--good); width: 8px; height: 8px; margin-top: -4px; }
.tl-seg-end .tl-state { color: var(--good); }
.tl-seg:last-child { padding-right: 0; }
.tl-dwell { font-size: 0.72rem; font-weight: 700; color: var(--ink-soft); }
.tl-rule {
  position: relative; align-self: center; height: 1px; background: var(--line);
}
/* The transition dot sits on the rule at the moment the state was entered. */
.tl-rule::before {
  content: ""; position: absolute; left: 0; top: 50%;
  width: 6px; height: 6px; margin-top: -3px; border-radius: 50%;
  background: var(--accent);
}
.tl-state { font-size: 0.72rem; font-weight: 600; color: var(--ink); margin-top: 0.2rem; }
.tl-entered { font-size: 0.7rem; color: var(--muted); }
/* Waiting is time parked on a person — management orange, everywhere. */
.tl-seg-waiting .tl-dwell, .tl-seg-waiting .tl-state { color: var(--warn); }
.tl-seg-waiting .tl-rule { background: var(--lp-management); }
.tl-seg-waiting .tl-rule::before { background: var(--lp-management); }
.tl-waiting {
  margin: 0.45rem 0 0; font-size: 0.74rem; font-weight: 700; color: var(--warn);
}
/* Impeded time: something was in the card's way. Louder than waiting, because
   waiting is how the flow levels itself and this is time nobody chose. */
.tl-impeded {
  margin: 0.1rem 0 0; font-size: 0.74rem; font-weight: 700; color: var(--bad);
}

/* ── Card sheet ─────────────────────────────────────────────────────────── */
.sheet-backdrop {
  position: fixed; inset: 0; background: rgba(10, 16, 22, 0.45); z-index: 20;
}
/*
 * A display rule beats the UA's [hidden] rule, and this file sets display on
 * plenty of classes that also toggle hidden (the resolution row, popovers,
 * errors). Say it once, first, so hidden always means hidden.
 */
[hidden] { display: none !important; }

.sheet {
  position: fixed; left: 0.75rem; right: 0.75rem; bottom: 1.25rem; z-index: 21;
  background: var(--surface); border-radius: 14px;
  padding: 1rem 1rem 1.4rem; max-height: calc(100vh - 2.5rem); overflow-y: auto;
  box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.25);
  max-width: 40rem; margin: 0 auto;
}

/*
 * The card sheet (2026-09-04). Every other sheet edits four fields and stays a
 * drawer; a card carries the work, its shape, and its whole record, so it is a
 * dialog with a head that never scrolls away, a scrolling body and actions
 * pinned to the bottom edge. It was a 40rem column on a 1280px screen, which
 * put Save nine hundred pixels below the title.
 */
.sheet.sheet-card {
  top: 1.25rem; bottom: 1.25rem;
  display: grid; grid-template-rows: auto minmax(0, 1fr) auto;
  padding: 0; overflow: hidden;
  max-width: min(72rem, calc(100vw - 1.5rem));
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.38);
}
.sheet-card .sheet-head {
  padding: 1rem 1.15rem 0.75rem;
  border-bottom: 1px solid var(--line);
  background: var(--surface);
}
.sheet-card .sheet-head h2 { margin: 0 0 0.2rem; font-size: 1.15rem; line-height: 1.25; }
.sheet-moved {
  margin: 0.6rem 0 0; padding: 0.5rem 0.65rem;
  border: 1px solid var(--warn); border-radius: 8px;
  font-size: 0.8rem; color: var(--warn);
  display: flex; gap: 0.6rem; align-items: center; flex-wrap: wrap;
}
.sheet-kicker {
  margin: 0 0 0.2rem; font-size: 0.7rem; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted);
}
/* The id an agent quotes, beside the kicker that says what this is. Same quiet
   register as the kicker, monospace so a slug reads as a slug, and selectable
   so it can be pasted straight back into a session. */
.sheet-id {
  margin: 0.1rem 0 0; text-transform: none; letter-spacing: 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.72rem; font-weight: 500; color: var(--muted); user-select: all;
}
.sheet-card .sheet-chips { margin: 0.5rem 0 0; }
.sheet-card .sheet-needs { margin: 0.5rem 0 0; }
.sheet-body {
  overflow-y: auto; overscroll-behavior: contain;
  padding: 1.15rem 1.15rem 1.4rem;
  display: grid; gap: 1.5rem; align-content: start;
}
.sheet-columns { display: grid; gap: 1.5rem; align-items: start; }
.sheet-col { display: grid; gap: 1.35rem; align-content: start; min-width: 0; }
.sheet-group { display: grid; gap: 0.55rem; min-width: 0; }
.sheet-group-title {
  margin: 0; font-size: 0.82rem; font-weight: 700; color: var(--ink-soft);
}
.sheet-field { display: grid; gap: 0.25rem; min-width: 0; }
.sheet-field > .sheet-label { margin-bottom: 0; }
.sheet-record { display: grid; gap: 0.9rem; padding-top: 1.25rem; border-top: 1px solid var(--line); }
.sheet-record:empty { display: none; }
/* First in the body on a closed card: no rule above it, and the separation
   below belongs to the group that follows. */
.sheet-record:first-child { padding-top: 0; border-top: 0; padding-bottom: 1.25rem; border-bottom: 1px solid var(--line); }
/* Where the time went: the scatter card's own .tl-* run, on the sheet. A grid
   item is min-width:auto, so without this the run of states widens the sheet
   instead of scrolling sideways inside its own block. */
.time-block { min-width: 0; }
.sheet-card .sheet-actions {
  margin: 0; padding: 0.8rem 1.15rem;
  border-top: 1px solid var(--line); background: var(--surface-2);
  border-radius: 0 0 14px 14px;
}
/*
 * State on the card sheet is one value with seven options, so it reads as a
 * row of pills. As a 2-column grid of full-width buttons it ate 450px of the
 * column and pushed size, value and risk reduction, the three numbers the
 * queue is ordered by, below the fold.
 */
.sheet-card .move-grid { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0; }
.sheet-card .move-btn {
  min-height: 2rem; padding: 0.3rem 0.7rem; border-radius: 999px;
  font-size: 0.76rem; font-weight: 600;
}
@media (pointer: coarse) {
  .sheet-card .move-btn { min-height: 2.75rem; padding: 0.5rem 0.9rem; } /* ≥44px touch target */
}

/* Two columns once the work and its shape can sit side by side without either
   dropping below a readable measure. */
@media (min-width: 62rem) {
  .sheet-columns { grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr); gap: 2rem; }
  .sheet-body { padding: 1.4rem 1.5rem 1.6rem; }
  .sheet-card .sheet-head { padding: 1.2rem 1.5rem 0.9rem; }
  .sheet-card .sheet-actions { padding: 0.85rem 1.5rem; }
}
/* A phone keeps the drawer feel: full width, one column, actions still pinned. */
@media (max-width: 34rem) {
  .sheet.sheet-card { left: 0.4rem; right: 0.4rem; top: 0.6rem; bottom: 0.6rem; }
  .sheet-card .move-grid { grid-template-columns: 1fr; }
}
.sheet h2 { margin: 0 0 0.2rem; font-size: 1rem; }
.sheet-sub { margin: 0 0 0.5rem; font-size: 0.78rem; color: var(--muted); }
.lineage { margin: 0 0 0.2rem; font-size: 0.78rem; color: var(--accent); font-weight: 600; }
.sheet-chips { display: flex; flex-wrap: wrap; gap: 0.35rem; margin: 0 0 0.6rem; }
.sheet-form { display: grid; gap: 0.55rem; margin: 0.6rem 0 0.9rem; }
.sheet-label { font-size: 0.74rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: -0.35rem; }
.move-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.45rem; margin-top: 0.4rem; }
.move-btn {
  border: 1px solid var(--line); background: var(--surface-2); color: var(--ink);
  border-radius: 8px; padding: 0.5rem 0.4rem; font-size: 0.8rem; font-weight: 600; cursor: pointer;
  min-height: 2.75rem;
}
.move-btn.current { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); cursor: default; }
.sheet-actions { display: flex; gap: 0.5rem; justify-content: flex-end; margin-top: 0.9rem; flex-wrap: wrap; }
/* A decision's answer leads its card: the first thing under the question, one
   field and one button (card answering-a-decision-is-obvious-on-the-card). */
.decision-answer {
  display: grid; gap: 0.45rem; margin: 0.6rem 0 0.7rem; padding: 0.75rem 0.85rem;
  background: var(--accent-soft); border: 1px solid var(--accent); border-left-width: 4px; border-radius: 8px;
}
.decision-answer .answer-label { font-weight: 700; font-size: 0.95rem; color: var(--ink); margin: 0; }
.decision-answer .answer-help { margin: 0; font-size: 0.82rem; color: var(--ink-soft); }
.decision-answer .answer-input {
  width: 100%; min-height: 4.2rem; resize: vertical; font: inherit; padding: 0.5rem 0.6rem;
  color: var(--ink); background: var(--field); border: 1px solid var(--field-line); border-radius: 6px;
}
.decision-answer .answer-input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.decision-answer .answer-record { justify-self: start; }
.decision-answer .answer-problem { margin: 0; font-size: 0.82rem; color: var(--bad); }
.sheet-actions .sheet-problem { margin: 0 auto 0 0; font-size: 0.82rem; color: var(--bad); }
/* The head of a sheet does not scroll, so a long answer scrolls inside its own
   box: who gave it, the way back, the card's body and the Save bar stay in
   reach on a phone with the longest answer the field allows (found in review
   at 375 wide, 2026-09-19). */
.decision-answer .answer-text {
  margin: 0; font-size: 1rem; line-height: 1.45; color: var(--ink); white-space: pre-wrap;
  max-height: min(11rem, 26vh); overflow-y: auto; overscroll-behavior: contain; padding-right: 0.25rem;
}
.decision-answer .answer-text:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.decision-answer .answer-input { max-height: 32vh; }
/* And the head itself never takes more than half the sheet, whatever it holds. */
.sheet-card .sheet-head { max-height: 56vh; overflow-y: auto; overscroll-behavior: contain; }
.decision-answer .answer-text.answer-missing { font-style: italic; }
.decision-answer .answer-by { margin: 0; font-size: 0.8rem; color: var(--ink-soft); }
.decision-answer .answer-reopen { justify-self: start; }
.note-not-answer {
  margin: 0.5rem 0 0; padding: 0.5rem 0.65rem; font-size: 0.85rem; line-height: 1.4;
  background: var(--accent-soft); border-left: 3px solid var(--accent); border-radius: 4px;
}

/* Risk flagging (spec §6). */
.risk-block {
  border: 1px solid var(--line); border-left: 4px solid var(--lp-risk);
  border-radius: 0 9px 9px 0; padding: 0.6rem 0.8rem; margin: 0.5rem 0 0.6rem;
  background: var(--bad-soft);
}
.risk-block.risk-clear { border-left-color: var(--line); background: var(--surface-2); }
details.risk-block > summary {
  cursor: pointer; min-height: 2.75rem; display: flex; align-items: center; margin-bottom: 0;
}
details.risk-block > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.risk-line { margin: 0 0 0.5rem; font-size: 0.82rem; color: var(--bad); font-weight: 600; }
/* On a board card the risk reads in two lines, like the note; the sheet keeps it whole. */
.card .card-risk { margin: 0.3rem 0 0; font-size: 0.78rem; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.risk-note { margin: 0 0 0.4rem; font-size: 0.76rem; color: var(--ink-soft); }
.risk-error { margin: 0.35rem 0 0; font-size: 0.78rem; color: var(--bad); font-weight: 600; }
.risk-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: 0.5rem; }
.risk-actions > .btn { flex: 1 1 9rem; }

/* Exemplar size picker (spec §4). */
.size-picker { display: grid; gap: 0.35rem; }
.size-option {
  display: flex; align-items: center; gap: 0.6rem; width: 100%; text-align: left;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  border-radius: 8px; padding: 0.4rem 0.6rem; cursor: pointer; min-height: 2.75rem;
}
.size-option.current { border-color: var(--accent); background: var(--accent-soft); }
.size-option:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.size-option-label { font-weight: 800; font-size: 0.84rem; width: 1.8rem; flex: none; }
.size-option-exemplar { font-size: 0.74rem; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Engineering detail + activity feed. */
.eng-detail { margin: 0.4rem 0 0.6rem; background: var(--surface-2); border-radius: 8px; padding: 0.5rem 0.7rem; }
.eng-detail summary { cursor: pointer; font-weight: 700; font-size: 0.8rem; color: var(--ink-soft); padding: 0.4rem 0; min-height: 2.75rem; display: flex; align-items: center; }
.eng-meta { margin: 0.2rem 0 0.4rem; font-size: 0.72rem; color: var(--muted); }
/* Legacy "Sources: …" tails folded out of the business face (feedback #5). */
.eng-sources { margin: 0.2rem 0 0.5rem; font-size: 0.76rem; color: var(--ink-soft); overflow-wrap: anywhere; }
.eng-detail textarea { margin: 0.2rem 0 0.5rem; }

/* Checkbox rows (epic sheet: engineering flag; release sheet: pin as current). */
.check-row { display: flex; align-items: center; gap: 0.5rem; font-size: 0.84rem; color: var(--ink); cursor: pointer; min-height: 2.75rem; }
.check-row input[type="checkbox"] { width: 1.1rem; height: 1.1rem; min-height: 0; flex: none; accent-color: var(--accent); }

/* Acceptance criteria on the card sheet (Samuel, 2026-09-06: "I think you're
   missing margins here"). The block had no rule of its own at all, so a
   three-line criterion ran edge to edge and the tick floated in the middle of
   it. Three things fix it: the block keeps its own gutter, a criterion aligns
   its box to the FIRST line rather than to the middle of however many lines it
   wraps to, and the add row gets air above it. */
.acceptance-block { display: grid; gap: 0.55rem; min-width: 0; }
.acceptance-block > .sheet-label { margin-bottom: 0; }
.criteria-list { display: grid; gap: 0.15rem; min-width: 0; }

.criterion-row {
  align-items: start; gap: 0.6rem; min-height: 0;
  padding: 0.45rem 0.15rem; border-radius: 8px; min-width: 0;
}
.criterion-row:hover { background: var(--surface-2); }
/* The row is the line and, when asked, the small form under it that removes
   or rewords the criterion. The label inside keeps the row's top alignment
   and gives up the touch-target height the row already provides. */
.criterion-line { display: flex; align-items: start; gap: 0.35rem; min-width: 0; }
.criterion-line .check-row { flex: 1 1 auto; align-items: start; gap: 0.6rem; min-height: 0; min-width: 0; }
.criterion-tool {
  flex: none; border: 0; background: transparent; color: var(--muted); cursor: pointer;
  font: inherit; font-size: 0.85rem; line-height: 1.45; padding: 0 0.3rem; border-radius: 6px;
  opacity: 0.55;
}
.criterion-row:hover .criterion-tool, .criterion-tool:focus-visible { opacity: 1; }
.criterion-tool:hover, .criterion-tool:focus-visible { color: var(--ink); background: var(--surface); }
@media (pointer: coarse) { .criterion-tool { opacity: 1; min-width: 2.75rem; min-height: 2.75rem; } }
.criterion-editor:empty { display: none; }
.criterion-editor { display: grid; gap: 0.35rem; margin: 0.4rem 0 0.2rem 1.7rem; }
.criterion-editor .form-row { gap: 0.4rem; align-items: stretch; }
.criterion-editor input { flex: 1 1 12rem; min-width: 0; }
.criterion-editor-note { margin: 0; font-size: 0.78rem; color: var(--ink-soft); }
/* 1.1rem box against a 1.45 line-height on 0.84rem text: half the difference
   puts the tick on the middle of the first line rather than the top of it. */
.criterion-row input[type="checkbox"] { margin-top: 0.11rem; }
.criterion-text { line-height: 1.45; min-width: 0; overflow-wrap: anywhere; }

/* Who stands behind a tick (card no-card-is-done-until-someone-who-did-not-build-it-verified-it):
   one grey tick for the builder's own claim, two blue ticks once somebody else verified it. */
.criterion-mark { flex: 0 0 auto; font: inherit; font-size: 0.8rem; letter-spacing: -0.2em; line-height: 1.45; padding: 0 0.2em 0 0; background: none; border: 0; cursor: pointer; }
.criterion-who { margin: 0.1rem 0 0.3rem 1.6rem; font-size: 0.8rem; color: var(--muted); }
.criterion-mark.is-claimed { color: var(--muted); }
.criterion-mark.is-verified { color: var(--accent); font-weight: 700; }
/* A person who did not build the card vouches for a line its builder ticked (card a-person-can-verify-a-line-the-builder-claimed). */
.criterion-verify { flex: 0 0 auto; font: inherit; font-size: 0.78rem; font-weight: 600; line-height: 1.3; padding: 0.1em 0.6em; margin-left: 0.25em; color: var(--accent); background: none; border: 1px solid var(--accent); border-radius: 999px; cursor: pointer; }
.criterion-verify:hover, .criterion-verify:focus-visible { background: var(--accent); color: var(--surface); }
@media (pointer: coarse) { .criterion-verify { padding: 0.35em 0.9em; } }

.criteria-add { margin-top: 0.15rem; gap: 0.5rem; align-items: stretch; }
.criteria-add input { flex: 1 1 auto; min-width: 0; }
.criteria-add .btn { flex: 0 0 auto; }

/* The backlog's chip rows, folded (Samuel, 2026-09-06: "they occupy a lot of
   space and deliver very little value... offer these options but take them out
   of the way"). Four rows of chips were on screen permanently for a reader who
   usually wanted none of them. Closed this costs one control; it opens itself
   when a filter is on, so a folded row never narrows the list in secret. */
/* Filters at one end, the view toggle at the other, on one line. The fold takes
   the slack, so when it opens the chips fill the width beside the toggle rather
   than pushing it onto a second line. */
.backlog-elsewhere { margin: 0.5rem 0 0.75rem; padding: 0.5rem 0.75rem; border: 1px dashed var(--line); border-radius: 8px; }
.backlog-elsewhere-title { margin: 0 0 0.4rem; font-size: 0.78rem; font-weight: 600; color: var(--muted); }
.backlog-elsewhere-list { display: grid; gap: 0.4rem; }
.backlog-elsewhere-row { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.backlog-elsewhere-wait { font-size: 0.78rem; color: var(--ink-soft); }
.backlog-controls {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 0.5rem; margin: 0 0 0.6rem;
}
/* Add a card is a button on the row, not a band above it (Samuel's screenshot,
   2026-09-26). Its form opens under the button and over the list, so the row
   keeps its shape while somebody types. */
.backlog-controls > .addcard { position: relative; flex: 0 0 auto; margin: 0; padding: 0; background: none; border-radius: 8px; }
.backlog-controls > .addcard > summary {
  min-height: 1.85rem; height: 1.85rem; padding: 0 0.6rem; border: 1px solid var(--line);
  border-radius: 8px; background: var(--accent-soft); white-space: nowrap; font-size: 0.85rem;
}
.backlog-controls > .addcard[open] > .addcard-form {
  position: absolute; top: calc(100% + 0.4rem); left: 0; z-index: 6;
  width: min(38rem, 92vw); padding: 0.8rem 1rem; margin: 0;
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow);
}
.backlog-controls > .search-count, .backlog-controls > .backlog-person { flex: 0 0 auto; }
/* The row's controls share one height, as the map's toolbar does. */
.backlog-controls > .search-field, .backlog-controls > .backlog-person, .backlog-controls .btn, .backlog-controls > .addcard > summary {
  box-sizing: border-box; height: 1.85rem; min-height: 1.85rem; padding-block: 0; display: inline-flex; align-items: center;
}
.board-toolbar > .board-find > .search-field, .board-toolbar > .btn {
  box-sizing: border-box; height: 1.85rem; min-height: 1.85rem; padding-block: 0; display: inline-flex; align-items: center;
}
@media (max-width: 720px) {
  /* A phone wraps the row rather than squeezing seven controls into one line. */
  .backlog-controls { flex-wrap: wrap; }
}
/* The fold takes the slack and never less than its own button: allowed to
   shrink below it, the button ran under the view switch (Victor's QA report,
   2026-10-23). */
.backlog-controls > .backlog-filters { flex: 1 1 auto; min-width: max-content; }
.backlog-controls > .board-toolbar { flex: 0 0 auto; margin: 0; }
.backlog-filters { margin: 0; }
.backlog-filters > summary {
  list-style: none; cursor: pointer; display: inline-flex; align-items: center;
  width: max-content;
}
.backlog-filters > summary::-webkit-details-marker { display: none; }
.backlog-filters > summary::after { content: " ▸"; opacity: 0.6; }
.backlog-filters[open] > summary::after { content: " ▾"; }
/* The open chips, under the whole row and across its width; each chip keeps
   its words on one line, and a group wraps chip by chip. */
.backlog-filter-panel { margin: 0 0 0.8rem; gap: 0.35rem; }
.backlog-filter-panel .chips { gap: 0.3rem; }
.backlog-filter-panel .chip { white-space: nowrap; }

.feed { display: grid; gap: 0.15rem; max-height: 14rem; overflow-y: auto; }
.feed-row { margin: 0; font-size: 0.76rem; color: var(--ink-soft); }
.feed-when { color: var(--muted); }
.feed-actor { color: var(--muted); }
.feed-detail { color: var(--ink-soft); }

/* Policies sheet. */
.policy-block { margin: 0.5rem 0; }
.policy-block h3 { margin: 0 0 0.2rem; font-size: 0.9rem; }
.policy-list { margin: 0.2rem 0 0.5rem; padding-left: 1.2rem; font-size: 0.82rem; color: var(--ink-soft); }

/* Timeline sheet (scatter drill-down — the touch path). It reads the same
   model as the hover card, so the two never disagree about a duration. */
.timeline { display: grid; gap: 0.2rem; margin-top: 0.4rem; }
.timeline-row { display: flex; justify-content: space-between; gap: 0.6rem; margin: 0; font-size: 0.84rem; border-top: 1px solid var(--line); padding: 0.4rem 0; }
.timeline-state { font-weight: 600; }
.timeline-detail { color: var(--muted); }
.timeline-total { display: flex; justify-content: space-between; gap: 0.6rem; margin: 0 0 0.2rem; font-size: 0.8rem; color: var(--muted); }
.timeline-total strong { color: var(--good); font-size: 0.9rem; }
/* Waiting is time parked on a person — management orange, as on the card. */
.timeline-waiting .timeline-state { color: var(--warn); }
.timeline-waiting-total { margin: 0.5rem 0 0; font-size: 0.82rem; font-weight: 700; color: var(--warn); }

/* What waits on the signed-in person (card a-person-is-told-where-they-are-
   that-a-decision-waits-on-them): the first thing under the header, in the
   decisions' warm colour, each entry a button that opens what it names. */
/* Who a wait is on, picked from the flow's people, and what is asked of them
   (card a-person-is-told-where-they-are-that-a-decision-waits-on-them). */
.waits-on-fields { display: grid; gap: 0.3rem; }
.waits-on-label { font-size: 0.78rem; font-weight: 600; color: var(--muted); }
.waits-on-person, .waits-on-ask, .waits-on-takeover { width: 100%; min-height: 2.25rem; font: inherit; }
.waits-on-takeover-field { display: grid; gap: 0.3rem; margin-top: 0.3rem; }
.decision-takeover { display: grid; gap: 0.4rem; justify-items: start; }
.decision-takeover .waits-on-fields { width: 100%; }
.decision-takeover-actions { display: flex; gap: 0.5rem; }
.waits-on-ask:disabled { opacity: 0.6; }
.waits-on-named { margin: 0.35rem 0 0; font-size: 0.82rem; overflow-wrap: anywhere; }
.waits-on-named.nobody { color: var(--warn); }
.waits-on-person-link { font-weight: 600; text-underline-offset: 2px; }

/* The people of a flow: where a wait on a picked person links to. */
.flow-people { list-style: none; margin: 0.8rem 0 0; padding: 0; display: grid; gap: 0.4rem; }
.flow-person {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25rem 0.6rem;
  padding: 0.55rem 0.75rem; border: 1px solid var(--line); border-radius: 8px;
}
.flow-person.is-focus { border-color: var(--warn); border-left-width: 4px; }
.flow-person-name { font-weight: 600; }
.flow-person-role { font-size: 0.82rem; color: var(--muted); }
.flow-person-waits { flex-basis: 100%; margin: 0.1rem 0 0; font-size: 0.82rem; overflow-wrap: anywhere; }

/* What waits on you, everywhere it shows (card a-card-waiting-on-you-says-
   what-you-can-do-and-lets-you-do-it): the act as a chip, the same row in
   every board's inbox, and the ask first on a card.
   Every colour pair is a token pair that reads in both themes. */
.wait-act-chip {
  display: inline-flex; align-items: center; gap: 0.3rem; padding: 0.12rem 0.55rem; border-radius: 999px;
  font-size: 0.74rem; font-weight: 600; line-height: 1.4; white-space: nowrap;
  background: var(--surface-2); color: var(--ink-soft);
}
.wait-act-chip::before { content: ""; width: 0.45rem; height: 0.45rem; border-radius: 50%; background: currentColor; }
.wait-act-chip[data-act="close"], .wait-act-chip[data-act="decision"] { background: var(--accent-soft); color: var(--accent); }
.wait-act-chip[data-act="outside"] { background: var(--warn-soft); color: var(--warn); }
.wait-act-chip[data-act="yes"] { background: var(--good-soft); color: var(--good); }

/* The ask, at the top of the card's head. */
.wait-ask {
  display: grid; gap: 0.55rem; margin: 0 0 0.9rem; padding: 0.85rem 1rem 0.9rem;
  border-radius: 10px; border: 1px solid var(--line); border-left: 4px solid var(--warn);
  background: var(--bg);
}
.wait-ask-top { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.wait-ask-label { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--warn); }
.wait-ask-sentence { margin: 0; font-size: 1.1rem; font-weight: 600; line-height: 1.35; color: var(--ink); overflow-wrap: anywhere; }
.wait-ask-sentence::first-letter { text-transform: uppercase; }
.wait-ask-command {
  display: flex; align-items: center; gap: 0.6rem; padding: 0.4rem 0.4rem 0.4rem 0.75rem;
  border: 1px solid var(--line); border-radius: 8px; background: var(--surface);
}
.wait-ask-command-text { flex: 1; min-width: 0; font-size: 0.85rem; overflow-wrap: anywhere; }
.wait-ask-copy { flex: none; min-height: 2.25rem; }
.wait-ask-foot { display: grid; min-width: 0; }
.wait-ask-why { min-height: 2.25rem; padding-left: 0; padding-right: 0.4rem; margin-right: auto; }
/* A long ask shows its first two lines; its control reads it all (Samuel, 2026-10-30). */
.wait-ask-clamped { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
.wait-ask-more { justify-self: start; min-height: 2rem; padding-left: 0; margin-top: -0.3rem; }
.wait-ask-more[hidden] { display: none; }
/* Why it waits, said in place (card what-waits-on-you-is-written-to-you-with-a-recommendation). */
.wait-ask-unwritten { font-weight: 500; color: var(--ink-2, var(--ink)); }
.wait-ask-explain { display: grid; gap: 0.35rem; padding: 0.65rem 0.8rem; border-left: 3px solid var(--accent); background: var(--surface); border-radius: 0 8px 8px 0; }
.wait-ask-explain[hidden] { display: none; }
.wait-ask-explain-line { margin: 0; font-size: 0.9rem; line-height: 1.45; color: var(--ink); overflow-wrap: anywhere; }
.wait-ask-notes { justify-self: start; min-height: 2.25rem; padding-left: 0; }
.wait-ask-verdict { display: grid; gap: 0.2rem; }
.wait-ask-verdict-note, .wait-ask-verdict-count { margin: 0; font-size: 0.88rem; line-height: 1.4; color: var(--ink); overflow-wrap: anywhere; }
.wait-ask-verdict-count { color: var(--muted, var(--ink)); }
/* A long review folds to its first lines, and read whole it scrolls in its own
   area, so the block never takes the whole screen (card a-long-review-folds-
   and-close-opens-its-box-with-the-suggested-line). */
.wait-ask-verdict-body { padding: 0; min-width: 0; overflow-wrap: anywhere; }
.wait-ask-verdict-body[data-folded="true"] {
  max-height: 4.6rem; overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, #000 55%, transparent);
  mask-image: linear-gradient(to bottom, #000 55%, transparent);
}
.wait-ask-verdict-body[data-folded="false"] { max-height: 40vh; overflow-y: auto; }
.wait-ask-verdict-body > :first-child { margin-top: 0; }
.wait-ask-verdict-unfold { justify-self: start; min-height: 2.25rem; padding-left: 0; }
.wait-actions-form .closing-line { min-height: 4.2rem; }
.wait-actions-question { margin: 0; font-size: 0.92rem; font-weight: 600; line-height: 1.4; color: var(--ink); overflow-wrap: anywhere; }

/* The suggested reply is content, a quiet quote under the ask, never a
   button's label (Samuel, 2026-10-30); pressed, it opens to edit. */
.wait-suggested { display: grid; gap: 0.25rem; min-width: 0; }
.wait-suggested-label { font-size: 0.72rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted, var(--ink)); }
.wait-suggested-text {
  display: block; width: 100%; margin: 0; padding: 0.5rem 0.75rem; font: inherit; font-size: 0.9rem; line-height: 1.45;
  text-align: left; color: var(--ink); background: var(--surface-2, var(--surface)); border: 0; border-left: 3px solid var(--line);
  border-radius: 0 8px 8px 0; white-space: pre-wrap; overflow-wrap: anywhere;
}
button.wait-suggested-text { cursor: text; }
button.wait-suggested-text:hover { border-left-color: var(--accent); }
button.wait-suggested-text:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* The act's controls: one column, the buttons short and fixed at the bottom
   right, one primary per row, the primary last. */
.wait-actions { display: grid; gap: 0.5rem; min-width: 0; }
.wait-actions-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 0.45rem; }
.wait-actions .btn { min-height: 2.25rem; }
.wait-actions-open[aria-expanded="true"]:not(.btn-primary) { border-color: var(--accent); color: var(--accent); }
.wait-actions-form { display: grid; gap: 0.45rem; }
.wait-actions-text {
  width: 100%; font: inherit; font-size: 0.9rem; padding: 0.55rem 0.65rem; border-radius: 8px;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink); resize: vertical;
}
.wait-actions-text:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
.wait-actions-said { margin: 0; font-size: 0.82rem; color: var(--bad); }
.wait-actions-said:empty { display: none; }

/* One wait as a row, in one column: the chip, the title, what it asks, the
   suggested reply, then the buttons at the bottom right. Nothing sits beside
   the ask competing for its width (Samuel, 2026-10-30). */
.waits-inbox-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }
.waits-inbox-row {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.55rem;
  padding: 0.75rem 0.9rem; border: 1px solid var(--line); border-radius: 10px; background: var(--surface);
}
.waits-inbox-row.stale { border-left: 4px solid var(--bad); }
.waits-inbox-main { display: grid; gap: 0.2rem; min-width: 0; }
.waits-inbox-line { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; }
.waits-inbox-stale {
  font-size: 0.72rem; font-weight: 700; padding: 0.1rem 0.5rem; border-radius: 999px;
  background: var(--bad-soft); color: var(--bad);
}
.waits-inbox-title {
  justify-self: start; font: inherit; font-size: 0.98rem; font-weight: 600; line-height: 1.35; text-align: left;
  background: none; border: 0; padding: 0; color: var(--ink); text-decoration: none; cursor: pointer; overflow-wrap: anywhere;
}
.waits-inbox-title:hover { text-decoration: underline; text-underline-offset: 3px; }
.waits-inbox-title:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.waits-inbox-asks { margin: 0; font-size: 0.86rem; line-height: 1.45; color: var(--ink-soft); overflow-wrap: anywhere; }
.waits-inbox-asks::first-letter { text-transform: uppercase; }
.waits-inbox-side { display: grid; min-width: 0; }
.waits-inbox-elsewhere { display: grid; gap: 0.5rem; min-width: 0; }
.waits-inbox-go, .waits-inbox-answer { min-height: 2.25rem; text-decoration: none; display: inline-flex; align-items: center; }

/* The count beside a board's name and in the strip's title: a soft pill. */
.waits-inbox-mark {
  display: inline-grid; place-items: center; min-width: 1.45rem; height: 1.45rem; padding: 0 0.4rem; border-radius: 999px;
  font-size: 0.76rem; font-weight: 700; font-variant-numeric: tabular-nums; background: var(--warn-soft); color: var(--warn);
}
.waits-inbox-mark.none { background: var(--surface-2); color: var(--muted); }

/* The inbox page. */
.waits-inbox { display: grid; gap: 1.4rem; max-width: 56rem; }
.waits-inbox-header { display: grid; gap: 0.25rem; }
.waits-inbox-heading { margin: 0; font-size: 1.35rem; }
.waits-inbox-lead { margin: 0; color: var(--muted); }
.waits-inbox-board { display: grid; gap: 0.6rem; }
.waits-inbox-board-name { margin: 0; display: flex; align-items: center; gap: 0.5rem; font-size: 0.95rem; }
.waits-inbox-board-name a { color: inherit; text-decoration: none; }
.waits-inbox-board-name a:hover { text-decoration: underline; text-underline-offset: 3px; }
.waits-inbox-here { font-size: 0.78rem; font-weight: 400; color: var(--muted); }
.waits-inbox-empty { margin: 0; font-size: 0.85rem; color: var(--muted); }

/* The sidebar's door: the first row, the count a pill that reads in both themes. */
.ws-waits { margin-bottom: 0.35rem; }
.ws-count-waits {
  display: inline-grid; place-items: center; min-width: 1.45rem; height: 1.3rem; padding: 0 0.4rem; border-radius: 999px;
  background: var(--warn-soft); color: var(--warn); font-weight: 700;
}

/* While something waits, a small light travels from side to side under the
   menu item, like the scanner of the car in Knight Rider (card what-waits-on-
   you-lives-in-the-menu-with-a-small-moving-light, wait-light.js). It is the
   site's moving light made small: a bright core in the engineering blue's
   halo (site-score-baton.js), in a slot as wide as the item and three pixels
   high. Only a transform moves, so it costs the page nothing. A person who
   asked for less motion sees it still, resting under the count, where the
   site's light ends in the mark. */
.ws-waits .ws-link, .frame-door-waits { position: relative; }
.wait-light { position: absolute; left: 0.6rem; right: 0.45rem; bottom: 1px; height: 3px; pointer-events: none; }
.wait-light::before {
  content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 28%; border-radius: 99px;
  background: radial-gradient(closest-side, var(--wait-light-core), var(--lp-engineering) 45%, transparent);
  animation: wait-light-sweep 2s ease-in-out infinite alternate;
}
/* On the phone's bar, which stands on the brand's dark ground in both themes, it is the site's own pair. */
.frame-door-waits .wait-light { left: 0.55rem; right: 0.55rem; bottom: 0.3rem; --wait-light-core: #f3f6f9; --lp-engineering: #42b0e4; }
@keyframes wait-light-sweep {
  from { transform: translateX(0); }
  to { transform: translateX(257%); } /* the slot's far end: (100% - 28%) of it, in the light's own widths */
}
@media (prefers-reduced-motion: reduce) {
  .wait-light::before { animation: none; left: auto; right: 0; width: 1.45rem; }
  .frame-door-waits .wait-light::before { right: auto; left: 50%; margin-left: -0.6rem; width: 1.2rem; }
}

/* ── Misc ───────────────────────────────────────────────────────────────── */
.banner {
  background: var(--bad-soft); color: var(--bad); font-weight: 600; font-size: 0.85rem;
  border-radius: 8px; padding: 0.6rem 0.9rem; margin: 0.6rem 0;
}
/* A refused change is read where the person is looking, which is often an open
   card: it floats above the sheet and its backdrop, and stays until dismissed
   (public/js/banner.js). */
.banner-write {
  position: fixed; top: 0.6rem; left: 50%; transform: translateX(-50%); z-index: 60; margin: 0;
  width: min(46rem, calc(100vw - 1.5rem));
  display: flex; align-items: flex-start; gap: 0.75rem;
  border: 1px solid var(--bad); box-shadow: 0 8px 28px rgba(0, 0, 0, 0.3); line-height: 1.4;
}
.banner-write .banner-text { flex: 1; min-width: 0; }
/* A fact told once, such as the frame having switched to another tenant: it
   floats where a refusal would, in the accent's calm colours, until dismissed. */
.banner-note {
  position: fixed; top: 0.6rem; left: 50%; transform: translateX(-50%); z-index: 60; margin: 0;
  width: min(46rem, calc(100vw - 1.5rem));
  display: flex; align-items: center; gap: 0.75rem;
  background: var(--accent-soft); color: var(--ink); border: 1px solid var(--accent); box-shadow: 0 8px 28px rgba(0, 0, 0, 0.2); line-height: 1.4;
}
.banner-note .banner-text { flex: 1; min-width: 0; }
.banner-note .banner-dismiss { color: var(--ink); border-color: var(--accent); }
.banner-dismiss {
  flex: none; font: inherit; font-weight: 700; color: var(--bad); background: transparent;
  border: 1px solid var(--bad); border-radius: 6px; padding: 0.2rem 0.6rem; min-height: 2rem; cursor: pointer;
}
.banner-dismiss:focus-visible { outline: 2px solid var(--bad); outline-offset: 2px; }
.empty { color: var(--muted); font-size: 0.86rem; padding: 1rem 0.2rem; text-align: center; }
/* Empty states that teach (public/js/empty-states.js): a title, a body and
   the way out, wherever a list has nothing to show. */
.empty-state {
  display: grid; gap: 0.35rem; justify-items: center;
  color: var(--muted); font-size: 0.86rem; padding: 1rem 0.6rem; text-align: center;
}
.empty-title { margin: 0; font-weight: 700; color: var(--ink); }
.empty-body { margin: 0; max-width: 44ch; }
.empty-actions { display: flex; gap: 0.4rem; flex-wrap: wrap; justify-content: center; margin-top: 0.3rem; }
.col-cards .empty-state { padding: 0.6rem 0.3rem; font-size: 0.78rem; }
.release-row .empty-state { flex: 1 1 auto; justify-items: start; text-align: left; padding: 0.2rem 0; }
.mapbox > .empty-state { padding: 1.2rem 0.8rem; }
.tnum { font-variant-numeric: tabular-nums; }

/* ── Legend swatches ──────────────────────────────────────────────────────
   The map card is a full-width title card (.sq), so every legend demo must
   out-specify it: `.sq.lg-*` beats `.sq` regardless of source order. */
.sq.lg-sq { width: 16px; height: 16px; min-height: 0; padding: 0; flex: none; }
.legend-col .sq { width: 46px; flex: none; padding: 0; }
.legend-col .sq.lg-sq { width: 16px; }

/* Size demos are proportional miniatures, not real cards: a legend that is
   taller than the map it explains pushes the map below the fold. */
.legend-col.legend-sizes { flex-direction: row; align-items: flex-end; gap: 0.5rem; }
.legend-col.legend-sizes b { width: 100%; }
.lg-size { flex-direction: column; align-items: center; gap: 0.15rem; font-size: 0.66rem; }
.lg-size .sq { width: 22px; padding: 0; }
/* Miniatures of the real ladder, in proportion: 38/50/66/84/102 scaled so XL
   reads at 31px. A legend whose steps do not match the map's steps teaches the
   wrong encoding. */
.lg-size .sq-xs { height: 12px; }
.lg-size .sq-s { height: 15px; }
.lg-size .sq-m { height: 20px; }
.lg-size .sq-l { height: 26px; }
.lg-size .sq-xl { height: 31px; }

/* ── No dead-end selectors: inline creation (CRUD completeness spec) ───────
   Every picker of variable data ends in `+ New <thing>…`, and choosing it
   opens a small form IN PLACE — under the select, in the map's own region,
   inside the deadline strip. Nothing navigates, so nothing half-typed is
   lost. Tokens only, so both themes come for free. */
.selector-field { display: grid; gap: 0.4rem; min-width: 0; }
.selector-field select { width: 100%; }

.inline-create {
  display: grid; gap: 0.5rem;
  background: var(--surface-2); border: 1px solid var(--line);
  border-left: 3px solid var(--accent); border-radius: 8px;
  padding: 0.7rem 0.8rem;
}
.inline-title { font-size: 0.78rem; font-weight: 800; color: var(--ink); letter-spacing: 0.01em; }
.inline-hint { margin: -0.2rem 0 0; font-size: 0.74rem; color: var(--muted); }
.inline-field { display: grid; gap: 0.2rem; min-width: 0; }
.inline-help { margin: 0; font-size: 0.78rem; color: var(--muted); }
.inline-field-label {
  font-size: 0.7rem; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.05em;
}
.inline-create input, .inline-create textarea, .inline-create select {
  font: inherit; font-size: 0.86rem; color: var(--ink);
  background: var(--field); border: 1px solid var(--field-line);
  border-radius: 7px; padding: 0.5rem 0.7rem; width: 100%; min-height: 2.75rem;
}
.inline-create textarea { min-height: 3.4rem; resize: vertical; }
.inline-create .check-row { min-height: 2.75rem; font-size: 0.8rem; }
.inline-actions { display: flex; gap: 0.5rem; justify-content: flex-end; flex-wrap: wrap; }
.inline-actions .btn { min-height: 2.75rem; }
.inline-error {
  margin: 0; display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap;
  background: var(--bad-soft); color: var(--bad); border-radius: 7px;
  padding: 0.45rem 0.6rem; font-size: 0.78rem; font-weight: 600;
}
.inline-error .btn { min-height: 2.25rem; padding: 0.25rem 0.7rem; }

/* Deadline strip: chips are buttons now (edit in place), with `+ New` last. */
.deadlines { display: block; overflow: visible; }
.deadline-row {
  display: flex; gap: 0.5rem; overflow-x: auto; padding-bottom: 0.2rem;
  -webkit-overflow-scrolling: touch;
}
.dl { min-height: 2.75rem; }
.dl-btn, .dl-add {
  cursor: pointer; font: inherit; text-align: left; color: var(--ink);
  display: flex; flex-direction: column; gap: 0.1rem;
}
.dl-btn:focus-visible, .dl-add:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.dl-add { border-left-color: var(--accent); color: var(--accent); justify-content: center; }
.dl-add .dl-label { color: var(--accent); }
#deadline-strip .inline-create { margin: 0.5rem 0 0.2rem; max-width: 34rem; }

/* The map's inline form sits above the backbone: creating a release must not
   scroll the map out from under the person doing it. */
.map-inline { margin: 0 0 0.7rem; }
.map-inline .inline-create { max-width: 34rem; }

/* Backbone add-column + rail add-row. */
.h-add {
  background: var(--surface-2); color: var(--accent); font-weight: 800; cursor: pointer;
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.h-feature.h-add { background: var(--surface-2); }
.h-epic.h-add:focus-visible { outline: 2px solid var(--ink); outline-offset: -3px; }
.band-spacer { background: var(--bg); }
.r-add {
  color: var(--accent); justify-content: center; font-weight: 700;
  border-left-color: var(--accent);
}
.r-add .r-name { color: var(--accent); }

/* `+` in an empty cell → a card in exactly that epic × release. */
.cell-add {
  width: 100%; min-height: 2.75rem; border: 1px dashed var(--line); border-radius: 4px;
  background: transparent; color: var(--muted); font: inherit; font-size: 0.95rem;
  font-weight: 700; cursor: pointer; touch-action: manipulation;
}
.cell-add:hover, .cell-add[aria-expanded="true"] { color: var(--accent); border-color: var(--accent); }
.cell-add:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Policy editor blocks stack inside the column sheet. */
.policy-block + .policy-block { margin-top: 0.8rem; }

/* A picker sharing a row with another control takes the whole row while its
   inline form is open — a create form squeezed into half a phone width is a
   dead end by another means. */
.form-row > .selector-field:has(.inline-create) { flex-basis: 100%; }

/* ── Metrics §5: next-up queue ─────────────────────────────────────────── */
.nextup-list { display: grid; gap: 0.3rem; margin-top: 0.4rem; }
.nextup-row {
  display: flex; gap: 0.6rem; align-items: baseline; text-align: left;
  font: inherit; color: var(--ink); background: var(--surface-2);
  border: 1px solid var(--line); border-radius: 8px; padding: 0.45rem 0.6rem;
  cursor: pointer; width: 100%;
}
.nextup-row:hover { border-color: var(--accent); }
.nextup-row:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }
.nextup-pos { color: var(--muted); font-weight: 700; font-size: 0.78rem; flex: 0 0 1.1rem; }
.nextup-body { display: grid; gap: 0.1rem; min-width: 0; }
.nextup-title { font-size: 0.84rem; font-weight: 600; }
/* Blocked by: the lock says the card cannot start; its place in the order stands. */
.nextup-lock { margin-left: 0.35rem; font-size: 0.72rem; vertical-align: middle; cursor: help; }
.nextup-blocked .nextup-title { color: var(--ink-soft); }
.nextup-meta { font-size: 0.74rem; color: var(--muted); }
.nextup-cardrow { display: flex; justify-content: space-between; gap: 0.8rem; padding: 0.12rem 0; }

/* Sequencing: the queue orders itself; rows carry rank and score. */
.seq-cell { display: flex; flex-direction: column; align-items: flex-end; gap: 0.2rem; flex: 0 0 auto; }
.seq-rank { font-size: 0.78rem; font-weight: 700; color: var(--muted); }
.seq-score { font-size: 0.72rem; font-weight: 600; color: var(--accent); background: var(--accent-soft); border-radius: 6px; padding: 0.1rem 0.4rem; }
.seq-score.seq-unscored { color: var(--muted); background: var(--surface-2); }

/* Dropping asks why and confirms (card dropping-a-card-asks-why-and-confirms). */
.drop-box { margin-top: 0.6rem; padding: 0.6rem 0.75rem; border: 1px solid var(--bad); border-radius: 8px; display: grid; gap: 0.45rem; }
.drop-reason { width: 100%; box-sizing: border-box; font: inherit; padding: 0.4rem 0.5rem; }
.drop-actions { display: flex; gap: 0.5rem; justify-content: flex-end; }
/* Closing a card: the proof in front of the person, and one line of theirs (card a-person-closes-a-card-with-the-proof-in-front-of-them). */
.close-box { margin-top: 0.6rem; padding: 0.6rem 0.75rem; border: 1px solid var(--accent); border-radius: 8px; display: grid; gap: 0.45rem; }
.close-verdict-head { margin: 0; font-size: 0.8rem; color: var(--muted); }
.close-verdict { padding: 0.3rem 0.5rem; border-left: 2px solid var(--accent); }
.close-criteria { margin: 0; padding-left: 1.15rem; display: grid; gap: 0.2rem; }
.close-criterion { font-size: 0.8rem; color: var(--ink-soft); line-height: 1.45; }
/* What is left before the close, said before anybody presses it (card a-person-sees-what-is-left-before-closing-not-after). */
.close-gate { margin: 0; font-size: 0.85rem; font-weight: 600; color: var(--ink); }
.close-gate.is-blocked { color: var(--warn); background: var(--warn-soft); border-radius: 6px; padding: 0.35rem 0.5rem; }
.close-criterion.is-open { color: var(--ink); font-weight: 600; }
.close-criterion.is-open::marker { color: var(--warn); }
.close-confirm:disabled { opacity: 0.5; cursor: not-allowed; }
.closing-line { width: 100%; box-sizing: border-box; font: inherit; padding: 0.4rem 0.5rem; }
/* What was said on the card, newest first. */
.card-worklog { display: grid; gap: 0.35rem; }
.card-worklog-entry { border-bottom: 1px solid var(--line); padding-bottom: 0.3rem; }
.card-worklog-summary { cursor: pointer; display: flex; flex-wrap: wrap; gap: 0.15rem 0.6rem; align-items: baseline; }
.card-worklog-title { font-size: 0.85rem; font-weight: 600; color: var(--ink); }
.card-worklog-who { font-size: 0.75rem; color: var(--muted); }
.drop-record { margin: 0.35rem 0 0; font-size: 0.82rem; color: var(--bad); }

/* ── The product frame (card the-product-has-a-frame-around-the-flow) ───────
   A bar across the whole width that says where you are (tenant, flow) and
   holds the person's menu; the tenant's area and the person's own are screens
   of their own under it. A preview behind a switch until sign-in lands: the
   body wears data-frame="on", and only then does the page take its full width
   and the sticky tab bar move under the bar. */
:root { --frame-bar: 3rem; }

/* The bar is locked at the top of the window (Samuel, 2026-09-29: "it has to
   stay locked in position"); the page starts under it. */
body[data-frame="on"] { padding: var(--frame-bar) 0 4.5rem; }
body[data-frame="on"] .wrap { max-width: none; padding: 0 1.25rem; }
/* The bar names the flow; a second heading under it would say it twice. */
body[data-frame="on"] .head-row { display: none; }
body[data-frame="on"] .app-header { padding-top: 0.75rem; }
body[data-frame="on"] .tabs { top: calc(var(--frame-bar) + 0.4rem); }

.frame-bar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 7;
  height: var(--frame-bar);
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0 1rem 0 0.75rem;
  background: var(--lp-ground); color: #f3f6f9;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06), 0 2px 8px rgba(0, 0, 0, 0.18);
}
.frame-mark {
  display: inline-flex; align-items: center; gap: 0.5rem; flex: none;
  color: inherit; text-decoration: none; font-weight: 800; letter-spacing: -0.01em; font-size: 1rem;
}
.frame-mark-glyph { width: 1.25rem; height: 1.25rem; display: block; flex: none; }
/* The name beside the mark, set the way the brand sets it (src/domain/brand.ts). */
.frame-mark-name { font-weight: var(--brand-word-weight); letter-spacing: var(--brand-word-tracking); text-transform: var(--brand-word-transform); font-size: 0.86em; }
.frame-mark:focus-visible, .frame-crumb:focus-visible, .frame-person:focus-visible { outline: 2px solid var(--lp-engineering); outline-offset: 2px; border-radius: 8px; }

.frame-where { display: flex; align-items: center; gap: 0.35rem; min-width: 0; flex: 1; }
.frame-crumb-sep { color: rgba(243, 246, 249, 0.4); }
.frame-menu { position: relative; min-width: 0; }
.frame-menu > summary { list-style: none; }
.frame-menu > summary::-webkit-details-marker { display: none; }
.frame-crumb {
  display: inline-flex; align-items: center; gap: 0.35rem;
  padding: 0.35rem 0.6rem; border-radius: 8px; cursor: pointer;
  font-weight: 500; font-size: 0.92rem; color: inherit; min-width: 0; max-width: 18rem;
}
.frame-crumb-plain { cursor: default; }
/* A crumb that opens a menu is capped by its menu, so a long name ends in an ellipsis rather than spilling over the next one. */
.frame-where > .frame-menu { max-width: 18rem; }
.frame-where > .frame-menu > .frame-crumb { max-width: 100%; }
.frame-crumb:not(.frame-crumb-plain):hover, .frame-menu[open] > .frame-crumb { background: rgba(255, 255, 255, 0.1); }
.frame-crumb-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.frame-caret { width: 0.4rem; height: 0.4rem; border: solid currentColor; border-width: 0 1.5px 1.5px 0; transform: translateY(-2px) rotate(45deg); opacity: 0.7; flex: none; }

.frame-right { display: flex; align-items: center; gap: 0.75rem; flex: none; }
/* Where no sidebar is drawn, what waits on you and the connected tools sit on the bar, one tap each. */
.frame-door {
  position: relative; display: inline-grid; place-items: center; width: 2.75rem; height: 2.75rem; margin: 0 -0.4rem;
  border-radius: 8px; color: inherit;
}
.frame-door:hover { background: rgba(255, 255, 255, 0.1); }
.frame-door:focus-visible { outline: 2px solid var(--lp-engineering); outline-offset: 2px; }
.frame-door-count {
  position: absolute; top: 0.3rem; right: 0.2rem; min-width: 1.05rem; height: 1.05rem; padding: 0 0.25rem; border-radius: 99px;
  background: var(--lp-engineering); color: #fff; font-size: 0.68rem; font-weight: 700; line-height: 1.05rem; text-align: center;
  font-variant-numeric: tabular-nums;
}
.frame-menu-heading { font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; font-size: 0.7rem; }
.frame-person {
  display: inline-flex; align-items: center; gap: 0.3rem; padding: 0.2rem 0.4rem 0.2rem 0.2rem; border-radius: 99px; cursor: pointer; color: inherit;
}
.frame-person:hover, .frame-menu[open] > .frame-person { background: rgba(255, 255, 255, 0.1); }
.frame-avatar {
  width: 1.75rem; height: 1.75rem; border-radius: 50%; display: inline-grid; place-items: center;
  background: var(--lp-engineering); color: #fff; font-weight: 700; font-size: 0.85rem;
}

/* The menus: under their summary, on the page's own surface. */
.frame-menu-list {
  position: absolute; top: calc(100% + 0.35rem); left: 0; z-index: 8;
  list-style: none; margin: 0; padding: 0.35rem; min-width: 15rem;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 8px 28px rgba(10, 16, 22, 0.22);
}
.frame-menu-me .frame-menu-list { left: auto; right: 0; min-width: 20rem; }
/* A closed menu takes no room: Chromium still lays out a closed details' content,
   and a person with several flows had a flow menu wider than a phone pushing
   the page sideways (card a-tenant-admin-sees-its-flows-people-and-plan). */
.frame-menu:not([open]) > .frame-menu-list { display: none; }
.frame-menu-item {
  display: flex; align-items: center; justify-content: space-between; gap: 0.6rem;
  width: 100%; padding: 0.5rem 0.65rem; border-radius: 8px; border: 0; background: transparent;
  color: var(--ink); text-decoration: none; text-align: left; font: inherit; font-weight: 400; font-size: 0.9rem; cursor: pointer;
}
.frame-menu-item:hover { background: var(--surface-2); }
.frame-menu-item[aria-current="page"] { background: var(--surface-2); color: var(--ink); font-weight: 500; }
.frame-menu-item:disabled { color: var(--muted); cursor: not-allowed; }
.frame-menu-hint { font-size: 0.72rem; color: var(--muted); font-weight: 500; }
.frame-menu-note { display: block; padding: 0.3rem 0.65rem 0.45rem; font-size: 0.74rem; color: var(--muted); line-height: 1.4; }
.frame-menu-row { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; padding: 0.4rem 0.65rem; border-top: 1px solid var(--line); }
.frame-menu-row + .frame-menu-row { border-top: 0; padding-top: 0; }
.frame-menu-label { font-size: 0.84rem; color: var(--ink-soft); font-weight: 400; white-space: nowrap; }

/* The tenant and flow menus hold many entries (card the-tenant-and-flow-
   menus-scroll-sort-a-f3f06b): each scrolls inside itself, never past the
   screen's bottom edge, under a search pinned at its top. */
.frame-menu-tenant .frame-menu-list, .frame-menu-flow .frame-menu-list {
  max-height: calc(100dvh - var(--frame-bar) - 1.25rem); overflow-y: auto; overscroll-behavior: contain;
  min-width: 17rem; max-width: min(24rem, calc(100vw - 1.5rem)); padding-top: 0;
  scroll-padding-top: 3.1rem;
}
.frame-menu-search-row {
  position: sticky; top: 0; z-index: 1; margin: 0 -0.35rem 0.25rem; padding: 0.45rem 0.45rem 0.4rem;
  background: var(--surface); border-bottom: 1px solid var(--line);
}
.frame-menu-search { position: relative; display: block; }
.frame-menu-search .icon { position: absolute; left: 0.6rem; top: 50%; transform: translateY(-50%); color: var(--muted); pointer-events: none; }
/* The house field, a well set apart from the menu's surface like every field (the field rule at the top). */
.frame-menu .frame-menu-search-field { width: 100%; padding: 0.45rem 0.6rem 0.45rem 2rem; font-size: 0.9rem; }
.frame-menu-search-field::-webkit-search-cancel-button { cursor: pointer; }
.frame-menu-search:focus-within .icon { color: var(--accent); }
/* The part of a name that matched, in the name's own ink: found, not shouted. */
.frame-menu-match {
  background: color-mix(in srgb, var(--accent) 22%, transparent); color: inherit;
  border-radius: 3px; padding: 0 0.06em; font-weight: 600;
}
.frame-menu-item-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.frame-menu-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; background: var(--surface-2); }
.frame-menu-empty { display: grid; gap: 0.35rem; justify-items: start; padding: 0.55rem 0.65rem 0.6rem; font-size: 0.84rem; color: var(--muted); }
.frame-menu-empty[hidden] { display: none; }
.frame-menu-clear {
  border: 0; background: transparent; padding: 0; font: inherit; font-size: 0.84rem; font-weight: 500;
  color: var(--accent); cursor: pointer; text-decoration: underline; text-underline-offset: 2px;
}
.frame-menu-clear:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }
@media (max-width: 40rem) {
  /* On a phone the menu spans the screen under the bar, whichever crumb opened it. */
  .frame-menu-tenant .frame-menu-list, .frame-menu-flow .frame-menu-list {
    position: fixed; top: calc(var(--frame-bar) + 0.35rem); left: 0.75rem; right: 0.75rem; min-width: 0; max-width: none;
    max-height: calc(100dvh - var(--frame-bar) - 1.25rem);
  }
}
.frame-seg { display: inline-flex; gap: 0.15rem; background: var(--surface-2); border-radius: 8px; padding: 0.15rem; }
.frame-seg-btn {
  border: 0; background: transparent; color: var(--ink-soft); font: inherit; font-size: 0.78rem; font-weight: 500;
  padding: 0.25rem 0.55rem; border-radius: 6px; cursor: pointer; white-space: nowrap;
}
.frame-seg-btn[aria-pressed="true"] { background: var(--surface); color: var(--ink); box-shadow: var(--shadow); }

/* The frame's own screens: a sub-navigation and content that is narrow by
   choice (a text, a form), never because the page is capped. */
.frame-screen { display: grid; grid-template-columns: 14rem minmax(0, 1fr); gap: 2rem; padding: 1rem 0 2rem; align-items: start; }
.frame-screen-plain { grid-template-columns: minmax(0, 1fr); }
.frame-subnav { display: grid; gap: 0.15rem; position: sticky; top: calc(var(--frame-bar) + 1rem); }
.frame-subnav-head { font-size: 0.78rem; font-weight: 500; color: var(--muted); padding: 0.3rem 0.7rem 0.5rem; }
.frame-subnav-link {
  display: block; padding: 0.45rem 0.7rem; border-radius: 8px; color: var(--ink-soft); text-decoration: none; font-weight: 400; font-size: 0.9rem;
}
.frame-subnav-link:hover { background: var(--surface-2); color: var(--ink); }
.frame-subnav-link[aria-current="page"] { background: var(--surface-2); color: var(--ink); font-weight: 500; }
.frame-subnav-back { margin-top: 0.8rem; color: var(--accent); font-size: 0.84rem; }
.frame-content { max-width: 60rem; min-width: 0; }
.frame-title { margin: 0.2rem 0 0.4rem; font-size: 1.5rem; letter-spacing: -0.01em; }
.frame-subtitle { margin: 1.4rem 0 0.5rem; font-size: 1rem; }
.frame-lead { margin: 0 0 1.2rem; font-size: 0.98rem; color: var(--ink-soft); line-height: 1.55; max-width: 60ch; }
.frame-note { margin: 1rem 0 0; font-size: 0.84rem; color: var(--muted); line-height: 1.5; max-width: 60ch; padding: 0.6rem 0.8rem; border-left: 3px solid var(--line); }
.frame-empty {
  padding: 1.6rem 1.2rem; border: 1px dashed var(--line); border-radius: 12px; color: var(--muted); font-size: 0.9rem; line-height: 1.5; max-width: 60ch;
}
.frame-rows { display: grid; grid-template-columns: minmax(9rem, 14rem) minmax(0, 1fr); gap: 0.55rem 1.2rem; margin: 0; }
.frame-rows dt { font-weight: 700; font-size: 0.88rem; color: var(--ink); }
.frame-rows dd { margin: 0; font-size: 0.9rem; color: var(--ink-soft); line-height: 1.5; }
.frame-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.frame-table th, .frame-table td { text-align: left; padding: 0.6rem 0.8rem; border-bottom: 1px solid var(--line); }
.frame-table th { font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); font-weight: 700; }
.frame-table tbody tr:last-child td { border-bottom: 0; }

/* Connect your agent (card you-connect-your-agent-from-the-board-alone): the
   one address to copy, the steps per app, and the person's connections. */
.agents-address { margin: 1rem 0 0.4rem; }
.agents-address-label { display: block; font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); font-weight: 700; margin-bottom: 0.35rem; }
.agents-address-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.agents-address-value, .agents-command {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.86rem; overflow-wrap: anywhere;
  padding: 0.45rem 0.65rem; background: var(--surface); border: 1px solid var(--line); border-radius: 8px; color: var(--ink);
}
.agents-address-value { flex: 1 1 18rem; min-width: 0; }
.agents-command { display: block; margin-top: 0.35rem; }
.agents-apps { display: grid; gap: 0.2rem; }
.agents-app { padding: 0.2rem 0; }
.agents-app-name { margin: 0.8rem 0 0.3rem; font-size: 0.92rem; }
.agents-steps { margin: 0; padding-left: 1.3rem; font-size: 0.88rem; line-height: 1.55; max-width: 64ch; }
.agents-steps li { margin: 0.15rem 0; }
.agents-table td { vertical-align: top; }
.agents-connection-since { display: block; font-size: 0.76rem; color: var(--muted); margin-top: 0.15rem; }
.agents-connection-action { text-align: right; }
.agents-confirm { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 0.4rem; }
.agents-confirm-text { margin: 0; font-size: 0.82rem; max-width: 28ch; text-align: left; }
@media (max-width: 640px) {
  .agents-table thead { display: none; }
  .agents-table tr { display: grid; gap: 0.2rem; padding: 0.6rem 0.8rem; border-bottom: 1px solid var(--line); }
  .agents-table td { padding: 0; border-bottom: 0; }
  .agents-connection-action { text-align: left; }
  .agents-confirm { justify-content: flex-start; }
}

/* The tenant's own places, run by its admin (card a-tenant-admin-sees-its-
   flows-people-and-plan): the tables read like the rest of the frame, and the
   forms that create a flow or invite a person open from their own button, one
   field per line, narrow by choice. */
.tenant-message { margin: 0.6rem 0 1rem; font-size: 0.88rem; line-height: 1.5; max-width: 60ch; }
.tenant-message-error { color: var(--bad); }
.tenant-message-note { color: var(--ink-soft); }
.tenant-company-save { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.9rem; }
.tenant-company-save .tenant-message { margin: 0; }
.tenant-company-save .tenant-message-saved { color: var(--good); font-weight: 600; }
.tenant-sub { display: block; font-size: 0.78rem; color: var(--muted); overflow-wrap: anywhere; }
/* A tenant's connected tools (card a-tenant-connects-its-own-tools-and-keeps-their-secrets-in-maestro). */
.tools-place { max-width: 52rem; }
.tools-list { list-style: none; margin: 0.6rem 0 1.2rem; padding: 0; display: grid; gap: 0.5rem; }
.tools-row, .tools-write { border: 1px solid var(--line); border-radius: 10px; background: var(--surface); padding: 0.75rem 0.9rem; display: grid; gap: 0.35rem; }
.tools-row-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; }
.tools-row .tenant-actions, .tools-write .tenant-actions { justify-content: flex-start; }
.tools-line { margin: 0; font-size: 0.9rem; color: var(--ink-soft); }
.tools-hint { margin: 0; font-size: 0.86rem; line-height: 1.5; color: var(--muted); max-width: 60ch; }
.tools-chip { font-size: 0.76rem; font-weight: 600; padding: 0.1rem 0.5rem; border-radius: 999px; background: var(--band); color: var(--ink-soft); }
.tools-chip-connected { background: var(--good-soft); color: var(--good); }
.tools-chip-expired { background: var(--warn-soft); color: var(--warn); }
.tools-amount { font-weight: 700; color: var(--ink); }
.tools-write-waiting { border-color: var(--warn); }
.tools-gate { margin-top: 1rem; }
.tools-gate-line { margin: 0.4rem 0; }
.tools-key-form, .tools-gate-form { margin-top: 0.6rem; }
.tenant-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 0.4rem; }
.tenant-actions-cell { vertical-align: middle; }
.tenant-actions a.btn { text-decoration: none; display: inline-flex; align-items: center; }
.frame-table strong { overflow-wrap: anywhere; }
.tenant-confirm { font-size: 0.84rem; color: var(--ink-soft); flex: 1 1 14rem; text-align: right; }
.tenant-form { display: grid; gap: 0.8rem; max-width: 34rem; margin-top: 1.4rem; padding-top: 0.4rem; border-top: 1px solid var(--line); }
.tenant-form .frame-subtitle { margin-top: 0.8rem; }
.tenant-form .frame-note { margin: 0; }
.tenant-form > .btn { justify-self: start; }
.tenant-field { display: grid; gap: 0.3rem; }
.tenant-field-label { font-size: 0.82rem; font-weight: 600; color: var(--ink-soft); }
.tenant-input, .tenant-select { width: 100%; box-sizing: border-box; padding: 0.55rem 0.7rem; border-radius: 8px; font: inherit; font-size: 0.92rem; min-height: 2.75rem; }
.tenant-flow-choices { border: 0; margin: 0; padding: 0; display: grid; gap: 0.35rem; }
.tenant-check { display: flex; align-items: center; gap: 0.5rem; font-size: 0.9rem; color: var(--ink); min-height: 2rem; }
.tenant-check input { width: 1.1rem; height: 1.1rem; }
.tenant-hint { margin: 0; font-size: 0.84rem; color: var(--muted); line-height: 1.5; max-width: 60ch; }
.tenant-form-actions { justify-content: flex-start; }

/* Who works where (card inviting-someone-already-in-the-company-says-what-
   will-happen): the flows and the people are cards; a closed one says who or
   where in a line, an open one lists them, each a link to the other card. */
.tenant-headline { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.6rem 1rem; }
.tenant-headline .frame-title { margin-right: auto; }
.tenant-cards { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }
.tenant-card { background: var(--surface); border: 1px solid var(--line); border-radius: 10px; min-width: 0; }
.tenant-card.is-open { border-color: var(--accent); box-shadow: var(--shadow); }
.tenant-card-row { display: flex; align-items: center; gap: 0.6rem; padding-right: 0.8rem; min-width: 0; }
.tenant-card-row > .tenant-actions { flex: none; }
.tenant-card-head {
  flex: 1 1 auto; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 1rem;
  padding: 0.7rem 0.8rem; color: var(--ink); text-decoration: none; border-radius: 10px;
}
.tenant-card-head:hover { background: var(--surface-2); }
.tenant-card-head:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.tenant-card-title { flex: 1 1 12rem; min-width: 0; display: grid; gap: 0.1rem; }
.tenant-card-title strong { overflow-wrap: anywhere; }
.tenant-card-meta { display: flex; flex-wrap: wrap; gap: 0.2rem 0.9rem; font-size: 0.84rem; color: var(--ink-soft); }
.tenant-strip { display: inline-flex; align-items: center; gap: 0.5rem; font-size: 0.84rem; color: var(--ink-soft); }
.tenant-faces { display: inline-flex; }
.tenant-faces .tenant-avatar + .tenant-avatar { margin-left: -0.45rem; }
.tenant-faces .tenant-avatar { box-shadow: 0 0 0 2px var(--surface); }
.tenant-avatar {
  flex: none; width: 1.9rem; height: 1.9rem; border-radius: 50%; display: inline-grid; place-items: center;
  background: var(--accent-soft); color: var(--accent); font-weight: 700; font-size: 0.85rem;
}
.tenant-card-body { padding: 0.2rem 0.8rem 0.9rem; border-top: 1px solid var(--line); display: grid; gap: 0.6rem; }
.tenant-card-subtitle { margin: 0.6rem 0 0; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); }
.tenant-members { list-style: none; margin: 0; padding: 0; display: grid; }
.tenant-member { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.7rem; padding: 0.45rem 0; border-bottom: 1px solid var(--line); min-width: 0; }
.tenant-member:last-child { border-bottom: 0; }
.tenant-member-who { flex: 1 1 10rem; min-width: 0; display: grid; gap: 0.05rem; }
.tenant-member-name { color: var(--accent); font-weight: 600; overflow-wrap: anywhere; }
.tenant-member-act { margin-left: auto; }
.tenant-asking .tenant-confirm { flex-basis: auto; text-align: left; }
.tenant-card-actions { justify-content: flex-start; }
.tenant-card-end { margin-top: 0.4rem; }
.tenant-give { display: grid; gap: 0.6rem; max-width: 30rem; padding: 0.7rem 0.8rem; border-radius: 8px; background: var(--surface-2); }
.tenant-role-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; }
.tenant-role-now { font-size: 0.92rem; color: var(--ink); }
.tenant-card .tenant-form { margin-top: 0.4rem; padding: 0.7rem 0.8rem 0.8rem; border-top: 0; border-radius: 8px; background: var(--surface-2); }
.tenant-card .tenant-form .frame-subtitle { margin-top: 0.2rem; }

/* The invite form names each address before anything is sent, and offers the company's people as they are typed. */
.tenant-suggestions { list-style: none; margin: -0.3rem 0 0; padding: 0.3rem; display: grid; gap: 0.1rem; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); }
.tenant-suggestion {
  width: 100%; display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 0.6rem; align-items: center; text-align: left;
  padding: 0.4rem 0.5rem; border: 0; border-radius: 6px; background: transparent; color: var(--ink); font: inherit; cursor: pointer;
}
.tenant-suggestion .tenant-avatar { grid-row: span 2; }
.tenant-suggestion:hover, .tenant-suggestion:focus-visible { background: var(--surface-2); outline: none; }
.tenant-suggestion-name { font-weight: 600; font-size: 0.9rem; }
.tenant-invitees { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.3rem; }
.tenant-invitee { display: flex; flex-wrap: wrap; gap: 0.2rem 0.7rem; font-size: 0.88rem; line-height: 1.45; color: var(--ink); padding-left: 0.6rem; border-left: 3px solid var(--line); overflow-wrap: anywhere; }
.tenant-invitee-known, .tenant-invitee-new { border-left-color: var(--accent); }
.tenant-invitee-you, .tenant-invitee-not-email { border-left-color: var(--bad); color: var(--bad); }
.tenant-invitee-in-flow { color: var(--ink-soft); }
.tenant-invitee-link { color: var(--accent); }
.tenant-mail-failed { color: var(--bad); font-size: 0.86rem; }
.tenant-mail-sent, .tenant-mail-none { color: var(--ink-soft); font-size: 0.86rem; }
.tenant-invitations { margin-top: 0.4rem; }
.tenant-history td { overflow-wrap: anywhere; }
.tenant-history time { white-space: nowrap; color: var(--muted); }
/* On a phone each row of a tenant's table is a block of its own: the cells
   stack, the headings step aside, and the actions sit under what they act on. */
@media (max-width: 640px) {
  .tenant-history, .tenant-invitations .frame-table { display: block; }
  .tenant-history thead, .tenant-invitations thead { display: none; }
  .tenant-history tbody, .tenant-invitations tbody { display: block; }
  .tenant-history tr, .tenant-invitations tr { display: block; padding: 0.6rem 0.8rem; border-bottom: 1px solid var(--line); }
  .tenant-history td, .tenant-invitations td { display: block; padding: 0.15rem 0; border-bottom: 0; }
  .tenant-actions { justify-content: flex-start; margin-top: 0.35rem; }
}

/* What every session did lately, under the Working now rows (card the-brief-
   tells-you-what-the-other-sessions-did): the same activity an agent's brief
   reads, newest first, each with its session and its card. */
.presence-recent { margin-top: 0.8rem; padding-top: 0.6rem; border-top: 1px solid var(--line); }
.presence-recent-head { margin: 0 0 0.4rem; font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); font-weight: 700; }
.recent-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.35rem; }
.recent-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.15rem 0.5rem; font-size: 0.82rem; line-height: 1.45; }
.recent-when { color: var(--muted); min-width: 4.5rem; }
.recent-who { font-weight: 600; color: var(--ink-soft); }
.recent-what { color: var(--ink); overflow-wrap: anywhere; }
/* A line cut at a word opens whole on a tap, and its title shows it on hover. */
.recent-what-cut { appearance: none; background: none; border: 0; padding: 0; margin: 0; font: inherit; line-height: inherit; text-align: left; cursor: pointer; }
.recent-what-cut:hover { text-decoration: underline dotted; text-underline-offset: 0.2em; }
.recent-what-cut:focus-visible { outline: 2px solid var(--accent, currentColor); outline-offset: 2px; border-radius: 2px; }

/* ── The flow's vault on a screen (2026-10-02) ──────────────────────────────
   A place of the flow, under its tabs (views-vault.js): the files with their
   version and last writer, one file read, edited or traced through its
   versions, and the removed ones apart. The text is shown as written, in the
   reading face, so a person sees exactly what an agent reads. */
.ws-places { margin-top: 0.35rem; padding-top: 0.35rem; border-top: 1px solid var(--line); display: grid; gap: 0.05rem; }
.vault-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.vault-head .btn { display: inline-flex; align-items: center; gap: 0.35rem; }
.vault-files td { vertical-align: top; }
.vault-file-open { display: grid; gap: 0.1rem; text-align: left; background: none; border: 0; padding: 0; color: var(--ink); cursor: pointer; font: inherit; }
.vault-file-open:hover .vault-file-title, .vault-file-open:focus-visible .vault-file-title { color: var(--accent); text-decoration: underline; }
.vault-file-title { font-weight: 600; }
.vault-file-path { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.78rem; color: var(--muted); overflow-wrap: anywhere; }
.vault-file-version { font-variant-numeric: tabular-nums; }
.vault-file-kind, .vault-file-when { color: var(--muted); }
.vault-file-when { white-space: nowrap; }
.vault-removed-list { list-style: none; margin: 0.5rem 0 0; padding: 0; display: grid; gap: 0.4rem; }
.vault-removed-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.3rem 0.8rem; padding: 0.5rem 0.8rem; border: 1px dashed var(--line); border-radius: 8px; }
.vault-removed-row .vault-file-path { font-size: 0.85rem; color: var(--ink-soft); text-decoration: line-through; }
.vault-removed-by { font-size: 0.8rem; color: var(--muted); }
.vault-empty { margin-top: 0.8rem; padding: 1.1rem 1.2rem; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; max-width: 62ch; line-height: 1.55; }
.vault-empty .frame-subtitle { margin-top: 0; }
.vault-empty .btn { display: inline-flex; align-items: center; gap: 0.35rem; margin-top: 0.4rem; }
.vault-back { display: inline-flex; align-items: center; gap: 0.3rem; margin: 0.4rem 0 0.2rem; background: none; border: 0; padding: 0.2rem 0; color: var(--accent); font: inherit; font-size: 0.86rem; cursor: pointer; }
.vault-file-name { margin: 0.6rem 0 0.2rem; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 1rem; overflow-wrap: anywhere; }
.vault-file-meta { margin: 0; font-size: 0.84rem; color: var(--muted); }
.vault-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.8rem 0; }
.vault-old-version { margin: 0.7rem 0 0; padding: 0.55rem 0.8rem; border-radius: 8px; background: var(--warn-soft); color: var(--ink); font-size: 0.86rem; }
.vault-link { background: none; border: 0; padding: 0; color: var(--accent); font: inherit; text-decoration: underline; cursor: pointer; }
.vault-confirm { margin: 0 0 0.8rem; padding: 0.8rem 1rem; border: 1px solid var(--bad); border-radius: 10px; background: var(--bad-soft); max-width: 62ch; }
.vault-confirm p { margin: 0; line-height: 1.5; }
.vault-confirm .vault-actions { margin-bottom: 0; }
.vault-message { margin: 0.6rem 0; font-size: 0.86rem; }
.vault-message-error { color: var(--bad); }
.vault-message-note { color: var(--ink-soft); }
.vault-text { margin: 0.4rem 0 1.5rem; padding: 1rem 1.2rem; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; white-space: pre-wrap; overflow-wrap: anywhere; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.86rem; line-height: 1.6; color: var(--ink); max-width: 80ch; }
.vault-doc { white-space: normal; font-family: inherit; font-size: 0.92rem; line-height: 1.6; }
.vault-doc > :first-child, .vault-doc > .md-heading:first-child { margin-top: 0; }
.vault-doc .md-task { list-style: none; margin-left: -1.2rem; }
.vault-doc .md-box { display: inline-block; width: 1.1rem; color: var(--ink-soft); }
.vault-doc > :last-child { margin-bottom: 0; }
.vault-doc .md-heading { margin: 1.2rem 0 0.4rem; line-height: 1.3; color: var(--ink); }
.vault-doc h4.md-heading { font-size: 1.25rem; }
.vault-doc h5.md-heading { font-size: 1.05rem; }
.vault-doc h6.md-heading { font-size: 0.95rem; }
.vault-doc p, .vault-doc ul, .vault-doc ol, .vault-doc blockquote { margin: 0.5rem 0; }
.vault-doc ul, .vault-doc ol { padding-left: 1.4rem; }
.vault-doc blockquote { padding-left: 0.8rem; border-left: 3px solid var(--line); color: var(--ink-soft); }
.vault-doc code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.84em; padding: 0.05rem 0.25rem; border-radius: 4px; background: var(--field); }
.vault-doc pre { margin: 0.6rem 0; padding: 0.7rem 0.9rem; border-radius: 8px; background: var(--field); border: 1px solid var(--line); overflow-x: auto; white-space: pre; }
.vault-doc pre code { padding: 0; background: none; }
.vault-doc .md-table { display: block; max-width: 100%; overflow-x: auto; border-collapse: collapse; margin: 0.6rem 0; font-size: 0.86rem; }
.vault-doc .md-table th, .vault-doc .md-table td { padding: 0.35rem 0.6rem; border: 1px solid var(--line); text-align: left; vertical-align: top; overflow-wrap: normal; min-width: 4rem; }
.vault-doc .md-table th { background: var(--field); font-weight: 700; }
.vault-doc a { color: var(--accent); }
a.vault-file-open, a.vault-back { text-decoration: none; }
.vault-history-list { margin: 0 0 0.8rem; }
.vault-versions { list-style: none; margin: 0; padding: 0; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); max-width: 62ch; }
.vault-version { display: grid; grid-template-columns: 2.5rem minmax(0, 1fr) auto auto; align-items: center; gap: 0.8rem; padding: 0.45rem 0.8rem; border-bottom: 1px solid var(--line); font-size: 0.86rem; }
.vault-version:last-child { border-bottom: 0; }
.vault-version-number { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--ink-soft); }
.vault-version-removed { color: var(--muted); font-style: italic; }
.vault-version-when { color: var(--muted); white-space: nowrap; }
.vault-version-read[aria-current="true"] { border-color: var(--accent); color: var(--accent); }
.vault-form { display: grid; gap: 0.8rem; margin-top: 0.6rem; max-width: 80ch; }
.vault-field { display: grid; gap: 0.3rem; }
.vault-field-label { font-size: 0.8rem; font-weight: 700; color: var(--ink-soft); }
.vault-field-hint { font-size: 0.78rem; color: var(--muted); }
.vault-path-input, .vault-editor { width: 100%; box-sizing: border-box; padding: 0.55rem 0.7rem; border: 1px solid var(--field-line); border-radius: 8px; background: var(--field); color: var(--ink); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.86rem; line-height: 1.55; }
.vault-editor { min-height: 18rem; resize: vertical; }
.vault-form .vault-actions { margin: 0; }
@media (max-width: 640px) {
  .vault-version { grid-template-columns: 2rem minmax(0, 1fr) auto; }
  .vault-version-when { display: none; }
  .vault-files th:nth-child(4), .vault-files td:nth-child(4) { display: none; }
}

/* ── The workspace under the bar (2026-09-29) ───────────────────────────────
   No layout to choose: three parts a person opens, closes and sizes
   (workspace.js). The sidebar on the left collapses; the main section scrolls
   with the page, as it always did; the side panel on the right shows a second
   tab beside it, with an edge to drag, and can take the main section's place.
   The body wears the state of each part and the panel's width. */
:root { --ws-sidebar: 14.5rem; }

body[data-frame="on"] .wrap { transition: margin 0.18s ease; }
body[data-frame="on"][data-sidebar="open"] .wrap { margin-left: var(--ws-sidebar); }
body[data-frame="on"][data-side="open"] .wrap { margin-right: var(--ws-side, 0px); }
body[data-frame="on"][data-side="max"] .wrap { display: none; }
/* With the sidebar open it is the navigation; collapsed, the tab bar takes the job back. */
body[data-frame="on"][data-sidebar="open"] .tabs { display: none; }
body[data-frame="on"][data-sidebar="open"] .app-header { padding-top: 0.9rem; }
@media (prefers-reduced-motion: reduce) { body[data-frame="on"] .wrap { transition: none; } }

/* The workspace's controls: line icons in the colour of the text beside them
   (icons.js), in quiet square buttons. */
.icon { display: block; flex: none; }
.frame-toggle {
  display: inline-grid; place-items: center; flex: none; width: 2rem; height: 2rem; padding: 0;
  border: 0; border-radius: 8px; background: transparent; color: rgba(243, 246, 249, 0.82); cursor: pointer;
}
.frame-toggle:hover { background: rgba(255, 255, 255, 0.1); color: #f3f6f9; }
.frame-toggle[aria-pressed="true"] { color: #f3f6f9; }
.frame-toggle:focus-visible { outline: 2px solid var(--lp-engineering); outline-offset: 2px; }
.frame-travel { width: 1.75rem; color: rgba(243, 246, 249, 0.6); }
.frame-travel-forward { margin-right: 0.35rem; }

/* The sidebar, in the manner of the desktop app it is modelled on: entries in
   regular weight with a line icon each, quiet group names, a subtle mark on
   the entry the reader is on. */
#sidebar-root[hidden], #side-root[hidden] { display: none; }
#sidebar-root {
  position: fixed; top: var(--frame-bar); left: 0; bottom: 0; width: var(--ws-sidebar); z-index: 6;
  overflow-y: auto; overscroll-behavior: contain; background: var(--surface); border-right: 1px solid var(--line);
}
.ws-sidebar { display: grid; align-content: start; gap: 1.2rem; padding: 0.85rem 0.5rem 1.5rem; }
.ws-company { margin-top: 0.5rem; padding: 0.85rem 0.6rem 0; border-top: 1px solid var(--line); font-size: 0.78rem; color: var(--muted); }
.ws-company .company-links { display: flex; flex-wrap: wrap; gap: 0.2rem 0.75rem; margin-bottom: 0.4rem; }
.ws-company a { color: inherit; text-underline-offset: 3px; }
.ws-company .company-line { margin: 0; }
.app-foot, .plans-foot { margin: 2.5rem auto 1.5rem; padding-top: 1rem; border-top: 1px solid var(--line); font-size: 0.82rem; color: var(--muted); }
.plans-foot { max-width: 72rem; padding-inline: 1rem; }
.app-foot .company-links, .plans-foot .company-links { display: flex; flex-wrap: wrap; gap: 0.3rem 1rem; margin-bottom: 0.4rem; }
.app-foot a, .plans-foot a { color: inherit; text-underline-offset: 3px; }
.app-foot .company-line, .plans-foot .company-line { margin: 0; }
.ws-group { display: grid; gap: 0.05rem; }
.ws-group-head {
  font-size: 0.78rem; font-weight: 500; color: var(--muted);
  padding: 0.2rem 0.6rem 0.35rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ws-row { display: flex; align-items: center; gap: 0.1rem; border-radius: 8px; min-width: 0; padding-right: 0.15rem; }
.ws-row:hover, .ws-row:focus-within { background: var(--surface-2); }
.ws-row-current, .ws-row-current:hover { background: var(--surface-2); }
.ws-link {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: 0.6rem;
  padding: 0.4rem 0.35rem 0.4rem 0.6rem; border-radius: 8px;
  color: var(--ink-soft); text-decoration: none; font-weight: 400; font-size: 0.9rem; line-height: 1.35;
}
.ws-link .icon { color: var(--muted); }
.ws-link-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ws-row:hover .ws-link, .ws-link[aria-current="page"] { color: var(--ink); }
.ws-row:hover .ws-link .icon, .ws-link[aria-current="page"] .icon { color: var(--ink-soft); }
.ws-link[aria-current="page"] { font-weight: 500; }
.ws-link:focus-visible, .ws-beside:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.ws-count { flex: none; font-size: 0.78rem; font-weight: 400; font-variant-numeric: tabular-nums; color: var(--muted); }
/* The control that opens a tab beside the main section: quiet until the row is
   pointed at or the control is reached by keyboard; lit while its tab is there. */
.ws-beside {
  flex: none; display: inline-grid; place-items: center; width: 1.7rem; height: 1.7rem; padding: 0;
  border: 0; border-radius: 6px; background: transparent; color: var(--muted); cursor: pointer; opacity: 0;
}
.ws-row:hover .ws-beside, .ws-row:focus-within .ws-beside, .ws-beside[aria-pressed="true"] { opacity: 1; }
.ws-beside:hover { background: var(--surface); color: var(--ink); }
.ws-beside[aria-pressed="true"] { color: var(--accent); }
@media (hover: none) { .ws-beside { opacity: 1; } }

/* The frame's own screens have a sub-navigation; beside the sidebar it would say the same twice. */
body[data-frame="on"][data-sidebar="open"] .frame-screen { grid-template-columns: minmax(0, 1fr); }
body[data-frame="on"][data-sidebar="open"] .frame-subnav { display: none; }

/* The side panel: its head, its own scroll, and the edge a person drags. */
#side-root {
  position: fixed; top: var(--frame-bar); right: 0; bottom: 0; width: var(--ws-side, 35rem); z-index: 6;
  background: var(--bg); border-left: 1px solid var(--line); box-shadow: -2px 0 12px rgba(10, 16, 22, 0.12);
}
#side-root:not([hidden]) { display: grid; grid-template-rows: auto minmax(0, 1fr); }
body[data-side="max"] #side-root { left: 0; width: auto; border-left: 0; box-shadow: none; }
body[data-side="max"][data-sidebar="open"] #side-root { left: var(--ws-sidebar); }
.ws-handle { position: absolute; left: -5px; top: 0; bottom: 0; width: 10px; cursor: col-resize; z-index: 1; touch-action: none; }
.ws-handle::after { content: ""; position: absolute; left: 4px; top: 0; bottom: 0; width: 2px; background: transparent; transition: background 0.12s ease; }
.ws-handle:hover::after, .ws-handle-active::after, .ws-handle:focus-visible::after { background: var(--accent); }
.ws-handle:focus-visible { outline: none; }
body[data-side="max"] .ws-handle { display: none; }
.ws-side-head {
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
  padding: 0.45rem 0.6rem 0.45rem 0.85rem; background: var(--surface); border-bottom: 1px solid var(--line);
}
.ws-side-tabs { display: flex; gap: 0.15rem; min-width: 0; overflow-x: auto; background: var(--surface-2); border-radius: 8px; padding: 0.15rem; }
.ws-side-tab {
  border: 0; background: transparent; color: var(--ink-soft); font: inherit; font-size: 0.84rem; font-weight: 400;
  padding: 0.3rem 0.65rem; border-radius: 6px; cursor: pointer; white-space: nowrap;
}
.ws-side-tab:hover { color: var(--ink); }
.ws-side-tab[aria-selected="true"] { background: var(--surface); color: var(--ink); font-weight: 500; box-shadow: var(--shadow); }
.ws-side-tab:focus-visible, .ws-side-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.ws-side-actions { display: flex; gap: 0.15rem; flex: none; }
.ws-side-btn {
  display: inline-grid; place-items: center; width: 1.9rem; height: 1.9rem; padding: 0;
  border: 0; border-radius: 8px; background: transparent; color: var(--ink-soft); cursor: pointer;
}
.ws-side-btn:hover { background: var(--surface-2); color: var(--ink); }
/* While the edge is dragged the page selects no text and eases no margin: the
   sections follow the pointer, not an animation of it. */
body.ws-dragging { user-select: none; cursor: col-resize; }
body.ws-dragging .wrap { transition: none; }
/* The bar is outside the panel's scroll, so what sticks inside sticks to the panel's own top. */
.ws-side-view { --frame-bar: 0rem; min-width: 0; overflow-y: auto; overscroll-behavior: contain; padding: 0.9rem 1rem 3rem; }

/* A section lays out for the width it has, not for the window's (workspace.js
   names each section's width on the section). Narrow: one column. Wide: the
   cockpit's burn-up sits beside its forecast, so the chart is read at a size
   and not at the size of the screen. Very wide: the metrics seat three in a
   row. Only under the frame: with the switch off the board is what it was. */
body[data-frame="on"] [data-pane="narrow"] .cockpit-panels,
body[data-frame="on"] [data-pane="narrow"] .metrics-grid,
body[data-frame="on"] [data-pane="narrow"] .metrics-hero,
body[data-frame="on"] [data-pane="narrow"] .forecast-band,
body[data-frame="on"] [data-pane="narrow"] .control-rows,
body[data-frame="on"] [data-pane="narrow"] .econ,
body[data-frame="on"] [data-pane="narrow"] .thumbs { grid-template-columns: minmax(0, 1fr); }
body[data-frame="on"] [data-pane="narrow"] .metrics-grid > .panel-cfd { grid-column: auto; }
body[data-frame="on"] [data-pane="narrow"] .tiles { grid-template-columns: repeat(3, 1fr); }
body[data-frame="on"] [data-pane="xwide"] .metrics-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
body[data-frame="on"] [data-pane="xwide"] .metrics-grid > .panel-cycle { order: 1; }
body[data-frame="on"] [data-pane="xwide"] .metrics-grid > .panel-throughput { order: 2; }
body[data-frame="on"] [data-pane="xwide"] .metrics-grid > .panel-cfd { order: 3; grid-column: auto; }
body[data-frame="on"] [data-pane="xwide"] .metrics-grid > .panel-economics { order: 4; }
body[data-frame="on"] [data-pane="xwide"] .metrics-grid > .panel-next-up { order: 5; grid-column: span 2; }

.cockpit-hero { display: grid; gap: 0.9rem; margin: 0 0 0.9rem; }
.cockpit-hero > * { margin-top: 0; margin-bottom: 0; min-width: 0; }
body[data-frame="on"] [data-pane="wide"] .cockpit-hero,
body[data-frame="on"] [data-pane="xwide"] .cockpit-hero { grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr); align-items: stretch; }
body[data-frame="on"] [data-pane="wide"] .cockpit-hero > .forecast-band,
body[data-frame="on"] [data-pane="xwide"] .cockpit-hero > .forecast-band { grid-template-columns: minmax(0, 1fr); align-content: start; }

/* Panels read together sit together: cycle time beside throughput, the value
   and risk chart beside the queue it orders, the cumulative flow, read alone,
   across the row. */
@media (min-width: 860px) { .metrics-grid > .panel-cfd { grid-column: 1 / -1; } }

@media (max-width: 48rem) {
  /* On a phone the workspace is the bar, the tab bar and one column. */
  #sidebar-root, #side-root { display: none !important; }
  .frame-travel { display: none; }
  body[data-frame="on"] .wrap { padding: 0 0.85rem; }
  .frame-bar { padding: 0 0.85rem; gap: 0.6rem; }
  .frame-mark-name { display: none; }
  .frame-crumb { max-width: 9rem; padding: 0.35rem 0.4rem; }
  .frame-where > .frame-menu { max-width: 9rem; }
  /* With the two doors on the bar, the flow's name has the room first and the tenant's gives way. */
  .frame-where > .frame-menu-tenant, .frame-where > .frame-crumb-tenant { flex: 0 3 auto; max-width: 6rem; }
  .frame-where > .frame-menu-flow { flex: 0 1 auto; }
  .frame-right { gap: 0.35rem; }
  .frame-door { margin: 0 -0.15rem; }
  .frame-screen { grid-template-columns: minmax(0, 1fr); gap: 1rem; }
  .frame-subnav { position: static; display: flex; overflow-x: auto; gap: 0.25rem; padding-bottom: 0.3rem; }
  .frame-subnav-head { display: none; }
  .frame-subnav-link { white-space: nowrap; }
  .frame-subnav-back { margin-top: 0; }
  .frame-rows { grid-template-columns: minmax(0, 1fr); gap: 0.2rem 0; }
  .frame-rows dd { margin-bottom: 0.6rem; }
}

/* ── Decisions (card a-decision-is-its-own-record-not-a-card) ────────────────
   A question put to a person, answered here. Open ones first, the overdue
   marked; the answered ones below, never mixed with the open. */
/* Since 2026-09-28 the decisions are a panel at the top of the cockpit, before
   Impediments and Key points (card open-decisions-have-their-own-place-on-the-
   cockpit): one full-width panel, the open ones answered in place, the
   answered ones folded under a summary. */
.decisions-panel { display: grid; gap: 0.8rem; margin: 0 0 0.9rem; padding-bottom: 1rem; }
.decisions-panel .decisions-head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin: 0; }
.decisions-panel .decisions-title { margin: 0; font-size: 0.98rem; }
/* The glyph every decision wears, drawn rather than written, so the title reads as one word in every language. */
.decisions-panel .decisions-title::before { content: "◆ "; color: var(--warn); }
.decisions-panel .decisions-lead { font-size: 0.9rem; }
.decisions-panel .decisions-raise { justify-self: start; margin: 0; }
.decisions-panel .decision-row { padding: 0.8rem 0.9rem; }
.decisions-answered > summary { cursor: pointer; list-style: none; display: inline-flex; align-items: center; gap: 0.4rem; }
.decisions-answered > summary::-webkit-details-marker { display: none; }
.decisions-answered > summary::before { content: ""; width: 0.4rem; height: 0.4rem; border: solid currentColor; border-width: 0 1.5px 1.5px 0; transform: rotate(-45deg); opacity: 0.7; transition: transform 0.15s ease; }
.decisions-answered[open] > summary::before { transform: rotate(45deg); }
.decisions-answered > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.decisions-answered-list { display: grid; gap: 0.8rem; margin-top: 0.6rem; }
.decisions-answered > .decisions-empty { margin-top: 0.6rem; }
.decisions-view { display: grid; gap: 1.2rem; padding-bottom: 1rem; }
.decisions-head { display: grid; gap: 0.4rem; }
.decisions-title { margin: 0.2rem 0 0; font-size: 1.35rem; letter-spacing: -0.01em; }
.decisions-lead { margin: 0; color: var(--ink-soft); font-size: 0.95rem; line-height: 1.5; max-width: 64ch; }
.decisions-raise { justify-self: start; margin-top: 0.3rem; }
.decisions-raise-form, .decision-answer-form { display: grid; gap: 0.35rem; }
.decisions-raise-form {
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 0.9rem 1rem; max-width: 46rem; box-shadow: var(--shadow);
}
.decisions-label { font-size: 0.78rem; font-weight: 700; color: var(--ink-soft); margin-top: 0.3rem; }
.decisions-field {
  width: 100%; border: 1px solid var(--field-line); border-radius: 8px; padding: 0.5rem 0.65rem; font: inherit; font-size: 0.92rem;
  background: var(--field); color: var(--ink); resize: vertical;
}
.decisions-field:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* The person a decision is put to, and what is asked of them, read like the form's other fields. */
.decisions-raise-form .waits-on-person, .decisions-raise-form .waits-on-ask {
  border: 1px solid var(--field-line); border-radius: 8px; padding: 0.5rem 0.65rem; font-size: 0.92rem;
  background: var(--field); color: var(--ink);
}
.decisions-raise-form .waits-on-label { font-weight: 700; color: var(--ink-soft); margin-top: 0.3rem; }
.decisions-actions { display: flex; gap: 0.5rem; justify-content: flex-end; margin-top: 0.4rem; }
.decisions-problem { margin: 0.2rem 0 0; color: var(--bad); font-size: 0.84rem; }
.decisions-subtitle { margin: 0.6rem 0 0.5rem; font-size: 1rem; color: var(--ink-soft); }
/* Cards a reviewer sent back that nobody picked up (card a-refused-review-goes-back-to-its-builder). */
.refused-waiting { margin-top: 0.4rem; display: grid; gap: 0.5rem; }
.refused-row { padding: 0.5rem 0.7rem; border: 1px solid var(--line); border-left: 3px solid var(--bad); border-radius: 8px; display: grid; gap: 0.2rem; }
.refused-title { justify-self: start; padding: 0; background: none; border: 0; font: inherit; font-weight: 600; color: var(--ink); cursor: pointer; text-align: left; }
.refused-title:hover, .refused-title:focus-visible { text-decoration: underline; }
.refused-why { margin: 0; font-size: 0.85rem; color: var(--ink-soft); }
.refused-wait { margin: 0; font-size: 0.8rem; color: var(--muted); }
.decisions-empty { margin: 0; color: var(--muted); font-size: 0.9rem; padding: 0.8rem 1rem; border: 1px dashed var(--line); border-radius: 10px; max-width: 46rem; }
.decisions-open, .decisions-answered { display: grid; gap: 0.8rem; }

.decision-row {
  background: var(--surface); border: 1px solid var(--line); border-left: 4px solid var(--lp-management); border-radius: 12px;
  padding: 0.9rem 1.1rem 1rem; box-shadow: var(--shadow); display: grid; gap: 0.5rem; max-width: 64rem;
}
.decision-stale { border-left-color: var(--lp-risk); }
.decision-answered { border-left-color: var(--lp-strategy); }
.decision-question { margin: 0; font-size: 1.05rem; line-height: 1.4; }
.decision-question::before { content: "◆ "; color: var(--warn); }
.decision-answered .decision-question::before { color: var(--good); }
.decision-context { margin: 0; color: var(--ink-soft); font-size: 0.92rem; line-height: 1.5; white-space: pre-wrap; }
.decisions-wait { margin: 0; display: flex; flex-wrap: wrap; gap: 0.35rem 0.8rem; font-size: 0.86rem; color: var(--ink-soft); align-items: center; }
.decisions-who { font-weight: 700; color: var(--ink); }
.decisions-wait-stale .decisions-since { color: var(--bad); font-weight: 600; }
.decisions-overdue {
  font-size: 0.7rem; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; color: var(--bad);
  background: var(--bad-soft); padding: 0.1rem 0.5rem; border-radius: 99px;
}
.decisions-holds { display: grid; gap: 0.25rem; margin: 0; font-size: 0.86rem; }
.decisions-holds-none { color: var(--muted); }
.decisions-holds-label { font-weight: 700; color: var(--ink-soft); }
.decisions-holds-list { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.3rem; }
.decisions-held {
  border: 1px solid var(--line); background: var(--surface-2); color: var(--ink); border-radius: 99px; padding: 0.15rem 0.6rem;
  font: inherit; font-size: 0.8rem; cursor: pointer;
}
.decisions-held:hover { border-color: var(--accent); color: var(--accent); }
.decision-answer-form { margin-top: 0.3rem; max-width: 46rem; }
.decision-record { justify-self: start; }
.decision-raised, .decision-answered-by { margin: 0; font-size: 0.76rem; color: var(--muted); }
.decision-recommendation-note { margin: 0; font-size: 0.8rem; color: var(--ink-soft); }
.decision-recommended { margin: 0; font-size: 0.86rem; color: var(--ink-soft); line-height: 1.5; white-space: pre-wrap; max-width: 64ch; }
.decision-answer { margin: 0; font-size: 0.95rem; line-height: 1.55; white-space: pre-wrap; padding: 0.5rem 0.8rem; background: var(--good-soft); border-radius: 8px; max-width: 64ch; }
.decision-reopen { justify-self: start; }
.backlog-decision { display: grid; gap: 0.1rem; text-align: left; border: 1px solid var(--line); background: var(--surface); border-radius: 10px; padding: 0.5rem 0.7rem; font: inherit; color: var(--ink); cursor: pointer; }
.backlog-decision-title { font-weight: 700; font-size: 0.88rem; }
.backlog-decision-sub { font-size: 0.74rem; color: var(--muted); }

/* The module sheet (card a-person-edits-a-module-on-the-map): its place on the
   backbone, the box an archive waits on, and the archived modules' way back. */
.module-move { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.archive-box, .archive-done {
  margin-top: 0.75rem; padding: 0.75rem 0.9rem; border-radius: 10px;
  background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line);
}
.archive-box p, .archive-done p { margin: 0 0 0.5rem; }
.archive-epics { margin: 0 0 0.6rem; padding-left: 1.2rem; }
.archive-why { color: var(--muted); font-size: 0.85rem; }
.archived-modules { margin-top: 0.9rem; }
.archived-modules-list { list-style: none; margin: 0.35rem 0 0; padding: 0; display: grid; gap: 0.4rem; }
.archived-modules-list li { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; }

/* ── Plans: the plans page, the plans admin and a tenant's comparison ─────
   Card a-price-change-starts-on-a-date-and-one-catalogue-serves-everyone. One
   drawing of the plans (plans-view.js), in the board's own tokens, so both
   themes hold at 4.5:1. */
.plans-body { margin: 0; background: var(--bg); color: var(--ink); font-family: var(--brand-font); }
.plans-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0.6rem 1rem; background: var(--lp-ground); color: #f3f6f9;
}
.plans-mark { color: inherit; text-decoration: none; display: inline-flex; align-items: center; gap: 0.5rem; }
.plans-page { max-width: 72rem; margin: 0 auto; padding: 1.5rem 1rem 3rem; box-sizing: border-box; }
.plans-title { font-size: 1.6rem; margin: 0 0 0.4rem; flex: none; }
.plans-lead { color: var(--ink-soft); margin: 0 0 1.2rem; max-width: 46rem; }
.plans-message { color: var(--ink-soft); }
.plans-controls { display: flex; flex-wrap: wrap; gap: 0.8rem; margin: 0 0 1rem; }
.plans-segs { display: inline-flex; border: 1px solid var(--field-line); border-radius: 8px; overflow: hidden; margin: 0 0 0.8rem; }
.plans-seg {
  font: inherit; font-size: 0.9rem; padding: 0.4rem 0.8rem; border: 0; cursor: pointer;
  background: var(--surface); color: var(--ink-soft);
}
.plans-seg + .plans-seg { border-left: 1px solid var(--field-line); }
.plans-seg[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); }
.plans-seg:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* Every plan of a module on one line, never wrapped onto a second row
   (Samuel, 2026-10-19: "I don't like the line broken"): where the line is
   narrower than the plans, as in the admin's preview, it scrolls sideways
   inside itself; on a phone the plans stack one under the other. The top
   padding keeps a card's badge inside the scrolling line. */
.plan-cards {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(11.5rem, 1fr); gap: 0.9rem;
  overflow-x: auto; padding: 0.8rem 0 0.3rem;
}
@media (max-width: 640px) {
  .plan-cards { grid-auto-flow: row; grid-auto-columns: auto; grid-template-columns: minmax(0, 1fr); overflow-x: visible; }
}
.plan-card {
  position: relative; background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
  padding: 1.1rem 1rem 1.2rem; min-width: 0; box-shadow: var(--shadow);
  display: flex; flex-direction: column; container-type: inline-size;
}
.plan-card.is-highlight { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.plan-card.is-wanted { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent); }
.plan-card.is-current { border-color: var(--good); box-shadow: 0 0 0 1px var(--good); }
.plan-badge {
  position: absolute; top: -0.7rem; right: 0.8rem; margin: 0; padding: 0.1rem 0.55rem; border-radius: 999px;
  font-size: 0.75rem; font-weight: 700; background: var(--accent); color: var(--on-accent);
}
.plan-card.is-current .plan-badge { background: var(--good); }
.plan-name { margin: 0 0 0.6rem; font-size: 0.9rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--accent); }
/* The price scales to its card, so a yearly price in dollars or reais never
   leaves it (Victor's report of 2026-10-23, item 2.2). */
.plan-price { margin: 0; font-size: clamp(1.2rem, 15cqi, 2rem); font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; white-space: nowrap; }
.plan-per { margin: 0.1rem 0 0.5rem; color: var(--muted); font-size: 0.85rem; }
.plan-note { margin: 0 0 0.3rem; color: var(--ink-soft); font-size: 0.85rem; }
.plan-lines { list-style: none; margin: 0.8rem 0 0; padding: 0; display: grid; gap: 0.35rem; font-size: 0.9rem; }
.plan-line { display: flex; flex-wrap: wrap; gap: 0.1rem 0.45rem; align-items: baseline; min-width: 0; }
.plan-line.is-off { color: var(--muted); }
.plan-mark { flex: none; font-weight: 700; color: var(--good); width: 0.8rem; }
.plan-line.is-off .plan-mark { color: var(--muted); }
.plan-text { flex: 1 1 calc(100% - 1.5rem); min-width: 0; overflow-wrap: anywhere; }
.plans-empty { color: var(--muted); }
/* The plan's button sits at the foot of its card, every card's at one height. */
.plan-cta {
  margin-top: auto; align-self: stretch; display: block; text-align: center; padding: 0.6rem 0.8rem; margin-block-start: 1rem;
  border: 1px solid var(--accent); border-radius: 8px; color: var(--accent); font-weight: 700; text-decoration: none;
}
.plan-cta.is-primary { background: var(--accent); color: var(--on-accent); }
.plan-cta:hover { box-shadow: 0 0 0 1px var(--accent); }
.plan-cta:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.plan-lines { flex: 1 0 auto; }
.site-plans-switches { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: center; }
.plans-currency { margin-bottom: 0.8rem; }
.tenant-plans { margin-top: 1.2rem; }
.tenant-plans-module h4 { margin: 0.8rem 0 0.6rem; }

/* An inbox row waiting on a close: what the close rests on, above its controls. */
.waits-inbox-close { display: grid; gap: 0.5rem; min-width: 0; }

/* ── The plans admin ───────────────────────────────────────────────────────
   Card a-price-change-starts-on-a-date-and-one-catalogue-serves-everyone, the
   layout Samuel chose on 2026-10-19: one plan at a time, its terms and what it
   includes as two tabs beside its name, that plan as the customer reads it on
   the right, every plan side by side below. Where values are read, only values
   are drawn; what describes a line opens in one side panel from its name.
   Restrained, on the board's own tokens. */
.plans-admin:has(.pk-shell) { max-width: none; padding: 0; }
.pa-message { margin: 0.6rem 0 0; padding: 0.4rem 0.6rem; border-radius: 6px; }
.pa-message.is-good { background: var(--good-soft); color: var(--good); }
.pa-message.is-bad { background: var(--bad-soft); color: var(--bad); }
.pa-problems-title { margin: 0.6rem 0 0.2rem; font-weight: 600; color: var(--bad); }
.pa-problems { margin: 0; padding-left: 1.2rem; color: var(--bad); }
.pk-shell { display: grid; grid-template-columns: minmax(0, 1fr); align-items: start; }
.pk-shell.has-panel { grid-template-columns: minmax(0, 1fr) minmax(22rem, 26rem); }
.pk-work { min-width: 0; padding: 1.4rem clamp(1rem, 3vw, 2rem) 2rem; display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.4rem; align-content: start; }

/* The header: the title and the edit/customer switch, then the product, whether customers see it, and the upgrade path. */
.pk-head { display: grid; gap: 0.9rem; }
.pk-head-top { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.8rem; }
.pk-title { margin: 0; font-size: 1.5rem; letter-spacing: -0.01em; }
.pk-head .plans-segs { margin: 0; }
/* One button per module: with the four areas beside Maestro, Benjamin and Marketing, the row is wider than a phone,
   so it scrolls sideways inside itself and the page never does. */
.pk-head, .pk-head-row { min-width: 0; }
.pk-modules { min-width: 0; max-width: 100%; overflow-x: auto; }
.pk-modules .plans-seg { flex: none; white-space: nowrap; }
.pk-head-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem 1.6rem; }
.pk-head-row .pk-switch-row { padding: 0; border: 0; gap: 0.6rem; }
.pk-path { margin: 0 0 0 auto; color: var(--ink-soft); font-size: 0.85rem; }
.pk-path-label { color: var(--muted); }
.pk-notice { margin: 0; padding: 0.5rem 0.75rem; border-radius: 8px; background: var(--warn-soft); color: var(--warn); font-size: 0.85rem; }

/* Small shared pieces */
.pk-kicker { margin: 0; font-size: 0.75rem; font-weight: 600; color: var(--muted); }
.pk-label { font-size: 0.85rem; font-weight: 600; color: var(--ink); }
.pk-tag {
  display: inline-block; font-size: 0.7rem; font-weight: 600; line-height: 1.5;
  padding: 0 0.45rem; border-radius: 999px; background: var(--surface-2); color: var(--ink-soft); white-space: nowrap;
}
.pk-tag.is-accent { background: var(--accent-soft); color: var(--accent); }
.pk-tag.is-good { background: var(--good-soft); color: var(--good); }
.pk-input, .pk-select { font: inherit; font-size: 0.9rem; border-radius: 6px; padding: 0.4rem 0.55rem; min-width: 0; box-sizing: border-box; }
.pk-input[type="number"] { font-variant-numeric: tabular-nums; }
.pk-field { display: grid; gap: 0.3rem; min-width: 0; }
.pk-field .pk-input, .pk-field .pk-select { width: 100%; }
.pk-field-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: 0.8rem; }
.pk-fixed { font-size: 0.9rem; color: var(--ink-soft); padding: 0.4rem 0; }
.pk-derived { font-size: 0.85rem; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.pk-primary, .pk-secondary, .pk-add, .pk-quiet {
  font: inherit; font-size: 0.875rem; border-radius: 6px; cursor: pointer; padding: 0.45rem 0.85rem;
  transition: background-color 150ms ease-out, border-color 150ms ease-out, color 150ms ease-out;
}
.pk-primary { background: var(--accent); color: var(--on-accent); border: 1px solid var(--accent); font-weight: 600; text-decoration: none; }
.pk-primary:hover:not(:disabled) { filter: brightness(1.08); }
.pk-secondary { background: var(--surface); color: var(--ink); border: 1px solid var(--field-line); }
.pk-secondary:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.pk-add { background: transparent; color: var(--accent); border: 1px dashed var(--field-line); white-space: nowrap; }
.pk-add:hover:not(:disabled) { border-color: var(--accent); background: var(--accent-soft); }
.pk-quiet { background: transparent; border: 1px solid transparent; color: var(--ink-soft); padding: 0.35rem 0.6rem; }
.pk-quiet:hover { color: var(--ink); background: var(--surface-2); }
.pk-danger { color: var(--bad); border-color: var(--bad); }
.pk-danger.is-armed { background: var(--bad); color: var(--on-accent); }
.pk-danger-text { color: var(--bad); }
:is(.pk-primary, .pk-secondary, .pk-add, .pk-quiet):disabled { opacity: 0.5; cursor: not-allowed; }
:is(.pk-primary, .pk-secondary, .pk-add, .pk-quiet, .pk-tick, .pk-infinity, .pk-switch, .po-rail-item, .po-line-button, .po-tab, .po-pick, .pk-chooser-option):focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
.pk-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }
/* A given plan's tenants, each with its take back (card a-tenant-given-an-agents-add-on-finds-its-agents-drawn-turned-on-and-runnable). */
.pk-given { display: grid; gap: 0.5rem; padding-top: 0.5rem; border-top: 1px solid var(--line); }
.pk-given-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.25rem; }
.pk-given-row { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; min-width: 0; }
.pk-given-row > span { overflow-wrap: anywhere; }

/* A switch: a yes or no that reads as one at a glance. */
.pk-switch-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0.55rem 0; }
.pk-switch {
  flex: none; position: relative; width: 2.4rem; height: 1.4rem; border-radius: 999px; padding: 0; cursor: pointer;
  background: var(--field-line); border: 0; transition: background-color 150ms ease-out;
}
.pk-switch::after {
  content: ""; position: absolute; top: 0.15rem; left: 0.15rem; width: 1.1rem; height: 1.1rem; border-radius: 50%;
  background: var(--surface); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); transition: transform 180ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.pk-switch[aria-checked="true"] { background: var(--accent); }
.pk-switch[aria-checked="true"]::after { transform: translateX(1rem); }

/* A plan's value on a line: a tick, a choice, a number or unlimited. */
.pk-tick {
  width: 1.75rem; height: 1.75rem; border-radius: 6px; padding: 0; cursor: pointer; display: inline-grid; place-items: center;
  background: var(--surface); border: 1px solid var(--field-line); transition: background-color 120ms ease-out, border-color 120ms ease-out;
}
.pk-tick:hover { border-color: var(--accent); }
.pk-tick-mark { width: 0.45rem; height: 0.8rem; border: solid transparent; border-width: 0 2px 2px 0; transform: translateY(-1px) rotate(45deg); }
.pk-tick[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); }
.pk-tick[aria-pressed="true"] .pk-tick-mark { border-color: var(--on-accent); }
.pk-select { max-width: 11rem; }
.pk-limit { display: inline-flex; align-items: center; gap: 0.35rem; }
.pk-limit .pk-input { width: 4.5rem; text-align: right; }
.pk-unlimited-word { display: inline-block; min-width: 4.5rem; font-size: 0.9rem; color: var(--ink); }
.pk-infinity {
  width: 1.9rem; height: 1.9rem; border-radius: 6px; cursor: pointer; font-size: 1.05rem; line-height: 1; padding: 0;
  background: transparent; color: var(--muted); border: 1px solid var(--line);
}
.pk-infinity:hover { color: var(--accent); border-color: var(--accent); }
.pk-infinity[aria-pressed="true"] { background: var(--accent-soft); color: var(--accent); border-color: var(--accent); }
.pk-always { font-size: 0.85rem; color: var(--muted); }

/* Adding a line: the four kinds. */
.pk-chooser { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.pk-chooser-option {
  font: inherit; font-size: 0.875rem; font-weight: 600; cursor: pointer; padding: 0.45rem 0.85rem; border-radius: 6px;
  background: var(--surface); color: var(--ink); border: 1px solid var(--line);
}
.pk-chooser-option:hover { border-color: var(--accent); color: var(--accent); }

/* The side panel */
.pk-panel {
  position: sticky; top: 0; height: 100vh; max-height: 100dvh; overflow-y: auto; box-sizing: border-box;
  background: var(--surface); border-left: 1px solid var(--line); outline: none;
  animation: pk-panel-in 200ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
@keyframes pk-panel-in { from { opacity: 0; transform: translateX(0.75rem); } to { opacity: 1; transform: none; } }
.pk-panel-bar { position: sticky; top: 0; display: flex; justify-content: flex-end; padding: 0.5rem 0.75rem; background: var(--surface); border-bottom: 1px solid var(--line); z-index: 1; }
.pk-panel-body { padding: 1rem 1.25rem 6rem; display: grid; gap: 1rem; align-content: start; }
.pk-panel-title { margin: -0.4rem 0 0; font-size: 1.2rem; overflow-wrap: anywhere; }
.pk-group { display: grid; gap: 0.6rem; padding-top: 1rem; border-top: 1px solid var(--line); }
.pk-group-title { margin: 0; font-size: 0.95rem; }
.pk-translations { display: grid; gap: 0.6rem; }
.pk-translation { display: grid; gap: 0.3rem; }
.pk-translation-head { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; }
.pk-lang { font-size: 0.8rem; font-weight: 600; color: var(--ink-soft); }
.pk-tr-state { font-size: 0.72rem; color: var(--muted); }
.pk-tr-state.is-machine { color: var(--accent); }
.pk-tr-state.is-pending { color: var(--warn); }
.pk-translation .pk-input { width: 100%; }
.pk-option { display: grid; gap: 0.5rem; padding: 0.7rem; border: 1px solid var(--line); border-radius: 8px; }
.pk-option-row { display: flex; gap: 0.4rem; align-items: center; }
.pk-option-row .pk-input { flex: 1; }
.pk-check-row { display: flex; gap: 0.55rem; align-items: center; font-size: 0.9rem; }
.pk-cap-row { display: flex; align-items: center; justify-content: space-between; gap: 0.8rem; font-size: 0.9rem; }
.pk-cap-row .pk-input { width: 6.5rem; text-align: right; }

/* The bar that stays at the bottom. */
.pk-savebar {
  position: sticky; bottom: 0; z-index: 5; background: var(--surface); border-top: 1px solid var(--line);
  box-shadow: 0 -4px 12px rgba(14, 27, 38, 0.06); padding: 0.65rem clamp(1rem, 3vw, 2rem);
}
.pk-savebar-inner { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.6rem 1rem; }
.pk-status { margin: 0 auto 0.45rem 0; font-size: 0.85rem; color: var(--muted); }
.pk-status.is-dirty { color: var(--warn); font-weight: 600; }
.pk-status.is-dirty::before { content: ""; display: inline-block; width: 0.5rem; height: 0.5rem; border-radius: 50%; background: currentColor; margin-right: 0.45rem; vertical-align: 0.05rem; }
.pk-inline-field { display: grid; gap: 0.2rem; font-size: 0.75rem; color: var(--muted); }
.pk-why { flex: 1 1 16rem; max-width: 30rem; }
.pk-why .pk-input { width: 100%; }
.pk-savebar .pa-message, .pk-savebar .pa-problems-title { margin-top: 0.5rem; }

/* Versions, folded until asked for. */
.pk-versions { border-top: 1px solid var(--line); padding-top: 0.8rem; }
.pk-versions summary { cursor: pointer; font-weight: 600; font-size: 0.95rem; }
.pk-version-list { list-style: none; margin: 0.8rem 0 0; padding: 0; display: grid; gap: 0.9rem; }
.pk-version { display: grid; gap: 0.25rem; padding-left: 0.9rem; border-left: 1px solid var(--line); }
.pk-version-head { margin: 0; display: flex; gap: 0.5rem; align-items: center; }
.pk-version-by { margin: 0; font-size: 0.8rem; color: var(--muted); }
.pk-version-note { margin: 0; font-size: 0.9rem; }
.pk-changes { margin: 0.2rem 0 0; padding-left: 1.1rem; font-size: 0.85rem; color: var(--ink-soft); }
.pk-customer { display: grid; gap: 0.6rem; }
.pk-customer .plans-segs { justify-self: start; margin: 0; }
.pk-customer-full { min-width: 0; }

/* One plan at a time: the plans down the left, the plan in the middle, it as the customer reads it on the right. */
.po { display: grid; gap: 2rem; min-width: 0; }
.po-top { display: grid; grid-template-columns: 13rem minmax(0, 1fr) minmax(16rem, 20rem); gap: 1.6rem; align-items: start; }
.po-rail { display: grid; gap: 0.6rem; position: sticky; top: 1rem; }
.po-rail-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.25rem; }
.po-rail-item {
  width: 100%; font: inherit; text-align: left; cursor: pointer; display: grid; gap: 0.1rem; justify-items: start;
  padding: 0.55rem 0.7rem; border-radius: 8px; background: transparent; color: var(--ink); border: 1px solid transparent;
}
.po-rail-item:hover { background: var(--surface-2); }
.po-rail-item.is-current { background: var(--surface); border-color: var(--line); box-shadow: var(--shadow); }
.po-rail-name { font-weight: 700; }
.po-rail-price { font-size: 0.8rem; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.po-rail-item.is-retired .po-rail-name { text-decoration: line-through; color: var(--muted); }
.po-main { display: grid; gap: 1rem; min-width: 0; }
.po-main-head { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.4rem 1.6rem; border-bottom: 1px solid var(--line); }
.po-plan-title { margin: 0 0 0.55rem; font-size: 1.35rem; overflow-wrap: anywhere; }
.po-tabs { display: flex; gap: 1.2rem; }
.po-tab {
  font: inherit; font-size: 0.9rem; font-weight: 600; cursor: pointer; background: transparent; color: var(--ink-soft);
  border: 0; border-bottom: 2px solid transparent; padding: 0.35rem 0 0.55rem; margin-bottom: -1px;
  transition: color 150ms ease-out, border-color 150ms ease-out;
}
.po-tab:hover { color: var(--ink); }
.po-tab[aria-selected="true"] { color: var(--accent); border-bottom-color: var(--accent); }
.po-tabpanel { min-width: 0; }
.po-form { display: grid; gap: 0.9rem; padding: 1.1rem; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; }
.po-includes { display: grid; gap: 0.8rem; }
.po-section-title { margin: 0; font-size: 1rem; }
.po-lines { list-style: none; margin: 0; padding: 0; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; }
.po-line { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--line); }
.po-line:last-child { border-bottom: 0; }
.po-line.is-open { background: var(--accent-soft); }
.po-line.is-hidden .po-line-name { color: var(--muted); }
.po-line-button {
  font: inherit; color: inherit; background: transparent; border: 0; cursor: pointer; text-align: left; padding: 0.2rem 0.25rem; margin: -0.2rem -0.25rem;
  border-radius: 6px; display: inline-flex; gap: 0.5rem; align-items: center; min-width: 0;
}
.po-line-button:hover { background: var(--surface-2); }
.po-line-value { flex: none; }
.po-preview { display: grid; gap: 0.6rem; position: sticky; top: 1rem; }
.po-preview .plan-cards { grid-auto-flow: row; grid-auto-columns: auto; grid-template-columns: minmax(0, 1fr); overflow: visible; }
.po-empty { margin: 0; font-size: 0.9rem; color: var(--muted); }

/* Every plan, side by side below, as the customer reads them: the one being edited is marked, a click on one edits it. */
.po-all { display: grid; gap: 0.4rem; min-width: 0; padding-top: 1.4rem; border-top: 1px solid var(--line); }
#po-all-body { min-width: 0; }
.po-all .plan-cards { padding: 0.8rem 0.1rem 0.6rem; }
.po-all .plan-card { transition: border-color 150ms ease-out, box-shadow 150ms ease-out; }
.po-all .plan-card:hover { border-color: var(--accent); }
.po-all .plan-card.is-editing { border-color: var(--ink); box-shadow: 0 0 0 1px var(--ink); }
.po-pick { position: absolute; inset: 0; z-index: 1; width: 100%; padding: 0; border: 0; border-radius: inherit; background: transparent; cursor: pointer; }
.po-all .plan-card.is-editing .po-pick { cursor: default; }

@media (max-width: 1280px) {
  .po-top { grid-template-columns: 12rem minmax(0, 1fr); }
  .po-preview { position: static; grid-column: 2; }
}
/* Narrower than a panel beside the work: the panel slides over it. */
@media (max-width: 1100px) {
  .pk-shell.has-panel { grid-template-columns: minmax(0, 1fr); }
  .pk-panel { position: fixed; top: 0; right: 0; bottom: 0; width: min(26rem, 100vw); height: auto; z-index: 20; box-shadow: -8px 0 24px rgba(14, 27, 38, 0.18); }
}
@media (max-width: 760px) {
  .po-top { grid-template-columns: minmax(0, 1fr); }
  .po-rail { position: static; }
  .po-rail-list { grid-auto-flow: column; grid-auto-columns: minmax(8rem, max-content); overflow-x: auto; }
  .po-preview { grid-column: auto; }
  .po-main-head { align-items: flex-start; flex-direction: column; }
  .po-plan-title { margin-bottom: 0; }
  .pk-path { margin-left: 0; }
  .pk-savebar { position: static; box-shadow: none; }
  .pk-savebar-inner { align-items: stretch; }
  .pk-why { max-width: none; }
  .pk-primary { width: 100%; }
}
@media (prefers-reduced-motion: reduce) {
  .pk-panel { animation: none; }
  .pk-switch, .pk-switch::after, .po-tab, .po-all .plan-card { transition: none; }
}

/* ── Maestro Benjamin ────────────────────────────────────────────────────────
   Card maestro-benjamin-runs-as-an-add-on-a-tenant-turns-on, step 1 of the
   parity plan Samuel agreed on 2026-10-19: a workspace for running assistants,
   in two arrangements behind a switch (console: cards and a panel with tabs;
   workspace: a rail, the prompt and settings, the chat always beside them).
   The place takes the frame's whole width and lays itself out for the room it
   has, so a narrow side panel and a phone get one column. */
.frame-content:has(.bj-place) { max-width: none; }
.bj-place { container: bj / inline-size; }
.bj-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.6rem 1rem; margin: 0 0 0.9rem; }
.bj-segmented { display: inline-flex; flex-wrap: wrap; gap: 0.2rem; padding: 0.2rem; border-radius: 10px; background: var(--surface-2); }
.bj-segment {
  display: inline-flex; align-items: center; gap: 0.4rem; border: 0; background: transparent; color: var(--ink-soft);
  font: inherit; font-size: 0.82rem; font-weight: 600; padding: 0.4rem 0.8rem; border-radius: 8px; min-height: 2.25rem; cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.bj-segment:hover { color: var(--ink); }
.bj-segment[aria-pressed="true"] { background: var(--surface); color: var(--ink); box-shadow: var(--shadow); }
.bj-segment:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.bj-segment-count { font-size: 0.74rem; font-weight: 500; color: var(--muted); font-variant-numeric: tabular-nums; }
.bj-split { display: grid; grid-template-columns: minmax(15rem, 19rem) minmax(0, 1fr); gap: 1.25rem; align-items: start; }
.bj-list { display: grid; gap: 0.5rem; min-width: 0; }
.bj-list-head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.bj-list-title, .bj-versions-title { margin: 0; font-size: 0.74rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); }

.bj-card {
  display: grid; gap: 0.35rem; text-align: left; font: inherit; color: var(--ink); cursor: pointer;
  padding: 0.8rem 0.9rem; border: 1px solid var(--line); border-radius: 10px; background: var(--surface);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.bj-card:hover { border-color: var(--field-line); }
.bj-card[aria-current="true"] { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.bj-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.bj-card-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.6rem; }
.bj-card-name { font-weight: 600; font-size: 0.95rem; overflow-wrap: anywhere; }
.bj-card-purpose { font-size: 0.8rem; color: var(--muted); }
.bj-card-description { font-size: 0.84rem; color: var(--ink-soft); line-height: 1.45; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.bj-card-meta { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0.15rem; }
.bj-tag { font-size: 0.72rem; color: var(--ink-soft); background: var(--surface-2); border-radius: 99px; padding: 0.1rem 0.5rem; font-variant-numeric: tabular-nums; white-space: nowrap; }

.bj-status { display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.74rem; font-weight: 600; white-space: nowrap; }
.bj-status-active { color: var(--good); }
.bj-status-paused { color: var(--warn); }
.bj-dot { width: 0.5rem; height: 0.5rem; border-radius: 50%; flex: none; background: currentColor; }
.bj-dot-active { background: var(--lp-strategy); }
.bj-dot-paused { background: var(--lp-management); }

.bj-detail, .bj-center, .bj-side { min-width: 0; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); }
.bj-detail, .bj-center { padding: 1.1rem 1.25rem 1.25rem; container: bjpanel / inline-size; }
.bj-detail { min-height: 28rem; }
.bj-side { padding: 0.9rem; position: sticky; top: 0.5rem; }
.bj-detail-inner { display: grid; gap: 0; min-width: 0; }
.bj-head { display: grid; gap: 0.35rem; padding-bottom: 0.8rem; }
.bj-head-title { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.7rem; }
.bj-head-name { margin: 0; font-size: 1.2rem; letter-spacing: -0.01em; overflow-wrap: anywhere; }
.bj-head-description { margin: 0; font-size: 0.9rem; color: var(--ink-soft); line-height: 1.5; max-width: 65ch; }
.bj-head-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem 0.5rem; margin: 0; font-size: 0.8rem; color: var(--muted); }
.bj-head-meta .btn-sm { min-height: 2rem; padding: 0.2rem 0.5rem; }
.bj-slug { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.78rem; background: var(--surface-2); color: var(--ink-soft); border-radius: 5px; padding: 0.1rem 0.4rem; overflow-wrap: anywhere; }

.bj-tabs { display: flex; gap: 0.25rem; border-bottom: 1px solid var(--line); overflow-x: auto; }
.bj-tab {
  border: 0; background: transparent; color: var(--ink-soft); font: inherit; font-size: 0.88rem; font-weight: 600; cursor: pointer;
  padding: 0.55rem 0.9rem; min-height: 2.75rem; border-bottom: 2px solid transparent; margin-bottom: -1px; white-space: nowrap;
}
.bj-tab:hover { color: var(--ink); }
.bj-tab[aria-selected="true"] { color: var(--ink); border-bottom-color: var(--accent); }
.bj-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 6px 6px 0 0; }
.bj-tab-panel { padding-top: 1rem; min-width: 0; }

/* The chat: what a customer would see, and under each answer what it stood on. */
.bj-chat { display: grid; grid-template-rows: auto minmax(0, 1fr); gap: 0.6rem; height: clamp(26rem, 64vh, 46rem); min-width: 0; }
.bj-chat-head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.bj-chat-title { margin: 0; font-weight: 600; font-size: 0.9rem; }
.bj-log {
  list-style: none; margin: 0; padding: 0.9rem; overflow-y: auto; display: flex; flex-direction: column; gap: 0.9rem;
  background: var(--bg); border: 1px solid var(--line); border-radius: 10px; min-height: 0;
}
.bj-message { display: grid; gap: 0.3rem; max-width: min(38rem, 88%); }
.bj-message-user { align-self: flex-end; justify-items: end; }
.bj-message-assistant { align-self: flex-start; }
.bj-message-system { align-self: center; justify-items: center; max-width: 100%; text-align: center; }
.bj-bubble { padding: 0.6rem 0.85rem; border-radius: 14px; line-height: 1.5; font-size: 0.92rem; overflow-wrap: anywhere; white-space: pre-wrap; }
.bj-message-user .bj-bubble { background: var(--accent); color: var(--on-accent); border-bottom-right-radius: 4px; }
.bj-message-assistant .bj-bubble { background: var(--surface); color: var(--ink); border: 1px solid var(--line); border-bottom-left-radius: 4px; }
.bj-answer { white-space: normal; }
.bj-answer p { margin: 0 0 0.5rem; }
.bj-answer > :last-child { margin-bottom: 0; }
.bj-answer ul, .bj-answer ol { margin: 0.2rem 0 0.5rem; padding-left: 1.2rem; }
.bj-answer li + li { margin-top: 0.15rem; }
.bj-answer code { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.85em; background: var(--surface-2); border-radius: 4px; padding: 0 0.3rem; }
.bj-answer pre { margin: 0 0 0.5rem; background: var(--surface-2); border-radius: 8px; padding: 0.6rem 0.75rem; overflow-x: auto; }
.bj-answer pre code { background: none; padding: 0; }
.bj-answer blockquote { margin: 0.2rem 0 0.5rem; padding-left: 0.65rem; border-left: 2px solid var(--line); color: var(--ink-soft); }
.bj-answer a { color: var(--accent); }
/* Under an answer, small chips for what it stood on; each opens its detail on a click. */
.bj-trace { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.bj-trace[hidden] { display: none; }
.bj-chip {
  font: inherit; font-size: 0.72rem; font-weight: 600; color: var(--muted); font-variant-numeric: tabular-nums; cursor: pointer;
  background: transparent; border: 1px solid var(--line); border-radius: 99px; padding: 0.15rem 0.6rem; min-height: 1.6rem;
  max-width: 14rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bj-chip:hover:not(:disabled) { color: var(--ink); border-color: var(--ink-soft); }
.bj-chip[aria-expanded="true"] { color: var(--accent); background: var(--accent-soft); border-color: transparent; }
.bj-chip:disabled { cursor: default; opacity: 0.7; }
.bj-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.bj-chip-detail {
  margin: 0; padding: 0.55rem 0.7rem; border: 1px solid var(--line); border-radius: 8px; background: var(--surface);
  font-size: 0.8rem; color: var(--ink-soft); font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}
.bj-chip-pages { list-style: none; display: grid; gap: 0.6rem; max-height: 16rem; overflow-y: auto; overscroll-behavior: contain; }
.bj-chip-page-title { margin: 0 0 0.15rem; font-weight: 600; color: var(--ink); }
.bj-chip-page-text { margin: 0; white-space: pre-wrap; line-height: 1.45; }
.bj-chip-model { font-family: ui-monospace, "SF Mono", Menlo, monospace; }
.bj-writing { display: inline-flex; gap: 0.3rem; align-items: center; padding: 0.8rem 0.95rem; }
.bj-writing-dot { width: 0.4rem; height: 0.4rem; border-radius: 50%; background: var(--muted); animation: bj-pulse 1.2s ease-in-out infinite; }
.bj-writing-dot:nth-child(2) { animation-delay: 0.15s; }
.bj-writing-dot:nth-child(3) { animation-delay: 0.3s; }
@keyframes bj-pulse { 0%, 80%, 100% { opacity: 0.35; transform: translateY(0); } 40% { opacity: 1; transform: translateY(-2px); } }
.bj-chat-error { margin: 0 0 0.3rem; color: var(--bad); font-size: 0.86rem; }
.bj-composer { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0.5rem; align-items: end; }
.bj-composer-input { min-height: 2.75rem; max-height: 9rem; resize: none; line-height: 1.4; field-sizing: content; }
.bj-paused-note { margin: 0; padding: 0.7rem 0.9rem; border-radius: 8px; background: var(--warn-soft); color: var(--warn); font-size: 0.88rem; font-weight: 600; }
.bj-chat-actions { display: flex; flex-wrap: wrap; gap: 0.35rem; justify-content: flex-end; }
.bj-chat-body { display: grid; grid-template-rows: minmax(0, 1fr) auto; gap: 0.6rem; min-height: 0; }

/* Every conversation the assistant had, newest first. */
.bj-conversations { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.25rem; align-content: start; overflow-y: auto; min-height: 0; }
.bj-conversation {
  width: 100%; display: grid; gap: 0.15rem; text-align: left; font: inherit; color: var(--ink); cursor: pointer;
  padding: 0.55rem 0.65rem; border-radius: 8px; border: 1px solid transparent; background: transparent;
}
.bj-conversation:hover { background: var(--surface-2); }
.bj-conversation[aria-current="true"] { background: var(--surface-2); border-color: var(--line); }
.bj-conversation:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.bj-conversation-question { font-size: 0.86rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bj-conversation-meta { font-size: 0.72rem; color: var(--muted); font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* The prompt: every version on the left, the one open on the right. */
.bj-prompt { display: grid; grid-template-columns: minmax(11rem, 14rem) minmax(0, 1fr); gap: 1.1rem; align-items: start; }
.bj-versions { display: grid; gap: 0.5rem; min-width: 0; }
.bj-version-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.25rem; }
.bj-version {
  width: 100%; display: grid; gap: 0.1rem; text-align: left; font: inherit; color: var(--ink); cursor: pointer;
  padding: 0.5rem 0.6rem; border-radius: 8px; border: 1px solid transparent; background: transparent;
}
.bj-version:hover { background: var(--surface-2); }
.bj-version[aria-current="true"] { background: var(--surface-2); border-color: var(--line); }
.bj-version:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.bj-version-top { display: flex; align-items: center; justify-content: space-between; gap: 0.4rem; }
.bj-version-number { font-weight: 700; font-size: 0.82rem; font-variant-numeric: tabular-nums; }
.bj-in-force { font-size: 0.68rem; font-weight: 700; color: var(--good); background: var(--good-soft); border-radius: 99px; padding: 0.05rem 0.45rem; }
.bj-version-label { font-size: 0.84rem; color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bj-version-by { font-size: 0.72rem; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bj-editor { display: grid; gap: 0.75rem; min-width: 0; }
.bj-editor-head { display: grid; gap: 0.2rem; }
.bj-editor-title { margin: 0; font-weight: 600; font-size: 0.95rem; }
.bj-prompt-text { min-height: 22rem; height: 52vh; resize: vertical; font-size: 0.92rem; line-height: 1.6; }
.bj-readonly { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; background: var(--surface-2); color: var(--ink); border-radius: 8px; padding: 0.9rem 1rem; max-height: 52vh; overflow: auto; font-size: 0.92rem; line-height: 1.6; }
.bj-readonly:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.bj-version-note { margin: 0; font-size: 0.86rem; color: var(--ink-soft); }
.bj-diff { border: 1px solid var(--line); border-radius: 8px; max-height: 52vh; overflow: auto; font-size: 0.86rem; line-height: 1.55; padding: 0.4rem 0; }
.bj-diff-legend { display: flex; flex-wrap: wrap; gap: 0.4rem 1rem; margin: 0 0.6rem 0.4rem; font-size: 0.76rem; color: var(--muted); }
.bj-diff-added-key::before, .bj-diff-removed-key::before { content: ""; display: inline-block; width: 0.65rem; height: 0.65rem; border-radius: 3px; margin-right: 0.35rem; vertical-align: -0.05rem; }
.bj-diff-added-key::before { background: var(--good-soft); box-shadow: inset 0 0 0 1px var(--good); }
.bj-diff-removed-key::before { background: var(--bad-soft); box-shadow: inset 0 0 0 1px var(--bad); }
.bj-diff-line { display: grid; grid-template-columns: 1.4rem minmax(0, 1fr); padding: 0 0.6rem; white-space: pre-wrap; overflow-wrap: anywhere; }
.bj-diff-added { background: var(--good-soft); }
.bj-diff-removed { background: var(--bad-soft); }
.bj-diff-mark { color: var(--muted); font-family: ui-monospace, "SF Mono", Menlo, monospace; }

/* Settings, in groups a person reads top to bottom. */
.bj-settings { display: grid; gap: 1.2rem; max-width: 42rem; }
.bj-group { display: grid; gap: 0.8rem; padding-bottom: 1.15rem; border-bottom: 1px solid var(--line); }
.bj-group-title { margin: 0; font-size: 0.95rem; }
.bj-group-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem; }
.bj-field { display: grid; gap: 0.3rem; min-width: 0; }
.bj-label { font-size: 0.82rem; font-weight: 600; color: var(--ink-soft); }
.bj-hint { margin: 0; font-size: 0.8rem; color: var(--muted); line-height: 1.45; max-width: 65ch; }
.bj-pair { display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); gap: 0.8rem; }
.bj-textarea { resize: vertical; line-height: 1.45; }
.bj-choices { border: 0; margin: 0; padding: 0; display: grid; gap: 0.4rem; }
.bj-choice { display: flex; align-items: flex-start; gap: 0.6rem; padding: 0.55rem 0.65rem; border: 1px solid var(--line); border-radius: 8px; cursor: pointer; transition: border-color 0.15s ease, background 0.15s ease; }
.bj-choice:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.bj-choice input { width: 1.05rem; height: 1.05rem; margin: 0.1rem 0 0; flex: none; }
.bj-choice-text { display: grid; gap: 0.1rem; min-width: 0; }
.bj-choice-name { font-weight: 600; font-size: 0.88rem; }
.bj-choice-description { font-size: 0.78rem; color: var(--muted); }
.bj-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; }
.bj-actions .btn[aria-pressed="true"] { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
.bj-settings > .bj-actions { position: sticky; bottom: 0; z-index: 1; background: var(--surface); padding: 0.75rem 0; margin-top: -0.4rem; border-top: 1px solid var(--line); }
.bj-field > .bj-segmented { justify-self: start; }
.bj-archive { margin-left: auto; color: var(--bad); }
.bj-confirm { margin-left: auto; display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; font-size: 0.84rem; color: var(--ink-soft); }
.bj-new { max-width: 46rem; }

/* The workspace: a rail of assistants, the prompt and settings, and the chat beside them. */
.bj-workspace { display: grid; grid-template-columns: minmax(11rem, 13rem) minmax(0, 1fr) minmax(18rem, 23rem); gap: 1rem; align-items: start; }
.bj-workspace-single { grid-template-columns: minmax(11rem, 13rem) minmax(0, 1fr); }
.bj-rail { display: grid; gap: 0.15rem; position: sticky; top: 0.5rem; min-width: 0; }
.bj-rail .bj-list-head { margin-bottom: 0.35rem; }
.bj-row { display: flex; align-items: center; gap: 0.55rem; width: 100%; min-height: 2.6rem; text-align: left; font: inherit; color: var(--ink); cursor: pointer; padding: 0.4rem 0.55rem; border: 0; border-radius: 8px; background: transparent; }
.bj-row:hover, .bj-row[aria-current="true"] { background: var(--surface-2); }
.bj-row[aria-current="true"] .bj-row-name { font-weight: 600; }
.bj-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.bj-row-text { display: grid; min-width: 0; }
.bj-row-name { font-size: 0.88rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bj-row-purpose { font-size: 0.74rem; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.bj-empty { display: grid; justify-items: start; gap: 0.5rem; padding: 2rem 1.5rem; border: 1px dashed var(--line); border-radius: 12px; }
.bj-detail .bj-empty, .bj-center .bj-empty { border: 0; padding: 1rem 0.25rem; }
.bj-empty-title { margin: 0; font-weight: 600; font-size: 1rem; }
.bj-loading { display: grid; gap: 0.6rem; grid-template-columns: minmax(15rem, 19rem) minmax(0, 1fr); }
.bj-skeleton { display: block; height: 9rem; border-radius: 12px; background: var(--surface-2); animation: bj-breathe 1.4s ease-in-out infinite; }
@keyframes bj-breathe { 50% { opacity: 0.55; } }

.bj-sources { list-style: none; margin: 0.4rem 0 1.2rem; padding: 0; display: grid; gap: 0.4rem; }
.bj-source { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; padding: 0.55rem 0.75rem; border: 1px solid var(--line); border-radius: 8px; }
.bj-source-title { flex: 1 1 12rem; min-width: 0; font-weight: 600; font-size: 0.88rem; overflow-wrap: anywhere; }
.bj-new-base { display: grid; gap: 0.5rem; margin-top: 0.4rem; padding: 0.9rem; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); }
.bj-add-source { margin-top: 0.4rem; padding-top: 0.9rem; border-top: 1px solid var(--line); }
.bj-number { max-width: 8rem; font-variant-numeric: tabular-nums; }
.bj-sampling { max-width: 22rem; }

@media (prefers-reduced-motion: reduce) {
  .bj-writing-dot, .bj-skeleton { animation: none; }
}

/* The room a panel has: a narrow one puts the versions in a strip above the editor. */
@container bjpanel (max-width: 44rem) {
  .bj-prompt { grid-template-columns: minmax(0, 1fr); }
  .bj-version-list { display: flex; overflow-x: auto; gap: 0.35rem; padding-bottom: 0.2rem; }
  .bj-version { min-width: 10rem; border-color: var(--line); }
}
/* The room the place has, not the window's: the chat goes under the prompt, then one column. */
@container bj (max-width: 66rem) {
  .bj-workspace { grid-template-columns: minmax(11rem, 13rem) minmax(0, 1fr); }
  .bj-side { grid-column: 2; position: static; }
}
@container bj (max-width: 46rem) {
  .bj-split, .bj-workspace, .bj-workspace-single, .bj-loading, .bj-prompt { grid-template-columns: minmax(0, 1fr); }
  .bj-side { grid-column: auto; }
  .bj-rail { position: static; display: flex; gap: 0.35rem; overflow-x: auto; padding-bottom: 0.2rem; }
  .bj-rail .bj-list-head { flex: none; margin: 0; }
  .bj-rail .bj-list-title { display: none; }
  .bj-row { width: auto; flex: none; max-width: 14rem; border: 1px solid var(--line); }
  .bj-version-list { display: flex; overflow-x: auto; gap: 0.35rem; }
  .bj-version { min-width: 10rem; border-color: var(--line); }
  .bj-detail, .bj-center { padding: 0.9rem; min-height: 0; }
  .bj-chat { height: clamp(24rem, 72vh, 40rem); }
  .bj-message { max-width: 92%; }
  .bj-prompt-text { height: 45vh; min-height: 16rem; }
}

/* ── The company's agents, drawn (card you-draw-the-companys-agents-and-what-
   each-hands-on). Dense, exact and quiet: the reference is Palantir Gotham,
   "nada de N8N-like". Lanes per department, flows inside, agents in columns
   by their hand-offs; one line weight, the pyramid's hues as marks only. */
.agents-screen { padding-top: 0.6rem; }
.agents-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.6rem 1rem; margin-bottom: 0.6rem; }
.agents-head .frame-title { margin: 0; }
.agents-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.agents-scope { min-height: 2.1rem; padding: 0.25rem 0.6rem; font-size: 0.86rem; max-width: 20rem; width: auto; }
.agents-zoom { display: inline-flex; align-items: center; gap: 0.25rem; }
.agents-zoom-level { min-width: 3.2rem; text-align: center; font-size: 0.8rem; color: var(--ink-soft); }
.agents-add { position: relative; }
.agents-add > summary { list-style: none; display: inline-flex; align-items: center; gap: 0.3rem; cursor: pointer; }
.agents-add > summary::-webkit-details-marker { display: none; }
.agents-add-menu { position: absolute; right: 0; top: calc(100% + 0.3rem); z-index: 7; min-width: 11rem; display: grid; padding: 0.3rem; background: var(--surface); border: 1px solid var(--line); border-radius: 8px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18); }
.agents-add-item { text-align: left; background: none; border: 0; padding: 0.45rem 0.6rem; border-radius: 6px; font: inherit; font-size: 0.88rem; color: var(--ink); cursor: pointer; }
.agents-add-item:hover, .agents-add-item:focus-visible { background: var(--surface-2); }
.agents-message { margin: 0 0 0.6rem; font-size: 0.86rem; }
.agents-message-error { color: var(--bad); }
.agents-message-note { color: var(--ink-soft); }

.agents-body { display: grid; grid-template-columns: minmax(0, 1fr) 20rem; gap: 0.8rem; align-items: stretch; height: calc(100vh - var(--frame-bar, 3rem) - 7.5rem); min-height: 26rem; }
[data-pane="narrow"] .agents-body { grid-template-columns: minmax(0, 1fr); height: auto; }
[data-pane="narrow"] .agents-canvas { height: 24rem; }
.agents-canvas { position: relative; overflow: hidden; border: 1px solid var(--line); border-radius: 10px; background: var(--bg); background-image: radial-gradient(var(--line) 0.8px, transparent 0.9px); background-size: 20px 20px; cursor: grab; outline: none; }
.agents-canvas:focus-visible { box-shadow: inset 0 0 0 2px var(--accent); }
.agents-canvas.is-panning { cursor: grabbing; }
.agents-world { position: absolute; left: 0; top: 0; transform-origin: 0 0; will-change: transform; }
.agents-empty { position: absolute; left: 1.2rem; top: 1rem; margin: 0; font-size: 0.9rem; color: var(--ink-soft); }

.agents-lane { position: absolute; box-sizing: border-box; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); }
.agents-lane.is-selected { border-color: var(--accent); }
.agents-lane-head { position: absolute; left: 0; top: 0; right: 0; height: 34px; display: flex; align-items: center; gap: 0.6rem; padding: 0 0.9rem; background: none; border: 0; border-bottom: 1px solid var(--line); font: inherit; color: var(--ink); cursor: pointer; text-align: left; }
.agents-lane-name { font-size: 0.74rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; }
.agents-lane-count { margin-left: auto; font-size: 0.72rem; color: var(--muted); }
.agents-lane-empty, .agents-flow-empty { position: absolute; margin: 0; font-size: 0.8rem; color: var(--muted); }
.agents-lane-empty { left: 0.9rem; top: 46px; }
.agents-flow-empty { left: 18px; top: 36px; }

.agents-flow { position: absolute; box-sizing: border-box; border: 1px dashed var(--field-line); border-radius: 6px; background: var(--band); }
.agents-flow.is-selected { border-color: var(--accent); border-style: solid; }
.agents-flow-head { position: absolute; left: 0; top: 0; right: 0; height: 30px; display: flex; align-items: center; padding: 0 0.8rem; background: none; border: 0; font: inherit; font-size: 0.8rem; font-weight: 600; color: var(--ink-soft); cursor: pointer; text-align: left; }
.agents-flow-head:hover, .agents-lane-head:hover { color: var(--accent); }

.agents-edges { position: absolute; left: 0; top: 0; overflow: visible; pointer-events: none; }
.agents-edges marker path { fill: var(--ink-soft); }
.agents-edge-line { fill: none; stroke: var(--ink-soft); stroke-width: 1.2; }
.agents-edge.is-crossing .agents-edge-line { stroke-dasharray: 4 3; }
.agents-edge.is-selected .agents-edge-line { stroke: var(--accent); stroke-width: 2; }
.agents-edge-hit { fill: none; stroke: transparent; stroke-width: 14; pointer-events: stroke; cursor: pointer; }
.agents-edge-label { font-size: 11px; fill: var(--ink-soft); paint-order: stroke; stroke: var(--surface); stroke-width: 4px; stroke-linejoin: round; pointer-events: all; cursor: pointer; }
.agents-edge.is-selected .agents-edge-label { fill: var(--accent); font-weight: 600; }

.agents-node { position: absolute; box-sizing: border-box; display: grid; align-content: start; gap: 0.3rem; padding: 0.55rem 0.7rem; background: var(--surface); border: 1px solid var(--field-line); border-left: 3px solid var(--lp-engineering); border-radius: 6px; font: inherit; color: var(--ink); text-align: left; cursor: pointer; box-shadow: var(--shadow); }
.agents-node:hover { border-color: var(--accent); }
.agents-node.is-selected { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft), var(--shadow); }
.agents-node:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.agents-node-name { font-size: 0.9rem; font-weight: 600; line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.agents-node-meta { display: flex; align-items: center; gap: 0.4rem; min-width: 0; font-size: 0.74rem; color: var(--muted); }
.agents-node-skill { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.agents-node-systems { margin-left: auto; padding: 0 0.35rem; border: 1px solid var(--line); border-radius: 99px; font-size: 0.68rem; }
.agents-node.is-ghost { border-style: dashed; border-left-width: 1px; background: transparent; color: var(--ink-soft); box-shadow: none; padding: 0.4rem 0.6rem; }
.agents-node.is-ghost .agents-node-name { font-size: 0.8rem; font-weight: 600; }
.agents-node-flow { font-size: 0.7rem; color: var(--muted); }
.agents-runs { flex: none; padding: 0 0.3rem; border-radius: 3px; font-size: 0.62rem; font-weight: 700; letter-spacing: 0.06em; color: var(--on-mark); background: var(--lp-engineering); }
.agents-runs-benjamin { background: var(--lp-management); }
.agents-runs-person { background: var(--lp-strategy); }
.agents-runs-system { background: var(--muted); color: var(--surface); }

.agents-side { box-sizing: border-box; overflow: auto; padding: 0.9rem 1rem; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); }
.agents-side-kind { margin: 0; font-size: 0.7rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
.agents-side-title { margin: 0.2rem 0 0.8rem; font-size: 1.05rem; line-height: 1.25; overflow-wrap: anywhere; }
.agents-side-sub { margin: 1.2rem 0 0.4rem; font-size: 0.74rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
.agents-rows { display: grid; gap: 0.7rem; }
.agents-row { display: grid; gap: 0.15rem; }
.agents-row-label { font-size: 0.72rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); }
.agents-row-value { font-size: 0.88rem; line-height: 1.45; white-space: pre-wrap; overflow-wrap: anywhere; }
.agents-muted { color: var(--muted); }
.agents-note { margin: 0.8rem 0 0; font-size: 0.78rem; line-height: 1.4; }
.agents-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.2rem; }
.agents-link { background: none; border: 0; padding: 0; font: inherit; font-size: 0.86rem; color: var(--accent); text-align: left; cursor: pointer; overflow-wrap: anywhere; }
.agents-link:hover { text-decoration: underline; }
.agents-actions { margin-top: 1rem; }
.agents-form { margin-top: 0; padding-top: 0; border-top: 0; max-width: none; gap: 0.6rem; }
.agents-form .tenant-input, .agents-form .tenant-select { min-height: 2.3rem; padding: 0.4rem 0.6rem; font-size: 0.88rem; }
.agents-textarea { resize: vertical; line-height: 1.4; }
.agents-counts { display: grid; grid-template-columns: 1fr auto; gap: 0.25rem 1rem; margin: 0; font-size: 0.86rem; }
.agents-counts dt { color: var(--ink-soft); }
.agents-counts dd { margin: 0; text-align: right; font-weight: 600; }
.agents-skills { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.25rem; }
.agents-skill { display: flex; align-items: center; gap: 0.5rem; width: 100%; padding: 0.4rem 0.5rem; background: none; border: 1px solid transparent; border-radius: 6px; font: inherit; font-size: 0.86rem; color: var(--ink); text-align: left; cursor: pointer; }
.agents-skill:hover, .agents-skill:focus-visible { border-color: var(--line); background: var(--surface-2); }
.agents-skill-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.agents-skill-count { font-size: 0.74rem; color: var(--muted); }
.agents-deploy { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.8rem; margin: 0 0 0.8rem; padding: 0.55rem 0.8rem; border: 1px solid var(--line); border-radius: 8px; background: var(--surface-2); font-size: 0.86rem; color: var(--ink); }
.agents-deploy.is-ahead { border-color: var(--accent); }
.agents-deploy-line { margin: 0; flex: 1 1 18rem; min-width: 0; }
.agents-deploy-list { flex-basis: 100%; order: 3; margin: 0; padding-left: 1.1rem; font-size: 0.8rem; color: var(--ink-soft); }
.agents-node-state { font-size: 0.68rem; padding: 0 0.3rem; border-radius: 4px; border: 1px solid var(--line); color: var(--muted); white-space: nowrap; }
.agents-node-state.is-ahead { border-color: var(--accent); color: var(--ink); }
.agents-node.is-draft { border-style: dashed; }
.agents-node.is-ahead { border-color: var(--accent); }
.agents-review .agents-list { margin: 0; padding-left: 1rem; font-size: 0.82rem; color: var(--ink-soft); }
.agents-installed { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.25rem; }
.agents-installed-all { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.25rem 0 0.5rem; }
.agents-installed-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 0.1rem 0.5rem; padding: 0.35rem 0.5rem; border-bottom: 1px solid var(--line); font-size: 0.86rem; color: var(--ink); }
.agents-installed-row .agents-skill-name { grid-column: 1 / -1; white-space: normal; }
.agents-installed-state { font-size: 0.74rem; color: var(--muted); }

/* The company view: flow cards, and the hand-offs between flows drawn once each. */
.agents-card { position: absolute; box-sizing: border-box; display: grid; grid-template-rows: auto 1fr; border: 1px solid var(--line); border-radius: 6px; background: var(--surface); box-shadow: var(--shadow); overflow: hidden; }
.agents-card.is-selected { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft), var(--shadow); }
.agents-card-head { display: flex; align-items: center; gap: 0.5rem; height: 44px; padding: 0 0.75rem; background: var(--surface-2); border: 0; border-bottom: 1px solid var(--line); font: inherit; color: var(--ink); text-align: left; cursor: pointer; }
.agents-card-head:hover .agents-card-name { color: var(--accent); }
.agents-card-name { flex: 1; min-width: 0; font-size: 0.86rem; font-weight: 700; letter-spacing: 0.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.agents-card-count { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.72rem; color: var(--muted); }
.agents-card-rows { list-style: none; margin: 0; padding: 5px 0; }
.agents-card-row { display: flex; align-items: center; gap: 0.5rem; width: 100%; height: 22px; padding: 0 0.75rem; background: none; border: 0; font: inherit; font-size: 0.8rem; color: var(--ink); text-align: left; cursor: pointer; }
.agents-card-row:hover { background: var(--surface-2); }
.agents-card-row.is-selected { background: var(--accent-soft); color: var(--accent); }
.agents-card-row-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.agents-card-row-systems { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.68rem; color: var(--muted); }
.agents-card-empty { margin: 0; padding: 0.6rem 0.75rem; font-size: 0.78rem; color: var(--muted); }
.agents-edge-between .agents-edge-line { stroke: var(--field-line); stroke-width: 1; }
.agents-edge-between .agents-edge-label { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 10px; fill: var(--muted); }

/* Who runs a skill, as a mark: one square, one hue, the pyramid's; the legend on the side says the words. */
.agents-mark { flex: none; width: 7px; height: 7px; border-radius: 1px; background: var(--lp-engineering); }
.agents-mark-benjamin { background: var(--lp-management); }
.agents-mark-person { background: var(--lp-strategy); }
.agents-mark-system { background: var(--muted); }
.agents-mark-none { background: transparent; box-shadow: inset 0 0 0 1px var(--field-line); }
.agents-legend { list-style: none; margin: 0.8rem 0 0; padding: 0.6rem 0 0; border-top: 1px solid var(--line); display: grid; gap: 0.3rem; font-size: 0.78rem; color: var(--ink-soft); }
.agents-legend li { display: flex; align-items: center; gap: 0.5rem; }

/* The graph view's nodes, tightened: a hairline, the name, a mono meta line. */
.agents-node { gap: 0.25rem; padding: 0.5rem 0.65rem; border-left-width: 1px; border-color: var(--line); box-shadow: none; }
.agents-node::before { content: ""; position: absolute; left: 0; top: 8px; bottom: 8px; width: 2px; background: var(--lp-engineering); opacity: 0.9; }
.agents-node.is-ghost::before { display: none; }
.agents-node-name { font-size: 0.84rem; }
.agents-node-meta { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.68rem; letter-spacing: 0.01em; }
.agents-node-systems { border: 0; padding: 0; }
.agents-lane { background: transparent; border-color: var(--line); }
.agents-lane-head { border-bottom-color: var(--line); }
.agents-lane-count { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.agents-flow { background: color-mix(in srgb, var(--surface) 60%, transparent); }
.agents-edge-line { stroke-width: 1; }
.agents-node-tag { flex: none; padding: 0 0.3rem; border: 1px solid var(--field-line); border-radius: 3px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.62rem; letter-spacing: 0.04em; color: var(--ink-soft); }

/* The company view: every value stream as a chain of compact nodes. */
.agents-node.is-compact { display: flex; align-items: center; gap: 0.45rem; padding: 0 0.55rem; border-left-width: 1px; }
.agents-node.is-compact::before { display: none; }
.agents-node.is-compact .agents-node-name { font-size: 0.74rem; font-weight: 500; }
.agents-node.is-compact .agents-node-tag { margin-left: auto; }

/* The company's brand, a place of the flow (card you-see-your-brand-on-one-page-with-where-each-fact-came-from):
   the 8 steps of the brand, each value with where it came from and whether a person confirmed it. */
.brand-content { max-width: 64rem; }
.brand-summary { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem 1rem; margin: 0 0 0.8rem; }
.brand-summary-number { font-size: 1.05rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.brand-summary-confirmed { color: var(--good); }
.brand-summary .brand-meter { width: 9rem; }
.brand-file-meta { font-size: 0.8rem; color: var(--muted); overflow-wrap: anywhere; }
.brand-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; margin: 0 0 1rem; font-size: 0.8rem; color: var(--muted); }
.brand-chip { display: inline-flex; align-items: center; border-radius: 999px; padding: 0.05rem 0.55rem; font-size: 0.72rem; font-weight: 700; background: var(--surface-2); color: var(--ink-soft); white-space: nowrap; }
.brand-origin-site { background: var(--accent-soft); color: var(--accent); }
.brand-origin-document { background: var(--dep-soft); color: var(--dep); }
.brand-origin-research { background: var(--warn-soft); color: var(--warn); }
.brand-origin-person { background: var(--good-soft); color: var(--good); }
.brand-suggestion { background: transparent; color: var(--warn); border: 1px dashed var(--warn); }
.brand-meter { display: flex; height: 0.35rem; border-radius: 0.2rem; background: var(--surface-2); overflow: hidden; }
.brand-meter i { display: block; height: 100%; }
.brand-meter-confirmed { background: var(--lp-strategy); }
.brand-meter-filled { background: var(--lp-management); opacity: 0.55; }
.brand-steps-nav { display: grid; grid-template-columns: repeat(auto-fill, minmax(12.5rem, 1fr)); gap: 0.4rem; margin: 0 0 1.2rem; }
.brand-step-link { display: grid; grid-template-columns: 1.4rem minmax(0, 1fr) auto; gap: 0.15rem 0.4rem; align-items: center; text-align: left; padding: 0.5rem 0.6rem; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); color: var(--ink); cursor: pointer; font: inherit; font-size: 0.84rem; }
.brand-step-link:hover { border-color: var(--accent); }
.brand-step-link .brand-meter { grid-column: 2 / 4; }
.brand-step-n { font-weight: 700; color: var(--muted); font-variant-numeric: tabular-nums; }
.brand-step-pc { font-size: 0.78rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.brand-step { padding: 0.2rem 0 1rem; border-top: 1px solid var(--line); scroll-margin-top: 4.5rem; }
.brand-step-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.2rem 1rem; }
.brand-step-score { font-size: 0.8rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.brand-step-note { margin: 0.2rem 0 0.6rem; font-size: 0.88rem; color: var(--ink-soft); }
.brand-fields { display: grid; gap: 0.1rem; margin: 0; }
.brand-field { display: grid; grid-template-columns: minmax(10rem, 14rem) minmax(0, 1fr); gap: 0.15rem 1rem; padding: 0.5rem 0; border-bottom: 1px dashed var(--line); }
.brand-field:last-child { border-bottom: 0; }
.brand-label { font-size: 0.84rem; color: var(--muted); padding-top: 0.1rem; }
.brand-value { margin: 0; min-width: 0; display: grid; gap: 0.3rem; }
.brand-text { overflow-wrap: anywhere; line-height: 1.5; }
.brand-empty { color: var(--muted); font-style: italic; }
.brand-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem 0.5rem; font-size: 0.76rem; color: var(--muted); }
.brand-source { color: var(--accent); overflow-wrap: anywhere; }
.brand-date { font-variant-numeric: tabular-nums; }
.brand-tags { display: flex; flex-wrap: wrap; gap: 0.3rem; margin: 0; padding: 0; list-style: none; }
.brand-tag { background: var(--surface-2); border-radius: 6px; padding: 0.1rem 0.55rem; font-size: 0.86rem; }
.brand-edit { display: grid; gap: 0.4rem; }
.brand-edit-value { width: 100%; min-width: 0; box-sizing: border-box; font: inherit; padding: 0.45rem 0.6rem; border: 1px solid var(--field-line); border-radius: 6px; background: var(--field); color: var(--ink); }
.brand-edit-hint { font-size: 0.76rem; color: var(--muted); }
.brand-actions { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.brand-table-wrap { overflow-x: auto; }
.brand-price { font-variant-numeric: tabular-nums; white-space: nowrap; }
.brand-swatches { display: flex; flex-wrap: wrap; gap: 0.8rem; margin: 0.4rem 0 0; padding: 0; list-style: none; }
.brand-swatch { display: grid; gap: 0.15rem; font-size: 0.8rem; }
.brand-swatch-color { display: block; width: 5.5rem; height: 3.2rem; border-radius: 8px; border: 1px solid var(--line); }
.brand-swatch-hex { color: var(--muted); font-variant-numeric: tabular-nums; }
.brand-documents, .brand-missing-list { display: grid; gap: 0.3rem; margin: 0.4rem 0 0; padding: 0; list-style: none; }
.brand-documents li, .brand-missing-list li { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.2rem 1rem; font-size: 0.88rem; }
.brand-missing-step { font-size: 0.78rem; color: var(--muted); }
.brand-link { background: none; border: 0; padding: 0; color: var(--accent); cursor: pointer; font: inherit; text-align: left; text-decoration: underline; }
.brand-raw { max-height: 60vh; overflow: auto; }
.brand-none { padding: 1rem 0; }
@media (max-width: 600px) {
  .brand-field { grid-template-columns: minmax(0, 1fr); }
  .brand-steps-nav { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* The legal documents admin (card the-legal-pack-exists): one section per
   document, its form closed until New version is pressed. */
.legal-admin-doc { margin: 0 0 2rem; padding: 0 0 1.2rem; border-bottom: 1px solid var(--line); }
.legal-admin-doc h2 { font-size: 1.15rem; margin: 0 0 0.4rem; }
.legal-admin-form { display: grid; gap: 0.8rem; margin-top: 0.8rem; }
.legal-admin-field { display: grid; gap: 0.3rem; font-size: 0.9rem; color: var(--ink-soft); }
.legal-admin-field textarea {
  font: inherit; font-size: 0.85rem; width: 100%; box-sizing: border-box; padding: 0.5rem 0.6rem;
  background: var(--field); color: var(--ink); border: 1px solid var(--field-line); border-radius: 6px;
}

/* The tenant's CRM, a place of the flow (card crm-a-tenant-turns-on-the-crm-and-its-data-stays-its-own). */
.crm-tabs { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.8rem 0 1rem; }
.crm-tab { border: 1px solid var(--line); background: var(--surface); color: var(--ink-soft); border-radius: 999px; padding: 0.3rem 0.85rem; font: inherit; font-size: 0.86rem; cursor: pointer; }
.crm-tab.is-active { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); font-weight: 600; }
.crm-open-form, .crm-back { margin: 0 0 0.8rem; }
.crm-form { display: grid; gap: 0.6rem; max-width: 32rem; margin: 0 0 1rem; padding: 0.9rem; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); }
.crm-field { display: grid; gap: 0.25rem; font-size: 0.86rem; color: var(--ink-soft); }
.crm-field input { font: inherit; color: var(--ink); background: var(--field); border: 1px solid var(--field-line); border-radius: 6px; padding: 0.4rem 0.55rem; }
.crm-form-actions { display: flex; gap: 0.5rem; }
.crm-table { width: 100%; }
.crm-link { border: 0; background: none; padding: 0; font: inherit; color: var(--accent); cursor: pointer; text-align: left; }
.crm-link:hover, .crm-link:focus-visible { text-decoration: underline; }
.crm-facts { display: grid; grid-template-columns: max-content 1fr; gap: 0.3rem 1rem; margin: 0.5rem 0 1rem; font-size: 0.9rem; }
.crm-facts dt { color: var(--muted); }
.crm-facts dd { margin: 0; color: var(--ink); overflow-wrap: anywhere; }
.crm-heading { margin: 1rem 0 0.4rem; font-size: 0.92rem; color: var(--ink); }
.crm-contacts, .crm-opportunities { margin: 0 0 0.8rem; padding-left: 1.1rem; }
.crm-opportunity { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; margin: 0.3rem 0; }
.crm-phase { font: inherit; font-size: 0.86rem; color: var(--ink); background: var(--field); border: 1px solid var(--field-line); border-radius: 6px; padding: 0.2rem 0.4rem; }
.crm-report { max-height: 28rem; overflow: auto; white-space: pre-wrap; }
.crm-off { padding: 1rem 0; }
/* The tenant's ideal customer profiles (card you-answer-a-few-questions-and-maestro-writes-your-ideal-customer-profile). */
.profiles-form { max-width: 40rem; }
.profiles-hint { color: var(--muted); font-size: 0.8rem; }
.profiles-field textarea, .profiles-field select { font: inherit; color: var(--ink); background: var(--field); border: 1px solid var(--field-line); border-radius: 6px; padding: 0.4rem 0.55rem; }
.profiles-report { max-width: 48rem; line-height: 1.5; color: var(--ink); }
.profiles-report .md-heading { margin: 1.1rem 0 0.3rem; }
.profiles-sources, .profiles-versions { margin: 0 0 1rem; padding-left: 1.2rem; font-size: 0.88rem; }
.profiles-source { margin: 0.3rem 0; overflow-wrap: anywhere; }
.profiles-kind { display: inline-block; padding: 0 0.45rem; border-radius: 999px; border: 1px solid var(--line); font-size: 0.76rem; color: var(--ink-soft); }
.profiles-kind-quote { border-color: var(--accent); color: var(--accent); }
.profiles-source-meta { color: var(--muted); }
.profiles-versions li { margin: 0.25rem 0; }
@media (max-width: 640px) {
  .crm-table { display: block; overflow-x: auto; }
  .crm-facts { grid-template-columns: 1fr; }
}

/* The invoices on the Plan place (card a-subscription-event-issues-the-invoice-with-nfs-e-through-asaas): a narrow screen scrolls the table, never the page. */
.tenant-invoices { overflow-x: auto; margin-top: 1rem; }
.tenant-invoices .frame-table th, .tenant-invoices .frame-table td { white-space: nowrap; }

/* When a charge is refused (card a-confirmed-payment-unlocks-the-plan-and-a-failed-one-falls-back-to-free). */
.pk-collections { border-top: 1px solid var(--line); padding-top: 0.8rem; margin-top: 1rem; }
.pk-collections-lead { color: var(--muted); margin: 0.3rem 0 0.8rem; }
.pk-collections-steps { margin: 0.8rem 0 0; padding-left: 1.2rem; }
