/* ═══════════════════════════════════════════════════════════════════════════
   Good Grief - Website
   Visual identity matched to src/index.css (the desktop app's CSS) so that
   visitors get a continuous experience: site -> install -> app should feel
   like one product, not three.

   This file is a website-shell layered on the app's ACTUAL visual primitives.
   - Same CSS variables (--bg, --surface, --candle, --iris, --text-1..3)
   - Same body::before with heavenly-bg.jpg overlaid by 90% black gradient
   - Same .glass-card rules (rgba(6,8,16,0.72) + 20px blur + multi-shadow)
   - Same h1-h4 font-weight: 300, system font stack, letter-spacing -0.01em

   The "A quick look" section uses real PNG/WebP screenshots of the running
   app (since v0.5.28). Earlier versions reproduced the app's tile grid in
   CSS — that approximation was removed once we had real screenshots to use.

   When the desktop app's index.css evolves, this file should be checked
   against it for drift. The intentional differences are: site-only sections
   (.hero, .pitch, .feature-grid, .ea-card, .ea-form, .faq-item) which the
   app does not have.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── CSS variables (verbatim from src/index.css) ─────────────────────── */
/* v0.5.61 — Default switched gold → forest. 10 themes total, matching
   the desktop app exactly. See src/index.css for full theme philosophy
   notes. */
/* Shared brand colour palette — single source of truth (brand/tokens.css),
   the same tokens the app imports. Must precede other rules. See BRAND.md. */
@import './brand-tokens.css';

/* ── Self-hosted Cormorant Garamond (the display serif) ────────────────────
   WAS loaded from Google Fonts with display=swap, which made the huge hero
   title first paint in the Georgia fallback and then visibly REFLOW when the
   webfont finally arrived — a big part of the "janky load" Zinta reported.
   Self-hosting the woff2 (in fonts/) and preloading the two latin faces the
   hero paints with (400 normal + 400 italic, see each page's <head>) lets the
   real serif render on the FIRST frame from same-origin: no fallback flash,
   no reflow, and one fewer third-party (fonts.gstatic.com) round-trip.
   Faces mirror Google's exact subsets/unicode-ranges; "normal" is a single
   variable file covering 300–600. Non-latin glyphs fall back through the
   --font-display stack. @import must precede @font-face, hence placed here. */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 300 600;
  font-display: swap;
  src: url('fonts/cormorant-garamond-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 300 600;
  font-display: swap;
  src: url('fonts/cormorant-garamond-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/cormorant-garamond-italic-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/cormorant-garamond-italic-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* Base palette (--bg, --surface(s), --border(s), --candle, --candle-glow,
     --iris, --iris-glow, --accent, --accent-soft, --text-1/2/3) now comes from
     the shared brand/tokens.css @imported above. Below: website-only tokens. */
  --candle-dim:  #4a7c59;
  --candle-bright: #a9c9b0;
  --iris-bright: #a89aff;
  --text-4:      #5a6b62;

  /* Layout (website-only) */
  --max-w: 1080px;
  --max-w-prose: 640px;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);

  /* Type — system fonts, matching the app
     v0.5.60: --font-heading + --font-display added so font-pair switcher
     can swap typography. Default keeps current Segoe UI everywhere. */
  --font-body: 'Segoe UI', -apple-system, BlinkMacSystemFont, system-ui, 'Helvetica Neue', sans-serif;
  --font-heading: 'Segoe UI', -apple-system, BlinkMacSystemFont, system-ui, 'Helvetica Neue', sans-serif;
  /* v0.5.101 — the DISPLAY face is the one piece of deliberate type identity:
     Cormorant Garamond, the same serif as the logo lockup + R·I·P. It drives the
     hero title and section titles so the whole page reads of-a-piece with the
     mark. Body, card titles, nav and buttons stay on the system sans (serif does
     the identity, sans does the reading). The playground font-pair switcher
     overrides all three vars, so this is only the default/reset state. */
  --font-display: 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
  --font-mono: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
}

@keyframes gg-aurora-shift {
  0%   { background-position: 0% 30%, 100% 60%, 50% 80%; }
  33%  { background-position: 100% 50%, 0% 30%, 70% 20%; }
  66%  { background-position: 30% 80%, 70% 0%,  20% 60%; }
  100% { background-position: 0% 30%, 100% 60%, 50% 80%; }
}

@keyframes gg-slow-zoom {
  0%, 100% { transform: scale(1.00) translate(0, 0); }
  50%      { transform: scale(1.06) translate(-1%, -1%); }
}

/* ── v0.5.71: animated waves + lights (were static before) + 2 new animated bgs ── */

@keyframes gg-waves-drift {
  0%   { background-position: 0 0,     50% 100%; }
  100% { background-position: 0 -80px, 50% 100%; }
}

@keyframes gg-lights-drift {
  0%, 100% { background-position: 20% 30%, 75% 65%, 50% 15%, 85% 20%, 15% 80%, 0 0; }
  50%      { background-position: 22% 28%, 73% 67%, 52% 17%, 83% 22%, 17% 78%, 0 0; }
}

@keyframes gg-drift {
  0%, 100% { transform: translate(0, 0)    scale(1); }
  33%      { transform: translate(2%, -1%) scale(1.05); }
  66%      { transform: translate(-1%, 2%) scale(0.98); }
}

@keyframes gg-pulse {
  0%, 100% { opacity: 0.55; transform: scale(1); }
  50%      { opacity: 0.85; transform: scale(1.06); }
}

/* Apply the heading/display variables wherever h1-h4 is used.
   Hero title gets the display variant; section headings get heading. */
.hero-title { font-family: var(--font-display); }
.hero-title-em { font-family: var(--font-display); font-style: italic; }

/* Desktop: nudge the page over so the open dock doesn't cover content */
@media (min-width: 1040px) {
  body { transition: padding-right 0.4s var(--ease, cubic-bezier(0.22, 1, 0.36, 1)); }
}
@media (prefers-reduced-motion: reduce) {
  body { transition: none; }
}

/* v0.5.65 — Saved looks bar */
/* v0.5.67 — Tone palette (lightness shift swatches under Theme + Accent) */
.gg-tone-palette {
  margin-top: 12px;
  padding: 10px 12px;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.02);
  border: 1px dashed rgba(255, 255, 255, 0.08);
}
.gg-tone-disabled {
  opacity: 0.55;
}
.gg-tone-disabled-msg {
  margin: 0;
  font-size: 11px;
  color: var(--text-3);
  font-style: italic;
}
.gg-tone-row {
  display: flex;
  gap: 6px;
  margin-top: 4px;
  flex-wrap: wrap;
}
.gg-tone-swatch {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  cursor: pointer;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  font-family: inherit;
  font-size: 9px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.55);
  transition: all 0.15s ease;
}
.gg-tone-swatch:hover {
  border-color: var(--accent);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
.gg-tone-swatch[aria-pressed="true"] {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-soft), 0 4px 12px rgba(0, 0, 0, 0.3);
}
.gg-tone-num {
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
  pointer-events: none;
  user-select: none;
}

.gg-saved-looks {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 12px 16px 14px;
  border-top: 1px solid var(--border-soft);
  background: rgba(0, 0, 0, 0.18);
}
.gg-saved-looks-label {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-2);
  margin: 0;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  flex-shrink: 0;
}
.gg-saved-look {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  color: var(--text-1);
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  padding: 5px 10px 5px 12px;
  border-radius: 999px;
  cursor: pointer;
  transition: all 0.15s;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.gg-saved-look:hover {
  border-color: var(--accent);
  background: rgba(255, 255, 255, 0.08);
}
.gg-saved-look-remove {
  background: transparent;
  border: none;
  color: var(--text-3);
  cursor: pointer;
  font-family: inherit;
  font-size: 14px;
  line-height: 1;
  padding: 0 2px;
  margin-left: 4px;
  border-radius: 4px;
}
.gg-saved-look-remove:hover { color: var(--accent); background: rgba(255, 255, 255, 0.06); }
/* v0.5.68 — Rename button on saved-look pills */
.gg-saved-look-rename {
  background: transparent;
  border: none;
  color: var(--text-3);
  cursor: pointer;
  font-family: inherit;
  font-size: 11px;
  line-height: 1;
  padding: 0 4px;
  margin-left: 6px;
  border-radius: 4px;
  opacity: 0.6;
}
.gg-saved-look-rename:hover { color: var(--accent); background: rgba(255, 255, 255, 0.06); opacity: 1; }
.gg-save-look-btn {
  background: rgba(255, 255, 255, 0.02);
  border: 1px dashed var(--border);
  color: var(--text-2);
  font-family: inherit;
  font-size: 12px;
  padding: 5px 12px;
  border-radius: 999px;
  cursor: pointer;
  transition: all 0.15s;
}
.gg-save-look-btn:hover {
  border-color: var(--accent);
  border-style: solid;
  color: var(--text-1);
}

/* When edit-mode is on, contenteditable elements get a dashed outline
   that's visible but not loud. Hovering thickens the line; focus shows
   a soft accent fill so the user knows they're editing. */
[data-edit-mode="on"] [contenteditable="true"] {
  outline: 1px dashed var(--accent);
  outline-offset: 4px;
  border-radius: 2px;
  cursor: text;
  transition: outline-color 0.15s ease, background 0.15s ease;
}
[data-edit-mode="on"] [contenteditable="true"]:hover {
  outline-style: solid;
  outline-color: var(--candle, var(--accent));
}
[data-edit-mode="on"] [contenteditable="true"]:focus {
  outline: 2px solid var(--accent);
  background: var(--accent-soft);
}

/* Export-edits modal */
.gg-edit-modal {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.65);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10000;
  padding: 24px;
}
.gg-edit-modal-card {
  background: rgba(8, 10, 18, 0.97);
  border: 1px solid var(--border);
  border-radius: 14px;
  width: 100%;
  max-width: 720px;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
}
.gg-edit-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 22px;
  border-bottom: 1px solid var(--border-soft);
}
.gg-edit-modal-head h3 {
  margin: 0;
  font-size: 1rem;
  font-weight: 500;
  color: var(--text-1);
}
.gg-edit-modal-close {
  background: transparent;
  border: none;
  color: var(--text-3);
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  padding: 4px 10px;
  border-radius: 6px;
  font-family: inherit;
}
.gg-edit-modal-close:hover { color: var(--text-1); background: rgba(255, 255, 255, 0.06); }
.gg-edit-modal-textarea {
  flex: 1;
  margin: 0;
  padding: 18px 22px;
  background: rgba(0, 0, 0, 0.3);
  border: none;
  color: var(--text-2);
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.6;
  resize: none;
  min-height: 240px;
  outline: none;
}
.gg-edit-modal-actions {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  padding: 14px 22px;
  border-top: 1px solid var(--border-soft);
  background: rgba(0, 0, 0, 0.2);
}
.gg-edit-modal-actions .gg-action-btn {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  color: var(--text-2);
  font-family: inherit;
  font-size: 13px;
  padding: 8px 16px;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.15s;
}
.gg-edit-modal-actions .gg-action-btn:hover {
  background: rgba(255, 255, 255, 0.08);
  color: var(--text-1);
  border-color: var(--accent);
}
.gg-edit-modal-actions .gg-action-btn.primary {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--text-1);
}
.gg-edit-modal-actions .gg-action-btn.primary:hover {
  filter: brightness(1.15);
}

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

html, body, #root { margin: 0; }

/* v0.5.63: <mark> defaults to yellow in every browser. Override globally
   so any highlighted text uses the active accent (Rule 31 compliance —
   yellow is banned even via browser defaults). */
mark {
  background: var(--accent-soft);
  color: var(--text-1);
  padding: 0 0.2em;
  border-radius: 2px;
  border-bottom: 1px solid var(--accent);
}

/* color-scheme:dark — Firefox scrollbars, Chrome autofill and UA validation
   bubbles otherwise render light-themed on this near-black site. */
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: 88px; color-scheme: dark; }

/* Skip-to-content link — off-screen until keyboard-focused (a11y). */
.skip-link {
  position: fixed;
  top: 10px;
  left: 10px;
  z-index: 1000;
  padding: 10px 16px;
  background: rgba(8, 10, 18, 0.97);
  border: 1px solid var(--accent);
  border-radius: 10px;
  color: var(--text-1);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
  transform: translateY(-160%);
  transition: transform 0.2s var(--ease, cubic-bezier(0.22, 1, 0.36, 1));
}
.skip-link:focus {
  transform: translateY(0);
  outline: 2px solid var(--candle, var(--accent));
  outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .skip-link { transition: none; }
}

body {
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--text-1);
  font-size: 15px;
  line-height: 1.6;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  min-height: 100vh;
}

/* ── Background image (verbatim from src/index.css body::before) ─────── */
/* Same heavily-darkened atmospheric photo the app uses. The 0.90 alpha
   overlay matches the app's preference for a moody, almost-black tone. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  background-color: #060810;
  background-image:
    linear-gradient(rgba(6,8,16,0.90), rgba(6,8,16,0.90)),
    url('heavenly-bg.jpg');
  background-size: cover;
  background-position: center 42%;
  background-repeat: no-repeat;
  pointer-events: none;
}

/* ── Type (matches app) ───────────────────────────────────────────────── */
/* v0.5.101 — was var(--font-body), which silently shadowed the earlier
   `h1-h4 { font-family: var(--font-heading) }` rule (equal specificity, later
   wins) and left --font-heading dead — so the playground's serif-heading pairs
   only ever restyled the hero. Now headings honour --font-heading (default =
   system sans; section/hero titles opt into --font-display below). */
h1, h2, h3, h4 {
  font-family: var(--font-heading);
  font-weight: 300;
  letter-spacing: -0.01em;
  line-height: 1.15;
  color: var(--text-1);
  margin: 0 0 0.5em;
}

h1 { font-size: clamp(2.2rem, 5.2vw, 3.6rem); }
h2 { font-size: clamp(1.6rem, 3.4vw, 2.4rem); }
h3 { font-size: clamp(1.15rem, 1.8vw, 1.35rem); font-weight: 400; }
h4 { font-size: 1rem; font-weight: 500; }

p {
  color: var(--text-2);
  margin: 0 0 1em;
  text-wrap: pretty;   /* v2026-07-14 — trims stranded one-word widows in prose; progressive, ignored where unsupported */
}
/* Short centred display-serif one-liners set evenly — a long-then-short break
   reads lopsided. balance is browser-capped to short blocks, so it only
   engages on these 1–3 line pull-quotes. Class beats the p rule above. */
.pitch-aside, .features-lede, .interlude-line, .interlude-sub { text-wrap: balance; }

a {
  color: var(--candle-bright);
  text-decoration: none;
  transition: color 0.2s var(--ease);
}
a:hover { color: var(--candle); text-decoration: underline; text-underline-offset: 3px; }
a:focus-visible {
  outline: 2px solid var(--candle-bright);
  outline-offset: 2px;
  border-radius: 3px;
  text-decoration: underline;
  text-underline-offset: 3px;
}
/* .dl-card/.sample-card are both 18px-radius <a> cards — the generic rule
   above would snap their corners to 3px while focused, visibly reshaping the
   whole card. Match their own radius instead. */
.dl-card:focus-visible, .sample-card:focus-visible { border-radius: 18px; }

/* Local literal, NOT --iris-glow: that shared app token is 16% alpha, which
   composites to ~1.13:1 against the page — invisible, and it sabotaged the
   signup fallback's "select + copy the address" flow. (v2-verified value.) */
::selection { background: rgba(108, 94, 220, .5); color: var(--text-1); }

/* height:auto is the real fix here, not max-width alone. Any <img> that
   carries HTML width/height attributes (for layout-shift prevention) but
   sits in a container narrower than its natural width, with no author
   `height` declared, gets its height pinned to the raw attribute pixel
   value (a low-priority presentational hint that still wins over nothing) —
   producing a squashed/stretched render. See the .phone-frame img comment
   below for the full mechanism; this is the sitewide safety net. */
img { max-width: 100%; height: auto; display: block; }

/* ── Scrollbar (verbatim from src/index.css) ─────────────────────────── */
::-webkit-scrollbar       { width: 4px; height: 4px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.10);
  border-radius: 2px;
}
::-webkit-scrollbar-thumb:hover { background: rgba(74, 124, 89, 0.35); }

/* ── Layout primitives ───────────────────────────────────────────────── */
.wrap {
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 0 1.5rem;
}

.wrap.wrap-prose { max-width: var(--max-w-prose); }

section { padding: clamp(2.5rem, 7vw, 5rem) 0; }

/* Restrained rhythm on the long dark scroll: a ~1% wash + hairline on
   alternating content sections (the hero is first, so stays untouched).
   No colour introduced — Rule 31 safe. */
main > section:nth-of-type(even) {
  background: rgba(255, 255, 255, 0.025);
  border-top: 1px solid var(--border-soft);
  border-bottom: 1px solid var(--border-soft);
}

.eyebrow {
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--candle-bright); /* v0.5.108 — was --candle; brighter for the uppercase kicker on near-black */
  margin: 0 0 1.5rem;
  font-weight: 500;
}

.section-title {
  /* v0.5.101 — the editorial serif, matching the hero + logo. Weight 400 (not
     the 300 a light sans wants) so Cormorant holds its presence on the dark
     ground; class selector beats the h2 element rule above. */
  font-family: var(--font-display);
  font-weight: 400;
  /* Own scale — Cormorant's smaller x-height needs more size than the h2
     clamp to re-open the H1 → H2 → body ladder against the 3.6rem hero. */
  font-size: clamp(2rem, 4vw, 2.85rem);
  line-height: 1.1;
  letter-spacing: -0.005em;
  text-wrap: balance;
  margin: 0 0 1.6rem;
}

.section-sub {
  color: var(--text-3);
  margin: 0 0 2rem;
  font-size: 0.95rem;
}
.section-title + .section-sub { margin-top: 0.4rem; }

.mobile-preview-link {
  color: var(--iris-bright, #c8beff);
  text-decoration: none;
  border-bottom: 1px dashed rgba(200, 190, 255, 0.3);
  padding-bottom: 1px;
  transition: color 0.18s ease, border-color 0.18s ease;
}
.mobile-preview-link:hover {
  color: var(--candle-2, #7eac88);
  border-bottom-color: rgba(126, 172, 136, 0.5);
}

.small { font-size: 0.85rem; color: var(--text-3); }

/* ── Header (site nav) ───────────────────────────────────────────────── */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(4, 5, 10, 0.78);
  backdrop-filter: blur(24px) saturate(110%);
  -webkit-backdrop-filter: blur(24px) saturate(110%);
  border-bottom: 1px solid rgba(255, 255, 255, 0.09);
  box-shadow: 0 8px 24px -16px rgba(0, 0, 0, 0.85);   /* v2026-07-14 — a soft plane so content doesn't dissolve into the bar on scroll */
}

.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 1rem;
  padding-bottom: 1rem;
}

.brand {
  min-width: 0;
  /* clipping lives on .brand-name, NOT here: .brand is a flex container, and
     text-overflow:ellipsis can never apply to a flex container's anonymous
     text — overflow:hidden here just hard-clipped the wordmark mid-glyph
     ("GOOD GRIE" with a sliced F on every phone subpage). */
  font-family: var(--font-display);
  font-size: 1.1rem;
  font-weight: 400;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--text-1);
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
/* the wordmark text, as a real flex item: blockified, so ellipsis works —
   worst-case squeeze degrades to "GOOD GRI…" instead of a sliced letter. */
.brand-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.brand:hover { color: var(--candle-bright); text-decoration: none; }
.brand .dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--candle);
  box-shadow: 0 0 10px var(--candle-glow);
  display: inline-block;
}

.nav {
  display: flex;
  gap: 1.6rem;
  align-items: center;
}
.nav a {
  color: var(--text-3);
  font-size: 0.92rem;
  transition: color 0.15s var(--ease);
}
.nav a:hover { color: var(--text-1); text-decoration: none; }
.nav a:focus-visible,
.nav a.cta:focus-visible,
.site-footer nav a:focus-visible {
  outline: 2px solid var(--candle-bright);
  outline-offset: 3px;
  border-radius: 6px;
}

.nav a.cta {
  /* Near-black on the light-sage gradient — the gradient is a bright fill,
     so the label must be dark to clear AA (~1.8:1 white → ~8:1 black). */
  color: #071008;
  background: linear-gradient(180deg, var(--candle-bright), var(--candle));
  padding: 0.55rem 1.1rem;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  font-weight: 500;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.4),
    0 4px 14px -4px rgba(74, 124, 89, 0.5);
  transition: all 0.2s var(--ease);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.nav a.cta:hover {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    0 6px 22px -4px rgba(74, 124, 89, 0.65);
  transform: translateY(-1px);
  color: #071008;
}
.nav a.cta:active {   /* v2026-07-14 — match the hero buttons' tactile press (was frozen on click) */
  transform: translateY(0) scale(0.97);
  transition-duration: 0.05s;
}

/* ── Mobile nav: button-toggled dropdown ─────────────────────────────────
   On screens ≤640px, the non-CTA nav links collapse into a small
   dropdown attached to a hamburger button. The CTA stays inline so
   the highest-value action is always one tap away.

   We use a plain <button> + JS toggle instead of <details>/<summary>.
   The <details> approach was nicer in theory (no JS for the toggle
   itself) but Firefox treats `display: contents` on <details>
   inconsistently — the descendant `display: flex` rule didn't actually
   override the disclosure-widget hide-when-closed behavior, so the
   nav links rendered as hidden on desktop. The boring pattern
   sidesteps this entirely.

   Desktop (>640px): .nav-links is a plain flex row, hamburger button
   is hidden. Visually identical to the original layout.
   Mobile (≤640px): .nav-links is hidden by default; the JS toggle
   sets data-open="true" on .nav-menu to reveal it as a dropdown. */

/* Default state (desktop): hamburger hidden, links visible inline. */
.nav-menu {
  display: flex;
  align-items: center;
  gap: 1.6rem;
}
.nav-toggle { display: none; }
.nav-links {
  display: flex;
  gap: 1.6rem;
  align-items: center;
}

@media (max-width: 720px) {
  /* Mobile: hamburger appears, links hide unless menu is open.
     720px (not 640) so the hamburger and the stacked hero arrive together. */
  .nav { gap: 0.6rem; }
  /* 44px min tap target on the two primary header controls. */
  .nav a.cta { min-height: 44px; display: inline-flex; align-items: center; padding: 0.6rem 1.15rem; max-width: 44vw; }

  .nav-menu {
    display: block;
    position: relative;
    gap: 0;
  }

  /* Hide the dropdown panel by default; show when data-open="true". */
  .nav-links { display: none; }
  .nav-menu[data-open="true"] .nav-links { display: flex; }

  /* The hamburger button. */
  .nav-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.06);
    color: var(--text-2);
    cursor: pointer;
    padding: 0;
    transition: background 0.15s var(--ease), border-color 0.15s var(--ease);
  }
  .nav-toggle:hover {
    background: rgba(255, 255, 255, 0.07);
    border-color: rgba(255, 255, 255, 0.10);
    color: var(--text-1);
  }
  .nav-toggle:focus-visible {
    outline: 2px solid var(--candle, #4a7c59);
    outline-offset: 2px;
  }
  .nav-toggle svg { display: block; }

  /* Visual feedback when the menu is open. */
  .nav-menu[data-open="true"] .nav-toggle {
    background: rgba(74, 124, 89, 0.10);
    border-color: rgba(74, 124, 89, 0.25);
    color: var(--candle-bright);
  }

  /* The dropdown panel. Anchored to the right of the toggle so it doesn't
     run off-screen on narrow viewports. */
  .nav-menu[data-open="true"] .nav-links {
    position: absolute;
    top: calc(100% + 0.6rem);
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    min-width: min(200px, calc(100vw - 32px));
    padding: 0.4rem;
    background: rgba(8, 10, 18, 0.96);
    backdrop-filter: blur(18px) saturate(120%);
    -webkit-backdrop-filter: blur(18px) saturate(120%);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 12px;
    box-shadow:
      0 10px 30px rgba(0, 0, 0, 0.55),
      0 0 0 1px rgba(255, 255, 255, 0.02) inset;
  }
  .nav-links a {
    padding: 0.7rem 0.9rem;
    border-radius: 8px;
    font-size: 0.95rem;
    color: var(--text-2);
    transition: background 0.12s var(--ease), color 0.12s var(--ease);
  }
  .nav-links a:hover {
    background: rgba(255, 255, 255, 0.05);
    color: var(--text-1);
    text-decoration: none;
  }
  .nav-links a:focus-visible {
    outline: 2px solid var(--candle, #4a7c59);
    outline-offset: -1px;
  }
}
@media (max-width: 400px) {
  /* Narrowest real phones (iPhone SE, older Android ~360-390px): wordmark +
     hamburger + CTA pill leaves very little room. Shrink the CTA further
     rather than let it clip/ellipsis. */
  .brand { font-size: 0.95rem; letter-spacing: 0.16em; }
  .nav a.cta { font-size: 0.82rem; padding: 0.55rem 0.85rem; max-width: 42vw; }
}

/* ── Buttons (matches app's .glass-btn family) ───────────────────────── */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.9em 1.6em;
  border-radius: 999px;
  font-family: var(--font-body);
  font-size: 0.95rem;
  font-weight: 500;
  letter-spacing: 0.005em;
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition:
    transform 0.15s var(--ease),
    box-shadow 0.2s ease,
    background 0.2s ease,
    border-color 0.2s ease,
    filter 0.2s ease;   /* v2026-07-14 — so the :hover brightness eases in with the lift instead of snapping a frame early */
  outline: none;
  user-select: none;
}
.btn:focus-visible { outline: 2px solid var(--candle); outline-offset: 3px; }
.btn:active { transform: scale(0.97); transition-duration: 0.05s; }

/* v0.5.61: .btn-primary repointed gold → forest. Now uses --accent +
   --accent-soft so it cascades through theme + accent dimension overrides.
   Text stays light — forest is dark enough that white reads well. */
.btn-primary {
  background:
    linear-gradient(165deg, rgba(255, 255, 255, 0.18), rgba(255, 255, 255, 0.04) 60%),
    var(--accent-soft);
  color: var(--text-1);
  border-color: var(--accent);
  backdrop-filter: blur(10px) saturate(120%);
  -webkit-backdrop-filter: blur(10px) saturate(120%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    inset 0 -2px 4px rgba(0, 0, 0, 0.18),
    0 4px 14px -4px var(--accent-soft),
    0 1px 2px rgba(0, 0, 0, 0.2);
}
.btn-primary:hover {
  background:
    linear-gradient(165deg, rgba(255, 255, 255, 0.26), rgba(255, 255, 255, 0.06) 60%),
    var(--accent-soft);
  filter: brightness(1.12);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.50),
    inset 0 -2px 4px rgba(0, 0, 0, 0.18),
    0 6px 22px -4px var(--accent),
    0 1px 2px rgba(0, 0, 0, 0.2);
  transform: translateY(-1px);
  color: var(--text-1);
  text-decoration: none;
}

.btn-ghost {
  background:
    linear-gradient(165deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.01) 60%),
    rgba(255, 255, 255, 0.03);
  color: var(--text-1);
  border-color: rgba(255, 255, 255, 0.10);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.08),
    0 2px 8px rgba(0, 0, 0, 0.2);
}
.btn-ghost:hover {
  background:
    linear-gradient(165deg, rgba(255, 255, 255, 0.10), rgba(255, 255, 255, 0.03) 60%),
    rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.18);
  color: var(--text-1);
  text-decoration: none;
}

.btn-large { padding: 1.05em 1.9em; font-size: 1.02rem; }

.btn-detail {
  font-family: var(--font-mono);
  font-size: 0.78em;
  font-weight: 400;
  opacity: 0.78;
  margin-left: 0.4em;
}

/* ── Glass card (verbatim from src/index.css) ────────────────────────── */
.glass-card {
  /* v2026-07-14 — the old fill rgba(4,6,14,0.82) composited DARKER than the
     page, so cards read as flat voids (no edge, black-on-near-black shadow).
     Lifted the slate fill above the background, added a top catchlight, a
     readable 10% edge, and a tight negative-spread drop so cards read as
     raised surfaces. Still dark, still glass. Strictly in-palette (Rule 31). */
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0) 42%),
    rgba(13, 18, 27, 0.74);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 18px;
  backdrop-filter: blur(20px) saturate(120%);
  -webkit-backdrop-filter: blur(20px) saturate(120%);
  box-shadow:
    0 14px 38px -12px rgba(0, 0, 0, 0.85),
    inset 0 1px 0 rgba(255, 255, 255, 0.10),
    0 0 50px rgba(108, 94, 220, 0.05);
  transition: box-shadow 0.3s ease, border-color 0.3s ease;
}
.glass-card:hover {
  border-color: rgba(255, 255, 255, 0.15);
  box-shadow:
    0 20px 50px -14px rgba(0, 0, 0, 0.9),
    inset 0 1px 0 rgba(255, 255, 255, 0.13),
    0 0 70px rgba(108, 94, 220, 0.09);
}

/* ═══════════════════════════════════════════════════════════════════════
   HERO
   ═══════════════════════════════════════════════════════════════════════ */
.hero { padding: clamp(3.5rem, 9vw, 6rem) 0 clamp(2rem, 5vw, 4rem); }

.hero .wrap { max-width: 880px; }

/* Hero logo lockup — uploaded GG mark + GOOD GRIEF wordmark + R · I · P
   stacked vertically. Replaced flat composite .hero-logo PNG in v0.5.54.
   Wordmark + RIP use site fonts so they scale crisply at any DPI. */
.hero-logo-lockup {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 0 0 2.2rem;
  user-select: none;
}
.hero-logo-mark {
  /* larger hero mark — responsive; source is 2368×1740 (≈1.36:1), so height
     follows width and object-fit preserves the real proportions (no squish). */
  width: clamp(122px, 12.5vw, 164px);
  height: auto;
  object-fit: contain;
  display: block;
  opacity: 0.96;
  filter: drop-shadow(0 6px 30px rgba(74, 124, 89, 0.20));
}
.hero-wordmark {
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 2.7vw, 1.85rem);
  font-weight: 400;
  letter-spacing: 0.24em;
  color: var(--text-1);
  margin: 1rem 0 0;
}
/* R · I · P — a pronounced little epitaph under the wordmark: the display
   serif at near-wordmark size, in the candle accent, flanked by hairline
   rules that fade in from the accent. It's the brand's wink (goodgrief.rip). */
.hero-rip {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.9rem;
  margin: 0.8rem 0 0;
}
.hero-rip span {
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 2vw, 1.4rem);
  font-weight: 500;
  letter-spacing: 0.52em;
  padding-left: 0.52em;       /* balance the trailing tracking so it stays centred */
  color: var(--candle-bright);
}
.hero-rip::before,
.hero-rip::after {
  content: '';
  height: 1px;
  width: clamp(30px, 6vw, 60px);
  flex-shrink: 0;
}
.hero-rip::before { background: linear-gradient(90deg, transparent, var(--candle)); }
.hero-rip::after  { background: linear-gradient(90deg, var(--candle), transparent); }

.hero-title {
  font-size: clamp(2.4rem, 6vw, 4.4rem);
  font-weight: 400; /* v0.5.108 — was 300; Cormorant reads thin at 300 on dark, 400 matches .section-title */
  /* v0.5.101 — gentler than the old -0.018em/1.04 (which were set for Segoe);
     Cormorant is a tighter, taller face and reads better with near-neutral
     tracking and a hair more leading. */
  line-height: 1.07;
  letter-spacing: -0.008em;
  color: var(--text-1);
  margin: 0 0 1.5rem;
  max-width: 20ch;
  text-wrap: balance;   /* stop "for you." stranding as an orphan */
}

.hero-title-em {
  display: block;
  /* v2026-07-14 — midpoint #4a7c59 (L~0.17) sagged dark through the middle of
     the line; candle green #7eac88 (L~0.36) keeps it evenly luminous end-to-end. */
  background: linear-gradient(135deg, #a9c9b0 0%, #7eac88 50%, #c8beff 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  margin-top: 0.15em;
  font-weight: 400; /* v0.5.108 — was 300, matches .hero-title */
}

.hero-sub {
  font-size: clamp(1.05rem, 1.5vw, 1.2rem);
  line-height: 1.65;
  max-width: 56ch;
  color: var(--text-1); /* v0.5.108 — was text-2; brighter body copy on dark */
  margin: 0 0 2.2rem;
  font-weight: 400;
  text-wrap: pretty;
}

.hero-ctas {
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem;
  margin-bottom: 1.6rem;
}

.hero-foot {
  font-size: 0.85rem;
  color: var(--text-2); /* v0.5.108 — was text-3; real copy, too dim before */
  max-width: 50ch;
  margin: 1.5rem 0 0;
  line-height: 1.55;
}

/* ═══════════════════════════════════════════════════════════════════════
   PITCH
   ═══════════════════════════════════════════════════════════════════════ */
.pitch p {
  font-size: 1.05rem;
  line-height: 1.75;
  color: var(--text-1); /* v0.5.108 — was text-2; primary reading copy, now bright */
  margin: 0 0 1.4em;
}

.pitch-aside {
  font-size: 1.35rem !important;
  font-weight: 400; /* v0.5.108 — was 300; reads light in sans at this size */
  color: var(--candle-bright) !important;
  border-left: 2px solid var(--candle);
  padding-left: 1.2rem;
  margin: 2.5rem 0 0 !important;
  max-width: 36ch;
  line-height: 1.4 !important;
  letter-spacing: -0.005em;
}

/* ═══════════════════════════════════════════════════════════════════════
   HOW IT WORKS — uses .glass-card primitive directly
   ═══════════════════════════════════════════════════════════════════════ */
.how-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1.2rem;
  margin-top: 2.5rem;
}

.how-card {
  /* Inherits .glass-card via class */
  padding: 1.6rem 1.4rem;
}

.how-num {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  color: var(--candle);
  margin-bottom: 0.9rem;
  font-weight: 500;
}

.how-card h3 {
  font-weight: 400;
  font-size: 1.15rem;
  color: var(--text-1);
  margin: 0 0 0.6rem;
}

.how-card p {
  margin: 0;
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--text-2);
}

/* ═══════════════════════════════════════════════════════════════════════
   PREVIEW — Real screenshots from the desktop app
   ═══════════════════════════════════════════════════════════════════════ */

.screenshot {
  margin: 0;
  border-radius: 18px;               /* --r-lg — matches the .glass-card family */
  overflow: hidden;
  /* Lifted matte surround so the dark app UI reads as a *framed product shot*
     rather than an empty box on a dark page (the single biggest polish gap). */
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.015));
  border: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow:
    0 24px 60px -20px rgba(0, 0, 0, 0.8),
    0 2px 8px rgba(0, 0, 0, 0.5),
    inset 0 0 0 1px rgba(255, 255, 255, 0.06);
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease);
}

.screenshot:hover {
  transform: translateY(-2px);
  box-shadow:
    0 30px 70px -20px rgba(0, 0, 0, 0.85),
    0 3px 10px rgba(0, 0, 0, 0.55),
    inset 0 0 0 1px rgba(255, 255, 255, 0.09);
}

.screenshot picture {
  display: block;
  padding: 8px 8px 0;                /* reveal the matte around the shot (top + sides) */
}
.screenshot img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 8px;                /* --r-sm inner radius, nested inside the frame */
  background: #060810;
  box-shadow: 0 6px 18px -10px rgba(0, 0, 0, 0.7);
}
.screenshot figcaption {
  padding: 0.9rem 1.1rem 1rem;
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--text-2);
  border-top: 1px solid rgba(255, 255, 255, 0.04);
  background: rgba(255, 255, 255, 0.012);
}

.screenshot figcaption strong {
  display: block;
  color: var(--text-1);
  font-weight: 500;
  font-size: 0.9rem;
  margin-bottom: 0.2rem;
}

/* ─── Screenshot lightbox (added v0.5.42) ─────────────────────────────────
   Native <dialog> handles focus-trap + Escape key. We just style the chrome.
   The dialog itself (the modal container) is set to fit-content so the
   image determines size; backdrop is styled via ::backdrop. */
.screenshot-lightbox[open] {
  /* Reset dialog defaults — we want the image to size the modal */
  border: none;
  padding: 0;
  background: transparent;
  max-width: 92vw;
  max-height: 92vh;
  /* Centred via dialog default + flex */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.8rem;
}
.screenshot-lightbox::backdrop {
  background: rgba(4, 6, 14, 0.88);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.screenshot-lightbox img {
  display: block;
  max-width: 92vw;
  max-height: 84vh;
  width: auto;
  height: auto;
  border-radius: 10px;
  box-shadow:
    0 30px 90px rgba(0, 0, 0, 0.7),
    0 0 80px rgba(108, 94, 220, 0.12);
  background: #060810;
}
.screenshot-lightbox-caption {
  margin: 0;
  padding: 0 1rem;
  max-width: 60ch;
  text-align: center;
  font-size: 0.85rem;
  line-height: 1.5;
  color: rgba(212, 200, 250, 0.78);
}
.screenshot-lightbox-close {
  position: fixed;
  top: 1.2rem;
  right: 1.4rem;
  width: 40px;
  height: 40px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 50%;
  background: rgba(20, 22, 34, 0.85);
  color: rgba(240, 240, 250, 0.9);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.18s var(--ease), transform 0.18s var(--ease);
  z-index: 10;
}
.screenshot-lightbox-close:hover {
  background: rgba(40, 42, 60, 0.95);
  transform: scale(1.06);
}
.screenshot-lightbox-close:focus-visible {   /* v2026-07-14 — keep a real focus ring for keyboard users (was outline:none) */
  background: rgba(40, 42, 60, 0.95);
  transform: scale(1.06);
  outline: 2px solid var(--candle-bright);
  outline-offset: 2px;
}
/* Hint that screenshots are clickable. Inline style applied via JS sets
   cursor: zoom-in, this rule adds a faint glow on hover for desktop. */
.screenshot:hover img {
  filter: brightness(1.04);
}

/* Hero screenshot — the focal product shot, dressed with a faux app title bar.
   Dots are neutral (--text-3), NOT the classic red/amber/green traffic lights
   (Rule 31). */
.screenshot-hero {
  position: relative;
  margin: 2rem auto 1.6rem;
  max-width: 1040px;
}
.screenshot-hero picture { padding-top: 40px; }
.screenshot-hero::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 32px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border-soft);
  border-radius: 18px 18px 0 0;
  pointer-events: none;
}
.screenshot-hero::after {
  content: '';
  position: absolute;
  top: 12.5px; left: 16px;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--text-3);
  box-shadow: 15px 0 0 var(--text-3), 30px 0 0 var(--text-3);
  opacity: 0.5;
  pointer-events: none;
}

.screenshot-hero figcaption {
  padding: 1.1rem 1.4rem 1.2rem;
  font-size: 0.95rem;
}

.screenshot-hero figcaption strong {
  font-size: 1rem;
}

/* Three-up grid below the hero. Bumped from 1100px → 1280px in v0.5.42 so
   each screenshot renders ~420px wide instead of ~360px — meaningful detail
   gain while still keeping the page compact. The lightbox handles full detail. */
.screenshot-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
  max-width: 1040px;   /* aligned with the hero shot + footer for one clean column */
  margin: 0 auto;
}

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

/* Footer privacy reassurance — minimal, just text + dot */
.screenshot-footer {
  margin: 1.6rem auto 0;
  max-width: 1040px;
  padding: 0.85rem 1rem;
  font-size: 0.88rem;
  color: var(--text-3);
  background: rgba(0, 0, 0, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.04);
  border-radius: 10px;
  display: flex;
  align-items: center;
  gap: 0.7rem;
}

.screenshot-footer .dot-iris {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--iris-bright, #c8beff);
  box-shadow: 0 0 8px rgba(108, 94, 220, 0.6);
  flex-shrink: 0;
}

/* ═══════════════════════════════════════════════════════════════════════
   FEATURES GRID
   ═══════════════════════════════════════════════════════════════════════ */
.feature-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1.2rem;
  margin-top: 2.5rem;   /* match .how-grid / .ea-card title→content interval */
}

.feature {
  /* Uses .glass-card */
  padding: 1.5rem 1.4rem;
}

.feature h3 {
  font-size: 11px;             /* match the .eyebrow / .ea-tier-label kicker family */
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--candle);
  margin: 0 0 1rem;
}

.feature ul {
  list-style: none;
  padding: 0;
  margin: 0;
}

.feature li {
  padding: 0.42rem 0;
  font-size: 0.92rem;
  color: var(--text-2);
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
}
.feature li:last-child { border-bottom: none; }

/* v2026-07-15 — "what's in it" enrichment: a benefit line under each card
   label, and a muted "…and more like it" hinting the list is only a taste. */
.feature-kicker {
  color: var(--text-2);
  font-size: 0.92rem;
  line-height: 1.45;
  margin: 0.15rem 0 0.9rem;
}
.feature li.more { color: var(--text-3); font-style: italic; }

/* v2026-07-15 — the two optional AI helpers, surfaced on the homepage. Reuses
   the .glass-card primitive; titles follow the .how-card/.price-card content
   convention (NOT the tiny .feature kicker); honesty line reuses .screenshot-
   footer + .dot-iris so it reads as one system with "a quick look". */
.ai-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1.4rem;
  margin-top: 2.5rem;
}
.ai-card { padding: 1.8rem 1.6rem; }
.ai-card h3 {
  font-size: 1.2rem;
  font-weight: 400;
  color: var(--text-1);
  letter-spacing: -0.005em;
  margin: 0 0 0.6rem;
}
.ai-card p { color: var(--text-2); font-size: 0.98rem; line-height: 1.62; margin: 0; }

/* v2026-07-15 — demo section "while you're in there" peek: a left-aligned,
   centred block of oddly-specific real sample-plan details to go open. */
.demo-peek {
  max-width: 48ch;
  margin: 2.2rem auto 0;
  text-align: left;
  color: var(--text-2);
  font-size: 0.98rem;
  line-height: 1.6;
}
.demo-peek-lead { color: var(--text-3); margin: 0 0 0.6rem; }
.demo-peek ul { list-style: none; padding: 0; margin: 0 0 0.9rem; }
.demo-peek li { padding: 0.32rem 0 0.32rem 1.2rem; position: relative; }
.demo-peek li::before { content: '\2014'; position: absolute; left: 0; color: var(--candle); }
.demo-peek-foot { margin: 0; }

/* v2026-07-15 — hero secondary "just keep me posted" as a quiet text link
   under the two buttons (the button slot now belongs to the live demo). */
.hero-altlink { margin: 0.85rem 0 0; font-size: 0.9rem; }
.hero-altlink a { color: var(--text-3); border-bottom: 1px solid rgba(255, 255, 255, 0.14); }
.hero-altlink a:hover { color: var(--candle-bright); border-bottom-color: var(--candle); }

/* ═══════════════════════════════════════════════════════════════════════
   EARLY ACCESS — uses .glass-card primitive
   ═══════════════════════════════════════════════════════════════════════ */
.early-access > .wrap > p {
  font-size: 1.02rem;
  line-height: 1.7;
  color: var(--text-2);
  margin-bottom: 1.4em;
}

.ea-card {
  margin-top: 2.5rem;
  /* Uses .glass-card */
  border-radius: 18px;
  overflow: hidden;
}

.ea-card-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.ea-tier {
  padding: 1.8rem 1.6rem;
}

.ea-tier:first-child {
  background: linear-gradient(135deg, rgba(74, 124, 89, 0.06), transparent 70%);
  border-right: 1px solid rgba(255, 255, 255, 0.06);
}

.ea-tier-future {
  opacity: 0.62;   /* v2026-07-14 — 0.55 dropped the small bullet copy under AA (~4.1:1); 0.62 clears it while staying de-emphasized */
}

.ea-tier-label {
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-3);
  margin: 0 0 0.6rem;
  font-weight: 500;
}

.ea-tier:first-child .ea-tier-label {
  color: var(--candle);
}

.ea-price {
  font-size: 2.4rem;
  font-weight: 300;
  color: var(--text-1);
  margin: 0 0 1rem;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
.ea-price span {
  font-size: 0.78rem;
  font-weight: 400;
  color: var(--text-3);
  margin-left: 0.3em;
  letter-spacing: 0;
}

.ea-tier:first-child .ea-price {
  background: linear-gradient(135deg, #a9c9b0 0%, #4a7c59 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.ea-bullets {
  list-style: none;
  padding: 0;
  margin: 0;
}
.ea-bullets li {
  padding: 0.35rem 0;
  font-size: 0.9rem;
  color: var(--text-2);
  position: relative;
  padding-left: 1.3rem;
}
.ea-bullets li::before {
  content: '✓';
  position: absolute;
  left: 0;
  color: var(--candle);
  font-weight: 700;
}

.ea-tier-future .ea-bullets li::before {
  content: '·';
  color: var(--text-4);
  font-weight: 700;
}

.ea-cta-row {
  padding: 1.4rem 1.6rem;
  background: rgba(0, 0, 0, 0.2);
}

.ea-fine {
  margin: 0.8rem 0 0;
  font-size: 0.82rem;
  color: var(--text-3);
}

/* ═══════════════════════════════════════════════════════════════════════
   EMAIL SIGNUP — uses app's input styling
   ═══════════════════════════════════════════════════════════════════════ */
.email-signup p {
  font-size: 1rem;
  line-height: 1.7;
  color: var(--text-2);
}

.ea-form {
  display: flex;
  gap: 0.6rem;
  margin: 1.8rem 0 0.5rem;
  flex-wrap: wrap;
}

.ea-form input[type="email"] {
  flex: 1;
  min-width: 220px;
  padding: 0.85em 1.05em;
  font-family: var(--font-body);
  font-size: 0.95rem;
  background: rgba(6, 8, 16, 0.70);
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 10px;
  color: var(--text-1);
  backdrop-filter: blur(8px);
  transition: border-color 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
}
.ea-form input[type="email"]::placeholder { color: rgba(114, 108, 168, 0.6); }
.ea-form input[type="email"]:focus {
  outline: none;
  border-color: rgba(74, 124, 89, 0.45);
  box-shadow: 0 0 0 2px rgba(74, 124, 89, 0.10), 0 0 16px rgba(74, 124, 89, 0.08);
  background: rgba(6, 8, 16, 0.85);
}

.ea-status {
  margin: 0.8rem 0 0;
  font-size: 0.92rem;
  min-height: 1.4em;
}
.ea-status-success { color: #94e2a3; }
/* Rule 31: error signal stays on the plum/mauve side, never pink-red. */
.ea-status-error   { color: #cf9dc4; }
.ea-status-info    { color: var(--text-3); }

.ea-privacy {
  margin-top: 1.5rem;
  color: var(--text-3);
  font-size: 0.85rem;
}
.ea-privacy a {
  color: var(--text-2);
  text-decoration: underline;
  text-decoration-color: rgba(255, 255, 255, 0.14);
  text-underline-offset: 3px;
}
.ea-privacy a:hover { color: var(--candle-bright); }

/* ═══════════════════════════════════════════════════════════════════════
   FAQ
   ═══════════════════════════════════════════════════════════════════════ */
.faq-item {
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  padding: 1.1rem 0;
}
.faq-item:first-of-type { border-top: 1px solid rgba(255, 255, 255, 0.05); }

.faq-item summary {
  cursor: pointer;
  font-size: 1.1rem;
  font-weight: 400;
  color: var(--text-1);
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  user-select: none;
  padding: 0.2rem 0;
  letter-spacing: -0.005em;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:focus-visible,
details > summary:focus-visible {   /* also covers pricing.html's bare <details> */
  outline: 2px solid var(--candle-bright);
  outline-offset: 4px;
  border-radius: 6px;
}

/* v2026-07-14 — the FAQ rows were the deadest region on the page: no hover
   feedback and a marker transition that never fired. Warm the question to the
   candle green under the cursor, and give the +/− a small felt pop on open. */
.faq-item summary { transition: color 0.18s var(--ease); }
.faq-item summary:hover { color: var(--candle-bright); }
.faq-item summary:hover::after { color: var(--candle-bright); }
.faq-item summary::after {
  content: '+';
  font-family: var(--font-mono);
  font-size: 1.3rem;
  color: var(--candle);
  transition: transform 0.18s var(--ease), color 0.18s var(--ease);
  flex-shrink: 0;
  font-weight: 300;
}

.faq-item[open] summary::after { content: '−'; transform: scale(1.12); }

.faq-item p {
  margin: 0.9rem 0 0;
  font-size: 0.95rem;
  line-height: 1.7;
  color: var(--text-2);
  padding-right: 2rem;
}

/* ═══════════════════════════════════════════════════════════════════════
   FOOTER
   ═══════════════════════════════════════════════════════════════════════ */
.site-footer {
  border-top: 1px solid rgba(255, 255, 255, 0.05);
  padding: 3rem 0 2.2rem;
  margin-top: 2rem;
}

.site-footer .row {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 2rem;
  flex-wrap: wrap;
  margin-bottom: 1.5rem;
}

.site-footer nav {
  display: flex;
  gap: 1.2rem;
  flex-wrap: wrap;
}

.site-footer nav a {
  color: var(--text-3);
  font-size: 0.9rem;
}
.site-footer nav a:hover { color: var(--text-1); text-decoration: none; }

.site-footer .legal {
  font-size: 0.82rem;
  color: var(--text-3);   /* was --text-4 — below AA on every theme for real copy */
  padding-top: 1rem;
  border-top: 1px solid rgba(255, 255, 255, 0.04);
}

/* ═══════════════════════════════════════════════════════════════════════
   RESPONSIVE
   ═══════════════════════════════════════════════════════════════════════ */
@media (max-width: 720px) {
  .hero-ctas { flex-direction: column; align-items: stretch; }
  .hero-ctas .btn { justify-content: center; }
  /* v2026-07-14 — let the founding-member price wrap to a 2nd line instead of
     clipping '→ $39, once' on the smallest phones; no-op where it already fits. */
  .hero-ctas .btn-primary { flex-wrap: wrap; }
  .hero-ctas .btn-primary .btn-detail { margin-left: 0; }
  /* footer links to a comfortable ~44px touch target when they wrap */
  .site-footer nav { gap: 0.35rem 1.4rem; }
  .site-footer nav a { display: inline-flex; align-items: center; min-height: 44px; }
  .hero-logo-mark { width: 104px; height: auto; }
  .hero-wordmark { font-size: 1.18rem; }
  .hero-rip { gap: 0.65rem; }
  .hero-rip span { font-size: 0.95rem; letter-spacing: 0.42em; padding-left: 0.42em; }


  .ea-card-row { grid-template-columns: 1fr; }
  .ea-tier:first-child { border-right: none; border-bottom: 1px solid rgba(255, 255, 255, 0.06); }

  .ea-form { flex-direction: column; }
  .ea-form input[type="email"] { min-width: 0; flex: none; }  /* flex:1's basis-0 would beat any future explicit height in this column context (the v2 collapse trap) */
  .ea-form .btn { justify-content: center; }
}


/* ═══════════════════════════════════════════════════════════════════════
   REDUCED MOTION
   ═══════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
  html { scroll-behavior: auto; }
}

/* ═══════════════════════════════════════════════════════════════════════
   SECONDARY PAGES
   These styles support pricing.html, download.html, support.html,
   privacy.html, terms.html, 404.html, and portal-return.html. They
   compose the existing primitives (.glass-card, .btn, etc.) but add
   page-specific layout helpers.

   The website was originally designed with a different CSS file (with
   class names like .price-card, .lede, .prose) before the v0.5.2 rewrite
   replaced style.css with the app-faithful version. The HTML on these
   pages still references the older class names. This block restores
   them to the new visual language rather than rewrite seven HTML files.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Section width helper ─────────────────────────────────────────────── */
section.tight {
  padding-top: 2rem;
  padding-bottom: 2rem;
}

/* ── Lede / subtitle under page hero h1 ──────────────────────────────── */
.lede {
  font-size: clamp(1.05rem, 1.5vw, 1.2rem);
  line-height: 1.65;
  color: var(--text-1); /* v0.5.108 — was text-2; brighter body copy on dark */
  max-width: 56ch;
  margin: 0 auto 1.5rem;
  font-weight: 400;
}

/* ── Decorative dot rule (section separator) ─────────────────────────── */
.dotrule {
  text-align: center;
  letter-spacing: 0.6em;
  color: var(--text-4);
  font-size: 0.9rem;
  padding: 2rem 0;
  user-select: none;
}

/* ─────────────────────────────────────────────────────────────────────
   PRICING PAGE
   ───────────────────────────────────────────────────────────────────── */
.price-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.4rem;
  margin: 2rem auto;
  max-width: 800px;
}

/* Chrome (background/border/blur/shadow/hover-lift) comes from .glass-card —
   price-card elements carry both classes now. Only layout lives here. */
.price-card {
  position: relative;
  padding: 2rem 1.6rem 1.8rem;
  display: flex;
  flex-direction: column;
}

.price-card.featured {
  border-color: rgba(74, 124, 89, 0.30);
  background:
    linear-gradient(180deg, rgba(74, 124, 89, 0.04), transparent 60%),
    rgba(4, 6, 14, 0.82);
}

.price-card h3 {
  font-size: 1.2rem;
  font-weight: 400;
  color: var(--text-1);
  margin: 0 0 0.4rem;
  letter-spacing: -0.005em;
}

.price-card p.small {
  color: var(--text-3);
  margin: 0 0 1.4rem;
  font-size: 0.9rem;
}

.price-amount {
  font-size: 3.2rem;
  font-weight: 300;
  color: var(--text-1);
  letter-spacing: -0.025em;
  line-height: 1;
  margin: 0.3rem 0 0.3rem;
}
.price-amount sup {
  font-size: 1.3rem;
  vertical-align: super;
  margin-right: 0.05em;
  color: var(--text-3);
  font-weight: 400;
}

.price-card.featured .price-amount {
  background: linear-gradient(135deg, #a9c9b0 0%, #4a7c59 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.price-period {
  font-size: 0.82rem;
  color: var(--text-3);
  letter-spacing: 0.04em;
  margin-bottom: 1.5rem;
}

.price-card ul {
  list-style: none;
  padding: 0;
  margin: 0 0 1.6rem;
  flex: 1;
}
.price-card ul li {
  padding: 0.42rem 0 0.42rem 1.4rem;
  font-size: 0.92rem;
  color: var(--text-2);
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
  position: relative;
}
.price-card ul li::before {
  content: '✓';
  position: absolute;
  left: 0;
  color: var(--candle);
  font-weight: 700;
}
.price-card ul li:last-child { border-bottom: none; }

.price-card .badge {
  position: absolute;
  top: -10px;
  right: 18px;
  background: linear-gradient(180deg, var(--candle-bright), var(--candle));
  color: #071008;   /* dark label on the bright sage fill — AA (was near-white ~1.8:1) */
  padding: 0.25rem 0.7rem;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  box-shadow: 0 4px 12px rgba(74, 124, 89, 0.35);
}

/* ─────────────────────────────────────────────────────────────────────
   DOWNLOAD PAGE
   ───────────────────────────────────────────────────────────────────── */
.dl-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1.2rem;
  margin: 2rem auto;
}

.dl-card {
  display: block;
  background: rgba(4, 6, 14, 0.82);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 18px;
  padding: 1.5rem 1.4rem;
  backdrop-filter: blur(20px) saturate(120%);
  -webkit-backdrop-filter: blur(20px) saturate(120%);
  text-decoration: none;
  color: inherit;
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease), border-color 0.3s var(--ease);   /* v2026-07-14 — was 0.18s/0.25s: lift+shadow now move on one clock, matching the other cards */
}
.dl-card:hover {
  transform: translateY(-2px);
  border-color: rgba(74, 124, 89, 0.30);
  text-decoration: none;
  box-shadow:
    0 12px 40px rgba(0, 0, 0, 0.65),
    0 0 30px rgba(74, 124, 89, 0.10);
}

.dl-card .os {
  font-size: 1.15rem;
  font-weight: 400;
  color: var(--text-1);
  margin-bottom: 0.2rem;
  letter-spacing: -0.005em;
}

.dl-card .ver {
  display: block;
  font-size: 0.78rem;
  color: var(--candle);
  letter-spacing: 0.06em;
  margin-bottom: 0.8rem;
  font-family: var(--font-mono);
}

.dl-card .arrow {
  color: var(--candle-bright);
  font-size: 0.9rem;
  font-weight: 500;
  display: inline-block;
  transition: transform 0.18s var(--ease);
}
.dl-card:hover .arrow {
  transform: translateX(3px);
  color: var(--candle);
}

/* ─────────────────────────────────────────────────────────────────────
   SUPPORT / FAQ PAGE
   ───────────────────────────────────────────────────────────────────── */
.faq {
  max-width: var(--max-w-prose);
  margin: 0 auto;
}

/* Note: .faq-item already exists in the main FAQ block — secondary pages
   inherit it directly. The .faq class above is a width container only. */

/* ─────────────────────────────────────────────────────────────────────
   PROSE PAGES (Privacy, Terms)
   ───────────────────────────────────────────────────────────────────── */
.prose {
  max-width: var(--max-w-prose);
  margin: 0 auto;
  padding: 3rem 1.5rem;
}

.prose h1 {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4.5vw, 2.8rem);
  font-weight: 400;
  margin: 0 0 0.4rem;
  line-height: 1.1;           /* v2026-07-14 — match the tuned serif titles */
  letter-spacing: -0.005em;
  text-wrap: balance;
}
/* The lightbox trigger — a real <button> wrapping each enlargeable
   screenshot's <picture> (see index.html's lightbox script). Reset to look
   and lay out exactly like the plain image it replaces. */
.gg-lightbox-trigger {
  all: unset;
  display: block;
  width: 100%;
  cursor: zoom-in;
}
.gg-lightbox-trigger:focus-visible {
  outline: 2px solid var(--candle);
  outline-offset: -3px;
  border-radius: 8px;
}

/* Bare page-level <h1> on pages with no dedicated hero layout (download,
   support, portal-return, 404). Cormorant is the deliberate type identity —
   drives the hero title and section titles so the whole page reads
   of-a-piece with the mark; a bare h1 shouldn't fall back to system sans. */
.page-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2.4rem, 5.5vw, 3.8rem);
  line-height: 1.08;          /* v2026-07-14 — match the tuned hero/section serif */
  letter-spacing: -0.005em;   /* was inheriting the sans-tuned -0.01em base */
  text-wrap: balance;         /* stop orphan 2nd lines on the longer subpage titles */
}

.prose h2 {
  font-size: 1.4rem;
  font-weight: 400;
  color: var(--text-1);
  margin: 2.5rem 0 1rem;
  letter-spacing: -0.005em;
}

.prose h3 {
  font-size: 1.1rem;
  font-weight: 500;
  color: var(--text-1);
  margin: 1.8rem 0 0.6rem;
}

.prose p {
  font-size: 1rem;
  line-height: 1.75;
  color: var(--text-2);
  margin: 0 0 1.2em;
}

.prose ul, .prose ol {
  color: var(--text-2);
  line-height: 1.75;
  padding-left: 1.4rem;
  margin: 0 0 1.2em;
}
.prose li { margin-bottom: 0.5em; }

.prose blockquote {
  border-left: 2px solid var(--candle);
  padding: 0.6rem 0 0.6rem 1.2rem;
  margin: 1.5rem 0;
  color: var(--candle-bright);
  font-style: italic;
  font-size: 1.05rem;
  line-height: 1.6;
  background: rgba(74, 124, 89, 0.03);
}

.prose hr {
  border: none;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  margin: 2.5rem 0;
}

.prose code {
  font-family: var(--font-mono);
  font-size: 0.88em;
  background: rgba(255, 255, 255, 0.06);
  padding: 0.1em 0.4em;
  border-radius: 4px;
  color: var(--text-1);
}

.prose strong { color: var(--text-1); font-weight: 600; }

.prose .meta {
  font-size: 0.85rem;
  color: var(--text-3);
  font-style: italic;
  margin: 0 0 2rem;
  font-family: var(--font-mono);
}

.prose a {
  color: var(--candle-bright);
  text-decoration: underline;
  text-decoration-color: rgba(74, 124, 89, 0.3);
  text-underline-offset: 3px;
}
.prose a:hover {
  text-decoration-color: var(--candle);
}

/* Responsive on prose pages */
@media (max-width: 720px) {
  .price-grid { grid-template-columns: 1fr; }
  .dl-grid { grid-template-columns: 1fr; }
  .prose { padding: 2rem 1.2rem; }
}

/* ═══════════════════════════════════════════════════════════════════════
   SAMPLE PDFS SECTION
   "What you walk away with" — links to four real PDFs the app produces.
   Same glass-card aesthetic as the features section above.
   ═══════════════════════════════════════════════════════════════════════ */
.samples {
  /* inherit the global section vertical rhythm; .wrap supplies the gutter.
     (Was double-padding horizontally, so the grid started 1.5rem further in
     than the features grid directly above it.) */
  padding-inline: 0;
}

/* Preview + samples are the two centre-aligned sections — commit their heading
   blocks to the same axis as their content so each has one alignment edge. */
.samples .section-title, .samples .eyebrow,
.preview .section-title, .preview .section-sub {
  text-align: center;
  margin-left: auto;
  margin-right: auto;
}

.samples-lede {
  font-size: clamp(1rem, 1.4vw, 1.1rem);
  line-height: 1.7;
  color: var(--text-2);
  max-width: 60ch;
  margin: 0.5rem auto 2.5rem;
  text-align: center;
}

.samples-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1.4rem;
  max-width: 1040px;   /* aligned with the preview grid above */
  margin: 0 auto;
}

.sample-card {
  display: flex;
  flex-direction: column;
  padding: 1.6rem 1.4rem 1.4rem;
  border-radius: 18px;
  text-decoration: none;
  color: inherit;
  transition: transform 0.18s var(--ease), box-shadow 0.25s ease, border-color 0.25s ease;
}

/* No transform here — sample-card also carries .glass-card, whose polish-layer
   hover rule (below, v0.5.127) already lifts it -4px. Redeclaring -2px here
   would just lose the cascade to the rule that comes later in the file. */
.sample-card:hover {
  border-color: rgba(74, 124, 89, 0.30);
  text-decoration: none;
  box-shadow:
    0 12px 40px rgba(0, 0, 0, 0.65),
    0 0 30px rgba(74, 124, 89, 0.10);
}

.sample-icon {
  width: 40px;
  height: 40px;
  border-radius: 12px;
  background: rgba(74, 124, 89, 0.10);
  border: 1px solid rgba(74, 124, 89, 0.22);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--candle-bright);
  margin-bottom: 1rem;
}

.sample-card h3 {
  font-size: 1.1rem;
  font-weight: 400;   /* v2026-07-14 — was 500; every other card title (how/price/faq) is 400 */
  color: var(--text-1);
  margin: 0 0 0.5rem;
  letter-spacing: -0.005em;
}

.sample-desc {
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--text-2);
  margin: 0 0 1rem;
  flex: 1;
}

.sample-link {
  font-size: 0.85rem;
  color: var(--candle-bright);
  font-weight: 500;
  display: inline-block;
  transition: transform 0.18s var(--ease), color 0.18s ease;
}

.sample-card:hover .sample-link {
  transform: translateX(3px);
  color: var(--candle);
}

.samples-foot {
  text-align: center;
  font-size: 0.8rem;
  color: var(--text-3);
  font-style: italic;
  margin: 2.5rem auto 0;
  max-width: 60ch;
  line-height: 1.6;
}


/* ════════════════════════════════════════════════════════════════════════
   v0.5.72 — Real app tile classes ported to website
   ────────────────────────────────────────────────────────────────────────
   The Design Lab page (preview.html) used to use its own .lab-tile classes
   for the home-screen mockup — completely disconnected from the real
   app's .glass-tile / .icon-wrap. Result: changing button-style in the
   playground bar did nothing to those tiles.

   This block ports the actual app's tile + button-style + section-color
   CSS so the preview.html mockup behaves IDENTICALLY to the deployed
   app. Now the design lab is a true verification surface: if button
   styles work here, they work in the app.
   ════════════════════════════════════════════════════════════════════════ */

/* The tile itself — frosted glass with a colored highlight that varies per group */
.glass-tile {
  /* layout */
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  padding: 8px 6px 8px;
  aspect-ratio: 1 / 1.18;
  min-height: 96px;
  cursor: pointer;
  /* iOS-style: the icon IS the visual; the tile chrome is minimal so the
     screen reads like a phone home screen of vivid icons on a dark wallpaper.
     Border and background almost vanish — any real surface comes from the
     icon-wrap below. */
  border: 1px solid transparent;
  border-radius: 18px;
  background: transparent;
  transition:
    transform 0.18s cubic-bezier(0.22, 1, 0.36, 1),
    background-color 0.25s ease,
    border-color 0.25s ease;
  text-decoration: none;
  outline: none;
  overflow: visible;
}

/* Subtle tile-level glow on hover only — keeps the calm at rest, gives
   feedback on intent. */
.glass-tile::before {
  content: '';
  position: absolute;
  top: 4px; left: 50%;
  width: 76px; height: 76px;
  transform: translateX(-50%);
  background: var(--tile-glow, radial-gradient(circle, rgba(108, 94, 220, 0.32), transparent 65%));
  filter: blur(18px);
  opacity: 0;
  pointer-events: none;
  z-index: 0;
  transition: opacity 0.3s ease;
  border-radius: 18px;
}

/* The decorative top-edge highlight only makes sense on a tile with a
   surface — without one, hide it. */
.glass-tile::after { display: none; }

.glass-tile:hover {
  transform: translateY(-2px);
  background: rgba(255, 255, 255, 0.03);
  border-color: rgba(255, 255, 255, 0.06);
}
.glass-tile:hover::before { opacity: 0.85; }

/* iOS press: the WHOLE tile dips slightly, but the dominant feel is the
   icon-wrap shrinking a touch. */
.glass-tile:active {
  transform: scale(0.96);
  transition-duration: 0.08s;
}
.glass-tile:active .icon-wrap {
  transform: scale(0.94);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.25),
    inset 0 6px 16px rgba(0, 0, 0, 0.22),
    0 1px 3px rgba(0, 0, 0, 0.4);
}

.glass-tile:focus-visible {
  outline: 2px solid var(--candle, #4a7c59);
  outline-offset: 3px;
}

/* The icon container — this is now the visually dominant element.
   Large (60×60), gradient-filled per group, white icon stroke, with
   iOS-style top highlight and bottom shadow. The rounded-square shape
   (continuous-curvature, 22% radius) matches the iOS app icon mask. */
.glass-tile .icon-wrap {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 60px; height: 60px;
  margin-bottom: 10px;
  border-radius: 14px;
  /* Per-group gradient set via --tile-icon-bg. v0.5.59: alpha pushed down to
     0.45-0.58 (was 0.72-0.82) so the see-through effect is actually VISIBLE
     against dark backgrounds. Previous values were too subtle — the body is
     near-black, so 0.78 alpha read as ~95% solid to the human eye.
     Backdrop-filter blur(14px) is what creates the frosted-glass effect
     (icons frost whatever's behind them). */
  background: var(--tile-icon-bg, linear-gradient(165deg, rgba(139, 126, 232, 0.55) 0%, rgba(108, 94, 220, 0.50) 100%));
  backdrop-filter: blur(14px) saturate(120%);
  -webkit-backdrop-filter: blur(14px) saturate(120%);
  /* White icons override any group color choice — iOS uniformity. */
  color: #ffffff;
  box-shadow:
    /* Top inner highlight — bumped to 0.5 so the iOS-glass rim still reads
       against the much more translucent fill. */
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    inset 0 -2px 4px rgba(0, 0, 0, 0.22),
    /* Outer shadow — subtle elevation */
    0 4px 12px -4px var(--tile-shadow-color, rgba(108, 94, 220, 0.45)),
    0 1px 2px rgba(0, 0, 0, 0.30);
  transition: transform 0.12s ease, box-shadow 0.18s ease, background 0.3s ease;
}

/* Lucide icon rendering inside the wrap: stroke-only, slightly thicker
   stroke for visual weight at this size. iOS app icons typically use
   filled glyphs; we're using outline lucide icons but boosting stroke
   width to match the visual presence. */
.glass-tile .icon-wrap > svg {
  width: 28px;
  height: 28px;
  stroke-width: 2;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.18));
}

.glass-tile .label {
  position: relative;
  z-index: 1;
  font-family: 'Segoe UI', -apple-system, sans-serif;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.2;
  text-align: center;
  /* Brighter than before — labels need to read clearly under iOS-style
     icons without competing with them. */
  color: rgba(237, 233, 255, 0.88);
  letter-spacing: 0.005em;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  max-width: 100%;
  padding: 0 2px;
}

/* Completion dot — sits like a notification badge on the top-right corner
   of the icon-wrap. Positioned relative to the tile's center (because the
   icon-wrap is centered) with a fixed offset that puts it on the icon's
   visible upper-right. */
.glass-tile .done-dot {
  position: absolute;
  top: 6px;
  left: 50%;
  margin-left: 22px; /* half of icon-wrap (30) minus dot half-width (8) */
  width: 12px; height: 12px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.16);
  border: 2px solid rgba(10, 13, 28, 0.95);
  z-index: 3;
  transition: background-color 0.3s ease, box-shadow 0.3s ease;
}
.glass-tile.is-complete .done-dot {
  background: #34c759; /* iOS system green */
  box-shadow: 0 0 6px rgba(52, 199, 89, 0.5);
}

/* Numeric badge — iOS-style red pill in the top-right corner of the icon */
.glass-tile .badge {
  position: absolute;
  top: 2px;
  left: 50%;
  margin-left: 18px;
  min-width: 22px;
  height: 20px;
  padding: 0 6px;
  display: grid; place-items: center;
  background: var(--tile-badge-bg, #5b7a9e); /* iOS system red */
  color: #ffffff;
  border-radius: 999px;
  border: 2px solid rgba(10, 13, 28, 0.95);
  font-family: 'Segoe UI', sans-serif;
  font-size: 10px;
  font-weight: 700;
  z-index: 3;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
}

/* Group-specific palettes — gradient fills for the iOS-style rounded-square
   icons. v0.5.59: alpha pushed down to 0.42-0.58 (was 0.72-0.82) so the
   see-through effect is actually visible. The lighter top stop keeps slightly
   more saturation than the bottom stop — creates the "glass catches light at
   top, fades through at bottom" iOS-glass illusion. Combined with stronger
   backdrop-filter blur, tiles now properly frost the cloud/body behind them. */
/* ════════════════════════════════════════════════════════════════════════
   v0.5.70 — Per-section color variables
   ────────────────────────────────────────────────────────────────────────
   Each tile group reads its colour from a named CSS variable. Default values
   live on :root; presets (data-section-colors="X") override those variables.
   This means changing the section-color preset re-skins every tile group at
   once via the cascade, and the per-group rules below stay simple.

   Rule 31 fix: The previous Start palette used gold (#C89327, #A47A1F) and
   the Legacy palette used red (#F47B8C, #D6485E, #A83142). Both replaced
   here — Start now sage-green throughout, Legacy now rose-mauve (purple
   side, not pink-red side).
   ════════════════════════════════════════════════════════════════════════ */
:root {
  /* Per-section main colour (used in gradient mid-stop). */
  --section-start: 126, 172, 136;       /* sage green (was gold-mixed) */
  --section-start-glow: rgba(74, 124, 89, 0.30);
  --section-media: 139, 124, 232;       /* lavender/iris */
  --section-media-glow: rgba(168, 154, 255, 0.30);
  --section-ceremony: 108, 94, 220;     /* iris */
  --section-ceremony-glow: rgba(108, 94, 220, 0.30);
  --section-legacy: 168, 127, 154;      /* rose-mauve (was red) */
  --section-legacy-glow: rgba(168, 127, 154, 0.28);
  --section-after: 58, 158, 128;        /* teal-green */
  --section-after-glow: rgba(56, 178, 148, 0.26);
  --section-legal: 139, 128, 176;       /* lavender */
  --section-legal-glow: rgba(189, 178, 232, 0.24);
  --section-settings: 110, 116, 130;    /* gray */
  --section-settings-glow: rgba(255, 255, 255, 0.10);
}

.tile-grid[data-group="Start"]     .glass-tile {
  --tile-glow: radial-gradient(circle, var(--section-start-glow), transparent 65%);
  --tile-icon-bg: linear-gradient(165deg,
      rgba(var(--section-start), 0.62) 0%,
      rgba(var(--section-start), 0.50) 60%,
      rgba(var(--section-start), 0.42) 100%);
  --tile-shadow-color: rgba(var(--section-start), 0.45);
  --tile-section-color: rgb(var(--section-start));
  --tile-section-soft: rgba(var(--section-start), 0.20);
}
.tile-grid[data-group="Media"]     .glass-tile {
  --tile-glow: radial-gradient(circle, var(--section-media-glow), transparent 65%);
  --tile-icon-bg: linear-gradient(165deg,
      rgba(var(--section-media), 0.62) 0%,
      rgba(var(--section-media), 0.50) 60%,
      rgba(var(--section-media), 0.42) 100%);
  --tile-shadow-color: rgba(var(--section-media), 0.45);
  --tile-section-color: rgb(var(--section-media));
  --tile-section-soft: rgba(var(--section-media), 0.20);
}
.tile-grid[data-group="Ceremony"]  .glass-tile {
  --tile-glow: radial-gradient(circle, var(--section-ceremony-glow), transparent 65%);
  --tile-icon-bg: linear-gradient(165deg,
      rgba(var(--section-ceremony), 0.62) 0%,
      rgba(var(--section-ceremony), 0.50) 60%,
      rgba(var(--section-ceremony), 0.42) 100%);
  --tile-shadow-color: rgba(var(--section-ceremony), 0.50);
  --tile-section-color: rgb(var(--section-ceremony));
  --tile-section-soft: rgba(var(--section-ceremony), 0.20);
}
.tile-grid[data-group="Legacy"]    .glass-tile {
  --tile-glow: radial-gradient(circle, var(--section-legacy-glow), transparent 65%);
  --tile-icon-bg: linear-gradient(165deg,
      rgba(var(--section-legacy), 0.62) 0%,
      rgba(var(--section-legacy), 0.50) 60%,
      rgba(var(--section-legacy), 0.42) 100%);
  --tile-shadow-color: rgba(var(--section-legacy), 0.42);
  --tile-section-color: rgb(var(--section-legacy));
  --tile-section-soft: rgba(var(--section-legacy), 0.20);
}
.tile-grid[data-group="After: People & things"] .glass-tile,
.tile-grid[data-group="After: Money & accounts"] .glass-tile {
  --tile-glow: radial-gradient(circle, var(--section-after-glow), transparent 65%);
  --tile-icon-bg: linear-gradient(165deg,
      rgba(var(--section-after), 0.55) 0%,
      rgba(var(--section-after), 0.48) 60%,
      rgba(var(--section-after), 0.42) 100%);
  --tile-shadow-color: rgba(var(--section-after), 0.42);
  --tile-section-color: rgb(var(--section-after));
  --tile-section-soft: rgba(var(--section-after), 0.20);
}
.tile-grid[data-group="Legal & directives"] .glass-tile,
.tile-grid[data-group="Logistics & access"] .glass-tile {
  --tile-glow: radial-gradient(circle, var(--section-legal-glow), transparent 65%);
  --tile-icon-bg: linear-gradient(165deg,
      rgba(var(--section-legal), 0.55) 0%,
      rgba(var(--section-legal), 0.48) 60%,
      rgba(var(--section-legal), 0.42) 100%);
  --tile-shadow-color: rgba(var(--section-legal), 0.42);
  --tile-section-color: rgb(var(--section-legal));
  --tile-section-soft: rgba(var(--section-legal), 0.20);
}
.tile-grid[data-group="Settings"]  .glass-tile {
  --tile-glow: radial-gradient(circle, var(--section-settings-glow), transparent 65%);
  --tile-icon-bg: linear-gradient(165deg,
      rgba(var(--section-settings), 0.55) 0%,
      rgba(var(--section-settings), 0.48) 60%,
      rgba(var(--section-settings), 0.42) 100%);
  --tile-shadow-color: rgba(var(--section-settings), 0.40);
  --tile-section-color: rgb(var(--section-settings));
  --tile-section-soft: rgba(var(--section-settings), 0.20);
}

/* ════════════════════════════════════════════════════════════════════════
   v0.5.69 — Button-style tile variants
   ────────────────────────────────────────────────────────────────────────
   The original [data-button-style="X"] rules only targeted .glass-btn-primary.
   But the actual home screen surface users see is .glass-tile .icon-wrap
   (the 60×60 coloured square with the icon). Without these rules, changing
   button style does nothing visible on the overview screen.
   Each style here re-skins the icon-wrap to match the button-style
   character. Keeps the per-group --tile-icon-bg gradient as the base for
   styles that respect the gradient colour (most do); overrides fully for
   styles that have a distinctive look (solid, outlined, neon, ghost).
   v0.5.69 also adds --surface-alpha for the transparency slider.
   ════════════════════════════════════════════════════════════════════════ */

:root {
  --surface-alpha: 1;  /* multiplier for translucent surfaces (0.4–1.4 from slider) */
}

/* LIQUID — animated gradient shift. */
@keyframes liquid-shift {
  0%, 100% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
}

/* ════════════════════════════════════════════════════════════════════════
   v0.5.69 — Surface alpha control (transparency slider)
   ────────────────────────────────────────────────────────────────────────
   The slider in the design modal sets --surface-alpha to a multiplier
   (default 1, range 0.4–1.4). We apply it to the tile icon-wrap and the
   glass-card via opacity-style modulation. Tile icon-wrap reads it as a
   filter on the existing background.
   ════════════════════════════════════════════════════════════════════════ */
.glass-tile .icon-wrap {
  filter: opacity(calc(var(--surface-alpha, 1) * 100%));
}
.glass-card {
  filter: opacity(calc(var(--surface-alpha, 1) * 100%));
}

/* ════════════════════════════════════════════════════════════════════════
   v0.5.70 — Section-color presets
   ────────────────────────────────────────────────────────────────────────
   data-section-colors="X" on <html> overrides the per-section CSS variables
   defined on :root. Each preset reskins all 7 sections at once.
   Default (no attribute set) uses the :root values above.

   Rule 31 strictly observed throughout — no reds, yellows, or golds.
   ════════════════════════════════════════════════════════════════════════ */

/* MONOCHROME — every section uses the active accent. Cohesive, calm. */
[data-section-colors="monochrome"] {
  --section-start:    var(--accent-rgb, 108, 94, 220);
  --section-media:    var(--accent-rgb, 108, 94, 220);
  --section-ceremony: var(--accent-rgb, 108, 94, 220);
  --section-legacy:   var(--accent-rgb, 108, 94, 220);
  --section-after:    var(--accent-rgb, 108, 94, 220);
  --section-legal:    var(--accent-rgb, 108, 94, 220);
  --section-settings: var(--accent-rgb, 108, 94, 220);
}

/* DUOTONE — alternating between accent and a complementary muted purple. */
[data-section-colors="duotone"] {
  --section-start:    var(--accent-rgb, 108, 94, 220);
  --section-media:    139, 128, 176;
  --section-ceremony: var(--accent-rgb, 108, 94, 220);
  --section-legacy:   139, 128, 176;
  --section-after:    var(--accent-rgb, 108, 94, 220);
  --section-legal:    139, 128, 176;
  --section-settings: 110, 116, 130;
}

/* PASTEL — softer, lighter versions of the default palette. */
[data-section-colors="pastel"] {
  --section-start:    180, 215, 188;        /* pale sage */
  --section-media:    197, 188, 240;        /* pale lavender */
  --section-ceremony: 178, 168, 232;        /* paler iris */
  --section-legacy:   210, 184, 200;        /* pale rose */
  --section-after:    158, 220, 196;        /* pale teal */
  --section-legal:    188, 180, 216;        /* pale lavender */
  --section-settings: 175, 180, 195;        /* pale gray */
}

/* EDITORIAL — warm grays and stone, very subtle differentiation. */
[data-section-colors="editorial"] {
  --section-start:    140, 138, 130;        /* warm gray */
  --section-media:    122, 122, 130;        /* cool gray */
  --section-ceremony: 95, 92, 100;          /* charcoal */
  --section-legacy:   148, 130, 138;        /* muted mauve */
  --section-after:    115, 130, 122;        /* muted sage */
  --section-legal:    128, 124, 142;        /* muted lavender */
  --section-settings: 80, 82, 90;           /* very dark */
}

/* FOREST — earth tones, all greens and browns (no gold). */
[data-section-colors="forest"] {
  --section-start:    148, 193, 157;        /* spring green */
  --section-media:    111, 157, 123;        /* sage */
  --section-ceremony: 74, 124, 89;          /* forest */
  --section-legacy:   122, 142, 112;        /* moss */
  --section-after:    94, 134, 110;         /* deep sage */
  --section-legal:    132, 116, 100;        /* bark (warm-brown, NOT gold) */
  --section-settings: 95, 92, 84;           /* stone */
}

/* OCEAN — blue spectrum, all cool tones. */
[data-section-colors="ocean"] {
  --section-start:    132, 178, 200;        /* shallow water */
  --section-media:    88, 134, 168;         /* mid-ocean */
  --section-ceremony: 56, 96, 138;          /* deep blue */
  --section-legacy:   122, 142, 168;        /* dusty blue */
  --section-after:    100, 168, 178;        /* aqua */
  --section-legal:    108, 124, 152;        /* slate-blue */
  --section-settings: 90, 100, 116;         /* gray-slate */
}

/* PURPLE — varying purples and lavenders. */
[data-section-colors="purple"] {
  --section-start:    179, 165, 232;        /* pale lavender */
  --section-media:    155, 138, 232;        /* lavender */
  --section-ceremony: 108, 94, 220;         /* iris */
  --section-legacy:   168, 127, 192;        /* rose-violet */
  --section-after:    132, 124, 180;        /* dusty purple */
  --section-legal:    139, 128, 176;        /* muted lavender */
  --section-settings: 100, 95, 120;         /* deep gray-purple */
}

/* v0.5.86 — 14 additional section presets mirrored from app */
[data-section-colors="emerald"] {
  --section-start: 60, 140, 100;
  --section-media: 80, 140, 140;
  --section-ceremony: 100, 150, 120;
  --section-legacy: 70, 110, 100;
  --section-after: 90, 160, 140;
  --section-legal: 80, 130, 110;
  --section-settings: 60, 90, 80;
}
[data-section-colors="midnight"] {
  --section-start: 50, 60, 90;
  --section-media: 60, 70, 110;
  --section-ceremony: 70, 80, 120;
  --section-legacy: 80, 90, 120;
  --section-after: 40, 50, 80;
  --section-legal: 55, 65, 95;
  --section-settings: 45, 55, 85;
}
[data-section-colors="twilight"] {
  --section-start: 140, 130, 180;
  --section-media: 130, 120, 180;
  --section-ceremony: 150, 140, 200;
  --section-legacy: 160, 150, 210;
  --section-after: 120, 110, 170;
  --section-legal: 140, 130, 190;
  --section-settings: 110, 100, 160;
}
[data-section-colors="mist"] {
  --section-start: 200, 205, 215;
  --section-media: 190, 195, 210;
  --section-ceremony: 180, 185, 200;
  --section-legacy: 210, 215, 220;
  --section-after: 195, 200, 215;
  --section-legal: 185, 190, 205;
  --section-settings: 175, 180, 195;
}
[data-section-colors="arctic"] {
  --section-start: 175, 200, 220;
  --section-media: 155, 185, 210;
  --section-ceremony: 200, 220, 230;
  --section-legacy: 165, 195, 215;
  --section-after: 180, 210, 225;
  --section-legal: 145, 175, 200;
  --section-settings: 135, 165, 190;
}
[data-section-colors="denim"] {
  --section-start: 110, 145, 175;
  --section-media: 90, 130, 165;
  --section-ceremony: 130, 165, 190;
  --section-legacy: 100, 135, 170;
  --section-after: 85, 120, 150;
  --section-legal: 120, 155, 180;
  --section-settings: 70, 100, 130;
}
[data-section-colors="lavender"] {
  --section-start: 175, 165, 210;
  --section-media: 160, 150, 200;
  --section-ceremony: 185, 175, 220;
  --section-legacy: 150, 140, 190;
  --section-after: 195, 185, 225;
  --section-legal: 165, 155, 200;
  --section-settings: 140, 130, 180;
}
[data-section-colors="berry"] {
  --section-start: 150, 110, 140;
  --section-media: 140, 105, 130;
  --section-ceremony: 165, 120, 155;
  --section-legacy: 130, 95, 120;
  --section-after: 175, 135, 165;
  --section-legal: 145, 105, 135;
  --section-settings: 115, 80, 105;
}
[data-section-colors="moss"] {
  --section-start: 110, 140, 95;
  --section-media: 95, 125, 85;
  --section-ceremony: 125, 150, 110;
  --section-legacy: 105, 135, 95;
  --section-after: 90, 120, 80;
  --section-legal: 115, 140, 100;
  --section-settings: 85, 110, 75;
}
[data-section-colors="slate"] {
  --section-start: 100, 115, 135;
  --section-media: 95, 110, 130;
  --section-ceremony: 115, 130, 145;
  --section-legacy: 90, 105, 125;
  --section-after: 105, 120, 140;
  --section-legal: 85, 100, 120;
  --section-settings: 75, 90, 110;
}
[data-section-colors="teal"] {
  --section-start: 90, 145, 145;
  --section-media: 80, 130, 135;
  --section-ceremony: 100, 155, 155;
  --section-legacy: 75, 125, 130;
  --section-after: 95, 150, 145;
  --section-legal: 85, 140, 140;
  --section-settings: 65, 110, 115;
}
[data-section-colors="sage"] {
  --section-start: 150, 175, 145;
  --section-media: 135, 160, 135;
  --section-ceremony: 160, 180, 155;
  --section-legacy: 130, 155, 130;
  --section-after: 155, 175, 145;
  --section-legal: 140, 165, 140;
  --section-settings: 115, 140, 115;
}
[data-section-colors="plum"] {
  --section-start: 130, 95, 115;
  --section-media: 120, 90, 110;
  --section-ceremony: 145, 105, 125;
  --section-legacy: 115, 85, 105;
  --section-after: 140, 100, 120;
  --section-legal: 125, 90, 110;
  --section-settings: 100, 75, 95;
}
[data-section-colors="periwinkle"] {
  --section-start: 155, 165, 215;
  --section-media: 140, 150, 205;
  --section-ceremony: 165, 175, 220;
  --section-legacy: 130, 140, 195;
  --section-after: 170, 180, 225;
  --section-legal: 150, 160, 210;
  --section-settings: 120, 130, 185;
}

/* ═══════════════════════════════════════════════════════════════════════
   v0.5.127 — "fable" polish layer
   Appended overrides so the careful base rules above stay untouched (easy to
   review/revert). Adds delight + intrigue: card lift, a breathing hero glow,
   a recurring candle-tick eyebrow motif, the pitch line as a pull-quote,
   feature-card accents, and a whole-site scroll-reveal. Every colour is
   Rule-31-safe (candle green / iris / lavender); every motion is guarded by
   prefers-reduced-motion, and the scroll-reveal degrades to "just visible"
   with zero JS on any browser without scroll-timeline support.
   ═══════════════════════════════════════════════════════════════════════ */

/* Every glass card gets a little life on hover — a gentle lift. */
.glass-card {
  transition: box-shadow .3s var(--ease), border-color .3s var(--ease), transform .3s var(--ease);
}
.glass-card:hover { transform: translateY(-4px); }

/* Eyebrow kicker — a small candle hairline before it, echoing the R·I·P rules. */
.eyebrow { display: inline-flex; align-items: center; gap: .65rem; }
.eyebrow::before {
  content: ''; width: 20px; height: 1px; flex-shrink: 0;
  background: linear-gradient(90deg, transparent, var(--candle));
}
/* The centred sections (Samples / Preview) need the eyebrow to span full width
   and centre its hairline+text — inline-flex above would otherwise pin it left. */
.samples .eyebrow, .preview .eyebrow { display: flex; justify-content: center; }

/* The pitch's closing line — "no one should have to guess your netflix
   password while planning your funeral" — becomes a centred pull-quote,
   the emotional turn of the page instead of a side note. */
.pitch-aside {
  border-left: none !important;
  padding-left: 0 !important;
  text-align: center;
  max-width: 32ch !important;
  margin: 3.2rem auto 0 !important;
  font-family: var(--font-display) !important;
  font-size: clamp(1.55rem, 3.4vw, 2.2rem) !important;
  line-height: 1.26 !important;
  letter-spacing: -0.01em;
  color: var(--candle-bright) !important;
}
/* v2026-07-14 — in the lone-line .tight band the pitch-aside's 3.2rem top
   margin (meant to separate it from copy above it in .pitch/.email-signup)
   stacked on the section's own 2rem padding and sank the quote to the bottom.
   No preceding content here, so zero it out for a centred, held pause. */
section.tight .pitch-aside { margin-top: 0 !important; }
.pitch-aside::before {
  content: ''; display: block; width: 42px; height: 1px; margin: 0 auto 1.5rem;
  background: linear-gradient(90deg, transparent, var(--candle), transparent);
}

/* "what's in it" — the flattest section gets a top accent hairline that warms
   on hover, and green headers, so four bullet lists read as designed cards. */
.feature { position: relative; overflow: hidden; }
.feature::before {
  content: ''; position: absolute; inset: 0 0 auto 0; height: 2px;
  background: linear-gradient(90deg, var(--candle), var(--iris));
  opacity: .5; transition: opacity .3s var(--ease);
}
.feature:hover::before { opacity: 1; }
.feature h3 { color: var(--candle-bright); }

/* Hero — a slow glow breathing behind the logo lockup. Quiet intrigue. */
.hero-logo-lockup { position: relative; z-index: 0; }
.hero-logo-lockup::after {
  content: ''; position: absolute; z-index: -1; pointer-events: none;
  top: -14%; left: 50%; transform: translateX(-50%);
  width: min(440px, 82vw); aspect-ratio: 1;
  background: radial-gradient(circle, rgba(126,172,136,0.17), rgba(108,94,220,0.09) 42%, transparent 68%);
  filter: blur(10px);
}
@media (prefers-reduced-motion: no-preference) {
  .hero-logo-lockup::after { animation: gg-breathe 9s var(--ease) infinite; }
  @keyframes gg-breathe {
    0%, 100% { opacity: .6;  transform: translateX(-50%) scale(1);    }
    50%      { opacity: 1;   transform: translateX(-50%) scale(1.09); }
  }
}

/* Whole-site scroll-reveal — sections rise gently as they enter. Pure CSS
   scroll-timeline; unsupported browsers ignore the @supports block entirely
   and show everything at full opacity (no flash-of-hidden, no JS).
   NB: .pitch .wrap was deliberately REMOVED from this list — it's the first
   section after the hero, so on tall/zoomed viewports (or during the font
   swap) its top straddled the fold and rendered hidden/nudged-down until you
   scrolled, which read as "content missing on load." First-viewport content
   must paint solid; the rise-in still plays for everything genuinely below.
   (.screenshot was also dropped — a dead token; the preview uses figure.phone,
   which has its own reveal rule below.) */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .how-card, .preview .section-title,
    .feature, .sample-card, .samples .section-title, .samples-lede,
    .ea-card, .email-signup .wrap, .faq-item {
      animation: gg-rise linear both;
      animation-timeline: view();
      animation-range: entry 3% cover 24%;
    }
    @keyframes gg-rise {
      from { opacity: 0; transform: translateY(26px); }
      to   { opacity: 1; transform: none; }
    }
  }
}

/* Epitaph rule — the hero's fading hairline promoted to a section-divider
   motif above the centred section titles, so five identical section-starts
   become a recognisable rhythm. Applied only where the title is centred. */
.samples .section-title::before,
.preview .section-title::before {
  content: ''; display: block; width: 56px; height: 1px; margin: 0 auto 1.3rem;
  background: linear-gradient(90deg, transparent, var(--candle), transparent);
  opacity: .6;
}

/* "what's in it" lede — a serif one-liner so the section doesn't open cold on
   a grid of lists. */
.features-lede {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.15rem, 2vw, 1.45rem);
  color: var(--text-1);
  max-width: 40ch;
  margin: -0.4rem 0 2.4rem;
  line-height: 1.4;
}

/* Founding members — the climax gets a candle top-glow so it feels arrived-at,
   not like another glass box. */
.ea-card { position: relative; }
.ea-card::after {
  content: ''; position: absolute; top: -1px; left: 12%; right: 12%; height: 1px;
  background: linear-gradient(90deg, transparent, var(--candle), transparent);
  opacity: .7;
}

/* Phone showcase — the product is a phone app, so "a quick look" shows it on a
   phone. Screenshots sit in a soft device bezel; the frame is CSS so the shots
   stay raw + crisp. */
.phone-showcase {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1rem, 2vw, 1.8rem);
  align-items: start;
  max-width: 940px;
  margin: 2.6rem auto 0;
}
.phone { display: flex; flex-direction: column; align-items: center; width: 100%; min-width: 0; }
@media (max-width: 840px) { .phone-showcase { grid-template-columns: repeat(2, 1fr); max-width: 470px; } }
@media (max-width: 480px) { .phone-showcase { grid-template-columns: 1fr; max-width: 280px; } }
.phone-frame {
  width: 100%;
  background: #0a0d14;
  border: 1px solid rgba(255, 255, 255, 0.13);
  border-radius: 30px;
  padding: 7px;
  box-shadow:
    0 24px 60px rgba(0, 0, 0, 0.6),
    0 0 46px rgba(108, 94, 220, 0.09),
    inset 0 1px 0 rgba(255, 255, 255, 0.07);
  transition: transform .35s var(--ease), box-shadow .35s var(--ease);
}
/* height:auto is NOT optional here. The <img> carries width/height HTML
   attributes (780×1688) for layout-shift prevention; those attributes act as
   a low-priority presentational hint that still WINS when no author height
   is declared (an unset property beats nothing — width:100% alone leaves
   height literally pinned at the attribute's raw 1688px, un-scaled, while
   width shrinks to the grid column — object-fit defaults to `fill`, so the
   image content gets stretched into that mismatched box. This is what "the
   screenshots look warped" turned out to be — a real bug, not a cache/
   extension/screenshot artifact. Explicit height:auto restores the
   aspect-ratio-driven sizing the width/height attributes are supposed to
   provide before load. object-fit:contain is a second line of defence. */
.phone-frame img { display: block; width: 100%; height: auto; object-fit: contain; border-radius: 24px; }
.phone:hover .phone-frame {
  transform: translateY(-6px);
  box-shadow:
    0 30px 72px rgba(0, 0, 0, 0.7),
    0 0 64px rgba(108, 94, 220, 0.15),
    inset 0 1px 0 rgba(255, 255, 255, 0.09);
}
.phone figcaption { margin-top: 1.05rem; text-align: center; max-width: 26ch; }
.phone figcaption strong { display: block; color: var(--candle-bright); font-weight: 500; font-size: 0.95rem; margin-bottom: 0.28rem; }
.phone figcaption span { color: var(--text-3); font-size: 0.82rem; line-height: 1.5; }

/* v2026-07-15 — a single centred phone (not the 4-up showcase), for the real
   app captures added to "what's in it" and the samples section. */
.phone-solo { max-width: 300px; margin: 2.6rem auto 0; }
.phone-solo figcaption { max-width: 34ch; }

/* v2026-07-15 — "same plan, ten keepsakes": phone + copy side by side. */
.samples-callout {
  display: flex;
  align-items: center;
  gap: clamp(1.5rem, 4vw, 3rem);
  max-width: 820px;
  margin: 3rem auto 0;
}
.samples-callout .phone-solo { margin: 0; flex: 0 0 clamp(190px, 32%, 270px); }
.samples-callout-copy { flex: 1 1 auto; }
.samples-callout-copy p { color: var(--text-2); margin: 0; }
.samples-callout-copy .eyebrow { margin-bottom: 0.8rem; }
@media (max-width: 640px) {
  .samples-callout { flex-direction: column; text-align: center; gap: 1.6rem; }
  .samples-callout .phone-solo { flex-basis: auto; max-width: 250px; }
  .samples-callout-copy .eyebrow { justify-content: center; }
}
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .phone { animation: gg-rise linear both; animation-timeline: view(); animation-range: entry 3% cover 26%; }
  }
}

/* Sample PDF previews — the actual exported pages as thumbnails, so people can
   SEE the output (not just a doc icon) before opening the full PDF. */
.sample-preview {
  height: 210px;
  overflow: hidden;
  border-radius: 12px;
  margin-bottom: 1.1rem;
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: #0a0d14;
  transition: border-color .3s var(--ease);
}
.sample-preview img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top center; }
/* Landscape wallet card: show the whole thing, centred, not a top-crop. */
.sample-preview.is-card { display: flex; align-items: center; justify-content: center; padding: 16px; }
.sample-preview.is-card img { height: auto; object-fit: contain; border-radius: 6px; }
.sample-card:hover .sample-preview { border-color: rgba(126, 172, 136, 0.4); }

/* Four sample cards in one row (was auto-fit → a lone wallet card wrapped
   below). Mirrors the 4-phone "a quick look" rhythm directly above it. */
.samples-grid { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 840px) { .samples-grid { grid-template-columns: repeat(2, 1fr); max-width: 560px; } }
@media (max-width: 480px) { .samples-grid { grid-template-columns: 1fr; max-width: 320px; } }

/* Download page — the app shown on a phone beside the two store cards.
   Reuses .phone-frame (from the "a quick look" showcase). Phone left, the
   App Store / Google Play cards stacked to its right; stacks on narrow. */
.store-layout {
  display: grid;
  grid-template-columns: minmax(0, 300px) 1fr;
  gap: clamp(1.6rem, 4vw, 3.2rem);
  align-items: center;
}
.store-phone { width: 100%; max-width: 300px; margin: 0 auto; }
.store-cards { display: flex; flex-direction: column; gap: 1.1rem; }
.store-cards .dl-card { margin: 0; }
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .store-phone { animation: gg-rise linear both; animation-timeline: view(); animation-range: entry 3% cover 24%; }
  }
}
@media (max-width: 720px) {
  .store-layout { grid-template-columns: 1fr; gap: 2rem; }
  .store-phone { max-width: 240px; }
}


/* ════════════════════════════════════════════════════════════════════════
   v0.5.88 — Dark moody cloud backgrounds. 5 new animated options.
   All sit on body::before so they layer above the theme bg but below
   content. Each has a corresponding @keyframes animation.
   ──────────────────────────────────────────────────────────────────────── */


@keyframes storm-drift {
  0%   { transform: scale(1) translate(0, 0); }
  50%  { transform: scale(1.08) translate(-2%, 1%); }
  100% { transform: scale(1.12) translate(-3%, 3%); }
}


@keyframes fog-drift {
  0%   { background-position: 0% 0%, 50% 0%, 100% 0%, 0% 0%; }
  100% { background-position: -250% 0%, -170% 0%, -180% 0%, 0% 0%; }
}


@keyframes nimbus-drift {
  0%   { background-position: 0% 0%; }
  100% { background-position: 100% 50%; }
}


@keyframes overcast-breath {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.82; }
}


@keyframes smoke-trail {
  0%   { background-position: 0% 0%, 50% 0%, 100% 0%, 25% 0%, 0% 0%; }
  100% { background-position: 250% 0%, 270% 0%, 200% 0%, 255% 0%, 0% 0%; }
}


/* ════════════════════════════════════════════════════════════════════════
   v0.5.88 — Button shape rules. Targets .glass-tile .icon-wrap which is
   the coloured icon badge on each tile. Uses clip-path or border-radius
   to reshape it. Specificity is 0,3,0 (matches the per-group rules);
   cascade order ensures these apply where set.
   ──────────────────────────────────────────────────────────────────────── */

/* All shape rules clear conflicting properties first to avoid mixing. */
html[data-button-shape] .glass-tile .icon-wrap {
  /* default state — let shape rule below override */
}

/* Border-radius variants */
html[data-button-shape="sharp"] .glass-tile .icon-wrap {
  border-radius: 2px;
  clip-path: none;
}
html[data-button-shape="squircle"] .glass-tile .icon-wrap {
  border-radius: 35%;
  clip-path: none;
}
html[data-button-shape="circle"] .glass-tile .icon-wrap {
  border-radius: 50%;
  clip-path: none;
}
html[data-button-shape="capsule"] .glass-tile .icon-wrap {
  border-radius: 50px;
  clip-path: none;
}
html[data-button-shape="leaf"] .glass-tile .icon-wrap {
  border-radius: 0 50% 0 50%;
  clip-path: none;
}
html[data-button-shape="leaf-alt"] .glass-tile .icon-wrap {
  border-radius: 50% 0 50% 0;
  clip-path: none;
}
html[data-button-shape="half-moon"] .glass-tile .icon-wrap {
  border-radius: 0 50% 50% 0;
  clip-path: none;
}

/* Clip-path variants. Border-radius is set to 0 since clip-path defines
   the final outline; rounded corners under a clip-path produce no visible
   change but waste paint work. */
html[data-button-shape="diamond"] .glass-tile .icon-wrap {
  clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
  border-radius: 0;
}
html[data-button-shape="hexagon"] .glass-tile .icon-wrap {
  clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
  border-radius: 0;
}
html[data-button-shape="hex-pointy"] .glass-tile .icon-wrap {
  clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
  border-radius: 0;
}
html[data-button-shape="octagon"] .glass-tile .icon-wrap {
  clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
  border-radius: 0;
}
html[data-button-shape="pentagon"] .glass-tile .icon-wrap {
  clip-path: polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%);
  border-radius: 0;
}
html[data-button-shape="triangle"] .glass-tile .icon-wrap {
  clip-path: polygon(50% 0%, 100% 100%, 0% 100%);
  border-radius: 0;
}
html[data-button-shape="star5"] .glass-tile .icon-wrap {
  clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
  border-radius: 0;
}
html[data-button-shape="star6"] .glass-tile .icon-wrap {
  clip-path: polygon(50% 0%, 65% 35%, 100% 35%, 75% 60%, 85% 100%, 50% 75%, 15% 100%, 25% 60%, 0% 35%, 35% 35%);
  border-radius: 0;
}
html[data-button-shape="star8"] .glass-tile .icon-wrap {
  clip-path: polygon(50% 0%, 60% 20%, 80% 10%, 75% 32%, 100% 35%, 80% 50%, 100% 65%, 75% 68%, 80% 90%, 60% 80%, 50% 100%, 40% 80%, 20% 90%, 25% 68%, 0% 65%, 20% 50%, 0% 35%, 25% 32%, 20% 10%, 40% 20%);
  border-radius: 0;
}
html[data-button-shape="plus"] .glass-tile .icon-wrap {
  clip-path: polygon(33% 0%, 67% 0%, 67% 33%, 100% 33%, 100% 67%, 67% 67%, 67% 100%, 33% 100%, 33% 67%, 0% 67%, 0% 33%, 33% 33%);
  border-radius: 0;
}
html[data-button-shape="arrow"] .glass-tile .icon-wrap {
  clip-path: polygon(0% 25%, 60% 25%, 60% 0%, 100% 50%, 60% 100%, 60% 75%, 0% 75%);
  border-radius: 0;
}
html[data-button-shape="chevron"] .glass-tile .icon-wrap {
  clip-path: polygon(75% 0%, 100% 50%, 75% 100%, 0% 100%, 25% 50%, 0% 0%);
  border-radius: 0;
}
html[data-button-shape="shield"] .glass-tile .icon-wrap {
  clip-path: polygon(50% 0%, 100% 15%, 100% 60%, 50% 100%, 0% 60%, 0% 15%);
  border-radius: 0;
}
html[data-button-shape="cut-tr"] .glass-tile .icon-wrap {
  clip-path: polygon(0% 0%, 75% 0%, 100% 25%, 100% 100%, 0% 100%);
  border-radius: 0;
}
html[data-button-shape="tag"] .glass-tile .icon-wrap {
  clip-path: polygon(0% 0%, 80% 0%, 100% 50%, 80% 100%, 0% 100%);
  border-radius: 0;
}
html[data-button-shape="trapezoid"] .glass-tile .icon-wrap {
  clip-path: polygon(20% 0%, 80% 0%, 100% 100%, 0% 100%);
  border-radius: 0;
}


/* ════════ v0.5.89 — 33 new section presets (total 55) ════════ */
[data-section-colors="jade"] {
  --section-start:    140, 184, 158;
  --section-media:    125, 168, 150;
  --section-ceremony: 110, 156, 135;
  --section-legacy:   130, 176, 154;
  --section-after:    117, 164, 143;
  --section-legal:    144, 188, 160;
  --section-settings: 95, 135, 117;
}
[data-section-colors="sapphire"] {
  --section-start:    88, 120, 168;
  --section-media:    77, 110, 156;
  --section-ceremony: 110, 140, 186;
  --section-legacy:   63, 96, 140;
  --section-after:    120, 150, 192;
  --section-legal:    74, 108, 152;
  --section-settings: 54, 82, 124;
}
[data-section-colors="rosewood"] {
  --section-start:    160, 112, 144;
  --section-media:    148, 104, 132;
  --section-ceremony: 168, 120, 152;
  --section-legacy:   136, 96, 120;
  --section-after:    184, 138, 160;
  --section-legal:    156, 112, 140;
  --section-settings: 120, 84, 104;
}
[data-section-colors="amethyst"] {
  --section-start:    138, 120, 196;
  --section-media:    125, 108, 184;
  --section-ceremony: 150, 132, 206;
  --section-legacy:   112, 95, 168;
  --section-after:    162, 144, 216;
  --section-legal:    132, 120, 190;
  --section-settings: 90, 76, 140;
}
[data-section-colors="ivy"] {
  --section-start:    94, 136, 112;
  --section-media:    84, 126, 102;
  --section-ceremony: 104, 140, 120;
  --section-legacy:   71, 110, 88;
  --section-after:    116, 146, 110;
  --section-legal:    92, 128, 104;
  --section-settings: 60, 94, 74;
}
[data-section-colors="frost"] {
  --section-start:    168, 192, 208;
  --section-media:    156, 180, 200;
  --section-ceremony: 184, 200, 216;
  --section-legacy:   144, 168, 192;
  --section-after:    192, 208, 220;
  --section-legal:    160, 184, 204;
  --section-settings: 132, 156, 180;
}
[data-section-colors="verdigris"] {
  --section-start:    122, 176, 160;
  --section-media:    110, 164, 149;
  --section-ceremony: 134, 188, 170;
  --section-legacy:   94, 148, 134;
  --section-after:    146, 200, 182;
  --section-legal:    116, 168, 154;
  --section-settings: 84, 136, 122;
}
[data-section-colors="grape"] {
  --section-start:    118, 90, 152;
  --section-media:    108, 84, 140;
  --section-ceremony: 130, 100, 158;
  --section-legacy:   94, 72, 128;
  --section-after:    140, 108, 168;
  --section-legal:    116, 88, 143;
  --section-settings: 82, 60, 110;
}
[data-section-colors="cornflower"] {
  --section-start:    128, 148, 200;
  --section-media:    116, 136, 188;
  --section-ceremony: 140, 160, 210;
  --section-legacy:   100, 120, 172;
  --section-after:    148, 168, 214;
  --section-legal:    124, 144, 192;
  --section-settings: 94, 114, 154;
}
[data-section-colors="rust-mauve"] {
  --section-start:    154, 122, 144;
  --section-media:    142, 112, 132;
  --section-ceremony: 166, 132, 160;
  --section-legacy:   130, 104, 122;
  --section-after:    176, 142, 164;
  --section-legal:    148, 116, 136;
  --section-settings: 112, 90, 108;
}
[data-section-colors="seafoam"] {
  --section-start:    148, 196, 184;
  --section-media:    136, 184, 173;
  --section-ceremony: 160, 208, 196;
  --section-legacy:   124, 172, 170;
  --section-after:    170, 220, 208;
  --section-legal:    144, 188, 176;
  --section-settings: 110, 150, 148;
}
[data-section-colors="aubergine"] {
  --section-start:    112, 88, 112;
  --section-media:    104, 80, 104;
  --section-ceremony: 124, 100, 128;
  --section-legacy:   94, 72, 96;
  --section-after:    134, 109, 138;
  --section-legal:    112, 88, 116;
  --section-settings: 78, 56, 84;
}
[data-section-colors="willow"] {
  --section-start:    140, 173, 142;
  --section-media:    128, 164, 130;
  --section-ceremony: 152, 181, 152;
  --section-legacy:   116, 152, 122;
  --section-after:    164, 189, 164;
  --section-legal:    138, 166, 140;
  --section-settings: 104, 132, 112;
}
[data-section-colors="cerulean"] {
  --section-start:    94, 158, 196;
  --section-media:    82, 148, 188;
  --section-ceremony: 116, 172, 208;
  --section-legacy:   60, 132, 172;
  --section-after:    132, 184, 216;
  --section-legal:    88, 150, 188;
  --section-settings: 58, 112, 142;
}
[data-section-colors="thistle"] {
  --section-start:    168, 144, 176;
  --section-media:    156, 132, 164;
  --section-ceremony: 181, 156, 188;
  --section-legacy:   144, 120, 156;
  --section-after:    188, 168, 196;
  --section-legal:    164, 140, 170;
  --section-settings: 124, 100, 136;
}
[data-section-colors="pine-mist"] {
  --section-start:    110, 144, 128;
  --section-media:    100, 136, 112;
  --section-ceremony: 122, 156, 138;
  --section-legacy:   88, 120, 100;
  --section-after:    134, 168, 144;
  --section-legal:    108, 140, 120;
  --section-settings: 76, 108, 84;
}
[data-section-colors="lilac"] {
  --section-start:    188, 168, 212;
  --section-media:    176, 156, 200;
  --section-ceremony: 196, 180, 220;
  --section-legacy:   164, 140, 192;
  --section-after:    204, 188, 228;
  --section-legal:    180, 168, 208;
  --section-settings: 144, 120, 176;
}
[data-section-colors="jewel"] {
  --section-start:    76, 140, 112;
  --section-media:    88, 120, 168;
  --section-ceremony: 138, 120, 196;
  --section-legacy:   154, 112, 144;
  --section-after:    94, 158, 180;
  --section-legal:    125, 108, 184;
  --section-settings: 84, 136, 122;
}
[data-section-colors="vellum"] {
  --section-start:    168, 156, 148;
  --section-media:    156, 144, 136;
  --section-ceremony: 180, 168, 156;
  --section-legacy:   144, 132, 120;
  --section-after:    188, 176, 164;
  --section-legal:    164, 152, 140;
  --section-settings: 128, 116, 104;
}
[data-section-colors="ink-blue"] {
  --section-start:    76, 94, 132;
  --section-media:    68, 86, 120;
  --section-ceremony: 92, 112, 142;
  --section-legacy:   56, 74, 108;
  --section-after:    100, 120, 160;
  --section-legal:    80, 102, 136;
  --section-settings: 44, 64, 92;
}
[data-section-colors="mossy"] {
  --section-start:    120, 140, 94;
  --section-media:    108, 128, 84;
  --section-ceremony: 132, 150, 104;
  --section-legacy:   92, 110, 72;
  --section-after:    140, 160, 112;
  --section-legal:    116, 140, 92;
  --section-settings: 78, 94, 60;
}
[data-section-colors="hydrangea"] {
  --section-start:    116, 132, 188;
  --section-media:    104, 120, 176;
  --section-ceremony: 128, 148, 200;
  --section-legacy:   88, 104, 160;
  --section-after:    144, 164, 212;
  --section-legal:    112, 136, 184;
  --section-settings: 76, 92, 140;
}
[data-section-colors="aqua"] {
  --section-start:    124, 180, 180;
  --section-media:    112, 168, 170;
  --section-ceremony: 136, 192, 192;
  --section-legacy:   96, 148, 160;
  --section-after:    148, 204, 204;
  --section-legal:    128, 180, 184;
  --section-settings: 90, 134, 136;
}
[data-section-colors="cocoa"] {
  --section-start:    142, 120, 104;
  --section-media:    130, 112, 94;
  --section-ceremony: 156, 132, 116;
  --section-legacy:   112, 92, 76;
  --section-after:    168, 144, 128;
  --section-legal:    138, 116, 104;
  --section-settings: 94, 76, 64;
}
[data-section-colors="cyan-fade"] {
  --section-start:    124, 196, 196;
  --section-media:    108, 184, 184;
  --section-ceremony: 136, 208, 208;
  --section-legacy:   84, 164, 168;
  --section-after:    160, 220, 220;
  --section-legal:    128, 192, 196;
  --section-settings: 80, 144, 148;
}
[data-section-colors="orchid"] {
  --section-start:    168, 132, 168;
  --section-media:    156, 124, 156;
  --section-ceremony: 184, 148, 184;
  --section-legacy:   138, 112, 140;
  --section-after:    196, 164, 196;
  --section-legal:    168, 136, 168;
  --section-settings: 128, 96, 140;
}
[data-section-colors="terra"] {
  --section-start:    156, 132, 120;
  --section-media:    144, 120, 108;
  --section-ceremony: 168, 144, 132;
  --section-legacy:   128, 104, 88;
  --section-after:    180, 156, 144;
  --section-legal:    152, 132, 120;
  --section-settings: 108, 90, 76;
}
[data-section-colors="pacific"] {
  --section-start:    76, 132, 136;
  --section-media:    68, 124, 128;
  --section-ceremony: 88, 144, 140;
  --section-legacy:   56, 108, 112;
  --section-after:    102, 156, 152;
  --section-legal:    78, 136, 132;
  --section-settings: 44, 88, 96;
}
[data-section-colors="blossom"] {
  --section-start:    184, 156, 172;
  --section-media:    172, 144, 160;
  --section-ceremony: 196, 168, 184;
  --section-legacy:   156, 128, 140;
  --section-after:    208, 180, 196;
  --section-legal:    176, 156, 172;
  --section-settings: 136, 108, 124;
}
[data-section-colors="graphite"] {
  --section-start:    100, 104, 116;
  --section-media:    92, 96, 104;
  --section-ceremony: 120, 124, 132;
  --section-legacy:   76, 80, 88;
  --section-after:    140, 144, 152;
  --section-legal:    104, 108, 116;
  --section-settings: 58, 62, 68;
}
[data-section-colors="peacock"] {
  --section-start:    72, 148, 164;
  --section-media:    60, 136, 154;
  --section-ceremony: 84, 156, 173;
  --section-legacy:   44, 116, 132;
  --section-after:    96, 156, 168;
  --section-legal:    72, 148, 160;
  --section-settings: 30, 88, 104;
}
[data-section-colors="powder"] {
  --section-start:    156, 184, 208;
  --section-media:    144, 172, 204;
  --section-ceremony: 168, 196, 216;
  --section-legacy:   128, 160, 196;
  --section-after:    180, 208, 224;
  --section-legal:    148, 176, 200;
  --section-settings: 112, 144, 176;
}
[data-section-colors="wisteria"] {
  --section-start:    152, 136, 188;
  --section-media:    140, 124, 176;
  --section-ceremony: 164, 148, 200;
  --section-legacy:   124, 108, 160;
  --section-after:    172, 160, 208;
  --section-legal:    148, 132, 180;
  --section-settings: 104, 76, 132;
}


/* ════════ v0.5.89 — 31 new button shapes (total 55) ════════ */
html[data-button-shape="rounded-soft"] .glass-tile .icon-wrap {
  border-radius: 16px;
  clip-path: none;
}
html[data-button-shape="rounded-medium"] .glass-tile .icon-wrap {
  border-radius: 12px;
  clip-path: none;
}
html[data-button-shape="rounded-deep"] .glass-tile .icon-wrap {
  border-radius: 40%;
  clip-path: none;
}
html[data-button-shape="ellipse"] .glass-tile .icon-wrap {
  border-radius: 50% / 35%;
  clip-path: none;
}
html[data-button-shape="cut-tl"] .glass-tile .icon-wrap {
  clip-path: polygon(25% 0%, 100% 0%, 100% 100%, 0% 100%, 0% 25%);
  border-radius: 0;
}
html[data-button-shape="cut-bl"] .glass-tile .icon-wrap {
  clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 25% 100%, 0% 75%);
  border-radius: 0;
}
html[data-button-shape="cut-br"] .glass-tile .icon-wrap {
  clip-path: polygon(0% 0%, 100% 0%, 100% 75%, 75% 100%, 0% 100%);
  border-radius: 0;
}
html[data-button-shape="cut-double"] .glass-tile .icon-wrap {
  clip-path: polygon(20% 0%, 100% 0%, 100% 80%, 80% 100%, 0% 100%, 0% 20%);
  border-radius: 0;
}
html[data-button-shape="square-pointy"] .glass-tile .icon-wrap {
  clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
  border-radius: 0;
}
html[data-button-shape="triangle-down"] .glass-tile .icon-wrap {
  clip-path: polygon(0% 0%, 100% 0%, 50% 100%);
  border-radius: 0;
}
html[data-button-shape="triangle-right"] .glass-tile .icon-wrap {
  clip-path: polygon(0% 0%, 100% 50%, 0% 100%);
  border-radius: 0;
}
html[data-button-shape="triangle-left"] .glass-tile .icon-wrap {
  clip-path: polygon(100% 0%, 0% 50%, 100% 100%);
  border-radius: 0;
}
html[data-button-shape="heptagon"] .glass-tile .icon-wrap {
  clip-path: polygon(50% 0%, 90% 20%, 100% 60%, 75% 100%, 25% 100%, 0% 60%, 10% 20%);
  border-radius: 0;
}
html[data-button-shape="nonagon"] .glass-tile .icon-wrap {
  clip-path: polygon(50% 0%, 85% 12%, 100% 42%, 93% 78%, 65% 100%, 35% 100%, 7% 78%, 0% 42%, 15% 12%);
  border-radius: 0;
}
html[data-button-shape="decagon"] .glass-tile .icon-wrap {
  clip-path: polygon(50% 0%, 80% 10%, 100% 35%, 100% 65%, 80% 90%, 50% 100%, 20% 90%, 0% 65%, 0% 35%, 20% 10%);
  border-radius: 0;
}
html[data-button-shape="dodecagon"] .glass-tile .icon-wrap {
  clip-path: polygon(25% 0%, 75% 0%, 100% 25%, 100% 75%, 75% 100%, 25% 100%, 0% 75%, 0% 25%, 12% 7%, 88% 7%, 100% 50%, 50% 50%);
  border-radius: 0;
}
html[data-button-shape="star-3"] .glass-tile .icon-wrap {
  clip-path: polygon(50% 0%, 80% 70%, 100% 70%, 65% 90%, 50% 100%, 35% 90%, 0% 70%, 20% 70%);
  border-radius: 0;
}
html[data-button-shape="star-4"] .glass-tile .icon-wrap {
  clip-path: polygon(50% 0%, 60% 40%, 100% 50%, 60% 60%, 50% 100%, 40% 60%, 0% 50%, 40% 40%);
  border-radius: 0;
}
html[data-button-shape="star-7"] .glass-tile .icon-wrap {
  clip-path: polygon(50% 0%, 58% 28%, 90% 22%, 73% 50%, 95% 75%, 65% 70%, 50% 100%, 35% 70%, 5% 75%, 27% 50%, 10% 22%, 42% 28%);
  border-radius: 0;
}
html[data-button-shape="star-12"] .glass-tile .icon-wrap {
  clip-path: polygon(50% 0%, 55% 18%, 70% 5%, 70% 23%, 90% 18%, 80% 35%, 100% 40%, 82% 50%, 100% 65%, 78% 67%, 85% 88%, 65% 78%, 60% 95%, 50% 85%, 40% 95%, 35% 78%, 15% 88%, 22% 67%, 0% 65%, 18% 50%, 0% 40%, 20% 35%, 10% 18%, 30% 23%, 30% 5%, 45% 18%);
  border-radius: 0;
}
html[data-button-shape="parallelogram"] .glass-tile .icon-wrap {
  clip-path: polygon(20% 0%, 100% 0%, 80% 100%, 0% 100%);
  border-radius: 0;
}
html[data-button-shape="parallelogram-r"] .glass-tile .icon-wrap {
  clip-path: polygon(0% 0%, 80% 0%, 100% 100%, 20% 100%);
  border-radius: 0;
}
html[data-button-shape="trapezoid-flip"] .glass-tile .icon-wrap {
  clip-path: polygon(0% 0%, 100% 0%, 80% 100%, 20% 100%);
  border-radius: 0;
}
html[data-button-shape="arrow-left"] .glass-tile .icon-wrap {
  clip-path: polygon(40% 0%, 100% 25%, 100% 75%, 40% 100%, 40% 80%, 0% 50%, 40% 20%);
  border-radius: 0;
}
html[data-button-shape="arrow-up"] .glass-tile .icon-wrap {
  clip-path: polygon(50% 0%, 100% 40%, 80% 40%, 80% 100%, 20% 100%, 20% 40%, 0% 40%);
  border-radius: 0;
}
html[data-button-shape="arrow-down"] .glass-tile .icon-wrap {
  clip-path: polygon(20% 0%, 80% 0%, 80% 60%, 100% 60%, 50% 100%, 0% 60%, 20% 60%);
  border-radius: 0;
}
html[data-button-shape="bookmark"] .glass-tile .icon-wrap {
  clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 50% 75%, 0% 100%);
  border-radius: 0;
}
html[data-button-shape="lozenge"] .glass-tile .icon-wrap {
  clip-path: polygon(20% 0%, 80% 0%, 100% 50%, 80% 100%, 20% 100%, 0% 50%);
  border-radius: 0;
}
html[data-button-shape="hex-stretch"] .glass-tile .icon-wrap {
  clip-path: polygon(15% 0%, 85% 0%, 100% 50%, 85% 100%, 15% 100%, 0% 50%);
  border-radius: 0;
}
html[data-button-shape="crystal"] .glass-tile .icon-wrap {
  clip-path: polygon(50% 0%, 100% 30%, 80% 100%, 20% 100%, 0% 30%);
  border-radius: 0;
}
html[data-button-shape="badge"] .glass-tile .icon-wrap {
  clip-path: polygon(50% 0%, 65% 25%, 100% 25%, 80% 50%, 100% 75%, 65% 75%, 50% 100%, 35% 75%, 0% 75%, 20% 50%, 0% 25%, 35% 25%);
  border-radius: 0;
}

/* v0.5.89 — Shared keyframes for new backgrounds */
@keyframes mesh-drift {
  0% { transform: scale(1) translate(0, 0); }
  100% { transform: scale(1.08) translate(2%, -1%); }
}
@keyframes aurora-shift {
  0% { transform: translate(0, 0) scale(1); opacity: 1; }
  100% { transform: translate(-3%, 2%) scale(1.05); opacity: 0.85; }
}
@keyframes pulse-breath {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.78; }
}
@keyframes beacon-sweep {
  0% { background-position: 0% 50%; }
  100% { background-position: 100% 50%; }
}
@keyframes starfield-twinkle {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}
@keyframes snowfall-drift {
  0% { background-position: 0% 0%; }
  100% { background-position: 0% 100%; }
}

/* Accessibility: visually-hidden but available to screen readers. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* Brand lockup: the real GG mark replaces the old placeholder dot.
   Sized in em so it scales with each .brand font-size (header + footer). */
.brand-logo {
  width: 1.9em; height: 1.9em;
  object-fit: contain;
  flex-shrink: 0;
  display: inline-block;
  vertical-align: middle;
}

/* ── Pre-launch notice strip (site-wide) ───────────────────────────────────
   Slim, tasteful banner at the top of <main> (pricing/download) flagging the
   founding-member offer. Replaces earlier one-off inline styles so the look
   stays consistent and theme-aware. */
.site-notice {
  background: var(--accent-soft);
  border-bottom: 1px solid var(--border);
  padding: 0.8rem 1.5rem;
  text-align: center;
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--text-2);
}
.site-notice strong { color: var(--candle-bright); font-weight: 600; }
.site-notice a {
  color: var(--candle-bright);
  text-decoration: underline;
  text-underline-offset: 3px;
  white-space: nowrap;
}
.site-notice a:hover { color: var(--text-1); }

/* Approximate local-currency hint under a price, filled by pricing-i18n.js.
   Empty (and collapsed) for AUD visitors or regions we can't price. */
.price-approx {
  margin: 0.3rem 0 0;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
}
.price-approx:empty { margin: 0; }

/* ════════════════════════════════════════════════════════════════════════
   web-2026-07-07 — THE CAMPAIGN LAYER. The site is the product for a while:
   landing, advertising, hype. Everything below is additive, theme-aware
   (uses the theme vars), Rule-31-safe, and reduced-motion-guarded.
   ──────────────────────────────────────────────────────────────────────── */

/* ── W2: hero proof line + a hero that fits one phone screen ─────────────── */
.hero-proof {
  margin: 1.2rem 0 0;   /* v2026-07-14 — was auto: every other hero copy block is left-aligned, so auto centred this one oddly ~250px in */
  color: var(--text-2);
  max-width: 46ch;
}
@media (max-width: 640px) {
  .hero-logo-mark { width: 92px; }
  .hero-logo-lockup { margin-bottom: 1.2rem; }
  .hero-title { font-size: clamp(2.1rem, 9vw, 2.8rem); }
}

/* ── W7a: the breath before the paperwork ────────────────────────────────── */
.interlude {
  min-height: 62vh;
  display: flex;
  align-items: center;
  text-align: center;
}
.interlude .wrap { width: 100%; }
.interlude-line {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.6rem, 3.4vw, 2.4rem);
  color: var(--text-1);
  max-width: 26ch;
  margin: 0 auto;
  line-height: 1.3;
}
.interlude-sub {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.1rem, 2vw, 1.45rem);
  color: var(--candle-bright);
  margin: 1.4rem auto 0;
}
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .interlude-line, .interlude-sub { animation: gg-rise linear both; animation-timeline: view(); }
    .interlude-line { animation-range: entry 15% cover 40%; }
    .interlude-sub  { animation-range: entry 30% cover 55%; }
  }
}

/* ── W8: the honest heartbeat — where it's up to ─────────────────────────── */
.status-strip { padding: 0.5rem 0 2.8rem; }   /* v2026-07-14 — was 1.5rem horizontal AND the inner .wrap adds 1.5rem = double gutter (same bug the .samples grid had); let the .wrap supply the single gutter */
.status-strip .wrap { max-width: 720px; margin: 0 auto; text-align: center; }
.status-stages {
  list-style: none;
  margin: 0 auto;
  padding: 0;
  display: flex;
  justify-content: center;
  gap: clamp(1.1rem, 4vw, 2.6rem);
  flex-wrap: wrap;
}
.status-stages li {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 0.82rem;
  letter-spacing: 0.06em;
  color: var(--text-3);
}
/* the same mark as the PDF timeline: filled = done, hollow = still to come */
.status-node {
  width: 9px; height: 9px; border-radius: 50%;
  border: 1.5px solid var(--iris);
  background: transparent;
  flex-shrink: 0;
}
.status-stages li.is-done { color: var(--text-2); }
.status-stages li.is-done .status-node { background: var(--iris); }
.status-stages li.is-now { color: var(--candle-bright); }
.status-stages li.is-now .status-node {
  position: relative;
  background: var(--candle);
  border-color: var(--candle);
  box-shadow: 0 0 10px var(--candle-glow);
}
/* A glow on a pseudo-element, animated via opacity/transform (compositor-only
   — the previous box-shadow animation repainted every frame instead). */
.status-stages li.is-now .status-node::after {
  content: ''; position: absolute; inset: -4px; border-radius: 50%;
  background: var(--candle-glow); opacity: 0.5;
}
@media (prefers-reduced-motion: no-preference) {
  .status-stages li.is-now .status-node::after { animation: gg-status-breathe 3.2s ease-in-out infinite; }
}
@keyframes gg-status-breathe {
  0%, 100% { opacity: 0.35; transform: scale(0.85); }
  50%      { opacity: 0.75; transform: scale(1.25); }
}
.status-line {
  margin: 1rem auto 0;
  font-size: 0.85rem;
  color: var(--text-3);
}

/* ── W3: the old-fashioned-way signup fallback ───────────────────────────── */
.ea-fallback { margin-top: 1.2rem; padding: 1.2rem 1.4rem; text-align: left; }
.ea-fallback-lead { margin: 0 0 0.8rem; color: var(--text-2); }
.ea-fallback-row { display: flex; gap: 0.7rem; align-items: center; flex-wrap: wrap; }
.ea-address {
  font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace;
  font-size: 0.95rem;
  color: var(--candle-bright);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border, rgba(255,255,255,0.12));
  border-radius: 10px;
  padding: 0.5rem 0.9rem;
  user-select: all;
}
.ea-fallback-mail { margin: 0.8rem 0 0; }
.ea-fallback-mail a { color: var(--text-2); text-decoration: underline; text-underline-offset: 3px; }

/* ── W9a: the wicks light as you read ────────────────────────────────────── */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .eyebrow::before, .pitch-aside::before {
      animation: gg-wick-light linear both;
      animation-timeline: view();
      animation-range: entry 20% cover 45%;
    }
  }
}
@keyframes gg-wick-light {
  from { filter: brightness(0.45); opacity: 0.5; }
  to   { filter: brightness(1.25); opacity: 1; }
}

/* ── W9b: the slow match — buttons answer intent with a traced ring ─────── */
@property --gg-angle {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}
.btn-primary { position: relative; }
.btn-primary::after {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: inherit;
  padding: 1.5px;
  background: conic-gradient(from 0deg, var(--candle-bright) var(--gg-angle), transparent 0deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s var(--ease);
}
@media (prefers-reduced-motion: no-preference) {
  .btn-primary:hover::after, .btn-primary:focus-visible::after {
    opacity: 0.85;
    animation: gg-slow-match 0.9s var(--ease) forwards;
  }
}
@keyframes gg-slow-match {
  from { --gg-angle: 0deg; }
  to   { --gg-angle: 360deg; }
}

/* ── W9c: reading by candlelight — the pitch section warms under the cursor */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .pitch { position: relative; }
  .pitch::after {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: radial-gradient(340px circle at var(--gg-glow-x, 50%) var(--gg-glow-y, 40%),
      var(--candle-glow), transparent 70%);
    mix-blend-mode: screen;
    opacity: 0;
    transition: opacity 0.6s var(--ease);
  }
  .pitch:hover::after { opacity: 1; }
}

/* ── The candle component (404 + footer) ─────────────────────────────────── */
.gg-candle {
  position: relative;
  width: 18px;
  height: 34px;
  margin: 0 auto;
}
.gg-wick {
  position: absolute;
  bottom: 0; left: 50%;
  transform: translateX(-50%);
  width: 2px; height: 12px;
  background: var(--text-3);
  border-radius: 1px;
}
.gg-flame {
  position: absolute;
  bottom: 10px; left: 50%;
  transform: translateX(-50%);
  width: 10px; height: 16px;
  background: var(--candle-bright);
  border-radius: 50% 50% 45% 45% / 60% 60% 40% 40%;
  filter: blur(1.5px);
  box-shadow: 0 0 18px var(--candle-glow), 0 0 40px var(--candle-glow);
  transform-origin: 50% 90%;
}
@media (prefers-reduced-motion: no-preference) {
  .gg-flame { animation: gg-flicker 2.6s ease-in-out infinite; }
}
@keyframes gg-flicker {
  0%, 100% { transform: translateX(-50%) scale(1) rotate(0deg); opacity: 0.95; }
  25%      { transform: translateX(-52%) scale(0.96, 1.04) rotate(-1.5deg); opacity: 1; }
  55%      { transform: translateX(-48%) scale(1.03, 0.97) rotate(1deg); opacity: 0.9; }
  80%      { transform: translateX(-50%) scale(0.98, 1.02) rotate(-0.5deg); opacity: 1; }
}
/* footer: the light left on for you.
   Deliberately index.html-only — it's a homepage grace note (paired with the
   scroll-triggered snuff below), not a sitewide footer component. The other
   6 pages' footers intentionally don't include the .gg-candle markup. */
.gg-candle-footer { margin: 2.2rem auto 0.9rem; }
.legal-flame-note {
  display: block;
  margin-top: 0.3rem;
  font-family: var(--font-display);
  font-style: italic;
  color: var(--text-3);
}
/* 404: unlit until someone lights it */
.gg-candle-404 { margin: 1.6rem auto 1.2rem; position: relative; }
/* an unlit candle should still read as a candle: without the wax body the
   bare 2px wick floated above the headline like a stray pipe character. */
.gg-candle-404::before {
  content: ''; position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  width: 6px; height: 14px; border-radius: 3px 3px 2px 2px;
  background: var(--text-4);
}
.gg-candle-404 .gg-flame {
  opacity: 0;
  transform: translateX(-50%) scale(0.2);
  transition: opacity 1.2s var(--ease), transform 1.2s var(--ease);
  animation: none;
}
/* ghost of the flame, so the button's promise is legible in advance */
body:not(.gg-candle-lit) .gg-candle-404 .gg-flame { opacity: 0.08; transform: translateX(-50%) scale(0.55); }
body.gg-candle-lit .gg-candle-404 .gg-flame { opacity: 0.95; transform: translateX(-50%) scale(1); }
@media (prefers-reduced-motion: no-preference) {
  body.gg-candle-lit .gg-candle-404 .gg-flame { animation: gg-flicker 2.6s ease-in-out 1.2s infinite; }
}
.gg-404-ctas { display: flex; gap: 0.8rem; justify-content: center; flex-wrap: wrap; }

/* ── A note from Zinta — a letter, not a card ────────────────────────────── */
.founder-note { padding-top: 1rem; }
.founder-note p { color: var(--text-2); }
/* v2026-07-14 — give the letter's story paragraphs the pitch's reading setting
   (they were the base 15px/1.6 in dim text-2 while the lighter pitch above is
   1.05rem/1.75/text-1 — an inverted hierarchy on the page's most personal prose).
   Scoped with :not() so the 11px eyebrow + italic signature stay untouched. */
.founder-note p:not(.eyebrow):not(.founder-sig) {
  font-size: 1.05rem;
  line-height: 1.75;
  color: var(--text-1);
}
.founder-note .eyebrow { margin-bottom: 1.4rem; }
.founder-sig {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-top: 1.8rem;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.25rem;
  color: var(--text-1) !important;
}
.founder-sig img { opacity: 0.85; }

/* ── The demo section — proof you can open ───────────────────────────────── */
.try-demo .section-sub { max-width: 48ch; }

/* ── W9d: the last light goes out at the very end (and relights on the way
   back up — scroll-linked, so it costs nothing). Blessed as a tasteful quirk. */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: scroll()) {
    .gg-candle-footer .gg-flame {
      animation: gg-flicker 2.6s ease-in-out infinite, gg-snuff linear forwards;
      animation-timeline: auto, scroll(root);
      animation-range: normal, 96% 100%;
    }
    .gg-candle-footer::after {
      content: '';
      position: absolute;
      bottom: 22px; left: 50%;
      width: 2px; height: 16px;
      border-radius: 2px;
      background: linear-gradient(to top, var(--text-3), transparent);
      filter: blur(2px);
      opacity: 0;
      transform: translateX(-50%) translateY(6px);
      animation: gg-smoke linear forwards;
      animation-timeline: scroll(root);
      animation-range: 98% 100%;
    }
  }
}
@keyframes gg-snuff {
  from { opacity: 0.95; }
  to   { opacity: 0; }
}
@keyframes gg-smoke {
  from { opacity: 0;   transform: translateX(-50%) translateY(6px); }
  to   { opacity: 0.6; transform: translateX(-50%) translateY(-9px); }
}

/* ── W10: the hero line dissolves under your hand ────────────────────────── */
/* hover-only (matches the candlelight-cursor guard below) — on a touch device
   a :hover/:active state can stick after tap, so without this gate the site's
   single most important line of copy could blur to 35% opacity for a beat on
   a phone. Desktop-only intent, desktop-only trigger. */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .hero-title-em {
    display: inline-block;
    max-width: 100%;
    transition: letter-spacing 1.6s var(--ease), filter 1.6s var(--ease),
                opacity 1.6s var(--ease), text-shadow 1.6s var(--ease);
  }
  .hero-title-em:hover {
    letter-spacing: 0.14em;
    filter: blur(3px);
    opacity: 0.35;
    text-shadow: 0 -14px 18px var(--candle-glow);
  }
}

/* ── print — browsers strip backgrounds by default, so the site's light-on-dark
      text printed as near-white on white. For a product whose whole pitch is
      paper (privacy/terms get printed by real executors), printing must work.
      The blanket animation/transition kill also un-hides every view()-timeline
      reveal, whose base states are opacity:0 until scrolled. (v2-verified.) ── */
@media print {
  body::before, .site-header, .skip-link, .gg-candle-footer, .gg-candle-404 { display: none !important; }
  * {
    background: transparent !important;
    color: #172220 !important;
    box-shadow: none !important;
    text-shadow: none !important;
    animation: none !important;
    transition: none !important;
  }
  body { background: #fff !important; }
}
