/* ============================================================
   DASHBOARD PAGE — "Warm Editorial Workspace" Design
   GrantCompass /dashboard — Personal Grant Tracking

   Loads AFTER main.css. Uses Fraunces, Plus Jakarta Sans,
   IBM Plex Mono (loaded from HTML <link> tags).
   All classes prefixed with `dash-` to avoid collisions.
   ============================================================ */

/* ============================================================
   CSS VARIABLES
   ============================================================ */

:root {
    /* Layout */
    --dash-max-width: 1200px;
    --dash-navbar-height: 72px;

    /* Typography */
    --dash-font-display: 'Fraunces', 'Georgia', serif;
    --dash-font-body: 'Plus Jakarta Sans', sans-serif;
    --dash-font-data: 'IBM Plex Mono', 'SF Mono', monospace;

    /* Warm palette */
    --dash-cream: #FAF8F4;
    --dash-cream-dark: #f2ebe0;
    --dash-paper: #FFFCF7;
    --dash-ink: #1a1714;
    --dash-ink-secondary: #5c5549;
    /* V1.1 fix (Lens D A11y audit 2026-04-24): was #9a9085 (~3.3:1 on paper,
       fails WCAG AA 4.5:1 on 25+ dashboard elements including #dashMemberSince
       1.71, #dashEmail 2.95, .dash-grant-item__org 3.06, .dash-rec-item__btn
       3.06). Bumped to #706660 (~5:1) — still visually "muted" relative to
       --dash-ink-secondary (#5c5549) so hierarchy is preserved, but all
       consuming surfaces now pass AA. */
    --dash-ink-muted: #706660;
    /* QA polish round 2 (A3 — 2026-05-12): #c7bfb4 was ≈1.9:1 on paper and is
       used as `color:` on ~15 text elements (member badge, timestamps, faint
       captions). Bumped to #8a8175 (≈4.6:1) — still the lightest tier of the
       ink scale (below --dash-ink-muted #706660) so hierarchy holds. It's also
       used for some borders / scrollbar thumbs, which are unaffected by the
       darker value (decorative — no contrast minimum). */
    --dash-ink-faint: #8a8175;

    /* Accent colors */
    --dash-forest: #2d6a4f;
    --dash-forest-light: rgba(45, 106, 79, 0.08);
    --dash-forest-deep: #1a4731;
    --dash-sienna: #C97B4B;
    --dash-sienna-light: rgba(201, 123, 75, 0.08);
    --dash-navy: #264673;
    --dash-navy-light: rgba(38, 70, 115, 0.08);
    --dash-gold: #b8860b;
    --dash-gold-light: rgba(184, 134, 11, 0.08);
    --dash-plum: #7b2d8e;
    --dash-plum-light: rgba(123, 45, 142, 0.08);
    --dash-rose: #c4532b;
    --dash-rose-light: rgba(196, 83, 43, 0.08);

    /* Shadows */
    --dash-shadow-sm: 0 1px 3px rgba(26, 23, 20, 0.04);
    --dash-shadow-md: 0 4px 12px rgba(26, 23, 20, 0.06);
    --dash-shadow-lg: 0 12px 32px rgba(26, 23, 20, 0.08);
    --dash-shadow-hover: 0 8px 24px rgba(26, 23, 20, 0.1);

    /* Radii */
    --dash-radius: 10px;
    --dash-radius-lg: 16px;
    --dash-radius-sm: 6px;

    /* Transitions */
    --dash-transition: 200ms ease;
    --dash-transition-slow: 400ms ease;
}

/* ============================================================
   0. BODY & PAGE BASE
   ============================================================ */

body:has(.dash-main),
body:has(.dash-auth-gate),
body:has(.dash-loading) {
    background: var(--dash-cream);
}

/* Subtle grain texture overlay */
body:has(.dash-main)::after,
body:has(.dash-auth-gate)::after,
body:has(.dash-loading)::after {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    opacity: 0.025;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
    background-repeat: repeat;
    background-size: 256px 256px;
}

/* Decorative background circles */
.dash-deco-circle {
    position: fixed;
    border-radius: 50%;
    border: 1px solid rgba(26, 23, 20, 0.04);
    pointer-events: none;
    z-index: 0;
}

.dash-deco-circle--one {
    width: 400px;
    height: 400px;
    top: -80px;
    right: -100px;
    background: radial-gradient(circle, var(--dash-forest-light) 0%, transparent 70%);
    opacity: 0.4;
}

.dash-deco-circle--two {
    width: 300px;
    height: 300px;
    bottom: -60px;
    left: -80px;
    background: radial-gradient(circle, var(--dash-sienna-light) 0%, transparent 70%);
    opacity: 0.4;
}

/* ============================================================
   1. LOADING STATE
   ============================================================ */

.dash-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    gap: 16px;
    position: relative;
    z-index: 2;
}

.dash-loading p {
    font-family: var(--dash-font-body);
    font-size: 0.9rem;
    color: var(--dash-ink-muted);
    margin: 0;
}

.dash-loading__spinner {
    width: 40px;
    height: 40px;
    border: 3px solid var(--dash-cream-dark);
    border-top-color: var(--dash-forest);
    border-radius: 50%;
    animation: dash-spin 0.8s linear infinite;
}

.dash-loading.is-loaded {
    animation: dash-fade-out 0.3s ease forwards;
    pointer-events: none;
}

@keyframes dash-fade-out {
    to {
        opacity: 0;
    }
}

/* ============================================================
   2. AUTH GATE
   ============================================================ */

.dash-auth-gate {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    padding: 24px;
    position: relative;
    z-index: 2;
}

.dash-auth-gate__card {
    max-width: 440px;
    width: 100%;
    background: var(--dash-paper);
    border-radius: var(--dash-radius-lg);
    padding: 48px 40px;
    text-align: center;
    box-shadow: var(--dash-shadow-lg);
    border: 1px solid var(--dash-cream-dark);
    animation: dash-card-enter 0.4s ease;
}

.dash-auth-gate__icon {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    background: var(--dash-forest-light);
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 24px;
}

.dash-auth-gate__icon svg {
    color: var(--dash-forest);
}

.dash-auth-gate__card h2 {
    font-family: var(--dash-font-display);
    font-size: 1.5rem;
    font-weight: 600;
    color: var(--dash-ink);
    margin: 0 0 12px;
    line-height: 1.3;
}

.dash-auth-gate__card p {
    font-family: var(--dash-font-body);
    font-size: 0.95rem;
    color: var(--dash-ink-muted);
    margin: 0 0 28px;
    line-height: 1.6;
}

.dash-auth-gate__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: 14px 24px;
    background: var(--dash-forest);
    color: #fff;
    font-family: var(--dash-font-body);
    font-size: 0.95rem;
    font-weight: 600;
    border: none;
    border-radius: var(--dash-radius);
    cursor: pointer;
    transition: background var(--dash-transition), transform var(--dash-transition);
}

.dash-auth-gate__btn:hover {
    background: var(--dash-forest-deep);
    transform: translateY(-1px);
}

.dash-auth-gate__btn:active {
    transform: translateY(0);
}

.dash-auth-gate__signup {
    font-size: 0.85rem;
    color: var(--dash-ink-muted);
    margin-top: 16px;
}

.dash-auth-gate__signup a {
    color: var(--dash-forest);
    font-weight: 600;
    text-decoration: none;
}

.dash-auth-gate__signup a:hover {
    text-decoration: underline;
}

/* ============================================================
   3. DASHBOARD MAIN & CONTAINER
   ============================================================ */

.dash-main {
    position: relative;
    z-index: 2;
    padding-top: calc(var(--dash-navbar-height) + 32px);
    padding-bottom: 64px;
    min-height: 100vh;
}

.dash-container {
    max-width: var(--dash-max-width);
    margin: 0 auto;
    padding: 0 24px;
    display: flex;
    flex-direction: column;
    gap: 20px;
}

/* ============================================================
   3. DASHBOARD HEADER
   ============================================================ */

.dash-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 4px 0;
}

.dash-header__left {
    display: flex;
    align-items: center;
    gap: 16px;
    min-width: 0;
}

.dash-header__avatar {
    width: 52px;
    height: 52px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--dash-forest), var(--dash-forest-deep));
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    font-family: var(--dash-font-display);
    font-size: 1.2rem;
    font-weight: 600;
    color: #fff;
    overflow: hidden;
}

.dash-header__avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 50%;
}

.dash-header__info {
    min-width: 0;
}

.dash-header__greeting {
    font-family: var(--dash-font-display);
    font-size: 1.5rem;
    font-weight: 600;
    color: var(--dash-ink);
    margin: 0;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dash-header__email {
    font-family: var(--dash-font-body);
    font-size: 0.85rem;
    color: var(--dash-ink-muted);
    margin: 2px 0 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dash-header__right {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-shrink: 0;
}

.dash-header__member {
    font-family: var(--dash-font-body);
    font-size: 0.78rem;
    color: var(--dash-ink-faint);
    white-space: nowrap;
}

.dash-header__explore-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 14px;
    font-family: var(--dash-font-body);
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--dash-forest);
    background: transparent;
    border: 1.5px solid var(--dash-forest);
    border-radius: var(--dash-radius);
    text-decoration: none;
    cursor: pointer;
    transition: background var(--dash-transition), color var(--dash-transition);
    white-space: nowrap;
}

.dash-header__explore-btn:hover {
    background: var(--dash-forest-light);
}

.dash-header__signout {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    border: none;
    background: transparent;
    color: var(--dash-ink-muted);
    cursor: pointer;
    transition: background var(--dash-transition), color var(--dash-transition);
}

.dash-header__signout:hover {
    background: var(--dash-cream-dark);
    color: var(--dash-ink);
}

/* ============================================================
   3.5  DASHBOARD SHELL — SIDE RAIL + CANVAS  (2026-07-26)
   ============================================================
   Replaces the V3 Sprint 2 quick-action chip row (`.dash-quick-actions`,
   2026-05-01), which was four buttons that scrolled away — not a
   navigation channel. The rail is BOTH a scroll-spy over the dashboard's
   own sections AND the index of member capabilities that live off the
   dashboard (eligibility map, Game Plan, workspace, roadmap).

   Spec: docs/superpowers/specs/2026-07-26-dashboard-rail-design.md
   Rendered by renderRail() in js/dashboard.src.js.

   ⚠ position:sticky is SILENTLY DEAD on this page — main.css sets
     overflow-x:hidden on html+body, which disables sticky for every
     descendant in Chromium. The rail is therefore position:fixed with a
     JS-computed left/top (follow → pin → park). See docs/DURABLE-GOTCHAS.md.
   ⚠ .dash-canvas MUST carry the flex-column + 20px gap that .dash-container
     supplies (line ~282) — moving the sections into an unstyled wrapper
     destroys the section rhythm dashboard-wide.
*/

.dash-shell {
    display: block;              /* single column until JS proves a rail exists */
    min-width: 0;
}

.dash-canvas {
    display: flex;
    flex-direction: column;
    gap: 20px;
    min-width: 0;                /* grid children floor at min-content otherwise */
}

/* Rail jumps move focus INTO the target section so the next Tab continues from
   there rather than back down the rail. Those targets get tabindex="-1" and are
   only ever focused programmatically, so the UA's blue ring is noise — the
   scroll itself is the sighted feedback, the focus move is the SR feedback. */
.dash-canvas:focus,
.dash-canvas > [tabindex="-1"]:focus { outline: none; }

/* ---- desktop: two columns. Only ever applied by renderRail(). ----
   Breakpoint is 1200px, matching --dash-max-width: below the container's own
   max width the content column is ALREADY constrained, so a rail there is
   taken straight out of content. Measured at 1024: the canvas drops 872 -> 731
   and grant titles wrap to four and five lines, i.e. the page gets denser
   exactly where space is scarcest. Under 1200 the mobile strip takes over. */
@media (min-width: 1200px) {
    .dash-shell.has-rail {
        display: grid;
        grid-template-columns: 248px minmax(0, 1fr);
        gap: 32px;
        align-items: start;
    }
}

.dash-rail {
    /* the cell reserves the column; .dash-rail__in is what the user sees */
    width: 100%;
    min-width: 0;
}

.dash-rail__in {
    position: fixed;             /* NOT sticky — see the warning above */
    top: 96px;                   /* placeholder; JS owns this every frame */
    width: 248px;
    max-height: calc(100vh - 112px);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-bottom: 10px;
    scrollbar-width: thin;
}
/* Near the end of the column the rail stays pinned and SHRINKS, so its last
   row gets cut. Without a cue that reads as breakage rather than as scroll.
   Toggled from _railPlace() only when it is genuinely overflowing. */
.dash-rail__in.is-clipped {
    mask-image: linear-gradient(to bottom, #000 calc(100% - 26px), transparent);
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 26px), transparent);
}
.dash-rail__in::-webkit-scrollbar { width: 6px; }
.dash-rail__in::-webkit-scrollbar-thumb {
    background: var(--dash-ink-faint);
    border-radius: 3px;
}

/* Skip-past-the-rail. The sitewide .dash-skip-link parks itself at
   left:-9999px, which inside an overflow:auto rail would create a scrollable
   region — so this one uses the clip technique and returns to normal flow
   on focus. (The page's own skip link targets #dashMain, which is ABOVE
   the rail and therefore skips nothing for a keyboard user here.) */
.dash-rail__skip {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}
.dash-rail__skip:focus {
    position: static;
    display: block;
    width: auto;
    height: auto;
    margin: 0 0 8px;
    padding: 8px 12px;
    overflow: visible;
    clip: auto;
    clip-path: none;
    background: var(--dash-forest-deep);
    color: #FAF7F2;
    border-radius: var(--dash-radius-sm);
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
}

.dash-rail__group { margin: 0 0 26px; }
.dash-rail__group:last-of-type { margin-bottom: 12px; }

.dash-rail__h {
    margin: 0 0 8px;
    padding: 0 12px;
    font-family: var(--dash-font-body);
    font-size: 0.69rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--dash-ink-muted);
}

.dash-rail__item {
    display: block;
    position: relative;
    width: 100%;
    text-align: left;
    background: none;
    border: 0;
    font-family: inherit;
    padding: 9px 12px;
    border-radius: 9px;
    cursor: pointer;
    text-decoration: none;
    box-shadow: inset 3px 0 0 transparent;
    transition: background var(--dash-transition), box-shadow var(--dash-transition);
}
.dash-rail__item .t {
    display: block;
    font-size: 0.94rem;
    font-weight: 600;
    line-height: 1.3;
    color: var(--dash-ink);
}
.dash-rail__item .d {
    /* The "Next action" row carries a real grant title, which can be 91 chars.
       Two lines is the budget; past that the rail starts competing with the
       column it is meant to index. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 0.8rem;
    font-weight: 400;
    color: var(--dash-ink-secondary);
    margin-top: 1px;
    line-height: 1.35;
}
.dash-rail__item:hover { background: var(--dash-cream-dark); }
.dash-rail__item:hover .t { color: var(--dash-forest-deep); }
.dash-rail__item:focus-visible {
    outline: 2px solid var(--dash-forest);
    outline-offset: 2px;
}

/* Colour means exactly one thing each: forest = where you are,
   rose/rust = what is new. Never both on the same signal. */
.dash-rail__item.is-on {
    background: var(--dash-forest-light);
    box-shadow: inset 3px 0 0 var(--dash-forest);
}
.dash-rail__item.is-on .t {
    color: var(--dash-forest-deep);
    font-weight: 700;
}

/* off-dashboard destinations earn an arrow; on-page anchors do not */
.dash-rail__item--out .t::after {
    content: "\2192";
    margin-left: 6px;
    color: var(--dash-ink-faint);
    font-size: 0.85em;
    display: inline-block;
    transition: transform var(--dash-transition), color var(--dash-transition);
}
.dash-rail__item--out:hover .t::after {
    color: var(--dash-rose);
    transform: translateX(2px);
}

.dash-rail__b {
    position: absolute;
    right: 10px;
    top: 9px;
    font-size: 0.7rem;
    font-weight: 700;
    border-radius: 999px;
    padding: 1px 8px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.dash-rail__b--total { background: var(--dash-cream-dark); color: var(--dash-ink-secondary); }
.dash-rail__b--new   { background: var(--dash-rose); color: #fff; }
/* MEASURED 2026-07-27 at the 248px rail width. The widest badge the code can
   emit is "2 questions" at 82px, which starts at x=156. At the old 74px reserve
   the label's text box ran to x=162 — SIX PIXELS PAST the badge — so a
   long-enough label could draw underneath it. Today's longest real label
   ("Recommended grants", 110px) does not reach that far, which is why nothing
   had visibly broken and why a badge-only test could never fail. 96px closes
   the box before the badge starts, so overlap is impossible rather than merely
   unobserved. dash-rail-qa.js asserts >=20% CLEARANCE, not mere non-overlap,
   so this fails the moment a longer label or badge is introduced. */
.dash-rail__b { max-width: 88px; overflow: hidden; text-overflow: ellipsis; }
.dash-rail__item:has(.dash-rail__b) .t { padding-right: 96px; }

/* The one place the rail previews an OUTCOME instead of naming a feature.
   Listing destinations demonstrably has not moved adoption. */
.dash-rail__rec {
    display: block;
    /* The card is an <a> in four of its five states and a <button> in the
       fifth (open-the-workspace). A UA button centres its text, so without
       this the recommendation silently switched to centre-aligned for exactly
       one member state while every other row in the rail stayed left. */
    text-align: left;
    font-family: inherit;
    cursor: pointer;
    width: 100%;
    background: var(--dash-paper);
    border: 1px solid var(--dash-cream-dark);
    border-left: 3px solid var(--dash-rose);
    border-radius: var(--dash-radius);
    padding: 11px 13px;
    margin: 0 0 10px;
    text-decoration: none;
    box-shadow: var(--dash-shadow-sm);
    transition: box-shadow var(--dash-transition), transform var(--dash-transition);
}
.dash-rail__rec:hover {
    box-shadow: var(--dash-shadow-md);
    transform: translateY(-1px);
}
.dash-rail__rec:focus-visible { outline: 2px solid var(--dash-forest); outline-offset: 2px; }
.dash-rail__rec .k {
    display: block;
    font-size: 0.63rem;
    font-weight: 800;
    letter-spacing: 0.11em;
    text-transform: uppercase;
    color: var(--dash-rose);
    margin-bottom: 3px;
}
.dash-rail__rec .t {
    /* Grant titles are long and unpredictable ("Scientific Research and
       Experimental Development (SR&ED)"). Clamp in CSS rather than slicing in
       JS — a slice cuts mid-word ("…Experimental Devel"). */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 0.92rem;
    font-weight: 700;
    color: var(--dash-ink);
    line-height: 1.3;
}
.dash-rail__rec .b { display: block; font-size: 0.79rem; color: var(--dash-ink-secondary); margin: 2px 0 6px; line-height: 1.35; }
.dash-rail__rec .c { display: block; font-size: 0.8rem; font-weight: 700; color: var(--dash-rose); }

.dash-rail__foot {
    border-top: 1px solid var(--dash-cream-dark);
    margin: 2px 12px 0;
    padding-top: 10px;
}
.dash-rail__foot .dash-rail__item {
    padding-left: 0;
    padding-right: 0;
    box-shadow: none;
}
.dash-rail__foot .dash-rail__item:hover { background: transparent; }
.dash-rail__top {
    background: none;
    border: 0;
    font: inherit;
    font-size: 0.79rem;
    color: var(--dash-ink-faint);
    cursor: pointer;
    padding: 6px 0;
}
.dash-rail__top:hover { color: var(--dash-forest-deep); }
.dash-rail__top:focus-visible { outline: 2px solid var(--dash-forest); outline-offset: 2px; }

/* A fixed rail must never float over the workspace takeover. Suppressed by
   body class — the documented pattern here — not by a z-index bidding war. */
body.wsp-pane-open .dash-rail__in,
body.wsp-pane-open .dash-railbar { display: none !important; }

/* The co-pilot's just-in-time profile prompt is position:fixed TOP-LEFT at
   z-index 9999 — moved there on 2026-05-15 *because that region was empty*.
   It is not empty any more. Today the two cannot co-occur (the prompt only
   fires mid-draft, i.e. under .wsp-pane-open, which already hides the rail),
   but that is an assumption about another module's trigger, and the last
   assumption about this exact region is what caused the 2026-05-15 bug. So
   make it structural: whenever that prompt exists, the rail yields. Measured
   overlap without this rule: prompt x20-340 vs rail x144-392. display:none,
   not visibility, so it leaves no invisible tab stops behind. */
body:has(#fp-progressive-prompt) .dash-rail__in { display: none !important; }

/* ---- mobile: the rail collapses to a horizontal spy strip ---- */
.dash-railbar { display: none; }

@media (max-width: 1199.98px) {
    /* MUST be display:none, not just unstyled — .dash-rail__in is position:fixed,
       so a rail that merely loses its grid cell still paints over the page.
       _railPlace() also early-returns on display:none. */
    .dash-rail { display: none; }

    .dash-railbar[hidden] { display: none; }
    .dash-railbar {
        display: block;
        position: fixed;
        /* 2026-09-18 deep QA: pinned to the nav's REAL height (nav-v7.css: 56px at every width).
           --dash-navbar-height is a legacy 72px, which left a 16px band between the two fixed
           bars where section titles scrolled through, sliced. */
        top: calc(56px + env(safe-area-inset-top, 0px));
        left: 0;
        right: 0;
        /* below the nav drawer (z1200), above page content */
        z-index: 1150;
        background: var(--dash-cream);
        padding: 0 16px;
        border-bottom: 1px solid var(--dash-cream-dark);
        transform: translateY(-115%);
        /* visibility:hidden (not transform alone) or the strip leaves a row of
           tabbable invisible links in the tab order */
        visibility: hidden;
        transition: transform 220ms cubic-bezier(.22, 1, .36, 1);
    }
    .dash-railbar.is-shown { transform: none; visibility: visible; }
    .dash-railbar__scroll {
        display: flex;
        gap: 6px;
        overflow-x: auto;
        padding: 9px 2px;
        scrollbar-width: none;
        -webkit-overflow-scrolling: touch;
    }
    .dash-railbar__scroll::-webkit-scrollbar { display: none; }
    .dash-railbar__pill {
        flex: none;
        display: flex;
        align-items: center;
        min-height: 44px;
        border: 1px solid var(--dash-cream-dark);
        background: var(--dash-paper);
        border-radius: 999px;
        padding: 0 16px;
        font: inherit;
        font-size: 0.85rem;
        font-weight: 600;
        color: var(--dash-ink-secondary);
        text-decoration: none;
        white-space: nowrap;
        cursor: pointer;
    }
    .dash-railbar__pill:focus-visible { outline: 2px solid var(--dash-forest); outline-offset: 2px; }
    .dash-railbar__pill.is-on {
        background: var(--dash-forest-deep);
        border-color: var(--dash-forest-deep);
        color: #fff;
    }
}

@media (prefers-reduced-motion: reduce) {
    .dash-rail__item,
    .dash-rail__rec,
    .dash-rail__item--out .t::after,
    .dash-railbar { transition: none; }
    .dash-rail__rec:hover { transform: none; }
}

/* ============================================================
   3.6  HOW-IT-WORKS HERO  (V3 Sprint 2 Item 2 — 2026-05-01)
   ============================================================
   3-step illustrated explainer (Track → Draft → Win) above pipeline.
   Auto-hides at ≥3 apps OR explicit dismiss. Adapts subtitle + CTA
   to user state (no quiz / has quiz, 0 / sparse / productive).
*/

.dash-hero-howit {
    position: relative;
    background: linear-gradient(135deg, #FFFDFA 0%, #F0FDF4 100%);
    border: 1px solid #C7E9D4;
    border-radius: 12px;
    padding: 22px 28px 24px;
    margin: 0 0 16px;
}
.dash-hero-howit[hidden] { display: none; }

.dash-hero-howit__dismiss {
    position: absolute;
    top: 10px;
    right: 10px;
    background: transparent;
    border: none;
    padding: 6px;
    cursor: pointer;
    color: var(--dash-ink-muted, #6B6458);
    border-radius: 4px;
    line-height: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.dash-hero-howit__dismiss:hover {
    background: rgba(0, 0, 0, 0.06);
    color: var(--dash-ink, #1A1814);
}
.dash-hero-howit__dismiss:focus-visible {
    outline: 2px solid var(--dash-forest, #2D6A4F);
    outline-offset: 2px;
}

.dash-hero-howit__head {
    margin-bottom: 18px;
    padding-right: 28px; /* room for dismiss button */
}
.dash-hero-howit__title {
    font-family: 'Fraunces', serif;
    font-size: 20px;
    font-weight: 500;
    color: var(--dash-ink, #1A1814);
    margin: 0 0 6px;
    letter-spacing: -0.01em;
    line-height: 1.2;
}
.dash-hero-howit__sub {
    font-size: 14px;
    color: #4F4A40;
    margin: 0;
    line-height: 1.5;
    max-width: 60ch;
}
.dash-hero-howit__sub strong {
    color: #14532D;
    font-weight: 600;
}

.dash-hero-howit__steps {
    display: grid;
    grid-template-columns: 1fr auto 1fr auto 1fr;
    gap: 12px;
    align-items: start;
    margin-bottom: 18px;
}

/* Steps are links (2026-08-30, dead-click fix). Colors pinned across every state so the
   sitewide a:hover { color: var(--sienna) } cannot repaint the card text. */
a.dash-hero-howit__step,
a.dash-hero-howit__step:hover,
a.dash-hero-howit__step:focus,
a.dash-hero-howit__step:visited,
a.dash-hero-howit__step:active {
    text-decoration: none;
    color: inherit;
    display: block;
    border-radius: 10px;
}
a.dash-hero-howit__step:hover { background: rgba(20, 83, 45, 0.05); }
a.dash-hero-howit__step:hover .dash-hero-howit__step-title { color: #14532D; }
a.dash-hero-howit__step:focus-visible { outline: 2px solid #14532D; outline-offset: 2px; }

.dash-hero-howit__step {
    text-align: center;
    padding: 0 6px;
    min-width: 0;
}
.dash-hero-howit__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    margin: 0 auto 10px;
    border-radius: 50%;
    background: #FFFFFF;
    border: 2px solid #14532D;
    color: #14532D;
}
.dash-hero-howit__icon svg {
    width: 22px;
    height: 22px;
}
.dash-hero-howit__step-title {
    font-family: 'Fraunces', serif;
    font-size: 15px;
    font-weight: 600;
    color: var(--dash-ink, #1A1814);
    margin: 0 0 4px;
    letter-spacing: 0;
}
.dash-hero-howit__step-desc {
    font-size: 12px;
    color: var(--dash-ink-muted, #6B6458);
    margin: 0 auto;
    line-height: 1.5;
    max-width: 24ch;
}
.dash-hero-howit__arrow {
    color: #14532D;
    align-self: center;
    margin-top: 14px;
    opacity: 0.45;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.dash-hero-howit__cta-row {
    text-align: center;
    border-top: 1px solid rgba(20, 83, 45, 0.10);
    padding-top: 16px;
}
.dash-hero-howit__cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 10px 22px;
    min-height: 42px;
    background: #2D6A4F;
    color: #FFFFFF;
    border: none;
    border-radius: 8px;
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.15s ease, transform 0.1s ease, box-shadow 0.15s ease;
}
.dash-hero-howit__cta:hover {
    background: #1B4332;
    transform: translateY(-1px);
    box-shadow: 0 3px 10px rgba(45, 106, 79, 0.22);
}
.dash-hero-howit__cta:focus-visible {
    outline: 2px solid #2D6A4F;
    outline-offset: 2px;
}

/* Mobile: stack vertically with rotated arrows.
   V3 Sprint 2 hotfix (Lens 4 P1-2 — 2026-05-01): bump dismiss button to
   44×44 min-size on mobile (WCAG 2.5.5 / Apple HIG touch target). At
   30×30 the dismiss was easily mis-tapped at the top-right corner. */
@media (max-width: 768px) {
    .dash-hero-howit {
        padding: 20px 18px 22px;
    }
    .dash-hero-howit__title {
        font-size: 18px;
    }
    .dash-hero-howit__steps {
        grid-template-columns: 1fr;
        gap: 14px;
    }
    .dash-hero-howit__arrow {
        margin: -2px auto;
        transform: rotate(90deg);
    }
    .dash-hero-howit__step {
        padding: 0;
    }
    .dash-hero-howit__step-desc {
        max-width: 36ch;
    }
    .dash-hero-howit__dismiss {
        min-width: 44px;
        min-height: 44px;
        padding: 13px;
        top: 6px;
        right: 6px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .dash-hero-howit__cta {
        transition: none;
    }
    .dash-hero-howit__cta:hover {
        transform: none;
    }
}

/* ============================================================
   3.7  FIRST-PURSUIT TOAST  (V3 Sprint 2 Item 5 — 2026-05-01)
   ============================================================
   Top-right celebratory toast on the user's very first ever pursuit.
   One-shot via localStorage.gc_first_pursuit_seen. Auto-dismisses
   after 12s OR on manual close click. Mobile: full-width slide-up
   from bottom.
*/

.dash-firstpursuit-toast {
    /* V3 Sprint 2 hotfix (Lens 5 P0 — 2026-05-01): moved from top-right to
       bottom-right on desktop. Top-right overlapped the "+ Pursue a new
       grant" CTA in the pipeline head (top of empty/sparse state pipelines),
       making the primary action unclickable until toast dismissed. Bottom-
       right is the canonical celebratory-toast position (Stripe, Linear). */
    position: fixed;
    bottom: 24px;
    right: 24px;
    z-index: 9999;
    display: flex;
    align-items: flex-start;
    gap: 12px;
    background: linear-gradient(135deg, #FFFDFA 0%, #F0FDF4 100%);
    border: 1px solid #2D6A4F;
    border-radius: 12px;
    padding: 16px 16px 16px 18px;
    max-width: 380px;
    box-shadow: 0 8px 28px rgba(26, 24, 20, 0.18);
    transform: translateY(12px) scale(0.96);
    opacity: 0;
    transition: transform 320ms cubic-bezier(0.34, 1.56, 0.64, 1), opacity 240ms ease;
    font-family: inherit;
}

.dash-firstpursuit-toast.is-shown {
    transform: translateY(0) scale(1);
    opacity: 1;
}

.dash-firstpursuit-toast__icon {
    font-size: 26px;
    line-height: 1;
    flex-shrink: 0;
    margin-top: 2px;
    /* Subtle inline animation on the emoji — celebratory bounce */
    animation: dashFirstPursuitEmojiBounce 0.7s ease-out 0.15s 1;
    transform-origin: center;
}
@keyframes dashFirstPursuitEmojiBounce {
    0% { transform: scale(0.6) rotate(-12deg); }
    50% { transform: scale(1.15) rotate(8deg); }
    100% { transform: scale(1) rotate(0); }
}

.dash-firstpursuit-toast__body {
    flex: 1;
    min-width: 0;
}

.dash-firstpursuit-toast__title {
    font-family: 'Fraunces', serif;
    font-size: 16px;
    font-weight: 600;
    color: #14532D;
    margin: 0 0 4px;
    letter-spacing: -0.005em;
    line-height: 1.2;
}

.dash-firstpursuit-toast__desc {
    font-size: 13px;
    color: #4F4A40;
    margin: 0;
    line-height: 1.5;
}

.dash-firstpursuit-toast__desc strong {
    color: #1A1814;
    font-weight: 600;
}

.dash-firstpursuit-toast__close {
    background: transparent;
    border: none;
    padding: 4px;
    cursor: pointer;
    color: #6B6458;
    border-radius: 4px;
    line-height: 0;
    flex-shrink: 0;
    align-self: flex-start;
    margin-top: -2px;
    margin-right: -4px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.dash-firstpursuit-toast__close:hover {
    background: rgba(0, 0, 0, 0.06);
    color: #1A1814;
}
.dash-firstpursuit-toast__close:focus-visible {
    outline: 2px solid #2D6A4F;
    outline-offset: 2px;
}

@media (max-width: 600px) {
    .dash-firstpursuit-toast {
        bottom: 16px;
        right: 12px;
        left: 12px;
        max-width: none;
        padding: 14px 14px 14px 16px;
    }
    .dash-firstpursuit-toast__title { font-size: 15px; }
    .dash-firstpursuit-toast__desc { font-size: 12px; }
}

/* R6-2 (2026-05-11): on small mobile (<=480px) the bottom toast covers
   the workspace section list. Switch to a compact top banner so it doesn't
   occlude the content. The back-strip is 44px; the banner sits just below it
   when inside the workspace takeover (wsp-pane-open), or just below the nav
   otherwise. The icon is hidden to keep the banner to a single line. */
@media (max-width: 480px) {
    .dash-firstpursuit-toast {
        bottom: auto;
        top: calc(56px + 44px + 4px); /* nav (56) + back-strip (44) + gap (4) */
        right: 8px;
        left: 8px;
        padding: 10px 12px;
        border-radius: 8px;
        max-width: none;
        gap: 8px;
        align-items: center;
        /* Slimmer animation from top */
        transform: translateY(-8px) scale(0.97);
    }
    .dash-firstpursuit-toast.is-shown {
        transform: translateY(0) scale(1);
    }
    .dash-firstpursuit-toast__icon {
        display: none; /* hide emoji to keep banner slim */
    }
    .dash-firstpursuit-toast__title {
        font-size: 13px;
        margin-bottom: 2px;
    }
    .dash-firstpursuit-toast__desc {
        font-size: 11.5px;
        line-height: 1.4;
    }
    /* When workspace pane is open, shift banner below the back-strip. */
    body.wsp-pane-open .dash-firstpursuit-toast {
        top: calc(56px + 44px + 6px);
    }
}

@media (prefers-reduced-motion: reduce) {
    .dash-firstpursuit-toast {
        transition: opacity 200ms ease;
        transform: none;
    }
    .dash-firstpursuit-toast.is-shown {
        transform: none;
    }
    .dash-firstpursuit-toast__icon {
        animation: none;
    }
}

/* ============================================================
   4. COMPLETION BAR
   ============================================================ */

.dash-completion {
    display: flex;
    align-items: center;
    gap: 16px;
    background: var(--dash-paper);
    border: 1px solid var(--dash-cream-dark);
    border-radius: var(--dash-radius);
    padding: 12px 20px;
}

.dash-completion.is-complete {
    display: none;
}

.dash-completion__info {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.dash-completion__text {
    font-family: var(--dash-font-body);
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--dash-ink-secondary);
}

.dash-completion__hint {
    font-family: var(--dash-font-body);
    font-size: 0.75rem;
    color: var(--dash-ink-muted);
}

.dash-completion__track {
    flex: 1;
    height: 6px;
    background: var(--dash-cream-dark);
    border-radius: 3px;
    overflow: hidden;
}

.dash-completion__fill {
    height: 100%;
    background: linear-gradient(90deg, var(--dash-forest), var(--dash-sienna));
    border-radius: 3px;
    transition: width var(--dash-transition-slow);
}

/* ============================================================
   6. SUBSCRIPTION PANEL
   ============================================================ */

.dash-subscription {
    animation: dash-card-enter 0.4s ease both;
    animation-delay: 240ms;
}

/* Shared sub card styles */
.dash-sub {
    background: var(--dash-paper);
    border: 1px solid var(--dash-cream-dark);
    border-radius: var(--dash-radius);
    padding: 20px 24px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}

/* Free tier */
.dash-sub--free {
    border-left: 3px solid var(--dash-ink-faint);
}

.dash-sub--free .dash-sub__info {
    flex: 1;
    min-width: 0;
}

.dash-sub--free .dash-sub__title {
    font-family: var(--dash-font-display);
    font-size: 1rem;
    font-weight: 600;
    color: var(--dash-ink);
    margin: 0 0 4px;
    display: flex;
    align-items: center;
    gap: 8px;
}

.dash-sub--free .dash-sub__badge {
    font-family: var(--dash-font-body);
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--dash-ink-muted);
    background: var(--dash-cream-dark);
    padding: 2px 8px;
    border-radius: 20px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.dash-sub--free .dash-sub__text {
    font-family: var(--dash-font-body);
    font-size: 0.85rem;
    color: var(--dash-ink-muted);
    margin: 0;
    line-height: 1.5;
}

.dash-sub--free .dash-sub__cta {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 10px 20px;
    background: var(--dash-forest);
    color: #fff;
    font-family: var(--dash-font-body);
    font-size: 0.85rem;
    font-weight: 600;
    border: none;
    border-radius: var(--dash-radius);
    text-decoration: none;
    cursor: pointer;
    transition: background var(--dash-transition), transform var(--dash-transition);
    white-space: nowrap;
    flex-shrink: 0;
}

.dash-sub--free .dash-sub__cta:hover {
    background: var(--dash-forest-deep);
    transform: translateY(-1px);
}

/* What you're missing callout */
.dash-sub__callout {
    margin-top: 16px;
    background: var(--dash-cream-dark);
    border-radius: var(--dash-radius-sm);
    padding: 14px 18px;
}

.dash-sub__callout-title {
    font-family: var(--dash-font-body);
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--dash-ink-secondary);
    margin: 0 0 8px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.dash-sub__callout-stats {
    display: flex;
    gap: 24px;
    flex-wrap: wrap;
}

.dash-sub__callout-stat {
    font-family: var(--dash-font-body);
    font-size: 0.82rem;
    color: var(--dash-ink-muted);
    display: flex;
    align-items: center;
    gap: 6px;
}

.dash-sub__callout-stat svg {
    width: 14px;
    height: 14px;
    color: var(--dash-forest);
    flex-shrink: 0;
}

/* Premium tier */
.dash-sub--premium {
    border-left: 3px solid var(--dash-forest);
    background: linear-gradient(135deg, var(--dash-paper) 0%, var(--dash-forest-light) 100%);
    flex-wrap: wrap;
}

.dash-sub--premium .dash-sub__info {
    flex: 1;
    min-width: 0;
}

.dash-sub--premium .dash-sub__title {
    font-family: var(--dash-font-display);
    font-size: 1rem;
    font-weight: 600;
    color: var(--dash-ink);
    margin: 0 0 4px;
    display: flex;
    align-items: center;
    gap: 8px;
}

.dash-sub--premium .dash-sub__badge {
    font-family: var(--dash-font-body);
    font-size: 0.7rem;
    font-weight: 600;
    color: #fff;
    background: var(--dash-forest);
    padding: 2px 8px;
    border-radius: 20px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.dash-sub--premium .dash-sub__details {
    display: flex;
    gap: 20px;
    margin-top: 6px;
}

.dash-sub--premium .dash-sub__detail {
    font-family: var(--dash-font-body);
    font-size: 0.82rem;
    color: var(--dash-ink-muted);
}

.dash-sub--premium .dash-sub__detail strong {
    color: var(--dash-ink-secondary);
    font-weight: 600;
}

.dash-sub--premium .dash-sub__cta {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 10px 20px;
    background: transparent;
    color: var(--dash-forest);
    font-family: var(--dash-font-body);
    font-size: 0.85rem;
    font-weight: 600;
    border: 1.5px solid var(--dash-forest);
    border-radius: var(--dash-radius);
    text-decoration: none;
    cursor: pointer;
    transition: background var(--dash-transition);
    white-space: nowrap;
    flex-shrink: 0;
}

.dash-sub--premium .dash-sub__cta:hover {
    background: var(--dash-forest-light);
}

/* Premium usage stats row */
.dash-sub__usage {
    display: flex;
    gap: 24px;
    margin: 12px 0 4px;
    flex-wrap: wrap;
}

.dash-sub__usage-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
}

.dash-sub__usage-number {
    font-family: var(--dash-font-data);
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--dash-forest);
}

.dash-sub__usage-label {
    font-family: var(--dash-font-body);
    font-size: 0.72rem;
    color: var(--dash-ink-muted);
}

/* Free tier "what you're missing" inline text */
.dash-sub__missing {
    font-family: var(--dash-font-body);
    font-size: 0.82rem;
    color: var(--dash-ink-secondary);
    line-height: 1.5;
    margin: 8px 0 0;
    padding: 10px 14px;
    background: var(--dash-cream);
    border-radius: var(--dash-radius-sm);
}

.dash-sub__missing strong {
    color: var(--dash-forest);
    font-weight: 600;
}

/* Subscription header row (icon + title) */
.dash-sub__header {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    margin-bottom: 10px;
}

.dash-sub__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 8px;
    flex-shrink: 0;
}

.dash-sub--premium .dash-sub__icon {
    background: var(--dash-forest-light);
    color: var(--dash-forest);
}

.dash-sub--free .dash-sub__icon {
    background: var(--dash-cream-dark);
    color: var(--dash-ink-muted);
}

.dash-sub__icon svg,
.dash-sub__icon .dash-lucide-icon {
    width: 20px;
    height: 20px;
}

.dash-sub__header .dash-sub__title {
    margin: 0;
}

.dash-sub__renewal {
    font-family: var(--dash-font-body);
    font-size: 0.78rem;
    color: var(--dash-ink-muted);
    margin: 2px 0 0;
}

.dash-sub__desc {
    font-family: var(--dash-font-body);
    font-size: 0.82rem;
    color: var(--dash-ink-muted);
    margin: 2px 0 0;
}

/* Subscription actions row (premium card footer) */
.dash-sub__actions {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    margin-top: 4px;
    flex-wrap: wrap;
}

/* Manage Billing button */
.dash-manage-billing-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 16px;
    background: transparent;
    border: 1px solid var(--dash-cream-dark, #E8E4DE);
    border-radius: var(--dash-radius-sm, 6px);
    color: var(--dash-ink-secondary, #5c5549);
    font-family: var(--dash-font-body);
    font-size: 0.82rem;
    cursor: pointer;
    transition: border-color var(--dash-transition), color var(--dash-transition);
    min-height: 44px; /* V1.1 Fix #9b (WCAG 2.5.5 — was 34.5px; high-stakes billing action) */
}

.dash-manage-billing-btn:hover {
    border-color: var(--dash-forest, #2d6a4f);
    color: var(--dash-forest, #2d6a4f);
}

.dash-manage-billing-btn svg {
    flex-shrink: 0;
}

/* Upgrade CTA visual emphasis */
.dash-sub__cta--upgrade {
    font-weight: 600;
}

/* Recommendation deadline badges */
.dash-rec-item__deadline {
    font-family: var(--dash-font-body);
    font-size: 0.75rem;
    padding: 2px 8px;
    border-radius: 10px;
    white-space: nowrap;
}

.dash-rec-item__deadline--urgent {
    background: var(--dash-rose-light);
    color: var(--dash-rose);
    font-weight: 600;
}

.dash-rec-item__deadline--soon {
    background: var(--dash-gold-light);
    color: var(--dash-gold);
}

.dash-rec-item__deadline--ongoing {
    background: var(--dash-cream-dark);
    color: var(--dash-ink-muted);
}

/* ============================================================
   6a-2. QUIZ PROFILE CARD
   ============================================================ */

.dash-quiz-profile {
    animation: dash-card-enter 0.4s ease both;
    animation-delay: 260ms;
    margin-bottom: 16px;
}

/* Collapsible accordion variant (Dashboard V1) — wraps the quiz profile in <details> */
.dash-quiz-profile--accordion {
    background: #FFFDFA;
    border: 1px solid #E8E1D4;
    border-radius: 8px;
    padding: 10px 14px;
    margin: 16px 0;
}
.dash-quiz-profile__summary {
    font-family: 'Fraunces', serif;
    font-size: 14px;
    font-weight: 600;
    color: #1A1814;
    cursor: pointer;
    user-select: none;
    padding: 4px 0;
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.dash-quiz-profile__summary::after {
    content: '⌄';
    color: #6B6458;
    font-family: 'Fraunces', serif;
    font-size: 16px;
    transition: transform 180ms ease;
}
.dash-quiz-profile--accordion[open] .dash-quiz-profile__summary::after {
    transform: rotate(180deg);
}
.dash-quiz-profile--accordion[open] .dash-quiz-profile__summary {
    margin-bottom: 10px;
    padding-bottom: 8px;
    border-bottom: 1px dashed #E8E1D4;
}

.dash-quiz-profile__card {
    background: var(--dash-paper);
    border: 1px solid var(--dash-cream-dark);
    border-left: 3px solid var(--dash-forest);
    border-radius: var(--dash-radius);
    padding: 18px 22px;
}

.dash-quiz-profile__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 14px;
}

.dash-quiz-profile__title-row {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--dash-forest);
}

.dash-quiz-profile__title {
    font-family: var(--dash-font-display);
    font-size: 1rem;
    font-weight: 600;
    margin: 0;
    color: var(--dash-ink);
}

.dash-quiz-profile__date {
    font-size: 0.75rem;
    color: var(--dash-ink-faint);
}

.dash-quiz-profile__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 10px 16px;
    margin-bottom: 14px;
}

.dash-quiz-profile__item {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.dash-quiz-profile__label {
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--dash-ink-faint);
}

.dash-quiz-profile__value {
    font-size: 0.875rem;
    color: var(--dash-ink);
    font-weight: 500;
}

.dash-quiz-profile__retake {
    display: inline-block;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--dash-forest);
    text-decoration: none;
    transition: color 0.15s;
}

.dash-quiz-profile__retake:hover {
    color: var(--dash-forest-dark, #0f3d22);
    text-decoration: underline;
}

/* V1.2 (2026-04-25): replaces .dash-quiz-profile__retake on the Quiz Profile
   card. Same visual language (inline link-style button) so the swap is
   invisible from a design perspective; semantics are different (button
   opens ProfileModal instead of navigating to the quiz). */
.dash-quiz-profile__edit-btn {
    display: inline-block;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--dash-forest);
    background: transparent;
    border: none;
    padding: 0;
    cursor: pointer;
    font-family: inherit;
    text-align: left;
    transition: color 0.15s;
    min-height: 44px;
}

.dash-quiz-profile__edit-btn:hover,
.dash-quiz-profile__edit-btn:focus-visible {
    color: var(--dash-forest-dark, #0f3d22);
    text-decoration: underline;
    outline: none;
}
.dash-quiz-profile__edit-btn:focus-visible {
    outline: 2px solid var(--dash-forest);
    outline-offset: 2px;
    border-radius: 4px;
}

@media (max-width: 640px) {
    .dash-quiz-profile__grid {
        grid-template-columns: 1fr 1fr;
    }
}

/* ============================================================
   7. SECTION TITLES
   ============================================================ */

.dash-section-title {
    font-family: var(--dash-font-display);
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--dash-ink);
    margin: 0 0 12px;
}

/* ============================================================
   9. MAIN GRID
   ============================================================ */

.dash-grid {
    display: grid;
    grid-template-columns: 3fr 2fr;
    gap: 24px;
    animation: dash-card-enter 0.5s ease both;
    animation-delay: 350ms;
}

/* ============================================================
   10. CARD COMPONENT
   ============================================================ */

.dash-card {
    background: var(--dash-paper);
    border: 1px solid var(--dash-cream-dark);
    border-radius: var(--dash-radius-lg);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.dash-card__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 18px 20px 0;
}

.dash-card__header h3 {
    font-family: var(--dash-font-display);
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--dash-ink);
    margin: 0;
}

.dash-card__actions {
    display: flex;
    gap: 4px;
}

/* Icon button */
.dash-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: none;
    background: transparent;
    color: var(--dash-ink-muted);
    cursor: pointer;
    transition: background var(--dash-transition), color var(--dash-transition);
    padding: 0;
}

.dash-icon-btn:hover {
    background: var(--dash-forest-light);
    color: var(--dash-forest);
}

.dash-icon-btn:focus-visible {
    outline: 2px solid var(--dash-forest);
    outline-offset: 2px;
}

/* ============================================================
   11. STATUS TABS (legacy hub sub-nav)
   ============================================================ */

.dash-status-tabs {
    display: flex;
    gap: 2px;
    padding: 4px;
    margin: 14px 16px 0;
    background: var(--dash-cream-dark);
    border-radius: var(--dash-radius);
    overflow-x: auto;
    -ms-overflow-style: none;
    scrollbar-width: none;
}

.dash-status-tabs::-webkit-scrollbar {
    display: none;
}

/* D16: Smooth slide transition for active tab */
.dash-status-tabs__tab {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 14px;
    font-family: var(--dash-font-body);
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--dash-ink-muted);
    background: transparent;
    border: none;
    border-bottom: 2px solid transparent;
    border-radius: var(--dash-radius-sm);
    cursor: pointer;
    transition: background var(--dash-transition), color var(--dash-transition), box-shadow var(--dash-transition), border-color var(--dash-transition), font-weight var(--dash-transition);
    white-space: nowrap;
}

.dash-status-tabs__tab:hover {
    color: var(--dash-ink-secondary);
    background: rgba(255, 252, 247, 0.5);
}

.dash-status-tabs__tab.active {
    background: var(--dash-paper);
    color: var(--dash-forest);
    font-weight: 600;
    box-shadow: var(--dash-shadow-sm);
    border-bottom: 2px solid var(--dash-forest);
}

.dash-status-tabs__count {
    font-family: var(--dash-font-data);
    font-size: 0.7rem;
    font-weight: 500;
    background: var(--dash-cream-dark);
    color: var(--dash-ink-faint);
    padding: 1px 6px;
    border-radius: 10px;
    min-width: 18px;
    text-align: center;
}

.dash-status-tabs__tab.active .dash-status-tabs__count {
    background: var(--dash-forest-light);
    color: var(--dash-forest);
}

/* ============================================================
   12. SEARCH
   ============================================================ */

.dash-search {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 20px;
    border-bottom: 1px solid var(--dash-cream-dark);
}

.dash-search svg {
    color: var(--dash-ink-faint);
    flex-shrink: 0;
}

.dash-search input {
    flex: 1;
    border: none;
    background: transparent;
    font-family: var(--dash-font-body);
    font-size: 0.85rem;
    color: var(--dash-ink);
    outline: none;
    padding: 2px 0;
}

.dash-search input::placeholder {
    color: var(--dash-ink-faint);
}

.dash-search:focus-within {
    border-bottom-color: var(--dash-forest);
}

.dash-search:focus-within svg {
    color: var(--dash-forest);
}

/* ============================================================
   13. GRANT LIST & ITEMS
   ============================================================ */

.dash-grants-list {
    max-height: 600px;
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--dash-ink-faint) transparent;
}

.dash-grants-list::-webkit-scrollbar {
    width: 6px;
}

.dash-grants-list::-webkit-scrollbar-track {
    background: transparent;
}

.dash-grants-list::-webkit-scrollbar-thumb {
    background: var(--dash-ink-faint);
    border-radius: 3px;
}

.dash-grants-list::-webkit-scrollbar-thumb:hover {
    background: var(--dash-ink-muted);
}

/* D10: Enhanced hover transitions */
.dash-grant-item {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 14px 20px;
    border-bottom: 1px solid var(--dash-cream-dark);
    cursor: pointer;
    transition: background var(--dash-transition), padding-left var(--dash-transition), transform var(--dash-transition), box-shadow var(--dash-transition);
    position: relative;
}

.dash-grant-item:last-child {
    border-bottom: none;
}

/* Status left border */
.dash-grant-item::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 3px;
    border-radius: 0 2px 2px 0;
}

.dash-grant-item--bookmarked::before    { background: var(--dash-navy); }
.dash-grant-item--in_progress::before  { background: var(--dash-gold); }
.dash-grant-item--applied::before      { background: var(--dash-plum); }
.dash-grant-item--approved::before     { background: var(--dash-forest); }
.dash-grant-item--rejected::before     { background: var(--dash-rose); }

/* D10: More visible hover state */
.dash-grant-item:hover {
    background: rgba(250, 245, 238, 0.85);
    padding-left: 24px;
    transform: translateY(-3px);
    box-shadow: 0 4px 12px rgba(26, 23, 20, 0.06);
}

/* Grant title */
.dash-grant-item__title {
    font-family: var(--dash-font-body);
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--dash-ink);
    margin: 0;
    line-height: 1.4;
    /* V1.1 Fix #10: long grant titles like "CanNor IDEANorth (Inclusive
       Diversification…)" blew the inner flex container (scrollWidth 1156px vs
       offsetWidth 675px at 1512 desktop). .dash-grant-item__info already has
       min-width: 0; the title needed explicit wrap permission for tokens
       without natural break points. Also target the inner <a> so anchor text
       wraps the same way. */
    overflow-wrap: break-word;
    word-break: break-word;
}
.dash-grant-item__title a {
    overflow-wrap: break-word;
    word-break: break-word;
}

/* Meta row: org, amount, deadline */
.dash-grant-item__meta {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.dash-grant-item__org {
    font-family: var(--dash-font-body);
    font-size: 0.78rem;
    color: var(--dash-ink-muted);
}

.dash-grant-item__amount {
    font-family: var(--dash-font-body);
    font-size: 0.78rem;
    color: var(--dash-ink-secondary);
    font-weight: 500;
}

.dash-grant-item__deadline {
    font-family: var(--dash-font-body);
    font-size: 0.75rem;
    padding: 2px 8px;
    border-radius: 10px;
    white-space: nowrap;
}

.dash-grant-item__deadline--urgent {
    background: var(--dash-rose-light);
    color: var(--dash-rose);
    font-weight: 600;
}

.dash-grant-item__deadline--soon {
    background: var(--dash-gold-light);
    color: var(--dash-gold);
}

.dash-grant-item__deadline--ongoing {
    background: var(--dash-cream-dark);
    color: var(--dash-ink-muted);
}

/* Top row: info + actions (+ optional compare checkbox) */
.dash-grant-item__top {
    display: flex;
    align-items: flex-start;
    gap: 0;
}

.dash-grant-item__info {
    flex: 1;
    min-width: 0;
}

/* Actions row */
.dash-grant-item__actions {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 2px;
}

/* Status select */
.dash-grant-item__status {
    font-family: var(--dash-font-body);
    font-size: 0.75rem;
    font-weight: 500;
    padding: 3px 10px;
    border-radius: 20px;
    border: 1px solid var(--dash-cream-dark);
    background: var(--dash-paper);
    color: var(--dash-ink-secondary);
    cursor: pointer;
    outline: none;
    transition: border-color var(--dash-transition);
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg width='10' height='6' viewBox='0 0 10 6' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1L5 5L9 1' stroke='%239a9085' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 8px center;
    padding-right: 24px;
}

.dash-grant-item__status:focus-visible {
    border-color: var(--dash-forest);
}

.dash-grant-item__status[data-color="navy"]   { border-color: var(--dash-navy); color: var(--dash-navy); }
.dash-grant-item__status[data-color="gold"]   { border-color: var(--dash-gold); color: var(--dash-gold); }
.dash-grant-item__status[data-color="plum"]   { border-color: var(--dash-plum); color: var(--dash-plum); }
.dash-grant-item__status[data-color="forest"] { border-color: var(--dash-forest); color: var(--dash-forest); }
.dash-grant-item__status[data-color="rose"]   { border-color: var(--dash-rose); color: var(--dash-rose); }

/* Note button */
.dash-grant-item__note-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    border: none;
    background: transparent;
    color: var(--dash-ink-faint);
    cursor: pointer;
    transition: background var(--dash-transition), color var(--dash-transition);
    padding: 0;
}

.dash-grant-item__note-btn:hover {
    background: var(--dash-cream-dark);
    color: var(--dash-ink-muted);
}

.dash-grant-item__note-btn.has-note {
    background: var(--dash-gold-light);
    color: var(--dash-gold);
}

/* Note preview */
.dash-grant-item__note-preview {
    font-family: var(--dash-font-body);
    font-size: 0.78rem;
    font-style: italic;
    color: var(--dash-ink-muted);
    background: var(--dash-cream);
    border-radius: var(--dash-radius-sm);
    padding: 6px 10px;
    margin-top: 4px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    line-height: 1.5;
}

/* Note button with note indicator */
.dash-grant-item__note-btn.has-note {
    background: var(--dash-gold-light);
    color: var(--dash-gold);
}

/* Premium pills (ease/diff/speed inline badges) */
.dash-grant-item__pills {
    display: flex;
    gap: 6px;
    margin-top: 6px;
    flex-wrap: wrap;
}

.dash-pill {
    font-family: var(--dash-font-data);
    font-size: 0.7rem;
    font-weight: 500;
    padding: 2px 8px;
    border-radius: 10px;
    white-space: nowrap;
}

.dash-pill--ease {
    background: var(--dash-forest-light);
    color: var(--dash-forest);
}

.dash-pill--diff {
    background: var(--dash-plum-light);
    color: var(--dash-plum);
}

.dash-pill--speed {
    background: var(--dash-navy-light);
    color: var(--dash-navy);
    font-family: var(--dash-font-body);
}

/* Deadline countdown badge */
.dash-grant-item__countdown {
    font-family: var(--dash-font-body);
    font-size: 0.7rem;
    font-weight: 600;
    padding: 2px 8px;
    border-radius: 10px;
    background: var(--dash-rose-light);
    color: var(--dash-rose);
}

/* Expand button */
.dash-grant-item__expand-btn {
    transition: transform 200ms ease;
}

.dash-grant-item.is-expanded .dash-grant-item__expand-btn {
    transform: rotate(180deg);
}

/* Expanded detail section */
.dash-grant-item__detail {
    border-top: 1px solid var(--dash-cream-dark);
    padding: 14px 16px;
    display: flex;
    flex-direction: column;
    gap: 14px;
    animation: dash-card-enter 0.3s ease;
}

.dash-detail-section h5 {
    font-family: var(--dash-font-body);
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--dash-ink);
    margin: 0 0 8px;
    display: flex;
    align-items: center;
    gap: 6px;
}

.dash-detail-section h5 i,
.dash-detail-section h5 svg {
    width: 14px;
    height: 14px;
    color: var(--dash-forest);
}

.dash-detail-section p {
    font-family: var(--dash-font-body);
    font-size: 0.82rem;
    color: var(--dash-ink-secondary);
    line-height: 1.55;
    margin: 0;
}

.dash-detail-progress {
    font-family: var(--dash-font-data);
    font-size: 0.72rem;
    font-weight: 500;
    color: var(--dash-forest);
    background: var(--dash-forest-light);
    padding: 2px 8px;
    border-radius: 10px;
    margin-left: auto;
}

/* Document checklist */
.dash-detail-docs {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.dash-doc-item {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 6px 8px;
    border-radius: var(--dash-radius-sm);
    font-family: var(--dash-font-body);
    font-size: 0.8rem;
    color: var(--dash-ink-secondary);
    line-height: 1.4;
    cursor: pointer;
    transition: background 150ms ease;
}

.dash-doc-item:hover {
    background: var(--dash-cream);
}

.dash-doc-item input[type="checkbox"] {
    flex-shrink: 0;
    width: 16px;
    height: 16px;
    margin-top: 2px;
    accent-color: var(--dash-forest);
}

.dash-doc-item:has(input:checked) span {
    text-decoration: line-through;
    color: var(--dash-ink-faint);
}

/* Stacking partner tags */
.dash-detail-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.dash-detail-tag {
    font-family: var(--dash-font-body);
    font-size: 0.75rem;
    font-weight: 500;
    padding: 4px 10px;
    border-radius: 14px;
    background: var(--dash-cream);
    color: var(--dash-ink-secondary);
    border: 1px solid var(--dash-cream-dark);
}

/* ============================================================
   14. EMPTY STATES
   ============================================================ */

.dash-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 32px 24px;
    text-align: center;
}

.dash-empty svg {
    color: var(--dash-ink-faint);
    margin-bottom: 16px;
    opacity: 0.6;
}

.dash-empty__title {
    font-family: var(--dash-font-display);
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--dash-ink-secondary);
    margin: 0 0 8px;
}

.dash-empty__text {
    font-family: var(--dash-font-body);
    font-size: 0.85rem;
    color: var(--dash-ink-muted);
    margin: 0 0 20px;
    max-width: 280px;
    line-height: 1.5;
}

.dash-empty__btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 10px 20px;
    background: var(--dash-forest);
    color: #fff;
    font-family: var(--dash-font-body);
    font-size: 0.85rem;
    font-weight: 600;
    border: none;
    border-radius: var(--dash-radius);
    text-decoration: none;
    cursor: pointer;
    transition: background var(--dash-transition), transform var(--dash-transition);
}

.dash-empty__btn:hover {
    background: var(--dash-forest-deep);
    transform: translateY(-1px);
}

/* ============================================================
   15. RECOMMENDATIONS
   ============================================================ */

.dash-recs-list {
    max-height: 500px;
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--dash-ink-faint) transparent;
}

.dash-recs-list::-webkit-scrollbar {
    width: 6px;
}

.dash-recs-list::-webkit-scrollbar-track {
    background: transparent;
}

.dash-recs-list::-webkit-scrollbar-thumb {
    background: var(--dash-ink-faint);
    border-radius: 3px;
}

.dash-recs-list::-webkit-scrollbar-thumb:hover {
    background: var(--dash-ink-muted);
}

.dash-rec-item {
    display: flex;
    flex-direction: column;
    gap: 5px;
    padding: 11px 18px;
    border-bottom: 1px solid var(--dash-cream-dark);
    transition: background var(--dash-transition);
}

.dash-rec-item:last-child {
    border-bottom: none;
}

.dash-rec-item:hover {
    background: var(--dash-cream);
}

.dash-rec-item__top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
}

.dash-rec-item__title {
    font-family: var(--dash-font-body);
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--dash-ink);
    margin: 0;
    line-height: 1.4;
    flex: 1;
    min-width: 0;
}

.dash-rec-item__score {
    font-family: var(--dash-font-data);
    font-size: 0.72rem;
    font-weight: 600;
    color: #fff;
    background: var(--dash-forest);
    padding: 3px 8px;
    border-radius: 10px;
    white-space: nowrap;
    flex-shrink: 0;
}

.dash-rec-item__reason {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-family: var(--dash-font-body);
    font-size: 0.72rem;
    font-weight: 500;
    color: var(--dash-forest);
    background: var(--dash-forest-light);
    padding: 3px 10px;
    border-radius: 10px;
    width: fit-content;
}

.dash-rec-item__meta {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.dash-rec-item__org {
    font-family: var(--dash-font-body);
    font-size: 0.78rem;
    color: var(--dash-ink-muted);
}

.dash-rec-item__amount {
    font-family: var(--dash-font-body);
    font-size: 0.78rem;
    color: var(--dash-ink-secondary);
    font-weight: 500;
}

.dash-rec-item__actions {
    display: flex;
    gap: 8px;
    margin-top: 4px;
}

.dash-rec-item__btn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 5px 12px;
    font-family: var(--dash-font-body);
    font-size: 0.75rem;
    font-weight: 500;
    border-radius: var(--dash-radius-sm);
    border: 1px solid var(--dash-cream-dark);
    background: transparent;
    color: var(--dash-ink-muted);
    cursor: pointer;
    transition: background var(--dash-transition), color var(--dash-transition), border-color var(--dash-transition);
}

.dash-rec-item__btn:hover {
    background: var(--dash-forest-light);
    color: var(--dash-forest);
    border-color: var(--dash-forest);
}

.dash-rec-item__btn--dismiss:hover {
    background: var(--dash-rose-light);
    color: var(--dash-rose);
    border-color: var(--dash-rose);
}

/* ============================================================
   16. NOTE MODAL
   ============================================================ */

.dash-note-modal {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
}

.dash-note-modal__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(26, 23, 20, 0.4);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}

.dash-note-modal__content {
    position: relative;
    max-width: 520px;
    width: 100%;
    background: var(--dash-paper);
    border-radius: var(--dash-radius-lg);
    box-shadow: var(--dash-shadow-lg);
    border: 1px solid var(--dash-cream-dark);
    animation: dash-modal-up 0.3s ease;
    overflow: hidden;
}

.dash-note-modal__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 20px 24px 0;
}

.dash-note-modal__header h4 {
    font-family: var(--dash-font-display);
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--dash-ink);
    margin: 0;
}

.dash-note-modal__close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: none;
    background: transparent;
    color: var(--dash-ink-muted);
    cursor: pointer;
    transition: background var(--dash-transition), color var(--dash-transition);
}

.dash-note-modal__close:hover {
    background: var(--dash-cream-dark);
    color: var(--dash-ink);
}

.dash-note-modal textarea {
    display: block;
    width: 100%;
    margin: 16px 0 0;
    padding: 14px 24px;
    font-family: var(--dash-font-body);
    font-size: 0.9rem;
    color: var(--dash-ink);
    background: var(--dash-cream);
    border: none;
    border-top: 1px solid var(--dash-cream-dark);
    border-bottom: 1px solid var(--dash-cream-dark);
    outline: none;
    resize: vertical;
    min-height: 140px;
    line-height: 1.6;
    box-sizing: border-box;
    transition: border-color var(--dash-transition);
}

.dash-note-modal textarea:focus {
    border-color: var(--dash-forest);
}

.dash-note-modal textarea::placeholder {
    color: var(--dash-ink-faint);
}

.dash-note-modal__footer {
    padding: 16px 24px 20px;
}

.dash-note-modal__save {
    display: block;
    width: 100%;
    padding: 12px 24px;
    background: var(--dash-forest);
    color: #fff;
    font-family: var(--dash-font-body);
    font-size: 0.9rem;
    font-weight: 600;
    border: none;
    border-radius: var(--dash-radius);
    cursor: pointer;
    transition: background var(--dash-transition), transform var(--dash-transition);
}

.dash-note-modal__save:hover {
    background: var(--dash-forest-deep);
    transform: translateY(-1px);
}

.dash-note-modal__save:active {
    transform: translateY(0);
}

/* ============================================================
   17. AUTH MODAL
   ============================================================ */

/* ★★ 2026-09-01 (Round 3). This modal TRAPPED a locked-out member on a phone.
   Three faults compounded, and each alone looked harmless:
     1. z-index:1000 sat UNDER the fixed nav (nav-v7.css:51, z-index:1300), so at
        375x667 the close x was 61% covered by .nav__inner — elementFromPoint
        returned the NAV, and a real tap on the x NAVIGATED TO THE HOMEPAGE.
     2. No overflow-y. The container is viewport-height by `inset:0`, so once the
        error box + hint made the card taller than the viewport there was nowhere
        to scroll: at 320x568 the x sat at top -32px and the heading was gone.
     3. `align-items:center` on a scroll container CLIPS THE TOP UNREACHABLY —
        the classic flex overflow trap — so simply adding overflow-y would not
        have brought the x back. `margin:auto` on the item is the fix that does:
        auto margins centre while there is free space and collapse to 0 when the
        item overflows, leaving BOTH edges reachable.
   Fixed here rather than by shrinking the message: an error that makes a modal
   unusable is a layout bug, not a reason to say less. Focus trapping is
   untouched — nothing about the DOM order, `inert` handling or the close
   binding changes. */
.dash-auth-modal {
    position: fixed;
    inset: 0;
    z-index: 1400;              /* ABOVE the fixed nav (1300) — a modal covers the page it blocks */
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    overflow-y: auto;           /* the WHOLE modal scrolls; the container is viewport-bound by inset:0 */
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
}

.dash-auth-modal__backdrop {
    /* fixed, not absolute: an absolutely-positioned backdrop inside a SCROLLING
       container covers only the un-scrolled box, so scrolling a tall modal used
       to reveal undimmed page beneath it. */
    position: fixed;
    inset: 0;
    background: rgba(26, 23, 20, 0.4);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}

.dash-auth-modal__content {
    position: relative;
    max-width: 420px;
    width: 100%;
    margin: auto;               /* see (3) above — NOT align-items alone */
    background: var(--dash-paper);
    border-radius: var(--dash-radius-lg);
    box-shadow: var(--dash-shadow-lg);
    border: 1px solid var(--dash-cream-dark);
    padding: 36px 32px;
    animation: dash-modal-up 0.3s ease;
}

.dash-auth-modal__close {
    position: absolute;
    top: 12px;
    right: 12px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: none;
    background: transparent;
    color: var(--dash-ink-muted);
    cursor: pointer;
    transition: background var(--dash-transition), color var(--dash-transition);
}

.dash-auth-modal__close:hover {
    background: var(--dash-cream-dark);
    color: var(--dash-ink);
}

/* Auth form elements (rendered by JS) */
.dash-auth-modal__content h3 {
    font-family: var(--dash-font-display);
    font-size: 1.35rem;
    font-weight: 600;
    color: var(--dash-ink);
    margin: 0 0 8px;
    text-align: center;
}

.dash-auth-modal__content p {
    font-family: var(--dash-font-body);
    font-size: 0.88rem;
    color: var(--dash-ink-muted);
    text-align: center;
    margin: 0 0 24px;
    line-height: 1.5;
}

.dash-auth-form {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.dash-auth-form label {
    font-family: var(--dash-font-body);
    font-size: 0.82rem;
    font-weight: 500;
    color: var(--dash-ink-secondary);
    display: block;
    margin-bottom: 4px;
}

.dash-auth-form input[type="email"],
.dash-auth-form input[type="password"],
.dash-auth-form input[type="text"] {
    width: 100%;
    padding: 11px 14px;
    font-family: var(--dash-font-body);
    font-size: 0.9rem;
    color: var(--dash-ink);
    background: var(--dash-cream);
    border: 1.5px solid var(--dash-cream-dark);
    border-radius: var(--dash-radius);
    outline: none;
    transition: border-color var(--dash-transition), box-shadow var(--dash-transition);
    box-sizing: border-box;
}

.dash-auth-form input:focus {
    border-color: var(--dash-forest);
    box-shadow: 0 0 0 3px var(--dash-forest-light);
}

.dash-auth-form input::placeholder {
    color: var(--dash-ink-faint);
}

.dash-auth-form__submit {
    width: 100%;
    padding: 12px 24px;
    background: var(--dash-forest);
    color: #fff;
    font-family: var(--dash-font-body);
    font-size: 0.9rem;
    font-weight: 600;
    border: none;
    border-radius: var(--dash-radius);
    cursor: pointer;
    transition: background var(--dash-transition), transform var(--dash-transition);
    margin-top: 4px;
}

.dash-auth-form__submit:hover {
    background: var(--dash-forest-deep);
    transform: translateY(-1px);
}

.dash-auth-form__submit:active {
    transform: translateY(0);
}

.dash-auth-form__google {
    width: 100%;
    padding: 11px 24px;
    background: #fff;
    color: var(--dash-ink);
    font-family: var(--dash-font-body);
    font-size: 0.9rem;
    font-weight: 500;
    border: 1.5px solid var(--dash-cream-dark);
    border-radius: var(--dash-radius);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    transition: background var(--dash-transition), border-color var(--dash-transition);
}

.dash-auth-form__google:hover {
    background: var(--dash-cream);
    border-color: var(--dash-ink-faint);
}

.dash-auth-form__divider {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 4px 0;
}

.dash-auth-form__divider::before,
.dash-auth-form__divider::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--dash-cream-dark);
}

.dash-auth-form__divider span {
    font-family: var(--dash-font-body);
    font-size: 0.78rem;
    color: var(--dash-ink-faint);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.dash-auth-form__switch {
    text-align: center;
    margin-top: 8px;
    font-family: var(--dash-font-body);
    font-size: 0.85rem;
    color: var(--dash-ink-muted);
}

.dash-auth-form__switch a {
    color: var(--dash-forest);
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
}

.dash-auth-form__switch a:hover {
    text-decoration: underline;
}

/* Forgot-password row (2026-08-30, auth audit): quiet, right-aligned, above the error slot */
.dash-auth-form__forgot { margin: -4px 0 10px; font-size: 12.5px; text-align: right; }
.dash-auth-form__forgot a { color: #4F4A40; text-decoration: underline; text-underline-offset: 2px; }
.dash-auth-form__forgot a:hover { color: #14532D; }

.dash-auth-form__error {
    font-family: var(--dash-font-body);
    font-size: 0.82rem;
    color: #A8401C; /* 5.4:1 on --dash-rose-light; the token measured 4.0:1 (2026-09-01) */
    background: var(--dash-rose-light);
    padding: 10px 14px;
    border-radius: var(--dash-radius-sm);
    text-align: center;
}

/* ============================================================
   18. TOAST NOTIFICATIONS
   ============================================================ */

#toastContainer {
    position: fixed;
    bottom: 24px;
    right: 24px;
    z-index: 2000;
    display: flex;
    flex-direction: column;
    gap: 8px;
    pointer-events: none;
}

.dash-toast {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 18px;
    background: var(--dash-paper);
    border: 1px solid var(--dash-cream-dark);
    border-radius: var(--dash-radius);
    box-shadow: var(--dash-shadow-lg);
    font-family: var(--dash-font-body);
    font-size: 0.85rem;
    color: var(--dash-ink);
    max-width: 360px;
    pointer-events: auto;
    animation: dash-toast-in 0.3s ease;
}

.dash-toast--success {
    border-left: 3px solid var(--dash-forest);
}

.dash-toast--error {
    border-left: 3px solid var(--dash-rose);
}

.dash-toast--info {
    border-left: 3px solid var(--dash-navy);
}

.dash-toast.is-exiting {
    animation: dash-toast-out 0.3s ease forwards;
}

.dash-toast svg {
    flex-shrink: 0;
    width: 18px;
    height: 18px;
}

.dash-toast--success svg { color: var(--dash-forest); }
.dash-toast--error svg   { color: var(--dash-rose); }
.dash-toast--info svg    { color: var(--dash-navy); }

/* ============================================================
   20. SETTINGS PANEL
   ============================================================ */

.dash-settings {
    background: var(--dash-paper);
    border: 1px solid var(--dash-cream-dark);
    border-radius: var(--dash-radius-lg);
    padding: 28px;
    margin-top: 24px;
    box-shadow: var(--dash-shadow-sm);
    animation: dash-card-enter 0.35s ease;
}

/* Settings gear button in header */
.dash-header__settings {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    border: 1px solid var(--dash-cream-dark);
    background: var(--dash-paper);
    color: var(--dash-ink-secondary);
    cursor: pointer;
    transition: all 0.2s ease;
}

.dash-header__settings:hover {
    border-color: var(--dash-forest);
    color: var(--dash-forest);
    background: var(--dash-forest-light);
}

.dash-header__settings.is-active {
    border-color: var(--dash-forest);
    color: var(--dash-paper);
    background: var(--dash-forest);
}

.dash-header__settings svg {
    transition: transform 0.3s ease;
}

.dash-header__settings:hover svg {
    transform: rotate(45deg);
}

.dash-header__settings.is-active svg {
    transform: rotate(90deg);
}

/* Settings header */
.dash-settings__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 24px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--dash-cream-dark);
}

.dash-settings__header .dash-section-title {
    margin: 0;
}

.dash-settings__close {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: 1px solid var(--dash-cream-dark);
    background: var(--dash-paper);
    color: var(--dash-ink-muted);
    cursor: pointer;
    transition: all 0.2s ease;
}

.dash-settings__close:hover {
    border-color: var(--dash-ink-secondary);
    color: var(--dash-ink);
    background: var(--dash-cream);
}

/* Section cards */
.dash-settings__section {
    padding: 20px 0;
    border-bottom: 1px solid var(--dash-cream-dark);
}

.dash-settings__section:last-child {
    border-bottom: none;
    padding-bottom: 0;
}

.dash-settings__section-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: var(--dash-radius-sm);
    background: var(--dash-forest-light);
    color: var(--dash-forest);
    margin-bottom: 8px;
}

.dash-settings__section-icon--danger {
    background: var(--dash-rose-light);
    color: var(--dash-rose);
}

.dash-settings__section-title {
    font-family: var(--dash-font-display);
    font-weight: 600;
    font-size: 1.05rem;
    color: var(--dash-ink);
    margin: 0 0 12px 0;
    line-height: 1.3;
}

.dash-settings__section-title--danger {
    color: var(--dash-rose);
}

.dash-settings__hint {
    font-family: var(--dash-font-body);
    font-size: 0.85rem;
    color: var(--dash-ink-muted);
    line-height: 1.5;
    margin: 0 0 14px 0;
}

/* Field styles */
.dash-settings__field {
    margin-bottom: 14px;
}

.dash-settings__field:last-child {
    margin-bottom: 0;
}

.dash-settings__label {
    display: block;
    font-family: var(--dash-font-body);
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--dash-ink-secondary);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    margin-bottom: 6px;
}

.dash-settings__input-row {
    display: flex;
    gap: 8px;
    align-items: center;
}

.dash-settings__input {
    flex: 1;
    font-family: var(--dash-font-body);
    font-size: 0.9rem;
    color: var(--dash-ink);
    background: var(--dash-cream);
    border: 1px solid var(--dash-cream-dark);
    border-radius: var(--dash-radius-sm);
    padding: 9px 14px;
    outline: none;
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.dash-settings__input:focus {
    border-color: var(--dash-forest);
    box-shadow: 0 0 0 3px rgba(45, 106, 79, 0.08);
}

.dash-settings__input::placeholder {
    color: var(--dash-ink-faint);
}

.dash-settings__save-btn {
    font-family: var(--dash-font-body);
    font-size: 0.82rem;
    font-weight: 600;
    color: #fff;
    background: var(--dash-forest);
    border: none;
    border-radius: var(--dash-radius-sm);
    padding: 9px 18px;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.2s ease, transform 0.1s ease;
}

.dash-settings__save-btn:hover {
    background: var(--dash-forest-deep);
}

.dash-settings__save-btn:active {
    transform: scale(0.97);
}

.dash-settings__save-btn:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

.dash-settings__readonly {
    font-family: var(--dash-font-body);
    font-size: 0.9rem;
    color: var(--dash-ink-secondary);
    background: var(--dash-cream);
    border: 1px solid var(--dash-cream-dark);
    border-radius: var(--dash-radius-sm);
    padding: 9px 14px;
}

.dash-settings__account-info {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.dash-settings__badge {
    display: inline-flex;
    align-items: center;
    font-family: var(--dash-font-body);
    font-size: 0.75rem;
    font-weight: 700;
    padding: 4px 10px;
    border-radius: 20px;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.dash-settings__badge--free {
    color: var(--dash-ink-secondary);
    background: var(--dash-cream-dark);
}

.dash-settings__badge--premium {
    color: #fff;
    background: linear-gradient(135deg, var(--dash-gold), #d4a30a);
}

.dash-settings__date {
    font-family: var(--dash-font-body);
    font-size: 0.82rem;
    color: var(--dash-ink-muted);
}

/* Action button (password, export) */
.dash-settings__action-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: var(--dash-font-body);
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--dash-forest);
    background: var(--dash-forest-light);
    border: 1px solid rgba(45, 106, 79, 0.15);
    border-radius: var(--dash-radius-sm);
    padding: 10px 18px;
    cursor: pointer;
    transition: all 0.2s ease;
}

.dash-settings__action-btn:hover {
    background: rgba(45, 106, 79, 0.14);
    border-color: var(--dash-forest);
}

.dash-settings__action-btn:active {
    transform: scale(0.97);
}

.dash-settings__action-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Toggle switches */
.dash-settings__toggles {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.dash-settings__toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 12px 0;
    cursor: pointer;
    border-bottom: 1px solid rgba(242, 235, 224, 0.5);
}

.dash-settings__toggle:last-child {
    border-bottom: none;
}

.dash-settings__toggle-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.dash-settings__toggle-label {
    font-family: var(--dash-font-body);
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--dash-ink);
}

.dash-settings__toggle-desc {
    font-family: var(--dash-font-body);
    font-size: 0.78rem;
    color: var(--dash-ink-muted);
}

/* Custom switch track */
.dash-settings__switch {
    position: relative;
    display: inline-flex;
    flex-shrink: 0;
}

.dash-settings__switch input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.dash-settings__switch-track {
    width: 44px;
    height: 24px;
    background: var(--dash-cream-dark);
    border-radius: 12px;
    position: relative;
    transition: background 0.25s ease;
    cursor: pointer;
}

.dash-settings__switch-track::after {
    content: '';
    position: absolute;
    width: 18px;
    height: 18px;
    background: #fff;
    border-radius: 50%;
    top: 3px;
    left: 3px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.15);
    transition: transform 0.25s ease;
}

.dash-settings__switch input:checked + .dash-settings__switch-track {
    background: var(--dash-forest);
}

.dash-settings__switch input:checked + .dash-settings__switch-track::after {
    transform: translateX(20px);
}

.dash-settings__switch input:focus-visible + .dash-settings__switch-track {
    box-shadow: 0 0 0 3px rgba(45, 106, 79, 0.2);
}

/* Danger section */
.dash-settings__section--danger {
    margin-top: 4px;
    padding-top: 20px;
}

.dash-settings__danger-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: var(--dash-font-body);
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--dash-rose);
    background: var(--dash-rose-light);
    border: 1px solid rgba(196, 83, 43, 0.15);
    border-radius: var(--dash-radius-sm);
    padding: 10px 18px;
    cursor: pointer;
    transition: all 0.2s ease;
}

.dash-settings__danger-btn:hover {
    background: rgba(196, 83, 43, 0.14);
    border-color: var(--dash-rose);
}

.dash-settings__danger-btn:active {
    transform: scale(0.97);
}

/* Delete confirmation */
.dash-settings__delete-warning {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    background: rgba(196, 83, 43, 0.06);
    border: 1px solid rgba(196, 83, 43, 0.15);
    border-radius: var(--dash-radius-sm);
    padding: 14px 16px;
    font-family: var(--dash-font-body);
    font-size: 0.85rem;
    color: var(--dash-ink);
    line-height: 1.5;
    margin-bottom: 14px;
}

.dash-settings__delete-warning svg {
    flex-shrink: 0;
    color: var(--dash-rose);
    margin-top: 1px;
}

.dash-settings__delete-actions {
    display: flex;
    gap: 10px;
    align-items: center;
}

.dash-settings__cancel-btn {
    font-family: var(--dash-font-body);
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--dash-ink-secondary);
    background: var(--dash-cream);
    border: 1px solid var(--dash-cream-dark);
    border-radius: var(--dash-radius-sm);
    padding: 9px 18px;
    cursor: pointer;
    transition: all 0.2s ease;
}

.dash-settings__cancel-btn:hover {
    border-color: var(--dash-ink-faint);
    background: var(--dash-cream-dark);
}

.dash-settings__confirm-delete-btn {
    font-family: var(--dash-font-body);
    font-size: 0.85rem;
    font-weight: 600;
    color: #fff;
    background: var(--dash-rose);
    border: none;
    border-radius: var(--dash-radius-sm);
    padding: 9px 18px;
    cursor: pointer;
    transition: all 0.2s ease;
}

.dash-settings__confirm-delete-btn:hover {
    background: #b0442a;
}

.dash-settings__confirm-delete-btn:active {
    transform: scale(0.97);
}

.dash-settings__confirm-delete-btn:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* ============================================================
   21. ANIMATIONS & KEYFRAMES
   ============================================================ */

@keyframes dash-spin {
    to {
        transform: rotate(360deg);
    }
}

@keyframes dash-count-up {
    from {
        opacity: 0;
        transform: translateY(8px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes dash-card-enter {
    from {
        opacity: 0;
        transform: translateY(12px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes dash-modal-up {
    from {
        opacity: 0;
        transform: translateY(20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes dash-toast-in {
    from {
        opacity: 0;
        transform: translateX(100%);
    }
    to {
        opacity: 1;
        transform: translateX(0);
    }
}

@keyframes dash-toast-out {
    from {
        opacity: 1;
        transform: translateX(0);
    }
    to {
        opacity: 0;
        transform: translateX(100%);
    }
}

/* ============================================================
   22. RESPONSIVE — TABLET (max-width: 1024px)
   ============================================================ */

@media (max-width: 1024px) {
    .dash-grid {
        grid-template-columns: 1fr;
    }

    .dash-header__right {
        gap: 8px;
    }

    .dash-header__member {
        display: none;
    }

    .dash-sub {
        flex-direction: column;
        align-items: flex-start;
    }

    .dash-sub--free .dash-sub__cta,
    .dash-sub--premium .dash-sub__cta {
        align-self: flex-start;
    }

    .dash-sub--premium .dash-sub__details {
        flex-direction: column;
        gap: 4px;
    }

    .dash-settings {
        padding: 24px;
    }
}

/* ============================================================
   23. RESPONSIVE — MOBILE (max-width: 768px)
   ============================================================ */

@media (max-width: 768px) {
    .dash-container {
        padding: 0 16px;
    }

    .dash-main {
        padding-top: calc(var(--dash-navbar-height) + 20px);
        padding-bottom: 40px;
    }

    .dash-header {
        flex-direction: column;
        align-items: flex-start;
        gap: 12px;
    }

    .dash-header__right {
        width: 100%;
        justify-content: flex-end;
    }

    .dash-status-tabs {
        margin: 12px 12px 0;
    }

    .dash-status-tabs__tab {
        padding: 7px 10px;
        font-size: 0.75rem;
    }

    .dash-grant-item {
        padding: 12px 16px;
    }

    .dash-grant-item__meta {
        gap: 8px;
    }

    .dash-grant-item__org {
        font-size: 0.72rem;
    }

    .dash-card__header {
        padding: 14px 16px 0;
    }

    .dash-search {
        padding: 8px 16px;
    }

    .dash-completion {
        flex-direction: column;
        align-items: flex-start;
        gap: 10px;
        padding: 12px 16px;
    }

    .dash-completion__track {
        width: 100%;
    }

    .dash-note-modal__content {
        margin: auto 16px;
    }

    .dash-auth-modal {
        /* 320x568 is the tightest real phone: 16px gutters keep the card wide
           enough to read, and the vertical padding guarantees the close x is
           never flush against the viewport edge once the modal scrolls. */
        padding: 16px;
    }

    .dash-auth-modal__content {
        padding: 28px 24px;
    }

    #toastContainer {
        bottom: 16px;
        right: 16px;
        left: 16px;
    }

    .dash-toast {
        max-width: none;
    }

    .dash-recs-list {
        max-height: 400px;
    }

    .dash-deco-circle--one {
        width: 250px;
        height: 250px;
    }

    .dash-deco-circle--two {
        width: 180px;
        height: 180px;
    }

    .dash-settings {
        padding: 20px 16px;
        margin-top: 16px;
    }

    .dash-settings__header {
        margin-bottom: 16px;
        padding-bottom: 12px;
    }

    .dash-settings__section {
        padding: 16px 0;
    }

    .dash-settings__input-row {
        flex-direction: column;
        gap: 10px;
    }

    .dash-settings__save-btn {
        align-self: flex-start;
    }

    .dash-settings__delete-actions {
        flex-direction: column;
        gap: 8px;
    }

    .dash-settings__cancel-btn,
    .dash-settings__confirm-delete-btn {
        width: 100%;
        text-align: center;
        justify-content: center;
    }
}

/* ============================================================
   24. RESPONSIVE — SMALL MOBILE (max-width: 480px)
   ============================================================ */

@media (max-width: 480px) {
    .dash-header__greeting {
        font-size: 1.25rem;
    }

    .dash-header__explore-btn span {
        display: none;
    }

    .dash-grants-list {
        max-height: none;
    }

    .dash-recs-list {
        max-height: none;
    }

    .dash-status-tabs {
        margin: 10px 8px 0;
        gap: 1px;
    }

    .dash-status-tabs__tab {
        padding: 6px 8px;
        font-size: 0.72rem;
    }

    .dash-status-tabs__count {
        font-size: 0.65rem;
        padding: 1px 5px;
    }

    .dash-auth-gate__card {
        padding: 36px 24px;
    }

    .dash-auth-gate__card h2 {
        font-size: 1.3rem;
    }

    .dash-note-modal textarea {
        padding: 12px 16px;
    }

    .dash-note-modal__header,
    .dash-note-modal__footer {
        padding-left: 16px;
        padding-right: 16px;
    }

    .dash-settings__section-title {
        font-size: 0.95rem;
    }

    .dash-settings__toggle {
        padding: 10px 0;
    }

    .dash-settings__toggle-label {
        font-size: 0.85rem;
    }

    .dash-settings__toggle-desc {
        font-size: 0.72rem;
    }

    .dash-settings__action-btn,
    .dash-settings__danger-btn {
        font-size: 0.8rem;
        padding: 9px 14px;
    }
}

/* ============================================================
   25. REDUCED MOTION
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/* ============================================================
   26. CUSTOM SCROLLBAR (global for dashboard)
   ============================================================ */

.dash-main {
    scrollbar-width: thin;
    scrollbar-color: var(--dash-ink-faint) transparent;
}

.dash-main ::-webkit-scrollbar {
    width: 6px;
}

.dash-main ::-webkit-scrollbar-track {
    background: transparent;
}

.dash-main ::-webkit-scrollbar-thumb {
    background: var(--dash-ink-faint);
    border-radius: 3px;
}

.dash-main ::-webkit-scrollbar-thumb:hover {
    background: var(--dash-ink-muted);
}

/* ============================================================
   29. D8 — PDF EXPORT BUTTON SPINNER
   ============================================================ */

.dash-btn-spinner {
    display: inline-block;
    width: 14px;
    height: 14px;
    border: 2px solid var(--dash-ink-faint);
    border-top-color: var(--dash-forest);
    border-radius: 50%;
    animation: dash-spin 0.7s linear infinite;
}

.dash-icon-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* ============================================================
   30. D9 — NOTE MODAL CHARACTER COUNTER
   ============================================================ */

.dash-note-char-count {
    font-family: var(--dash-font-data);
    font-size: 0.72rem;
    color: var(--dash-ink-faint);
    text-align: right;
    margin-bottom: 8px;
    transition: color var(--dash-transition);
}

.dash-note-char-count--warn {
    color: var(--dash-rose);
}

/* ============================================================
   31. D11 — SETTINGS TOGGLE ANIMATION
   ============================================================ */

/* Already have transition on .dash-settings__switch-track (line 2666)
   and ::after (line 2680). This ensures both are smooth. */

.dash-settings__switch-track {
    transition: background-color 0.25s ease;
}

.dash-settings__switch-track::after {
    transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

/* ============================================================
   32. D13 — RECOMMENDATION SKELETON LOADING
   ============================================================ */

.dash-skeleton {
    position: relative;
    overflow: hidden;
    background: var(--dash-cream-dark);
    border-radius: var(--dash-radius);
    border-bottom: 1px solid var(--dash-cream-dark);
}

.dash-skeleton--rec {
    height: 88px;
    margin: 0 20px;
    margin-bottom: 1px;
    border-radius: 0;
}

.dash-skeleton--rec:first-child {
    margin-top: 8px;
}

.dash-skeleton::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(
        90deg,
        transparent 0%,
        rgba(255, 252, 247, 0.5) 50%,
        transparent 100%
    );
    animation: dash-shimmer 1.5s ease-in-out infinite;
}

@keyframes dash-shimmer {
    0% {
        transform: translateX(-100%);
    }
    100% {
        transform: translateX(100%);
    }
}

/* ============================================================
   34. D17 — FOOTER NEWSLETTER SUCCESS/ERROR
   ============================================================ */

.dash-newsletter-success {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 0;
    font-family: var(--dash-font-body);
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--dash-forest);
    animation: dash-card-enter 0.3s ease;
}

.dash-newsletter-success svg {
    color: var(--dash-forest);
    flex-shrink: 0;
}

.dash-newsletter-error {
    font-family: var(--dash-font-body);
    font-size: 0.82rem;
    color: var(--dash-rose);
    margin-top: 8px;
    animation: dash-card-enter 0.3s ease;
}

/* ============================================================
   35. D18 — DOCUMENT CHECKLIST SAVE CONFIRMATION
   ============================================================ */

.dash-doc-saved {
    font-family: var(--dash-font-body);
    font-size: 0.68rem;
    font-weight: 600;
    color: var(--dash-forest);
    margin-left: auto;
    padding: 1px 8px;
    border-radius: 10px;
    background: var(--dash-forest-light);
    animation: dash-card-enter 0.2s ease;
    transition: opacity 0.3s ease;
    flex-shrink: 0;
}

.dash-doc-saved--out {
    opacity: 0;
}

/* ============================================================
   36. PAYMENT WARNING BANNER
   ============================================================ */

.dash-payment-warning {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 20px;
    background: #FFF3CD;
    border: 1px solid #FFECB5;
    border-radius: var(--dash-radius);
    margin-bottom: 20px;
    font-family: var(--dash-font-body);
    font-size: 0.85rem;
    color: #664D03;
    line-height: 1.5;
}

.dash-payment-warning svg {
    flex-shrink: 0;
    color: #856404;
}

.dash-payment-warning a {
    color: #664D03;
    font-weight: 600;
    text-decoration: underline;
}

.dash-payment-warning a:hover {
    color: #533B03;
}

/* 2026-09-27: Premium paused for an unpaid bill — a stronger state than the grace-period notice; not dismissible. */
.dash-payment-warning--paused {
    background: #FDECEC;
    border-color: #F5C2C2;
    color: #7A1C1C;
}
.dash-payment-warning--paused svg,
.dash-payment-warning--paused a { color: #7A1C1C; }
.dash-payment-warning--paused a:hover { color: #5C1414; }

.dash-payment-warning__close {
    background: none;
    border: none;
    font-size: 18px;
    color: #664D03;
    cursor: pointer;
    margin-left: auto;
    padding: 4px;
    opacity: 0.7;
    line-height: 1;
    flex-shrink: 0;
}

.dash-payment-warning__close:hover {
    opacity: 1;
}

/* Subscription panel: past_due state */
.dash-sub--past-due {
    border-color: #FFECB5;
}

.dash-sub__past-due-alert {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    background: #FFF3CD;
    border: 1px solid #FFECB5;
    border-radius: var(--dash-radius-sm);
    margin: 0 16px 12px;
    font-size: 0.8rem;
    color: #664D03;
    line-height: 1.4;
}

.dash-sub__past-due-alert svg {
    flex-shrink: 0;
    color: #856404;
}

.dash-sub__past-due-alert a {
    color: #664D03;
    font-weight: 600;
    text-decoration: underline;
}

.dash-sub__past-due-alert a:hover {
    color: #533B03;
}

/* Subscription panel: cancelled badge */
.dash-sub__cancelled {
    font-size: 0.75rem;
    color: #856404;
    font-weight: 500;
}

@media (max-width: 768px) {
    .dash-payment-warning {
        padding: 10px 14px;
        font-size: 0.8rem;
        gap: 8px;
    }

    .dash-sub__past-due-alert {
        margin: 0 12px 10px;
        font-size: 0.75rem;
    }
}

/* ============================================================
   37. REDUCED MOTION — Additional items
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
    .dash-skeleton::after {
        animation: none;
    }

    .dash-btn-spinner {
        animation: none;
    }
}

/* Trial expired banner */
.trial-expired-banner {
    background: #fffbeb; border: 1px solid #fde68a; border-radius: 10px;
    padding: 14px 20px; margin: 16px auto; max-width: 1200px;
}
.trial-expired-banner__content {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.trial-expired-banner__content strong { color: #92400e; font-size: 14px; }
.trial-expired-banner__content span { color: #a16207; font-size: 13px; }
.trial-expired-banner__cta {
    padding: 6px 14px; background: #15803d; color: #fff !important;
    border-radius: 6px; font-size: 13px; font-weight: 600; text-decoration: none;
    margin-left: auto;
}
.trial-expired-banner__close {
    background: none; border: none; cursor: pointer; color: #a16207;
    font-size: 20px; padding: 0 4px; line-height: 1;
}

/* Active trial countdown badge */
.dash-trial-badge {
    background: #f0fdf4; border: 1px solid #bbf7d0; border-radius: 8px;
    padding: 10px 16px; margin-bottom: 16px; font-size: 13px; color: #15803d;
}
.dash-trial-badge__sub { color: #6b7280; }

/* ============================================================
   MY PLAYBOOKS — $19 one-time unlock section (Apr 22 2026)
   Sits between dash-subscription and dash-quiz-profile. Hidden
   by default; JS reveals when user has ≥1 Playbook Unlock.
   ============================================================ */

.dash-playbooks {
    animation: dash-card-enter 0.4s ease both;
    animation-delay: 260ms;
    margin-top: 16px;
    background: var(--dash-paper);
    border: 1px solid var(--dash-cream-dark);
    border-left: 3px solid var(--accent-sienna, #c4532b);
    border-radius: var(--dash-radius);
    padding: 20px 24px;
}

.dash-playbook__header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 16px;
}

.dash-playbook__header .dash-section-title {
    margin: 0 0 2px;
}

.dash-playbook__subtitle {
    font-size: 13px;
    color: var(--dash-ink-muted, #64748b);
    margin: 0;
}

.dash-playbook__upgrade {
    font-size: 13px;
    font-weight: 600;
    color: var(--accent-forest, #14532d);
    text-decoration: none;
    white-space: nowrap;
    padding: 6px 12px;
    border-radius: 8px;
    border: 1px solid var(--accent-forest, #14532d);
    transition: background 160ms ease;
    flex-shrink: 0;
}
.dash-playbook__upgrade:hover {
    background: var(--accent-forest, #14532d);
    color: #fff;
}

.dash-playbook__list {
    display: grid;
    gap: 8px;
}

.dash-playbook__item {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 14px;
    padding: 12px 14px;
    background: var(--dash-cream, #fdfcfa);
    border: 1px solid var(--dash-cream-dark, #e7e2da);
    border-radius: 10px;
    text-decoration: none;
    color: inherit;
    transition: border-color 160ms ease, transform 160ms ease;
}

.dash-playbook__item:hover {
    border-color: var(--accent-sienna, #c4532b);
    transform: translateY(-1px);
}

.dash-playbook__icon {
    width: 32px;
    height: 32px;
    border-radius: 8px;
    background: rgba(196, 83, 43, 0.12);
    color: var(--accent-sienna, #c4532b);
    display: grid;
    place-items: center;
    flex-shrink: 0;
}

.dash-playbook__text {
    min-width: 0;
}

.dash-playbook__title {
    font-size: 14px;
    font-weight: 600;
    color: var(--dash-ink, #1a1714);
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dash-playbook__org {
    font-size: 12px;
    color: var(--dash-ink-secondary, #57534e);
    margin-top: 2px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dash-playbook__meta {
    font-size: 11px;
    color: var(--dash-ink-muted, #64748b);
    margin-top: 2px;
    letter-spacing: 0.02em;
}

.dash-playbook__cta {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 13px;
    font-weight: 600;
    color: var(--accent-forest, #14532d);
    white-space: nowrap;
    flex-shrink: 0;
}

@media (max-width: 600px) {
    .dash-playbooks {
        padding: 16px 18px;
    }
    .dash-playbook__header {
        flex-direction: column;
        gap: 8px;
    }
    .dash-playbook__upgrade {
        width: 100%;
        text-align: center;
    }
    .dash-playbook__item {
        grid-template-columns: auto 1fr;
        gap: 10px;
    }
    .dash-playbook__cta {
        grid-column: 1 / -1;
        justify-content: flex-end;
        padding-top: 4px;
    }
}

/* ─── VIP / Comp Access (Apr 22 2026) ──────────────────────────────────────
   Gold-accented variants for admin-granted premium users. Mirrors the
   .dash-sub--premium card structure but with a warm gold palette so VIPs
   feel like VIPs without looking out of place in the dashboard. */

.dash-sub--vip {
    border-left: 3px solid #d4a017;
    background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%);
    flex-wrap: wrap;
}

.dash-sub--vip .dash-sub__title {
    font-family: var(--dash-font-display);
    font-size: 1.05rem;
    font-weight: 700;
    color: #78350f;
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 4px;
}

.dash-sub--vip .dash-sub__renewal {
    color: #92400e;
    font-size: 0.85rem;
    margin: 0;
}

.dash-sub--vip .dash-sub__icon--vip {
    background: linear-gradient(135deg, #fbbf24 0%, #d4a017 100%);
    color: #fff;
}

.dash-sub--vip .dash-sub__usage {
    border-top: 1px solid #fde68a;
    margin-top: 14px;
    padding-top: 14px;
}

.dash-sub--vip .dash-sub__usage-number {
    color: #78350f;
}

.dash-sub--vip .dash-sub__usage-label {
    color: #92400e;
}

.dash-sub--vip .dash-sub__cta {
    background: #78350f;
    color: #fff;
    border: 1px solid #78350f;
}

.dash-sub--vip .dash-sub__cta:hover {
    background: #92400e;
    border-color: #92400e;
}

.dash-vip-sparkle {
    font-size: 0.95em;
    filter: drop-shadow(0 1px 2px rgba(212, 160, 23, 0.3));
}

/* VIP pill used in Settings "Your Plan" row */
.dash-vip-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 14px;
    background: linear-gradient(135deg, #fbbf24 0%, #d4a017 100%);
    color: #fff;
    border-radius: 20px;
    font-family: var(--dash-font-body);
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    box-shadow: 0 1px 3px rgba(212, 160, 23, 0.35);
}

.dash-vip-pill__sparkle {
    font-size: 0.95em;
}

.dash-vip-granted-on {
    color: var(--dash-ink-muted);
    font-style: italic;
}

/* VIP variant of the settings account-type badge */
.dash-settings__badge--vip {
    background: linear-gradient(135deg, #fbbf24 0%, #d4a017 100%);
    color: #fff;
    font-weight: 700;
    letter-spacing: 0.03em;
}

.dash-settings__section--vip {
    border-left: 2px solid #fbbf24;
    padding-left: 14px;
    background: linear-gradient(135deg, #fffbeb 0%, transparent 60%);
}

.dash-settings__section-icon--vip {
    color: #d4a017;
}


/* ============================================================
   F2 — My Toolkits widget (Apr 30 2026)
   Mirrors .dash-playbook visual pattern; forest accent (vs sienna)
   to differentiate "templates you bought" from "playbooks you bought".
   ============================================================ */
.dash-toolkits {
    background: var(--dash-paper, #fff);
    border: 1px solid var(--dash-cream-dark, #e7e2da);
    border-radius: 14px;
    padding: 20px 22px;
    margin-bottom: 16px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
}

.dash-toolkit__list {
    display: grid;
    gap: 8px;
}

.dash-toolkit__item {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 14px;
    padding: 12px 14px;
    background: var(--dash-cream, #fdfcfa);
    border: 1px solid var(--dash-cream-dark, #e7e2da);
    border-radius: 10px;
    text-decoration: none;
    color: inherit;
    transition: border-color 160ms ease, transform 160ms ease;
}

.dash-toolkit__item:hover {
    border-color: var(--accent-forest, #14532d);
    transform: translateY(-1px);
}

.dash-toolkit__icon {
    width: 32px;
    height: 32px;
    border-radius: 8px;
    background: rgba(20, 83, 45, 0.10);
    color: var(--accent-forest, #14532d);
    display: grid;
    place-items: center;
    flex-shrink: 0;
}

.dash-toolkit__text { min-width: 0; }

.dash-toolkit__title {
    font-size: 14px;
    font-weight: 600;
    color: var(--dash-ink, #1a1714);
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dash-toolkit__meta {
    font-size: 11px;
    color: var(--dash-ink-muted, #64748b);
    margin-top: 2px;
    letter-spacing: 0.02em;
}

.dash-toolkit__cta {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 13px;
    font-weight: 600;
    color: var(--accent-forest, #14532d);
    white-space: nowrap;
    flex-shrink: 0;
}

/* ============================================================
   Task 35: Empty-state Activation Flow  (2026-05-10)
   Prefix: act-
   ============================================================ */

.act-flow {
    display: flex;
    flex-direction: column;
    gap: 28px;
    padding: 0 0 8px;
}

/* ── Header ── */

.act-header {
    padding: 20px 24px;
    background: #FAF7F2;
    border: 1px solid #e2ded8;
    border-radius: 10px;
}

.act-header__title {
    font-size: 22px;
    font-weight: 700;
    color: #1F3D2A;
    margin: 0 0 4px;
    line-height: 1.25;
}

.act-header__sub {
    font-size: 14px;
    color: #4b5563;
    margin: 0;
}

.act-header__browse {
    color: #1F3D2A;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.act-header__browse:hover {
    color: #7A4524;
}

/* ── Sections ── */

.act-section {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.act-section__heading {
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #6b7280;
    margin: 0;
}

.act-section__empty {
    font-size: 14px;
    color: #6b7280;
    margin: 0;
}

.act-section__empty a {
    color: #1F3D2A;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 2px;
}

/* ── Card grid ── */

.act-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 12px;
}

/* ── Individual card ── */

.act-card {
    background: #fff;
    border: 1px solid #e5e7eb;
    border-radius: 10px;
    padding: 16px 18px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.act-card:hover {
    border-color: #1F3D2A;
    box-shadow: 0 2px 8px rgba(31, 61, 42, 0.08);
}

.act-card__title {
    font-size: 14px;
    font-weight: 700;
    color: #1F3D2A;
    margin: 0 0 2px;
    line-height: 1.35;
}

.act-card__org {
    font-size: 12px;
    color: #6b7280;
    margin: 0;
}

.act-card__amount {
    font-size: 13px;
    font-weight: 600;
    color: #374151;
    margin: 4px 0 0;
}

.act-card__ev {
    font-size: 11px;
    color: #7A4524;
    margin: 2px 0 0;
    font-weight: 500;
}

.act-card__pursue {
    margin-top: 12px;
    padding: 8px 14px;
    background: #1F3D2A;
    color: #FAF7F2;
    border: none;
    border-radius: 6px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    align-self: flex-start;
    transition: background 0.15s ease;
    line-height: 1;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
}

.act-card__pursue:hover {
    background: #2d5a3e;
}

/* ── Footer link ── */

.act-footer {
    margin: 0;
}

.act-footer__link {
    font-size: 13px;
    font-weight: 600;
    color: #1F3D2A;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.act-footer__link:hover {
    color: #7A4524;
}

/* ── Responsive ── */

@media (max-width: 640px) {
    .act-grid {
        grid-template-columns: 1fr;
    }

    .act-header {
        padding: 16px;
    }

    .act-header__title {
        font-size: 18px;
    }
}

@media (max-width: 600px) {
    .dash-toolkits { padding: 16px 18px; }
    .dash-toolkit__cta { font-size: 12px; }
}

/* P2 (2026-05-11): skip-to-content link for keyboard / screen-reader users. */
.dash-skip-link {
    position: absolute;
    left: -9999px;
    top: -9999px;
    z-index: 10000;
    background: #1F3D2A;
    color: #FAF7F2;
    padding: 8px 12px;
    border-radius: 0 0 4px 0;
    font-size: 13px;
    font-weight: 500;
    text-decoration: none;
}
.dash-skip-link:focus {
    left: 0;
    top: 0;
}

/* ============================================================
   DAY-2 OFFER BANNER (.d2o) — 2026-08-06
   Spec: docs/superpowers/specs/2026-08-06-day2-offer-slot-spec.md
   (D13 dashboard-only · D14 static in-flow · D15 dismiss).
   Rendered by renderDay2Offer() into #dashDay2Offer, immediately
   ABOVE the free-user hero (.dfh) — which suppresses itself while
   this is visible, so the two never stack into a paywall.

   ⚠ The [hidden] attribute is silently overridden by ANY rule that
   sets `display`, so the guard below is LOAD-BEARING: without it a
   "hidden" banner is an invisible click-blocker on the first screen.

   ⚠ Static, in-flow, no position:sticky (silently dead on this page
   — body{overflow-x:hidden} traps it), no position:fixed, no
   z-index above the dismiss button's local stacking. It can never
   cover or displace anything.

   Look: the invitation. House palette, but deliberately NOT the
   free hero's terracotta CTA and NOT the Radar's dark-green card —
   a warm parchment field with a deep-green seal edge, so a member
   reads "something addressed to me" before they read a word.
   ============================================================ */
/* Card geometry matches .dash-today exactly — radius-lg, --dash-cream-dark hairline,
   --dash-shadow-sm. It was radius 12 with a warm gold border and no shadow, which sat
   off-system between two cards that both use the house card. The ONE deliberate
   deviation is the parchment gradient + the green seal edge: that is the invitation's
   identity and the reason a member reads it as addressed to them. */
.d2o {
    position: relative;
    background: linear-gradient(135deg, #FFFCF4 0%, #F7F2E4 100%);
    border: 1px solid var(--dash-cream-dark, #f2ebe0);
    border-left: 4px solid var(--dash-forest, #2d6a4f);
    border-radius: var(--dash-radius-lg, 16px);
    box-shadow: var(--dash-shadow-sm, 0 1px 3px rgba(26, 23, 20, 0.04));
    padding: 20px 24px 22px;
    margin: 0 0 16px;
}
.d2o[hidden] { display: none !important; }

/* 44px hit target (the visual glyph is 18px, the button is not).
   .d2o__body reserves the same width so no text can run under it. */
.d2o__dismiss {
    position: absolute;
    top: 4px;
    right: 4px;
    width: 44px;
    height: 44px;
    background: transparent;
    border: none;
    padding: 0;
    cursor: pointer;
    color: var(--dash-ink-muted, #706660);
    border-radius: 8px;
    line-height: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.d2o__dismiss:hover { background: rgba(0, 0, 0, 0.06); color: var(--dash-ink, #1a1714); }
.d2o__dismiss:focus-visible { outline: 2px solid #2D6A4F; outline-offset: 2px; }

.d2o__body {
    min-width: 0;
    padding-right: 44px;   /* clearance for the dismiss button */
}
.d2o__copy { min-width: 0; max-width: 72ch; }

.d2o__eyebrow {
    display: inline-flex;
    align-items: center;
    background: #EAF3ED;
    border: 1px solid #C7E9D4;
    border-radius: 999px;
    padding: 3px 10px;
    font-family: var(--dash-font-data, monospace);
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: #14532D;          /* ≈9:1 on #EAF3ED */
    margin-bottom: 10px;
}

.d2o__headline {
    font-family: var(--dash-font-display, 'Fraunces', serif);
    font-size: 22px;
    font-weight: 500;
    color: #14532D;
    margin: 0 0 8px;
    letter-spacing: -0.01em;
    line-height: 1.25;
    /* Real programme titles run to 102 chars and the renderer allows 90 — the
       headline WRAPS rather than truncating (a half-name is a wrong name).
       `anywhere` keeps an unbreakable token (a long URL-ish code in a title)
       from pushing the card past the viewport. */
    overflow-wrap: anywhere;
}
/* The programme name carries a weight change so OUR sentence break (a colon) stays
   visible against the em dashes that live INSIDE catalogue titles. */
.d2o__prog { font-weight: 700; }
/* ── Annual offer (2026-10-06 rev 2) ─────────────────────────────────────────
   ANCHOR OR PERCENT: the headline is "40% off…" (Fraunces, as before); $179 only
   ever appears in .d2o__price, beside its struck $299 — sans, body size, where a
   strikethrough reads as a price anchor and not a typo. Terms sit under it, then
   the deadline line (absolute + relative, ET). FINAL DAY (.d2o--urgent): the seal
   edge, the eyebrow and the deadline turn sienna #C4532B; the CTA stays the house
   green so the action is still the same action. */
.d2o--annual .d2o__headline { font-weight: 600; }
.d2o--annual .d2o__sub { margin-bottom: 10px; }
.d2o__price { display: block; font-size: 16px; color: var(--dash-ink, #1a1714); margin-bottom: 2px; }
.d2o__price strong { font-weight: 700; }
.d2o__nw { white-space: nowrap; }   /* a fact never splits across lines */
.d2o__price s { color: #6B6459; text-decoration-thickness: 1.5px; }
/* QA r1 #11: the price is ALWAYS two lines — "$179 $299 for your first year" then
   "about $14.92/mo" — so no separator exists to orphan. */
.d2o__price-main, .d2o__price-pm { display: block; }
.d2o__price-main { white-space: nowrap; }
.d2o__price-pm { font-size: 14px; color: #4F4A40; }
.d2o__terms { display: block; font-size: 13px; color: #5B5548; }
/* Screen-reader-only words ("instead of" before the struck $299). */
.d2o__sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
/* Separators only where the whole row fits on one line; below 768px every fact
   is its own line and the dots disappear (a wrapped row can never start or end
   with an orphaned "·"). */
.d2o__fact { white-space: nowrap; }
@media (max-width: 767px) {
    .d2o__sep { display: none; }
    .d2o__terms .d2o__fact { display: block; }
    .d2o__terms .d2o__fact::first-letter { text-transform: uppercase; }   /* "Monthly stays $39/mo" on its own line */
    .d2o__dl-abs { display: block; }
}
.d2o__deadline {
    font-size: 14px;
    color: #2F2A22;
    margin: 0 0 16px;
    line-height: 1.5;
}
.d2o__deadline strong { font-weight: 700; color: #14532D; }
.d2o--urgent { border-left-color: #C4532B; }
.d2o--urgent .d2o__eyebrow { background: #FBEDE7; border-color: #EBC0AE; color: #9A3A1B; }  /* ≈7:1 */
.d2o--urgent .d2o__deadline strong { color: #A8431F; }   /* sienna, darkened to ≥4.5:1 on the parchment */
.d2o__sub {
    font-size: 14px;
    color: #4F4A40;
    margin: 0 0 16px;
    line-height: 1.55;
}

/* ── "What's included": expands in place, never navigates away ─────────── */
/* Sibling of .d2o__actions, always AFTER it — see the markup note in
   renderDay2Offer(). Expanding grows the card downward only. */
.d2o__incl {
    margin: 16px 0 0;
    padding: 14px 16px;
    background: rgba(255, 255, 255, 0.62);
    border: 1px solid var(--dash-cream-dark, #f2ebe0);
    border-radius: var(--dash-radius, 10px);
}
/* ⚠ Same guard as .d2o[hidden] — the attribute alone is silently overridden by any
   rule that sets `display`, and a "collapsed" panel that is still visible makes the
   toggle's aria-expanded a lie. */
.d2o__incl[hidden] { display: none !important; }
.d2o__incl-list { list-style: none; margin: 0; padding: 0; }
.d2o__incl-i {
    position: relative;
    padding-left: 22px;
    margin: 0 0 9px;
    font-family: var(--dash-font-body, sans-serif);
    font-size: 13.5px;
    line-height: 1.5;
    color: #4F4A40;
}
.d2o__incl-i:last-child { margin-bottom: 0; }
.d2o__incl-i::before {
    content: '';
    position: absolute;
    left: 2px;
    top: 6px;
    width: 10px;
    height: 6px;
    border-left: 2px solid var(--dash-forest, #2d6a4f);
    border-bottom: 2px solid var(--dash-forest, #2d6a4f);
    transform: rotate(-45deg);
}
.d2o__incl-i strong { font-weight: 700; color: var(--dash-ink, #1a1714); }
.d2o__plans {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    font-family: var(--dash-font-body, sans-serif);
    font-size: 0.78rem;
    font-weight: 700;
    border-bottom: 1px solid transparent;
}
.d2o__plans,
.d2o__plans:hover,
.d2o__plans:focus,
.d2o__plans:visited,
.d2o__plans:active { color: var(--dash-forest, #2d6a4f); text-decoration: none; }
.d2o__plans:hover { border-bottom-color: currentColor; }
.d2o__plans:focus-visible { outline: 2px solid var(--dash-forest, #2d6a4f); outline-offset: 2px; }

.d2o__actions {
    display: flex;
    align-items: center;
    gap: 18px;
    flex-wrap: wrap;
}
/* ⚠ font-family is EXPLICIT on both controls. A <button> and an <a> do not inherit
   the page font the same way: the button was computing to -apple-system while every
   neighbouring dashboard control (.dash-today__cta, .dash-btn) renders in Plus
   Jakarta Sans, so the one element we most want to look native looked pasted in.
   Scale follows .dash-today__cta (--dash-font-body / 700). */
.d2o__cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 11px 24px;
    min-height: 44px;
    background: var(--dash-forest, #2d6a4f);
    color: #FFFFFF;
    border: 1px solid var(--dash-forest, #2d6a4f);
    border-radius: var(--dash-radius-sm, 6px);
    font-family: var(--dash-font-body, sans-serif);
    font-size: 0.82rem;
    font-weight: 700;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.15s ease, transform 0.1s ease, box-shadow 0.15s ease;
}
/* Sitewide `a:hover { color: var(--sienna) }` will otherwise repaint the label
   on hover — repeat the colour across every link state (documented gotcha). */
.d2o__cta,
.d2o__cta:hover,
.d2o__cta:focus,
.d2o__cta:visited,
.d2o__cta:active { color: #FFFFFF; text-decoration: none; }
.d2o__cta:hover { background: #245741; transform: translateY(-1px); box-shadow: 0 4px 14px rgba(45, 106, 79, 0.28); }
.d2o__cta:focus-visible { outline: 2px solid #14532D; outline-offset: 2px; }

.d2o__more {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 44px;
    padding: 0;
    background: transparent;
    border: none;                       /* it is a <button> now: an in-place toggle */
    border-bottom: 1px solid transparent;
    font-family: var(--dash-font-body, sans-serif);
    font-size: 0.78rem;
    font-weight: 700;
    cursor: pointer;
}
.d2o__more,
.d2o__more:hover,
.d2o__more:focus,
.d2o__more:visited,
.d2o__more:active { color: var(--dash-forest, #2d6a4f); text-decoration: none; }
.d2o__more:hover { border-bottom-color: currentColor; }
.d2o__more:focus-visible { outline: 2px solid var(--dash-forest, #2d6a4f); outline-offset: 2px; }
/* A caret that states the toggle's direction — the label alone gives no affordance
   that anything expands, and aria-expanded is invisible to sighted members. */
.d2o__more::after {
    content: '';
    width: 7px; height: 7px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: translateY(-2px) rotate(45deg);
}
.d2o__more.is-open::after { transform: translateY(2px) rotate(-135deg); }

/* ≥1024px: two columns — the invitation on the left, the single action on the
   right. Deliberately NOT 900: between 900 and ~1023 the left rail is still on
   screen, so splitting off a 180px action column squeezed the copy to ~344px and
   the card grew TALLER than the single-column layout it replaced (269px vs 199px,
   measured). Two columns only once there is room for two columns.
   ≥1024px: two columns — the invitation on the left, the single action on the
   right, vertically centred. Without this the card runs the full shell width with
   the copy hugging the left edge and ~40% dead space beside it, which reads as an
   unfinished module rather than an invitation.
   ⚠ FLEX, not grid. The first attempt used a grid with the actions spanning
   `grid-row: 1 / -1`; Chrome dumped the whole 98px spanning item into row ONE, so
   the eyebrow floated 37px below the card's top padding and the card measured
   200px instead of 140. The wrapper (.d2o__copy) makes it a two-item flex row
   with nothing to span. */
@media (min-width: 1024px) {
    .d2o__body {
        display: flex;
        flex-wrap: wrap;                  /* lets .d2o__incl take its own row */
        /* ⚠ flex-start, NOT center. With centre alignment, expanding "What's included"
           grows the copy column and pushes the CTA down by half the growth — the
           control the member is aiming at moves because they pressed a different one.
           Top-aligned, the action block cannot move at all. Collapsed, the two columns
           are within a few px of each other anyway (the action block is the taller). */
        align-items: flex-start;
        justify-content: space-between;   /* action pinned right, not floating mid-card */
        gap: 32px;
    }
    .d2o__copy     { flex: 1 1 auto; order: 1; }
    .d2o__sub      { margin-bottom: 0; }
    .d2o__deadline { margin-bottom: 0; }
    .d2o__actions  { flex: 0 0 auto; order: 2; flex-direction: column; align-items: stretch; gap: 10px; min-width: 180px; }
    .d2o__more     { justify-content: center; }
    /* The panel takes its own full-width row UNDER both columns, so neither the copy
       nor the action block moves when it opens. */
    .d2o__incl     { flex: 1 0 100%; order: 3; margin-top: 18px; max-width: 80ch; }
}

/* <600px: stack. Deliberately NOT 768 — a full-bleed ~700px primary button on a
   tablet reads as an ad banner, and the inline row fits comfortably down to 600. */
@media (max-width: 599px) {
    .d2o { padding: 16px 16px 18px; }
    .d2o__headline { font-size: 19px; }
    .d2o__sub { font-size: 13.5px; }
    .d2o__price { font-size: 15px; }
    .d2o__deadline { font-size: 13.5px; }
    .d2o__incl { padding: 12px 13px; }
    .d2o__incl-i { font-size: 13px; }
    /* QA r1 #16: the action column takes the card's full inner width (the 44px
       dismiss column only matters on the first row, where the X sits), and
       "What's included" aligns left with everything else on the card. */
    .d2o__actions { gap: 10px; align-items: stretch; flex-direction: column; margin-right: -44px; }
    .d2o__cta { width: 100%; }
    .d2o__more { width: auto; align-self: flex-start; justify-content: flex-start; }
    .d2o__incl { margin-right: -44px; }
}
/* 320-360px: the final-day pill ("ONE-TIME OFFER · ENDS TONIGHT") must stay one
   line beside the X — tighter tracking + a step down in size, never a wrap. */
@media (max-width: 360px) {
    .d2o__eyebrow { font-size: 9.5px; letter-spacing: 0.04em; padding: 3px 8px; white-space: nowrap; }
}

/* Nothing here animates by design; the CTA's hover lift is the only motion. */
@media (prefers-reduced-motion: reduce) {
    .d2o__cta { transition: none; }
    .d2o__cta:hover { transform: none; }
}

/* ============================================================
   DAY-2 OFFER — "you already have Premium" notice (.d2on)
   2026-08-06, spec §9 A1 (second redirect destination).
   Rendered by renderDay2OfferPremium() into #dashD2oPremium.

   ⚠ Deliberately NOT the .d2o invitation card. This is not an
   offer and must not look like one: no gradient field, no seal
   edge, no button. A subscriber pressed an invitation and is
   being told, in one line, that they are already past it — the
   right register is a receipt, not a pitch. It sits ABOVE the
   invitation slot and, when it is up, that slot renders nothing.

   ⚠ Same [hidden] guard as .d2o: the attribute is silently
   overridden by ANY rule that sets `display`, and a "hidden"
   notice is an invisible click-blocker on the first screen.  */
.d2on {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: 10px;
    background: #FFFFFF;          /* no --dash-white token exists; the card surfaces use the literal */
    border: 1px solid var(--dash-cream-dark, #f2ebe0);
    border-left: 3px solid var(--dash-forest, #2d6a4f);
    border-radius: var(--dash-radius, 10px);
    padding: 12px 14px;
    margin: 0 0 16px;
}
.d2on[hidden] { display: none !important; }

.d2on__body {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    min-width: 0;                 /* the text must be allowed to wrap, not push */
    padding-right: 8px;           /* the 40px dismiss button supplies the rest */
    flex: 1 1 auto;
}
.d2on__icon { flex: 0 0 auto; color: var(--dash-forest, #2d6a4f); margin-top: 1px; }
.d2on__text {
    margin: 0;
    font-size: 14px;
    line-height: 1.5;
    color: #4F4A40;
    min-width: 0;
    overflow-wrap: anywhere;
}

/* The one way out of an otherwise dead-end acknowledgment (round 3, P2). Inline at the
   END of the sentence and deliberately SUBORDINATE — this is a receipt, not a pitch, so
   the link is the same 14px as the copy it closes, in the house forest, with no button
   geometry at all. A real <a href>, so it is keyboard-focusable for free.
   ⚠ The colour is repeated across :hover/:focus/:visited/:active because the sitewide
   `a:hover { color: var(--sienna) }` otherwise wins the cascade and the link turns
   terracotta on hover — the one colour on this page that means "primary action". */
.d2on__link {
    white-space: nowrap;          /* the arrow never orphans onto its own line */
    font-weight: 600;
    border-bottom: 1px solid rgba(45, 106, 79, 0.35);
}
.d2on__link,
.d2on__link:hover,
.d2on__link:focus,
.d2on__link:visited,
.d2on__link:active { color: var(--dash-forest, #2d6a4f); text-decoration: none; }
.d2on__link:hover { border-bottom-color: currentColor; }
.d2on__link:focus-visible { outline: 2px solid var(--dash-forest, #2d6a4f); outline-offset: 2px; }

/* 40px hit target on a 16px glyph — in-flow (not absolute) so it can never sit
   on top of the text at a narrow width; the flex row keeps them side by side. */
.d2on__dismiss {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    margin: -8px -6px -8px 0;     /* optical: keeps the visible glyph aligned to the first line */
    background: transparent;
    border: none;
    padding: 0;
    cursor: pointer;
    color: var(--dash-ink-muted, #706660);
    border-radius: 8px;
    line-height: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.d2on__dismiss:hover { background: rgba(0, 0, 0, 0.06); color: var(--dash-ink, #1a1714); }
.d2on__dismiss:focus-visible { outline: 2px solid var(--dash-forest, #2d6a4f); outline-offset: 2px; }

@media (max-width: 599px) {
    .d2on { padding: 11px 12px; gap: 8px; }
    .d2on__text { font-size: 13.5px; }
}

/* ============================================================
   FREE-USER HERO (.dfh) — 2026-06-18
   Animated workspace demo + outcome-led upgrade nudge + free
   next-action. Renders for non-premium users (renderFreeUpgradeHero).
   ============================================================ */
.dfh {
    position: relative;
    background: linear-gradient(135deg, #FFFDFA 0%, #F0FDF4 100%);
    border: 1px solid #C7E9D4;
    border-radius: 12px;
    padding: 22px 26px 24px;
    margin: 0 0 16px;
}
.dfh[hidden] { display: none; }

.dfh__dismiss {
    position: absolute;
    top: 10px;
    right: 10px;
    background: transparent;
    border: none;
    padding: 6px;
    cursor: pointer;
    color: var(--dash-ink-muted, #706660);
    border-radius: 4px;
    line-height: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    z-index: 2;
}
.dfh__dismiss:hover { background: rgba(0, 0, 0, 0.06); color: var(--dash-ink, #1a1714); }
.dfh__dismiss:focus-visible { outline: 2px solid #2D6A4F; outline-offset: 2px; }

.dfh__grid {
    display: grid;
    grid-template-columns: 300px 1fr;
    gap: 26px;
    align-items: center;
}
.dfh__demo-wrap { display: flex; justify-content: center; }

.dfh__copy { min-width: 0; padding-right: 24px; }
.dfh__eyebrow {
    display: inline-block;
    font-family: var(--dash-font-data, monospace);
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: #C4532B;
    margin-bottom: 8px;
}
.dfh__title {
    font-family: var(--dash-font-display, 'Fraunces', serif);
    font-size: 22px;
    font-weight: 500;
    color: var(--dash-ink, #1a1714);
    margin: 0 0 8px;
    letter-spacing: -0.01em;
    line-height: 1.2;
}
.dfh__body {
    font-size: 14px;
    color: #4F4A40;
    margin: 0 0 16px;
    line-height: 1.55;
    max-width: 52ch;
}
.dfh__body em { font-style: normal; font-weight: 600; color: #14532D; }

.dfh__actions { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.dfh__cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 11px 22px;
    min-height: 44px;
    background: #C4532B;
    color: #FFFFFF;
    border: none;
    border-radius: 8px;
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.15s ease, transform 0.1s ease, box-shadow 0.15s ease;
}
.dfh__cta:hover { background: #A8431F; transform: translateY(-1px); box-shadow: 0 4px 14px rgba(196, 83, 43, 0.28); }
.dfh__cta:focus-visible { outline: 2px solid #C4532B; outline-offset: 2px; }
.dfh__next {
    font-size: 13px;
    font-weight: 600;
    color: #2D6A4F;
    text-decoration: none;
    border-bottom: 1px solid transparent;
}
.dfh__next:hover { border-bottom-color: currentColor; }
.dfh__reassure { font-size: 12px; color: var(--dash-ink-muted, #706660); margin: 12px 0 0; }

/* ── The animated mini-workspace demo ─────────────────────── */
.dfh-demo {
    width: 100%;
    max-width: 300px;
    background: #fff;
    border: 1px solid #E5E0D8;
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 6px 24px rgba(26, 23, 20, 0.08);
}
.dfh-demo__bar {
    display: flex;
    align-items: center;
    gap: 5px;
    padding: 8px 12px;
    background: #F4F1EB;
    border-bottom: 1px solid #E8E3DA;
}
.dfh-demo__dot { width: 8px; height: 8px; border-radius: 50%; background: #D5CEC2; }
.dfh-demo__dot:nth-child(1) { background: #E0A89A; }
.dfh-demo__dot:nth-child(2) { background: #E6D2A0; }
.dfh-demo__dot:nth-child(3) { background: #A9CBB4; }
.dfh-demo__bar-label { margin-left: auto; font-size: 10.5px; color: #6b6258; font-family: var(--dash-font-data, monospace); } /* 6b6258 ≈ 5.2:1 on the #f4f1eb bar (WCAG AA) */

.dfh-demo__stage {
    position: relative;
    padding: 16px 16px 18px;
    min-height: 196px;
    animation: dfhStage 14s ease-in-out infinite;
}
.dfh-demo__doc-title {
    font-family: var(--dash-font-display, 'Fraunces', serif);
    font-size: 13px;
    color: #2D6A4F;
    margin-bottom: 12px;
    font-weight: 600;
}
.dfh-demo__line { height: 7px; background: #EEE9E1; border-radius: 4px; margin-bottom: 8px; overflow: hidden; }
.dfh-demo__line.l1 { width: 92%; }
.dfh-demo__line.l2 { width: 78%; }
.dfh-demo__line.l3 { width: 64%; }
.dfh-demo__line i { display: block; height: 100%; width: 0; border-radius: 4px; background: linear-gradient(90deg, #2D6A4F, #52B788); }
.dfh-demo__line.l1 i { animation: dfhType1 14s linear infinite; }
.dfh-demo__line.l2 i { animation: dfhType2 14s linear infinite; }
.dfh-demo__line.l3 i { animation: dfhType3 14s linear infinite; }
.dfh-demo__caret {
    position: absolute;
    left: 16px; top: 33px;
    width: 2px; height: 12px;
    background: #2D6A4F;
    animation: dfhCaret 14s steps(1) infinite;
}

.dfh-demo__check { list-style: none; margin: 14px 0 0; padding: 0; }
.dfh-demo__check li {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    color: #4F4A40;
    margin-bottom: 8px;
    opacity: 0;
}
.dfh-demo__check li.c1 { animation: dfhCheck1 14s ease-out infinite; }
.dfh-demo__check li.c2 { animation: dfhCheck2 14s ease-out infinite; }
.dfh-demo__check li.c3 { animation: dfhCheck3 14s ease-out infinite; }
.dfh-demo__box { position: relative; flex: 0 0 auto; width: 14px; height: 14px; border-radius: 3px; background: #2D6A4F; }
.dfh-demo__box::after {
    content: '';
    position: absolute;
    left: 4px; top: 1px;
    width: 4px; height: 8px;
    border: solid #fff;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

.dfh-demo__stamp {
    position: absolute;
    top: 12px; right: 12px;
    background: #2D6A4F;
    color: #fff;
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 4px 9px;
    border-radius: 5px;
    transform: scale(0.8) rotate(-3deg);
    opacity: 0;
    animation: dfhStamp 14s ease-out infinite;
}
.dfh-demo__funded {
    display: inline-block;
    margin-top: 14px;
    background: #15803D;
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    padding: 6px 11px;
    border-radius: 6px;
    opacity: 0;
    box-shadow: 0 4px 14px rgba(21, 128, 61, 0.3);
    animation: dfhFunded 14s ease-out infinite;
}

@keyframes dfhStage { 0% { opacity: 0; } 3% { opacity: 1; } 96% { opacity: 1; } 100% { opacity: 0; } }
@keyframes dfhType1 { 0%, 3% { width: 0; } 15%, 96% { width: 100%; } 100% { width: 0; } }
@keyframes dfhType2 { 0%, 15% { width: 0; } 27%, 96% { width: 100%; } 100% { width: 0; } }
@keyframes dfhType3 { 0%, 27% { width: 0; } 39%, 96% { width: 100%; } 100% { width: 0; } }
@keyframes dfhCaret { 0%, 3% { opacity: 0; } 4% { opacity: 1; } 39% { opacity: 1; } 40%, 100% { opacity: 0; } }
@keyframes dfhCheck1 { 0%, 42% { opacity: 0; transform: translateX(-6px); } 46%, 96% { opacity: 1; transform: none; } 100% { opacity: 0; } }
@keyframes dfhCheck2 { 0%, 48% { opacity: 0; transform: translateX(-6px); } 52%, 96% { opacity: 1; transform: none; } 100% { opacity: 0; } }
@keyframes dfhCheck3 { 0%, 54% { opacity: 0; transform: translateX(-6px); } 58%, 96% { opacity: 1; transform: none; } 100% { opacity: 0; } }
@keyframes dfhStamp { 0%, 60% { opacity: 0; transform: scale(0.8) rotate(-3deg); } 66%, 96% { opacity: 1; transform: scale(1) rotate(-3deg); } 100% { opacity: 0; } }
@keyframes dfhFunded { 0%, 74% { opacity: 0; transform: translateY(8px); } 82%, 96% { opacity: 1; transform: translateY(0); } 100% { opacity: 0; } }

/* Mobile: stack demo above copy */
@media (max-width: 768px) {
    .dfh { padding: 18px 16px 20px; }
    .dfh__grid { grid-template-columns: 1fr; gap: 18px; }
    .dfh__copy { padding-right: 28px; }
    .dfh__title { font-size: 19px; }
    .dfh__actions { gap: 12px; }
    .dfh__cta { width: 100%; }
    .dfh__next { width: 100%; text-align: center; }
}

/* Reduced motion: show the finished state, no animation */
@media (prefers-reduced-motion: reduce) {
    .dfh-demo__stage,
    .dfh-demo__line i,
    .dfh-demo__check li,
    .dfh-demo__stamp,
    .dfh-demo__funded,
    .dfh-demo__caret { animation: none !important; }
    .dfh-demo__stage { opacity: 1; }
    .dfh-demo__line i { width: 100%; }
    .dfh-demo__check li { opacity: 1; transform: none; }
    .dfh-demo__stamp { opacity: 1; transform: scale(1) rotate(-3deg); }
    .dfh-demo__funded { opacity: 1; transform: none; }
    .dfh-demo__caret { opacity: 0; }
}

/* ═══ D2 (2026-07-03 holistic overhaul): Your Funding Radar ═══ */
.dash-radar { background: linear-gradient(135deg, #1f3d30, #1a5632); border-radius: 14px; padding: 20px 22px; color: #f2ede2; margin-bottom: 16px; }
.dash-radar__kick { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: #c9b98a; font-weight: 700; }
.dash-radar__title { font-size: 18px; font-weight: 700; margin: 4px 0 12px; color: #fff; font-family: Georgia, 'Times New Roman', serif; }
.dash-radar__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.dash-radar__lane { display: block; background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.13); border-radius: 10px; padding: 11px 13px; text-decoration: none; color: inherit; position: relative; transition: background .15s ease, transform .15s ease; }
a.dash-radar__lane:hover { background: rgba(255,255,255,.12); transform: translateY(-1px); }
.dash-radar__lane--step { border-color: #c9b98a; background: rgba(201,185,138,.14); }
.dash-radar__k { font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: #a9c2b2; font-weight: 700; margin-bottom: 4px; }
.dash-radar__t { font-size: 14px; font-weight: 600; color: #fff; line-height: 1.4; }
.dash-radar__m { font-size: 12.5px; color: #bfd0c5; margin-top: 3px; }
.dash-radar__lane.is-locked .dash-radar__blur { filter: blur(4px); pointer-events: none; user-select: none; }
.dash-radar__lock { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 700; color: #ffd98a; text-decoration: none; }
.dash-radar__foot { margin-top: 12px; font-size: 12.5px; color: #a9c2b2; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px; }
.dash-radar__foot a { color: #ffd98a; text-decoration: none; font-weight: 600; }
/* Round-2 (2026-07-16): feed rows — named matches from users/{uid}.radar.feed.
   Amounts in Jakarta 800, NEVER IBM Plex Mono (Atlas $-amount ban, sim-K F1). */
.dash-radar__rows { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.dash-radar__row { display: block; background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.13); border-radius: 10px; padding: 11px 14px; text-decoration: none; color: inherit; position: relative; transition: background .15s ease; }
a.dash-radar__row:hover { background: rgba(255,255,255,.12); }
.dash-radar__row-top { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.dash-radar__row-title { font-size: 14.5px; font-weight: 700; color: #fff; line-height: 1.35; min-width: 0; }
.dash-radar__row-amt { font-family: inherit; font-size: 13px; font-weight: 800; color: #ffd98a; white-space: nowrap; flex-shrink: 1; max-width: 45%; overflow: hidden; text-overflow: ellipsis; }
.dash-radar__row-meta { font-size: 12.5px; color: #bfd0c5; margin-top: 3px; display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: center; }
.dash-radar__chip { display: inline-block; font-size: 10.5px; font-weight: 700; letter-spacing: .04em; border: 1px solid rgba(255,255,255,.25); border-radius: 999px; padding: 1px 8px; color: #e8e2d2; }
.dash-radar__chip--mail { border-color: rgba(201,185,138,.6); color: #c9b98a; }
.dash-radar__intel { font-size: 12.5px; color: #a9c2b2; margin-top: 6px; position: relative; }
.dash-radar__intel.is-locked .dash-radar__intel-txt { filter: blur(4px); pointer-events: none; user-select: none; }
.dash-radar__intel-lock { position: absolute; inset: 0; display: flex; align-items: center; font-size: 11.5px; font-weight: 700; color: #ffd98a; cursor: pointer; }
.dash-radar__intel-lock:hover, .dash-radar__intel-lock:focus-visible { text-decoration: underline; }
.dash-radar__more[hidden] { display: none; }
.dash-radar__more-btn { display: block; width: 100%; margin-top: 2px; padding: 8px 10px; background: none; border: 1px dashed rgba(255,255,255,.3); border-radius: 8px; font: inherit; font-size: 12.5px; font-weight: 700; color: #cfe0d5; cursor: pointer; }
.dash-radar__more-btn:hover, .dash-radar__more-btn:focus-visible { border-color: rgba(255,255,255,.55); color: #fff; }
.dash-radar__strip { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.dash-radar__ogl { margin-top: 8px; font-size: 10.5px; color: #7fa18d; line-height: 1.5; }
@media (max-width: 720px) { .dash-radar__strip { grid-template-columns: 1fr; } .dash-radar__row-top { flex-wrap: wrap; } .dash-radar__row-amt { max-width: 100%; } }

@media (max-width: 720px) { .dash-radar { padding: 16px; } .dash-radar__grid { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) { .dash-radar__lane { transition: none; } }

/* D1: folded empty pipeline stages */
.dash-pipeline-stage-fold { font-size: 12.5px; color: #8a958e; padding: 6px 2px 2px; margin: 0; }

/* D3: unified grants tabs */
.dash-grants-tabs { display: inline-flex; gap: 2px; background: #efece4; border-radius: 999px; padding: 3px; font-size: 12.5px; font-weight: 600; margin-left: 10px; vertical-align: 3px; }
.dash-grants-tabs button { border: 0; background: none; padding: 5px 14px; border-radius: 999px; color: #5b6b63; cursor: pointer; font: inherit; }
.dash-grants-tabs button.is-on { background: #fff; color: #1a2e26; box-shadow: 0 1px 3px rgba(0,0,0,.08); }
.dash-grid--single { grid-template-columns: 1fr; }

/* QA round 1 (2026-07-03) */
.dash-grants-tabs button:focus-visible { outline: 2px solid #1a5632; outline-offset: 2px; }
.dash-pill--speed { white-space: normal; max-width: 100%; overflow-wrap: anywhere; }

/* ── Contracts V1 (2026-07-17): "Contracts matching your profile" module ──────
   Mirrors the .dash-radar card DNA (forest gradient, inner rows) with the
   contracts .ctd- palette (forest / sienna / parchment) + urgency treatment
   consistent with the tender-desk page (u7 = sienna, u3 = solid sienna). */
.dash-contracts { background: linear-gradient(135deg, #1a3d2e, #0f2a1f); border-radius: 14px; padding: 20px 22px; color: #f2ede2; margin-bottom: 16px; }
.dash-contracts[hidden] { display: none; }
.dash-contracts__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; margin-bottom: 12px; }
.dash-contracts__kick { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: #c9b98a; font-weight: 700; font-family: 'IBM Plex Mono', ui-monospace, monospace; }
.dash-contracts__title-h { font-size: 18px; font-weight: 700; margin: 4px 0 0; color: #fff; font-family: 'Fraunces', Georgia, 'Times New Roman', serif; }
.dash-contracts__tune { flex: 0 0 auto; font-size: 12.5px; font-weight: 600; color: #e8a87c; text-decoration: none; white-space: nowrap; padding: 6px 12px; border: 1px solid rgba(232,168,124,.4); border-radius: 999px; transition: background .15s ease, border-color .15s ease; }
.dash-contracts__tune:hover, .dash-contracts__tune:focus-visible { background: rgba(232,168,124,.14); border-color: rgba(232,168,124,.75); color: #f6d3ba; }
.dash-contracts__rows { display: flex; flex-direction: column; gap: 9px; }
.dash-contracts__row { display: block; background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.13); border-left: 3px solid rgba(255,255,255,.13); border-radius: 10px; padding: 12px 14px; text-decoration: none; color: inherit; transition: background .15s ease, transform .15s ease; }
.dash-contracts__row:hover, .dash-contracts__row:focus-visible { background: rgba(255,255,255,.12); transform: translateX(2px); }
.dash-contracts__row.u7 { border-left-color: #e8a87c; }
.dash-contracts__row.u3 { border-left-color: #d67a4f; }
.dash-contracts__row-top { display: flex; align-items: center; flex-wrap: wrap; gap: 7px; margin-bottom: 6px; }
.dash-contracts__type { font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 10px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: #bfe0cd; background: rgba(255,255,255,.09); border: 1px solid rgba(255,255,255,.16); padding: 2px 7px; border-radius: 6px; }
.dash-contracts__setaside { font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 10px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: #f2dca8; background: rgba(179,128,31,.28); border: 1px solid rgba(232,213,168,.4); padding: 2px 7px; border-radius: 6px; }
.dash-contracts__due { margin-left: auto; font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 10.5px; letter-spacing: .03em; padding: 3px 9px; border-radius: 999px; background: rgba(255,255,255,.1); color: #d8e4dc; white-space: nowrap; }
.dash-contracts__row.u7 .dash-contracts__due { background: rgba(232,168,124,.22); color: #f6d3ba; }
.dash-contracts__row.u3 .dash-contracts__due { background: #c0603a; color: #fff; }
.dash-contracts__due--none { background: rgba(255,255,255,.06); color: #a9bcae; opacity: .85; }
.dash-contracts__title { font-family: 'Fraunces', Georgia, 'Times New Roman', serif; font-size: 15.5px; font-weight: 600; line-height: 1.3; color: #fff; overflow-wrap: anywhere; }
.dash-contracts__entity { font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 11px; letter-spacing: .04em; text-transform: uppercase; color: #a9bcae; margin-top: 4px; overflow-wrap: anywhere; }
.dash-contracts__why { font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 12px; color: #e8a87c; margin-top: 7px; line-height: 1.5; }
.dash-contracts__why::before { content: '\21B3  '; }
.dash-contracts__foot { margin-top: 12px; font-size: 13px; }
.dash-contracts__foot a { color: #c9b98a; text-decoration: none; font-weight: 600; }
.dash-contracts__foot a:hover, .dash-contracts__foot a:focus-visible { color: #fff; text-decoration: underline; }
@media (max-width: 720px) {
    .dash-contracts { padding: 16px; }
    .dash-contracts__head { flex-wrap: wrap; }
    .dash-contracts__due { margin-left: 0; }
}
@media (prefers-reduced-motion: reduce) { .dash-contracts__row { transition: none; } .dash-contracts__row:hover { transform: none; } }

/* ── Contracts V1.1 (2026-07-18) — saved-tender shortlist extension ──────────
   Additive classes only; same one-system styling as the matched rows above.
   Adds a "Your shortlist" group ABOVE the matched rows (saved tenders still in
   the feed, closing-soonest), a "+N more saved" link, a quiet "N closed since"
   line, and a "Saved" marker on any matched row the user has also saved. */
.dash-contracts__group { margin-bottom: 2px; }
.dash-contracts__group-label { font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; color: #c9b98a; font-weight: 700; margin: 0 0 9px; }
.dash-contracts__group-label--matched { margin-top: 16px; padding-top: 14px; border-top: 1px solid rgba(255,255,255,.1); }
.dash-contracts__saved { font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 10px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: #bfe0cd; background: rgba(120,190,150,.18); border: 1px solid rgba(191,224,205,.42); padding: 2px 7px; border-radius: 6px; }
.dash-contracts__more { margin-top: 9px; font-size: 12.5px; }
.dash-contracts__more a { color: #c9b98a; text-decoration: none; font-weight: 600; }
.dash-contracts__more a:hover, .dash-contracts__more a:focus-visible { color: #fff; text-decoration: underline; }
.dash-contracts__closed { margin-top: 10px; font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 11.5px; color: #a9bcae; opacity: .9; line-height: 1.5; }

/* ═══════════════════════════════════════════════════════════════════════════
   DASHBOARD RETHINK (2026-07-27) — #dashToday, unified grants filters, state chips.

   Token-only by rule. This page already carries ~13 distinct border-radius values,
   ~25 box-shadow definitions (3 of them systematised) and ~15 "accent" colours
   across four non-interoperating styling systems; the whole point of this change is
   to stop growing that. Every value below is a var(--dash-*).
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Today band ─────────────────────────────────────────────────────────── */
/* Free-member emails v2 (plan 3 review): the tap card for a link from those emails (nothing happens until the tap) */
.dash-email-action { background: var(--dash-paper); border: 1px solid var(--dash-cream-dark); border-left: 3px solid var(--dash-forest);
    border-radius: var(--dash-radius-lg); padding: 16px 20px 14px; margin-bottom: 18px; box-shadow: var(--dash-shadow-sm); scroll-margin-top: 80px; }
.dash-email-action[hidden] { display: none; }
.dash-email-action__k { margin: 0 0 2px; font-size: .72rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--dash-ink-muted); }
.dash-email-action__t { margin: 0 0 10px; font-family: var(--dash-font-display); font-size: 1.1rem; font-weight: 600; color: var(--dash-ink); overflow-wrap: anywhere; }
.dash-email-action__l { display: block; font-weight: 700; margin: 0 0 6px; color: var(--dash-ink); }
.dash-email-action__in { width: 100%; box-sizing: border-box; min-height: 64px; padding: 10px 12px; border: 1px solid var(--dash-cream-dark); border-radius: 8px; font: inherit; font-size: 16px; resize: vertical; }
.dash-email-action__h { margin: 8px 0 10px; font-size: .92rem; color: var(--dash-ink-muted); line-height: 1.5; }
.dash-email-action__acts { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.dash-email-action__go { min-height: 44px; padding: 10px 18px; border: 0; border-radius: 10px; background: var(--dash-forest); color: #fff; font: inherit; font-weight: 700; cursor: pointer; }
.dash-email-action__go[disabled] { opacity: .6; cursor: default; }
.dash-email-action__no { min-height: 44px; padding: 10px 12px; border: 0; background: transparent; color: var(--dash-ink-muted); font: inherit; cursor: pointer; text-decoration: underline; }
.dash-email-action__err { margin: 8px 0 0; color: #8A4209; font-size: .9rem; }
/* Free-member emails v2 (plan 3): the programs an email named (dashboard.html?show=<ids>#start-here) */
.dash-emailed {
    display: block; background: var(--dash-paper); border: 1px solid var(--dash-cream-dark);
    border-left: 3px solid var(--dash-forest, #1B4332); border-radius: var(--dash-radius-lg);
    padding: 18px 22px 12px; margin-bottom: 18px; box-shadow: var(--dash-shadow-sm); scroll-margin-top: 80px;
}
.dash-emailed[hidden] { display: none; }
.dash-emailed__t { margin: 0 0 10px; font-family: var(--dash-font-display); font-size: 1.1rem; font-weight: 600; color: var(--dash-ink); }
.dash-emailed__list { list-style: none; margin: 0; padding: 0; }
.dash-emailed__item { border-top: 1px solid var(--dash-cream-dark); padding: 12px 0; }
.dash-emailed__item:first-child { border-top: 0; padding-top: 0; }
.dash-emailed__title { margin: 0 0 6px; font-weight: 700; font-size: 1rem; overflow-wrap: anywhere; }
.dash-emailed__title a { color: var(--dash-ink); }
.dash-emailed__cond { margin: 0 0 6px; padding: 6px 10px; border-radius: 8px; background: #FCEFDF; color: #8A4209; font-size: 0.9rem; line-height: 1.45; }
.dash-emailed__ok, .dash-emailed__note { margin: 0 0 6px; font-size: 0.9rem; color: var(--dash-ink-muted); line-height: 1.5; }
.dash-emailed__acts { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: center; }
.dash-emailed__rules { display: inline-block; padding: 12px 0; font-weight: 600; color: var(--dash-forest); }
.dash-emailed__title a { text-decoration: underline; text-underline-offset: 3px; }
.dash-emailed__save { min-height: 44px; padding: 10px 14px; border-radius: 8px; border: 1px solid var(--dash-forest); background: #fff; color: var(--dash-forest); font: inherit; font-weight: 600; cursor: pointer; }
.dash-emailed__save[disabled] { cursor: default; opacity: .7; }
@media (max-width: 640px) { .dash-emailed { padding: 16px 16px 10px; } }
.dash-today {
    display: block;
    background: var(--dash-paper);
    border: 1px solid var(--dash-cream-dark);
    border-radius: var(--dash-radius-lg);
    padding: 20px 24px 16px;
    margin-bottom: 18px;
    box-shadow: var(--dash-shadow-sm);
}
.dash-today__head {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 12px; margin-bottom: 4px;
}
.dash-today__t {
    margin: 0; font-family: var(--dash-font-display);
    font-size: 1.2rem; font-weight: 600; line-height: 1.2; color: var(--dash-ink);
}
.dash-today__date {
    font-family: var(--dash-font-data); font-size: 0.72rem; font-weight: 500;
    letter-spacing: 0.08em; text-transform: uppercase; color: var(--dash-ink-muted);
}
.dash-today__sub {
    margin: 0 0 12px; font-family: var(--dash-font-body);
    font-size: 0.82rem; line-height: 1.45; color: var(--dash-ink-secondary);
}
.dash-today__lane {
    display: grid;
    /* The last track sizes to its CONTENT, not a hardcoded 28px. Pinning it meant the
       coarse-pointer rule that grows the dismiss button to the 44px touch minimum
       pushed the lane 16px past its own container at 768-920px — the track stayed 28
       wide while the button rendered 44. */
    grid-template-columns: 3px minmax(0, 1fr) max-content auto;
    align-items: center; gap: 14px;
    padding: 12px 0; border-top: 1px solid var(--dash-cream-dark);
}
.dash-today__bar { align-self: stretch; border-radius: 2px; background: var(--dash-cream-dark); }
.dash-today__lane--due  .dash-today__bar { background: var(--dash-rose); }
.dash-today__lane--work .dash-today__bar { background: var(--dash-forest); }
.dash-today__lane--new  .dash-today__bar { background: var(--dash-sienna); }
.dash-today__lane--plan .dash-today__bar { background: var(--dash-forest-light); }
.dash-today__body { min-width: 0; }
.dash-today__k {
    display: block; font-family: var(--dash-font-body); font-size: 0.62rem;
    font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase;
    color: var(--dash-ink-muted); margin-bottom: 4px;
}
.dash-today__lane--due .dash-today__k { color: var(--dash-rose); }
.dash-today__h {
    display: block; font-family: var(--dash-font-body); font-size: 0.95rem;
    font-weight: 600; line-height: 1.32; color: var(--dash-ink);
    /* Grant titles run to 91 characters in this catalogue. Clamp in CSS, never
       slice in JS — a slice cuts mid-word. */
    display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2;
    -webkit-box-orient: vertical; overflow: hidden;
}
.dash-today__lane--due .dash-today__h { font-weight: 700; }
.dash-today__s {
    display: block; font-family: var(--dash-font-body); font-size: 0.8rem;
    line-height: 1.4; color: var(--dash-ink-secondary); margin-top: 2px;
    display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2;
    -webkit-box-orient: vertical; overflow: hidden;
}
.dash-today__cta {
    font-family: var(--dash-font-body); font-size: 0.78rem; font-weight: 700;
    padding: 9px 15px; border-radius: var(--dash-radius-sm); cursor: pointer;
    white-space: nowrap; text-decoration: none;
    background: transparent; color: var(--dash-ink-secondary);
    border: 1px solid var(--dash-cream-dark);
    transition: background var(--dash-transition), color var(--dash-transition);
}
.dash-today__cta:hover { background: var(--dash-cream-dark); color: var(--dash-ink); }
/* Exactly ONE solid button on the band — the most urgent lane. */
.dash-today__cta.is-primary {
    background: var(--dash-forest); color: var(--dash-paper); border-color: var(--dash-forest);
}
.dash-today__cta.is-primary:hover { background: var(--dash-forest-deep); color: var(--dash-paper); }
.dash-today__cta:focus-visible,
.dash-today__x:focus-visible { outline: 2px solid var(--dash-forest); outline-offset: 2px; }
.dash-today__x {
    width: 28px; height: 28px; border: 0; border-radius: var(--dash-radius-sm);
    background: transparent; color: var(--dash-ink-faint);
    font-size: 17px; line-height: 1; cursor: pointer;
}
.dash-today__x:hover { background: var(--dash-cream-dark); color: var(--dash-ink); }
.dash-today__empty {
    font-family: var(--dash-font-body); font-size: 0.86rem; line-height: 1.5;
    color: var(--dash-ink-secondary); padding: 14px 0 6px;
    border-top: 1px solid var(--dash-cream-dark);
}
.dash-today__foot {
    display: flex; justify-content: space-between; align-items: center; gap: 12px;
    flex-wrap: wrap; border-top: 1px solid var(--dash-cream-dark);
    padding-top: 10px; margin-top: 4px;
}
.dash-today__honest {
    font-family: var(--dash-font-body); font-size: 0.73rem; line-height: 1.4;
    color: var(--dash-ink-faint);
}
.dash-today__tune {
    font-family: var(--dash-font-body); font-size: 0.76rem; font-weight: 600;
    color: var(--dash-forest-deep); text-decoration: none; white-space: nowrap;
}

/* ── Unified grants: filter chips + search row ──────────────────────────── */
.dash-gfilters {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    margin: 0 0 12px;
}
.dash-gfilters__chips { display: flex; gap: 6px; flex-wrap: wrap; flex: 1 1 auto; min-width: 0; }
.dash-gchip {
    font-family: var(--dash-font-body); font-size: 0.76rem; font-weight: 600;
    padding: 7px 12px; border-radius: 999px; cursor: pointer;
    border: 1px solid var(--dash-cream-dark); background: transparent;
    color: var(--dash-ink-secondary); white-space: nowrap;
    transition: background var(--dash-transition), color var(--dash-transition);
}
.dash-gchip:hover { background: var(--dash-cream-dark); }
.dash-gchip.is-on {
    background: var(--dash-forest); border-color: var(--dash-forest); color: var(--dash-paper);
}
/* ⚠ 2026-07-29 — the count rendered FLUSH against the label on phones ("All6",
   "Needs you3"). The space is present in the markup; the touch-target rules below
   set `display: inline-flex` on the chip to hit 44px, and a flex container strips
   whitespace between its items — so a rule about MINIMUM HEIGHT silently deleted a
   space in the text, on touch devices only. `gap` restores it without giving up the
   centring the flex display was added for. */
.dash-gchip { gap: 5px; }
.dash-gchip__n { font-family: var(--dash-font-data); font-weight: 500; opacity: 0.75; }
.dash-gchip.is-zero { color: var(--dash-ink-faint); }
.dash-gchip.is-zero.is-on { color: var(--dash-paper); }
.dash-gchip:focus-visible { outline: 2px solid var(--dash-forest); outline-offset: 2px; }
.dash-search--inline { flex: 0 1 260px; margin: 0; }

/* ── State chip (replaces the progress bar on every row) ────────────────── */
.dash-pipeline-row__state { display: flex; align-items: center; gap: 8px; min-width: 0; }
.dash-gstate {
    font-family: var(--dash-font-body); font-size: 0.66rem; font-weight: 700;
    letter-spacing: 0.06em; text-transform: uppercase;
    padding: 6px 10px; border-radius: 999px; white-space: nowrap;
    /* Fixed width so the chips form a plumb column down the list — a ragged
       middle column is what made the old row read as mush. */
    min-width: 88px; text-align: center;
}
.dash-gstate--saved     { background: var(--dash-cream-dark); color: var(--dash-ink-secondary); }
.dash-gstate--tracking  { background: var(--dash-cream-dark); color: var(--dash-ink-secondary); }
.dash-gstate--working   { background: var(--dash-forest-light); color: var(--dash-forest-deep); }
.dash-gstate--submitted { background: var(--dash-forest-deep); color: var(--dash-paper); }
.dash-gstate--won       { background: var(--dash-forest); color: var(--dash-paper); }
.dash-gstate--lost      { background: var(--dash-cream-dark); color: var(--dash-ink-faint); }
.dash-pipeline-row__state-detail {
    font-family: var(--dash-font-data); font-size: 0.72rem;
    color: var(--dash-ink-secondary); white-space: nowrap;
}
@media (max-width: 700px) {
    .dash-today { padding: 16px 16px 12px; }
    /* Two rows on a phone: [bar | text | x] then [bar | CTA]. The x must be PLACED
       explicitly at row 1 — leaving it to auto-placement dropped it onto a third row of
       its own, left-aligned under the button, with ~40px of dead space above it. */
    .dash-today__lane {
        grid-template-columns: 3px minmax(0, 1fr) auto;
        grid-template-rows: auto auto;
        row-gap: 10px;
        align-items: start;
    }
    .dash-today__bar { grid-row: 1 / 3; }
    .dash-today__body { grid-column: 2; grid-row: 1; }
    .dash-today__x { grid-column: 3; grid-row: 1; justify-self: end; }
    .dash-today__cta { grid-column: 2 / 4; grid-row: 2; justify-self: start; }
    .dash-pipeline-row__state-detail { display: none; }
    /* Touch targets. The QA sweep found 7 controls under the 44px minimum at every
       width — the dismiss x, the lane CTA and the five filter chips. Desktop pointers
       tolerate that; a thumb does not, and the dismiss control is the one thing on this
       band a member is most likely to reach for on a phone. */
    .dash-today__x { width: 44px; height: 44px; font-size: 20px; }
    .dash-today__cta { min-height: 44px; display: inline-flex; align-items: center; }
    .dash-gchip { min-height: 44px; display: inline-flex; align-items: center; }
    /* Four chips at the default 12px side padding come to ~2px more than a 390px phone
       can hold, so they wrapped to two rows for the sake of a hair. Trimming the
       horizontal padding only — the 44px touch height is untouched. */
    .dash-gchip { padding-left: 9px; padding-right: 9px; }
    /* ⚠ The .dash-gfilters / .dash-search--inline / .dash-icon-btn flex rules that
       lived here were REMOVED 2026-07-29: this region is now a GRID at this width
       (variant B, at the end of this file), and flex sizing on a grid child is dead
       code that reads like it is doing something. Layout for the strip lives in ONE
       place now — do not re-add sizing here. */
}

/* Touch targets on any COARSE pointer, not just narrow viewports. A 768-920px tablet
   is a thumb device with a desktop-width layout, so a width-only media query left its
   dismiss control and filter chips under the 44px minimum. Keyed to the input device,
   which is what the rule is actually about. */
@media (pointer: coarse) {
    .dash-today__x { width: 44px; height: 44px; font-size: 20px; }
    .dash-today__cta,
    .dash-gchip { min-height: 44px; display: inline-flex; align-items: center; }
}

/* Filtered/searched-to-empty state for the unified grants list (2026-07-27).
   Distinct from #dashPipelineEmpty, which means "you have no grants at all". */
.dash-pipeline-nomatch {
    background: var(--dash-paper);
    border: 1px solid var(--dash-cream-dark);
    border-radius: var(--dash-radius);
    padding: 24px 20px;
    text-align: center;
}
.dash-pipeline-nomatch__h {
    margin: 0 0 4px;
    font-family: var(--dash-font-display);
    font-size: 1rem; font-weight: 600; color: var(--dash-ink);
}
.dash-pipeline-nomatch__s {
    margin: 0 0 14px;
    font-family: var(--dash-font-body);
    font-size: 0.84rem; line-height: 1.45; color: var(--dash-ink-secondary);
}

/* Match-criteria set-up state (2026-07-28) — shown before the quiz, so the profile is
   reachable from the dashboard at the moment it is most needed rather than only after. */
.dash-quiz-profile__empty { padding: 4px 2px 8px; }
.dash-quiz-profile__empty p {
    margin: 0 0 12px;
    font-family: var(--dash-font-body);
    font-size: 0.86rem; line-height: 1.5; color: var(--dash-ink-secondary);
}

/* Carried-profile provenance (2026-07-28) — for a member whose profile came from the
   grant-page eligibility check rather than a quiz. Says so once, quietly, so five
   answers they gave elsewhere do not read as a form they never filled in. Sits between
   the header and the grid; never rendered for a quiz-sourced profile. */
.dash-quiz-profile__origin {
    margin: 0 0 12px;
    font-family: var(--dash-font-body);
    font-size: 0.8rem; line-height: 1.5; color: var(--dash-ink-secondary);
}

/* Quiz results section (2026-07-28) — the member's last precision-quiz outcome, kept on
   the dashboard so leaving the results page does not lose it. Token-only. */
.dash-quiz-results {
    background: var(--dash-paper);
    border: 1px solid var(--dash-cream-dark);
    border-radius: var(--dash-radius);
    padding: 14px 18px;
    margin-bottom: 18px;
}
.dash-qr__lead, .dash-qr__foot {
    font-family: var(--dash-font-body); font-size: 0.82rem; color: var(--dash-ink-secondary);
    margin: 6px 0 12px;
}
.dash-qr__foot { margin: 12px 0 2px; }
.dash-qr__list { list-style: none; margin: 0; padding: 0; }
.dash-qr__row {
    display: grid; grid-template-columns: max-content minmax(0, 1fr) max-content;
    gap: 12px; align-items: center;
    padding: 11px 0; border-top: 1px solid var(--dash-cream-dark);
}
.dash-qr__rank {
    font-family: var(--dash-font-data); font-size: 0.76rem; font-weight: 600;
    color: var(--dash-ink-faint);
}
.dash-qr__main { min-width: 0; }
.dash-qr__title {
    display: block; font-family: var(--dash-font-body); font-size: 0.92rem;
    font-weight: 600; color: var(--dash-ink); text-decoration: none; line-height: 1.3;
}
.dash-qr__title:hover { color: var(--dash-forest-deep); }
.dash-qr__org {
    display: block; font-family: var(--dash-font-body); font-size: 0.78rem;
    color: var(--dash-ink-secondary); margin-top: 2px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dash-qr__score {
    font-family: var(--dash-font-data); font-size: 0.95rem; font-weight: 700;
    text-align: right; white-space: nowrap; color: var(--dash-forest-deep);
}
.dash-qr__score em {
    display: block; font-family: var(--dash-font-body); font-style: normal;
    font-size: 0.66rem; font-weight: 600; letter-spacing: 0.05em;
    text-transform: uppercase; color: var(--dash-ink-muted); margin-top: 2px;
}
.dash-qr__score--poss { color: var(--dash-ink-secondary); }
.dash-today__empty-cta { margin-top: 12px; }
@media (max-width: 700px) {
    .dash-qr__row { grid-template-columns: max-content minmax(0, 1fr); row-gap: 6px; }
    .dash-qr__score { grid-column: 2; text-align: left; }
}

/* ═══════════════════════════════════════════════════════════════════════
   Grants toolbar consolidation — 2026-07-29
   Khalid's pick after seeing four variants measured in the real page:
   VARIANT C on desktop, VARIANT B on mobile.

   The problem was never the control layout. Measured on the live page, the
   distance from the "Your grants" heading to the first grant was 319px (35% of
   a 900px desktop screen) and 497px (59% of a phone) across 8 horizontal bands —
   and the space was going to the count line wrapping to two rows, the free-cap
   notice running to three, and ~90px gaps between every block. Two of the four
   variants rearranged the controls and measured WORSE.

   So this does three things at every width — one-line counts, a tightened cap
   notice, collapsed gaps — and then splits: desktop puts everything on one
   strip (C), mobile leads with search and drops the chips beneath it (B).
   ═══════════════════════════════════════════════════════════════════════ */

.dash-pipeline-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin: 0 0 10px;
}
.dash-pipeline-head__title { margin: 0 0 4px; }
.dash-pipeline-head__actions { align-items: center; gap: 8px; flex-wrap: nowrap; }

/* The count strip is a row of numbers. Anything that is not a number was moved
   out of it (see the watchNote note in dashboard.src.js). */
.dash-pipeline-meta__primary { font-size: 11px; line-height: 1.5; gap: 2px 10px; }
.dash-pipeline-meta__watch {
  margin-top: 4px;
  font-family: var(--dash-font-body);
  font-size: 12px;
  line-height: 1.45;
  color: var(--dash-ink-secondary, #6B6458);
}
.dash-pipeline-meta__cap { margin-top: 5px; font-size: 12px; line-height: 1.45; }

/* Sort, relocated out of the header actions into the filter strip. */
.dash-gsort { display: inline-flex; align-items: center; gap: 6px; font-size: 12px;
  color: var(--dash-ink-secondary, #6B6458); }
.dash-gsort select {
  font-family: var(--dash-font-body);
  font-size: 12px; padding: 6px 9px; border-radius: 8px;
  border: 1px solid var(--dash-cream-dark, #E8E1D4); background: #FFFDFA;
  color: var(--dash-ink, #1A1814); cursor: pointer;
}
.dash-gsort select:focus-visible { outline: 2px solid var(--dash-forest); outline-offset: 2px; }

/* ── Desktop: variant C — one strip ─────────────────────────────────── */
/* ⚠ 701/700, NOT 681/680. The file's existing mobile block is `max-width: 700px`.
   A 680px boundary here would leave 681-700px matching BOTH that block's flex rules
   and this grid — 20px of viewport where the two layouts fight. Breakpoints must
   agree with the ones already in the file, not with the number in a mockup. */
@media (min-width: 701px) {
  .dash-gfilters {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    margin: 0 0 12px;
    padding: 9px 12px;
    border: 1px solid var(--dash-cream-dark, #E8E1D4);
    border-radius: 10px;
    background: #FFFDFA;
  }
  .dash-gfilters__chips { flex: 0 0 auto; }
  .dash-search--inline { flex: 0 1 240px; margin: 0; }
  .dash-gsort { margin-left: auto; }
}

/* ── Mobile: variant B — search leads, chips beneath ────────────────── */
@media (max-width: 700px) {
  .dash-gfilters {
    display: grid;
    grid-template-columns: 1fr auto auto;
    grid-template-areas: "search sort export" "chips chips chips";
    gap: 10px 8px;
    align-items: center;
    margin: 0 0 12px;
  }
  .dash-search--inline {
    grid-area: search; flex: none; margin: 0;
    background: #FFFDFA;
    border: 1px solid var(--dash-cream-dark, #E8E1D4);
    border-radius: 10px;
    padding: 8px 12px;
    /* ⚠ min-width:0 is load-bearing on a grid child: without it the input's
       intrinsic width floors the 1fr track and pushes the row past the viewport. */
    min-width: 0;
  }
  /* ⚠ AND the same on the INPUT, which is what I missed on the first deploy of this
     (2026-07-29): min-width:0 on the wrapper stopped the ROW overflowing, so the
     harness's no-horizontal-scroll assertion passed — while the input kept its
     intrinsic size INSIDE the padded wrapper and spilled its placeholder across the
     "Sort" label sitting next to it. "Search your grants...Sort". A container that
     does not overflow the page can still be overflowed by its own child; assert the
     child against the parent, not the page. */
  .dash-search--inline input {
    min-width: 0;
    width: 100%;
    flex: 1 1 auto;
  }
  .dash-gsort { grid-area: sort; }
  .dash-gfilters #exportBtn { grid-area: export; }
  .dash-gfilters__chips {
    grid-area: chips;
    display: flex; gap: 5px; flex-wrap: wrap;
    padding-top: 8px;
    border-top: 1px solid rgba(26, 23, 20, 0.06);
  }
  /* The head is a column here; do NOT centre, or the primary action floats alone
     in the middle of its own row and reads as a mistake. */
  .dash-pipeline-head { align-items: stretch; }
  .dash-pipeline-head__actions { justify-content: flex-start; margin-top: 8px; width: auto; }
}

/* ═══ Our Picks for You (2026-08-13) ═══════════════════════════════════════
   Spec: docs/superpowers/specs/2026-08-13-our-picks-recommendations-design.md.
   The table itself rides gameplan.css (.gp-table / .gp-c / .gp-th — loaded on
   this page since 2026-08-13); everything below is the dashboard-side chrome. */
.dash-our-picks {
    background: var(--dash-paper);
    border: 1px solid var(--dash-cream-dark);
    border-radius: var(--dash-radius);
    padding: 14px 18px;
    margin-bottom: 18px;
    /* Native #dashOurPicks hash jumps (Second Look letters) must clear the fixed nav —
       mirrors _railJump's 96/132 offsets (2026-08-18). */
    scroll-margin-top: 96px;
}
@media (max-width: 1199px) {
    .dash-our-picks { scroll-margin-top: 132px; }
}
.dash-op__lead {
    font-family: var(--dash-font-body); font-size: 0.88rem; color: var(--dash-ink-secondary);
    margin: 8px 0 10px; line-height: 1.5;
}
.dash-op__facts {
    margin: 0 0 14px; line-height: 2;
}
.dash-op__factsLead {
    font-family: var(--dash-font-body); font-size: 0.78rem; font-weight: 600;
    color: var(--dash-ink-faint); text-transform: uppercase; letter-spacing: 0.04em;
    margin-right: 4px;
}
.dash-op__fact {
    display: inline-block; margin: 0 4px 0 0; padding: 2px 9px;
    font-family: var(--dash-font-body); font-size: 0.8rem; color: var(--dash-ink);
    background: var(--dash-cream, #f6f1e7); border: 1px solid var(--dash-cream-dark);
    border-radius: 999px; white-space: nowrap;
}
.dash-op__factsEdit {
    font-family: var(--dash-font-body); font-size: 0.8rem; color: var(--dash-forest, #1f5138);
    text-decoration: underline; white-space: nowrap;
}
/* horizontal-scroll container so a wide table can never force page scroll */
.dash-op__scroll { overflow-x: auto; contain: inline-size; }
.dash-op__table { min-width: 640px; }
.dash-op__t { font-weight: 600; color: var(--dash-ink); text-decoration: none; }
.dash-op__t:hover { text-decoration: underline; }
.dash-op__strong {
    display: inline-block; margin-left: 8px; padding: 1px 8px; border-radius: 999px;
    font-size: 0.68rem; font-weight: 700; letter-spacing: 0.03em;
    background: var(--gp-ok-bg, #e6f1ea); color: var(--gp-ok-ink, #2c5e3f);
}
/* Delta memory (retention follow-through 2026-08-28): what changed since the previous
   review. Rendered only when a non-empty delta exists — first reviews carry none. */
.dash-op__delta {
    margin: 2px 0 10px; padding: 6px 12px; border-radius: 8px; display: inline-block;
    font-size: 0.82rem; font-weight: 600;
    background: var(--gp-ok-bg, #e6f1ea); color: var(--gp-ok-ink, #2c5e3f);
}
.dash-op__newTag {
    display: inline-block; margin-left: 8px; padding: 1px 8px; border-radius: 999px;
    font-size: 0.68rem; font-weight: 700; letter-spacing: 0.03em;
    background: var(--gp-mid-bg, #f3ecdb); color: var(--gp-mid-ink, #7a5a1a);
}
.dash-op__odds {
    display: inline-block; padding: 3px 9px; border-radius: 7px;
    font-size: 0.76rem; font-weight: 600;
}
.dash-op__odds--ok  { background: var(--gp-ok-bg, #e6f1ea);  color: var(--gp-ok-ink, #2c5e3f); }
.dash-op__odds--mid { background: var(--gp-mid-bg, #f3ecdb); color: var(--gp-mid-ink, #7a5a1a); }
.dash-op__odds--low { background: var(--gp-low-bg, #f4ece9); color: var(--gp-low-ink, #8a5240); }
.dash-op__quick {
    display: inline-block; padding: 3px 9px; border-radius: 7px;
    font-size: 0.76rem; font-weight: 600;
    background: var(--gp-ok-bg, #e6f1ea); color: var(--gp-ok-ink, #2c5e3f);
}
.dash-op__why {
    display: inline-flex; align-items: center; gap: 5px;
    min-height: 30px; padding: 3px 10px;
    font: inherit; font-size: 0.8rem; color: var(--dash-ink);
    background: none; border: 1px solid var(--dash-cream-dark); border-radius: 8px;
    cursor: pointer;
}
.dash-op__why:hover { border-color: var(--gp-forest, #1f5138); }
.dash-op__whyN { font-weight: 700; color: var(--gp-ok-ink, #2c5e3f); white-space: nowrap; }
.dash-op__whyQ { color: var(--dash-ink-secondary); white-space: nowrap; }
.dash-op__row { cursor: pointer; }
/* ⚠ [hidden] is silently overridden by ANY display rule (documented gotcha) — the
   gp-table mobile block sets tr { display:block }, so the attribute needs teeth: */
.dash-op__detail[hidden] { display: none !important; }
.dash-op__detail > td {
    background: var(--dash-cream, #f6f1e7);
    border-top: 0; padding: 14px 18px 16px;
}
.dash-op__note {
    font-family: var(--dash-font-body); font-size: 0.86rem; color: var(--dash-ink);
    line-height: 1.55; margin: 0 0 10px;
}
.dash-op__g { margin: 0 0 10px; }
.dash-op__gLead {
    font-size: 0.74rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
    color: var(--dash-ink-faint); margin: 0 0 4px;
}
.dash-op__g ul { list-style: none; margin: 0; padding: 0; }
.dash-op__g li {
    font-family: var(--dash-font-body); font-size: 0.85rem; color: var(--dash-ink);
    line-height: 1.5; padding: 3px 0 3px 24px; position: relative;
}
.dash-op__m {
    position: absolute; left: 2px; top: 3px; font-weight: 700;
    color: var(--dash-ink-faint);
}
.dash-op__m--ok { color: var(--gp-ok-ink, #2c5e3f); }
.dash-op__ansRow { display: inline-flex; gap: 8px; margin-left: 10px; vertical-align: middle; }
.dash-op__ans {
    min-width: 52px; min-height: 32px; padding: 4px 14px;
    font: inherit; font-size: 0.8rem; font-weight: 600;
    color: var(--gp-forest, #1f5138); background: #fff;
    border: 1px solid var(--gp-forest, #1f5138); border-radius: 8px; cursor: pointer;
}
.dash-op__ans:hover:not(:disabled) { background: var(--gp-ok-bg, #e6f1ea); }
.dash-op__ans:disabled { opacity: 0.5; cursor: default; }
.dash-op__ansDone { display: inline-block; margin-left: 10px; font-size: 0.8rem; color: var(--gp-ok-ink, #2c5e3f); }
.dash-op__ansErr  { display: inline-block; margin-left: 10px; font-size: 0.8rem; color: var(--gp-low-ink, #8a5240); }
.dash-op__calib {
    font-family: var(--dash-font-body); font-size: 0.82rem; font-style: italic;
    color: var(--dash-ink-secondary); margin: 10px 0 12px;
}
.dash-op__view { display: inline-block; }
.dash-op__headsup {
    margin: 16px 0 4px; padding: 12px 16px;
    background: var(--gp-mid-bg, #f3ecdb); border-radius: 10px;
}
.dash-op__hLead {
    font-size: 0.78rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
    color: var(--gp-mid-ink, #7a5a1a); margin: 0 0 8px;
}
.dash-op__hRow { padding: 6px 0; border-top: 1px solid rgba(122, 90, 26, 0.15); }
.dash-op__hRow:first-of-type { border-top: 0; }
.dash-op__hTitle { font-size: 0.86rem; font-weight: 600; color: var(--dash-ink); margin: 0 0 2px; }
.dash-op__hNote  { font-size: 0.82rem; color: var(--dash-ink-secondary); margin: 0 0 2px; line-height: 1.45; }
.dash-op__hQuote { font-size: 0.78rem; font-style: italic; color: var(--dash-ink-faint); margin: 0; }
.dash-op__foot {
    font-family: var(--dash-font-body); font-size: 0.76rem; color: var(--dash-ink-faint);
    margin: 12px 0 2px;
}
/* Touch targets: the whole-row toggle carries the tap on phones; buttons stay ≥32px
   with generous row padding, and the two answer buttons clear 44px together. */
@media (max-width: 700px) {
    .dash-op__table { min-width: 0; }
    .dash-op__ans { min-height: 44px; min-width: 64px; }
    .dash-op__why { min-height: 38px; }
    .dash-op__fact { white-space: normal; }
}

/* The gp sticky header is tuned for the Game Plan PAGE (top:57px = that page's nav) and
   inside this section it floats over row 1 and eats its clicks (caught by E2E 2026-08-13).
   An 8-row table needs no sticky header — make it static here. */
.dash-op__table thead th.gp-th { position: static; box-shadow: none; }

/* round-1 QA fixes (2026-08-13): the earlier static-header override LOST the cascade to
   gameplan.css (equal specificity, later file wins — the documented load-order class);
   this three-class selector wins outright. Plus rank spacing + award basis sub-line. */
.dash-our-picks .dash-op__table thead th.gp-th { position: static; box-shadow: none; }
.dash-our-picks .gp-prog__rank { display: inline-block; min-width: 20px; margin-right: 8px; color: var(--dash-ink-faint); font-weight: 600; }
.dash-op__amt { display: block; font-weight: 700; color: var(--gp-forest, #1f5138); }
.dash-op__amtBasis { display: block; font-size: 0.72rem; color: var(--dash-ink-faint); }
@media (max-width: 700px) {
    /* the why button must wrap, not clip, inside the stacked mobile cell */
    .dash-op__why { white-space: normal; flex-wrap: wrap; max-width: 100%; text-align: left; }
    .dash-op__whyQ { white-space: normal; }
}

/* round-2 (Codex composition findings 3/4/11, verified): the expanded detail connects to its
   row via a shared accent; the "to confirm" group reads amber against the green evidence. */
.dash-op__row--open > td { background: var(--dash-cream, #f6f1e7); }
.dash-op__row--open > td:first-child { box-shadow: inset 3px 0 0 var(--gp-forest, #1f5138); }
.dash-op__detail > td:first-child { box-shadow: inset 3px 0 0 var(--gp-forest, #1f5138); }
.dash-op__g--confirm .dash-op__gLead { color: var(--gp-mid-ink, #7a5a1a); }
.dash-op__g--confirm .dash-op__m { color: var(--gp-mid-ink, #7a5a1a); }

/* ═══ Our Picks round 3 (2026-08-13, Khalid review) ═══════════════════════ */

/* The profile panel — the shown work, designed as a first-class object, every chip editable */
.dash-op__profile {
    margin: 0 0 16px; padding: 14px 16px;
    background: linear-gradient(180deg, #fbf8f1, #f6f1e7);
    border: 1px solid var(--dash-cream-dark); border-radius: 12px;
}
.dash-op__profileHead { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.dash-op__profileTitle {
    font-family: var(--dash-font-body); font-size: 0.86rem; font-weight: 700; color: var(--dash-ink);
}
.dash-op__profileCount { font-size: 0.76rem; color: var(--dash-ink-faint); }
.dash-op__profileChips { display: flex; flex-wrap: wrap; gap: 7px; }
.dash-op__fact {
    display: inline-flex; align-items: center; gap: 6px;
    margin: 0; padding: 5px 11px; min-height: 30px;
    font: inherit; font-size: 0.8rem; color: var(--dash-ink);
    background: #fff; border: 1px solid var(--dash-cream-dark); border-radius: 999px;
    cursor: pointer; transition: border-color .12s ease, box-shadow .12s ease;
}
.dash-op__fact:hover { border-color: var(--gp-forest, #1f5138); box-shadow: 0 1px 4px rgba(31,81,56,.12); }
.dash-op__factPen { font-size: 0.72rem; color: var(--dash-ink-faint); }
.dash-op__fact:hover .dash-op__factPen { color: var(--gp-forest, #1f5138); }
.dash-op__profileFoot { margin: 10px 0 0; font-size: 0.76rem; color: var(--dash-ink-faint); }

/* WHY IT FITS — the significance carrier: green evidence badge + confirm count + chevron */
.dash-op__why {
    display: inline-flex; align-items: center; gap: 8px;
    min-height: 34px; padding: 5px 12px;
    font: inherit; font-size: 0.8rem;
    background: var(--gp-ok-bg, #e6f1ea);
    border: 1px solid rgba(44, 94, 63, 0.35); border-radius: 9px;
    color: var(--gp-ok-ink, #2c5e3f); cursor: pointer;
    transition: box-shadow .12s ease, border-color .12s ease;
}
.dash-op__why:hover { border-color: var(--gp-forest, #1f5138); box-shadow: 0 2px 8px rgba(31,81,56,.16); }
.dash-op__whyBig { font-size: 1.02rem; font-weight: 800; }
.dash-op__whyN { font-weight: 700; white-space: nowrap; }
.dash-op__whyQ {
    white-space: nowrap; font-weight: 600; font-size: 0.74rem;
    color: var(--gp-mid-ink, #7a5a1a); background: var(--gp-mid-bg, #f3ecdb);
    padding: 2px 8px; border-radius: 999px;
}
.dash-op__whyChev { font-size: 0.7rem; color: var(--gp-ok-ink, #2c5e3f); }
.dash-op__row--open .dash-op__whyChev { transform: rotate(180deg); }

/* Timing cell (Quick folded in as a small companion chip) */
.dash-op__timing { font-size: 0.82rem; }
.dash-op__timing--mid { color: var(--gp-mid-ink, #7a5a1a); font-weight: 600; }
.dash-op__timing--date { font-weight: 600; }

/* Hover evidence card (desktop pointer-fine only; created once, fixed to document) */
.dash-op__hover {
    display: none; position: absolute; z-index: 1200; width: 300px;
    padding: 13px 15px; background: #fff; border: 1px solid var(--dash-cream-dark);
    border-radius: 12px; box-shadow: 0 10px 30px -12px rgba(42,33,22,.35);
    font-family: var(--dash-font-body);
}
.dash-op__hoverT { margin: 0 0 7px; font-size: 0.84rem; font-weight: 700; color: var(--dash-ink); }
.dash-op__hover ul { list-style: none; margin: 0 0 6px; padding: 0; }
.dash-op__hover li { font-size: 0.8rem; color: var(--dash-ink); padding: 2px 0 2px 20px; position: relative; line-height: 1.4; }
.dash-op__hover li span { position: absolute; left: 0; color: var(--gp-ok-ink, #2c5e3f); font-weight: 700; }
.dash-op__hoverMore { margin: 0 0 4px; font-size: 0.76rem; color: var(--dash-ink-faint); }
.dash-op__hoverQ { margin: 0 0 6px; font-size: 0.78rem; font-weight: 600; color: var(--gp-mid-ink, #7a5a1a); }
.dash-op__hoverFoot { margin: 6px 0 0; padding-top: 7px; border-top: 1px solid var(--dash-cream-dark); font-size: 0.74rem; color: var(--dash-ink-faint); }

/* Drawer CTA row */
.dash-op__actions { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-top: 4px; }
.dash-op__cta {
    display: inline-flex; align-items: center; justify-content: center;
    min-height: 40px; padding: 8px 18px; border-radius: 9px;
    font: inherit; font-size: 0.86rem; font-weight: 700; text-decoration: none; cursor: pointer;
}
.dash-op__cta--primary { background: var(--gp-forest, #1f5138); color: #fff; border: 1px solid var(--gp-forest, #1f5138); }
.dash-op__cta--primary:hover { background: var(--gp-forest-d, #163d2a); }
.dash-op__cta--ghost { background: #fff; color: var(--gp-forest, #1f5138); border: 1px solid var(--gp-forest, #1f5138); }
.dash-op__cta--ghost:hover { background: var(--gp-ok-bg, #e6f1ea); }

/* ── Mobile: purpose-built CARDS, not a collapsed table (the 390px view was broken) ── */
@media (max-width: 700px) {
    .dash-op__scroll { overflow-x: visible; contain: none; }
    .dash-op__table { min-width: 0; }
    .dash-op__table > tbody { display: block; }
    .dash-op__table > tbody > tr.dash-op__row {
        display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px;
        background: #fff; border: 1px solid var(--dash-cream-dark); border-radius: 12px;
        padding: 12px 14px; margin: 0 0 10px;
    }
    /* kill the generic stacked-table look: no per-cell uppercase labels */
    .dash-op__table .gp-c::before { content: none !important; display: none !important; }
    .dash-op__table .gp-c { display: block; padding: 0; border: 0; }
    .dash-op__cProg { order: 1; flex: 1 1 100%; }
    .dash-op__cProg .gp-prog__rank { min-width: 0; margin-right: 6px; }
    .dash-op__cAward { order: 2; flex: 0 0 auto; }
    .dash-op__cAward .dash-op__amt { display: inline; font-size: 0.86rem; }
    .dash-op__cAward .dash-op__amtBasis { display: inline; margin-left: 4px; }
    .dash-op__cOdds { order: 3; flex: 0 0 auto; }
    .dash-op__cTiming { order: 4; flex: 0 0 auto; font-size: 0.8rem; }
    .dash-op__cWhy { order: 5; flex: 1 1 100%; }
    .dash-op__cWhy .dash-op__why { width: 100%; justify-content: space-between; min-height: 44px; }
    .dash-op__table > tbody > tr.dash-op__detail {
        display: block; margin: -6px 0 10px; border: 1px solid var(--dash-cream-dark);
        border-top: 0; border-radius: 0 0 12px 12px;
    }
    .dash-op__detail > td { display: block; }
    .dash-op__detail > td:first-child { box-shadow: none; }
    .dash-op__row--open { border-radius: 12px 12px 0 0 !important; }
    .dash-op__row--open > td:first-child { box-shadow: none; }
    .dash-op__ans { min-height: 44px; min-width: 64px; }
    .dash-op__actions .dash-op__cta { flex: 1 1 100%; }
    .dash-op__fact { min-height: 38px; }
}

/* ═══ Our Picks round 4 (2026-08-13, Khalid: column widths + ragged program names) ═══ */
/* Column budget: Program owns the space; Opens/Closes shrinks to content. */
.dash-op__table { table-layout: fixed; }
.dash-op__table .gp-th--prog { width: 32%; }
.dash-op__table .gp-th--award { width: 15%; }
.dash-op__table .gp-th--odds { width: 15%; }
.dash-op__table .gp-th--fit { width: 24%; }
.dash-op__table .gp-th--timing { width: 14%; }
/* Program cell: rank in a fixed gutter, title wraps in its own block — every wrapped
   line aligns; the Strong fit tag sits on its own line instead of jostling the title. */
.dash-op__cProg { display: flex; align-items: flex-start; gap: 10px; }
.dash-our-picks .dash-op__cProg .gp-prog__rank {
    flex: 0 0 22px; min-width: 22px; margin: 1px 0 0; text-align: center;
    font-size: 0.76rem; font-weight: 600; color: var(--dash-ink-faint);
    background: var(--dash-cream, #f6f1e7); border-radius: 999px; line-height: 22px; height: 22px;
}
.dash-op__tWrap { min-width: 0; }
.dash-op__t { display: block; line-height: 1.35; }
.dash-op__strong, .dash-op__newTag { display: inline-block; margin: 4px 4px 0 0; }
.dash-op__cTiming { white-space: nowrap; }
.dash-op__cTiming .dash-op__quick { margin-left: 6px; }
/* keep award/odds content from crowding the fixed columns */
.dash-op__cAward, .dash-op__cOdds { overflow-wrap: break-word; }
@media (max-width: 700px) {
    .dash-op__table { table-layout: auto; }
    .dash-op__table .gp-th--prog, .dash-op__table .gp-th--award, .dash-op__table .gp-th--odds,
    .dash-op__table .gp-th--fit, .dash-op__table .gp-th--timing { width: auto; }
    .dash-op__cProg { display: flex; }
    .dash-op__cTiming { white-space: normal; }
}

/* round-4b: the fixed budget + nowrap forced right-edge clipping ("Between intakes" cut).
   Timing wraps naturally and gets a slightly wider track; fit gives a point back. */
.dash-op__table .gp-th--fit { width: 23%; }
.dash-op__table .gp-th--timing { width: 15%; }
.dash-op__cTiming { white-space: normal; }
.dash-op__table { min-width: 0; }

/* round-4c: the WHY pill overflowed its fixed track into the timing column. The pill may
   wrap to two lines inside its cell; track budget rebalanced (fit up, prog/award trimmed). */
.dash-op__table .gp-th--prog { width: 30%; }
.dash-op__table .gp-th--award { width: 14%; }
.dash-op__table .gp-th--odds { width: 14%; }
.dash-op__table .gp-th--fit { width: 27%; }
.dash-op__table .gp-th--timing { width: 15%; }
.dash-op__why { flex-wrap: wrap; max-width: 100%; row-gap: 4px; }
.dash-op__cWhy { padding-right: 14px; }

/* round-4d: chevron wrapped to a lonely second line inside the pill on desktop — drop it
   there (hover card + row cursor carry the affordance); keep it on mobile's full-width bar.
   Quick chip gets its own line inside the timing cell instead of clipping at the edge. */
@media (min-width: 701px) {
    .dash-op__whyChev { display: none; }
    .dash-op__cTiming .dash-op__quick { display: block; width: max-content; margin: 5px 0 0; }
}

/* ═══ Our Picks round 5 (2026-08-13 live review) ═══════════════════════════ */
/* Khalid's screenshot: the row's tabindex focus ring painted as a harsh clipped green box.
   Mouse clicks get no ring; keyboard focus gets a soft inset ring that cannot clip. */
.dash-op__row:focus { outline: none; }
.dash-op__row:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--gp-forest, #1f5138); border-radius: 4px; }
.dash-op__why:focus { outline: none; }
.dash-op__why:focus-visible { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--gp-forest, #1f5138); }
.dash-op__ans:focus-visible, .dash-op__cta:focus-visible, .dash-op__fact:focus-visible {
    outline: 2px solid var(--gp-forest, #1f5138); outline-offset: 2px;
}
/* breathing room at the table's right edge (timing column sat flush against the pane) */
.dash-op__cTiming { padding-right: 16px; }
.dash-op__table .gp-th--timing { padding-right: 16px; }

/* round-5 continued: inline top reason, promoted verdict, edit control, mobile chip collapse */
.dash-op__whyTop {
    display: block; margin-top: 5px; font-size: 0.76rem; color: var(--dash-ink-secondary);
    line-height: 1.35;
}
.dash-op__calib {
    font-family: var(--dash-font-body); font-size: 0.87rem; font-weight: 600; font-style: normal;
    color: var(--gp-ok-ink, #2c5e3f); margin: 12px 0;
    padding: 8px 12px; background: var(--gp-ok-bg, #e6f1ea); border-radius: 8px; display: inline-block;
}
.dash-op__calibMark { margin-right: 7px; font-weight: 800; }
.dash-op__editAll {
    margin-left: auto; padding: 4px 12px; min-height: 30px;
    font: inherit; font-size: 0.78rem; font-weight: 600; color: var(--gp-forest, #1f5138);
    background: #fff; border: 1px solid var(--gp-forest, #1f5138); border-radius: 8px; cursor: pointer;
}
.dash-op__editAll:hover { background: var(--gp-ok-bg, #e6f1ea); }
.dash-op__chipsMore { display: none; }
@media (max-width: 700px) {
    .dash-op__profileChips { max-height: 88px; overflow: hidden; }
    .dash-op__profileChips.is-open { max-height: none; }
    .dash-op__chipsMore {
        display: inline-block; margin-top: 8px; padding: 6px 12px; min-height: 38px;
        font: inherit; font-size: 0.8rem; font-weight: 600; color: var(--gp-forest, #1f5138);
        background: none; border: 0; text-decoration: underline; cursor: pointer;
    }
    .dash-op__editAll { margin-left: 0; margin-top: 6px; }
    .dash-op__whyTop { padding: 0 2px; }
}

/* ═══ Who actually wins your programs (2026-08-16, distribution wave) ═══════
   Card chrome mirrors .dash-our-picks exactly — same paper, same border token,
   same radius, same 18px rhythm — because the two sit adjacent and a second
   card geometry between them would read as a different KIND of thing rather
   than the next section.

   ⚠ Row geometry is deliberately NOT a table. Our Picks earns its grid by
   carrying five comparable columns; this module carries one fact per program,
   and a two-column table of "name | sentence" would inherit the grid's minimum
   width and its horizontal scroll for no gain.

   ⚠ The whole row is one <a>: the program name and the fact are a single
   destination, so two adjacent tap targets would just be two ways to do the
   same thing, with the smaller one under the 44px floor. */
.dash-who-wins {
    background: var(--dash-paper);
    border: 1px solid var(--dash-cream-dark);
    border-radius: var(--dash-radius);
    padding: 14px 18px;
    margin-bottom: 18px;
}
.dash-ww__lead {
    font-family: var(--dash-font-body); font-size: 0.88rem; color: var(--dash-ink-secondary);
    margin: 8px 0 10px; line-height: 1.5;
}
.dash-ww__list { list-style: none; margin: 0; padding: 0; }
.dash-ww__row { border-top: 1px solid var(--dash-cream); }
.dash-ww__row:first-child { border-top: 0; }

/* Row link. ⚠ Sitewide `a:hover { color: var(--sienna) }` reaches this card, so
   the colour is repeated across every link state at (0,0,2,0) — otherwise the
   program name turns sienna on hover and reads as a different component. */
/* ⚠ GRID, not a wrapping flex row. As a flex row each fact began wherever its
   program name happened to end, so the three facts started at three arbitrary
   x positions with a ragged right edge — and the whole reason to show three at
   once is to compare them. A two-track grid gives the names a shared left edge
   and the facts a shared right one, which is the alignment the reader was
   otherwise being asked to do themselves.
   ⚠ `minmax(0, 1fr)`, never `1fr`: a 1fr track floors at min-content, and these
   cells hold long program titles. */
.dash-ww__link,
.dash-ww__link:hover,
.dash-ww__link:focus,
.dash-ww__link:visited,
.dash-ww__link:active {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline;
    gap: 4px 16px;
    padding: 11px 2px; min-height: 44px; box-sizing: border-box;
    text-decoration: none; color: var(--dash-ink);
}
.dash-ww__link:hover { background: var(--dash-cream); }
.dash-ww__link:focus-visible {
    outline: 2px solid var(--gp-forest, #1f5138); outline-offset: -2px; border-radius: 4px;
}
.dash-ww__prog {
    font-family: var(--dash-font-body); font-size: 0.9rem; font-weight: 600;
    color: var(--dash-ink); line-height: 1.35;
}
/* ⚠ BODY font, not `--dash-font-data`. That token is this dashboard's vocabulary
   for compact numeric tokens — chip counts, metric numerals, short stamps — and
   every other use of it is a number. Setting a full English sentence in it made
   the card's most valuable content read as terminal output rather than as a
   finding, and on a phone, where each fact wraps, the card became alternating
   bands of proportional and monospaced text. Our Picks puts figures in mono
   inside TABLE CELLS, where mono means "a column of comparable numbers"; there
   is no column here, so it meant nothing. */
.dash-ww__fact {
    font-family: var(--dash-font-body); font-size: 0.82rem;
    color: var(--dash-ink-secondary); line-height: 1.35; text-align: right;
}
.dash-ww__foot { margin: 10px 0 2px; }
.dash-ww__all,
.dash-ww__all:hover,
.dash-ww__all:focus,
.dash-ww__all:visited,
.dash-ww__all:active {
    font-family: var(--dash-font-body); font-size: 0.82rem; font-weight: 600;
    color: var(--gp-forest, #1f5138); text-decoration: none;
}
.dash-ww__all:hover { text-decoration: underline; }
.dash-ww__all:focus-visible { outline: 2px solid var(--gp-forest, #1f5138); outline-offset: 2px; }

/* The discovery variant deliberately has NO styles of its own: it reuses
   .dash-ww__lead and .dash-ww__all so the two states are the same component
   with different content, rather than two objects that happen to share an id.
   Its footer link keeps the 44px floor because it is the card's only control. */
.dash-ww__all { display: inline-flex; align-items: center; min-height: 44px; }

/* ⚠ 701/700, matching this file's existing phone breakpoint — not 681/680. */
@media (max-width: 700px) {
    .dash-who-wins { padding: 12px 14px; }
    /* Stack name over fact: side by side they compete for a 320px line and the
       fact ends up on its own line anyway, just without the name's leading.
       One track, so the shared right edge (which only helps when the two sit on
       one line) gives way to a shared LEFT one. */
    .dash-ww__link { grid-template-columns: minmax(0, 1fr); gap: 2px; }
    .dash-ww__fact { text-align: left; }
}

/* Who-wins premium panels variant (2026-08-25): the shared GCWinnerPanel
   replaces the outbound fact rows for members. The panel brings its own card
   styling — the list just needs its chrome stripped. */
.dash-ww__list--panels { list-style: none; margin: 0; padding: 0; }
.dash-ww__row--panel { display: block; padding: 0; margin: 0 0 10px; border: 0; }
.dash-ww__row--panel .dash-ww__panelhost[hidden] { display: none; }
/* ⚠ .dash-ww__link carries its own display rule, which silently DEFEATS the
   [hidden] attribute (the documented [hidden]-vs-display class) — without this
   line the "hidden" fallback fact rows paint beside the panels: the same fact
   twice, in two populations. Caught by screenshot, not by the property read. */
.dash-ww__row--panel .dash-ww__link[hidden] { display: none; }
.dash-ww__progline {
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  color: #6f6858; margin: 2px 0 6px;
}
.dash-ww__progline[hidden] { display: none; }

/* Cancel save screen entry (2026-10-16): quiet, always present for a paying member, never a trap */
.dash-settings__cancel { display: inline-block; margin: 10px 0 0 4px; padding: 12px 4px; font-size: 14px; font-weight: 600; color: #57534E; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: #C9C1B5; }
.dash-settings__cancel:hover { color: #1C1917; text-decoration-color: currentColor; }
