/* ============================================================
   TWOEN · front-page STRUCTURE variants  ·  home-variants.css
   ------------------------------------------------------------
   Structure-only layout for the demo-led / 2n-dominant front
   page (Xchange 0162). Loaded on top of site.css (tokens, nav,
   steps, ladder, buttons, footer reused from there).
   Two variants: Option B (split hero) + Option D (single col).
   NO final copy / NO visual polish — placement + proportion only.
   ============================================================ */

/* —— wider canvas (directive #6: use more horizontal space) —— */
.wrap--wide { width: 100%; max-width: 80rem; margin: 0 auto; padding: 0 var(--gutter); }

/* —— review strip (so Jim knows which variant he's on; removable) —— */
.vbar {
  background: var(--dark); color: rgba(242,237,227,0.85);
  font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.18em;
  text-transform: uppercase; text-align: center; padding: 0.5rem var(--gutter);
}
.vbar a { color: var(--accent); }
.vbar b { color: var(--paper); }

/* header wordmark now lives in site.css (.wordmark) — unified square all-caps,
   standardized across all pages (0176). Removed the serif-italic boutique form. */

/* —— the dominant 2n product logo (hero) —— */
.logo2n {
  font-family: var(--serif); font-style: italic; font-weight: 400;
  font-variation-settings: "opsz" 144, "SOFT" 100;
  line-height: 0.9; letter-spacing: -0.04em; color: var(--ink);
  font-size: clamp(4.5rem, 11vw, 8.5rem);
}
.logo2n sup { color: var(--accent); font-size: 0.5em; margin-left: 0.02em; }
/* real outlined-SVG logo asset (replaces the text 2ⁿ placeholder, 0166) */
.logo2n-img { display: block; height: clamp(4.5rem, 11vw, 8.5rem); width: auto; }
.foot__mark svg { color: var(--paper); }
/* hero thesis headline (the locked positioning spine, 0165) */
.hero-thesis {
  font-family: var(--serif); font-style: italic; font-weight: 400;
  font-variation-settings: "opsz" 144, "SOFT" 100;
  font-size: clamp(1.75rem, 3.4vw, 2.6rem); line-height: 1.05;
  letter-spacing: -0.02em; color: var(--ink); margin-top: 0.5rem; max-width: 20ch;
}
.posline {
  font-family: var(--serif); font-weight: 400; font-variation-settings: "opsz" 16;
  font-size: clamp(1.15rem, 1.7vw, 1.5rem); line-height: 1.4;
  color: var(--ink-soft); margin-top: 0.75rem; max-width: 26rem;
}
.foot__tagline {
  font-family: var(--serif); font-style: italic; font-size: 1.05rem;
  color: var(--paper); margin-top: 0.35rem;
}
.cta-line { margin-top: 1.75rem; display: flex; gap: 1rem; flex-wrap: wrap; align-items: center; }
.cta-line .note { font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.1em; color: var(--ink-faint); }

/* —— Telegram-style framed demo window (structural representation) —— */
.demo-window {
  border: 1px solid var(--rule); background: var(--paper-deep);
  display: flex; flex-direction: column; overflow: hidden;
  box-shadow: 0 1px 0 var(--rule), 0 18px 40px -28px rgba(26,24,20,0.5);
}
.demo-window__bar {
  display: flex; align-items: center; gap: 0.7rem;
  padding: 0.8rem 1rem; background: var(--dark); color: var(--paper);
}
.demo-window__avatar {
  width: 1.9rem; height: 1.9rem; border-radius: 50%; flex-shrink: 0;
  background: var(--accent); color: var(--paper);
  font-family: var(--serif); font-style: italic; font-size: 1rem;
  display: flex; align-items: center; justify-content: center;
}
.demo-window__id { font-family: var(--sans); font-weight: 500; font-size: 0.9rem; line-height: 1.1; }
.demo-window__id small {
  display: block; font-family: var(--mono); font-size: 0.6rem;
  letter-spacing: 0.12em; text-transform: uppercase; color: #6fcf97; margin-top: 0.1rem;
}
.demo-window__body {
  padding: 1.25rem 1.1rem; display: flex; flex-direction: column; gap: 0.7rem;
  min-height: 16rem; justify-content: flex-end;
}
.bubble {
  font-family: var(--sans); font-size: 0.92rem; line-height: 1.45;
  padding: 0.65rem 0.9rem; max-width: 80%; border-radius: 0.9rem;
  white-space: pre-line;   /* 0419 D1/D2: preserve \n line breaks in Sue's bubbles (BotFather steps, token-stored) — else they collapse to a run-on */
}
.bubble--in  { background: var(--paper); color: var(--ink); border-bottom-left-radius: 0.2rem; align-self: flex-start; border: 1px solid var(--rule); }
.bubble--out { background: var(--accent); color: var(--paper); border-bottom-right-radius: 0.2rem; align-self: flex-end; }
/* The ~2n system line (flint 0301 render contract): milestone off-ramp copy in the
   platform's voice. Treatment = VARIANT D (Jim 0309, picked off the 0301 picker):
   LEFT-ALIGNED, in Sue's column — but rust-distinct (tint + border) so it reads as the
   platform's voice, not Sue. Applies to both the opener frame and the milestones. */
.bubble--2n {
  align-self: flex-start; max-width: 80%; text-align: left;
  background: rgba(181, 71, 31, 0.07); color: var(--ink-soft);   /* 0419 A2: slightly darker (was --ink-faint) — welcome + 5/10/15 milestones */
  border: 1px solid rgba(181, 71, 31, 0.24); border-radius: 0.7rem;
  font-size: 0.82rem; line-height: 1.4; padding: 0.55rem 0.95rem;
  white-space: pre-line;   /* preserve the opener's 3-line frame (0267 chrome); harmless for single-line milestones */
}
.demo-window__input {
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
  padding: 0.8rem 1rem; border-top: 1px solid var(--rule); background: var(--paper);
  font-family: var(--sans); font-size: 0.9rem; color: var(--ink-faint);
}
.demo-window__send {
  width: 1.8rem; height: 1.8rem; border-radius: 50%; background: var(--accent); color: var(--paper);
  display: flex; align-items: center; justify-content: center; font-size: 0.85rem; flex-shrink: 0;
}
.demo-window__note {
  font-family: var(--mono); font-size: 0.6rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--ink-faint); text-align: center;
  padding: 0.5rem; border-top: 1px solid var(--rule-soft); background: var(--paper-deep);
}

/* ========== OPTION B — split hero ========== */
.hero-split {
  display: grid; grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
  gap: clamp(2rem, 5vw, 4.5rem); align-items: center;
  padding: clamp(3rem, 7vw, 6rem) 0 clamp(2.5rem, 5vw, 4rem);
}
.hero-split__demo { width: 100%; max-width: 30rem; justify-self: end; }

/* ========== OPTION D — hero (proportion correction, 0176/0189) ========== */
/* MARK + PRINCIPLE, not banner energy. Reverses 0170: the 2ⁿ mark is the dominant
   anchor again; the headline shrinks to a subordinate principle sitting to the
   RIGHT of the mark, lower half, last line's baseline ~ the mark's bottom.
   Geometry rules (Jim, 0176): each line one-line (no desktop wrap); combined
   height of both lines < 50% of the 2ⁿ height. Math (max clamp): 2ⁿ = 11rem;
   lines = 1.52rem×1.12 + 1.36rem×1.12 ≈ 3.23rem ≈ 29% of 11rem. ✓
   (headline/subhead dialed −20% — Jim 0224 "reduce the volume"; mark unchanged.) */
.hero-lead {
  padding: clamp(3rem, 7vw, 6rem) 0 clamp(2rem, 4vw, 3rem);
  display: flex; flex-direction: column; align-items: flex-start;
}
/* align-items:flex-end → text block bottom sits at the mark's bottom edge */
.hero-band { display: flex; align-items: flex-end; gap: var(--mark-gap, clamp(1.1rem, 3vw, 2.5rem)); }
/* dominant anchor — scaled by --mark-scale (0179: 2ⁿ −10%; variants set it live).
   Headline does NOT ride the scale (only the mark shrinks, per Jim "reduce 2ⁿ");
   the 0189 relationships still hold (mark stays dominant, text stays <50%). */
.hero-band .logo2n-img { height: calc(clamp(5.5rem, 15vw, 11rem) * var(--mark-scale, 0.90)); flex-shrink: 0; }
.hero-headline {
  display: flex; flex-direction: column; gap: 0.04em; margin: 0;
  padding-bottom: 0.16em; /* descender comp: drop block so 2nd line BASELINE ~ mark bottom */
}
.hl-lead, .hl-sub {
  font-family: var(--serif); font-style: italic; font-weight: 400;
  font-variation-settings: "opsz" 144, "SOFT" 100;
  white-space: nowrap; /* Jim: each line fits on ONE line */
  line-height: 1.12; letter-spacing: -0.02em;
}
/* line 1 = the principle (ink); line 2 = the action (subordinate, ink-soft). No rust. */
.hl-lead { font-size: calc(clamp(0.92rem, 2.0vw, 1.52rem) * var(--hero-size, 1)); color: var(--ink); }
.hl-sub  { font-size: clamp(0.84rem, 1.75vw, 1.36rem); color: var(--ink-soft); }
.hero-lead .cta-line { margin-top: 1.75rem; }
.hero-demo { width: 100%; max-width: 44rem; margin: clamp(2rem, 4vw, 3rem) 0 0; }

/* mobile: nowrap lines would overflow a phone — stack the band, ease the rules */
@media (max-width: 720px) {
  .hero-band { flex-direction: column; align-items: flex-start; gap: 0.75rem; }
  .hl-lead, .hl-sub { white-space: normal; }
}

/* —— responsive: collapse split to stacked, demo-first stays sensible —— */
@media (max-width: 860px) {
  .hero-split { grid-template-columns: 1fr; gap: 2rem; text-align: left; }
  .hero-split__demo { justify-self: stretch; max-width: 34rem; }
}

/* ============================================================
   DESKTOP SIDECAR (≥1200px) — 0177/0191
   Two-column workspace, NOT a redesign. Left ~67% = the whole
   site (header+content+footer), scrolls normally, self-contained.
   Right ~33% = Sue as a FIXED floating pane beside the site.
   Below 1200px: passthrough → stacked mobile layout (0189) intact.
   ============================================================ */
@media (min-width: 1200px) {
  /* LEFT COLUMN — the site. Header is a block child here, so its bar/border
     stop at 67% = "header visually stops at the Sue boundary" (Jim 0177). */
  .site-col { width: 67%; }

  /* RIGHT COLUMN — re-home the SAME hero-demo node (not a 2nd one) as a fixed,
     floating tool window. Out of flow → no empty gap where the full-width demo
     used to sit; "How it works" follows the hero directly. */
  .hero-demo {
    position: fixed; top: 24px; right: 24px; bottom: 24px;
    width: calc(33% - 48px); max-width: none; margin: 0; z-index: 30;
  }
  .hero-demo .demo-window {
    height: 100%;
    border-radius: 14px;                 /* floats: rounded corners (Jim 0177) */
    box-shadow: 0 24px 60px -28px rgba(26,24,20,0.55), 0 1px 0 var(--rule);
  }
  .hero-demo .demo-window__body { flex: 1 1 auto; }   /* fill the tall pane */
  .hero-lead { padding-bottom: 0; }                    /* tighten under the band */

  /* Re-verify 0189 hero geometry in the NARROWER left column (~67% of 1440 ≈
     965px, ~756px at the 1200px breakpoint). Mark-dominant + baseline-on-2ⁿ
     geometry is unchanged; ease the headline clamp so the nowrap lines fit the
     narrower box with margin (longest line is 41 chars). Combined height stays
     well under 50% of the 2ⁿ (≈ 2.9rem vs 11rem ≈ 26% after the −20%). */
  .hl-lead { font-size: calc(clamp(0.88rem, 1.36vw, 1.4rem) * var(--hero-size, 1)); }
  .hl-sub  { font-size: clamp(0.8rem, 1.2vw, 1.2rem); }

  /* READABLE-WIDTH CAP (Jim 0178): primary content blocks cap at ~700px,
     LEFT-anchored — the excess column width becomes the intentional interior
     gutter between content and Sue. Do NOT stretch content to the full 67%.
     Scoped to .section content blocks (prose + tile grids). The HERO is mark +
     a short headline (not long-line text), so it's exempt — it stays anchored
     to the 2ⁿ at its natural width rather than being pinched into 700px
     (kestrel's flag #1). Header/footer stay full-column bars (header stops at
     the Sue boundary, 0177). */
  .section .wrap--wide { max-width: var(--content-cap, 800px); margin-left: 0; margin-right: auto; }

  /* Header stays FIXED/sticky on scroll — no disappearing (Jim 0224, REVERSES
     0179's desktop-static choice). site.css's `.nav { position: sticky; top:0 }`
     now stands on desktop too; nothing to override here. */

  /* Tile discipline (Jim 0178, item 2) is already satisfied structurally:
     .steps/.ladder/.products/.channels are repeat(3,1fr) and collapse straight
     to 1fr (3-down) at ≤760px — there is NO 2-across band. Inside the cap,
     3-across tiles hold. Nothing to change here. */
}

/* ============================================================
   HERO TUNERS — BAKED (Jim 0259, locks the 0239 live controls; #vswitch stripped):
   headline +3 (--hero-size 1.5) · mark↔headline gap −3 (--mark-gap 0.5rem) ·
   2ⁿ mark −12% (--mark-scale 0.88) · content column +100px (--content-cap 900px).
   ============================================================ */
:root {
  --hero-size: 1.5;
  --mark-gap: 0.5rem;
  --mark-scale: 0.88;
  --content-cap: 900px;
}

/* Blank line between all visible stacked paragraphs, sitewide (Jim 0259 §2.1 —
   breathing room). Adjacent-sibling so the first paragraph after a heading isn't
   pushed; covers the hero lead, multi-paragraph summaries, and prose runs. */
.prose + .prose,
.hero__sub + .prose,
.hero-lead-hook .prose + .prose { margin-top: 1.5rem; }

/* ============================================================
   PERSONA SIDECAR — non-demo "Sue remembering" pane on inner pages
   (Jim 0180 directive · wired 0222 · personas = buddy, voiced 0194).
   The fixed Sue tool-window (0191) in its IDLE state: a blurred persona
   SNAPSHOT — a memory, not a live exchange — so the same pane that runs
   the demo on home persists across the site and reads as "Sue remembers."
   Inner pages load this file + wrap their body in .site-col (→ the 67%
   rule above applies) and drop in a .sue-sidecar pane. Reuses the
   .demo-window/.bubble base above — one source of truth, no duplication.
   Desktop-only (≥1200px); hidden below (no inline pane clutter on mobile).
   SYNTHETIC personas — illustrative, never a real operator conversation.
   ============================================================ */
.sue-sidecar { display: none; }            /* mobile/tablet: no idle pane */
@media (min-width: 1200px) {
  .sue-sidecar {
    display: block;
    position: fixed; top: 24px; right: 24px; bottom: 24px;
    width: calc(33% - 48px); z-index: 30;
  }
  .sue-sidecar .demo-window {
    height: 100%; border-radius: 14px;
    box-shadow: 0 24px 60px -28px rgba(26,24,20,0.55), 0 1px 0 var(--rule);
  }
  .sue-sidecar .demo-window__body { flex: 1 1 auto; }
  /* left-anchor inner-page content in the 67% column (match home discipline) */
  .site-col .wrap { margin-left: 0; margin-right: auto; }
}
/* IDLE / non-demo treatment — "gated, not unreadable" (Jim 0224): a faint
   blur softens the exchange into "a memory" while the words stay legible
   enough to CREATE PULL; a top fade lets the thread dissolve upward. The
   status reads "remembering" (not the live "online" green) and the input row
   stays crisp — the invitation to talk is the one sharp thing. */
.demo-window--idle .demo-window__body {
  filter: blur(1.5px); opacity: 0.95;   /* nudged up from 1px — "a little more fuzzy" (Jim 0232), still gated-not-unreadable */
  -webkit-mask-image: linear-gradient(180deg, rgba(0,0,0,0.7) 0%, #000 24%);
          mask-image: linear-gradient(180deg, rgba(0,0,0,0.7) 0%, #000 24%);
}
.demo-window--idle .demo-window__id small { color: var(--ink-faint); }

/* Sue name = rust accent (Jim 0224) — her brand color on the frame ID, on
   every Sue frame (active demo + idle panes). Avatar/bubbles already rust. */
.demo-window__id { color: var(--accent); }

/* DEMO-OFF state CTA — "Talk to Sue / Start the Demo" (Jim 0237). Big press-me
   focal point, dead-centered on the fuzzy pane. Treatment = PAPER (Jim picked it,
   "very nice" — baked, switcher stripped): cream fill, ink text, rust ring —
   dominant without a heavy black slab at size. */
.demo-window { position: relative; }
.demo-cta {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  z-index: 6; text-align: center; line-height: 1.12; white-space: nowrap; cursor: pointer;
  font-family: var(--sans); border-radius: 14px; padding: 1.15rem 2.5rem;
  background: var(--paper); color: var(--ink);
  box-shadow: 0 18px 44px -14px rgba(26,24,20,0.5), 0 0 0 2px var(--accent);
  transition: transform 0.12s ease;
}
.demo-cta:hover  { transform: translate(-50%, -50%) scale(1.03); background: #fff; }
.demo-cta b      { display: block; font-weight: 700; font-size: 1.4rem; letter-spacing: -0.01em; }
.demo-cta small  { display: block; font-weight: 600; font-size: 0.95rem; margin-top: 0.25rem; color: var(--accent); }

/* DEMO-LIVE state (Jim 0237) — interactive Sue convo: un-blur, drop the centered
   CTA, and the carried transcript paints into the body (demo-state.js). Driven by
   flint's window.SueDemo (0238) via html[data-demo="live"], or .is-live for the
   local preview flip. */
html[data-demo="live"] .demo-window--idle .demo-window__body,
.demo-window.is-live .demo-window__body { filter: none; opacity: 1; -webkit-mask-image: none; mask-image: none; }
html[data-demo="live"] .demo-cta,
.demo-window.is-live .demo-cta { display: none; }
/* live: scrollable transcript + interactive input field (painted by demo-state.js) */
html[data-demo="live"] .demo-window__body { overflow-y: auto; justify-content: flex-start; }
html[data-demo="live"] .demo-window__input { cursor: text; }
.demo-window__field {
  flex: 1 1 auto; min-width: 0; border: 0; background: transparent;
  font: inherit; color: var(--ink); outline: none;
  resize: none; line-height: 1.4; max-height: 120px; overflow-y: auto;   /* auto-grow textarea (0265) */
}
.demo-window__field::placeholder { color: var(--ink-faint); }
.demo-window__input { align-items: flex-end; }   /* keep send aligned to the last line as the textarea grows */

/* "Sue is typing" — animated three dots (Jim 0265 §2) */
.demo-thinking { display: inline-flex; align-items: center; gap: 5px; }
.demo-thinking span {
  width: 6px; height: 6px; border-radius: 50%; background: var(--ink-faint);
  animation: demo-blink 1.2s infinite ease-in-out;
}
.demo-thinking span:nth-child(2) { animation-delay: 0.18s; }
.demo-thinking span:nth-child(3) { animation-delay: 0.36s; }
@keyframes demo-blink { 0%, 75%, 100% { opacity: 0.25; transform: translateY(0); } 38% { opacity: 1; transform: translateY(-2px); } }

/* ============================================================
   /SUPPORT — "Talk to Joe" scaffold (0279). STRUCTURE-ONLY: 4 states, copy =
   placeholders, no live behavior. Reuses .demo-window (the chat primitive) inside
   a calm, centered SUPPORT frame — NOT the marketing sidecar (the chat window is the
   main content, not a floating pane). At wire-time the live controller (IR API, 0278)
   shows one state via [data-joe-state]. (Review captions/switcher stripped at production wire-time, 0340.)
   ============================================================ */
.joe-state { margin: 2.75rem 0; }
/* the chat window, centered in the content flow (not a fixed sidecar) */
.joe-support .joe-window { max-width: 32rem; margin: 0 auto; }
/* State 1 — auth gate: a calm, centered verify card */
.joe-gate, .joe-fallback {
  max-width: 32rem; margin: 0 auto; text-align: center;
  border: 1px solid var(--rule); border-radius: 10px; background: var(--paper-deep);
  padding: 2.5rem 2rem;
}
.joe-gate__mark {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.7rem; height: 2.7rem; border-radius: 50%;
  background: var(--accent); color: var(--paper);
  font-family: var(--serif); font-style: italic; font-size: 1.35rem; margin-bottom: 1.1rem;
}
.joe-gate__title, .joe-fallback__title {
  font-family: var(--serif); font-size: 1.4rem; line-height: 1.2; margin: 0 0 0.7rem; color: var(--ink);
}
.joe-gate__note, .joe-fallback__note {
  font-family: var(--sans); font-size: 0.95rem; line-height: 1.5; color: var(--ink-soft); margin: 0 0 1.5rem;
}
.joe-gate__alt {
  font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--ink-faint); margin: 1.3rem 0 0;
}
/* State 3 — terminal closed end-state: muted, distinct from an active chat */
.joe-window--closed { opacity: 0.94; }
.joe-window--closed .demo-window__bar { background: var(--ink-soft); }
.joe-window--closed .demo-window__id small { color: var(--ink-faint); }
.joe-window__closed {
  font-family: var(--mono); font-size: 0.6rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-faint); text-align: center; padding: 0.95rem 1rem;
  border-top: 1px solid var(--rule); background: var(--paper-deep);
}
/* State 4 — Joe-down static fallback uses the .joe-fallback card (shared rule above); paper, not paper-deep */
.joe-fallback { background: var(--paper); }

/* buddy's /support procedural landing (0308): single-column reading copy + the login surface (auth gate)
   after exactly two paragraphs. The real page — not the stacked review scaffold. */
.joe-support__body { margin: 0 auto; }                 /* .prose already caps the measure at 40rem */
/* the login surface (Jim 0309): a BLANK Joe pane with the login FLOATING on top. The .joe-window inside
   is 32rem centered (existing .joe-support .joe-window rule); the float overlays it via .demo-window's
   position:relative — same overlay mechanism as the Sue demo's .demo-cta. */
.joe-login { margin: 1.9rem 0; }
.joe-window--blank .demo-window__body { min-height: 12rem; }        /* blank pane keeps a sensible height */
.joe-window--blank .demo-window__input { opacity: 0.5; }            /* inert pre-login (login floats over it) */
.joe-login__float {
  position: absolute; inset: 0; z-index: 6;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0.9rem; text-align: center; padding: 1.5rem;
  background: rgba(234, 227, 213, 0.66);               /* paper-deep scrim over the blank pane */
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
}
.joe-login__prompt { font-family: var(--sans); font-size: 0.95rem; line-height: 1.5; color: var(--ink-soft); margin: 0; max-width: 22rem; }
/* Google/Apple OAuth sign-in affordances (Jim 0309). OFFICIAL brand marks now inline (Google 4-colour "G",
   Apple logo) — guideline-compliant, white/light button per Google's light theme. Google live; Apple = Soon. */
.joe-oauth { display: flex; flex-direction: column; gap: 0.6rem; width: 100%; max-width: 15rem; }
.joe-oauth__btn {
  display: flex; align-items: center; justify-content: center; gap: 0.6rem; width: 100%;
  background: var(--paper); color: var(--ink); border: 1px solid var(--rule); font-weight: 500;
}
.joe-oauth__btn:disabled { opacity: 0.72; cursor: not-allowed; }   /* not-yet-available (Apple) / review-inert */
.joe-oauth__mark {                                                 /* transparent holder for the official SVG mark */
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.15rem; height: 1.15rem; flex-shrink: 0;
}
.joe-oauth__mark svg { display: block; width: 100%; height: 100%; }
.joe-oauth__soon {                                                 /* honest "not wired yet" cue on the Apple button */
  margin-left: 0.4rem; font-family: var(--sans); font-size: 0.6rem; font-weight: 600;
  letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-soft);
  border: 1px solid var(--rule); border-radius: 999px; padding: 0.04rem 0.4rem;
}
.joe-support__fallback { color: var(--ink-soft); }     /* para 4 quieter — it's the fallback, not the main path */

/* 0474 — /support PLACEHOLDER layout pass (Jim's glance: the Joe block read off-center under the banner +
   "doesn't look very good / tighten it"). Root cause: the banner (.callout, 44rem, left-hugging) and the
   Joe preview (.joe-window, 32rem, margin auto) sat on DIFFERENT axes. Fix: a sparse coming-soon page reads
   best on ONE centered axis — hero, banner, and the Joe preview all centered in a single narrow column.
   Scoped to .support-ph so the shared .callout / .joe-window / .hero rules used on the marketing pages (and
   the parked full Joe surface) are untouched. */
.support-ph .hero .wrap,
.support-ph .section .wrap { max-width: 40rem; margin-inline: auto; }   /* one narrow centered column */
.support-ph .hero { padding-bottom: 0.4rem; }                           /* pull the banner up under the title */
.support-ph .hero__title { text-align: center; }
.support-ph .callout { margin-inline: auto; text-align: center;
  border-left: 0; padding: 1.5rem 1.7rem; }                             /* centered banner card (left accent reads wrong when centered) */
.support-ph .callout .prose { margin-inline: auto; max-width: 30rem; }  /* keep the message a tidy centered measure */
.support-ph .joe-login { margin: 1.4rem auto 0; }                       /* tighten the banner → Joe gap */
.support-ph .joe-window { margin-inline: auto; }                        /* Joe pane centered on the SAME axis as the banner */

/* /welcome — registration landing (0320). Reuses .joe-gate (the centered card) + .joe-oauth (Google/Apple),
   one card per claim-outcome state (stacked + labeled for review, like the /support scaffold). */
.welcome-card { margin: 2.5rem auto; }                  /* .joe-gate already caps width + centers */
.welcome-card .joe-oauth { margin: 1.25rem auto 0; }    /* center the OAuth buttons within the centered card */
.welcome-candidates {
  list-style: none; margin: 1.1rem 0 0; padding: 0;
  display: flex; flex-direction: column; gap: 0.5rem; text-align: left;
}
.welcome-candidates li {
  font-family: var(--sans); font-size: 0.9rem; color: var(--ink);
  border: 1px solid var(--rule); border-radius: 8px; padding: 0.7rem 0.9rem; background: var(--paper);
}
/* /support token-conditional framing (Jim's fold, 0321): controller shows one [data-support-mode] by ?t=. */
.support-framing { margin: 1.5rem 0 0; }

/* ============================================================
   DESKTOP TYPOGRAPHY + LAYOUT LOCK (Jim/buddy 0239) — visual only, no copy.
   Two tiers only: H1 + Body.
   ============================================================ */
/* H1 — one scale (collapsed to the former H2/section-title scale); restrained,
   editorial, not overscaled. Inner-page hero h1 and section headings render alike.
   Last word → rust (applied in markup via type-accent.js). */
.hero__title, .section-title {
  font-size: clamp(1.875rem, 4.2vw, 2.75rem); line-height: 1.06;
  letter-spacing: -0.022em; max-width: 26ch;
}
/* Body — ONE canonical style across all pages: the "Who I am" lead paragraph
   (About). Same size/weight/line-height everywhere; no per-page variation. */
.prose, .hero__sub {
  font-size: clamp(1.15rem, 1.8vw, 1.5rem); line-height: 1.45; font-weight: 400;
}
/* (0414, Jim's flow-walk) color was the last per-page variation: .prose openers (home hook) read --ink
   while .hero__sub openers (demo/about/2n/proof) read the muted --ink-soft — same size/weight, so the
   only difference was color, which reads as a weight difference. Unify to --ink → every page's opening
   paragraph is now one canonical style, completing the "no per-page variation" intent above. */
.prose, .hero__sub { color: var(--ink); }

/* Preview-variant banner (home-v2.html, 0251) — marks the comparison artifact. */
.variant-flag {
  font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.06em;
  color: var(--paper); background: var(--accent);
  display: inline-block; padding: 0.4rem 0.8rem; border-radius: 6px; margin: 1.25rem 0 0;
}
.variant-flag a { color: var(--paper); text-decoration: underline; }

/* Header height (desktop) — ~2× the gutter padding: deliberate, institutional,
   not compressed (Jim 0239 §5). Mobile (≤860px) keeps its stacked nav. */
@media (min-width: 861px) {
  .nav__inner { padding-top: 1.9rem; padding-bottom: 1.9rem; }
}

/* Hero horizontal rule under the headline (Jim 0236 §1 — leaner hero, no subhead). */
.hero-rule { border: 0; border-top: 1px solid var(--rule); width: min(100%, 34rem); margin: 1.4rem 0 0; }

/* ============================================================
   PROOF v2 close (Jim 0231) — keep the CTA, then let the payoff
   two-liner land LAST. The payoff is the page's whole argument in
   two lines, so it gets serif weight + space; "That is the proof."
   in rust is the punch. (proof.html only.)
   ============================================================ */
.proof-close { margin-top: 2.5rem; }
.proof-close__cta {
  font-family: var(--serif); font-size: clamp(1.25rem, 2.2vw, 1.7rem);
  line-height: 1.25; color: var(--ink); margin: 0;
}
.proof-payoff {
  font-family: var(--serif); font-style: italic;
  font-size: clamp(1.2rem, 2vw, 1.6rem); line-height: 1.4;
  color: var(--ink); margin-top: 2.75rem;
  padding-top: 1.75rem; border-top: 1px solid var(--rule);
}
.proof-payoff__last { color: var(--accent); font-style: normal; }

/* ============================================================
   COPY-PAGE spacing (Jim 0232) — gauge true content length: MORE air
   between paragraphs, LESS air before each sub-heading. Scoped to
   .copy-page (main on /proof + /products) so home/demo rhythm is untouched.
   ============================================================ */
.copy-page .prose + .prose { margin-top: 1.45rem; }          /* visible gap between stacked paragraphs */
.copy-page .section { padding-top: clamp(1.75rem, 3.5vw, 2.75rem); padding-bottom: clamp(1.75rem, 3.5vw, 2.75rem); }
.copy-page .section__head { margin-bottom: 1.2rem; }          /* tighten the rule → heading → body transition */

/* ============================================================
   ROSTER block (About page, Xchange 0233) — the governed-fleet roles.
   WIP/partial until the fleet self-bio collection completes. (about.html)
   ============================================================ */
.roster--wip {
  margin-top: 1.5rem; padding: 1.4rem 1.6rem;
  border: 1px solid var(--rule); border-radius: 10px; background: var(--paper-deep);
}
.roster__list { list-style: none; margin: 1rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 1rem; }
.roster__list li { font-family: var(--sans); font-size: 0.95rem; line-height: 1.5; color: var(--ink); }
.roster__list b { color: var(--accent); font-weight: 600; }
.roster__role {
  font-family: var(--mono); font-size: 0.6rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-faint); margin-left: 0.5rem;
}
.roster__note {
  font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-faint); margin: 1.1rem 0 0;
}
/* (0414) buddy's short/long roster-expand removed — buddy is now a single-line entry like every other
   role (Jim's consistency trim). The .roster__more/short/long rules are gone with their only user. */

/* ============================================================
   ACCORDION — inline "…more" expansion (buddy 0234). Restrained, no
   heavy UI: each section's first block stands alone as coherent short-form;
   the expansion is the optional second layer. No-JS via <details>/<summary>.
   Used on Home (Thesis + Company), Proof, About. If a browser can't toggle,
   the short form still reads complete and the rest is just below.
   ============================================================ */
details.more > summary { display: block; list-style: none; cursor: pointer; }
details.more > summary::-webkit-details-marker { display: none; }
details.more > summary::marker { content: ""; }
.more__cue {
  display: inline-block; margin-top: 0.5rem;
  font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.08em;
  color: var(--accent); cursor: pointer;
}
.more__cue:hover { color: var(--accent-deep); }
details.more[open] .more__cue { display: none; }
details.more > summary > .prose + .prose { margin-top: 1.45rem; }  /* multi-para summaries breathe like copy-page */
/* (0414, Jim's flow-walk) the EXPANDED …more copy is a direct .prose child of details.more, AFTER <summary>,
   so no `.prose + .prose` rule reached it — it butted the summary paragraph. Give it the same blank line. */
details.more[open] > .prose { margin-top: 1.45rem; }

/* ============================================================
   HOME "Three ways in" — equal-weight engagement blocks (home_v1 §5).
   product / project / partnership read as peers, not a priced ladder.
   ============================================================ */
.ways { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1.25rem, 2.5vw, 1.75rem); margin-top: 1.5rem; }
@media (max-width: 760px) { .ways { grid-template-columns: 1fr; } }
.way {
  display: flex; flex-direction: column; gap: 0.65rem;
  padding: 1.4rem 1.5rem; border: 1px solid var(--rule); border-radius: 10px; background: var(--paper-deep);
}
.way__name { font-family: var(--serif); font-size: 1.12rem; line-height: 1.25; color: var(--ink); }
.way__body { font-family: var(--sans); font-size: 0.9rem; line-height: 1.5; color: var(--ink-soft); flex: 1 1 auto; }
.way .btn { align-self: flex-start; margin-top: 0.2rem; }
.quiet-close { font-family: var(--serif); font-size: clamp(1.15rem, 2vw, 1.45rem); color: var(--ink); margin: 0; }

/* 0448 — the in-frame checkout OVERLAY is flint's #sue-checkout-overlay (demo-client.js, 0447): an absolute
   panel that fills the Sue frame (marked [data-sue-frame]) with exit-top / pay-bottom chrome. flint owns
   STRUCTURE — the overlay's flex layout, and #sue-checkout is a flex child BELOW the chrome where Stripe
   mounts. The site owns VISUAL polish, keyed off the data-checkout paint (open|closed|done|error) set on
   <html>. This SUPERSEDES the pre-0447 bare-#sue-checkout absolute rule: that predated the overlay and
   would have pulled #sue-checkout out of flint's flex flow (position:absolute;inset:0), covering the
   "Back to Sue" chrome. Now the overlay owns fill; the site only rounds it to the frame's corners. The
   overlay is opaque and covers the conversation while open, so no separate dim is needed; on close/abandon
   flint tears it down and the conversation behind reappears intact (see sue:checkout-closed in demo-state.js). */
.demo-window { position: relative; }                                 /* positioning context for the in-frame overlay */
#sue-checkout-overlay { border-radius: inherit; overflow: hidden; }  /* match the Sue frame's rounded corners (flint sets bg/layout) */
html[data-checkout="done"] #sue-checkout-overlay { display: none; }  /* finish() already tears it down; belt-and-suspenders */

/* 0472 #6 — in-frame Stripe checkout PAINT (0238 split: flint owns the overlay STRUCTURE, bram owns the
   PAINT). Jim: the mount "lands like a thud — the header changed / lost its color / lost its look." Cause:
   flint's chrome (.sue-checkout__chrome) was a bare paper strip, so the branded dark Sue header
   (.demo-window__bar: var(--dark) bg, var(--paper) text) turned pale on checkout-open, and the overlay
   snapped in with no transition. Paint the chrome to MATCH the Sue header so the look carries through, and
   fade the overlay in so it arrives instead of thudding. NOTE: flint's overlay CSS (#sue-checkout-css) is
   injected at runtime AFTER this stylesheet, so these selectors are qualified by #sue-checkout-overlay to
   out-SPECIFY his rules (1,1,0 > his 0,1,0) rather than lose the cascade to load order. */
#sue-checkout-overlay { animation: sue-checkout-in 0.2s ease both; }              /* arrive, don't snap (flint sets no animation) */
@keyframes sue-checkout-in { from { opacity: 0; } to { opacity: 1; } }
#sue-checkout-overlay .sue-checkout__chrome {                                     /* match .demo-window__bar so the header keeps its look */
  background: var(--dark); color: var(--paper); border-bottom: 0; }
#sue-checkout-overlay .sue-checkout__back { color: var(--paper); opacity: 0.92; } /* the exit reads on the dark bar */
#sue-checkout-overlay .sue-checkout__back:hover { opacity: 1; }
@media (prefers-reduced-motion: reduce) { #sue-checkout-overlay { animation: none; } }
