/* ─────────────────────────────────────────────────────────────────────────
   Scaffold info site — shared styles
   Palette mirrored from the Scaffold app (frontend/src/App.tsx · GN).
   ───────────────────────────────────────────────────────────────────────── */

:root {
    --bg:            #092e19;
    --bg-elevated:   #0c3a20;
    --card:          #133622;
    --card-hi:       #17492c;
    --ink:           #e8f0ea;
    --ink-dim:       #e8f0ea;
    --ink-faint:     #e8f0ea;
    --border:        rgba(255, 255, 255, 0.08);
    --border-hi:     rgba(255, 255, 255, 0.18);
    --accent:        #8ecba4;
    --accent-dim:    rgba(142, 203, 164, 0.3);
    --accent-faint:  rgba(142, 203, 164, 0.08);

    --font: 'Montserrat', system-ui, -apple-system, 'Segoe UI', sans-serif;
    --maxw: 1120px;
    --header-h: 64px;
    --radius: 12px;
    --radius-md: 14px;          /* media / photo placeholders */
    --radius-lg: 20px;          /* feature cards */

    --divider: rgba(255, 255, 255, 0.55);
    --flow-gap: clamp(28px, 4.5vw, 52px);   /* vertical rhythm between stacked blocks */
    --tile-gap: clamp(24px, 4vw, 40px);     /* gap between the feature demo tiles */
}

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--ink);
    font-family: var(--font);
    font-size: 16px;
    line-height: 1.65;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

a { color: inherit; text-decoration: none; }

img, svg { max-width: 100%; }

h1, h2, h3 { line-height: 1.2; letter-spacing: -0.01em; margin: 0 0 0.5em; }
h1 { font-size: clamp(2rem, 5vw, 3.25rem); font-weight: 700; }
h2 { font-size: clamp(1.5rem, 3.2vw, 2.1rem); font-weight: 700; }
h3 { font-size: 1.15rem; font-weight: 600; }
p  { margin: 0 0 1rem; }

.container {
    width: 100%;
    max-width: var(--maxw);
    margin: 0 auto;
    padding: 0 clamp(20px, 5vw, 40px);
}

.accent { color: var(--accent); }
.muted  { color: var(--ink-dim); }

/* ── Header ──────────────────────────────────────────────────────────────── */
.site-header {
    position: sticky;
    top: 0;
    /* Above the demo cursor (z-index 100) so the sticky header covers it when
       a demo scrolls up behind the bar. */
    z-index: 200;
    background: rgba(7, 38, 22, 0.85);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--border);
}

.site-header .container {
    display: flex;
    align-items: center;
    gap: 16px;
    height: var(--header-h);
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
}
.brand svg, .brand img { display: block; }
.brand .brand-mark { width: 34px; height: auto; }
.brand .wordmark {
    font-size: 1.15rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    color: var(--ink);
    user-select: none;
}

.nav {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 4px;
}
.nav a {
    position: relative;
    padding: 8px 14px;
    border-radius: 8px;
    font-size: 0.9rem;
    font-weight: 500;
    letter-spacing: 0.01em;
    color: var(--ink-dim);
    transition: color 0.15s ease, background 0.15s ease;
    white-space: nowrap;
}
.nav a:hover { color: var(--ink); background: rgba(255, 255, 255, 0.04); }
.nav a[aria-current="page"] {
    color: var(--ink);
    background: var(--accent-faint);
}
.nav a[aria-current="page"]::after {
    content: "";
    position: absolute;
    left: 14px; right: 14px; bottom: 2px;
    height: 2px;
    background: var(--accent);
    border-radius: 2px;
}

/* Intermediate widths: above the mobile breakpoint the full horizontal nav
   plus the Launch button would otherwise overflow and force horizontal
   scroll, so tighten the links and button until they fit. */
@media (min-width: 721px) and (max-width: 955px) {
    .site-header .container { gap: 6px; }
    .brand .wordmark { font-size: 1rem; letter-spacing: 0.04em; }
    .nav { gap: 0; }
    .nav a { padding: 6px 7px; font-size: 0.76rem; }
    /* .site-header prefix so this wins over the later .nav-launch.btn base rule. */
    .site-header .nav-launch.btn {
        margin-left: 4px; padding: 5px 13px; font-size: 0.8rem; border-radius: 7px;
    }
}

/* Mobile menu toggle */
.nav-toggle {
    margin-left: auto;
    display: none;
    width: 40px; height: 40px;
    align-items: center; justify-content: center;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 8px;
    color: var(--ink);
    cursor: pointer;
}
.nav-toggle svg { width: 20px; height: 20px; }

@media (max-width: 720px) {
    .nav-toggle { display: inline-flex; }
    .nav {
        position: absolute;
        top: var(--header-h);
        left: 0; right: 0;
        flex-direction: column;
        align-items: stretch;
        gap: 2px;
        padding: 10px clamp(20px, 5vw, 40px) 18px;
        background: rgba(9, 46, 25, 0.98);
        backdrop-filter: blur(10px);
        border-bottom: 1px solid var(--border);
        transform: translateY(-8px);
        opacity: 0;
        pointer-events: none;
        transition: opacity 0.18s ease, transform 0.18s ease;
    }
    .nav.open { opacity: 1; transform: none; pointer-events: auto; }
    .nav a { padding: 12px 14px; font-size: 1rem; }
    .nav a[aria-current="page"]::after { display: none; }
    /* Full-width CTA at the bottom of the open menu. */
    .nav-launch.btn { margin: 8px 0 0; padding: 12px 14px; font-size: 1rem; }
}

/* ── Buttons ─────────────────────────────────────────────────────────────── */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 13px 24px;
    border-radius: 10px;
    font-family: var(--font);
    font-size: 0.98rem;
    font-weight: 600;
    cursor: pointer;
    border: 1px solid transparent;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.05s ease;
}
.btn:active { transform: translateY(1px); }
.btn-primary {
    background: var(--accent);
    color: #07271a;
}
.btn-primary:hover { background: #a6d9b7; }
.btn-ghost {
    background: transparent;
    border-color: var(--border-hi);
    color: var(--ink);
}
.btn-ghost:hover { background: rgba(255, 255, 255, 0.05); border-color: var(--accent-dim); }
/* Larger tap target for a page's primary call to action. */
.btn-lg {
    padding: 17px 40px;
    font-size: clamp(1.02rem, 1.7vw, 1.18rem);
    border-radius: 12px;
}

/* Launch CTA in the header nav (non-home pages), styled like the hero's
   "Launch Scaffold" button. The .nav a rules are more specific than
   .btn/.btn-primary, so restate the button look here (dark-green text on the
   accent fill) with enough specificity to win. Sits right of Resources. */
.nav-launch.btn {
    margin-left: 8px;
    /* Vertical padding trimmed so the pill height matches the nav links
       (~40px), not the taller hero button. */
    padding: 6px 22px;
    border-radius: 9px;
    font-size: 0.98rem;
    font-weight: 600;
    letter-spacing: normal;
    color: #07271a;                 /* dark green, matching the hero button */
    background: var(--accent);
}
.nav-launch.btn:hover { background: #a6d9b7; color: #07271a; }

/* ── Sections ────────────────────────────────────────────────────────────── */
.section { padding: clamp(56px, 9vw, 104px) 0; }
.section-sm { padding: clamp(40px, 6vw, 64px) 0; }
.section + .section { border-top: 1px solid var(--border); }

.eyebrow {
    display: inline-block;
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--accent);
    margin-bottom: 14px;
}

.lead {
    font-size: clamp(1.05rem, 2vw, 1.28rem);
    color: var(--ink-dim);
    max-width: 62ch;
}

/* ── Hero ────────────────────────────────────────────────────────────────── */
.hero {
    /* No bottom padding: the hero ends in the demos header, and .features owns
       the space down to the first tile so it equals the tile-to-tile gap. */
    padding: clamp(28px, 5vw, 56px) 0 0;
    text-align: center;
}
.hero .logo-xl { display: block; margin: 0 auto 24px; width: clamp(140px, 26vw, 210px); height: auto; }
.hero h1 {
    max-width: none;
    margin-left: auto;
    margin-right: auto;
    white-space: nowrap;                     /* keep the headline on one line */
    font-size: clamp(1.1rem, 4.6vw, 3rem);   /* scale with width so it never overflows */
}
.hero .lead { margin: 18px auto 0; text-align: center; }
/* The CTA sits directly under the headline, above the intro copy, so it needs
   space on both sides — the leads add their own 18px on top of the lower gap. */
.hero .cta-row {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    justify-content: center;
    margin: 30px 0 14px;
}
/* Divider + header introducing the feature demos below. The divider's own rule
   only sets space beneath the line, so add the matching space above it here. */
.hero .section-divider { margin-top: var(--flow-gap); }
.demos-head {
    max-width: 46ch;
    margin: 0 auto;
    text-align: center;
    font-size: clamp(1.35rem, 3.6vw, 2.35rem);
}

/* ── Cards / grids ───────────────────────────────────────────────────────── */
.grid {
    display: grid;
    gap: 22px;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
.card {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 26px 24px;
    transition: border-color 0.15s ease, transform 0.15s ease, background 0.15s ease;
}
.card:hover { border-color: var(--border-hi); background: var(--card-hi); transform: translateY(-2px); }
.card h3 { margin-bottom: 8px; }
.card-social {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin-top: 12px;
    color: var(--ink-dim);
    font-size: 0.9rem;
    transition: color 0.18s ease;
}
.card-social:hover { color: var(--accent); }
.card-social svg { width: 17px; height: 17px; fill: currentColor; }
.card p { color: var(--ink-dim); margin: 0; font-size: 0.96rem; }
.card .icon {
    width: 40px; height: 40px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 10px;
    background: var(--accent-faint);
    color: var(--accent);
    margin-bottom: 16px;
}
.card .icon svg { width: 22px; height: 22px; }

/* Numbered steps */
.steps { counter-reset: step; display: grid; gap: 20px; }
.step {
    display: grid;
    grid-template-columns: 44px 1fr;
    gap: 18px;
    align-items: start;
    padding: 22px 24px;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
.step::before {
    counter-increment: step;
    content: counter(step);
    display: flex; align-items: center; justify-content: center;
    width: 44px; height: 44px;
    border-radius: 50%;
    border: 1px solid var(--accent-dim);
    background: var(--accent-faint);
    color: var(--accent);
    font-weight: 700;
    font-size: 1.05rem;
}
.step h3 { margin-bottom: 4px; }
.step p { margin: 0; color: var(--ink-dim); font-size: 0.96rem; }

/* Resource / link list */
.link-list { display: grid; gap: 14px; }
.link-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 18px 22px;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    transition: border-color 0.15s ease, background 0.15s ease;
}
.link-item:hover { border-color: var(--border-hi); background: var(--card-hi); }
.link-item .li-title { font-weight: 600; }
.link-item .li-desc { color: var(--ink-dim); font-size: 0.9rem; margin-top: 2px; }
.link-item .arrow { color: var(--accent); flex-shrink: 0; }

/* Prose column for text-heavy pages */
.prose { max-width: 68ch; }
.prose h2 { margin-top: 2em; }
.prose h2:first-child { margin-top: 0; }
.prose p { color: var(--ink-dim); }
.prose p, .prose li { line-height: 1.8; }
.prose strong { color: var(--ink); font-weight: 600; }
.prose ul { color: var(--ink-dim); margin: 0 0 1.4em; padding-left: 22px; display: flex; flex-direction: column; gap: 14px; }
.prose a { color: var(--ink); text-decoration: underline; }
.prose a:hover { color: var(--accent); }
.pull {
    margin: 2em 0;
    padding: 20px 26px;
    border-left: 3px solid var(--accent);
    background: var(--accent-faint);
    border-radius: 0 8px 8px 0;
    font-size: 1.1rem;
    color: var(--ink);
}

/* Callout band */
.band {
    text-align: center;
    background: var(--bg-elevated);      /* solid — the lighter end of the former gradient */
}
.band h2 { max-width: 20ch; margin-left: auto; margin-right: auto; }
.band .cta-row { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; margin-top: 28px; }

/* ── Feature walkthrough ─────────────────────────────────────────────────── */
/* The hero's demos header reads as the first item in this stack, so the space
   above the first tile matches the gap between tiles (hero padding-bottom is 0). */
.features { padding-top: var(--tile-gap); }
.features .container {
    display: grid;
    /* minmax(0, 1fr) caps the track at the container width: without it the
       auto track grows to the widest demo's min-content and overflows narrow
       screens (horizontal scroll). The demos are fluid and self-clip within. */
    grid-template-columns: minmax(0, 1fr);
    gap: var(--tile-gap);
}
.feature {
    text-align: center;
    padding: clamp(28px, 5vw, 56px) clamp(20px, 4vw, 48px);
    border: 1px solid var(--border-hi);
    border-radius: var(--radius-lg);
    background: var(--bg-elevated);      /* solid — the lighter end of the former gradient */
}
.feature h2 { margin-bottom: 14px; font-weight: 600; }
.feature-desc {
    font-size: clamp(1.02rem, 1.7vw, 1.18rem);
    color: var(--ink-dim);
    max-width: 46ch;
    margin: 0 auto clamp(24px, 4vw, 40px);
}

/* ── Placeholders — shared surface for demo boxes and photos ──────────────────
   Swap each .media-placeholder / .about-photo for a <video> or <img> later. */
.media-placeholder,
.about-photo {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    text-align: center;
    color: var(--ink-dim);
    background:
        radial-gradient(120% 120% at 50% 0%, var(--accent-faint), transparent 60%),
        var(--card);
    border: 1.5px dashed var(--border-hi);
    border-radius: var(--radius-md);
}
.media-placeholder .play,
.about-photo .ph-icon { color: var(--accent); opacity: 0.9; }
.media-label,
.ph-label { font-weight: 600; color: var(--ink); }
.media-note,
.ph-note {
    font-size: 0.75rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-faint);
}

/* Demo / video placeholder (16:9) */
.media-placeholder {
    max-width: 760px;
    margin: 0 auto;
    padding: 24px;
    aspect-ratio: 16 / 9;
}
.media-placeholder .play { width: clamp(40px, 6vw, 54px); height: clamp(40px, 6vw, 54px); }
.media-label { font-size: 0.98rem; max-width: 34ch; }

/* ── Interactive demos ───────────────────────────────────────────────────────
   Faithful, self-driving mocks of the Scaffold app UI, shown in place of the
   video placeholders. Colours mirror the app's GN palette exactly (App.tsx) so
   the demo reads as the real product. Driven by js/main.js. */
.demo {
    max-width: 720px;
    margin: 0 auto;
    /* Positioning context for the absolutely-positioned demo cursor, so it
       anchors to the demo root rather than a distant ancestor. */
    position: relative;
}

/* 1 · Set your own agenda — a mock of the app's opening screen:
   logo, intro line, and the chatbox that auto-types a thought. */
.demo-screen {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: clamp(24px, 4vw, 44px);
    padding: clamp(28px, 5vw, 48px) clamp(20px, 4vw, 40px);
    background: var(--bg);                   /* GN.bg — the app canvas */
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}
.demo-logo { width: clamp(84px, 16vw, 120px); height: auto; }
.demo-intro {
    margin: 0;
    font-size: clamp(1rem, 2.4vw, 1.25rem);
    color: var(--ink);
    text-align: center;
}

.demo-agenda .demo-chatbox {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    max-width: 560px;
    background: #3d5c48;                     /* GN.cardBg */
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 8px;
    padding: 16px 20px;
}
.demo-field {
    position: relative;
    flex: 1;
    min-height: 27px;
    font-size: 17px;
    line-height: 1.55;
    color: var(--ink);
    text-align: left;               /* override .feature's centered text */
    overflow-wrap: anywhere;
}
.demo-placeholder {
    position: absolute;
    inset: 0;
    color: rgba(232, 240, 234, 0.35);       /* GN.inkFaint */
    pointer-events: none;
    transition: opacity 0.15s ease;
}
.demo-agenda.is-typing .demo-placeholder,
.demo-agenda.has-text .demo-placeholder { opacity: 0; }

.demo-caret {
    display: inline-block;
    width: 2px;
    height: 1.25em;
    vertical-align: text-bottom;
    margin-bottom: 1px;
    background: var(--accent);              /* GN.accent — caretColor */
    opacity: 0;
}
/* Solid while typing; blinks when the field is idle. */
.demo-agenda.is-typing .demo-caret { opacity: 1; }
.demo-agenda.is-idle .demo-caret { animation: demoCaretBlink 1.05s step-end infinite; }
@keyframes demoCaretBlink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }

.demo-send {
    flex-shrink: 0;
    width: 36px; height: 36px;
    border-radius: 8px;
    font-size: 16px;
    font-family: var(--font);
    display: flex; align-items: center; justify-content: center;
    border: 1px solid rgba(255, 255, 255, 0.08);
    background: transparent;
    color: rgba(232, 240, 234, 0.35);
    cursor: not-allowed;
    transition: all 0.15s ease;
}
/* Enabled state — mirrors PromptInput's active send button. */
.demo-agenda.has-text .demo-send {
    border-color: var(--accent-dim);
    background: var(--accent-faint);
    color: var(--ink);
    cursor: pointer;
}
/* Brief pulse when a thought is "sent" before the next one types. */
.demo-agenda.is-sending .demo-send {
    transform: scale(0.9);
    background: var(--accent);
    color: #07271a;
}

@media (prefers-reduced-motion: reduce) {
    .demo-caret { display: none; }
}

/* 3 · Establish your own criteria for success — a mock of a live session:
   the top prompt bar with the wrap-up checkmark in the right gutter, two
   message cards below, and a demo cursor that clicks the checkmark, opens the
   end-session confirmation, then clicks "Yes, end session". */
.demo-conclude { position: relative; }
.demo-app {
    display: flex;
    flex-direction: column;
    gap: clamp(14px, 2.4vw, 22px);
    /* No bottom padding: the trailing connector runs to the window's edge, so
       the thread reads as continuing past the frame (there's more, unshown). */
    padding: clamp(20px, 4vw, 34px) clamp(18px, 3.5vw, 32px) 0;
    background: var(--bg);                    /* GN.bg — the app canvas */
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    overflow: hidden;                         /* clip the trailing poles at the edge */
    text-align: left;                         /* override .feature's centering */
}
.demo-disclaimer {
    margin: 0;
    font-size: clamp(7.5px, 1.4vw, 10px);
    line-height: 1.35;
    color: rgba(232, 240, 234, 0.35);        /* GN.inkFaint */
    text-align: center;
    white-space: nowrap;                     /* keep it to a single line */
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Prompt bar + checkmark share a row; the checkmark is centred beside it. */
.demo-top { display: flex; align-items: center; gap: 12px; }
.demo-input {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 12px;
    background: #3d5c48;                       /* GN.cardBg */
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 8px;
    padding: clamp(11px, 1.8vw, 15px) clamp(14px, 2.4vw, 22px);
}
.demo-input-ph {
    flex: 1;
    font-size: clamp(13px, 1.9vw, 15px);
    color: rgba(232, 240, 234, 0.35);        /* GN.inkFaint — placeholder */
}
.demo-arrow {
    flex-shrink: 0;
    width: 32px; height: 32px;
    border-radius: 8px;
    font-size: 15px;
    font-family: var(--font);
    display: flex; align-items: center; justify-content: center;
    border: 1px solid rgba(255, 255, 255, 0.08);
    background: transparent;
    color: rgba(232, 240, 234, 0.35);        /* GN.inkFaint — disabled send */
}

/* Wrap-up checkmark — a 40px outlined circle, faithful to the app button. */
.demo-check-wrap { position: relative; flex-shrink: 0; }
.demo-check {
    width: clamp(36px, 5.4vw, 42px);
    height: clamp(36px, 5.4vw, 42px);
    border-radius: 50%;
    border: 1.8px solid var(--ink);
    background: transparent;
    color: var(--ink);
    display: flex; align-items: center; justify-content: center;
    padding: 0;
    transition: background 0.15s ease, transform 0.12s ease;
}
.demo-check svg { width: 60%; height: 60%; }
.demo-conclude.is-hover-check .demo-check { background: rgba(255, 255, 255, 0.06); }
.demo-conclude.is-press-check .demo-check { transform: scale(0.9); background: rgba(255, 255, 255, 0.12); }

/* End-session confirmation — drops down from the checkmark, aligned to its
   right edge (App.tsx EndSessionConfirm). Hidden until the checkmark is clicked. */
.demo-popover {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    width: clamp(210px, 30vw, 250px);
    background: var(--bg);                     /* GN.bg */
    border: 1.5px solid var(--ink);
    border-radius: 14px;
    padding: 16px 18px 14px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
    z-index: 5;
    opacity: 0;
    transform: translateY(-6px) scale(0.97);
    transform-origin: top right;
    pointer-events: none;
    transition: opacity 0.16s ease, transform 0.16s ease;
}
.demo-conclude.is-open .demo-popover { opacity: 1; transform: none; }
.demo-popover h3 {
    margin: 0 0 14px;
    font-size: clamp(12px, 1.9vw, 14px);
    font-weight: 600;
    line-height: 1.4;
    color: var(--ink);
}
.demo-popover-actions {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.demo-cancel {
    background: transparent; border: none; padding: 0;
    font-family: var(--font); font-size: clamp(11px, 1.6vw, 12px);
    color: rgba(232, 240, 234, 0.6);          /* GN.inkDim */
    text-decoration: underline;
}
.demo-end {
    flex-shrink: 0;
    background: transparent; border: 1px solid var(--ink);
    color: var(--ink);
    font-family: var(--font); font-size: clamp(11px, 1.6vw, 12px);
    padding: 6px 11px; border-radius: 6px; white-space: nowrap;
    transition: background 0.15s ease, transform 0.12s ease;
}
.demo-conclude.is-hover-end .demo-end { background: rgba(255, 255, 255, 0.06); }
.demo-conclude.is-press-end .demo-end { transform: scale(0.94); background: rgba(255, 255, 255, 0.14); }

/* Message thread — cards with a crosshair in the right gutter and vertical
   connector poles between them (App.tsx MessageCard / connectors). */
.demo-thread { display: flex; flex-direction: column; }
.demo-row { display: flex; align-items: center; gap: 12px; }
.demo-card {
    flex: 1;
    border-radius: 8px;
    padding: clamp(12px, 2vw, 16px) clamp(14px, 2.4vw, 22px);
    border: 1px solid rgba(255, 255, 255, 0.08);
}
.demo-card.assistant { background: #133622; }  /* GN.cardBgAssistant */
.demo-card.user      { background: #3d5c48; }  /* GN.cardBg */
.demo-card p {
    margin: 0;
    font-size: clamp(12px, 1.9vw, 14.5px);
    line-height: 1.5;
    color: var(--ink);
}
.demo-target {
    flex-shrink: 0;
    width: clamp(36px, 5.4vw, 42px);
    display: flex; align-items: center; justify-content: center;
    color: var(--ink);
    opacity: 0.28;
}
.demo-target svg { width: 20px; height: 20px; }
/* Connector poles, echoing the 22% / 78% verticals between cards. The
   right margin matches the card gutter (gap + crosshair) so the poles align
   under the card column, not the full row. */
.demo-connector {
    position: relative;
    height: clamp(20px, 3.4vw, 30px);
    margin-right: calc(clamp(36px, 5.4vw, 42px) + 12px);
}
.demo-connector span {
    position: absolute; top: 0; bottom: 0; width: 4px; border-radius: 2px;
    background: rgba(200, 210, 200, 0.45);    /* GN.connector */
}
.demo-connector span:first-child { left: 22%; }
.demo-connector span:last-child  { left: 78%; }

/* When the session ends, the thread softens back and the checkmark fills in. */
.demo-conclude.is-ended .demo-thread,
.demo-conclude.is-ended .demo-top { opacity: 0.5; transition: opacity 0.4s ease; }
.demo-conclude.is-ended .demo-check {
    background: var(--accent);
    border-color: var(--accent);
    color: #07271a;
}

/* Demo cursor — hidden until the sequence runs; glides between targets. */
.demo-cursor {
    position: absolute;
    top: 0; left: 0;
    width: 22px; height: 22px;
    opacity: 0;
    pointer-events: none;
    filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.4));
    transform: translate(var(--cx, 0), var(--cy, 0));
    transition: transform 0.7s cubic-bezier(0.5, 0, 0.2, 1), opacity 0.3s ease;
    /* Above every demo overlay (export menu z-30, end-session popover) so the
       cursor stays visible when it moves onto them. */
    z-index: 100;
}
.demo.is-running .demo-cursor { opacity: 1; }

/* 4 · Reflect on your progress — the frozen "interaction completed" card
   (App.tsx KeyTakeawaysCard). The cursor clicks "+ Add takeaway", a field
   drops in, and a takeaway auto-types into it. The interaction continues
   below, connectors running off the bottom edge. */
/* Panels and connectors butt directly together (no inter-child gap), so the
   poles run flush out of one panel and into the next — as in the app. */
.demo-reflect .demo-app { gap: 0; }
/* No crosshair gutter here — the message card spans the full width like the
   takeaways panel, so the connectors span full width too. */
.demo-reflect .demo-connector { margin-right: 0; }
.demo-takeaways {
    display: flex;
    flex-direction: column;
    gap: clamp(12px, 2vw, 16px);
    background: #3d5c48;                       /* GN.cardBg */
    border: 1.8px solid var(--ink);
    border-radius: 10px;
    padding: clamp(16px, 2.6vw, 22px) clamp(18px, 3vw, 26px);
    color: var(--ink);
}
.demo-tk-header {
    text-align: center;
    font-size: clamp(12.5px, 2vw, 15px);
    font-style: italic;
    color: var(--ink);
}

/* The takeaway field only exists once "+ Add takeaway" is clicked. */
.demo-tk-list { display: none; }
.demo-reflect.is-adding .demo-tk-list { display: block; }
@keyframes tkIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
.demo-reflect.is-adding .demo-tk-row { animation: tkIn 0.28s cubic-bezier(0.16, 1, 0.3, 1) both; }
.demo-tk-row { display: flex; align-items: center; gap: 12px; }
.demo-tk-field {
    position: relative;
    flex: 1;
    min-height: 1.5em;
    border: 1px solid rgba(255, 255, 255, 0.18);  /* GN.borderLatest */
    border-radius: 10px;
    padding: clamp(9px, 1.6vw, 12px) clamp(12px, 2vw, 16px);
    font-size: clamp(12.5px, 1.9vw, 15px);
    line-height: 1.5;
    color: var(--ink);
    text-align: left;                             /* override .feature centering */
    overflow-wrap: anywhere;
}
.demo-tk-ph {
    position: absolute;
    inset: clamp(9px, 1.6vw, 12px) clamp(12px, 2vw, 16px);
    font-style: italic;
    color: rgba(232, 240, 234, 0.35);            /* GN.inkFaint */
    pointer-events: none;
    transition: opacity 0.15s ease;
}
.demo-reflect.tk-has-text .demo-tk-ph { opacity: 0; }
.demo-tk-caret {
    display: inline-block;
    width: 2px; height: 1.15em;
    vertical-align: text-bottom; margin-bottom: 1px;
    background: var(--accent);                    /* GN.accent — caretColor */
    opacity: 0;
}
.demo-reflect.tk-typing .demo-tk-caret { opacity: 1; }
.demo-reflect.tk-idle .demo-tk-caret { animation: demoCaretBlink 1.05s step-end infinite; }
.demo-tk-remove {
    flex-shrink: 0;
    width: 26px; height: 26px;
    border: none; background: transparent;
    color: var(--ink);
    display: flex; align-items: center; justify-content: center;
    padding: 0;
}
.demo-tk-remove svg { width: 16px; height: 16px; }

/* Action row — "+ Add takeaway" (underlined) on the left, pin and
   "Continue interaction" on the right. */
.demo-tk-actions {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.demo-tk-add {
    background: transparent; border: none; padding: 0;
    font-family: var(--font); font-size: clamp(12px, 1.8vw, 14px);
    color: var(--ink); text-decoration: underline;
    transition: opacity 0.12s ease;
}
.demo-reflect.is-press-add .demo-tk-add { opacity: 0.5; }
/* Pin and "Continue interaction" travel together on the right, as in App.tsx. */
.demo-tk-action-group {
    display: flex; align-items: center; gap: 16px; flex-shrink: 0;
}
/* Pushpin toggle — filled pin plus an underlined label, matching the app's
   default (pinned) state. Static in the demos: nothing here toggles it. */
.demo-tk-pin {
    display: inline-flex; align-items: center; gap: 6px;
    background: transparent; border: none; padding: 0;
    font-family: var(--font); font-size: clamp(12px, 1.8vw, 14px);
    color: var(--ink); white-space: nowrap;
}
.demo-tk-pin span { text-decoration: underline; }
.demo-tk-pin svg { width: 15px; height: 15px; flex-shrink: 0; }
.demo-tk-continue {
    flex-shrink: 0;
    background: transparent;
    border: 1px solid rgba(255, 255, 255, 0.18);   /* GN.borderLatest */
    color: var(--ink);
    font-family: var(--font); font-size: clamp(12px, 1.8vw, 14px);
    padding: 7px 16px; border-radius: 6px; white-space: nowrap;
}

/* 5 · Save and export for future reference — a wider mock of the whole app
   window (header + canvas + format sidebar). The cursor clicks "Export chat",
   the file-type menu opens, then it clicks "Text file". Mirrors App.tsx's
   header actions, export menu, and FormatSidebar. */
.demo-export {
    max-width: 100%;
    /* Shared layout metrics — the sidebar width and the canvas gutters. Kept in
       one place so the header title can be centred over the takeaways panel. */
    --fmt-w: clamp(44px, 5vw, 60px);
    --canvas-pl: clamp(16px, 3vw, 40px);
    --canvas-pr: clamp(56px, 6.5vw, 74px);
}
.demo-window {
    background: var(--bg);                     /* GN.bg */
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    overflow: hidden;
}

/* Header — logo (left) and actions (right); the title is absolutely centred
   over the takeaways panel below (not the whole bar). */
.demo-header {
    position: relative;
    display: flex; align-items: center; justify-content: space-between;
    gap: clamp(12px, 1.8vw, 20px);
    min-height: 48px;
    padding: 7px clamp(12px, 2vw, 24px);
    border-bottom: 1px solid var(--border);
    background: rgba(7, 38, 22, 0.97);
}
.demo-hd-left { display: flex; align-items: center; gap: 10px; min-width: 0; }
.demo-hd-logo {
    font-size: clamp(13px, 1.9vw, 21px);
    font-weight: 600; letter-spacing: 0.12em; color: var(--ink);
    white-space: nowrap;
}
.demo-hd-mark { width: clamp(22px, 3vw, 34px); height: auto; flex-shrink: 0; }
.demo-hd-title {
    /* In-flow between the logo and actions so it can never overlap them; it
       shrinks and ellipsizes when the header is tight rather than sitting on
       top of its neighbours (which it did while absolutely positioned). */
    flex: 0 1 auto;
    min-width: 0;
    text-align: center;
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 5px 12px;
    color: var(--ink);
    font-size: clamp(11px, 1.5vw, 14px); letter-spacing: 0.02em;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.demo-hd-actions {
    display: flex; align-items: center; gap: clamp(4px, 0.7vw, 8px);
    min-width: 0;
}
.demo-hd-btn {
    height: 22px; padding: 0 8px; border-radius: 3px;
    border: 1px solid var(--border); background: transparent;
    color: rgba(232, 240, 234, 0.6);          /* GN.inkDim */
    font-family: var(--font);
    font-size: clamp(8px, 1vw, 10px); letter-spacing: 0.08em;
    white-space: nowrap; flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    line-height: 1;
}
.demo-hd-q {
    width: 22px; padding: 0; border-radius: 50%;
    font-size: 11px; font-weight: 600;
}

/* Export-chat button + dropdown menu. The wrap is a flex box so its button
   aligns with the sibling header buttons (not offset by inline baseline). */
.demo-export-wrap { position: relative; flex-shrink: 0; display: flex; align-items: center; }
.demo-export.is-press-export .demo-export-btn,
.demo-export.is-menu-open .demo-export-btn { color: var(--ink); background: rgba(255, 255, 255, 0.04); }
.demo-export-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    z-index: 30;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 4px;
    display: flex; flex-direction: column;
    min-width: 120px;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
    opacity: 0;
    transform: translateY(-6px) scale(0.98);
    transform-origin: top right;
    pointer-events: none;
    transition: opacity 0.16s ease, transform 0.16s ease;
}
.demo-export.is-menu-open .demo-export-menu { opacity: 1; transform: none; }
.demo-ex-item {
    background: transparent; border: none;
    color: var(--ink); font-family: var(--font);
    font-size: clamp(9.5px, 1.2vw, 11px); letter-spacing: 0.06em;
    padding: 8px 10px; border-radius: 4px; text-align: left; white-space: nowrap;
}
.demo-export.is-hover-text .demo-ex-text { background: rgba(255, 255, 255, 0.06); }
.demo-export.is-press-text .demo-ex-text { background: rgba(255, 255, 255, 0.12); }

/* Body — canvas (left) + format sidebar (right). */
.demo-body { display: flex; flex-direction: row; align-items: stretch; }
.demo-export .demo-canvas {
    flex: 1; min-width: 0;
    /* Wide right gutter: both panels stop at the content box (so their right
       edges align), and the message card's crosshair floats in the gutter —
       adding space between the panels and the format buttons. */
    padding: clamp(16px, 2.5vw, 28px) var(--canvas-pr) 0 var(--canvas-pl);
    display: flex; flex-direction: column; gap: 0;
    overflow: hidden;                          /* clip the trailing connectors */
    text-align: left;                          /* override .feature's centering */
}
.demo-export .demo-tk-list { display: block; }
/* Both panels span the full content width, so connectors span it too. */
.demo-export .demo-connector { margin-right: 0; }
/* The trailing connector grows to fill any leftover canvas height (e.g. when
   the format sidebar is taller), so its poles always run to the window's
   bottom edge and are clipped there — the thread reads as continuing. */
.demo-export .demo-canvas > .demo-connector:last-child { flex: 1 1 auto; }
/* The crosshair floats in the right gutter instead of taking a flex column,
   so the message card stays full width and aligns with the takeaways panel. */
.demo-export .demo-row { position: relative; }
.demo-export .demo-target {
    position: absolute;
    top: 50%;
    left: calc(100% + 16px);
    transform: translateY(-50%);
}

/* Format sidebar — 60px rail of formatting tools. */
.demo-format {
    width: var(--fmt-w);
    flex-shrink: 0;
    display: flex; flex-direction: column; align-items: stretch; gap: 8px;
    padding: 16px 8px;
    border-left: 1px solid var(--border);
}
.demo-fmt-btn {
    position: relative;
    background: transparent; border: none;
    color: var(--ink);
    font-family: var(--font);
    font-size: clamp(15px, 2vw, 22px);
    height: clamp(32px, 4vw, 44px);
    padding: 0; line-height: 1;
    opacity: 0.85;
    display: flex; align-items: center; justify-content: center;
    border-radius: 6px;
}
.demo-fmt-undo { opacity: 0.3; }               /* nothing to undo → dimmed */
.demo-fmt-btn svg { width: clamp(16px, 2.2vw, 22px); height: clamp(16px, 2.2vw, 22px); }
.demo-fmt-divider { height: 1px; background: var(--border); margin: 4px 6px; }
.demo-fmt-badge {
    position: absolute; right: 8px; bottom: 6px;
    width: 12px; height: 12px; border-radius: 50%;
    background: var(--bg); color: var(--ink);
    font-size: 11px; line-height: 11px; font-weight: 700;
    display: flex; align-items: center; justify-content: center;
}

/* 2 · Remember kernels of insight — a mock session with the format sidebar.
   The cursor drags to select a sentence, then clicks Bold (B) and the sentence
   turns bold. Reuses the window / canvas / format-sidebar pieces. */
.demo-highlight {
    max-width: 100%;                           /* full width like the export demo */
    --fmt-w: clamp(44px, 5vw, 60px);
    --canvas-pl: clamp(16px, 3vw, 40px);
    /* Smaller right gutter than the export demo — the crosshair/checkmark float
       here and the format bar sits close — but with a touch of breathing room so
       the checkmark doesn't crowd the formatting bar. */
    --canvas-pr: clamp(62px, 6.4vw, 76px);
}
.demo-highlight .demo-canvas {
    flex: 1; min-width: 0;
    padding: clamp(16px, 2.5vw, 26px) var(--canvas-pr) 0 var(--canvas-pl);
    display: flex; flex-direction: column; gap: 0;
    overflow: hidden;                          /* clip the trailing connectors */
    text-align: left;                          /* override .feature's centering */
}
/* Disclaimer and input row get breathing room; cards/connectors stay flush. */
.demo-highlight .demo-disclaimer { margin-bottom: clamp(14px, 2.2vw, 22px); }
.demo-highlight .demo-input-row  { margin-bottom: clamp(20px, 3vw, 32px); }
/* Panels span the full content width; crosshair + checkmark float in the gutter. */
.demo-highlight .demo-connector { margin-right: 0; }
.demo-highlight .demo-canvas > .demo-connector:last-child { flex: 1 1 auto; }
.demo-highlight .demo-row { position: relative; }
.demo-highlight .demo-target,
.demo-highlight .demo-check {
    position: absolute;
    top: 50%;
    left: calc(100% + 16px);
    transform: translateY(-50%);
}

/* The sentence being selected + bolded. Selection tint and bold treatment
   (weight 800, white) match App.tsx. */
.demo-boldable { border-radius: 2px; transition: background 0.15s ease; }
.demo-highlight.is-selecting .demo-boldable { background: rgba(142, 203, 164, 0.25); }
.demo-highlight.is-bold .demo-boldable { font-weight: 800; color: #ffffff; }
/* Bold tool press feedback. */
.demo-highlight.is-press-bold .demo-fmt-bold { opacity: 1; background: rgba(255, 255, 255, 0.14); }

@media (prefers-reduced-motion: reduce) {
    .demo-cursor { display: none; }
    .demo-caret, .demo-tk-caret { display: none; }
    /* Show the end-session confirmation statically — the key UI, no motion. */
    .demo-conclude .demo-popover { opacity: 1; transform: none; }
    .demo-conclude .demo-check { background: rgba(255, 255, 255, 0.06); }
    /* Show the export menu statically — the key UI, no motion. */
    .demo-export .demo-export-menu { opacity: 1; transform: none; }
    /* Show the sentence already bolded — the outcome, no motion. */
    .demo-highlight.is-bold .demo-boldable,
    .demo-highlight .demo-boldable { font-weight: 800; color: #ffffff; }
}

/* Photo placeholder */
.about-photo { padding: 20px; }
.about-photo.portrait  { aspect-ratio: 3 / 4; }
.about-photo.landscape { aspect-ratio: 4 / 3; }
/* Real photos reuse the placeholder box (aspect-ratio + layout width) but drop
   the dashed frame and cover-fill their slot. */
img.about-photo {
    display: block;
    object-fit: cover;
    padding: 0;
    border: none;
    background: none;
}
.card img.about-photo { width: 100%; }   /* community cards have no width class */
.about-photo .ph-icon { width: 38px; height: 38px; }
.ph-label { font-size: 0.9rem; }

/* ── About Us ────────────────────────────────────────────────────────────── */
.about-title {
    text-align: center;
    font-style: italic;
    font-weight: 600;
    font-size: clamp(1.9rem, 5vw, 3rem);
    margin: 0;
}
/* Body copy on the Philosophy / About Us / Community pages — a touch larger
   and more open than the base paragraph so the long-form text reads easily. */
.about-copy p, .bio p { font-size: 1.1rem; line-height: 1.8; }
.about-copy p { margin-bottom: 1.4em; }
.about-copy p:last-child { margin-bottom: 0; }

/* Long-form resource writing: .about-copy plus the headings and lists that a
   piece long enough to need sections wants. Sits on top of .about-copy, so a
   page opts in with class="about-copy doc-copy". */
.doc-copy h2 {
    font-style: italic;
    font-weight: 600;
    font-size: clamp(1.4rem, 3vw, 1.9rem);
    margin: 1.9em 0 0.6em;
}
.doc-copy h3 {
    font-style: italic;
    font-size: 1.15rem;
    color: var(--accent);
    margin: 1.8em 0 0.5em;
}
.doc-copy > :first-child { margin-top: 0; }
.doc-copy ul, .doc-copy ol {
    margin: 0 0 1.4em;
    padding-left: 1.4em;
    display: grid;
    gap: 10px;
    font-size: 1.1rem;
    line-height: 1.8;
    color: var(--ink-dim);
}
.doc-copy li::marker { color: var(--accent); }
/* A pulled-out line between sections, matching the section rules elsewhere. */
.doc-rule {
    border: 0;
    border-top: 1px solid var(--border-hi);
    width: 120px;
    margin: 2.4em 0;
}

.about-photo-centered { width: clamp(200px, 40%, 280px); margin: 30px auto 40px; }

/* Bio: text wraps around a floated photo, matching the mockups.
   All vertical spacing between blocks flows from --flow-gap on the divider,
   so the section paddings that would otherwise stack are zeroed out. */
.about-intro { padding-bottom: 0; }
/* Equal space around each divider, collapse-proof: the space ABOVE the line is
   the section's top padding, the space BELOW is the divider's bottom margin. */
.about-bio { padding: var(--flow-gap) 0 0; }
.about-bio:last-of-type { padding-bottom: var(--flow-gap); }
.about-bio + .about-bio { border-top: none; }   /* drop the full-width section rule */
.section-divider {
    border: 0;
    height: 3px;
    border-radius: 3px;
    background: var(--divider);
    margin: 0 0 var(--flow-gap);
}
.bio::after { content: ""; display: block; clear: both; }
.bio p { margin: 0; }
.photo-left {
    float: left;
    width: clamp(140px, 20%, 200px);
    margin: 4px 32px 18px 0;
}
.photo-right {
    float: right;
    width: clamp(140px, 20%, 200px);
    margin: 4px 0 18px 32px;
}
@media (max-width: 640px) {
    .photo-left, .photo-right {
        float: none;
        width: min(280px, 72%);
        margin: 0 auto 24px;
    }
    /* The demo mocks are a "wider-than-phone" app window meant to self-clip via
       overflow:hidden. But .feature is a grid item, and a grid item's default
       min-width:auto lets it grow to its content's min-content — so the wide
       demo blows the item past the minmax(0,1fr) track, overflowing the phone
       and pushing the header's right side (Export chat) off-screen. min-width:0
       lets the item honour the track so the demo clips internally as intended
       and the top bar stays within the viewport. */
    .features .feature { min-width: 0; }
    /* Drop the document title on phones: it crowds the action row and adds
       nothing on a phone-width mock. */
    .demo-hd-title { display: none; }
    /* In the narrow takeaways panel the side-by-side actions don't fit:
       "+ Add takeaway" wraps to two lines and "Continue interaction" overflows
       the panel into the format sidebar. Stack them so each sits on its own
       line within the panel. */
    .demo-tk-actions {
        flex-direction: column;
        align-items: stretch;
        gap: 10px;
    }
    .demo-tk-add { white-space: nowrap; text-align: left; }
    /* Same reasoning for the right-hand pair: stack them within the panel. */
    .demo-tk-action-group { flex-direction: column; align-items: flex-start; gap: 10px; }
    .demo-tk-continue { align-self: flex-start; }
}

/* ── FAQ accordion ───────────────────────────────────────────────────────── */
.faq-title { margin-bottom: clamp(24px, 4vw, 40px); }
.faq { display: grid; }
.faq-item { border-bottom: 1px solid var(--border-hi); }
.faq-item summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    padding: 22px 4px;
    cursor: pointer;
    list-style: none;
    font-weight: 700;
    font-style: italic;
    font-size: clamp(1.05rem, 2vw, 1.3rem);
    color: var(--ink);
    transition: color 0.15s ease;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:hover { color: var(--accent); }
.faq-chevron {
    flex-shrink: 0;
    width: 12px; height: 12px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(45deg);
    transition: transform 0.2s ease;
    margin-right: 6px;
}
.faq-item[open] .faq-chevron { transform: rotate(-135deg); }
.faq-answer {
    padding: 0 4px 24px;
}
.faq-answer p { margin: 0; color: var(--ink-dim); }
/* Multi-paragraph answers: space between paragraphs, none around the block. */
.faq-answer p + p { margin-top: 1em; }
/* Inline links in body copy — underlined like .prose, since bare `a` inherits. */
.faq-answer a, .about-copy a { color: var(--ink); text-decoration: underline; }
.faq-answer a:hover, .about-copy a:hover { color: var(--accent); }
.faq-answer .faq-todo { color: var(--ink-faint); font-style: italic; }

/* ── Scroll-reveal / entrance animations ─────────────────────────────────────
   Elements marked [data-reveal] start hidden and fade/slide in when they enter
   the viewport (JS adds .is-visible). Hero elements are in view on load, so they
   animate in on load; everything below reveals on scroll. Stagger via the
   optional --reveal-delay custom property. Fully disabled for reduced-motion. */
@media (prefers-reduced-motion: no-preference) {
    [data-reveal] {
        opacity: 0;
        transform: translateY(20px);
        transition: opacity 0.9s cubic-bezier(0.22, 1, 0.36, 1),
                    transform 0.9s cubic-bezier(0.22, 1, 0.36, 1);
        transition-delay: var(--reveal-delay, 0ms);
    }
    [data-reveal].is-visible {
        opacity: 1;
        transform: none;
    }

    /* Hero text fades in exactly like the app's "It takes just one thought to
       start." line: a subtle 6px slide from the left over 0.5s, appearing after
       the logo has assembled (delays set inline). Mirrors the app's logoFadeIn. */
    .hero-fade { animation: heroFadeIn 0.5s ease both; }

    /* Hero logo "builds" floor-by-floor on load, matching the app's ScaffoldLogo
       (each group drops in from above; per-group delays are set inline). */
    .logo-build g { animation: logoBuild 0.38s ease both; }
}

/* Mirrors the app's logoFloorIn keyframes. */
@keyframes logoBuild {
    from { opacity: 0; transform: translateY(-10px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Mirrors the app's logoFadeIn keyframes (fade + slight slide from the left). */
@keyframes heroFadeIn {
    from { opacity: 0; transform: translateX(-6px); }
    to   { opacity: 1; transform: translateX(0); }
}

/* ── Footer ──────────────────────────────────────────────────────────────── */
.site-footer {
    border-top: 1px solid var(--border);
    padding: 40px 0;
    color: var(--ink-faint);
    font-size: 0.88rem;
}
.site-footer .container {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}
.site-footer .container > span { margin-right: auto; }
.site-footer nav { display: flex; gap: 18px; flex-wrap: wrap; }
.site-footer a { color: var(--ink-dim); }
.site-footer a:hover { color: var(--ink); }
.site-footer .footer-social {
    display: flex;
    align-items: center;
    gap: 16px;
}
.site-footer .footer-social a {
    display: inline-flex;
    color: var(--ink-faint);
    transition: color 0.18s ease, transform 0.18s ease;
}
.site-footer .footer-social a:hover {
    color: var(--accent);
    transform: translateY(-1px);
}
.site-footer .footer-social svg {
    width: 19px;
    height: 19px;
    fill: currentColor;
}

/* ── Resources index ─────────────────────────────────────────────────────────
   Grouped list of articles: a "Starred" group, a divider, then "Latest". Each
   row is one big link — thumbnail left, title and blurb right. */
.res-group-label {
    font-style: italic;
    font-size: 1.05rem;
    color: var(--ink-dim);
    margin: 0 0 14px;
}
.res-group + .res-group { margin-top: 0; }
.res-list { display: grid; gap: 18px; }
.res-item {
    display: flex;
    align-items: center;
    gap: clamp(18px, 3vw, 32px);
    padding: clamp(18px, 2.5vw, 26px);
    border: 1px solid var(--border-hi);
    border-radius: var(--radius-lg);
    background: var(--bg-elevated);
    color: var(--ink);
    transition: border-color 0.15s ease, background 0.15s ease, transform 0.15s ease;
}
.res-item:hover {
    border-color: var(--accent-dim);
    background: var(--card-hi);
    transform: translateY(-2px);
}
.res-item h2 {
    font-style: italic;
    font-size: clamp(1.15rem, 2.6vw, 1.6rem);
    margin: 0 0 10px;
}
.res-item p { margin: 0; color: var(--ink-dim); }
.res-item-body { min-width: 0; }         /* let long blurbs wrap, not overflow */

/* Article thumbnail: a still of the piece — 3/2 matches the screenshots, so
   object-fit trims next to nothing. */
.res-thumb {
    flex: 0 0 auto;
    display: block;
    width: clamp(140px, 24vw, 230px);
    aspect-ratio: 3 / 2;
    object-fit: cover;
    border-radius: var(--radius-md);
    background: var(--bg);
    border: 1px solid var(--border);
}
/* Portrait sources (slideshow covers) crop from the top, so the deck's title
   survives the 3/2 frame instead of being cut out of the middle. */
.res-thumb-top { object-position: top; }
.res-empty {
    padding: clamp(28px, 4vw, 44px);
    border: 1px solid var(--border-hi);
    border-radius: var(--radius-lg);
    text-align: center;
    color: var(--ink-dim);
    font-style: italic;
}

@media (max-width: 560px) {
    .res-item { flex-direction: column; align-items: stretch; text-align: center; }
    .res-thumb { width: 100%; max-width: 220px; margin: 0 auto; }
}

/* Resources page heading row: title centred, section links to its right. The
   1fr spacer keeps the title optically centred despite the link. */
.res-topbar {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 16px;
    margin-bottom: var(--flow-gap);
}
.res-topbar h1 { grid-column: 2; margin: 0; }
.res-topbar-action { grid-column: 3; justify-self: end; }
@media (max-width: 640px) {
    .res-topbar { grid-template-columns: 1fr; justify-items: center; }
    .res-topbar h1, .res-topbar-action { grid-column: auto; justify-self: center; }
}

/* ── Version tracker ─────────────────────────────────────────────────────────
   One collapsible row per release date, separated by rules. Same native
   <details> mechanism as the FAQ, so it works without JS. */
.vt-list { display: grid; margin-top: var(--flow-gap); }
.vt-item { border-bottom: 1px solid var(--border-hi); }
.vt-item summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    padding: 22px 4px;
    cursor: pointer;
    list-style: none;
    font-weight: 700;
    font-size: clamp(1.15rem, 2.4vw, 1.5rem);
    color: var(--ink);
    transition: color 0.15s ease;
}
.vt-item summary::-webkit-details-marker { display: none; }
.vt-item summary:hover { color: var(--accent); }
.vt-body { padding: 0 4px 28px; }
.vt-body h3 {
    font-style: italic;
    font-size: 1.05rem;
    margin: 0 0 10px;
    color: var(--accent);
}
.vt-group + .vt-group { margin-top: 22px; }
.vt-body ul {
    margin: 0;
    padding-left: 1.25em;
    display: grid;
    gap: 8px;
    color: var(--ink-dim);
}
.vt-body li { line-height: 1.6; }

/* ── Example Starting Points ──────────────────────────────────────────────────
   Intro copy, then a filterable one-at-a-time browser of example prompts.
   Without JS every card is simply listed; main.js switches it to the carousel. */
.sp-title { text-align: left; }
.sp-meta {
    font-style: italic;
    color: var(--ink-dim);
    font-size: 0.95rem;
    margin: 8px 0 28px;
}
.sp-browser { margin-top: var(--flow-gap); }
.sp-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 22px;
}
.sp-chip {
    padding: 7px 18px;
    border-radius: 999px;
    border: 1px solid var(--border-hi);
    background: transparent;
    color: var(--ink-dim);
    font-family: var(--font);
    font-size: 0.92rem;
    font-weight: 500;
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.sp-chip:hover { border-color: var(--accent-dim); background: rgba(255, 255, 255, 0.05); }
.sp-chip[aria-pressed="true"] {
    border-color: var(--accent);
    color: var(--ink);
    background: var(--accent-faint);
}
.sp-stage { display: grid; gap: 18px; }
.sp-card {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: clamp(240px, 42vh, 420px);
    padding: clamp(28px, 5vw, 56px);
    border: 1px solid var(--border-hi);
    border-radius: var(--radius-lg);
    background: var(--bg-elevated);
}
.sp-card p {
    margin: 0;
    max-width: 44ch;
    text-align: center;
    font-size: clamp(1.05rem, 2.3vw, 1.5rem);
    line-height: 1.5;
}
/* Carousel mode (JS on): one card at a time, with the pager below.
   Every card is stacked into the same grid area, so the stage always stands as
   tall as the longest prompt and the pager below it never moves as you flip.
   Hidden cards keep their space (visibility, not display) but leave the tab
   order and the accessibility tree. */
.sp-browser.is-enhanced .sp-stage { grid-template-areas: "card"; }
.sp-browser.is-enhanced .sp-card {
    grid-area: card;
    visibility: hidden;
}
.sp-browser.is-enhanced .sp-card.is-current { visibility: visible; }
.sp-browser:not(.is-enhanced) .sp-filters,
.sp-browser:not(.is-enhanced) .sp-pager { display: none; }
.sp-pager {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: clamp(24px, 6vw, 64px);
    margin-top: 18px;
}
.sp-arrow {
    width: 44px; height: 44px;
    display: inline-flex; align-items: center; justify-content: center;
    border: 0;
    border-radius: 10px;
    background: transparent;
    color: var(--ink);
    font-family: var(--font);
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
}
.sp-arrow:hover { background: rgba(255, 255, 255, 0.06); color: var(--accent); }
.sp-arrow:disabled { opacity: 0.35; cursor: default; background: transparent; color: var(--ink); }
.sp-count {
    margin: 0;
    font-size: 0.9rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-dim);
    font-variant-numeric: tabular-nums;
}

/* ── Intentional design slideshow ─────────────────────────────────────────────
   A deck exported slide by slide. Same shape as the starting points browser —
   the markup lists every slide, and main.js stacks them into one frame with the
   pager below. Slides are 4/5 portrait, so the frame is capped by height rather
   than width to keep a whole slide on screen. Reuses .sp-pager for the pager. */
.ss-viewer { margin-top: var(--flow-gap); }
.ss-stage { display: grid; gap: 18px; justify-items: center; }
.ss-slide {
    margin: 0;
    max-width: 100%;
    padding: clamp(12px, 1.8vw, 20px);
    border: 1px solid var(--border-hi);
    border-radius: var(--radius-lg);
    background: var(--bg-elevated);
}
.ss-slide img {
    display: block;
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: min(72vh, 740px);
    border-radius: var(--radius-md);
    background: var(--bg);
}
/* Viewer mode (JS on): one slide at a time. Every slide sits in the same grid
   area, so the pager below never moves as you flip. Hidden slides keep their
   space (visibility, not display) but leave the tab order. */
.ss-viewer.is-enhanced .ss-stage { grid-template-areas: "slide"; }
.ss-viewer.is-enhanced .ss-slide {
    grid-area: slide;
    visibility: hidden;
}
.ss-viewer.is-enhanced .ss-slide.is-current { visibility: visible; }
.ss-viewer:not(.is-enhanced) .sp-pager { display: none; }

/* Small helpers */
.center { text-align: center; }
.mt-0 { margin-top: 0; }
.section-head { max-width: 60ch; margin-bottom: 40px; }
.section-head.center { margin-left: auto; margin-right: auto; }
