/*
 * Bmad Studio — Visual foundation (Story 2.1)
 * =============================================
 * The single source of truth for the design system: tokens, typography,
 * base components (button + input) and the pre-auth centered-card shell.
 *
 * Token naming convention (local; none pre-existed in this file):
 *   --color-*   colors        (DESIGN.md → Colors)
 *   --space-*   spacing scale  4·8·12·16·24·32·48·64 (DESIGN.md → Layout & Spacing)
 *   --radius-*  corner radii   (DESIGN.md → Shapes)
 *   --shadow-*  elevation      (DESIGN.md → Elevation & Depth)
 *
 * Contrast note (AC 5): the DESIGN.md *background* tints are preserved verbatim;
 * several *text* tokens are darkened so each status-chip pair and the primary
 * button clear WCAG AA (>=4.5:1 for normal text — chip 12.5/600 and button
 * 15/600 do NOT qualify as "large text", so 4.5:1 applies). See per-token notes.
 *
 * Font: Quicksand (OFL; vendored from Fontsource) self-hosted under assets/fonts/ — no runtime CDN.
 * Sources: DESIGN.md, EXPERIENCE.md (spines win over the reference mockups).
 */

/* ── Quicksand (self-hosted, OFL — see assets/fonts/OFL.txt) ─────────────── */
@font-face {
    font-family: "Quicksand";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("../fonts/quicksand-400--w-pQeM.woff2") format("woff2");
}

@font-face {
    font-family: "Quicksand";
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("../fonts/quicksand-500-q-9OFZS.woff2") format("woff2");
}

@font-face {
    font-family: "Quicksand";
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("../fonts/quicksand-600-XUero_-.woff2") format("woff2");
}

@font-face {
    font-family: "Quicksand";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("../fonts/quicksand-700-ZRdyeUG.woff2") format("woff2");
}

/* ── Design tokens ──────────────────────────────────────────────────────── */
:root {
    /* Ink (navy family — text & structure) */
    --color-ink: #1E2742;          /* primary text, headings, wordmark — 13.32:1 on canvas */
    --color-ink-soft: #565F7A;     /* secondary text, labels — 6.34:1 on white (AA pass) */
    --color-ink-mute: #9095A8;     /* meta, placeholders, icons — 2.98:1 on white: placeholder/meta only, never a label */

    /* Canvas & surfaces (warm) */
    --color-canvas: #F7F3EB;       /* app background (cream) */
    --color-card: #FFFFFF;         /* cards, panels, sheets */
    --color-surface-alt: #FCFAF5;  /* subtle inset / hover fill */
    --color-line: #EBE5DA;         /* hairline borders, dividers */
    --color-line-strong: #E0D9CC;  /* inputs, stronger separation */

    /* Accent (coral-red — used sparingly) */
    --color-accent: #E05C45;       /* brand CTA color / current-step marker (DESIGN.md) */
    --color-accent-strong: #CB4C35;/* hover/active of accent */
    --color-accent-tint: #FBE8E2;  /* current-step chip bg, focus glow */
    --color-decor-blue: #EAF0F6;   /* decorative pre-auth glow only (not a brand color) */

    /* Primary-button background: darkened from --color-accent (#E05C45) because
       white-on-#E05C45 is only 3.63:1 (fails AA). #C0432D = 5.14:1 white-on. (AC 5) */
    --color-accent-button: #C0432D;
    --color-accent-button-hover: #AD3722; /* 6.28:1 white-on (AA pass) */

    /* Status tints — backgrounds verbatim from DESIGN.md; text tokens darkened to clear AA (AC 5) */
    --color-status-done-text: #2C7252;     /* was #2F7A57 (4.43:1) -> 4.93:1 on done-bg */
    --color-status-done-bg: #E4F0E7;
    --color-status-current-text: #B83E29;  /* was #CB4C35 (3.84:1) -> 4.72:1 on current-bg */
    --color-status-current-bg: #FBE8E2;
    --color-status-skippable-text: #3A699C;/* was #3D6FA6 (4.50:1 borderline) -> 4.91:1 on skippable-bg */
    --color-status-skippable-bg: #E7EFF7;
    --color-status-locked-text: #5C6175;   /* was #8A8FA3 (2.70:1, flagged) -> 5.16:1 on locked-bg */
    --color-status-locked-bg: #EFEBE3;

    /* Spacing scale (4·8·12·16·24·32·48·64) */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 24px;
    --space-6: 32px;
    --space-7: 48px;
    --space-8: 64px;

    /* Radii */
    --radius-card: 16px;
    --radius-inner: 12px;
    --radius-control: 10px;  /* buttons, inputs */
    --radius-pill: 999px;    /* chips */

    /* Elevation (borders over shadows) */
    --shadow-card: 0 1px 2px rgba(30, 39, 66, .04), 0 4px 16px rgba(30, 39, 66, .05);
    --shadow-modal: 0 24px 60px rgba(30, 39, 66, .20);
    --color-scrim: rgba(30, 39, 66, .45); /* navy scrim behind modals */

    /* Type scale — size (line-heights applied per role below) */
    --font-sans: "Quicksand", system-ui, -apple-system, "Segoe UI", sans-serif;
    --text-display: 36px;
    --text-page-title: 26px;
    --text-section: 19px;
    --text-body: 16px;
    --text-label: 15px;
    --text-meta: 13.5px;
    --text-chip: 12.5px;
}

/* ── Reset / base ───────────────────────────────────────────────────────── */
* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

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

body {
    font-family: var(--font-sans);
    font-size: var(--text-body);
    font-weight: 400;
    line-height: 1.6;
    color: var(--color-ink);
    background-color: var(--color-canvas);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-wrap: pretty;
}

input,
button,
textarea,
select {
    font-family: inherit;
    font-size: inherit;
}

a {
    color: var(--color-accent-button);
    font-weight: 600;
    text-decoration: none;

    &:hover {
        text-decoration: underline;
    }
}

/* ── Type scale ─────────────────────────────────────────────────────────── */
.t-display {
    font-size: var(--text-display);
    line-height: 1.15;
    font-weight: 600;
    letter-spacing: -0.01em;
}

h1,
.t-page-title {
    font-size: var(--text-page-title);
    line-height: 1.2;
    font-weight: 600;
    letter-spacing: -0.01em;
}

h2,
.t-section {
    font-size: var(--text-section);
    line-height: 1.3;
    font-weight: 600;
    letter-spacing: -0.01em;
}

.t-body {
    font-size: var(--text-body);
    line-height: 1.6;
    font-weight: 400;
}

.t-meta {
    font-size: var(--text-meta);
    line-height: 1.4;
    font-weight: 500;
    color: var(--color-ink-mute);
}

.t-chip {
    font-size: var(--text-chip);
    line-height: 1;
    font-weight: 600;
}

/* All-caps eyebrow (e.g. "WELCOME ABOARD") */
.eyebrow {
    font-size: var(--text-chip);
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-accent);
}

/* ── Shared focus ring (accent) on every interactive element ────────────── */
:where(a, button, input, textarea, select, [tabindex]):focus-visible {
    outline: none;
    border-color: var(--color-accent);
    box-shadow: 0 0 0 3px var(--color-accent-tint);
}

/* ── Button ─────────────────────────────────────────────────────────────── */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-height: 44px;
    padding: var(--space-3) var(--space-5);
    border: 1px solid transparent;
    border-radius: var(--radius-control);
    font-size: var(--text-label);
    line-height: 1.2;
    font-weight: 600;
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
    text-decoration: none;

    &.btn--primary {
        background-color: var(--color-accent-button); /* white text 5.14:1 — AA */
        color: #FFFFFF;

        &:hover {
            background-color: var(--color-accent-button-hover);
            text-decoration: none;
        }
    }

    &.btn--secondary {
        background-color: var(--color-card);
        border-color: var(--color-line-strong);
        color: var(--color-ink);

        &:hover {
            background-color: var(--color-surface-alt);
        }
    }

    &.btn--ghost {
        background-color: transparent;
        color: var(--color-ink-soft);

        &:hover {
            background-color: var(--color-surface-alt);
        }
    }

    /* Destructive action (Story 3.6 — "Unlock & discard"). Same coral-red as --primary
       but semantically distinct — never used for a safe/affirmative CTA. */
    &.btn--destructive {
        background-color: var(--color-accent-button);
        color: var(--color-card);
        border-color: transparent;

        &:hover {
            background-color: var(--color-accent-button-hover);
        }
    }

    &.btn--block {
        width: 100%;
    }
}

/* ── Input field (label-above pattern) ──────────────────────────────────── */
.field {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);

    & + & {
        margin-top: var(--space-4);
    }

    .field__label {
        font-size: 14px;
        line-height: 1.2;
        font-weight: 600;
        color: var(--color-ink-soft);
    }

    .field__input {
        height: 44px;
        width: 100%;
        padding: 0 var(--space-4);
        border: 1px solid var(--color-line-strong);
        border-radius: var(--radius-control);
        background-color: var(--color-card);
        font-size: var(--text-body);
        color: var(--color-ink);

        &::placeholder {
            color: var(--color-ink-mute);
        }

        /* The shared :where(...) focus ring has zero specificity, so the input's own
           1px line-strong border would otherwise win — restate the accent border here
           (specificity high enough) so focus shows BOTH the ring and the accent edge. */
        &:focus-visible {
            border-color: var(--color-accent);
        }
    }

    .field__help {
        font-size: 13px;
        line-height: 1.4;
        color: var(--color-ink-mute);
    }

    /* Field-tied validation error (Story 2.2). Calm coral, never a harsh flood;
       paired with role="alert" in the markup so it is announced. The matching
       input gets a soft coral edge when the form re-renders with errors. */
    .field__error {
        font-size: 13px;
        line-height: 1.4;
        font-weight: 600;
        color: var(--color-status-current-text);
    }

    &.field--invalid .field__input,
    .field__input[aria-invalid="true"] {
        border-color: var(--color-accent);
    }
}

/* ── Status chip ────────────────────────────────────────────────────────── */
.chip {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-1) var(--space-3);
    border-radius: var(--radius-pill);
    font-size: var(--text-chip);
    line-height: 1;
    font-weight: 600;

    &.chip--done {
        color: var(--color-status-done-text);
        background-color: var(--color-status-done-bg);
    }

    &.chip--current {
        color: var(--color-status-current-text);
        background-color: var(--color-status-current-bg);
    }

    &.chip--skippable {
        color: var(--color-status-skippable-text);
        background-color: var(--color-status-skippable-bg);
    }

    &.chip--locked {
        color: var(--color-status-locked-text);
        background-color: var(--color-status-locked-bg);
    }
}

/* ── Wordmark (neutral "B" disc + product name) ─────────────────────────── */
.wordmark {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);

    .wordmark__mark {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 30px;
        height: 30px;
        border-radius: 9px;
        background-color: var(--color-ink);
        color: var(--color-card);
        font-weight: 700;
        font-size: 16px;
    }

    .wordmark__name {
        font-weight: 600;
        font-size: 17px;
        letter-spacing: -0.01em;
        color: var(--color-ink);
    }
}

/* ── Pre-auth centered-card shell ───────────────────────────────────────── */
.pre-auth {
    position: relative;
    min-height: 100vh;
    /* dvh keeps the card reachable under mobile browser chrome; vh is the fallback */
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-7);
    padding: var(--space-6);
    background-color: var(--color-canvas);
    /* Clip the decorative blobs horizontally, but never the (vertically scrollable)
       content: tall child screens (Login/Reset) must stay reachable, not be cut off. */
    overflow-x: clip;
    overflow-y: auto;

    /* Decorative ambient blobs (pure decoration, behind the card) */
    .pre-auth__glow {
        position: absolute;
        border-radius: 50%;
        pointer-events: none;

        &.pre-auth__glow--top {
            top: -160px;
            right: -120px;
            width: 420px;
            height: 420px;
            background: radial-gradient(circle, var(--color-accent-tint) 0%, rgba(251, 232, 226, 0) 70%);
        }

        &.pre-auth__glow--bottom {
            bottom: -180px;
            left: -140px;
            width: 460px;
            height: 460px;
            background: radial-gradient(circle, var(--color-decor-blue) 0%, rgba(234, 240, 246, 0) 70%);
        }
    }

    .pre-auth__inner {
        position: relative;
        width: 100%;
        max-width: 432px;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: var(--space-6);
    }

    .pre-auth__card {
        width: 100%;
        padding: var(--space-7) var(--space-6);
        background-color: var(--color-card);
        border: 1px solid var(--color-line);
        border-radius: var(--radius-card);
        box-shadow: var(--shadow-card);
    }

    /* Tighten the air on narrow screens so the card keeps a usable inner width. */
    @media (width <= 480px) {
        padding: var(--space-4);

        .pre-auth__card {
            padding: var(--space-6) var(--space-5);
        }
    }
}

/* ── Dead-end states (invite expired, account disabled) ──────────────────────
   Calm, blame-free off-platform dead-ends (Story 2.5, mockups 14/15). They live
   on the pre-auth shell; the card content is centered, with a left-aligned
   "what to do" helper card and a decorative status icon. */
.dead-end {
    text-align: center;

    /* Soft round status disc holding a decorative (aria-hidden) glyph. */
    .dead-end__icon {
        width: 64px;
        height: 64px;
        margin: 0 auto var(--space-5);
        border-radius: var(--radius-pill);
        background-color: var(--color-status-locked-bg);
        display: flex;
        align-items: center;
        justify-content: center;
        color: var(--color-ink-mute);
    }
}

/* Inset "what to do / how to get back in" panel. Left-aligned inside the
   otherwise-centered dead-end card. */
.helper-card {
    margin-top: var(--space-5);
    padding: var(--space-4);
    text-align: left;
    background-color: var(--color-surface-alt);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-inner);

    /* Muted uppercase label — distinct from .eyebrow (which is accent-colored). */
    .helper-card__eyebrow {
        font-size: var(--text-chip);
        font-weight: 600;
        letter-spacing: 0.05em;
        text-transform: uppercase;
        color: var(--color-ink-mute);
    }

    .helper-card__body {
        margin-top: var(--space-2);
        color: var(--color-ink-soft);
    }
}

/* ── Post-auth app shell (sidebar + content) ─────────────────────────────────
   Story 3.1. A fixed 240px rail on the card surface (borders over shadows) + a
   centered content column. The active nav row is the one accent-tinted element;
   color is never the sole signal (active row also gets weight 600 + aria-current).
   Source: DESIGN.md → Layout & Spacing, Components → Sidebar; UX-DR3/DR9/DR22/DR24. */
.app-shell {
    display: flex;
    min-height: 100vh;
    min-height: 100dvh;
    background-color: var(--color-canvas);
}

.app-sidebar {
    flex: none;
    width: 240px;
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
    padding: var(--space-5) var(--space-4);
    background-color: var(--color-card);
    border-right: 1px solid var(--color-line);
    /* Stay put while the content column scrolls. */
    position: sticky;
    top: 0;
    height: 100vh;
    height: 100dvh;
    /* On a very short viewport the pinned user chip / sign-out must stay reachable
       by scrolling the rail itself rather than being pushed below the fold. */
    overflow-y: auto;

    .app-sidebar__wordmark {
        padding: var(--space-2);
        font-weight: 600;

        /* The wordmark is a link to Home but must not read as body-link text. */
        &:hover {
            text-decoration: none;
        }
    }
}

.app-nav {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);

    .app-nav__item {
        display: flex;
        align-items: center;
        gap: var(--space-3);
        min-height: 44px;
        padding: var(--space-3);
        border: 1px solid transparent;
        border-radius: var(--radius-control);
        color: var(--color-ink-soft);
        font-size: var(--text-label);
        font-weight: 500;
        text-decoration: none;
        transition: background-color .12s ease, color .12s ease;

        &:hover {
            background-color: var(--color-surface-alt);
            color: var(--color-ink);
            text-decoration: none;
        }

        /* Active row: the one accent-tinted fill (UX-DR9). Color is paired with
           weight 600 + aria-current so it never relies on color alone (UX-DR24). */
        &.is-active {
            background-color: var(--color-accent-tint);
            color: var(--color-ink);
            font-weight: 600;
        }

        /* The shared focus ring is accent-tint, which would be near-invisible on
           the active row (same fill). Give the active row a stronger accent ring
           so keyboard focus stays visible on the current page (UX-DR22). */
        &.is-active:focus-visible {
            border-color: var(--color-accent);
            box-shadow: 0 0 0 2px var(--color-card), 0 0 0 4px var(--color-accent);
        }
    }

    /* Neutral geometric glyphs (decorative; the text label carries the meaning). */
    .app-nav__glyph {
        flex: none;
        display: inline-block;
        width: 16px;
        height: 16px;
        border: 2px solid currentColor;
        opacity: .75;

        &.app-nav__glyph--home {
            border-radius: 5px;
        }

        &.app-nav__glyph--usage {
            border-radius: 50%;
        }

        &.app-nav__glyph--admin {
            border-radius: 4px;
            width: 14px;
        }
    }
}

.app-more-aside {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding-top: var(--space-4);
    border-top: 1px solid var(--color-line);

    .chat__back {
        flex: none;
        font-size: var(--text-meta);
        font-weight: 600;
        color: var(--color-ink-soft);
        text-decoration: none;

        &:hover {
            color: var(--color-ink);
        }
    }
}

.app-userchip {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-top: auto;
    padding-top: var(--space-4);
    border-top: 1px solid var(--color-line);

    .app-userchip__avatar {
        flex: none;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 34px;
        height: 34px;
        border-radius: 50%;
        background-color: var(--color-status-skippable-bg);
        color: var(--color-status-skippable-text);
        font-weight: 700;
        font-size: 14px;
    }

    .app-userchip__identity {
        flex: 1;
        min-width: 0;
        line-height: 1.25;
    }

    .app-userchip__name {
        display: block;
        font-size: var(--text-meta);
        font-weight: 600;
        color: var(--color-ink);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .app-userchip__signout {
        flex: none;
    }

    .app-signout-btn {
        padding: var(--space-1) var(--space-2);
        border: 1px solid transparent;
        border-radius: var(--radius-control);
        background: transparent;
        color: var(--color-ink-mute);
        font-size: var(--text-meta);
        font-weight: 600;
        cursor: pointer;

        &:hover {
            color: var(--color-ink);
            background-color: var(--color-surface-alt);
        }
    }
}

.app-content {
    flex: 1;
    min-width: 0;
    overflow-y: scroll;
    position: relative;
    height: 100dvh;

    .app-content__inner {
        max-width: 1000px;
        padding: var(--space-7) var(--space-7);
        margin: 0 auto;
    }

    @media (width <= 720px) {
        padding: var(--space-5) var(--space-4);
    }
}

/* ── Dashboard intro + start tiles (Story 3.2) ─────────────────────────────── */
.dashboard-intro {
    margin-top: var(--space-3);
    color: var(--color-ink-soft);
}

.start-tiles {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-4);
    margin-top: var(--space-6);

    @media (width <= 720px) {
        grid-template-columns: 1fr;
    }
}

/* Each tile is a <form> (server-rendered POST). The whole card is the affordance;
   its submit button carries the title and stretches over the card so the entire
   surface is clickable, while the hidden inputs ride along. */
.start-tile {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-5);
    background-color: var(--color-card);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-card);
    box-shadow: 0 1px 2px rgb(30 39 66 / 4%), 0 4px 16px rgb(30 39 66 / 5%);
    transition: border-color .15s ease, box-shadow .15s ease;

    &:hover,
    &:focus-within {
        border-color: var(--color-line-strong);
        box-shadow: 0 1px 2px rgb(30 39 66 / 6%), 0 8px 24px rgb(30 39 66 / 8%);
    }
}

.start-tile__badge {
    position: absolute;
    top: var(--space-4);
    right: var(--space-4);
    padding: var(--space-1) var(--space-3);
    border-radius: var(--radius-pill);
    font-size: var(--text-chip);
    font-weight: 600;
    color: var(--color-status-current-text);
    background-color: var(--color-accent-tint);
}

.start-tile__disc {
    display: inline-grid;
    width: 46px;
    height: 46px;
    border-radius: var(--radius-inner);
    place-items: center;

    &::before {
        content: '';
        width: 40%;
        aspect-ratio: 1/1;
    }

    &.start-tile__disc--brainstorm {
        background-color: var(--color-accent-tint);

        &::before {
            background-color: var(--color-accent);
            border-radius: 50%;
        }
    }

    &.start-tile__disc--define {
        background-color: var(--color-status-skippable-bg);

        &::before {
            width: calc(40% - 8px);
            border: solid 4px var(--color-status-skippable-text);
            border-radius: 4px;
        }
    }

    &.start-tile__disc--research {
        background-color: var(--color-status-done-bg);

        &::before {
            width: calc(40% - 8px);
            border: solid 4px var(--color-status-done-text);
            border-radius: 50%;
        }
    }
}

/* The clickable title: a real submit button styled as text, stretched to cover
   the whole tile (so a click anywhere submits) without hiding the badge/disc. */
.start-tile__action {
    appearance: none;
    border: 0;
    padding: 0;
    background: none;
    text-align: left;
    font-family: inherit;
    cursor: pointer;
    color: var(--color-ink);

    &::after {
        content: "";
        position: absolute;
        inset: 0;
        border-radius: var(--radius-card);
    }
}

.start-tile__title {
    font-size: 17px;
    font-weight: 600;
    color: var(--color-ink);
}

.start-tile__desc {
    font-size: var(--text-meta);
    color: var(--color-ink-soft);
}

/* ── Define a product: Start fresh / Start from a brainstorm (Story 4.7) ─────── */
.define-product__options {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-4);
    margin-top: var(--space-6);

    @media (width <= 720px) {
        grid-template-columns: 1fr;
    }
}

.define-product__option {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-5);
    background-color: var(--color-card);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-card);
    box-shadow: 0 1px 2px rgb(30 39 66 / 4%), 0 4px 16px rgb(30 39 66 / 5%);

    & .btn {
        margin-top: auto;
        align-self: flex-start;
    }
}

.define-product__option-title {
    font-size: 17px;
    font-weight: 600;
    color: var(--color-ink);
}

.define-product__option-desc {
    font-size: var(--text-meta);
    color: var(--color-ink-soft);
}

.define-product__picker {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    margin-top: var(--space-6);
}

.define-product__pick {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    margin: 0;
    padding: var(--space-4) var(--space-5);
    background-color: var(--color-card);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-card);
}

.define-product__pick-name {
    font-weight: 600;
    color: var(--color-ink);
}

.define-product__empty {
    margin-top: var(--space-6);
    padding: var(--space-6);
    text-align: center;
    background-color: var(--color-surface-alt);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-card);

    & .btn {
        margin-top: var(--space-4);
    }
}

.define-product__back {
    margin-top: var(--space-6);
    font-size: var(--text-meta);
}

/* ── Pipeline view + phase pipeline component (Story 3.2, UX-DR8) ───────────── */
.pipeline-header {
    margin-top: var(--space-3);
}

.phase-pipeline {
    list-style: none;
    margin: var(--space-6) 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.phase-card {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: var(--space-4);
    padding: var(--space-5);
    background-color: var(--color-card);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-card);

    /* Current: accent border emphasis + tinted shadow, per the mockup. */
    &.phase-card--current {
        border: 1.5px solid var(--color-accent);
        box-shadow: 0 1px 2px rgb(30 39 66 / 4%), 0 8px 24px rgb(224 92 69 / 10%);
    }

    /* Locked-ahead: muted, no action. */
    &.phase-card--locked {
        background-color: var(--color-surface-alt);
        opacity: .85;
    }

    @media (width <= 720px) {
        grid-template-columns: auto 1fr;

        .phase-card__meta {
            grid-column: 1 / -1;
            flex-direction: row;
            align-items: center;
            justify-content: space-between;
        }
    }
}

/* Number/glyph circle — the "glyph" modality (paired with color + the text chip
   so status never relies on color alone). */
.phase-card__glyph {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: var(--radius-pill);
    font-size: var(--text-section);
    font-weight: 600;
    border: 1px solid transparent;

    &.phase-card__glyph--done {
        color: var(--color-status-done-text);
        background-color: var(--color-status-done-bg);
        border-color: var(--color-status-done-text);
    }

    &.phase-card__glyph--current {
        color: var(--color-card);
        background-color: var(--color-accent);
        box-shadow: 0 0 0 6px var(--color-accent-tint);
    }

    &.phase-card__glyph--skippable {
        color: var(--color-status-skippable-text);
        background-color: var(--color-status-skippable-bg);
        border-color: var(--color-line-strong);
    }

    &.phase-card__glyph--locked {
        color: var(--color-ink-mute);
        background-color: var(--color-status-locked-bg);
        border-color: var(--color-line-strong);
    }
}

.phase-card__dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: var(--radius-pill);
    background-color: var(--color-card);
}

.phase-card__name {
    font-size: var(--text-section);
    font-weight: 600;
    color: var(--color-ink);
    margin: 0;
}

.phase-card__desc {
    margin-top: var(--space-1);
    font-size: var(--text-meta);
    color: var(--color-ink-soft);
}

.phase-card__meta {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: var(--space-3);
}

.phase-card__locked-note {
    font-size: var(--text-meta);
    color: var(--color-ink-mute);
}

/* Skipped-research microcopy (Story 3.5) — calm note below the phase description. */
.phase-card__skipped-note {
    margin-top: var(--space-2);
    font-size: var(--text-meta);
    color: var(--color-ink-soft);
    font-style: italic;
}

/* ── Destructive unlock dialog (Story 3.6, UX-DR13, mockup 06) ─────────────── */

/* Native <dialog> sheet — showModal() provides top-layer stacking + ::backdrop scrim. */
.unlock-dialog {
    border: none;
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-modal);
    padding: 0;
    margin: auto;
    max-width: 480px;
    width: calc(100% - var(--space-6));
    overflow: hidden;
    color: var(--color-ink);

    &::backdrop {
        background-color: var(--color-scrim);
    }
}

/* Coral warning banner at the top of the dialog. */
.unlock-dialog__banner {
    background-color: var(--color-accent-tint);
    border-bottom: 1px solid #F3D6CD;
    padding: var(--space-5) var(--space-6);
    display: flex;
    align-items: center;
    gap: var(--space-4);
    font-size: var(--text-body);
    font-weight: 600;
    color: var(--color-accent-strong);
}

/* Coral "!" circle — visual emphasis on the warning banner. */
.unlock-dialog__bang {
    width: 38px;
    height: 38px;
    flex: none;
    border-radius: var(--radius-pill);
    background-color: var(--color-accent);
    color: var(--color-card);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: var(--text-section);
    font-weight: 700;
}

/* Dialog content area. */
.unlock-dialog__body {
    padding: var(--space-6);
}

.unlock-dialog__title {
    font-size: var(--text-section);
    font-weight: 600;
    margin: 0 0 var(--space-3);
    letter-spacing: -0.01em;
}

.unlock-dialog__desc {
    font-size: var(--text-label);
    line-height: 1.65;
    color: var(--color-ink-soft);
    margin-bottom: var(--space-5);
}

/* Itemized list of phases that will be discarded. */
.unlock-dialog__list {
    list-style: none;
    padding: var(--space-4);
    background-color: var(--color-surface-alt);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-inner);
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    margin-bottom: var(--space-5);
}

.unlock-dialog__item {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    font-size: var(--text-meta);
    color: var(--color-ink);

    /* Coral bullet dot before each list item. */
    &::before {
        content: "";
        display: inline-block;
        width: 7px;
        height: 7px;
        border-radius: var(--radius-pill);
        background-color: var(--color-accent);
        flex: none;
    }
}

.unlock-dialog__item-status {
    color: var(--color-ink-mute);
    font-weight: 500;
}

/* "This can't be undone" reassurance note. */
.unlock-dialog__caveat {
    font-size: var(--text-meta);
    color: var(--color-ink-mute);
    line-height: 1.55;
    margin-bottom: var(--space-6);
}

/* Cancel + confirm button row — equal width via flex. */
.unlock-dialog__actions {
    display: flex;
    gap: var(--space-3);
}

/* The <form> wrapper shares the flex space with the Cancel button. */
.unlock-dialog__confirm-form {
    flex: 1;
    display: flex;
}

/* Each button (and the confirm form) takes equal space. */
.unlock-dialog__cancel-btn,
.unlock-dialog__confirm-btn {
    flex: 1;
}

/* ── "Next phase" choice dialog (Brainstorming chat) ───────────────────────────
   Continue to Research vs. Skip to PRD. Native <dialog> + ::backdrop scrim, same
   chrome as .unlock-dialog but calm (no destructive banner). */
.phase-choice-dialog {
    border: none;
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-modal);
    padding: 0;
    margin: auto;
    max-width: 440px;
    width: calc(100% - var(--space-6));
    overflow: hidden;
    color: var(--color-ink);

    &::backdrop {
        background-color: var(--color-scrim);
    }
}

.phase-choice-dialog__body {
    padding: var(--space-6);
}

.phase-choice-dialog__title {
    font-size: var(--text-section);
    font-weight: 600;
    margin: 0 0 var(--space-3);
    letter-spacing: -0.01em;
}

.phase-choice-dialog__desc {
    font-size: var(--text-label);
    line-height: 1.65;
    color: var(--color-ink-soft);
    margin-bottom: var(--space-5);
}

/* Choices stack full-width so each reads as its own decision; each form's button
   fills the row. */
.phase-choice-dialog__actions {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);

    form {
        margin: 0;
        display: flex;
    }

    .btn {
        flex: 1;
    }
}

.phase-choice-dialog__cancel {
    width: 100%;
    margin-top: var(--space-3);
}

/* ── Dashboard project list + project row (Story 3.3, UX-DR10) ─────────────── */
.project-list-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: var(--space-8);
    margin-bottom: var(--space-4);
}

.project-list-count {
    font-size: var(--text-meta);
    font-weight: 500;
    color: var(--color-ink-mute);
}

.project-list {
    background-color: var(--color-card);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-card);
    box-shadow: 0 1px 2px rgb(30 39 66 / 4%), 0 4px 16px rgb(30 39 66 / 5%);
    overflow: hidden;
}

/* One full-width row; the whole row is the resume affordance (links to the
   Pipeline). Hover tints the row; the global accent focus-visible ring applies. */
.project-row {
    display: flex;
    align-items: center;
    gap: var(--space-5);
    padding: var(--space-4) var(--space-5);
    color: inherit;
    text-decoration: none;
    transition: background-color .15s ease;

    & + .project-row {
        border-top: 1px solid var(--color-line);
    }

    &:hover {
        background-color: var(--color-surface-alt);
        text-decoration: none;
    }
}

.project-row__main {
    flex: 1;
    min-width: 0;
}

.project-row__name {
    font-size: var(--text-body);
    font-weight: 600;
    color: var(--color-ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.project-row__meta {
    margin-top: var(--space-1);
    font-size: var(--text-meta);
    color: var(--color-ink-mute);
}

.project-row__chip {
    flex-shrink: 0;
    white-space: nowrap;
}

/* 4-segment progress bar — one segment per phase, tinted by its status. The bar
   is decorative (aria-hidden in the markup); the chip carries the textual state
   so status never relies on color alone (UX-DR24). */
.project-row__progress {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    gap: var(--space-1);
    width: 88px;
}

.progress-seg {
    flex: 1;
    height: 5px;
    border-radius: 3px;
    background-color: var(--color-line-strong);

    &.progress-seg--done {
        background-color: var(--color-status-done-text);
    }

    &.progress-seg--current {
        background-color: var(--color-status-current-text);
    }

    &.progress-seg--skippable {
        background-color: var(--color-status-skippable-text);
    }

    &.progress-seg--locked {
        background-color: var(--color-line-strong);
    }
}

@media (width <= 720px) {
    .project-row {
        flex-wrap: wrap;
        gap: var(--space-3);
    }

    .project-row__main {
        flex-basis: 100%;
    }
}

/* ── Empty / first-run project list (Story 3.3, UX-DR21) ───────────────────── */
.project-empty {
    margin-top: var(--space-8);
    padding: var(--space-6);
    text-align: center;
    background-color: var(--color-surface-alt);
    border: 1px dashed var(--color-line-strong);
    border-radius: var(--radius-card);
}

.project-empty__title {
    font-size: var(--text-section);
    font-weight: 600;
    color: var(--color-ink);
}

.project-empty__desc {
    margin-top: var(--space-2);
    font-size: var(--text-meta);
    color: var(--color-ink-soft);
}

/* ── Cold-load skeleton (Story 3.3, UX-DR20) ───────────────────────────────── */
.project-row--skeleton {
    pointer-events: none;
}

.skeleton-bar {
    display: inline-block;
    height: 12px;
    border-radius: var(--radius-control);
    background: linear-gradient(
        90deg,
        var(--color-line) 25%,
        var(--color-surface-alt) 37%,
        var(--color-line) 63%
    );
    background-size: 400% 100%;
    animation: skeleton-shimmer 1.4s ease infinite;

    &.skeleton-bar--name {
        width: 42%;
    }

    &.skeleton-bar--meta {
        width: 26%;
        height: 10px;
        margin-top: var(--space-2);
    }

    &.skeleton-bar--chip {
        width: 96px;
        height: 22px;
        border-radius: var(--radius-pill);
        flex-shrink: 0;
    }
}

@keyframes skeleton-shimmer {
    0% {
        background-position: 100% 50%;
    }

    100% {
        background-position: 0 50%;
    }
}

/* ── Pipeline rename form (Story 3.4) ───────────────────────────────────── */
.rename-form {
    margin-top: var(--space-4);
    margin-bottom: var(--space-3);

    .rename-form__field {
        display: flex;
        flex-direction: column;
        gap: var(--space-2);
    }

    .rename-form__label {
        font-size: 14px;
        line-height: 1.2;
        font-weight: 600;
        color: var(--color-ink-soft);
    }

    .rename-form__row {
        display: flex;
        gap: var(--space-2);
        align-items: center;
    }

    .rename-form__input {
        flex: 1 1 0;
        height: 44px;
        padding: 0 var(--space-4);
        border: 1px solid var(--color-line-strong);
        border-radius: var(--radius-control);
        background-color: var(--color-card);
        font-size: var(--text-body);
        color: var(--color-ink);

        &::placeholder {
            color: var(--color-ink-mute);
        }

        &:focus-visible {
            border-color: var(--color-accent);
        }

        &.rename-form__input--invalid {
            border-color: var(--color-status-current-text);
        }
    }

    .rename-form__btn {
        flex-shrink: 0;
    }

    /* Calm coral error — non-blaming, matches the .field__error pattern */
    .rename-form__error {
        font-size: 13px;
        line-height: 1.4;
        font-weight: 600;
        color: var(--color-status-current-text);
    }
}

/* ── Accessibility utility ──────────────────────────────────────────────── */
/* Visually hidden but available to assistive tech (the standard clip pattern). */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ── Chat / working session (Story 4.1, mockup 04) ──────────────────────── */
.chat {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    min-height: 0;

    /* Connection status (ARIA live region) — quiet, only visible when populated. */
    .chat__status {
        min-height: 1em;
        font-size: var(--text-meta);
        font-style: italic;
        color: var(--color-ink-mute);
    }

    /* Scrollable message thread, centered column. */
    .chat__thread {
        display: flex;
        flex-direction: column;
        gap: var(--space-4);
        width: 100%;
        max-width: 720px;
        margin: 0 auto;
        padding: var(--space-2) 0;
        overflow-y: auto;
    }

    /* Saved artifacts (Story 4.4) — calm, auto-saved; no manual save action. */
    .chat__artifacts {
        width: 100%;
        max-width: 720px;
        margin: var(--space-2) auto 0;
    }

    .chat__artifacts-title {
        margin: 0 0 var(--space-2);
        font-size: var(--text-meta);
        font-weight: 600;
        color: var(--color-ink-mute);
    }

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

    .chat__artifact {
        display: flex;
        align-items: center;
        gap: var(--space-2);
        padding: var(--space-2) var(--space-3);
        border-radius: var(--radius-inner);
        background: var(--color-surface-alt);
        border: 1px solid var(--color-line);
        font-size: var(--text-label);
        color: var(--color-ink-soft);
    }

    /* Live "Saved: …" fragment appended to the thread when an artifact lands. */
    .artifact-saved {
        align-self: center;
        font-size: var(--text-meta);
        font-style: italic;
        color: var(--color-ink-mute);
    }

    /* In-context promotion (Story 4.7) — "Use this to define a product". A calm
       forward action shown below a completed brainstorm; reuses the .btn--primary
       CTA so it reads as the affirmative next step without new button chrome. */
    .chat__promote-wrap {
        width: 100%;
        max-width: 720px;
        margin: var(--space-4) auto 0;
        text-align: center;
    }

    .chat__promote {
        margin: 0;
    }

    .chat__promote-helper {
        margin: var(--space-2) 0 0;
        font-size: var(--text-meta);
        color: var(--color-ink-soft);
    }

    /* Assistant message — neutral avatar + light bubble.
       Holds Markdown rendered to HTML (server-side, see MarkdownRenderer): the nested
       rules below give those elements sensible rhythm within the bubble. */
    .agent-message {
        display: block;
        padding: var(--space-4);
        border-radius: var(--radius-inner);
        background: var(--color-card);
        border: 1px solid var(--color-line);
        box-shadow: var(--shadow-card);
        font-size: var(--text-label);
        line-height: 1.65;
        color: var(--color-ink);

        /* Collapse the outer margins so the bubble padding stays even. */
        > :first-child {
            margin-top: 0;
        }

        > :last-child {
            margin-bottom: 0;
        }

        p {
            margin: 0 0 var(--space-3);
        }

        h1,
        h2,
        h3,
        h4,
        h5,
        h6 {
            margin: var(--space-4) 0 var(--space-2);
            font-weight: 700;
            line-height: 1.3;
            color: var(--color-ink);
        }

        h1 {
            font-size: 1.4em;
        }

        h2 {
            font-size: 1.25em;
        }

        h3 {
            font-size: 1.1em;
        }

        h4,
        h5,
        h6 {
            font-size: 1em;
        }

        ul,
        ol {
            margin: 0 0 var(--space-3);
            padding-left: var(--space-5);
        }

        ul {
            list-style: disc;
        }

        ol {
            list-style: decimal;
        }

        li {
            margin: var(--space-1) 0;
        }

        /* Nested lists hug their parent item. */
        li > ul,
        li > ol {
            margin: var(--space-1) 0 0;
        }

        a {
            color: var(--color-accent);
            text-decoration: none;

            &:hover {
                text-decoration: underline;
            }
        }

        strong {
            font-weight: 700;
        }

        em {
            font-style: italic;
        }

        /* Inline code — subtle tinted chip. */
        code {
            padding: 0.1em 0.35em;
            border-radius: var(--radius-pill);
            background: var(--color-accent-tint);
            font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
            font-size: 0.875em;
        }

        /* Fenced code block — padded, scrollable, no chip styling on inner code. */
        pre {
            margin: 0 0 var(--space-3);
            padding: var(--space-3);
            border-radius: var(--radius-inner);
            background: var(--color-ink);
            color: var(--color-card);
            overflow-x: auto;

            code {
                padding: 0;
                background: none;
                color: inherit;
                font-size: 0.85em;
            }
        }

        blockquote {
            margin: 0 0 var(--space-3);
            padding-left: var(--space-3);
            border-left: 3px solid var(--color-line);
            color: var(--color-ink-soft);
        }

        hr {
            margin: var(--space-4) 0;
            border: 0;
            border-top: 1px solid var(--color-line);
        }

        table {
            width: 100%;
            margin: 0 0 var(--space-3);
            border-collapse: collapse;
            font-size: 0.95em;
        }

        th,
        td {
            padding: var(--space-2) var(--space-3);
            border: 1px solid var(--color-line);
            text-align: left;
        }

        th {
            font-weight: 700;
            background: var(--color-accent-tint);
        }
    }

    /* User message — accent-tinted bubble, aligned to the trailing edge. */
    .user-message {
        align-self: flex-end;
        max-width: 80%;
        padding: var(--space-4);
        border-radius: var(--radius-inner);
        background: var(--color-accent-tint);
        font-size: var(--text-label);
        line-height: 1.65;
        color: var(--color-ink);
        white-space: pre-wrap;

        /* Optimistic « Pièce jointe : … » lines echoed with the sent bubble. */
        .user-message__attachment {
            font-size: var(--text-meta);
            color: var(--color-ink-mute);
        }
    }

    /* Blinking caret shown while the assistant streams; removed at terminal status. */
    .agent-caret {
        display: inline-block;
        width: 2px;
        height: 1.1em;
        margin-left: 2px;
        vertical-align: text-bottom;
        background: var(--color-accent);
        animation: chat-caret-blink 1s step-end infinite;
    }

    /* Narrated status line (streamed session.status events). */
    /* Interim run status (working…/running/idle) exists only to drive the working
       indicator — it must never render as a visible thread row. The chat-stream
       controller reads the terminal status from the Mercure event payload, not the
       DOM, so hiding these appended fragments is safe. */
    .session-status {
        display: none;
    }

    /* Tool-use trace (streamed agent.tool_use events). */
    /* "Using …" rows are progress noise for a non-technical audience — the working
       indicator already conveys forward motion. Hidden the same way as .session-status
       so the appended fragments never render as visible thread rows. */
    .agent-tool-use {
        display: none;
    }

    /* Calm, reassuring error — never a stack trace (EXPERIENCE.md). */
    .session-error {
        padding: var(--space-3) var(--space-4);
        border-radius: var(--radius-inner);
        background: var(--color-accent-tint);
        font-size: var(--text-label);
        color: var(--color-status-current-text);
    }

    .chat__working {
        display: flex;
        align-items: center;
        gap: var(--space-3);
        max-width: 720px;
        margin: 0 auto;
        width: 100%;

        /* Respect the [hidden] attribute. A bare `display: flex` overrides the UA
           `[hidden] { display: none }` (equal specificity → author rule wins), which
           kept the indicator permanently on screen. The composer reveals it on send and
           the chat-stream controller hides it again on a terminal status. */
        &[hidden] {
            display: none;
        }
    }

    .chat__working-dot {
        width: 10px;
        height: 10px;
        flex: none;
        border-radius: var(--radius-pill);
        background: var(--color-accent);
        animation: chat-calmpulse 1.4s ease-in-out infinite;
    }

    .chat__working-label {
        font-size: var(--text-meta);
        font-weight: 600;
        color: var(--color-ink-mute);
    }
}

.chat__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    padding: var(--space-4);
    padding-left: var(--space-5);
    border-bottom: 1px solid var(--color-line);
    position: sticky;
    top: 0;
    backdrop-filter: blur(8px);

    .chat__heading, .chat__actions {
        display: flex;
        align-items: center;
        gap: var(--space-4);
    }

    /* Phase badge — neutral, calm; distinct from status chips. */
    .chat__phase-badge {
        flex: none;
        padding: var(--space-1) var(--space-3);
        border-radius: var(--radius-pill);
        background: var(--color-surface-alt);
        border: 1px solid var(--color-line);
        font-size: var(--text-chip);
        font-weight: 600;
        color: var(--color-ink-soft);
    }
}



/* Bottom-docked composer. */
.composer {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--space-3);
    width: 100%;
    max-width: 720px;
    margin: 0 auto;
    padding: var(--space-3);
    border-radius: calc(var(--radius-control) + var(--space-3));
    background: var(--color-card);
    border: 1px solid var(--color-line-strong);
    box-shadow: var(--shadow-card);

    /* Selected-attachment chips — a full-width row ABOVE the input (order -1),
       collapsed entirely while empty so the composer keeps its one-line shape. */
    .composer__attachments {
        order: -1;
        flex-basis: 100%;
        display: flex;
        flex-wrap: wrap;
        gap: var(--space-2);

        &:empty {
            display: none;
        }
    }

    .composer__chip {
        display: inline-flex;
        align-items: center;
        gap: var(--space-2);
        max-width: 100%;
        padding: var(--space-1) var(--space-2);
        border-radius: var(--radius-control);
        border: 1px solid var(--color-line-strong);
        background: var(--color-accent-tint);
        font-size: var(--text-meta);
        color: var(--color-ink);

        .composer__chip-name {
            max-width: 220px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        .composer__chip-size {
            color: var(--color-ink-mute);
        }

        .composer__chip-remove {
            border: none;
            background: transparent;
            padding: 0;
            font-size: 11px;
            line-height: 1;
            color: var(--color-ink-mute);
            cursor: pointer;

            &:hover {
                color: var(--color-ink);
            }
        }
    }

    /* Calm inline pre-validation message (fichier trop lourd / type refusé) —
       full-width row under the controls, mirrors the .field__error coral. */
    .composer__error {
        order: 10;
        flex-basis: 100%;
        margin: 0;
        font-size: var(--text-meta);
        font-weight: 600;
        color: var(--color-status-current-text);
    }

    /* Paperclip — ghost sibling of the send button. */
    .composer__attach {
        flex: none;
        width: 48px;
        height: 48px;
        display: flex;
        align-items: center;
        justify-content: center;
        border: none;
        border-radius: var(--radius-control);
        background: transparent;
        color: var(--color-ink-mute);
        cursor: pointer;

        &:hover {
            background: var(--color-accent-tint);
            color: var(--color-ink);
        }
    }

    .composer__input {
        flex: 1 1 auto;
        resize: none;
        border: none;
        outline: none;
        background: transparent;
        font-family: inherit;
        font-size: var(--text-label);
        line-height: 16px;
        color: var(--color-ink);
        field-sizing: content;
        border-radius: var(--radius-control);
        padding: var(--space-2);
        min-height: 48px;

        &::placeholder {
            color: var(--color-ink-mute);
        }

        &:disabled {
            cursor: not-allowed;
        }
    }

    .composer__send {
        flex: none;
        width: 48px;
        height: 48px;
        display: flex;
        align-items: center;
        justify-content: center;
        border: none;
        border-radius: var(--radius-control);
        background: var(--color-accent);
        color: var(--color-card);
        font-size: 18px;
        font-weight: 700;
        cursor: pointer;

        &:hover {
            background: var(--color-accent-strong);
        }

        &:disabled {
            opacity: .5;
            cursor: not-allowed;
        }
    }
}

.composer__helper {
    max-width: 720px;
    margin: var(--space-2) auto 0;
    width: 100%;
    font-size: var(--text-meta);
    color: var(--color-ink-mute);
    text-align: center;
}

@keyframes chat-calmpulse {
    0%, 100% { opacity: .35; transform: scale(.8); }
    50% { opacity: 1; transform: scale(1); }
}

/* Caret blink. Starts visible and ends visible (opacity 1 at 0%/100%) so that
   under prefers-reduced-motion — where the global rule pins iteration-count to 1 —
   the caret settles as a steady, visible bar rather than disappearing. */
@keyframes chat-caret-blink {
    0%, 50%, 100% { opacity: 1; }
    51%, 99% { opacity: 0; }
}

/* ── Export screen + export cards (Story 5.1, UX-DR14, mockup 07) ──────────── */

/* Header zone of the Pipeline view: eyebrow on the left, Export action on the right. */
.pipeline-header__top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
}

/* Export action in the Chat header — sits beside the phase badge, never pushes
   the layout (the header is a flex row with align-items: flex-start). */
.chat__export {
    flex: none;
}

/* Back link above the Export screen title (mirrors the chat back link tone). */
.export-back {
    display: inline-block;
    font-size: var(--text-meta);
    font-weight: 600;
    color: var(--color-ink-mute);
    text-decoration: none;
    margin-bottom: var(--space-4);

    &:hover {
        color: var(--color-ink-soft);
    }
}

.export-header {
    margin-top: var(--space-1);
}

.export-intro {
    color: var(--color-ink-soft);
    max-width: 580px;
    margin: var(--space-2) 0 var(--space-6);
}

/* Saved-artifacts list (Story 5.4) — calm rows: name + phase/date meta on the
   left, a download action on the right. Sober, structured; reuses tokens. */
.artifact-empty {
    color: var(--color-ink-soft);
    max-width: 580px;
}

.artifact-list {
    list-style: none;
    margin: 0 0 var(--space-6);
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.artifact-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    padding: var(--space-4);
    background-color: var(--color-card);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-card);

    & .artifact-row__main {
        display: flex;
        flex-direction: column;
        gap: var(--space-1);
        min-width: 0;
    }

    & .artifact-row__name {
        font-weight: 600;
        color: var(--color-ink);
        overflow-wrap: anywhere;
    }

    & .artifact-row__meta {
        font-size: var(--text-meta);
        color: var(--color-ink-mute);
    }

    & .artifact-row__dot {
        margin: 0 var(--space-1);
    }

    & .artifact-row__action {
        flex-shrink: 0;
    }
}

/* Two side-by-side cards; collapse to one column on narrow widths (mirrors
   .phase-card's responsive pattern). */
.export-cards {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-4);
    margin-bottom: var(--space-5);

    @media (width <= 720px) {
        grid-template-columns: 1fr;
    }
}

.export-card {
    display: flex;
    flex-direction: column;
    padding: var(--space-6);
    background-color: var(--color-card);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);

    .export-card__top {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-bottom: var(--space-4);
    }

    /* Icon disc — tinted per audience (accent for client, blue for dev). */
    .export-card__icon {
        width: 50px;
        height: 50px;
        border-radius: var(--radius-inner);

        &.export-card__icon--client_brief {
            background-color: var(--color-accent-tint);
        }

        &.export-card__icon--dev_handoff {
            background-color: var(--color-status-skippable-bg);
        }
    }

    /* Audience badge — a pill on the chip token scale, tinted per audience. */
    .export-card__badge {
        &.export-card__badge--client_brief {
            color: var(--color-status-current-text);
            background-color: var(--color-status-current-bg);
        }

        &.export-card__badge--dev_handoff {
            color: var(--color-status-skippable-text);
            background-color: var(--color-status-skippable-bg);
        }
    }

    .export-card__title {
        font-size: var(--text-section);
        font-weight: 600;
        margin-bottom: var(--space-1);
    }

    .export-card__desc {
        color: var(--color-ink-soft);
        margin-bottom: var(--space-4);
    }

    .export-card__contents {
        list-style: none;
        margin: 0 0 var(--space-5);
        padding: 0;
        display: flex;
        flex-direction: column;
        gap: var(--space-2);
    }

    .export-card__content-item {
        display: flex;
        align-items: center;
        gap: var(--space-2);
        font-size: var(--text-label);
        color: var(--color-ink-soft);
    }

    .export-card__check {
        color: var(--color-status-done-text);
        font-weight: 700;
    }

    /* Footer pinned to the card bottom so the two cards align (mockup 07). */
    .export-card__footer {
        margin-top: auto;
    }

    .export-card__format {
        font-size: var(--text-meta);
        color: var(--color-ink-mute);
        margin-bottom: var(--space-3);
    }

    /* Both export actions are CSRF POST forms (dev_handoff — Story 5.2;
       client_brief — Story 5.3); keep the button full-width inside the <form>. */
    .export-card__footer form {
        margin: 0;
    }

    .export-card__action {
        width: 100%;

        &:disabled {
            opacity: .55;
            cursor: not-allowed;
        }
    }

    /* Calm "not yet" note — conveys unavailability by TEXT, not color alone. */
    .export-card__unavailable-note {
        margin-top: var(--space-2);
        font-size: var(--text-meta);
        color: var(--color-ink-soft);
        text-align: center;
    }
}

/* Reassurance row beneath the cards. */
.export-reassurance {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    background-color: var(--color-surface-alt);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-inner);
    padding: var(--space-4) var(--space-5);

    .export-reassurance__mark {
        flex: none;
        width: 22px;
        height: 22px;
        border-radius: var(--radius-pill);
        border: 2px solid var(--color-ink-mute);
        color: var(--color-ink-mute);
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: var(--text-meta);
        font-weight: 700;
    }

    .export-reassurance__text {
        font-size: var(--text-label);
        color: var(--color-ink-soft);
        line-height: 1.5;
    }
}

/* ── Story 5.2: dev-bundle export progress (AC4 — never goes dark) ─────────── */
/* The worker streams export.* Turbo Streams into #export-output: a calm
   "Preparing…" status, a ready-to-download link, or a reassuring error note. */
.export-progress {
    margin-top: var(--space-5);

    .export-output {
        &:empty {
            display: none;
        }

        display: flex;
        flex-direction: column;
        gap: var(--space-3);
        padding: var(--space-4) var(--space-5);
        border: 1px solid var(--color-line);
        border-radius: var(--radius-inner);
        background-color: var(--color-surface-alt);
        font-size: var(--text-label);
        color: var(--color-ink-soft);
    }

    .export-status {
        color: var(--color-ink-soft);
    }

    .export-ready {
        font-weight: 600;
        color: var(--color-accent);
    }

    /* Calm note, not an alarming banner — mirrors the chat .session-error cues. */
    .export-error {
        color: var(--color-status-current-text);
    }
}

/* ── Personal Usage view (Story 6.2, FR3, mockup 08) ───────────────────────
   A calm, qualitative usage-card: month label + reassurance pill, a thin %
   bar (the single accent focal element), and a 3-up row of stat tiles. The
   card holds its shape with zero data (no layout jump). Token-driven only. */
.usage-intro {
    margin-top: var(--space-3);
    max-width: 560px;
    color: var(--color-ink-soft);
}

.usage-card {
    margin-top: var(--space-6);
    padding: var(--space-5);
    background-color: var(--color-card);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);

    .usage-card__head {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--space-3);
        flex-wrap: wrap;
        margin-bottom: var(--space-4);
    }

    .usage-card__month {
        margin: 0;
    }

    .usage-card__caption {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--space-3);
        margin-top: var(--space-3);
    }

    .usage-card__caption-text {
        color: var(--color-ink-mute);
    }

    .usage-card__percent {
        font-weight: 600;
        color: var(--color-ink-soft);
    }
}

/* Reassurance pill — qualitative, never an alarm. All three tones are calm
   status-tints (no accent/red): visibility-only, no caps (PRD Open Item B). */
.usage-pill {
    font-size: var(--text-chip);
    font-weight: 600;
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-pill);
    white-space: nowrap;

    &.usage-pill--calm {
        color: var(--color-status-done-text);
        background-color: var(--color-status-done-bg);
    }

    &.usage-pill--steady {
        color: var(--color-status-skippable-text);
        background-color: var(--color-status-skippable-bg);
    }

    &.usage-pill--busy {
        color: var(--color-status-locked-text);
        background-color: var(--color-status-locked-bg);
    }
}

/* The thin % bar — the one focal accent element on this view. */
.usage-bar {
    height: 12px;
    border-radius: var(--radius-pill);
    background-color: var(--color-surface-alt);
    border: 1px solid var(--color-line);
    overflow: hidden;

    .usage-bar__fill {
        height: 100%;
        border-radius: var(--radius-pill);
        background-color: var(--color-accent);
        transition: width .2s ease;
    }
}

/* Stat tiles — large ink number + ink-mute label. Mirrors the .start-tiles
   3-up grid shape (collapses to 1 column on narrow screens). */
.usage-tiles {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-4);
    margin-top: var(--space-4);

    @media (width <= 720px) {
        grid-template-columns: 1fr;
    }
}

.usage-tile {
    padding: var(--space-5);
    background-color: var(--color-card);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-card);
    box-shadow: 0 1px 2px rgb(30 39 66 / 4%);

    .usage-tile__value {
        font-size: var(--text-page-title);
        font-weight: 600;
        letter-spacing: -0.02em;
        color: var(--color-ink);
    }

    .usage-tile__label {
        margin-top: var(--space-1);
        font-size: var(--text-label);
        color: var(--color-ink-soft);
    }
}

/* ── Admin roster (Story 6.3) ───────────────────────────────────────────── */
/* The team roster: invite affordance + a horizontally-scrollable table of every
   user + pending invite. Accent is reserved for the single "Invite someone"
   primary button; status chips reuse the existing .chip--done/skippable/locked
   tints (see the Status chip block). Token-driven; no inline hex. */
.admin-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-5);

    @media (width <= 720px) {
        flex-direction: column;
    }
}

.admin-invite {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex: none;

    .admin-invite__email {
        height: 44px;
        padding: 0 var(--space-3);
        border: 1px solid var(--color-line-strong);
        border-radius: var(--radius-control);
        font-family: inherit;
        font-size: var(--text-label);
        color: var(--color-ink);
        background-color: var(--color-card);

        &::placeholder {
            color: var(--color-ink-mute);
        }

        &:focus-visible {
            outline: none;
            border-color: var(--color-accent);
            box-shadow: 0 0 0 3px var(--color-accent-tint);
        }
    }

    /* The one focal accent element on this view (DESIGN.md — keep red rare). */
    .admin-invite__submit {
        height: 44px;
        padding: 0 var(--space-4);
        border: none;
        border-radius: var(--radius-control);
        font-family: inherit;
        font-size: var(--text-label);
        font-weight: 600;
        color: var(--color-card);
        background-color: var(--color-accent-button);
        cursor: pointer;

        &:hover {
            background-color: var(--color-accent-button-hover);
        }

        &:focus-visible {
            outline: none;
            box-shadow: 0 0 0 3px var(--color-accent-tint);
        }
    }
}

.admin-intro {
    margin-top: var(--space-2);
    margin-bottom: var(--space-6);
    max-width: 560px;
    font-size: var(--text-body);
    line-height: 1.6;
    color: var(--color-ink-soft);
}

.admin-notice {
    margin-bottom: var(--space-4);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-inner);
    font-size: var(--text-label);

    &.admin-notice--ok {
        color: var(--color-status-done-text);
        background-color: var(--color-status-done-bg);
    }

    &.admin-notice--err {
        color: var(--color-status-current-text);
        background-color: var(--color-status-current-bg);
    }
}

/* App-wide calm flash region (F3) — generic feedback for skip/add/unlock and
   optimistic-lock conflicts, rendered by layout/app.html.twig above the content.
   Mirrors .admin-notice's calm status colours. */
.app-flashes {
    margin-bottom: var(--space-4);
}

.app-flash {
    margin-bottom: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-inner);
    font-size: var(--text-label);

    &:last-child {
        margin-bottom: 0;
    }

    &.app-flash--ok {
        color: var(--color-status-done-text);
        background-color: var(--color-status-done-bg);
    }

    &.app-flash--err {
        color: var(--color-status-current-text);
        background-color: var(--color-status-current-bg);
    }
}

.admin-table-wrap {
    overflow-x: auto;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-card);
    background-color: var(--color-card);
    box-shadow: var(--shadow-card);
}

.admin-table {
    width: 100%;
    min-width: 680px;
    border-collapse: collapse;

    th,
    td {
        padding: var(--space-4) var(--space-5);
        text-align: left;
        vertical-align: middle;
    }

    thead th {
        font-size: var(--text-chip);
        font-weight: 600;
        letter-spacing: 0.04em;
        text-transform: uppercase;
        color: var(--color-ink-mute);
        background-color: var(--color-surface-alt);
        border-bottom: 1px solid var(--color-line);
    }

    .admin-table__access {
        text-align: right;
    }

    tbody tr {
        border-bottom: 1px solid var(--color-line);

        &:last-child {
            border-bottom: none;
        }
    }

    .admin-row--muted {
        .admin-person__name,
        .admin-person__email {
            color: var(--color-ink-mute);
        }
    }
}

.admin-table__person {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}

.admin-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 38px;
    height: 38px;
    border-radius: var(--radius-pill);
    font-size: var(--text-label);
    font-weight: 700;
    color: var(--color-status-skippable-text);
    background-color: var(--color-status-skippable-bg);
}

.admin-person {
    display: flex;
    flex-direction: column;
    min-width: 0;

    .admin-person__name {
        font-size: var(--text-label);
        font-weight: 600;
        color: var(--color-ink);
    }

    .admin-person__you {
        font-size: var(--text-chip);
        font-weight: 600;
        color: var(--color-ink-mute);
    }

    .admin-person__email {
        font-size: var(--text-chip);
        color: var(--color-ink-mute);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
}

.admin-dash {
    color: var(--color-line-strong);
    font-weight: 600;
}

/* The per-user "This month" usage figure (Story 6.4) — a thin NEUTRAL comfort
   bar + a one-word qualitative label. Informational and calm: it deliberately
   does NOT use --color-accent (reserved for the single "Invite someone" button)
   and never signals an alarm (visibility-only, no caps). */
.admin-usage {
    display: flex;
    align-items: center;
    gap: var(--space-2);

    .admin-usage__bar {
        flex: 1;
        min-width: 70px;
        max-width: 120px;
        height: 7px;
        border-radius: var(--radius-pill);
        background-color: var(--color-status-locked-bg);
        overflow: hidden;
    }

    .admin-usage__fill {
        display: block;
        height: 100%;
        border-radius: var(--radius-pill);
        background-color: var(--color-status-skippable-text);
    }

    .admin-usage__label {
        font-size: var(--text-chip);
        color: var(--color-ink-mute);
        white-space: nowrap;
    }
}

.admin-access-btn {
    border: none;
    background: none;
    padding: 0;
    font-family: inherit;
    font-size: var(--text-chip);
    font-weight: 600;
    color: var(--color-ink-mute);
    cursor: pointer;

    &:hover {
        color: var(--color-ink-soft);
    }

    /* Enable reads as a positive re-activation — tint it the interactive blue. */
    &.admin-access-btn--link {
        color: var(--color-status-skippable-text);

        &:hover {
            color: var(--color-status-skippable-text);
        }
    }

    &:focus-visible {
        outline: none;
        border-radius: var(--radius-control);
        box-shadow: 0 0 0 3px var(--color-accent-tint);
    }
}

/* ── Motion ─────────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }
}
