/*
  styles.css — page-specific styles that aren't worth their own file.
  Token references resolve against Open-Props + shared/base.css aliases.

  Open-Props tokens used here (jump to the docs for the full scale):
    --size-N          spacing       https://open-props.style/#sizes
    --font-size-N     type scale    https://open-props.style/#typography
    --font-mono       monospace     https://open-props.style/#typography
    --radius-N        corners       https://open-props.style/#sizes
    --radius-round    pill / circle https://open-props.style/#sizes

  Semantic aliases (--surface-N, --text-N, --accent, --border, --danger)
  are defined in shared/base.css — change them once to re-skin the
  whole app.

  NOTE (FE.0a / Garden Grid): shared/base.css now overrides the
  Open-Props colour, radius and soft-shadow tokens. So --radius-N here
  resolves to 0 (zero border-radius is a Garden Grid signature) and the
  semantic aliases point at the Garden Grid palette. Rules below that
  still say `border-radius: var(--radius-2)` therefore render square —
  intentionally. Per-page restyling to the 2px-border / sweep primitives
  is each FE.* task's job; this file was only reconciled for the ASCII
  charts + stale/overdue tints.
*/

/* ── Home dashboard (FE.3) ── */
.home {
  width: min(60rem, 100%);
  display: flex;
  flex-direction: column;
  gap: var(--size-4);
}
.home .card { width: 100%; }
.home__cta { gap: var(--size-2); align-items: flex-start; }

/* Outcome-first headline — the dominant commitment number. */
.home__headline {
  align-items: flex-start;
  gap: var(--size-1);
}
.home__headline-value {
  font-size: var(--font-size-7);
  line-height: 1;
}

.home__warn { display: flex; }

/* Jump-back card / quick links. */
.home__jumpback {
  text-decoration: none;
  display: flex;
  flex-direction: column;
  gap: var(--size-1);
}
.home__jumpback-name {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: var(--font-size-4);
  color: var(--fg);
}
.home__quick-links {
  display: flex;
  gap: var(--size-4);
  flex-wrap: wrap;
  margin-top: var(--size-2);
}
.home__signed { margin-top: var(--size-2); }

/* ── Onboarding checklist (TASK-34) ──
   Setup: N of 4 card sits above the headline while incomplete.
   Garden Grid (decision-2): 2px borders, no radius, mono labels,
   no soft shadow. The card surface (.card) already supplies the
   border + hard shadow tokens from shared/base.css. */
.home__onboarding {
  display: flex;
  flex-direction: column;
  gap: var(--size-3);
}
.home__onboarding-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--size-2);
}
.home__onboarding-count {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: var(--font-size-3);
  color: var(--fg);
}
.home__onboarding-steps {
  /* Mono ladder so the marks and labels visually align by character
     cell, reinforcing the Garden Grid mono aesthetic. */
  font-family: var(--font-mono);
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--size-2);
}
.home__onboarding-step {
  display: flex;
  align-items: center;
  gap: var(--size-2);
  flex-wrap: wrap;
}
.home__onboarding-mark {
  /* The ▣/▢ block character carries the done/not-done state. Fixed
     width keeps labels aligned regardless of which char is shown. */
  display: inline-block;
  width: 1.25em;
  text-align: center;
  color: var(--muted);
}
.home__onboarding-step.is-done .home__onboarding-mark { color: var(--accent); }
.home__onboarding-step.is-done .home__onboarding-label {
  color: var(--muted);
  text-decoration: line-through;
}
.home__onboarding-step.is-next .home__onboarding-label {
  font-weight: 700;
}
.home__onboarding-cta { margin-left: auto; }
.home__onboarding-hint { margin-left: auto; }

/* Tail state: a single-row "Setup complete ✓ [Dismiss]" pill. Kept
   intentionally minimal so it doesn't visually compete with the
   commitment-outcome headline below it (decision-1 / AC #4). */
.home__onboarding--done {
  display: flex;
  align-items: center;
  gap: var(--size-2);
}

/* ── Settings page (FE.4) ── */
.settings {
  width: min(48rem, 100%);
  display: flex;
  flex-direction: column;
  gap: var(--size-4);
}
.settings .card { width: 100%; gap: var(--size-3); }
.settings__form { display: flex; flex-direction: column; gap: var(--size-3); }
.settings__actions { display: flex; gap: var(--size-2); flex-wrap: wrap; align-items: center; }
.settings__theme { margin-top: var(--size-1); }
.settings__danger { border-color: var(--red); }

/* Login brand lockup (FE.1) — centred mark + name + tagline above the
   sign-in form. The inline mark inherits the accent via currentColor
   (glow on dark). */
.login-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--size-1);
  color: var(--accent);
  text-align: center;
  margin-bottom: var(--size-2);
}
[data-theme="dark"] .login-brand { color: var(--accent-glow); }
.login-brand__name {
  margin: 0;
  font-family: var(--font-mono);
  font-weight: 700;
  letter-spacing: 0.5px;
  color: var(--fg);
}
.login-brand__tagline {
  margin: 0;
}

/* Login OTP step indicator */
.otp-step {
  font-size: var(--font-size-0);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-2);
}

/* OTP code input: monospace + wider spacing so users can read each digit. */
.otp-code-input {
  font-family: var(--font-mono);
  font-size: var(--font-size-3);
  letter-spacing: 0.5em;
  text-align: center;
}

/* Theme toggle button in the topbar */
.theme-toggle {
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius-round);
  width: 2rem;
  height: 2rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--text-1);
}

.theme-toggle:hover {
  background: var(--surface-3);
}

/* Authenticated home page */
.home-user-card pre {
  background: var(--surface-3);
  padding: var(--size-2);
  border-radius: var(--radius-2);
  overflow-x: auto;
  font-size: var(--font-size-0);
  color: var(--text-1);
}

/* First-time Jira credentials setup form */
.jira-credentials-card {
  width: min(34rem, 100%);
  gap: var(--size-4);
}

.jira-credentials-form {
  display: flex;
  flex-direction: column;
  gap: var(--size-3);
}

.jira-credentials-form .field {
  gap: var(--size-2);
}

.jira-credentials-form .field input {
  font-size: var(--font-size-1);
  background: var(--surface-1);
}

.jira-credentials-form .field input::placeholder {
  color: var(--text-2);
}

.jira-credentials-form input[name="apiToken"] {
  font-family: var(--font-mono);
}

.jira-credentials-form .btn-primary {
  width: 100%;
  margin-top: var(--size-1);
}

/* ── Inline "Where do I get an API token?" disclosure (TASK-55) ──
   A quiet text link under the API Token input, NOT a peer UI block —
   the input + submit must remain the form's visual hierarchy. No
   border, no surface, body font; just a small underlined link with a
   chevron. Expanded content sits as an indented helper-text block
   beneath the link, still chrome-free.
   <details>/<summary> reference:
   https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details */
.api-token-help {
  /* Sit almost flush with the input — the .field already supplies a
     `gap: var(--size-2)`, so any extra margin here is what the user
     reads as "extra space". Pull tight against the input instead. */
  margin-top: calc(-1 * var(--size-1));
  background: transparent;
}

.api-token-help__summary {
  /* Reads as a link, not a control. Default disclosure marker hidden;
     we render our own chevron for the rotation cue. */
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: baseline;
  gap: var(--size-1);
  font-size: var(--font-size-0);
  color: var(--muted);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: currentColor;
  background: transparent;
  user-select: none;
}

.api-token-help__summary:hover {
  color: var(--accent);
  text-decoration-color: currentColor;
}

.api-token-help__summary:focus-visible {
  outline: 2px solid var(--accent, var(--border));
  outline-offset: 3px;
}

/* Safari uses ::-webkit-details-marker, modern browsers respect
   list-style:none on the summary itself — cover both. */
.api-token-help__summary::-webkit-details-marker { display: none; }

.api-token-help__summary::before {
  content: "▸";
  display: inline-block;
  font-size: 0.85em;
  transition: transform 0.15s ease;
}

.api-token-help[open] > .api-token-help__summary::before {
  transform: rotate(90deg);
}

.api-token-help__steps {
  /* Helper-text block, indented to align with the link's text. No
     border, no card chrome, no background — just quiet body copy. */
  margin: var(--size-2) 0 0;
  padding: 0 0 0 var(--size-4);
  background: transparent;
  display: flex;
  flex-direction: column;
  gap: var(--size-1);
  font-size: var(--font-size-0);
  color: var(--text-2);
  /* Align "1./2./3." columns when steps wrap. */
  font-variant-numeric: tabular-nums;
  line-height: 1.5;
}

/* "Need a screenshot walk-through? See the full guide →" — quiet
   follow-on to the inline 3-step guide. Sits inside the disclosure
   so the primary affordance (the 3 steps) stays foreground; users who
   skim those and want more click through to TASK-55a's tutorial. */
.api-token-help__more {
  margin: var(--size-2) 0 0;
  font-size: var(--font-size-0);
  color: var(--text-2);
}
.api-token-help__more a {
  color: var(--muted);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: currentColor;
}
.api-token-help__more a:hover { color: var(--accent); }

/* Board picker — stale-then-fresh list of the user's Jira boards (TASK-3.2). */
.board-picker {
  width: min(38rem, 100%);
  gap: var(--size-4);
}

.board-picker__header {
  display: flex;
  flex-direction: column;
  gap: var(--size-2);
}

.board-picker__actions {
  display: flex;
  align-items: center;
  gap: var(--size-3);
  flex-wrap: wrap;
}

.board-picker__search {
  display: flex;
  align-items: center;
  gap: var(--size-2);
  margin-top: var(--size-2);
}

.board-picker__search-input {
  flex: 1;
  font-size: var(--font-size-1);
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius-2);
  padding: var(--size-2);
}

.board-picker__pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--size-3);
  margin-top: var(--size-2);
}

.board-picker__row-links {
  display: flex;
  gap: var(--size-3);
  margin-left: calc(var(--size-3) + 1em); /* indent past the checkbox */
}

.board-picker__link {
  font-size: var(--font-size-0);
  color: var(--accent, var(--text-1));
  text-decoration: none;
}

.board-picker__link:hover {
  text-decoration: underline;
}

/* SprintView — single-sprint viewer (TASK-3.4). */
.sprint-view {
  width: min(80rem, 100%);
  gap: var(--size-4);
}

.sprint-view__header {
  display: flex;
  flex-direction: column;
  gap: var(--size-2);
}

.sprint-view__breadcrumbs a {
  font-size: var(--font-size-0);
  color: var(--text-2);
  text-decoration: none;
}

.sprint-view__breadcrumbs a:hover {
  text-decoration: underline;
}

.sprint-view__controls {
  display: flex;
  align-items: center;
  gap: var(--size-4);
  flex-wrap: wrap;
}

.sprint-view__label {
  display: flex;
  align-items: center;
  gap: var(--size-2);
}

/* Sprint picker — width only; the border/radius/fill come from the
   shared `select` primitive in base.css (FE.0a) so all dropdowns match. */
.sprint-view__select {
  min-width: 20rem;
}

.sprint-view__refresh {
  display: flex;
  align-items: center;
  gap: var(--size-2);
}

.sprint-view__empty {
  padding: var(--size-3);
  text-align: center;
}

.sprint-view table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-0);
}

.sprint-view th,
.sprint-view td {
  text-align: left;
  padding: var(--size-1) var(--size-2);
  border-bottom: 1px solid var(--border);
}

.sprint-view th {
  background: var(--surface-2);
  font-weight: 600;
}

.sprint-view tbody tr:hover {
  background: var(--surface-2);
}

.outcome-symbol {
  font-family: var(--font-mono);
  font-weight: 600;
}

/* ASCII chart container (TASK-3.5; restyled to Garden Grid in FE.0a).
   The charts now live in the system's one persistently-DARK terminal
   surface (decision-2) so the in-app charts, the brand mark, and the OG
   card read as one continuous block-character idea.
   • `white-space: pre` preserves the careful spacing the renderers emit.
   • `--font-mono` is JetBrains Mono (vendored) — monospaced, so the
     careful column alignment still holds; it includes the U+2580–U+259F
     block elements the renderers use.
   • `font-variant-ligatures: none` keeps box-drawing chars from being
     "improved" into something else by certain fonts.
   • Slightly reduced line-height so adjacent rows visually stack as
     one continuous shape rather than reading like prose.
   Forced to the dark palette regardless of the active theme.          */
.ascii-chart {
  font-family: var(--font-mono);
  font-variant-ligatures: none;
  white-space: pre;
  line-height: 1.2;
  font-size: var(--font-size-0);
  margin: var(--size-3) 0;
  padding: var(--size-3);
  background: #0d160f;
  color: #e8f1ea;
  border: 2px solid var(--border);
  box-shadow: var(--shadow-rest);
  overflow-x: auto;
}

.sprint-view__charts {
  display: flex;
  flex-direction: column;
  gap: var(--size-2);
}

/* Sprint commitment lede — the "So far this sprint" / commitment count /
   stat strip that leads the page (replaces the older OUTCOME card). The
   kicker + paragraph sit tight together; the StatsStrip below carries its
   own grid so we only need vertical rhythm here. */
.sprint-view__lede {
  display: flex;
  flex-direction: column;
  gap: var(--size-2);
  margin: var(--size-2) 0;
}
.sprint-view__lede-kicker { margin: 0; }
.sprint-view__lede-text {
  margin: 0;
  font-size: var(--font-size-1);
}
.sprint-view__lede-text strong {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* "Next due this sprint" — three clickable tiles in a single row. The
   tinted background + lift-on-hover signal "tap me" without leaning on
   accent buttons (which would compete with the page's actual primary CTA).
   `minmax(0, 1fr)` lets the summary text shrink and ellipsise rather than
   blowing the grid out when titles are long. */
.sprint-view__next-due {
  display: flex;
  flex-direction: column;
  gap: var(--size-2);
  margin: var(--size-3) 0;
}
.sprint-view__next-due-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--size-2);
}
.sprint-view__due-tile {
  display: flex;
  flex-direction: column;
  gap: var(--size-1);
  padding: var(--size-2) var(--size-3);
  border: 2px solid var(--accent);
  background: var(--accent-pale);
  color: var(--fg);
  text-decoration: none;
  box-shadow: var(--shadow-sm);
  transition: transform 80ms ease, box-shadow 80ms ease, background 80ms ease;
  min-width: 0; /* lets the inner ellipsis kick in inside grid cells */
}
.sprint-view__due-tile:hover {
  background: var(--surface);
  box-shadow: var(--shadow-rest);
  transform: translate(-1px, -1px);
}
.sprint-view__due-tile:active {
  box-shadow: var(--shadow-sm);
  transform: translate(0, 0);
}
.sprint-view__due-tile--overdue {
  border-color: var(--red);
  background: var(--red-pale);
  color: var(--red);
}
.sprint-view__due-tile--inert {
  cursor: default;
  opacity: 0.85;
}
.sprint-view__due-tile--inert:hover {
  transform: none;
  box-shadow: var(--shadow-sm);
  background: var(--accent-pale);
}

.sprint-view__due-tile-when {
  font-family: var(--font-mono);
  font-size: var(--font-size-0);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.sprint-view__due-tile-rel { }
.sprint-view__due-tile-abs {
  font-weight: 400;
  opacity: 0.8;
}

.sprint-view__due-tile-ticket {
  display: flex;
  align-items: baseline;
  min-width: 0;
  font-size: var(--font-size-1);
}
.sprint-view__due-tile-key {
  font-family: var(--font-mono);
  font-weight: 700;
  flex: 0 0 auto;
}
.sprint-view__due-tile-summary {
  flex: 1 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Flow section — cycle-time histogram (TASK-4.10) + stuck kanban
   (TASK-83). Same vertical-stack rhythm as __charts; the .ascii-chart
   styling already handles the monospace blocks. */
.sprint-view__flow-charts {
  display: flex;
  flex-direction: column;
  gap: var(--size-2);
}

/* "Where work got stuck" kanban (TASK-83). Sits beneath the cycle
   histogram inside the diagnosis section. Horizontally scrollable —
   busy sprints can pile up many stuck columns and we'd rather scroll
   than wrap and lose the at-a-glance ordering. */
.sprint-view__stuck {
  display: flex;
  flex-direction: column;
  gap: var(--size-2);
  margin-top: var(--size-3);
}
.sprint-view__stuck-title {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--font-size-1);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.sprint-view__stuck-board {
  display: flex;
  flex-direction: row;
  gap: var(--size-2);
  overflow-x: auto;
  padding-bottom: var(--size-1);
}
.sprint-view__stuck-col {
  display: flex;
  flex-direction: column;
  gap: var(--size-1);
  min-width: 16rem;
  max-width: 22rem;
  padding: var(--size-2);
  border: 2px solid var(--fg);
  background: var(--surface);
}
.sprint-view__stuck-col-header {
  display: flex;
  align-items: baseline;
  gap: var(--size-1);
  padding-bottom: var(--size-1);
  border-bottom: 2px solid var(--fg);
  font-family: var(--font-mono);
  font-size: var(--font-size-1);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.sprint-view__stuck-col-status { font-weight: 700; }
.sprint-view__stuck-col-count  { opacity: 0.7; }
.sprint-view__stuck-col-cards {
  display: flex;
  flex-direction: column;
  gap: var(--size-1);
}
.sprint-view__stuck-card {
  display: flex;
  align-items: baseline;
  gap: var(--size-1);
  padding: var(--size-1) var(--size-2);
  border: 2px solid var(--accent);
  background: var(--accent-pale);
  color: var(--fg);
  text-decoration: none;
  box-shadow: var(--shadow-sm);
  transition: transform 80ms ease, box-shadow 80ms ease, background 80ms ease;
}
.sprint-view__stuck-card:hover {
  background: var(--surface);
  box-shadow: var(--shadow-rest);
  transform: translate(-1px, -1px);
}
.sprint-view__stuck-card:active {
  box-shadow: var(--shadow-sm);
  transform: translate(0, 0);
}
.sprint-view__stuck-card--inert {
  cursor: default;
  opacity: 0.85;
}
.sprint-view__stuck-card--inert:hover {
  transform: none;
  box-shadow: var(--shadow-sm);
  background: var(--accent-pale);
}
.sprint-view__stuck-card-key {
  font-family: var(--font-mono);
  font-weight: 700;
  flex: 0 0 auto;
}
.sprint-view__stuck-card-days {
  font-family: var(--font-mono);
  font-size: var(--font-size-0);
  opacity: 0.8;
  flex: 1 1 auto;
  text-align: right;
}
.sprint-view__stuck-card-now {
  flex: 0 0 auto;
}

/* ─────────────────────────────────────────────────────────────────
   Outcome-first information architecture (TASK-9 / decision-1)
   ─────────────────────────────────────────────────────────────────
   The layout itself asserts the product thesis: commitment / on-time is
   THE OUTCOME (the headline) and the flow metrics are the DIAGNOSIS
   (subordinate, beneath). Shared by SprintView + TeamLeadView so the
   hierarchy reads identically everywhere; the named .metric-outcome /
   .metric-diagnosis slots are what the m-4 presentation switcher targets
   (data-slot=…) and is forbidden from re-ordering (AC #6). */

/* OUTCOME headline slot — the dominant treatment. A large mono
   .stat-value (decision-2 §08) so the commitment verdict is the first
   number the eye lands on. Mirrors the Home dashboard headline. */
.metric-outcome {
  align-items: flex-start;
  gap: var(--size-1);
}
.metric-outcome__value {
  /* The single biggest figure on the page — bigger than any diagnosis
     stat-card value (--font-size-5) so a diagnosis chart can never be
     styled to outrank the outcome (AC #6/#8). */
  font-size: var(--font-size-7);
  line-height: 1;
}
.metric-outcome__sub {
  font-family: var(--font-mono);
  font-size: var(--font-size-0);
}

/* Coverage confidence ladder (TASK-40, FE.6b).
   When coverage is too low to trust the commitment %, the headline
   figure is swapped for the coverage % and tinted danger-red so the
   demotion is visible at a glance. `--metric-outcome__value` keeps the
   font-size from the headline rule above. */
.metric-outcome__value--danger { color: var(--red); }

/* Caption / nudge rows that sit BELOW .metric-outcome__sub. Mono so
   they read as supporting data, slightly narrower line-height for a
   compact stack. The .pill-warn chip in the mid band rides as an inline
   sibling — same baseline as the surrounding mono text. */
.metric-outcome__caption {
  display: inline-flex;
  align-items: center;
  gap: var(--size-1);
  font-family: var(--font-mono);
  font-size: var(--font-size-0);
}

.metric-outcome__nudge {
  margin: var(--size-1) 0 0 0;
  max-width: 60ch;            /* Tight measure so the copy reads as a teaching note. */
  font-size: var(--font-size-0);
  color: var(--text-2);
}
.metric-outcome__nudge a {
  font-family: var(--font-mono);
  color: var(--accent);
}

/* DIAGNOSIS cluster — visibly secondary. A top rule + breathing room
   sets it apart as the 'why' beneath the verdict; its contents are the
   smaller .stat-card grid / terminal charts, never headline-sized. */
.metric-diagnosis {
  margin-top: var(--size-4);
  display: flex;
  flex-direction: column;
  gap: var(--size-2);
}
.metric-diagnosis__lead {
  margin: 0;
  font-size: var(--font-size-0);
}

/* The (i) explainer affordance ($$.ui.InfoTip) — an accent glyph riding
   beside a label/heading. Reuses the .tip popover primitive (base.css);
   we only restyle the trigger glyph here (drop the dotted underline the
   generic .tip carries, tint it accent, nudge it off the label). */
.info-tip {
  margin-left: 0.35em;
  color: var(--accent);
  border-bottom: 0;
  font-size: 0.85em;
  vertical-align: baseline;
}
[data-theme="dark"] .info-tip { color: var(--accent-glow); }

/* Emphasised anchoring column in a .data-table (the commitment / on-time
   column of the team overview). Mono + accent + bold so it reads as the
   primary signal, not a peer of the supporting flow columns (AC #3). */
.data-table th.col-outcome { color: var(--accent-hi); }
.data-table td.col-outcome {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--accent-hi);
}
[data-theme="dark"] .data-table th.col-outcome,
[data-theme="dark"] .data-table td.col-outcome { color: var(--accent-glow); }

/* Dark chart panel (AC #11). The chart cluster gets the dark .code-block
   surface so the ASCII charts read as one continuous block-character idea
   (the same dark vocabulary as the Punctual brand mark / OG card). The
   nested .ascii-chart blocks shed their own dark surface so they sit
   INSIDE the one panel rather than stacking nested dark boxes — a
   re-skin of the container, not a rewrite of the chart strings. */
.chart-terminal {
  gap: var(--size-3);
}
.chart-terminal .ascii-chart {
  margin: 0;
  padding: 0;
  background: transparent;
  border: 0;
  box-shadow: none;
  overflow-x: visible;
}

.board-picker__list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--size-2);
}

.board-picker__row {
  display: flex;
  flex-direction: column;
  gap: var(--size-1);
  padding: var(--size-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-2);
  background: var(--surface-1);
}

.board-picker__label {
  display: flex;
  align-items: center;
  gap: var(--size-2);
  cursor: pointer;
}

.board-picker__meta {
  font-size: var(--font-size-0);
}

/* Inline "Syncing…" badge alongside the board name. */
.badge {
  display: inline-block;
  padding: 0.1em 0.5em;
  font-size: var(--font-size-0);
  border-radius: var(--radius-2);
  background: var(--surface-3);
  color: var(--text-2);
}

.badge--syncing {
  background: var(--surface-3);
  color: var(--text-1);
  animation: var(--animation-pulse, none);
}

.board-picker__row-error {
  margin: 0;
  font-size: var(--font-size-0);
  color: var(--danger, #c00);
}

/* Tiny inline retry link inside a row error. Mimics an underlined link
   but keeps button semantics so screen readers / keyboards work. */
.btn-link {
  background: none;
  border: none;
  padding: 0;
  margin-left: var(--size-1);
  color: inherit;
  text-decoration: underline;
  cursor: pointer;
  font: inherit;
}

/* BoardSettings — per-board devDoneStatuses editor (TASK-3.7).
   Mirrors the card / list / row pattern from BoardPicker so the two
   pages feel like the same family. */
.board-settings {
  width: min(38rem, 100%);
  gap: var(--size-4);
}

.board-settings__header {
  display: flex;
  flex-direction: column;
  gap: var(--size-2);
}

.board-settings__breadcrumbs {
  display: flex;
  gap: var(--size-3);
  flex-wrap: wrap;
}

.board-settings__breadcrumbs a {
  font-size: var(--font-size-0);
  color: var(--text-2);
  text-decoration: none;
}

.board-settings__breadcrumbs a:hover {
  text-decoration: underline;
}

.board-settings__empty {
  padding: var(--size-3);
  text-align: center;
}

.board-settings__form {
  display: flex;
  flex-direction: column;
  gap: var(--size-3);
}

.board-settings__list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--size-1);
}

.board-settings__row {
  padding: var(--size-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-2);
  background: var(--surface-1);
}

.board-settings__label {
  display: flex;
  align-items: center;
  gap: var(--size-2);
  cursor: pointer;
}

.board-settings__name {
  font-size: var(--font-size-1);
}

.board-settings__actions {
  display: flex;
  align-items: center;
  gap: var(--size-3);
  flex-wrap: wrap;
}

.board-settings__saved {
  font-size: var(--font-size-0);
}

.board-settings__save-error {
  margin: 0;
  font-size: var(--font-size-0);
  color: var(--danger, #c00);
  width: 100%;
}

/* ── wipStaleThresholdDays input (TASK-4.11) ──
   `.field` provides the Garden Grid input shell (2px border, zero radius,
   sweep underline on focus). We constrain the input to its natural
   number-input width so it doesn't stretch the full form column and
   pin the hint copy directly beneath it. */
.board-settings__threshold input[type=number] {
  max-width: 9rem;
}
.board-settings__threshold-hint {
  margin: var(--size-1) 0 0 0;
  font-size: var(--font-size-0);
}

/* SprintView breadcrumb settings link — slight inline separation
   from the "← All boards" link. */
.sprint-view__settings-link {
  margin-left: var(--size-2);
}

/* SprintView exclusion toggle (TASK-3.9). Sits next to the dropdown;
   styled as a compact label so it doesn't dominate the controls row. */
.sprint-view__exclusion {
  display: flex;
  align-items: center;
  gap: var(--size-1);
  font-size: var(--font-size-0);
  cursor: pointer;
}

/* Visual deemphasis for a currently-viewed excluded sprint. Italicises
   the sprint name + tones down the totals card a touch so the reader
   knows the numbers below aren't contributing to the board overview. */
.sprint-view__totals--excluded h3 {
  font-style: italic;
  color: var(--text-2);
}

.sprint-view__totals--excluded {
  opacity: 0.85;
}

.sprint-view__excluded-badge {
  margin-left: var(--size-2);
  font-style: normal;
  font-size: var(--font-size-0);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* BoardOverview — board-level aggregate page (TASK-3.9). Reuses the
   wide-card width from SprintView so the ASCII charts have room. */
.board-overview {
  width: min(80rem, 100%);
  gap: var(--size-4);
}

.board-overview__header {
  display: flex;
  flex-direction: column;
  gap: var(--size-2);
}

.board-overview__breadcrumbs {
  display: flex;
  gap: var(--size-3);
  flex-wrap: wrap;
}

.board-overview__breadcrumbs a {
  font-size: var(--font-size-0);
  color: var(--text-2);
  text-decoration: none;
}

.board-overview__breadcrumbs a:hover {
  text-decoration: underline;
}

.board-overview__empty {
  padding: var(--size-3);
  text-align: center;
}

.board-overview__charts {
  display: flex;
  flex-direction: column;
  gap: var(--size-2);
}

.board-overview table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-0);
}

.board-overview th,
.board-overview td {
  text-align: left;
  padding: var(--size-1) var(--size-2);
  border-bottom: 1px solid var(--border);
}

.board-overview th {
  background: var(--surface-2);
  font-weight: 600;
}

.board-overview tbody tr:hover {
  background: var(--surface-2);
}

.board-overview__footer {
  margin-top: var(--size-2);
  font-size: var(--font-size-0);
}

/* DeveloperTrendView — per-developer trend page (TASK-4.8). Same wide-card
   width as BoardOverview so the ASCII charts have room. Header/breadcrumb
   patterns mirror BoardOverview to keep the navigation chrome consistent. */
.developer-trend {
  width: min(80rem, 100%);
  gap: var(--size-4);
}

.developer-trend__header {
  display: flex;
  flex-direction: column;
  gap: var(--size-2);
}

.developer-trend__breadcrumbs {
  display: flex;
  gap: var(--size-3);
  flex-wrap: wrap;
}

.developer-trend__breadcrumbs a {
  font-size: var(--font-size-0);
  color: var(--text-2);
  text-decoration: none;
}

.developer-trend__breadcrumbs a:hover {
  text-decoration: underline;
}

/* Picker row — label + <select> on the same line with breathing room.
   Ref: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_flexible_box_layout */
.developer-trend__picker {
  display: flex;
  align-items: center;
  gap: var(--size-2);
  flex-wrap: wrap;
}

.developer-trend__picker select {
  font-size: var(--font-size-1);
  padding: var(--size-1) var(--size-2);
}

.developer-trend__empty {
  padding: var(--size-3);
  text-align: center;
}

/* KPI strip: four labelled stats side-by-side, wrapping to a column on
   narrow viewports. Using a <dl> with grid keeps each label tied to its
   value semantically while letting CSS lay them out horizontally.
   Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl
   Ref: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout */
.developer-trend__kpis {
  padding: var(--size-3);
  background: var(--surface-2);
  border-radius: var(--radius-2);
}

.developer-trend__kpi-grid {
  display: grid;
  /* auto-fit + minmax gives us 4-up on desktop, gracefully collapsing
     to 2-up / 1-up as the viewport narrows. Each grid child is a
     .developer-trend__kpi wrapper (one per KPI), so labels stay glued
     to their values regardless of viewport width. */
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: var(--size-3) var(--size-4);
  margin: 0;
}

/* One KPI = label stacked on top of value, in its own grid cell. */
.developer-trend__kpi {
  display: flex;
  flex-direction: column;
  gap: var(--size-1);
}

.developer-trend__kpi dt {
  font-size: var(--font-size-0);
  color: var(--text-2);
  font-weight: 500;
}

.developer-trend__kpi dd {
  margin: 0;
  font-size: var(--font-size-3);
  font-weight: 600;
  color: var(--text-1);
  line-height: 1.1;
}

.developer-trend__charts {
  display: flex;
  flex-direction: column;
  gap: var(--size-2);
}

/* TeamLeadView — the 1-on-1 surface (TASK-4.9). Single-column layout
   for readability during a call; wide card to give the WIP/history
   tables room. Visual language mirrors DeveloperTrendView for
   consistency — same KPI grid pattern, same breadcrumb chrome. */
.team-lead {
  width: min(80rem, 100%);
  gap: var(--size-4);
}

.team-lead__header {
  display: flex;
  flex-direction: column;
  gap: var(--size-2);
}

.team-lead__title {
  display: flex;
  flex-direction: column;
  gap: var(--size-1);
}

.team-lead__sprint-context {
  font-size: var(--font-size-0);
  color: var(--text-2);
}

.team-lead__breadcrumbs {
  display: flex;
  gap: var(--size-3);
  flex-wrap: wrap;
}

.team-lead__breadcrumbs a {
  font-size: var(--font-size-0);
  color: var(--text-2);
  text-decoration: none;
}

.team-lead__breadcrumbs a:hover {
  text-decoration: underline;
}

.team-lead__picker {
  display: flex;
  align-items: center;
  gap: var(--size-2);
  flex-wrap: wrap;
}

.team-lead__picker select {
  font-size: var(--font-size-1);
  padding: var(--size-1) var(--size-2);
}

.team-lead__last-sync {
  font-size: var(--font-size-0);
  margin: 0;
}

.team-lead__empty {
  padding: var(--size-3);
  text-align: center;
}

.team-lead__charts {
  display: flex;
  flex-direction: column;
  gap: var(--size-2);
}

/* Team-overview "Where work got stuck" wrapper. Mirrors the
   .team-lead__charts block — a sec-kicker on top, the kanban board
   underneath, separated by the same gap as the rest of the
   team-overview column flex. The kanban itself owns its column layout
   via the shared .sprint-view__stuck-* classes. */
.team-lead__stuck {
  display: flex;
  flex-direction: column;
  gap: var(--size-2);
}

/* WIP table — `.stale` and `.overdue` rows are tinted. Stale is a
   yellow-ish hint that things are sticking; overdue is a stronger
   warning. When both apply, .overdue wins via CSS source order. */
.team-lead__wip,
.team-lead__history,
.team-lead__team-overview {
  display: flex;
  flex-direction: column;
  gap: var(--size-2);
}

.team-lead__wip-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-0);
}

.team-lead__wip-table th,
.team-lead__wip-table td {
  text-align: left;
  padding: var(--size-1) var(--size-2);
  border-bottom: 1px solid var(--border);
  /* Top-align every cell so the issue key, status, ages, due and flag
     badge all line up on the same top edge — when the Issue cell wraps
     to a second line (summary), the other columns stay anchored to the
     top rather than floating to the middle. */
  vertical-align: top;
}

.team-lead__wip-table th {
  background: var(--surface-2);
  font-weight: 600;
}

.team-lead__wip-table tbody tr:hover {
  background: var(--surface-2);
}

/* Row tinting removed (FE.0a testing): the STALE / OVERDUE chips in the
   Flags column already carry that signal, so a full-row background was
   redundant and made the Flags cell look misaligned. The .stale/.overdue
   classes stay on the <tr> for the flag rendering; they just no longer
   paint the row. */

/* Clamp the summary to a single line with an ellipsis so a long
   ticket title doesn't balloon the row height. Full text is available
   via the cell's title attribute on hover.
   Ref: https://developer.mozilla.org/en-US/docs/Web/CSS/text-overflow */
.team-lead__wip-summary {
  font-size: var(--font-size-0);
  max-width: 36rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.team-lead__flag {
  font-size: var(--font-size-0);
  padding: 1px var(--size-1);
  border-radius: var(--radius-1);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.team-lead__flag--stale {
  background: var(--amber-pale);
  border: 1px solid var(--amber);
  color: var(--amber);
}

.team-lead__flag--overdue {
  background: var(--red-pale);
  border: 1px solid var(--red);
  color: var(--red);
}

.team-lead__history-block + .team-lead__history-block {
  margin-top: var(--size-3);
}

.team-lead__history-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--size-1);
}

.team-lead__history-row {
  font-size: var(--font-size-1);
}

.team-lead__history-row a {
  font-weight: 600;
}

/* ─────────────────────────────────────────────────────────────────
   Breadcrumb / sub-nav emphasis (FE.0a testing refinement)
   ─────────────────────────────────────────────────────────────────
   The per-page breadcrumb links (All boards / Board overview / 1-on-1 /
   Settings / Sprints) were muted + low-contrast. This grouped rule —
   placed after the per-component rules above so it wins on source order —
   gives them the shared Garden Grid `.nav-link` treatment: fg-coloured,
   semibold, with the 2px accent sweep underline on hover. The sweep is
   the bottom-pinned background-size gradient documented in base.css. */
.sprint-view__breadcrumbs a,
.board-settings__breadcrumbs a,
.board-overview__breadcrumbs a,
.developer-trend__breadcrumbs a,
.team-lead__breadcrumbs a {
  font-size: var(--font-size-1);
  font-weight: 600;
  color: var(--fg);
  text-decoration: none;
  background-image: linear-gradient(var(--accent), var(--accent));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 2px;
  transition: background-size 0.2s ease, color 0.15s ease;
}

.sprint-view__breadcrumbs a:hover,
.board-settings__breadcrumbs a:hover,
.board-overview__breadcrumbs a:hover,
.developer-trend__breadcrumbs a:hover,
.team-lead__breadcrumbs a:hover {
  color: var(--accent);
  text-decoration: none;
  background-size: 100% 2px;
}

/* ── Help page: Why Punctual needs due dates (TASK-36) ──
   Scoped layout for HelpDueDates.js. No new design tokens — every
   colour / border / shadow leans on the Garden Grid aliases set in
   shared/base.css. The page-level rules below just compose those
   primitives into a long-form reading layout that the global `.card`
   (width: min(28rem, 100%); padding: var(--size-5)) doesn't fit. */

.help-dd {
  width: min(60rem, 100%);
  display: flex;
  flex-direction: column;
  gap: var(--size-5);
}
.help-dd .card { width: 100%; }

.help-dd__header { display: flex; flex-direction: column; gap: var(--size-1); }
.help-dd__title { margin: 0; font-size: var(--font-size-6); }
.help-dd__subtitle { color: var(--muted); margin: 0; }

/* Single-sentence punchline card — visually distinct from the WHY
   cards via the accent-pale tint so a skim-reader can't miss it. */
.help-dd__tldr {
  background: var(--accent-pale);
  gap: var(--size-2);
}
.help-dd__tldr p { color: var(--fg); }
.help-dd__tldr-jump { font-family: var(--font-mono); font-size: var(--font-size-0); }
.help-dd__tldr-jump a { color: var(--accent-hi); text-underline-offset: 3px; }

.help-dd__section { display: flex; flex-direction: column; gap: var(--size-3); }
.help-dd__h3 { margin: 0; font-size: var(--font-size-4); }
.help-dd__lede { color: var(--muted); margin: 0; max-width: 60ch; }

/* WHY grid — 3 prose cards. Single column on narrow viewports per
   AC #6 (renders correctly at mobile widths). The auto-fit minmax
   collapses to one column below ~32rem without a media query. */
.help-dd__why-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  gap: var(--size-3);
}
.help-dd__why { gap: var(--size-2); }
.help-dd__why h4 { margin: 0; font-size: var(--font-size-3); }
.help-dd__why p { color: var(--fg); }

/* Screenshot step list — ordered list, marker hidden because the
   .sec-kicker "Step N" inside each card already numbers them. The
   auto-fit grid puts two cards side-by-side at the page's natural
   width (~60rem container ÷ ~22rem min → two columns) and collapses
   to a single column on tablets / phones automatically.
   `align-items: start` stops a tall card with a tip from stretching
   its row-mate vertically just to match heights.
   Ref: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns#auto-fit */
.help-dd__steps {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr));
  gap: var(--size-3);
  align-items: start;
}
.help-dd__step { gap: var(--size-2); }

/* Anchor wrapping the screenshot — click opens the full-resolution
   asset in a new tab. The zoom-in cursor signals the affordance on
   hover so the user knows it's interactive.
   Ref: https://developer.mozilla.org/en-US/docs/Web/CSS/cursor */
.help-dd__shot-link {
  display: block;
  cursor: zoom-in;
  text-decoration: none;
}
.help-dd__shot {
  display: block;
  width: 100%;
  height: auto;
  border: 2px solid var(--border);
  background: var(--surface2);
  /* Keep the hard-offset shadow off the image itself — the wrapping
     .card already carries the paper-stack look. */
}
.help-dd__caption { color: var(--fg); margin: 0; max-width: 60ch; }
.help-dd__tip {
  margin: 0;
  padding: var(--size-2) var(--size-3);
  border-left: 4px solid var(--amber);
  background: var(--amber-pale);
  color: var(--amber);
  font-size: var(--font-size-1);
}

/* JQL code block — base `.code-block` is the dark terminal panel;
   the help page just constrains width and adds a touch of breath. */
.help-dd__code {
  white-space: pre-wrap;
  word-break: break-word;
  max-width: 100%;
}

/* Live JQL variant — the code block is an <a> linking to the user's
   Jira search. Same dark-terminal look, but cursor + subtle hover
   say "this is clickable". The default underline on dark backgrounds
   looks ratty; the hover state earns the affordance instead. */
.help-dd__code--live {
  display: block;
  cursor: pointer;
  text-decoration: none;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.help-dd__code--live:hover {
  transform: translate(-2px, -2px);
  box-shadow: var(--shadow-lift);
}

/* Outcome banner + footer nav. The outcome block uses the
   .stats-strip-style dark inverted surface sparingly (one per page,
   per decision-2 rule 7), implemented inline so we don't need to
   reach for the StatsStrip component machinery. */
.help-dd__outcome {
  background: var(--fg);
  color: var(--bg);
  border: 2px solid var(--border);
  box-shadow: var(--shadow-rest);
  padding: var(--size-4) var(--size-5);
  display: flex;
  flex-direction: column;
  gap: var(--size-1);
}
.help-dd__outcome .sec-kicker { color: var(--accent-glow); }
.help-dd__outcome p { margin: 0; max-width: 60ch; }

.help-dd__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--size-3);
  flex-wrap: wrap;
  margin-top: var(--size-3);
}

@media (max-width: 600px) {
  .help-dd__title { font-size: var(--font-size-5); }
  .help-dd__h3 { font-size: var(--font-size-3); }
  .help-dd__footer { flex-direction: column; align-items: stretch; }
}

/* ── Help · Connect Jira (TASK-55a) ──
   Screenshot-led tutorial that mirrors the .help-dd page. Same long-
   form reading layout, same step-card grid, same dark inverted
   outcome strip — but with an embedded screenshot inside the outcome
   block (the onboarding checklist payoff). Garden Grid throughout. */

.help-jc {
  width: min(60rem, 100%);
  display: flex;
  flex-direction: column;
  gap: var(--size-5);
}
.help-jc .card { width: 100%; }

.help-jc__header { display: flex; flex-direction: column; gap: var(--size-1); }
.help-jc__title { margin: 0; font-size: var(--font-size-6); }
.help-jc__subtitle { color: var(--muted); margin: 0; max-width: 50ch; }

/* Single-sentence punchline card — accent-pale tint so a skim reader
   spots the destination immediately, same treatment as .help-dd__tldr. */
.help-jc__tldr {
  background: var(--accent-pale);
  gap: var(--size-2);
}
.help-jc__tldr p { color: var(--fg); }
.help-jc__tldr-jump { font-family: var(--font-mono); font-size: var(--font-size-0); }
.help-jc__tldr-jump a { color: var(--accent-hi); text-underline-offset: 3px; }

.help-jc__section { display: flex; flex-direction: column; gap: var(--size-3); }
.help-jc__h3 { margin: 0; font-size: var(--font-size-4); }
.help-jc__lede { color: var(--muted); margin: 0; max-width: 60ch; }

/* Step grid — same auto-fit behaviour as .help-dd__steps so two cards
   sit side-by-side at the page's natural width and collapse to a
   single column on tablets / phones. `align-items: start` stops a
   tip-bearing card from stretching its row-mate. */
.help-jc__steps {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr));
  gap: var(--size-3);
  align-items: start;
}
.help-jc__step { gap: var(--size-2); }

/* Screenshot wrapper — click opens the full-resolution PNG in a new
   tab. Zoom-in cursor signals the affordance.
   Ref: https://developer.mozilla.org/en-US/docs/Web/CSS/cursor */
.help-jc__shot-link {
  display: block;
  cursor: zoom-in;
  text-decoration: none;
}
.help-jc__shot {
  display: block;
  width: 100%;
  height: auto;
  border: 2px solid var(--border);
  background: var(--surface2);
}
.help-jc__caption { color: var(--fg); margin: 0; max-width: 60ch; }
.help-jc__tip {
  margin: 0;
  padding: var(--size-2) var(--size-3);
  border-left: 4px solid var(--amber);
  background: var(--amber-pale);
  color: var(--amber);
  font-size: var(--font-size-1);
}

/* Outcome strip — dark inverted surface (decision-2 rule 7: one loud
   moment per page). Hosts the onboarding-checklist screenshot inside
   it as the visual payoff. The shot wrapper here has its own class so
   the dark-strip context can override the border colour. */
.help-jc__outcome {
  background: var(--fg);
  color: var(--bg);
  border: 2px solid var(--border);
  box-shadow: var(--shadow-rest);
  padding: var(--size-4) var(--size-5);
  display: flex;
  flex-direction: column;
  gap: var(--size-2);
}
.help-jc__outcome .sec-kicker { color: var(--accent-glow); }
.help-jc__outcome p { margin: 0; max-width: 60ch; }

.help-jc__outcome-shot-link {
  display: block;
  cursor: zoom-in;
  text-decoration: none;
  margin-top: var(--size-2);
  max-width: 36rem;
}
.help-jc__outcome-shot {
  display: block;
  width: 100%;
  height: auto;
  /* Lighter border than the regular .help-jc__shot — the dark strip
     already provides structural contrast, a solid --border (which
     matches --fg) would disappear into the background. */
  border: 2px solid var(--accent-glow);
  background: var(--surface2);
}

.help-jc__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--size-3);
  flex-wrap: wrap;
  margin-top: var(--size-3);
}

@media (max-width: 600px) {
  .help-jc__title { font-size: var(--font-size-5); }
  .help-jc__h3 { font-size: var(--font-size-3); }
  .help-jc__footer { flex-direction: column; align-items: stretch; }
}

/* ── Help index (TASK-36 follow-up) ──
   Lightweight landing page for the help corpus. Grid of liftable
   article cards; same Garden Grid primitives the rest of the app
   uses, no new design tokens. */

.help-index {
  width: min(60rem, 100%);
  display: flex;
  flex-direction: column;
  gap: var(--size-4);
}

.help-index__header { display: flex; flex-direction: column; gap: var(--size-1); }
.help-index__title { margin: 0; font-size: var(--font-size-6); }
.help-index__subtitle { color: var(--muted); margin: 0; max-width: 50ch; }

/* Article grid — auto-fit so 2 cards sit side-by-side at the page's
   natural width, collapsing to 1 column on narrow viewports without
   a media query. Same approach as .help-dd__why-grid. */
.help-index__grid {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr));
  gap: var(--size-3);
}
.help-index__item { display: flex; }

.help-index__card {
  /* Override the base .card width: min(28rem, 100%) so the card fills
     its grid cell and the grid (not the card) controls layout. */
  width: 100%;
  text-decoration: none;
  color: inherit;
  gap: var(--size-2);
  /* Align the CTA to the bottom so cards with shorter blurbs still
     present a tidy "Read →" along the same baseline as their row-mates. */
  justify-content: flex-start;
}

.help-index__card-title {
  margin: 0;
  font-size: var(--font-size-4);
}

.help-index__card-blurb {
  margin: 0;
  color: var(--muted);
  flex: 1; /* push the CTA to the bottom of the card */
}

.help-index__card-cta {
  font-family: var(--font-mono);
  font-size: var(--font-size-0);
  font-weight: 600;
  color: var(--accent-hi);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-top: var(--size-2);
}

.help-index__foot {
  margin: 0;
  font-size: var(--font-size-1);
  max-width: 60ch;
}

@media (max-width: 600px) {
  .help-index__title { font-size: var(--font-size-5); }
}

/* ═════════════════════════════════════════════════════════════════
   PUBLIC MARKETING LANDING (TASK-82 · m-10)
   ═════════════════════════════════════════════════════════════════
   Scoped `.landing*` namespace — this is the only surface in the app
   that renders WITHOUT the in-app Layout wrapper (see hashRouter
   `opts.bare`), so it has to ship its own topbar + footer chrome.

   Garden Grid conventions still apply (decision-2): 2px borders,
   zero radius, hard paper shadows, sage-pastel surfaces, mono
   numerals + uppercase mono labels, sans headlines. The reference
   design (TASK-82 conversation) added a few primitives we adopt
   here: a thin sticky topbar with a single bottom rule, a single-
   column main flow at ~960px, an accent-bordered headline card,
   block-character bullet rows, and a quiet white-on-light footer.

   Reference: backlog/tasks/task-82 - …
   Reference: backlog/decisions/decision-2 - …
   ───────────────────────────────────────────────────────────────── */

.landing {
  /* Bleed to the viewport edges so the topbar / footer can span full
     width. The standard `.main` wrapper centres + pads its child; on
     `bare` routes we skip Layout, so the SPA mount's body becomes our
     canvas directly. */
  width: 100%;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-body);
}

/* ── Topbar ──────────────────────────────────────────────────────
   Sticky, 56px tall, white-ish surface with the 2px Garden Grid
   bottom rule. Mirrors the in-app .navbar but stripped of the icon
   buttons and the wraparound — a marketing topbar wants to read as
   a single horizontal line at any width. */
.landing__topbar {
  position: sticky;
  top: 0;
  z-index: 200;
  background: var(--surface);
  border-bottom: 2px solid var(--border);
  box-shadow: var(--shadow-sm);
}
.landing__topbar-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--size-3);
  width: min(64rem, 100%);
  margin: 0 auto;
  padding: var(--size-2) var(--size-4);
}
.landing__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--size-2);
  text-decoration: none;
  color: var(--fg);
}
.landing__brand-mark { display: block; }
.landing__brand-name {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: var(--font-size-2);
  letter-spacing: 0.06em;
  color: var(--fg);
}
.landing__topbar-nav {
  display: flex;
  align-items: center;
  gap: var(--size-1);
}
.landing__topbar-link {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-mono);
  font-size: var(--font-size-0);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  text-decoration: none;
  padding: var(--size-1) var(--size-3);
  /* Reuse the signature sweep underline from .nav-link. */
  background-image: linear-gradient(var(--accent), var(--accent));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 2px;
  transition: background-size 0.2s ease, color 0.15s ease;
}
.landing__topbar-link:hover {
  color: var(--accent);
  background-size: 100% 2px;
}
/* Sign-in CTA — promoted out of the muted nav row with the accent
   colour + an inset bottom rule so it reads as the call-to-action
   tucked into the right of the bar. */
.landing__topbar-link--cta {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1.5px;
  background-image: none;
}
.landing__topbar-link--cta:hover {
  color: var(--accent-hi);
}

/* ── Main column ─────────────────────────────────────────────────
   Each section uses a `__section` wrapper for the full-width band
   (lets us add dividers / alt backgrounds later) and a `__section-
   inner` to constrain the readable column width to ~60rem. */
.landing__main {
  display: flex;
  flex-direction: column;
}
.landing__section {
  width: 100%;
  padding: var(--size-7) var(--size-4);
}
.landing__section + .landing__section {
  /* No structural divider line — the eye gets the section break from
     the heading's leading whitespace + the typographic shift. Keeps
     the page from reading as a series of equal-weight panels. */
  padding-top: var(--size-6);
}
.landing__section-inner {
  width: min(60rem, 100%);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: var(--size-3);
}
.landing__h2 {
  margin: 0;
  font-size: var(--font-size-6);
  letter-spacing: -0.01em;
}
.landing__lede {
  margin: 0;
  color: var(--muted);
  font-size: var(--font-size-2);
  max-width: 60ch;
}
.landing__lede--italic { font-style: italic; }
.landing__hand {
  /* The "We lead with the answer." pivot text between the six
     equal cards and the dominant COMMITMENT MET card. Bold + slightly
     larger so the reader's eye hooks here before dropping into the
     headline card. */
  margin: var(--size-4) 0 0;
  font-weight: 700;
  font-size: var(--font-size-3);
}

/* ── Hero ────────────────────────────────────────────────────────
   Big mark + big name + tagline + subhead + two CTAs. Left-aligned
   like the screenshots so it reads as one continuous block, not a
   centred billboard.

   Structure: `.landing__hero` is the full-width band, `.landing__
   hero-inner` is the centred 60rem readable column. Same pattern as
   every other section's `__section-inner` wrapper. We can't use a
   `> *` width rule here because Open-Props normalize sets
   `max-inline-size: var(--size-header-1)` on :where(h1) and
   `var(--size-content-3)` on :where(p) — those caps fight any
   width we set on the elements themselves. A wrapper sidesteps the
   collision: the wrapper is the column, children left-align in it. */
.landing__hero {
  width: 100%;
  padding: var(--size-7) var(--size-4) var(--size-6);
}
.landing__hero-inner {
  width: min(60rem, 100%);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-start; /* left-align the title block, not centred */
}
/* Children's own max-inline-size still applies WITHIN the column —
   that's the open-props normalize behaviour and it keeps the title
   and subhead line lengths comfortable. */
.landing__hero-mark {
  /* Currentcolor-driven .brand-mark__bar resolves to --accent via
     base.css. Margin-bottom pushes the title clear of the mark. */
  color: var(--accent);
  margin-bottom: var(--size-4);
}
.landing__hero-mark .brand-mark { display: block; }
/* The hero mark is the page's strongest visual anchor — we want it
   bigger than the title type. Bump it via an explicit size so it
   matches the screenshot proportions on every viewport. */
.landing__hero-title {
  margin: 0 0 var(--size-2);
  font-size: clamp(2.5rem, 6vw, 4.5rem);
  letter-spacing: -0.03em;
  line-height: 1.05;
}
.landing__hero-tagline {
  margin: 0 0 var(--size-3);
  font-size: var(--font-size-4);
  color: var(--muted);
}
.landing__hero-subhead {
  margin: 0 0 var(--size-5);
  font-size: var(--font-size-2);
  color: var(--muted);
  max-width: 50ch;
}
.landing__hero-ctas {
  display: flex;
  flex-wrap: wrap;
  gap: var(--size-3);
  align-items: center;
}
/* The secondary CTA in the hero is the unshadowed sibling of the
   primary (per wireframe). Override the default .btn shadow. */
.landing__cta-secondary {
  box-shadow: none;
  text-decoration: none;
}

/* ── The problem — six small cards row ──────────────────────────
   Tiny stat cards rendered in mono so the COMMITMENT-MET card
   below them reads as the dominant element. Mirrors the wireframe's
   "what most tools show" vs. "we lead with the answer" pivot. */
.landing__six-cards {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: var(--size-2);
  margin-top: var(--size-3);
}
.landing__small-stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--size-1);
  padding: var(--size-3) var(--size-2);
  background: var(--surface);
  border: 2px solid var(--border-soft);
  text-align: center;
}
.landing__small-stat .stat-label {
  font-size: var(--font-size-00);
  letter-spacing: 0.1em;
}
.landing__small-stat .stat-value {
  font-size: var(--font-size-3);
  font-weight: 700;
}

/* Single-column under ~720px — wireframe says collapse 6×1 to 3×2. */
@media (max-width: 720px) {
  .landing__six-cards { grid-template-columns: repeat(3, 1fr); }
}

/* ── COMMITMENT MET headline card ───────────────────────────────
   The dominant element of the problem section: accent-pale fill +
   thick accent border (matches the reference design's summary card
   primitive). Hard paper shadow per Garden Grid. */
.landing__headline-card {
  background: var(--accent-pale);
  border: 2px solid var(--accent-hi);
  border-left: 6px solid var(--accent-hi);
  box-shadow: var(--shadow-rest);
  padding: var(--size-5) var(--size-5);
  display: flex;
  flex-direction: column;
  gap: var(--size-2);
}
.landing__headline-kicker {
  margin: 0 0 var(--size-1);
  color: var(--accent-hi);
  padding-top: 0;
  border-top: none;
}
.landing__headline-row {
  display: flex;
  align-items: flex-start;
  gap: var(--size-2);
  font-family: var(--font-mono);
  color: var(--accent-hi);
  line-height: 1;
}
.landing__headline-value {
  font-size: clamp(3.5rem, 9vw, 6rem);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
.landing__headline-unit {
  font-size: clamp(2rem, 5vw, 3rem);
  font-weight: 700;
}
.landing__headline-sub {
  font-family: var(--font-mono);
  font-size: var(--font-size-0);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--accent-hi);
}
.landing__headline-diagnosis {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--font-size-1);
  color: var(--accent-hi);
}
.landing__headline-card .divider-soft {
  border-top-color: var(--accent-hi);
  opacity: 0.4;
  margin: var(--size-2) 0;
}

/* ── Sparkline cells (▓░) ────────────────────────────────────────
   Used in the headline card and in the leaderboard rows. Each cell
   is a flex row item with a fixed minimum height; ".is-on" is the
   filled accent variant, default is the dim track. */
.landing__spark {
  display: flex;
  gap: 3px;
  align-items: stretch;
  height: 1.4rem;
}
.landing__spark-cell {
  flex: 1 1 0;
  min-width: 0;
  background: var(--accent-hi);
  opacity: 0.25;
}
.landing__spark-cell.is-on { opacity: 1; }

/* ── Dev-done flow ──────────────────────────────────────────────
   Status pills + arrows. The active step (DEV-DONE) is the accent-
   filled chip, others are bordered-only chips. Wraps under ~720px
   so each step gets its own line, with arrows still visible. */
.landing__flow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--size-2);
  padding: var(--size-4);
  background: var(--surface);
  border: 2px solid var(--border);
  box-shadow: var(--shadow-rest);
}
.landing__flow-step {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-mono);
  font-size: var(--font-size-1);
  font-weight: 600;
  padding: var(--size-2) var(--size-3);
  border: 2px solid var(--border);
  background: var(--surface);
  color: var(--fg);
}
.landing__flow-step.is-active {
  background: var(--accent-hi);
  color: #ffffff;
  border-color: var(--accent-hi);
}
.landing__flow-arrow {
  font-family: var(--font-mono);
  color: var(--muted);
  font-size: var(--font-size-2);
}
.landing__flow-caption {
  margin: var(--size-2) 0 0;
  color: var(--muted);
  max-width: 60ch;
}
.landing__flow-reopen {
  margin: 0;
  font-size: var(--font-size-2);
  color: var(--fg);
}

/* ── Leaderboards ───────────────────────────────────────────────
   Two cards side-by-side. Use existing `.card` primitive for the
   border + shadow; landing-specific styles only for the list rows. */
.landing__leader-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--size-3);
}
@media (max-width: 720px) {
  /* Wireframe: stack vertically; framing line stays above the stack. */
  .landing__leader-grid { grid-template-columns: 1fr; }
}
.landing__leader-card {
  /* Override the default `.card` width so the grid cell controls it. */
  width: 100%;
}
.landing__leader-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.landing__leader-row {
  display: grid;
  grid-template-columns: 2rem 1fr auto auto;
  align-items: center;
  gap: var(--size-2);
  padding: var(--size-2) 0;
  border-bottom: 1px solid var(--border-soft);
}
.landing__leader-row:last-child { border-bottom: none; }
.landing__leader-rank {
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--muted);
}
.landing__leader-name {
  font-size: var(--font-size-2);
  color: var(--fg);
}
.landing__leader-pct {
  font-family: var(--font-mono);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--fg);
}
.landing__leader-trend { color: var(--red); }
.landing__leader-bar {
  display: inline-flex;
  gap: 2px;
  width: 7rem;
  height: 0.9rem;
}
.landing__leader-bar .landing__spark-cell {
  /* The inner cells share the same .is-on styling as the sparkline. */
}
.landing__leader-note {
  margin: var(--size-2) 0 0;
  font-family: var(--font-mono);
  font-style: italic;
  font-size: var(--font-size-0);
  color: var(--muted);
}

/* ── 1-on-1 lens — per-dev block ────────────────────────────────
   Definition list giving four indicator → value rows. Mono labels,
   mixed mono/sans values so cycle/bounce text reads naturally. */
.landing__person-card { width: 100%; gap: var(--size-3); }
.landing__person-head {
  display: flex;
  align-items: baseline;
  gap: var(--size-2);
  border-bottom: 2px solid var(--border-soft);
  padding-bottom: var(--size-2);
}
.landing__person-name {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: var(--font-size-3);
  letter-spacing: 0.04em;
  color: var(--fg);
}
.landing__person-window {
  font-family: var(--font-mono);
  font-size: var(--font-size-0);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
}
.landing__person-grid {
  display: grid;
  grid-template-columns: minmax(8rem, max-content) 1fr;
  /* `align-items: baseline` ties each dt to its dd along the text
     baseline — much cleaner read for a label/value list than the
     default `align-items: stretch` (which would top-align them and
     drift visually as soon as the dd has a chip or bar inside). */
  align-items: baseline;
  gap: var(--size-2) var(--size-3);
  margin: 0;
}
.landing__person-grid dt {
  /* Open-Props normalize (with very low :where() specificity) sets
     `margin-block-start: var(--size-5)` on every dt after the first,
     to space them out in a flow-style definition list. That margin
     also fires inside grid cells, pushing each dt~1.25rem below the
     dd it should sit beside — so the value visually attaches to the
     PREVIOUS label. Zeroing it restores the row alignment.
     Ref: https://developer.mozilla.org/en-US/docs/Web/CSS/margin-block-start */
  margin: 0;
  font-size: var(--font-size-1);
  font-weight: 700;
  color: var(--muted);
}
.landing__person-grid dd {
  margin: 0;
  /* Same family of fixes — normalize sets `max-inline-size:
     var(--size-content-2)` on dd; explicit `none` lets long values
     (e.g. a row of ticket-key chips) lay out on one line. */
  max-inline-size: none;
  font-size: var(--font-size-1);
  color: var(--fg);
}
.landing__person-bar-cell {
  display: inline-flex;
  align-items: center;
  gap: var(--size-2);
}
.landing__person-pct {
  font-family: var(--font-mono);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ── Bullets (Who it's for / Honesty) ───────────────────────────
   ▓ / ░ bullet rows. Pulled visually from the reference design's
   accent-bar bullets — a 3px accent column on the left + the
   inline mark glyph + the body text. The ghost variant softens
   both the column and the mark for "not for…" bullets. */
.landing__bullets-group { margin-bottom: var(--size-5); }
.landing__bullets-group:last-child { margin-bottom: 0; }
.landing__bullets {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--size-3);
}
.landing__bullet-row {
  display: grid;
  grid-template-columns: 1.4rem 1fr;
  align-items: start;
  gap: var(--size-3);
  padding: var(--size-1) 0 var(--size-1) var(--size-3);
  border-left: 3px solid var(--accent);
  font-size: var(--font-size-2);
}
.landing__bullet-row--ghost {
  border-left-color: var(--border-soft);
  color: var(--muted);
}
.landing__bullet {
  width: 1em;
  height: 1em;
  fill: var(--accent);
  margin-top: 0.25em;
}
.landing__bullet--ghost {
  fill: var(--border-soft);
  opacity: 0.6;
}

/* ── Closing CTA ────────────────────────────────────────────────
   Repeat of the hero primary. Centred, generous vertical breathing
   room so it doesn't feel like the page is still going underneath. */
.landing__section--closing {
  padding-top: var(--size-5);
  padding-bottom: var(--size-7);
}
.landing__section--closing .landing__section-inner {
  align-items: center;
}

/* ── Footer ─────────────────────────────────────────────────────
   Quiet, single line: mark + name on the left, tagline middle, year
   right. White-ish surface band so it visually closes the page. */
.landing__footer {
  width: 100%;
  background: var(--surface);
  border-top: 2px solid var(--border);
}
.landing__footer-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--size-3);
  flex-wrap: wrap;
  width: min(60rem, 100%);
  margin: 0 auto;
  padding: var(--size-3) var(--size-4);
}
.landing__footer-brand {
  display: inline-flex;
  align-items: center;
  gap: var(--size-2);
  color: var(--accent);
}
.landing__footer-tag {
  font-family: var(--font-body);
  color: var(--muted);
  font-size: var(--font-size-1);
}
.landing__footer-year {
  font-family: var(--font-mono);
  font-size: var(--font-size-0);
  color: var(--muted);
}

/* ── Narrow viewport tweaks ─────────────────────────────────────
   Single-column under ~720px (per wireframe). */
@media (max-width: 720px) {
  .landing__section { padding: var(--size-5) var(--size-3); }
  .landing__h2 { font-size: var(--font-size-5); }
  .landing__hero { padding: var(--size-5) var(--size-3) var(--size-4); }
  .landing__hero-mark svg { width: 140px; height: 140px; }
  .landing__topbar-inner { padding: var(--size-2) var(--size-3); }
  .landing__topbar-link { padding: var(--size-1) var(--size-2); }
}
