/* ============================================
   CUTTLEFISH BRAND STYLES
   Architectural Analyticism • Warm Minimalism
   ============================================ */

/* === TYPOGRAPHY === */

@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@300;400;500;600&family=Inter:wght@300;400;500;600;700&family=Lora:ital,wght@0,400;0,500;0,600;1,400;1,500&display=swap');

:root {
    /* Typography */
    --font-mono: 'IBM Plex Mono', 'Courier New', monospace;
    --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    --font-serif: 'Lora', Georgia, 'Times New Roman', serif;

    /* Color Palette — Black on cream, red for annotations */
    --color-bg-cream: #FAF9F6;
    --color-bg-white: #FFFFFF;
    --color-bg-warm-gray: #F5F4F1;

    --color-text-black: #1A1A1A;
    --color-text-charcoal: #2D2D2D;
    --color-text-gray: #5A5A5A;
    --color-text-light-gray: #8A8A8A;

    --color-border-dark: #3A3A3A;
    --color-border-medium: #C4C4C4;
    --color-border-light: #E5E5E5;

    /* Red annotation family — full 4-tier ladder from moodboard #11 red-scale study.
       Used like an architect's red pen: crimson primary, oxblood for emphasis,
       bright for hover/active, rose for pale tints, subtle for background washes. */
    --color-annotation: #B91C1C;
    --color-annotation-deep: #7F1D1D;
    --color-annotation-active: #DC2626;
    --color-annotation-muted: #991B1B;
    --color-annotation-rose: #FECACA;
    --color-annotation-subtle: rgba(185, 28, 28, 0.08);

    /* Legacy --accent aliases (kept so existing templates don't break — prefer --color-annotation-* in new code) */
    --color-accent: var(--color-annotation);
    --color-accent-light: var(--color-annotation-active);
    --color-accent-dark: var(--color-annotation-deep);
    --color-accent-muted: var(--color-annotation-muted);
    --color-accent-subtle: var(--color-annotation-subtle);

    /* Cobalt reference — cross-references, link states, alternate annotation paths
       (moodboard #12 / #13 / cover) */
    --color-reference: #1E3A8A;
    --color-reference-subtle: rgba(30, 58, 138, 0.08);

    /* Ochre — in-progress/development status, secondary structural line
       (moodboard #13 / #15 / cover, replaces former warm gold) */
    --color-ochre: #92400E;
    --color-ochre-light: #B45309;

    /* Technical grid */
    --grid-size: 8px;

    /* Button radius — subtle rounding per brand rule (square elsewhere) */
    --radius-btn: 2px;

    /* Status — muted earth tones (moodboard pass) */
    --color-status-operational: #5C7A3E;
    --color-status-development: var(--color-ochre);
    --color-status-offline: var(--color-annotation);
    /* Stale: warm grey 500-ish — "needs re-verification, not broken".
       NOT red (annotation reserved for VALUE), NOT ochre (development
       already owns it). Sits between --color-text-light-gray (#8A8A8A)
       and --color-border-medium (#C4C4C4) — subdued, attention-without-alarm.
       See issue #333, §Decisions row 4. */
    --color-status-stale: #A39B8E;

    /* Spacing scale (8px base) */
    --space-xs: calc(var(--grid-size) * 1);
    --space-sm: calc(var(--grid-size) * 2);
    --space-md: calc(var(--grid-size) * 3);
    --space-lg: calc(var(--grid-size) * 4);
    --space-xl: calc(var(--grid-size) * 6);
    --space-2xl: calc(var(--grid-size) * 8);
    --space-3xl: calc(var(--grid-size) * 12);

    /* Motion — single brand easing curve (ease-out-expo). Premium products
       decelerate softly; never bounce or elastic. Use --ease-brand for any
       state transition that should feel intentional rather than mechanical. */
    --ease-brand: cubic-bezier(0.16, 1, 0.3, 1);
    --duration-fast: 150ms;
    --duration-base: 200ms;
}

/* === GLOBAL POLISH === */

html {
    /* Anchor jumps animate; keyboard PgUp/PgDn still hard-snap */
    scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
}

/* Highlight color matches the architect's pen — rose plate on cream */
::selection {
    background: var(--color-annotation-rose);
    color: var(--color-text-black);
}

/* === BASE === */

body {
    font-family: var(--font-sans);
    font-weight: 400;
    color: var(--color-text-charcoal);
    background-color: var(--color-bg-cream);
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

code, kbd, samp, pre {
    font-family: var(--font-mono);
}

/* === HEADINGS ===

   Brand voice shift: Lora serif is the PRIMARY heading typeface for ALL
   semantic levels (h1–h6). The unified serif system pulls the brand
   decisively toward "research journal" rather than "SaaS dashboard"; the
   hierarchy is created by size and leading, not by typeface swap.

   Typesetting:
   - 500 weight reads substantial without being shouty (Lora 500 ≈ Inter 600)
   - Tight leading (1.05–1.3) treats display headlines as objects, not paragraphs
   - Negative tracking at larger sizes — serifs at display size need to close up
   - text-wrap: balance distributes line lengths evenly (last-line orphans gone)
   - font-feature-settings enables true kerning + ligatures Lora ships
   - font-optical-sizing: auto picks the right cut where the variable font allows

   Inter sans is still available for headings via the `.heading-sans` opt-out
   class — use sparingly for utility surfaces (forms, dashboards) where the
   serif voice would feel mismatched.
*/

h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-serif);
    font-weight: 500;
    color: var(--color-text-black);
    text-wrap: balance;
    font-feature-settings: "kern", "liga", "calt";
    font-optical-sizing: auto;
}

/* Display sizes — defaults for hero and section headings.
   Templates can override via inline style for sub-page contexts. */
h1 {
    font-size: 3rem;          /* 48px */
    line-height: 1.08;
    letter-spacing: -0.02em;
}

h2 {
    font-size: 2rem;          /* 32px */
    line-height: 1.18;
    letter-spacing: -0.015em;
}

h3 {
    font-size: 1.5rem;        /* 24px */
    line-height: 1.25;
    letter-spacing: -0.01em;
}

h4 {
    font-size: 1.25rem;       /* 20px */
    line-height: 1.3;
    letter-spacing: -0.005em;
}

h5 {
    font-size: 1.0625rem;     /* 17px */
    line-height: 1.35;
}

h6 {
    font-size: 1rem;          /* 16px */
    line-height: 1.4;
}

/* Sans opt-out — for utility surfaces (dashboards, forms, operator tools)
   where the editorial serif feels mismatched. */
.heading-sans,
h1.heading-sans, h2.heading-sans, h3.heading-sans,
h4.heading-sans, h5.heading-sans, h6.heading-sans {
    font-family: var(--font-sans);
    font-weight: 600;
}

/* Italic display variant — opt-in for hero moments where the brand wants
   the most editorial register. Pairs Lora italic 500 with extra leading
   to let the slope breathe. Use sparingly — one per page max. */
.heading-display-italic,
h1.heading-display-italic,
h2.heading-display-italic {
    font-family: var(--font-serif);
    font-style: italic;
    font-weight: 500;
    line-height: 1.05;
    letter-spacing: -0.022em;
}

/* Body paragraphs — text-wrap: pretty smooths last-line ragging without
   the layout-cost of `balance`. Safe to apply globally on p. */
p {
    text-wrap: pretty;
}

/* === INLINE EDITORIAL — em, strong, body links, code chips ===

   These rules give the brand voice somewhere to land when templates use
   ordinary HTML elements. The pattern mirrors impeccable.style:
   one accent color (red), used for italic emphasis and inline code highlights;
   strong stays neutral but heavier; body links carry a hairline underline
   (architectural/editorial reference, not no-underline). */

em {
    font-style: italic;
    color: var(--color-annotation);
}

strong, b {
    font-weight: 600;
    color: var(--color-text-black);
}

/* Inline code chip — red @ 12% alpha background, deep-red text.
   Scoped to NOT touch <code> inside <pre> (which is .brand-code, dark theme). */
:not(pre) > code {
    font-family: var(--font-mono);
    font-size: 0.875em;
    padding: 0.1em 0.4em;
    background: rgba(185, 28, 28, 0.10);
    color: var(--color-annotation-deep);
    border-radius: 2px;
    white-space: nowrap;
}

/* Body-context links — red text + hairline underline. Scoped to article-like
   contexts so we don't override the dozens of styled link components
   (.btn-brand, .nav-brand__link, .footer-link, .episode-card, etc.).

   The :where() wrapper keeps specificity at 0,1,0 — same as a single class —
   so component classes always win without needing !important. */
:where(.prose, .editorial, .briefing-body, article) a:not([class]) {
    color: var(--color-annotation);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 0.2em;
    text-decoration-color: rgba(185, 28, 28, 0.35);
    transition: text-decoration-color var(--duration-fast) var(--ease-brand),
                color var(--duration-fast) var(--ease-brand);
}

:where(.prose, .editorial, .briefing-body, article) a:not([class]):hover {
    color: var(--color-annotation-deep);
    text-decoration-color: var(--color-annotation-deep);
}

/* === LABELS ===

   Brand voice convention: prefer ALL_CAPS_SNAKE_CASE identifiers for
   system-voice eyebrows (PRIVATE_FEED_URL, QUICK_LINKS, MCP_SERVER_01).
   Title Case is fine for editorial labels (Author, Episode, Podcast).
   The snake_case form signals "this is the system speaking about its
   own structure" — REST routes, env vars, technical IDs. Pairs with
   the .link-route pattern below, which exposes the route name itself
   on the right side of nav rows. */

label, .label {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-text-gray);
}

/* Annotation label — red, used sparingly for emphasis */
.label-annotation {
    font-family: var(--font-mono);
    font-size: 0.7rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-accent);
}

/* === SYSTEM LINKS — REST-style route names exposed inline ===

   The architecture of the app is part of its voice. Django URL names
   like `podcast:list` or `account:settings` are surfaced as the
   secondary text inside link rows: human label on the left, mono
   route + sans arrow on the right. The pattern reads as editorial
   honesty about the system's own structure — pairs with the SNAKE_CASE
   eyebrow convention above.

   Three pieces:
   - .link-route — inline anchor styled as `route:name →`
   - .link-row   — two-column row: human label left, .link-route right
   - .list-routes — vertical stack of .link-row, eyebrow on top */

.link-route {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 400;
    letter-spacing: 0.04em;
    color: var(--color-text-charcoal);
    text-decoration: none;
    white-space: nowrap;
    transition: color var(--duration-fast) var(--ease-brand);
}

.link-route::after {
    content: " →";
    font-family: var(--font-sans);
    color: var(--color-text-light-gray);
    margin-left: 2px;
    transition: color var(--duration-fast) var(--ease-brand);
}

.link-route:hover {
    color: var(--color-annotation);
}

.link-route:hover::after {
    color: var(--color-annotation);
}

.link-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-md);
    padding: var(--space-xs) 0;
    border-bottom: 1px solid var(--color-border-light);
    text-decoration: none;
    color: inherit;
    transition: color var(--duration-fast) var(--ease-brand);
}

.link-row:last-child {
    border-bottom: none;
}

.link-row__label {
    font-family: var(--font-sans);
    font-size: 0.875rem;
    color: var(--color-text-black);
}

.link-row:hover .link-row__label {
    color: var(--color-annotation-deep);
}

.list-routes {
    display: flex;
    flex-direction: column;
}

.list-routes > .label {
    margin-bottom: var(--space-sm);
}

/* === DATA DISPLAYS === */

.spec-sheet, .data-display {
    font-family: var(--font-mono);
    font-size: 0.875rem;
    line-height: 1.8;
    letter-spacing: 0.02em;
    font-variant-numeric: tabular-nums;
    background: var(--color-bg-white);
    border: 1px solid var(--color-border-light);
    padding: var(--space-lg);
}

/* === TECHNICAL DRAWING ELEMENTS === */

/* Subtle grid background */
.technical-bg {
    background-image:
        linear-gradient(var(--color-border-light) 1px, transparent 1px),
        linear-gradient(90deg, var(--color-border-light) 1px, transparent 1px);
    background-size: var(--grid-size) var(--grid-size);
}

/* Connection lines with endpoint nodes */
.connection-line {
    border-top: 1px solid var(--color-border-medium);
    position: relative;
}

.connection-line::before,
.connection-line::after {
    content: '';
    position: absolute;
    width: 6px;
    height: 6px;
    border: 1px solid var(--color-border-dark);
    background: var(--color-bg-cream);
    border-radius: 50%;
    top: -3px;
}

.connection-line::before { left: 0; }
.connection-line::after { right: 0; }

/* Technical double-border */
.technical-border {
    border: 1px solid var(--color-border-dark);
    box-shadow:
        inset 0 0 0 3px var(--color-bg-cream),
        inset 0 0 0 4px var(--color-border-medium);
}

/* Blueprint container with inset border */
.blueprint-box {
    position: relative;
    padding: var(--space-lg);
    border: 2px solid var(--color-border-dark);
    background: var(--color-bg-white);
}

.blueprint-box::before {
    content: '';
    position: absolute;
    top: 8px;
    left: 8px;
    right: 8px;
    bottom: 8px;
    border: 1px solid var(--color-border-light);
    pointer-events: none;
}

/* Red annotation overlay — structural emphasis line */
.annotation-line {
    border-top: 1.5px solid var(--color-accent);
    position: relative;
}

/* Red annotation mark — used for axis markers, emphasis points */
.annotation-mark {
    display: inline-block;
    width: 6px;
    height: 6px;
    background: var(--color-accent);
    border-radius: 50%;
}

/* Cobalt reference mark — cross-references, footnote anchors, link endpoints */
.annotation-reference-mark {
    display: inline-block;
    width: 6px;
    height: 6px;
    background: var(--color-reference);
    border-radius: 50%;
}

/* Ochre mark — secondary structural points, in-progress markers */
.annotation-ochre-mark {
    display: inline-block;
    width: 6px;
    height: 6px;
    background: var(--color-ochre);
    border-radius: 50%;
}

/* Dashed red registration line — alignment guide / overlay grid
   (moodboard #07 kristin-king dashed site-plan crosshair) */
.annotation-dashed {
    border-top: 1.5px dashed var(--color-annotation);
    position: relative;
}

/* Pale-rose highlight plate — marginalia, editorial callouts, quoted lines
   (moodboard #11 pale-rose floor tiles). Tint-level surface; red body type
   stays legible on it. Use once per section at most. */
.highlight-rose {
    background: var(--color-annotation-rose);
    padding: var(--space-md) var(--space-lg);
    font-family: var(--font-serif);
    font-style: italic;
    font-size: 1rem;
    line-height: 1.5;
    color: var(--color-text-black);
}

.highlight-rose > .highlight-eyebrow {
    display: block;
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 500;
    font-style: normal;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-annotation-deep);
    margin-bottom: var(--space-xs);
}

/* Cobalt monospace label — mirrors .label-annotation for cross-references */
.label-reference {
    font-family: var(--font-mono);
    font-size: 0.7rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-reference);
}

/* === LAYOUT === */

.section {
    padding: var(--space-3xl) 0;
}

.section-hero {
    max-width: 1000px;
    margin: 0 auto;
    padding: var(--space-3xl) var(--space-lg);
    text-align: center;
}

.container-brand {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 var(--space-lg);
}

/* === BUTTONS === */

/* Button family — four self-contained variants with subtle lift shadow.
   Visual hierarchy (most → least prominent):
     1. .btn-brand-accent  solid red       — primary CTA, max one per page
     2. .btn-brand         outline black   — neutral default
     3. .btn-brand-deep    solid dark red  — secondary CTA in red ladder
     4. .btn-brand-dark    solid black     — neutral alternate / inverse
   All four share typography, padding, border-radius, transition, and rest/hover shadow. */

.btn-brand,
.btn-brand-accent,
.btn-brand-deep,
.btn-brand-dark {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    padding: var(--space-sm) var(--space-lg);
    border: 1px solid transparent;
    border-radius: var(--radius-btn);
    /* Explicit properties only — never animate `all` (catches layout props
       and tanks 60fps). Brand easing is ease-out-expo: soft deceleration. */
    transition: background-color var(--duration-fast) var(--ease-brand),
                color var(--duration-fast) var(--ease-brand),
                border-color var(--duration-fast) var(--ease-brand),
                box-shadow var(--duration-base) var(--ease-brand),
                transform var(--duration-base) var(--ease-brand);
    cursor: pointer;
    text-decoration: none;
    display: inline-block;
    box-shadow: 0 1px 2px rgba(26, 26, 26, 0.08);
}

.btn-brand:hover,
.btn-brand-accent:hover,
.btn-brand-deep:hover,
.btn-brand-dark:hover {
    box-shadow: 0 3px 8px rgba(26, 26, 26, 0.14);
    transform: translateY(-1px);
}

/* Outline black — neutral default */
.btn-brand {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    background: var(--color-bg-white);
    border-color: var(--color-border-dark);
    color: var(--color-text-black);
}

.btn-brand:hover {
    background: var(--color-text-black);
    color: var(--color-bg-white);
    border-color: var(--color-text-black);
}

/* Accent — solid red, primary CTA; border uses annotation-deep so it's
   visible against the red fill and matches the visual weight of outline buttons */
.btn-brand-accent {
    background: var(--color-annotation);
    border-color: var(--color-annotation-deep);
    color: var(--color-bg-white);
}

.btn-brand-accent:hover {
    background: var(--color-annotation-deep);
    border-color: var(--color-annotation-deep);
    color: var(--color-bg-white);
}

/* Deep red — solid annotation-deep, secondary CTA */
.btn-brand-deep {
    background: var(--color-annotation-deep);
    border-color: var(--color-annotation-deep);
    color: var(--color-bg-white);
}

.btn-brand-deep:hover {
    background: var(--color-annotation-muted);
    border-color: var(--color-annotation-muted);
    color: var(--color-bg-white);
}

/* Dark — solid black, neutral alternate */
.btn-brand-dark {
    background: var(--color-text-black);
    border-color: var(--color-text-black);
    color: var(--color-bg-white);
}

.btn-brand-dark:hover {
    background: var(--color-text-charcoal);
    border-color: var(--color-text-charcoal);
    color: var(--color-bg-white);
}

/* Size modifiers — compose with any btn-brand-* color variant.
   Default (no modifier) = lg: 16px / 32px, 12px type.
   btn-brand--md: 8px / 24px, 12px type — standard page buttons.
   btn-brand--sm: 8px / 16px, 11px type — compact contexts (navbar, inline). */
.btn-brand--md {
    padding: var(--space-xs) var(--space-md);
}

.btn-brand--sm {
    padding: var(--space-xs) var(--space-sm);
    font-size: 0.688rem;
    letter-spacing: 0.06em;
    line-height: 1;
    min-height: 30px;
}

/* Disabled — inert, no shadow, no lift, muted color */
.btn-brand:disabled,
.btn-brand[aria-disabled="true"],
.btn-brand-accent:disabled,
.btn-brand-accent[aria-disabled="true"],
.btn-brand-deep:disabled,
.btn-brand-deep[aria-disabled="true"],
.btn-brand-dark:disabled,
.btn-brand-dark[aria-disabled="true"] {
    cursor: not-allowed;
    opacity: 0.5;
    box-shadow: none;
    transform: none;
}

.btn-brand-accent:disabled,
.btn-brand-accent[aria-disabled="true"] {
    background: var(--color-annotation-muted);
    border-color: var(--color-annotation-muted);
}

/* Busy state — async-request affordance for submit buttons.

   The label is left completely untouched: no swap, no stacked spans, no
   width measurement. The cue lives on the button's chrome — a 1px hairline
   that sweeps left→right along the bottom edge for as long as the request
   is in flight. Reads as "the architect's pen is drawing the line."

   Triggers (any one of):
   - `.htmx-request` — added automatically by HTMX to the requesting element.
     For a form (`<form hx-post>`), HTMX puts the class on the FORM, not on
     the button inside. Two ways to get the sweep on the button itself:
       (a) put `hx-post`/`hx-put`/`hx-delete` on the button directly, or
       (b) set `hx-indicator="this"` on the button.
   - `[aria-busy="true"]` — manual trigger. Also announces to assistive tech.
     Useful for non-HTMX async paths (fetch, custom JS).

   The hairline inherits `currentColor`, so it matches the button's text:
   accent-deep on outline buttons, cream on solid black, etc. */

.btn-brand,
.btn-brand-accent,
.btn-brand-deep,
.btn-brand-dark {
    position: relative;
    overflow: hidden;  /* clip the sweep at the button's rounded edges */
}

.btn-brand.htmx-request,
.btn-brand-accent.htmx-request,
.btn-brand-deep.htmx-request,
.btn-brand-dark.htmx-request,
.btn-brand[aria-busy="true"],
.btn-brand-accent[aria-busy="true"],
.btn-brand-deep[aria-busy="true"],
.btn-brand-dark[aria-busy="true"] {
    cursor: progress;
    pointer-events: none;  /* prevent double-submit while in flight */
}

.btn-brand.htmx-request::after,
.btn-brand-accent.htmx-request::after,
.btn-brand-deep.htmx-request::after,
.btn-brand-dark.htmx-request::after,
.btn-brand[aria-busy="true"]::after,
.btn-brand-accent[aria-busy="true"]::after,
.btn-brand-deep[aria-busy="true"]::after,
.btn-brand-dark[aria-busy="true"]::after {
    content: "";
    position: absolute;
    inset: auto 0 0 0;
    height: 1px;
    background: linear-gradient(
        to right,
        transparent 0%,
        currentColor 50%,
        transparent 100%
    );
    background-size: 40% 100%;
    background-repeat: no-repeat;
    animation: btn-brand-busy 1.2s var(--ease-brand) infinite;
}

@keyframes btn-brand-busy {
    from { background-position: -40% 0; }
    to   { background-position: 140% 0; }
}

/* Reduced motion — drop the sweep, leave a static hairline so the
   affordance is still present without the animation. */
@media (prefers-reduced-motion: reduce) {
    .btn-brand.htmx-request::after,
    .btn-brand-accent.htmx-request::after,
    .btn-brand-deep.htmx-request::after,
    .btn-brand-dark.htmx-request::after,
    .btn-brand[aria-busy="true"]::after,
    .btn-brand-accent[aria-busy="true"]::after,
    .btn-brand-deep[aria-busy="true"]::after,
    .btn-brand-dark[aria-busy="true"]::after {
        animation: none;
        background: currentColor;
        opacity: 0.5;
    }
}

/* === PILL/RUNNING ===
   Persistent in-flight state for the async-action UI pattern (issue #397).
   Sibling primitive to the .btn-brand-*[aria-busy] hairline sweep — but
   for surfaces where the in-flight signal must survive page reloads
   (e.g. Perplexity Deep Research, which runs for 3-10 min and the
   operator may close the tab and return).

   Renders via the {% include "components/forms/async_action.html" %}
   include when RunningTaskFinder finds a DBTaskResult in
   READY/RUNNING for the supplied scope.  The 2s WorkflowPollView poll
   keeps the page redrawing until the task settles, at which point the
   pill is swapped back out for the idle button.

   Pencil node: Component/Pill/Running (SFddo) — see gap-audit.md §28. */

.pill-running {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.5rem 1rem;
    min-height: 36px;  /* matches .btn-brand-deep so swap doesn't reflow */
    background: var(--color-bg-warm-gray);
    color: var(--color-text-charcoal);
    border: 1px solid var(--color-border-light);
    border-radius: 9999px;  /* fully rounded — the only pill in the system */
    font-family: var(--font-mono);
    font-size: 0.75rem;
    letter-spacing: 0.04em;
    cursor: progress;
    pointer-events: none;
    position: relative;
    animation: pill-running-pulse 1.5s ease-in-out infinite;
}

@keyframes pill-running-pulse {
    0%, 100% {
        box-shadow: 0 0 0 0 rgba(45, 45, 45, 0.0);
    }
    50% {
        box-shadow: 0 0 0 4px rgba(45, 45, 45, 0.06);
    }
}

/* Reduced motion — drop the pulse and the icon spin.  aria-busy="true"
   and role="status" carry the meaning for assistive tech. */
@media (prefers-reduced-motion: reduce) {
    .pill-running {
        animation: none;
    }
    .pill-running .fa-spin,
    .pill-running .fa-circle-notch {
        animation: none;
    }
}

/* === CARDS === */

/* Card eyebrow label — neutral gray, never annotation red.
   Eyebrows on cards identify the content type, not a value.
   Red is reserved for the value itself (see anti-pattern #3). */
.card-technical .card__eyebrow,
.product-card .card__eyebrow,
.episode-card .card__eyebrow {
    font-family: var(--font-mono);
    font-style: normal;
    font-size: 0.625rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--color-text-gray);
    margin-bottom: var(--space-xs);
    display: block;
}

.card-technical {
    background: var(--color-bg-white);
    border: 1px solid var(--color-border-medium);
    padding: var(--space-lg);
    position: relative;
    transition: border-color var(--duration-base) var(--ease-brand),
                box-shadow var(--duration-base) var(--ease-brand),
                transform var(--duration-base) var(--ease-brand);
}

/* Hover only when the card is the click target (anchor or button).
   Static container usage stays inert. Layered shadow + 1px lift gives
   real depth without going Material/SaaS-glossy. */
a.card-technical:hover,
button.card-technical:hover {
    border-color: var(--color-border-dark);
    box-shadow: 0 1px 0 rgba(26, 26, 26, 0.04),
                0 8px 24px -8px rgba(45, 45, 45, 0.18);
    transform: translateY(-1px);
}

/* Hero section spec box */
.technical-spec-box {
    background: var(--color-bg-white);
    border: 2px solid var(--color-border-dark);
    padding: var(--space-2xl);
    position: relative;
}

.technical-spec-box::before {
    content: '';
    position: absolute;
    top: 6px;
    left: 6px;
    right: 6px;
    bottom: 6px;
    border: 1px solid var(--color-border-light);
    pointer-events: none;
}

/* Product card — homepage multi-product cards */
.product-card {
    background: var(--color-bg-white);
    border: 1px solid var(--color-border-medium);
    padding: var(--space-lg);
    transition: border-color var(--duration-base) var(--ease-brand),
                box-shadow var(--duration-base) var(--ease-brand),
                transform var(--duration-base) var(--ease-brand);
}

a.product-card:hover,
button.product-card:hover {
    border-color: var(--color-border-dark);
    box-shadow: 0 1px 0 rgba(26, 26, 26, 0.04),
                0 6px 18px -8px rgba(45, 45, 45, 0.15);
    transform: translateY(-1px);
}

/* Episode card — podcast episode cards */
.episode-card {
    background: var(--color-bg-white);
    border: 1px solid var(--color-border-medium);
    padding: var(--space-lg);
    transition: border-color var(--duration-base) var(--ease-brand),
                box-shadow var(--duration-base) var(--ease-brand),
                transform var(--duration-base) var(--ease-brand);
    display: block;
    text-decoration: none;
    color: inherit;
}

.episode-card:hover {
    border-color: var(--color-border-dark);
    box-shadow: 0 1px 0 rgba(26, 26, 26, 0.04),
                0 8px 24px -8px rgba(45, 45, 45, 0.18);
    transform: translateY(-1px);
}

/* Episode card title — centered per design system review */
.episode-card__title {
    font-family: var(--font-serif);
    font-weight: 500;
    font-size: 1.0625rem;
    line-height: 1.35;
    color: var(--color-text-black);
    text-align: center;
    text-wrap: balance;
    margin-bottom: var(--space-xs);
}

.episode-card__meta {
    font-family: var(--font-mono);
    font-size: 0.625rem;
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-text-gray);
    text-align: center;
}

/* Server card — static container; no hover (see usage in pages/home.html).
   If a future surface makes it clickable, wrap in <a class="server-card"> and
   add an a.server-card:hover rule alongside it. */
.server-card {
    background: var(--color-bg-white);
    border: 1px solid var(--color-border-medium);
    padding: var(--space-lg);
}

/* Corner-mark card (architectural drawing style) */
.card-corner-marks {
    position: relative;
    background: var(--color-bg-white);
    padding: var(--space-lg);
}

.card-corner-marks::before,
.card-corner-marks::after {
    content: '';
    position: absolute;
    width: 16px;
    height: 16px;
    border: 2px solid var(--color-border-dark);
}

.card-corner-marks::before {
    top: 0;
    left: 0;
    border-right: none;
    border-bottom: none;
}

.card-corner-marks::after {
    bottom: 0;
    right: 0;
    border-left: none;
    border-top: none;
}

/* === IMAGES ===

   .img-framed — 1px border using --color-border-medium. Solves the
   cream-on-cream visibility problem: AI-generated cover art uses the
   page background (#FAF9F6) as its own background, making it invisible
   unless framed. Apply to any img or image container where the image
   background might match the page background. */

.img-framed {
    border: 1px solid var(--color-border-medium);
}

/* === NAVIGATION === */

/* Root nav — cream bg to kill the white/cream seam; ledger-rule bottom border */
.nav-brand {
    background: var(--color-bg-cream);
    border-bottom: 1px solid var(--color-border-medium);
    position: relative;
    z-index: 100;
}

/* Inner flex container — fixed 64px height, max-width 1280px */
.nav-brand__container {
    max-width: 1280px;
    margin: 0 auto;
    padding: 0 var(--space-lg);
    height: 64px;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

/* Logo anchor — no underline, just the mark */
.nav-brand__brand {
    display: flex;
    align-items: center;
    text-decoration: none;
    flex-shrink: 0;
}

/* Logo image — sized in CSS only; markup must never carry inline sizing */
.nav-brand__logo {
    height: 32px;
    width: auto;
    display: block;
}

/* Desktop link group */
.nav-brand__links {
    display: flex;
    align-items: center;
    gap: var(--space-lg);
}

/* Individual nav link — Inter, mono-caps style */
.nav-brand__link {
    font-family: var(--font-sans);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-text-gray);
    text-decoration: none;
    position: relative;
    transition: color 0.15s ease;
}

.nav-brand__link:hover {
    color: var(--color-text-black);
}

/* Active state — architect's red-pen underline via ::after pseudo-element */
.nav-brand__link.is-active {
    color: var(--color-text-black);
}

.nav-brand__link.is-active::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -4px;
    height: 1px;
    background: var(--color-annotation);
}

/* Focus ring — 2px annotation-red, applies to all interactive nav elements */
.nav-brand__link:focus-visible,
.nav-brand__brand:focus-visible,
.nav-brand__hamburger:focus-visible,
.nav-brand__avatar:focus-visible,
.nav-brand__login:focus-visible,
.nav-brand__menu-item:focus-visible {
    outline: 2px solid var(--color-annotation);
    outline-offset: 2px;
}

/* Edition stamp wrapper — right-rail, mono, hidden below 768px */
.nav-brand__edition {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

/* Mono uppercase utility — used inside __edition and wherever a label stamp is needed */
.nav-brand__label {
    font-family: var(--font-mono);
    font-size: 0.688rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-text-light-gray);
}

/* Mobile hamburger toggle — square, transparent, focus ring matches others */
.nav-brand__hamburger {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    background: transparent;
    border: none;
    border-radius: var(--radius-btn);
    cursor: pointer;
    padding: 0;
    color: var(--color-text-charcoal);
    transition: color 0.15s ease;
}

.nav-brand__hamburger:hover {
    color: var(--color-text-black);
}

/* User-initials icon button — matches btn-brand--sm height, charcoal border */
.nav-brand__avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-xs);
    line-height: 1;
    background: var(--color-bg-white);
    border: 1px solid var(--color-border-dark);
    border-radius: var(--radius-btn);
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--color-text-charcoal);
    text-decoration: none;
    cursor: pointer;
    box-shadow: 0 1px 2px rgba(26, 26, 26, 0.08);
    transition: background-color var(--duration-fast) var(--ease-brand),
                border-color var(--duration-fast) var(--ease-brand),
                box-shadow var(--duration-base) var(--ease-brand),
                transform var(--duration-base) var(--ease-brand);
}

.nav-brand__avatar:hover {
    background: var(--color-bg-warm-gray);
    box-shadow: 0 3px 8px rgba(26, 26, 26, 0.14);
    transform: translateY(-1px);
}

/* Dropdown panel — architectural offset shadow, square corners */
.nav-brand__menu {
    position: absolute;
    top: 100%;
    right: 0;
    min-width: 200px;
    background: var(--color-bg-white);
    border: 1px solid var(--color-border-dark);
    box-shadow: 4px 4px 0 0 rgba(26, 26, 26, 0.08);
    z-index: 200;
}

/* Dropdown link/button */
.nav-brand__menu-item {
    display: block;
    width: 100%;
    padding: var(--space-sm) var(--space-md);
    font-family: var(--font-sans);
    font-size: 0.875rem;
    font-weight: 400;
    color: var(--color-text-charcoal);
    text-decoration: none;
    text-align: left;
    background: transparent;
    border: none;
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.nav-brand__menu-item:hover {
    background: var(--color-bg-warm-gray);
}

/* Logout variant — hover draws attention with annotation red */
.nav-brand__menu-item--logout:hover {
    color: var(--color-annotation);
    background: var(--color-bg-warm-gray);
}

/* Anonymous-state sign-in CTA — matches nav-brand__avatar exactly */
.nav-brand__login {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-xs);
    line-height: 1;
    background: var(--color-bg-white);
    border: 1px solid var(--color-border-dark);
    border-radius: var(--radius-btn);
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--color-text-charcoal);
    text-decoration: none;
    cursor: pointer;
    box-shadow: 0 1px 2px rgba(26, 26, 26, 0.08);
    transition: background-color var(--duration-fast) var(--ease-brand),
                border-color var(--duration-fast) var(--ease-brand),
                box-shadow var(--duration-base) var(--ease-brand),
                transform var(--duration-base) var(--ease-brand);
}

.nav-brand__login:hover {
    background: var(--color-bg-warm-gray);
    box-shadow: 0 3px 8px rgba(26, 26, 26, 0.14);
    transform: translateY(-1px);
}


/* Responsive — logo shrinks at mobile, hamburger/desktop links toggle */
@media (max-width: 639px) {
    .nav-brand__logo {
        height: 28px;
    }

    .nav-brand__links,
    .nav-brand__edition {
        display: none;
    }
}

@media (min-width: 640px) {
    .nav-brand__hamburger {
        display: none;
    }
}

@media (max-width: 767px) {
    .nav-brand__edition {
        display: none;
    }
}

/* Reduced-motion — strip all transitions for users who prefer it */
@media (prefers-reduced-motion: reduce) {
    .nav-brand__link,
    .nav-brand__brand,
    .nav-brand__hamburger,
    .nav-brand__avatar,
    .nav-brand__login,
    .nav-brand__menu-item,
    .nav-brand__mobile-link {
        transition: none;
    }
}

/* === WORKFLOW DRAWER ===
   Mobile-friendly left-edge <dialog> drawer for the 12-phase episode
   workflow nav, with a persistent rail at the md: (≥768px) breakpoint.

   Breakpoint note: this surface uses 768px (not the top-nav's 640px)
   because the workflow rail is 256px wide. At 640px the remaining
   ~384px of content beside the rail is too tight; at 768px we have
   512px content, which is the minimum that renders the per-phase
   forms (paste research, audio upload, metadata) without overflow.

   Pencil components: Drawer/Workflow (Ox5U4) + Button/Hamburger (ItN8O)
   in design-system.pen. See docs/designs/gap-audit.md §29.
   The mobile-panel pattern follows the existing .nav-brand__mobile-panel
   precedent (gap-audit §13.1) and uses native <dialog> + ::backdrop,
   matching the Phase 4 paste-modal pattern already shipped in this
   template. No JS library, no Alpine, no focus-trap shim. */

.workflow-drawer {
    /* Modal mode (mobile) — left-edge slide-in. <dialog> with .showModal()
       handles focus trap, Escape, and backdrop click natively. */
    margin: 0;
    padding: 0;
    border: 0;
    background: var(--color-bg-cream);
    color: var(--color-text-charcoal);
    max-width: 320px;
    width: 85vw;
    height: 100vh;
    max-height: 100vh;
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    border-right: 1px solid var(--color-border-medium);
    overflow-y: auto;
    box-shadow: 4px 0 0 0 rgba(26, 26, 26, 0.08);
}

.workflow-drawer::backdrop {
    background: rgba(26, 26, 26, 0.4);
}

.workflow-drawer__nav {
    padding: var(--space-lg) var(--space-md) var(--space-xl);
    display: block;
}

/* Hamburger trigger — visible only on mobile, hidden via media query
   at ≥768px. 44px tap-height per Apple HIG / WCAG 2.5.5. */
.workflow-drawer__trigger {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    height: 44px;
    padding: 0 var(--space-md);
    background: var(--color-bg-white);
    border: 1px solid var(--color-border-dark);
    border-radius: var(--radius-btn);
    cursor: pointer;
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-text-black);
    transition: background-color 0.15s ease, color 0.15s ease;
    margin-bottom: var(--space-md);
}

.workflow-drawer__trigger:hover {
    background: var(--color-text-black);
    color: var(--color-bg-white);
}

.workflow-drawer__trigger-icon {
    display: inline-block;
    width: 18px;
    height: 14px;
    flex-shrink: 0;
}

.workflow-drawer__trigger-icon::before {
    content: "";
    display: block;
    width: 18px;
    height: 14px;
    background-image: linear-gradient(
        to bottom,
        currentColor 0,
        currentColor 1.5px,
        transparent 1.5px,
        transparent 6.25px,
        currentColor 6.25px,
        currentColor 7.75px,
        transparent 7.75px,
        transparent 12.5px,
        currentColor 12.5px,
        currentColor 14px
    );
}

/* Desktop (≥768px): drawer collapses to a persistent rail. The same
   <dialog> element renders inline as a normal block; no modal semantics,
   no backdrop, no trigger button. We override the UA default
   `dialog:not([open]) { display: none }` so the rail is always visible
   on desktop regardless of the [open] attribute state. */
@media (min-width: 768px) {
    .workflow-drawer,
    .workflow-drawer[open] {
        display: block;
        position: static;
        inset: auto;
        width: 16rem;
        max-width: 16rem;
        height: auto;
        max-height: none;
        margin: 0;
        padding: 0;
        background: transparent;
        border: 0;
        border-right: 0;
        box-shadow: none;
        overflow: visible;
        color: var(--color-text-charcoal);
    }

    .workflow-drawer::backdrop {
        display: none;
    }

    .workflow-drawer__nav {
        padding: 0;
    }

    .workflow-drawer__trigger {
        display: none;
    }
}

/* Reduced-motion */
@media (prefers-reduced-motion: reduce) {
    .workflow-drawer__trigger {
        transition: none;
    }
}

/* === WORKFLOW PASTE MODAL (Phase 4) ===
   Native <dialog> paste modals share the same workflow surface as the
   drawer. At 375px viewport the default Tailwind `max-w-2xl` (672px)
   overflows; this rule constrains the modal to viewport width minus a
   1rem gutter on each side while preserving the desktop cap. Scoped to
   the .workflow-paste-modal BEM class so it cannot leak into other
   <dialog> instances (e.g. the drawer itself). */

.workflow-paste-modal {
    width: calc(100vw - 2rem);
    max-width: 42rem; /* matches Tailwind max-w-2xl (672px) */
    max-height: calc(100vh - 2rem);
    margin: auto;
    padding: 0;
    border: 0;
    background: var(--color-bg-white);
    box-shadow: 0 10px 30px rgba(26, 26, 26, 0.15);
    overflow-y: auto;
}

.workflow-paste-modal::backdrop {
    background: rgba(26, 26, 26, 0.5);
}

/* === FILE INPUT (BRAND) ===
   Touch-target sized native <input type="file"> wrapper for audio +
   cover-art upload (Phases 9/11). Replaces the inline Tailwind `file:`
   utilities so the file-chooser button is 44px tall (Apple HIG /
   WCAG 2.5.5 minimum). Pencil component: queued under Drawer/Workflow
   family (issue #417); production CSS painted here. */

.input-file-brand {
    display: block;
    width: 100%;
    font-size: 0.875rem;
    font-family: var(--font-mono);
    color: var(--color-text-charcoal);
}

.input-file-brand::file-selector-button {
    margin-right: var(--space-md);
    height: 44px;
    padding: 0 var(--space-md);
    border: 1px solid var(--color-border-dark);
    background: var(--color-bg-white);
    color: var(--color-text-charcoal);
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.input-file-brand::file-selector-button:hover {
    background: var(--color-text-black);
    color: var(--color-bg-white);
}

@media (prefers-reduced-motion: reduce) {
    .input-file-brand::file-selector-button {
        transition: none;
    }
}

/* === FOOTER === */

.footer-section-header {
    font-family: var(--font-mono);
    font-size: 0.688rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-text-gray);
    margin-bottom: var(--space-md);
}

.footer-link {
    color: var(--color-text-gray);
    text-decoration: none;
    transition: color 0.2s ease;
}

.footer-link:hover {
    color: var(--color-text-black);
}

/* === TABLES === */

.table-spec {
    width: 100%;
    font-family: var(--font-mono);
    font-size: 0.875rem;
    border-collapse: collapse;
}

.table-spec th {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-align: left;
    padding: var(--space-sm);
    border-bottom: 2px solid var(--color-border-dark);
    background: var(--color-bg-warm-gray);
}

.table-spec td {
    padding: var(--space-sm);
    border-bottom: 1px solid var(--color-border-light);
}

.spec-table-inline {
    font-family: var(--font-mono);
    font-size: 0.75rem;
}

.spec-table-inline td {
    padding: var(--space-xs) 0;
    vertical-align: top;
}

.spec-table-inline td:first-child {
    color: var(--color-text-gray);
    padding-right: var(--space-md);
}

/* === FORMS === */

.input-brand {
    font-family: var(--font-mono);
    font-size: 0.875rem;
    padding: var(--space-xs) var(--space-sm);
    border: 1px solid var(--color-border-medium);
    background: var(--color-bg-white);
    color: var(--color-text-charcoal);
    transition: border-color 0.2s ease;
}

.input-brand:focus {
    outline: none;
    border-color: var(--color-border-dark);
    box-shadow: 0 0 0 3px rgba(58, 58, 58, 0.1);
}

/* === CODE BLOCKS === */

pre.brand-code {
    font-family: var(--font-mono);
    font-size: 0.875rem;
    line-height: 1.6;
    background: var(--color-text-black);
    color: var(--color-bg-cream);
    padding: var(--space-lg);
    border: 1px solid var(--color-border-dark);
    overflow-x: auto;
}

/* === STATUS INDICATORS === */

.status-indicator {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    margin-right: 6px;
}

.status-operational {
    background: var(--color-status-operational);
}

.status-development {
    background: var(--color-status-development);
}

.status-offline {
    background: var(--color-status-offline);
}

/* Stale status indicator — company facts that need re-verification.
   Warm grey; neither operational (green) nor offline (red). Issue #333. */
.status-stale {
    background: var(--color-status-stale);
}

/* === DIVIDERS === */

.divider-technical {
    height: 1px;
    background: var(--color-border-medium);
    margin: var(--space-lg) 0;
    position: relative;
}

.divider-technical::before {
    content: '';
    position: absolute;
    left: 50%;
    top: -3px;
    transform: translateX(-50%);
    width: 6px;
    height: 6px;
    border: 1px solid var(--color-border-dark);
    background: var(--color-bg-cream);
    border-radius: 50%;
}

/* === BAND / STAMP ===

   Mono definition band — a strip of key/value stamps between hairlines.
   One component, two canonical usages: the edition-stamp strip under a
   hero, and the colophon trust band (METHOD / SOURCES / VALIDATION /
   MADE BY). Keys stay gray; values step up to black 500 so the eye
   lands on the content, not the scaffolding. Two columns on mobile,
   four from 640px. */

.band-stamp {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-md) var(--space-lg);
    padding: var(--space-md) 0;
    border-top: 1px solid var(--color-border-medium);
    border-bottom: 1px solid var(--color-border-medium);
    font-family: var(--font-mono);
    font-size: 0.688rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-text-gray);
}

.band-stamp__item {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.band-stamp__key {
    color: var(--color-text-gray);
}

.band-stamp__value {
    color: var(--color-text-black);
    font-weight: 500;
    line-height: 1.5;
}

@media (min-width: 640px) {
    .band-stamp {
        grid-template-columns: repeat(4, 1fr);
    }
}

/* === BAND / LOGOS ===

   "Heard by" logo strip — mono label left, grayscale logos right,
   hairlines top and bottom.

   GATING RULE: ship only with real, permissioned logos. Placeholder or
   aspirational logos violate the "plausible-but-empty" anti-slop rule
   (see the stats-theater anti-pattern in NOTICES & CALLOUTS). If there
   are no real logos to show, do not render the band at all. */

.band-logos {
    display: flex;
    align-items: center;
    gap: var(--space-xl);
    padding: var(--space-md) 0;
    border-top: 1px solid var(--color-border-medium);
    border-bottom: 1px solid var(--color-border-medium);
}

.band-logos__label {
    font-family: var(--font-mono);
    font-size: 0.688rem;
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-text-gray);
    white-space: nowrap;
    flex-shrink: 0;
}

.band-logos__items {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
    flex: 1;
    flex-wrap: wrap;
    filter: grayscale(100%);
    opacity: 0.75;
}

.band-logos__items img {
    height: 32px;
    width: auto;
    display: block;
}

/* === SAMPLE PLAYER (homepage) ===

   Compact audio-sample player for the marketing homepage — lets a
   visitor hear a real published-episode excerpt before subscribing.
   Drafting-panel / mono-label idiom: an .annotation-leader eyebrow
   ("EPISODE SAMPLE" over a sublabel) identifies the block, then a
   plain HTML5 <audio controls preload="none"> element carries
   playback — no custom transport, no waveform, no JS.

   HOMEPAGE-SCOPED ONLY. This is NOT the `body.report-mode`-scoped
   .episode-player / .episode-player-condensed family in report.css,
   which serves the full inline episode report page and carries
   chapter-list/report-caption structure this component does not
   need. Do not merge the two families or restyle report.css to
   match — pen node Player/Sample (DACT2). */

.sample-player {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    padding: var(--space-md) var(--space-lg);
    background: var(--color-bg-white);
    border: 1px solid var(--color-border-light);
}

.sample-player audio {
    width: 100%;
}

/* === CLAIM STRIP (homepage) ===

   Flat three-part assertion list — e.g. "No app to install · No new
   habit · Plays where you already listen". Distinct from
   .band-stamp: band-stamp pairs a gray key with a black value in a
   grid of columns; claim-strip is a single flat row of plain
   assertions separated by mono middots, with no key/value structure
   and no hairline borders of its own.

   HOMEPAGE-SCOPED. Pen node Claim/Strip (wVW3D). */

.claim-strip {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--space-sm);
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.04em;
    color: var(--color-text-black);
    text-align: center;
}

.claim-strip__item {
    display: inline-flex;
}

.claim-strip__item:not(:last-child)::after {
    content: "·";
    margin-left: var(--space-sm);
    color: var(--color-text-light-gray);
    font-weight: normal;
}

/* === LEDGER ===

   Full-width ruled rows — the ledger opens with a medium hairline,
   rows separate with light hairlines, and the last row closes with a
   medium hairline. One family, two row modifiers:
   - .ledger__row--step   How-It-Works rows: mono red step ID, serif
                          title, sans description, mono meta stamp.
   - .ledger__row--moment Timestamped listening-moment rows: mono
                          timestamp column + body. */

.ledger {
    border-top: 1px solid var(--color-border-medium);
}

.ledger__row {
    display: grid;
    gap: var(--space-lg);
    padding: var(--space-lg) 0;
    border-bottom: 1px solid var(--color-border-light);
    align-items: baseline;
}

.ledger__row:last-child {
    border-bottom-color: var(--color-border-medium);
}

.ledger__row--step {
    grid-template-columns: 110px 1.2fr 1.6fr auto;
}

.ledger__row--moment {
    grid-template-columns: 78px 1fr;
    gap: var(--space-md);
}

.ledger__id {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.1em;
    color: var(--color-annotation);
}

.ledger__title {
    font-family: var(--font-serif);
    font-weight: 500;
    font-size: clamp(1.375rem, 2.5vw, 1.625rem);
    line-height: 1.15;
    margin: 0;
    color: var(--color-text-black);
    text-wrap: balance;
}

.ledger__row--moment .ledger__title {
    font-size: 1.125rem;
}

.ledger__desc {
    font-size: 0.9375rem;
    line-height: 1.6;
    color: var(--color-text-gray);
    margin: 0;
    max-width: 48ch;
}

.ledger__meta {
    font-family: var(--font-mono);
    font-size: 0.688rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-text-gray);
    white-space: nowrap;
}

@media (max-width: 719px) {
    .ledger__row--step {
        grid-template-columns: 88px 1fr;
    }

    .ledger__row--step .ledger__desc,
    .ledger__row--step .ledger__meta {
        grid-column: 2;
    }
}

/* === QUOTE BLOCK ===

   Editorial pull quote: big portrait photo on the left, oversize
   italic Lora quote on the right that overlaps into the photo
   column and carries a red underline (architect's pen beneath the
   words, not down the gutter). Quote is the largest type in the
   block. Stacks under 540px. Promoted verbatim from the briefing
   page — now a system pattern. */

.quote-block {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-md);
    margin: 0;
    padding: 0;
    align-items: center;
    position: relative;
}

@media (min-width: 540px) {
    .quote-block {
        grid-template-columns: minmax(360px, 540px) 1fr;
        gap: 0;
        /* Text sits below the face level — the lower body of the
           portrait is faded to transparent, so anchoring the quote
           toward the lower-mid of the photo keeps the eye line
           beneath the subject's gaze without crowding the chin. */
        align-items: end;
    }
}

.quote-block__photo {
    /* Larger-than-life portrait. No hard frame — the image fades
       diagonally around the subject so the head reads as a vignette
       rather than a cropped rectangle. */
    width: 100%;
    max-width: 640px;
    margin: 0;
    position: relative;
    z-index: 1;
}

.quote-block__photo img {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 3 / 4;
    object-fit: cover;
    object-position: center top;
    border: 0;
    filter: grayscale(20%) contrast(1.02);
    /* Linear fade mask, tilted -15° so the gradient runs at a slight
       diagonal rather than straight down. Most of the image stays
       solid; only the lower-right corner softly dissolves into the
       page background. */
    -webkit-mask-image: linear-gradient(
        -15deg,
        transparent 0%,
        rgb(0 0 0 / 0.2) 18%,
        rgb(0 0 0 / 0.75) 38%,
        rgb(0 0 0) 58%,
        rgb(0 0 0) 100%
    );
    mask-image: linear-gradient(
        -15deg,
        transparent 0%,
        rgb(0 0 0 / 0.2) 18%,
        rgb(0 0 0 / 0.75) 38%,
        rgb(0 0 0) 58%,
        rgb(0 0 0) 100%
    );
}

.quote-block__text {
    margin: 0;
    font-family: var(--font-serif);
    font-style: italic;
    font-weight: 400;
    color: var(--color-text-black);
    font-size: clamp(1.5rem, 3.6vw, 2.5rem);
    line-height: 1.2;
    text-wrap: pretty;
    position: relative;
    z-index: 2;
    /* Cream halo — invisible against the page background, becomes a
       soft glow where the quote crosses dark areas of the portrait
       (e.g. the Karpathy stage backdrop). Layered shadows give a
       denser legibility lift without looking like a blunt outline. */
    text-shadow:
        0 0 4px rgb(250 249 246 / 0.95),
        0 0 10px rgb(250 249 246 / 0.85),
        0 0 22px rgb(250 249 246 / 0.55);
}

/* Desktop overlap — pull the quote deeper into the photo column so
   the opening words sit ON the image, not adjacent to it. The
   portrait is faded around its edges, so the text reads cleanly
   over whatever's left of the image. */
@media (min-width: 540px) {
    .quote-block__text {
        margin-left: -6rem;
    }
}

.quote-block__text p {
    margin: 0 0 var(--space-md);
    text-decoration-line: underline;
    text-decoration-color: var(--color-annotation);
    text-decoration-thickness: 2.5px;
    text-underline-offset: 0.18em;
    /* Skip the descenders so the underline sits cleanly. */
    text-decoration-skip-ink: auto;
}

.quote-block__text cite {
    display: block;
    font-family: var(--font-mono);
    font-style: normal;
    font-weight: 500;
    font-size: 0.6875rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-text-charcoal);
}

.quote-block__credit {
    display: block;
    font-family: var(--font-mono);
    font-size: 0.625rem;
    letter-spacing: 0.04em;
    color: var(--color-text-light-gray);
    margin-top: var(--space-xs);
}

.quote-block__credit a {
    color: inherit;
    text-decoration: underline;
    text-decoration-color: var(--color-border-medium);
    text-underline-offset: 0.15em;
}

/* Collapsible credit — `<details><summary>Source</summary>…</details>`.
   Summary reads as a single-word mono link; the full attribution
   appears when expanded. */
.quote-block__credit-toggle {
    margin-top: var(--space-sm);
}

.quote-block__credit-toggle > summary {
    list-style: none;
    cursor: pointer;
    display: inline-block;
    font-family: var(--font-mono);
    font-size: 0.625rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--color-text-light-gray);
    text-decoration: underline;
    text-decoration-color: var(--color-border-medium);
    text-underline-offset: 0.25em;
    transition: color var(--duration-fast) var(--ease-brand);
}

.quote-block__credit-toggle > summary::-webkit-details-marker {
    display: none;
}

.quote-block__credit-toggle > summary:hover {
    color: var(--color-text-charcoal);
}

.quote-block__credit-toggle[open] > summary {
    margin-bottom: var(--space-xs);
}

.quote-block__credit-toggle[open] > summary::after {
    content: " ▾";
    font-family: var(--font-sans);
}

.quote-block__credit-toggle:not([open]) > summary::after {
    content: " ▸";
    font-family: var(--font-sans);
}

/* === FIGURE PANEL ===

   Drafting-paper panel for diagrams: an 8px drafting grid painted via
   repeating gradients, four corner registration marks, and a mono
   FIG. footer. Two corner marks render via ::before/::after; the
   bottom pair need explicit empty <span> elements carrying
   .figure-panel__corner--bl / --br (the `content` property in the
   grouped rule is ignored by the real elements — kept for the
   pseudo-elements). Grid line color is raw rgba — a faded cut of
   --color-border-medium with no token equivalent. Pairs with
   .annotation-leader below for legible HTML annotations. */

.figure-panel {
    position: relative;
    padding: var(--space-lg);
    background-image:
        repeating-linear-gradient(0deg, rgba(196, 193, 185, 0.35) 0, rgba(196, 193, 185, 0.35) 0.5px, transparent 0.5px, transparent 8px),
        repeating-linear-gradient(90deg, rgba(196, 193, 185, 0.35) 0, rgba(196, 193, 185, 0.35) 0.5px, transparent 0.5px, transparent 8px);
}

.figure-panel::before,
.figure-panel::after,
.figure-panel__corner--bl,
.figure-panel__corner--br {
    content: "";
    position: absolute;
    width: 14px;
    height: 14px;
}

.figure-panel::before {
    top: 8px;
    left: 8px;
    border-top: 1px solid var(--color-border-dark);
    border-left: 1px solid var(--color-border-dark);
}

.figure-panel::after {
    top: 8px;
    right: 8px;
    border-top: 1px solid var(--color-border-dark);
    border-right: 1px solid var(--color-border-dark);
}

.figure-panel__corner--bl {
    bottom: 8px;
    left: 8px;
    border-bottom: 1px solid var(--color-border-dark);
    border-left: 1px solid var(--color-border-dark);
}

.figure-panel__corner--br {
    bottom: 8px;
    right: 8px;
    border-bottom: 1px solid var(--color-border-dark);
    border-right: 1px solid var(--color-border-dark);
}

.figure-panel__footer {
    display: flex;
    justify-content: space-between;
    margin-top: var(--space-md);
    font-family: var(--font-mono);
    font-size: 0.625rem;
    letter-spacing: 0.08em;
    color: var(--color-text-light-gray);
}

/* === ANNOTATION LEADER ===

   Leader annotation — red dot + hairline leading into a mono label
   with a gray sublabel. Real HTML, not SVG text, so annotations stay
   legible at every viewport. Stack a column of these beside a
   .figure-panel to label the drawing. */

.annotation-leader {
    display: grid;
    grid-template-columns: 24px 1fr;
    gap: 12px;
    align-items: start;
}

.annotation-leader__line {
    height: 1px;
    background: var(--color-annotation);
    margin-top: 8px;
    position: relative;
}

.annotation-leader__line::before {
    content: "";
    position: absolute;
    left: -3px;
    top: -2.5px;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--color-annotation);
}

.annotation-leader__label {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    color: var(--color-annotation);
}

.annotation-leader__sub {
    font-family: var(--font-mono);
    font-size: 0.688rem;
    letter-spacing: 0.04em;
    color: var(--color-text-gray);
    margin-top: 4px;
}

/* === UTILITY CLASSES === */

.text-mono { font-family: var(--font-mono); }
.text-sans { font-family: var(--font-sans); }
.tabular-nums { font-variant-numeric: tabular-nums; }
.text-technical-label {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-text-gray);
}
.text-small-caps { font-variant: small-caps; letter-spacing: 0.05em; }
.text-accent { color: var(--color-accent); }
.text-ochre { color: var(--color-ochre); }

.bg-cream { background-color: var(--color-bg-cream); }
.bg-warm-gray { background-color: var(--color-bg-warm-gray); }
.bg-accent-subtle { background-color: var(--color-accent-subtle); }

.border-technical { border: 1px solid var(--color-border-dark); }
.border-accent { border-color: var(--color-accent); }

/* === FORM PAGE LAYOUT ===

   Used for short-form pages (login, magic-link, password reset, signup-validate).
   Establishes a single centered column for the whole page so the title and the
   card share the same vertical center axis. Title block is wider than the card
   so longer headlines don't wrap awkwardly while the input column stays calm. */

.form-page__title {
    max-width: 640px;
    margin: 0 auto;
    text-align: center;
}

.form-page__title > .text-technical-label {
    display: block;
    margin-bottom: var(--space-sm);
}

.form-page__title > h1 {
    margin: 0;
}

.form-page__intro {
    max-width: 560px;
    margin: var(--space-md) auto 0;
    font-size: 1rem;
    line-height: 1.6;
    color: var(--color-text-charcoal);
}

.form-page__card {
    width: 100%;
    max-width: 28rem;
    margin: 0 auto;
}

.form-page__card-body {
    padding: var(--space-md);
}

/* Inline footnote for cardless form pages (confirmation, dead-end, status).
   When a page has no inputs, the card is the wrong primitive — use the title
   block + this centered text footer instead. */
.form-page__footnote {
    max-width: 560px;
    margin: 0 auto;
    text-align: center;
    font-size: 0.875rem;
    color: var(--color-text-gray);
}

.form-page__footnote a {
    color: var(--color-text-gray);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 0.2em;
    text-decoration-color: var(--color-border-medium);
    transition: color var(--duration-fast) var(--ease-brand),
                text-decoration-color var(--duration-fast) var(--ease-brand);
}

.form-page__footnote a:hover {
    color: var(--color-text-black);
    text-decoration-color: var(--color-text-black);
}

/* === MCP PAGE LAYOUT === */

/* Full-width MCP page layout override */
.mcp-page #main_header { display: none; }
.mcp-page main > div { max-width: 100% !important; padding: 0 !important; }

.mcp-container {
    max-width: 1000px;
    margin: 0 auto;
    padding: var(--space-2xl) var(--space-lg);
}

.mcp-header {
    border: 2px solid var(--color-border-dark);
    background: var(--color-bg-white);
    padding: var(--space-2xl);
    margin-bottom: var(--space-2xl);
    position: relative;
}

.mcp-header::before {
    content: '';
    position: absolute;
    top: 8px;
    left: 8px;
    right: 8px;
    bottom: 8px;
    border: 1px solid var(--color-border-light);
    pointer-events: none;
}

.install-note {
    font-size: 0.75rem;
    color: var(--color-text-gray);
    background: var(--color-bg-warm-gray);
    padding: var(--space-sm) var(--space-md);
    line-height: 1.6;
}

/* === NOTICES & CALLOUTS ===

   ANTI-PATTERN — never ship these (also documented in design-system.pen
   anti-patterns frame, kept in sync):
   1. Thick colored border on ONE side of a multi-line container ("border-left:
      3px solid red" + tinted bg). It is the single most recognizable tell of
      AI-generated UI. Use a tinted background OR a 1px full border. Never both.
      Never one-sided. Single-line tier markers (label tags, eyebrows) may use
      a 1px underline or text color alone, but never a 3px+ side bar.
      EXCEPTION: a 1–2px active-state indicator on a single-line sidebar nav
      item is the canonical pattern (VS Code, Notion, GitHub) and is allowed.
   2. Plausible-but-empty stats blocks ("100% verified · 0 errors · 12 sources").
      Stats theater. If a number isn't actionable, don't display it.
   3. Red used for decoration — oversized opening quote marks, ornamental
      dividers, accent flourishes on cards. The annotation red is reserved for
      VALUE: the number that matters, the verdict, the architect's pen mark on
      the part of the page that earns attention. If the red doesn't make a
      reader look at the *content*, remove it.
   4. Typography slop / generic AI voice. Sentence sprawl past 25 words.
      Adjective doublets ("clear and confident"). Em dashes three times per
      paragraph as a pacing crutch. Lists of three by default because that is
      the model's rhythm. Graduate-school reading level for no reason. Copy
      that could sit on any product's marketing page without changing a word.
      Target 8th-grade reading level, vary list length, replace em dashes
      with periods, cut doublets, and read the prose aloud.

   Canonical notice patterns: .notice (info), .notice--error (alert),
   .notice--warn (warn). Each has a .notice__eyebrow that carries the
   meaning in mono caps; the body stays charcoal for legibility. */

.notice {
    background: var(--color-bg-warm-gray);
    padding: var(--space-md);
    margin-bottom: var(--space-lg);
    font-family: var(--font-serif);
    font-style: italic;
    font-size: 0.875rem;
    line-height: 1.6;
    color: var(--color-text-charcoal);
}

/* Mono eyebrow carries the meaning; surface stays neutral. The pattern
   replaces the older "tinted body color on faint tinted bg" approach
   that read as dork-on-dirty — see anti-pattern #1 (no thick colored
   side bars) and the rose-plate aesthetic established by .highlight-rose. */
.notice__eyebrow {
    display: block;
    font-family: var(--font-mono);
    font-style: normal;
    font-size: 0.688rem;
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-text-gray);
    margin-bottom: var(--space-xs);
}

.notice--error {
    background: var(--color-annotation-rose);
}

.notice--error .notice__eyebrow {
    color: var(--color-annotation-deep);
}

.notice--warn .notice__eyebrow {
    color: var(--color-ochre);
}


.details-accordion {
    margin-bottom: var(--space-sm);
    border: 1px solid var(--color-border-light);
    background: var(--color-bg-cream);
}

.details-accordion summary {
    padding: var(--space-md);
    cursor: pointer;
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.details-accordion > div {
    padding: var(--space-lg);
    border-top: 1px solid var(--color-border-light);
    background: var(--color-bg-white);
}

/* Copy button for code blocks */
.copy-btn {
    position: absolute;
    top: 8px;
    right: 8px;
    background: var(--color-border-medium);
    color: var(--color-text-black);
    border: none;
    padding: 4px 8px;
    font-family: var(--font-mono);
    font-size: 0.688rem;
    cursor: pointer;
    opacity: 0.7;
    transition: opacity 0.2s;
}

.copy-btn:hover {
    opacity: 1;
}

/* === RESPONSIVE === */

@media (max-width: 768px) {
    :root {
        --space-3xl: calc(var(--grid-size) * 8);
        --space-2xl: calc(var(--grid-size) * 6);
    }
}

/* === TABS ===
   Generic, reusable sentence-case tab strip (issue #350). First
   consumer is /account/settings; the component is intentionally
   system-level so other surfaces (e.g. operator dashboards) can
   reuse it.
   Pairs with the Tabs Pencil component (node x0jV4).
   Active state uses a 2px black bottom underline that sits flush
   with the strip's 1px bottom rule — visual precedent is
   .nav-brand__link.is-active::after, but tabs use a thicker,
   sentence-case treatment because they are content-level
   ("About Tom Counsell"), not nav scaffolding (the navbar uses
   uppercase mono-caps for system metadata). */

.tabs {
    display: flex;
    gap: var(--space-lg);
    border-bottom: 1px solid var(--color-border-light);
    margin-bottom: var(--space-xl);
}

.tab {
    display: inline-block;
    padding: var(--space-sm) 0 calc(var(--space-sm) + 2px);
    color: var(--color-text-light-gray);
    text-decoration: none;
    font-family: var(--font-sans);
    font-size: 0.875rem;
    font-weight: 500;
    position: relative;
    transition: color var(--duration-fast) var(--ease-brand);
}

.tab:hover {
    color: var(--color-text-charcoal);
}

.tab--active {
    color: var(--color-text-black);
}

.tab--active::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    height: 2px;
    background: var(--color-text-black);
}

/* === ACCESSIBILITY === */

*:focus-visible {
    outline: 2px solid var(--color-annotation);
    outline-offset: 2px;
    transition: outline-offset var(--duration-fast) var(--ease-brand);
}

@media (prefers-contrast: high) {
    :root {
        --color-border-medium: #000000;
        --color-text-gray: #000000;
        --color-accent: #B91C1C;
    }
}
