/* ============================================================
   Dashboard V1 — Pipeline styles
   Scoped with `dash-pipeline*` prefix. Legacy `.dash-pipeline`
   (flex-row status-tab strip in `.dash-card--grants`) was renamed
   to `.dash-status-tabs` in the Phase 1 refactor — no collision.
   ============================================================ */

/* ─── Next-action banner ─── */
.dash-next-action {
  margin: 10px 0 14px;
  background: #FFFDFA;
  border: 1px solid #2D6A4F;
  border-left-width: 3px;
  border-radius: 8px;
  padding: 11px 14px 11px 16px;
  display: flex;
  gap: 14px;
  align-items: center;
}
.dash-next-action__prefix {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #1F4A37;
  font-weight: 700;
  white-space: nowrap;
}
.dash-next-action__body {
  flex: 1;
  font-family: 'Fraunces', Georgia, serif;
  font-size: 14px;
  font-weight: 500;
  color: #1A1814;
  letter-spacing: -0.005em;
  line-height: 1.35;
}
.dash-next-action__body strong { font-weight: 600; }
.dash-next-action__deadline {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  color: #9F4121;
  font-weight: 700;
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.dash-next-action__cta {
  background: #1A1814;
  color: #FFFDFA;
  border: none;
  padding: 7px 14px;
  border-radius: 5px;
  font-family: var(--dash-font-body);   /* 2026-07-27: was 'DM Sans', which dashboard.html never loads */
  font-weight: 600;
  font-size: 12px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
  min-height: 44px; /* V1.1 Fix #3 (WCAG 2.5.5 — was 28px) */
}
.dash-next-action__cta:hover { background: #3A362E; }

/* ─── Instant-Draft "your started application is ready" banner ───
   (2026-06-08) Slim, dismissible band shown above the pipeline when a
   freshly-generated url-scan/instant-draft is waiting. Visually consistent
   with .dash-next-action: forest left-accent, cream background. */
.dash-idraft-banner {
  margin: 10px 0 14px;
  background: linear-gradient(135deg, #F4FBF6, #FFFDFA);
  border: 1px solid #2D6A4F;
  border-left-width: 3px;
  border-radius: 8px;
  padding: 11px 14px 11px 16px;
  display: flex;
  gap: 12px;
  align-items: center;
}
.dash-idraft-banner__mark {
  color: #1F4A37;
  font-size: 16px;
  line-height: 1;
  flex-shrink: 0;
}
.dash-idraft-banner__text {
  flex: 1;
  min-width: 0;
  font-family: 'Fraunces', Georgia, serif;
  font-size: 14px;
  font-weight: 500;
  color: #1A1814;
  letter-spacing: -0.005em;
  line-height: 1.35;
}
.dash-idraft-banner__text strong { font-weight: 600; }
.dash-idraft-banner__open {
  background: #1A1814;
  color: #FFFDFA;
  border: none;
  padding: 7px 14px;
  border-radius: 5px;
  font-family: var(--dash-font-body);   /* 2026-07-27: was 'DM Sans', which dashboard.html never loads */
  font-weight: 600;
  font-size: 12px;
  cursor: pointer;
  white-space: nowrap;
  min-height: 44px;
  flex-shrink: 0;
}
.dash-idraft-banner__open:hover { background: #3A362E; }
.dash-idraft-banner__dismiss {
  background: transparent;
  border: none;
  color: #6B6458;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.dash-idraft-banner__dismiss:hover { color: #1A1814; }
@media (max-width: 640px) {
  .dash-idraft-banner { flex-wrap: wrap; }
  .dash-idraft-banner__text { flex-basis: calc(100% - 68px); }
  .dash-idraft-banner__open { flex: 1; }
}

/* ─── Pipeline header ─── */
.dash-pipeline-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 0 12px;
  margin-bottom: 16px;
  border-bottom: 1px solid #E8E1D4;
  flex-wrap: wrap;
}
.dash-pipeline-head__left {
  display: flex;
  align-items: baseline;
  gap: 18px;
  min-width: 0;
  flex-wrap: wrap;
}
.dash-pipeline-head__title {
  font-family: 'Fraunces', Georgia, serif;
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: #1A1814;
  margin: 0;
}
.dash-pipeline-head__meta {
  display: block;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  color: #6B6458;
  letter-spacing: 0.02em;
}
.dash-pipeline-head__meta strong {
  color: #1A1814;
  font-weight: 600;
  font-family: 'Fraunces', serif;
  font-size: 13px;
}
.dash-pipeline-head__meta .sep { color: #C9C2B5; }
/* Apr 25 2026 (strategic decision B-new) — two-line meta. Top line is
   the rollup (active count · pipeline value · next deadline · saved).
   Sub-line surfaces a single concrete "Most likely" anchor (highest-EV
   pursuit by realistic value × deadline proximity). */
.dash-pipeline-meta__primary {
  display: flex;
  align-items: baseline;
  gap: 4px 14px;
  flex-wrap: wrap;
}
.dash-pipeline-meta__subline {
  margin-top: 5px;
  font-size: 11.5px;
  color: #6B6458;
  letter-spacing: 0.01em;
  font-family: var(--dash-font-body);   /* 2026-07-27: was 'DM Sans', which dashboard.html never loads */
}
.dash-pipeline-meta__subline strong {
  color: #1A1814;
  font-weight: 600;
  font-family: 'Fraunces', serif;
  font-size: 12.5px;
}
.dash-pipeline-meta__label {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 10.5px;
  color: #8a857d;
  font-weight: 600;
  font-family: 'IBM Plex Mono', monospace;
}
.dash-pipeline-meta__hint {
  cursor: help;
  color: #8a857d;
  font-size: 10px;
  margin-left: 2px;
  vertical-align: super;
}
/* 2026-05-15 (Lens 6 P1-E + sprint-2 verification): the bookmark counter
   is now an anchor so users can reach their saved-but-not-pursued grants
   from the dashboard. Sprint-2 verification flagged the dotted-underline
   as not visible — bumped the dotted weight to 1.5px + sienna tint so
   the interactive hint actually reads as one. */
.dash-pipeline-meta__bookmarks-link {
  color: inherit;
  text-decoration: none;
  border-bottom: 1.5px dotted #8a857d;
  padding-bottom: 1px;
  transition: border-color .12s, color .12s;
  cursor: pointer;
}
.dash-pipeline-meta__bookmarks-link:hover,
.dash-pipeline-meta__bookmarks-link:focus-visible {
  color: var(--forest, #2D6A4F);
  border-bottom-color: var(--forest, #2D6A4F);
}
.dash-pipeline-meta__bookmarks-link:focus-visible {
  outline: 2px solid var(--forest, #2D6A4F);
  outline-offset: 3px;
  border-radius: 2px;
}
.dash-pipeline-head__actions {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-shrink: 0;
}

.dash-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: 6px;
  font-family: var(--dash-font-body);   /* 2026-07-27: was 'DM Sans', which dashboard.html never loads */
  font-weight: 600;
  min-height: 44px; /* V1.1 Fix #4 (WCAG 2.5.5 — was 32px for --ghost/--primary) */
  font-size: 12px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: all 120ms ease;
  text-decoration: none;
}
.dash-btn--primary { background: #1A1814; color: #FFFDFA; }
.dash-btn--primary:hover { background: #3A362E; }
.dash-btn--ghost { background: #FFFDFA; color: #3A362E; border-color: #E8E1D4; }
.dash-btn--ghost:hover { background: #F4EEDF; border-color: #A39B8C; }

/* ─── Pipeline stage groups ─── */
.dash-pipeline-stage {
  margin-bottom: 22px;
}
.dash-pipeline-stage__head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 4px 10px 12px;
  margin-bottom: 10px;
  border-left: 3px solid #A39B8C;
  border-bottom: 1px solid #E8E1D4;
  cursor: pointer;
  user-select: none;
}
/* Keyboard focus ring for the ARIA-button stage head (a11y wave 2026-07-24). */
.dash-pipeline-stage__head:focus-visible {
  outline: 2.5px solid #1F4A37;
  outline-offset: 2px;
}
.dash-pipeline-stage__name {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #3A362E;
  font-weight: 700;
}
.dash-pipeline-stage__count {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10px;
  color: #6B6458;
  font-weight: 600;
  background: #F4EEDF;
  padding: 2px 8px;
  border-radius: 10px;
}
.dash-pipeline-stage__chev {
  margin-left: auto;
  color: #A39B8C;
  font-family: 'Fraunces', serif;
  font-size: 14px;
  transition: transform 180ms ease;
}
.dash-pipeline-stage.collapsed .dash-pipeline-stage__chev {
  transform: rotate(-90deg);
}
.dash-pipeline-stage.collapsed .dash-pipeline-stage__body {
  display: none;
}

/* Stage-specific accent colors — the left-border is the primary stage indicator */
.dash-pipeline-stage--tracking .dash-pipeline-stage__head { border-left-color: #A39B8C; }
.dash-pipeline-stage--drafting .dash-pipeline-stage__head { border-left-color: #C4532B; background: linear-gradient(to right, rgba(196, 83, 43, 0.04), transparent 40%); }
.dash-pipeline-stage--submitted .dash-pipeline-stage__head { border-left-color: #2D6A4F; background: linear-gradient(to right, rgba(45, 106, 79, 0.04), transparent 40%); }
.dash-pipeline-stage--won .dash-pipeline-stage__head { border-left-color: #2D6A4F; background: linear-gradient(to right, rgba(45, 106, 79, 0.08), transparent 40%); }
.dash-pipeline-stage--won .dash-pipeline-stage__count { background: #E8EFEA; color: #1F4A37; }
.dash-pipeline-stage--drafting .dash-pipeline-stage__count { background: #F8E8DF; color: #9F4121; }
/* QA polish round 2 (A3): dimming the whole head with opacity:0.55 dropped the
   uppercase stage label to ~1.7:1 contrast (axe serious). Mute it with an
   accessible muted-ink color + lighter border instead — keeps the "this stage
   is closed/cold" signal without failing WCAG AA. */
.dash-pipeline-stage--lost .dash-pipeline-stage__head { border-left-color: #BCB4A4; }
.dash-pipeline-stage--lost .dash-pipeline-stage__name { color: #6B6458; font-weight: 600; }
.dash-pipeline-stage--lost .dash-pipeline-stage__count { opacity: 0.85; }
.dash-pipeline-stage--lost .dash-pipeline-stage__chev { color: #BCB4A4; }

/* V2 Commit C (Functional-P1-8): empty-stage placeholder — stages with 0
 * grants always render but muted so the pipeline always shows the full
 * 5-stage arc, not just non-empty ones. The body is pointer-events:none so
 * the placeholder doesn't capture clicks meant for other stages.
 */
/* QA polish round 2 (A3): a flat 0.52 opacity on the whole stage dropped the
   stage-name label below 4.5:1. Mute via accessible colors instead — the empty
   stage still reads as "placeholder" without an axe contrast failure. */
.dash-pipeline-stage.is-empty-stage .dash-pipeline-stage__head {
  cursor: default;
  border-left-color: #C9C2B2;
}
.dash-pipeline-stage.is-empty-stage .dash-pipeline-stage__name { color: #6B6458; font-weight: 600; }
.dash-pipeline-stage.is-empty-stage .dash-pipeline-stage__chev { color: #C9C2B2; }
.dash-pipeline-stage.is-empty-stage .dash-pipeline-stage__count { opacity: 0.7; }
.dash-pipeline-stage.is-empty-stage .dash-pipeline-stage__body {
  padding: 8px 16px 14px;
}
.dash-pipeline-stage__empty-note {
  margin: 0;
  font-size: 13px;
  /* V2 Commit C hotfix (Lens 4 finding #3): #8B8275 was 1.80:1 on paper bg,
   * failing WCAG AA. Using --dash-ink-muted token (#706660, ~4.59:1 AA pass). */
  color: #706660;
  font-style: italic;
  line-height: 1.4;
}

/* ─── Pipeline row (per-grant card) ─── */
.dash-pipeline-row {
  background: #FFFDFA;
  border: 1px solid #E8E1D4;
  border-radius: 8px;
  padding: 14px 18px;
  margin-bottom: 8px;
  display: grid;
  /* main | state | deadline | outcome menu | chevron. The menu column is
     RESERVED (2026-07-28) rather than overlaid: it used to be absolutely
     positioned at right:38px, so on hover it covered the deadline and
     overlapped the state pill — the row hid its own information exactly when
     the member reached for it. An element that appears on hover has to have
     somewhere to appear. */
  grid-template-columns: minmax(0, 1fr) 132px 62px 104px 14px;
  gap: 16px;
  align-items: center;
  cursor: pointer;
  transition: all 120ms ease;
  text-decoration: none;
  color: inherit;
  position: relative;
}
.dash-pipeline-row:hover {
  border-color: #1F4A37;
  transform: translateY(-1px);
  box-shadow: 0 3px 10px rgba(26, 24, 20, 0.06);
}
.dash-pipeline-row--urgent { border-left: 3px solid #C4532B; padding-left: 17px; }
.dash-pipeline-row--warm { border-left: 3px solid #B8851C; padding-left: 17px; }

.dash-pipeline-row__main {
  min-width: 0;
}
.dash-pipeline-row__name {
  font-family: 'Fraunces', serif;
  font-size: 15px;
  font-weight: 600;
  color: #1A1814;
  letter-spacing: -0.005em;
  line-height: 1.3;
  margin-bottom: 4px;
}
.dash-pipeline-row__meta {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  color: #6B6458;
  letter-spacing: 0.02em;
}
.dash-pipeline-row__meta .sep { color: #C9C2B5; margin: 0 5px; }

/* ── The "what is this one about?" line (2026-07-28) ──────────────────────────
   Replaces the approval-rate line, which had NO CSS RULE AT ALL — it inherited
   the page default, rendering LARGER than the 15px serif title above it and in a
   font belonging to neither the title (Fraunces) nor the meta (IBM Plex Mono).
   This is prose, so it takes the body sans deliberately — a third voice would be
   noise, but reading a program's purpose in a monospace label font is worse.
   Sized BELOW the title and the meta so the row still reads title-first, and
   hard-clamped to one line: the whole point is a scannable list, and the full
   description is one hover away. */
.dash-pipeline-row__gist {
  font-family: var(--dash-font-body);
  font-size: 12.5px;
  line-height: 1.4;
  color: #6B6458;
  margin-top: 3px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dash-pipeline-row__meta strong { color: #1A1814; font-weight: 700; font-family: 'Fraunces', serif; font-size: 12px; }

.dash-pipeline-row__progress {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 0;
}
.dash-pipeline-row__progress-bar {
  height: 6px;
  background: #F0EBE0;
  border-radius: 3px;
  overflow: hidden;
}
.dash-pipeline-row__progress-bar div {
  height: 100%;
  background: #2D6A4F;
  border-radius: 3px;
  transition: width 220ms ease;
}
.dash-pipeline-row--urgent .dash-pipeline-row__progress-bar div { background: #C4532B; }
.dash-pipeline-row__progress-label {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10px;
  color: #6B6458;
  letter-spacing: 0.04em;
  font-weight: 600;
  text-align: right;
}

.dash-pipeline-row__deadline {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 13px;
  font-weight: 700;
  color: #6B6458;
  text-align: right;
  letter-spacing: 0.02em;
}
.dash-pipeline-row__deadline--urgent { color: #9F4121; }
.dash-pipeline-row__deadline--warm { color: #B8851C; }
.dash-pipeline-row__deadline--cool { color: #6B6458; font-weight: 600; }

/* Apr 25 (post-blind-review #14 / 7-bug Bug 7) — was #C9C2B5 (very faded
   tan) which made rows look like static list items. Lifted to forest
   green at 55% opacity so the row's interactivity is visible at rest;
   animates to 100% opacity + 4px nudge on hover.
   V3 Sprint 2 Item 7 (2026-05-01) — switched from text "›" to a proper
   SVG chevron-right + bumped contrast on rest state for stronger
   drawer-open affordance. */
.dash-pipeline-row__chev {
  color: #1F4A37;
  opacity: 0.55;
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  transition: transform 150ms ease, opacity 150ms ease;
  line-height: 1;
}
.dash-pipeline-row:hover .dash-pipeline-row__chev {
  opacity: 1;
  transform: translateX(4px);
}

/* V3 Sprint 2 Item 7 (2026-05-01) — first-3-hovers tooltip on pipeline
   rows. JS adds .dash-pipeline-row--show-hint to each row until the
   sessionStorage hover counter (gc_pipeline_hover_count) hits 3. Tooltip
   only renders for rows with the class AND on hover/focus. Pure CSS —
   no JS positioning. */
.dash-pipeline-row--show-hint {
  /* spacing for the tooltip below — prevents overlap with the next row */
}
.dash-pipeline-row--show-hint::after {
  content: 'Open workspace →';
  position: absolute;
  bottom: -10px;
  right: 12px;
  background: #1A1814;
  color: #FAF7F2;
  font-size: 11px;
  font-weight: 500;
  padding: 5px 10px;
  border-radius: 5px;
  letter-spacing: 0.01em;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 180ms ease, transform 180ms ease;
  z-index: 5;
  box-shadow: 0 3px 10px rgba(26, 24, 20, 0.18);
}
.dash-pipeline-row--show-hint:hover::after,
.dash-pipeline-row--show-hint:focus-within::after {
  opacity: 1;
  transform: translateY(0);
}

/* V3 Sprint 2 Item 5 (2026-05-01) — first-pursuit pulse animation on
   the new pipeline row. Forest-green ring pulses 3 times then fades.
   JS adds the class on first pursuit (count 0 → 1) and strips it after
   6 seconds. Pure CSS — no JS animation lib. */
.dash-pipeline-row--first-pursuit {
  animation: dashFirstPursuitPulse 2s ease-out 0s 3;
  position: relative;
}
@keyframes dashFirstPursuitPulse {
  0% {
    box-shadow: 0 0 0 0 rgba(45, 106, 79, 0.55), 0 3px 10px rgba(26, 24, 20, 0.08);
    border-color: #2D6A4F;
  }
  60% {
    box-shadow: 0 0 0 14px rgba(45, 106, 79, 0), 0 3px 10px rgba(26, 24, 20, 0.08);
    border-color: #2D6A4F;
  }
  100% {
    box-shadow: 0 0 0 0 rgba(45, 106, 79, 0), 0 3px 10px rgba(26, 24, 20, 0.06);
    border-color: #1F4A37;
  }
}
@media (prefers-reduced-motion: reduce) {
  .dash-pipeline-row--first-pursuit {
    animation: none;
    border-color: #2D6A4F;
    box-shadow: 0 0 0 3px rgba(45, 106, 79, 0.25);
  }
}

/* Touch-feedback for mobile — clear visual confirmation that the row
   is being tapped. Subtle scale-down + faster transition for tactile
   feel on touch devices. */
@media (hover: none) and (pointer: coarse) {
  .dash-pipeline-row:active {
    transform: scale(0.99);
    transition: transform 80ms ease;
    background: #F8F5EE;
  }
  .dash-pipeline-row__chev {
    opacity: 0.7; /* slightly stronger on touch — no hover state to discover */
  }
  /* Hide the tooltip on touch — it never reads correctly on tap (no hover),
     and the visual press feedback is sufficient affordance. */
  .dash-pipeline-row--show-hint::after { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .dash-pipeline-row,
  .dash-pipeline-row__chev,
  .dash-pipeline-row--show-hint::after {
    transition: none;
  }
  .dash-pipeline-row:hover {
    transform: none;
  }
  .dash-pipeline-row:hover .dash-pipeline-row__chev {
    transform: none;
  }
}

/* Next-action line (below main row) */
.dash-pipeline-row__next {
  grid-column: 1 / -1;
  font-family: var(--dash-font-body);   /* 2026-07-27: was 'DM Sans', which dashboard.html never loads */
  font-size: 12.5px;
  color: #1A1814;
  padding-top: 10px;
  margin-top: 10px;
  border-top: 1px dashed #F0EBE0;
  line-height: 1.45;
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.dash-pipeline-row__next-label {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #9F4121;
  font-weight: 700;
  padding: 2px 7px;
  background: #F8E8DF;
  border-radius: 3px;
  flex-shrink: 0;
}
.dash-pipeline-row__next strong { color: #1A1814; font-weight: 600; }

/* Loss -> motion recovery strip (2026-08-28). Rendered as a SIBLING after the row
   anchor (links may not nest inside links); tucked under its card like a thread
   reply. Dead rows get "Similar open programs"; between-intakes/paused/upcoming
   get the reopen-alert door. */
.dash-pipeline-row__recover {
  margin: -2px 0 10px 14px;
  padding: 7px 12px;
  background: #FBF7EF;
  border: 1px solid #EFE8D9;
  border-radius: 6px;
  font-family: var(--dash-font-body);
  font-size: 12.5px;
  line-height: 1.5;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px;
}
.dash-pipeline-row__recover-label {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase;
  color: #7A6A4F; font-weight: 700; padding: 2px 7px;
  background: #F1E9D8; border-radius: 3px; flex-shrink: 0;
}
.dash-pipeline-row__recover-link {
  color: #9F4121; font-weight: 600; text-decoration: none;
  /* inline-link tap target: pad the hit area without moving the line */
  padding: 6px 2px; margin: -6px -2px;
}
.dash-pipeline-row__recover-link:hover,
.dash-pipeline-row__recover-link:focus-visible { text-decoration: underline; }
.dash-pipeline-row__recover-sep { color: #C9BFA9; }

/* Stage change dropdown (inline on each row) */
/* B4 fix: vertically center via top:50%/translateY(-50%) instead of top:10px
   (which left the select misaligned with the stage column and its 44px height
   overlapping the deadline text in the row). z-index:10 ensures the dropdown
   paints above adjacent rows when open (they have position:relative but no
   explicit z-index, defaulting to auto/0 in the stacking order). */
.dash-pipeline-row__stage-change {
  /* In flow, in its own column — no longer absolute, so it cannot cover the
     deadline or collide with the state pill. */
  min-width: 0;
  opacity: 0;
  transition: opacity 150ms ease;
}
/* focus-within so keyboard users can reach it — an opacity:0 control is
   reachable by Tab and was previously invisible while focused. */
.dash-pipeline-row:hover .dash-pipeline-row__stage-change,
.dash-pipeline-row:focus-within .dash-pipeline-row__stage-change { opacity: 1; }
.dash-pipeline-row__stage-change select {
  /* Was IBM Plex Mono 9px uppercase on beige — a FOURTH typographic voice in a
     row that already carries a serif title, a mono meta line and a pill. It read
     as borrowed from another product. Now it matches the row's own body voice and
     the pill's rounding, and recedes until hovered. */
  width: 100%;
  font-family: var(--dash-font-body);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  background: #FFFDFA;
  border: 1px solid #E0D9CB;
  border-radius: 999px;
  padding: 0 10px;
  min-height: 44px; /* V1.1 hotfix (P0.2 — WCAG 2.5.5): was 19.5px native OS select height. */
  color: #57534E;
  cursor: pointer;
}
.dash-pipeline-row__stage-change select:hover { border-color: #C9C2B5; color: #3A362E; }
/* V2 Commit D (polish-4): explicit :focus-visible ring so Windows High
 * Contrast Mode users see a focus indicator. Without `outline:`, HCM
 * strips box-shadow + background, leaving no visual focus cue. */
.dash-pipeline-row__stage-change select:focus-visible {
  outline: 2.5px solid #1F4A37;
  outline-offset: 2px;
}

/* ────────────────────────────────────────────────────────────
   V3 Sprint 2 — Item 1 (2026-05-01) — Recommended-grants empty state.
   Renders inside #dashPipeline when appEntries.length === 0. Replaces
   the deficit-framed static "Take quiz / Browse" CTAs with active
   pursue-able recommendations (or a stronger no-quiz pitch).
*/
.dash-pipeline-recs {
  background: linear-gradient(180deg, #FFFDFA 0%, #FAF7F2 100%);
  border: 1px solid #E8E1D4;
  border-radius: 12px;
  padding: 28px 24px 24px;
  margin: 4px 0 16px;
}
.dash-pipeline-recs__head {
  margin: 0 0 20px;
}
.dash-pipeline-recs__eyebrow {
  display: inline-block;
  color: #2D6A4F;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-bottom: 8px;
  font-family: 'IBM Plex Mono', monospace;
}
.dash-pipeline-recs__heading {
  font-family: 'Fraunces', serif;
  font-size: 22px;
  font-weight: 500;
  color: #1A1814;
  margin: 0 0 6px;
  letter-spacing: -0.01em;
  line-height: 1.2;
}
.dash-pipeline-recs__sub {
  font-size: 14px;
  color: #6B6458;
  margin: 0;
  line-height: 1.5;
}
.dash-pipeline-recs__sub strong {
  color: #1A1814;
  font-weight: 600;
}
.dash-pipeline-recs__edit {
  color: #2D6A4F;
  text-decoration: underline;
  text-decoration-color: rgba(45, 106, 79, 0.4);
  text-underline-offset: 2px;
  font-weight: 500;
}
.dash-pipeline-recs__edit:hover {
  text-decoration-color: #2D6A4F;
}
.dash-pipeline-recs__list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0 0 14px;
}
.dash-pipeline-recs__footnote {
  font-size: 12px;
  color: #8B8475;
  margin: 0;
  font-style: italic;
  text-align: center;
  line-height: 1.4;
}
.dash-pipeline-recs__footnote strong {
  font-style: normal;
  color: #1F4332;
  font-weight: 600;
}

/* Recommendation row card — pursue-able grant */
.dash-rec-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 16px;
  background: #FFFFFF;
  border: 1px solid #E8E1D4;
  border-radius: 10px;
  padding: 16px 18px;
  align-items: start;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease;
}
.dash-rec-row:hover {
  border-color: #2D6A4F;
  box-shadow: 0 2px 8px rgba(45, 106, 79, 0.08);
  transform: translateY(-1px);
}
.dash-rec-row__main {
  min-width: 0;
}
.dash-rec-row__reason {
  display: inline-block;
  background: #F0FDF4;
  color: #14532D;
  font-size: 11px;
  font-weight: 600;
  padding: 3px 8px;
  border-radius: 10px;
  margin-bottom: 6px;
  letter-spacing: 0.02em;
}
/* A "Worth checking: Only if your business …" condition: a caution in a neutral tone, never the green "fits you"
   pill, and never taller than two lines (full text in the title attribute). 2026-09-23. */
.dash-rec-row__reason.dash-rec-row__reason--check,
.dash-rec-item__reason.dash-rec-item__reason--check {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  background: #FEF7EC;
  color: #7A4A12;
  border: 1px solid #F1DDBE;
  font-weight: 500;
  letter-spacing: 0;
  line-height: 1.35;
  max-width: 100%;
}
.dash-rec-row__title {
  font-family: 'Fraunces', serif;
  font-size: 16px;
  font-weight: 500;
  color: #1A1814;
  margin: 0 0 3px;
  line-height: 1.3;
  letter-spacing: -0.005em;
}
.dash-rec-row__org {
  font-size: 13px;
  color: #6B6458;
  margin: 0 0 8px;
  line-height: 1.4;
}
.dash-rec-row__meta {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  align-items: center;
}
.dash-rec-row__meta li {
  font-size: 12px;
  color: #6B6458;
  line-height: 1.4;
}
.dash-rec-row__meta li:not(:last-child)::after {
  content: '·';
  margin-left: 6px;
  opacity: 0.5;
}
.dash-rec-row__score {
  color: #14532D;
  font-weight: 600;
}
.dash-rec-row__deadline--urgent {
  color: #B91C1C;
  font-weight: 600;
}
.dash-rec-row__deadline--soon {
  color: #B45309;
  font-weight: 600;
}
.dash-rec-row__deadline--ongoing,
.dash-rec-row__deadline--open {
  color: #14532D;
}
.dash-rec-row__actions {
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: stretch;
  min-width: 130px;
}
.dash-rec-row__pursue {
  background: #2D6A4F;
  color: #FFFFFF;
  border: none;
  border-radius: 6px;
  padding: 10px 16px;
  min-height: 44px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.15s ease, transform 0.1s ease;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
}
.dash-rec-row__pursue:hover:not(:disabled) {
  background: #1B4332;
  transform: translateY(-1px);
}
.dash-rec-row__pursue:focus-visible {
  outline: 2px solid #2D6A4F;
  outline-offset: 2px;
}
.dash-rec-row__pursue:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
}
.dash-rec-row__pursue span[aria-hidden] {
  font-size: 16px;
  font-weight: 700;
  line-height: 1;
}
.dash-rec-row__view {
  display: inline-flex;
  justify-content: center;
  font-size: 12px;
  color: #6B6458;
  text-decoration: none;
  padding: 4px 8px;
  font-weight: 500;
}
.dash-rec-row__view:hover {
  color: #2D6A4F;
  text-decoration: underline;
}

/* No-quiz / no-results variants — center the CTAs prominently */
.dash-pipeline-recs--noquiz,
.dash-pipeline-recs--noresults {
  text-align: center;
  padding: 36px 24px 30px;
}
.dash-pipeline-recs--noquiz .dash-pipeline-recs__head,
.dash-pipeline-recs--noresults .dash-pipeline-recs__head {
  max-width: 460px;
  margin: 0 auto 22px;
}
.dash-pipeline-recs__cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  align-items: center;
}
.dash-pipeline-recs__cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 12px 22px;
  min-height: 44px;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.15s ease, transform 0.1s ease;
}
.dash-pipeline-recs__cta--primary {
  background: #2D6A4F;
  color: #FFFFFF;
  border: none;
}
.dash-pipeline-recs__cta--primary:hover {
  background: #1B4332;
  transform: translateY(-1px);
}
.dash-pipeline-recs__cta--secondary {
  background: transparent;
  color: #1F4332;
  border: 1px solid #1F4332;
}
.dash-pipeline-recs__cta--secondary:hover {
  background: #F0FDF4;
}

/* Mobile — stack the row's actions below main, full-width buttons */
@media (max-width: 600px) {
  .dash-pipeline-recs {
    padding: 24px 16px 20px;
  }
  .dash-pipeline-recs__heading { font-size: 19px; }
  .dash-rec-row {
    grid-template-columns: 1fr;
    gap: 12px;
    padding: 14px 16px;
  }
  .dash-rec-row__actions {
    flex-direction: row;
    min-width: 0;
  }
  .dash-rec-row__pursue {
    flex: 1;
  }
  .dash-rec-row__view {
    flex: 0 0 auto;
  }
  .dash-pipeline-recs__cta-row {
    flex-direction: column;
    align-items: stretch;
  }
  .dash-pipeline-recs__cta {
    width: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .dash-rec-row,
  .dash-rec-row__pursue,
  .dash-pipeline-recs__cta--primary {
    transition: none;
  }
  .dash-rec-row:hover,
  .dash-rec-row__pursue:hover:not(:disabled),
  .dash-pipeline-recs__cta--primary:hover {
    transform: none;
  }
}

/* Legacy static empty state (kept for fallback if JS fails to render
   the new recommendations) */
.dash-pipeline-empty {
  text-align: center;
  padding: 48px 20px;
  background: #FFFDFA;
  border: 1px dashed #A39B8C;
  border-radius: 10px;
  margin: 20px 0;
}
.dash-pipeline-empty h3 {
  font-family: 'Fraunces', serif;
  font-size: 20px;
  font-weight: 500;
  color: #1A1814;
  margin: 0 0 8px;
  letter-spacing: -0.01em;
}
.dash-pipeline-empty p {
  font-size: 14px;
  color: #6B6458;
  max-width: 48ch;
  margin: 0 auto 20px;
  line-height: 1.5;
}
.dash-pipeline-empty__actions {
  display: flex;
  gap: 10px;
  justify-content: center;
  flex-wrap: wrap;
}

/* ─── Sort control (pipeline header right side) ─── */
.dash-pipeline-head__sort {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.08em;
  color: #6B6458;
  text-transform: uppercase;
}
.dash-pipeline-head__sort-label { font-weight: 500; }
.dash-pipeline-head__sort select {
  padding: 4px 8px;
  border: 1px solid #E8E1D4;
  border-radius: 4px;
  background: #FFFDFA;
  color: #3A362E;
  font-family: var(--dash-font-body);   /* 2026-07-27: was 'DM Sans', which dashboard.html never loads */
  font-size: 12px;
  cursor: pointer;
  text-transform: none;
  letter-spacing: 0;
  min-height: 44px; /* V1.1 Fix #5 (WCAG 2.5.5 — was 32px) */
}
.dash-pipeline-head__sort select:hover { border-color: #A39B8C; }

/* Task 5.5: Roadmap origin badge on pipeline rows */
.dash-pipeline-row__origin {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #1F4A37;
  background: #E8EFEA;
  padding: 2px 6px;
  border-radius: 3px;
  margin-left: 6px;
  display: inline-block;
  vertical-align: middle;
  font-weight: 600;
}

/* Task 5.5: Context banner shown above pipeline when ≥1 pursuit came from
   the roadmap. Sits inside #dashPipeline (prepended by renderPipeline). */
.dash-pipeline-roadmap-context {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 10px 14px;
  margin: 0 0 14px;
  background: #F8F4EC;
  border: 1px solid #E8E1D4;
  border-radius: 6px;
  font-size: 12px;
  color: #3A362E;
}
.dash-pipeline-roadmap-context strong { color: #1A1814; font-weight: 700; }
.dash-pipeline-roadmap-context a {
  color: #1F4A37;
  text-decoration: none;
  font-weight: 600;
  font-size: 11px;
  white-space: nowrap;
}
.dash-pipeline-roadmap-context a:hover { text-decoration: underline; }

/* Mobile */
@media (max-width: 680px) {
  .dash-pipeline-row {
    /* No reserved menu column on mobile — 104px of a 320px row is a quarter of
       the width for a control that is already forced visible below. */
    grid-template-columns: 1fr auto;
    gap: 8px;
  }
  .dash-pipeline-row__stage-change { grid-column: 1 / -1; }
  .dash-pipeline-row__progress { grid-column: 1 / -1; min-width: 0; }
  /* ⚠ 2026-07-29 — the deadline was landing in visual no-man's land. At this width
     the grid collapses to `1fr auto`, so the deadline cell fell into column 1 and kept
     the desktop `text-align: right` it needs as a right-hand column. Measured on a 390px
     phone: a 224px cell starting at x=19 in a 358px row, so "Rolling" floated in the
     middle with 115px of nothing after it and no column edge to justify against. It is
     the fact that decides whether you can act, styled as though it had been dropped
     there. Full width, left-aligned, directly under the meta it belongs to. */
  .dash-pipeline-row__deadline { grid-column: 1 / -1; text-align: left; }
  .dash-pipeline-row__chev { display: none; }
  .dash-pipeline-head { flex-direction: column; align-items: flex-start; }
  .dash-pipeline-head__actions { width: 100%; flex-wrap: wrap; }
  .dash-next-action { flex-direction: column; align-items: flex-start; gap: 8px; }

  /* Origin badge wraps to its own line under the meta on narrow screens so
     it doesn't push amount off the edge. */
  .dash-pipeline-row__origin {
    margin-left: 0;
    margin-top: 4px;
  }
  .dash-pipeline-roadmap-context {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }
  /* V1.1 hotfix (P0.2): mobile has no hover → force the stage-change dropdown
     always visible so users can actually reach it with touch. Desktop retains
     hover-only behavior via the default opacity:0 rule above. */
  .dash-pipeline-row__stage-change { opacity: 1; }
}

/* V2 CONV-β hotfix (L5 Critical #2): pipeline-row pulse animation when
 * user dismisses the cap-reached paywall via "Remove a grant to free up
 * space". Pre-fix the dismiss was a dead-end (modal closed, user had no
 * next step). Now paywall-modal scrolls pipeline into view + applies
 * this class for ~3s so rows visibly pulse, drawing the user's eye to
 * the rows they can remove via the stage-change dropdown. */
.dash-pipeline-row.is-remove-hint {
  animation: dashRemoveHintPulse 1.1s ease-in-out 3;
  position: relative;
  z-index: 1;
}
@keyframes dashRemoveHintPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(159, 65, 33, 0); }
  50%      { box-shadow: 0 0 0 4px rgba(159, 65, 33, 0.28), 0 2px 12px rgba(159, 65, 33, 0.18); }
}
@media (prefers-reduced-motion: reduce) {
  .dash-pipeline-row.is-remove-hint {
    animation: none;
    box-shadow: 0 0 0 3px rgba(159, 65, 33, 0.32);
  }
}

/* ★ 2026-07-28 (composition round 2) — the free-tier cap line.
   It used to be the last grey 11px monospace fragment of the dot-separated meta
   row: a member who had passed the free tier learned so from the least prominent
   text on the page, sitting under a toolbar whose loudest control invites them to
   add another. Its own line, page body type, and the upgrade path attached — the
   moment a free member outgrows the free tier is the most qualified upgrade
   moment this product has. Deliberately NOT alarm-coloured: nothing enforces the
   cap (ApplicationsStore guards only MAX_APPLICATIONS), so this is information,
   not a wall, and it must not read as though their work is about to stop. */
.dash-pipeline-meta__cap {
  margin-top: 8px;
  font-family: var(--dash-font-body);
  font-size: 12.5px;
  line-height: 1.5;
  color: #4A4438;
  max-width: 62ch;
}
.dash-pipeline-meta__cap strong { color: #1A1814; font-weight: 600; }
.dash-pipeline-meta__cap-link {
  color: #1F5C3D;
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid rgba(31,92,61,0.28);
}
.dash-pipeline-meta__cap-link:hover,
.dash-pipeline-meta__cap-link:focus-visible {
  color: #16452D;
  border-bottom-color: currentColor;
}
