/*
 * Seeds — gatherseeds.app
 *
 * Colors and type are the app's, copied from constants/theme.ts and
 * app.config.js so the site and the app read as one thing:
 *   sage  #8C9A8B  the sprout in the icon; growth, affirmation
 *   wine  #3C171F  the soil in the icon; the dark sections here
 *   gold  #C8A34A  the one high-contrast accent, kept scarce on purpose
 *   cream #F4EEE3  the app's light canvas and the splash background
 *
 * Fraunces / Inter / IBM Plex Mono, the same three families the app loads.
 *
 * HOW THE TWO ACCENTS DIVIDE (2026-08-04):
 *   gold = action and accent — buttons, step numbers, links, timestamps,
 *          pull-quote rules, the FAQ toggle. Anything you act on or look at.
 *   sage = growth and life — the stem the steps sit on, the sprout mark,
 *          hover states.
 * The app keeps gold scarce because there it means "this bloomed." Here it
 * carries the calls to action, which is a deliberate widening for the site
 * only — don't push it back into the app.
 *
 * ONE text measure for the whole page. Every section starts at the same x
 * position — mixing two container widths is what made the left edge jump
 * 160px between sections in the first build. Line length is controlled with
 * a max-width on the prose, never by narrowing the column.
 */

:root {
  --sage: #8c9a8b;
  --sage-deep: #5f6e5e;
  --sage-pale: #cfd6ce;
  --wine: #3c171f;
  --wine-deep: #2a1016;
  --gold: #c8a34a;
  /* The app's gold is a fill colour. On cream it fails contrast as text, so
     anything small and gold on a light background uses this deeper stop.
     Gold on wine is fine as-is. */
  --gold-deep: #7d5f16;

  --text: #2b211e;
  --text-secondary: #6e6258;
  --bg: #f4eee3;
  --card: #fcf9f2;
  --border: #e6dbc9;

  --on-dark: #fbf6f2;
  --on-dark-soft: #cbb7b7;

  /* Charcoal — the app's own dark mode, copied from constants/theme.ts.
     A third surface alongside cream and wine, so the page has somewhere to
     go that isn't another wine band. */
  --charcoal: #1e1b1a;
  --charcoal-card: #272322;
  --charcoal-border: #39322f;
  --on-charcoal: #f1ebde;
  --on-charcoal-soft: #a79c90;

  --serif: 'Fraunces', Georgia, serif;
  --sans: 'Inter', system-ui, -apple-system, sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, monospace;

  --wrap: 880px;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }

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

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 24px; }

h1, h2, h3 { font-family: var(--serif); font-weight: 500; line-height: 1.14; margin: 0; }
h1 { font-size: clamp(30px, 4.4vw, 47px); letter-spacing: -0.018em; }
h2 { font-size: clamp(27px, 4vw, 38px); letter-spacing: -0.012em; margin-bottom: 20px; max-width: 19ch; }
h3 { font-size: 19px; margin-bottom: 6px; }
p { margin: 0 0 18px; }
p:last-child { margin-bottom: 0; }
section p, .step p, .faq details > p, .beat p { max-width: 62ch; }
a { color: var(--gold-deep); text-underline-offset: 3px; }

.eyebrow {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-secondary);
  margin-bottom: 18px;
}

.fine { font-size: 14px; color: var(--text-secondary); }

/* ── Dark surfaces ──────────────────────────────────────────
   The soil in the app icon is a texture, not a flat colour, so the dark
   sections here carry a faint grain rather than a solid fill. Generated
   inline with SVG turbulence — no extra file, no extra request. */

.dark {
  background-color: var(--wine);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.055'/%3E%3C/svg%3E");
  color: #f1e9e4;
}
.dark h1, .dark h2, .dark h3 { color: var(--on-dark); }

/* ── Charcoal surfaces ──────────────────────────────────────
   The app's dark mode, used where a wine band would be too heavy or would
   sit too close to another one. Same grain as .dark. */

.charcoal {
  background-color: var(--charcoal);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E");
  color: var(--on-charcoal);
  border-top: none !important;
}
.charcoal h1, .charcoal h2, .charcoal h3 { color: var(--on-charcoal); }
.charcoal .eyebrow { color: var(--gold); }
.charcoal p, .charcoal .step p { color: var(--on-charcoal-soft); }
.charcoal p a { color: var(--gold); }
.charcoal .fine { color: var(--on-charcoal-soft); }
.charcoal .pull { border-left-color: var(--gold); color: var(--on-charcoal); }
/* .moment is a <p>, so the blanket paragraph colour above would mute the
   one line on the page that should be loudest. */
.charcoal .moment { color: var(--on-charcoal); }
/* The number sits on the stem and needs a ring the colour of whatever is
   behind it, or the line runs straight through the circle. */
.charcoal .step .num { box-shadow: 0 0 0 6px var(--charcoal); }
/* The sprout mark is dark sage — it needs lifting on anything this dark. */
.charcoal .sprig { filter: brightness(1.35); }
.dark .eyebrow { color: var(--gold); }
.dark p a { color: var(--gold); }
.dark .fine { color: var(--on-dark-soft); }
.dark .pull { border-left-color: var(--gold); color: var(--on-dark); }

/* ── Header ─────────────────────────────────────────────────
   Sits on the dark hero, so it inherits .dark colours. */

header { padding: 24px 0 0; }
header .wrap { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.brand {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--serif); font-size: 22px;
  color: var(--text); text-decoration: none;
}
.brand img { display: block; width: 30px; height: 30px; border-radius: 22.5%; }
.nav-cta {
  font-size: 15px; font-weight: 500;
  color: var(--text); text-decoration: none;
  border: 1px solid var(--border); border-radius: 999px;
  padding: 7px 17px; background: var(--card);
}
.nav-cta:hover { border-color: var(--gold); }

/* On the homepage the header sits inside the dark hero. */
.dark .brand { color: var(--on-dark); }
.dark .nav-cta {
  color: var(--on-dark); background: transparent;
  border-color: rgba(207, 214, 206, 0.32);
}
.dark .nav-cta:hover { border-color: var(--gold); background: rgba(200, 163, 74, 0.09); }

/* ── Hero ───────────────────────────────────────────────────
   Dark and full-bleed. The icon is dark and textured; a cream hero made
   the page open on its quietest possible note.

   The background is Brandon's image — a sprout in soil, and beside it a web
   of connected things someone has kept: a melody, a photo, a page of
   writing, an idea. The exported file is already mirrored, so the sprout is
   on the right and stays pinned there; the words sit on the left opposite it.

   Two layers over the wine, not one. ::before is the picture at 50%.
   ::after is a scrim that is nearly solid on the left, where the words sit,
   and fully transparent on the right, where the sprout needs to read. That
   split is what lets the image be strong and the headline still be legible —
   raising the opacity alone put even cream text below 4:1 over the bright
   bubbles. Both are separate layers rather than a flattened file, so the
   opacity, the scrim and the flip are each one edit. */

.hero-shell {
  position: relative;
  background-color: var(--wine);
  background-image: none;
  isolation: isolate;
}
.hero-shell::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: url("img/hero-bg.jpg");
  background-image: image-set(url("img/hero-bg.webp") type("image/webp"),
                              url("img/hero-bg.jpg") type("image/jpeg"));
  background-size: cover;
  /* Right-justified, so the sprout is pinned to the right edge and any
     cropping eats the quiet end of the picture instead. */
  background-position: right center;
  /* NOTE: the mirroring is baked into the exported file, deliberately NOT
     done here with `transform: scaleX(-1)`. A transform mirrors the element
     AFTER the background has been positioned, which makes background-position
     mean the opposite of what it reads — this hit once already and the
     mobile crop was showing the wrong half of the picture as a result.
     To redo the flip, re-export from tools/raw/hero-source.png with a
     FLIP_LEFT_RIGHT rather than reaching for a transform. */
  /* Opacity raised from 0.25 so the picture actually reads. Anything above
     about 0.3 makes even cream text fail contrast over the bright bubbles,
     which is what ::after below exists to solve — the image stays strong on
     the right where the sprout is, and gets covered where the words are. */
  opacity: 0.5;
  z-index: -2;
  pointer-events: none;
}

/* The scrim, mirrored along with the picture. Near-solid on the left where
   the words sit, clearing to nothing on the right so the sprout comes
   through at full strength. Re-measured after the flip against the
   brightest pixel in the text area: cream 6.0:1, lede 4.8:1. */
.hero-shell::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    260deg,
    rgba(42, 16, 22, 0) 0%,
    rgba(42, 16, 22, 0) 30%,
    rgba(42, 16, 22, 0.55) 62%,
    rgba(42, 16, 22, 0.8) 100%
  );
  z-index: -1;
  pointer-events: none;
}

@media (max-width: 820px) {
  /* A phone hero is roughly half as wide as it is tall, and a 16:9 picture
     cannot crop into that shape well from any anchor point. So mobile gets
     its own portrait file rather than a different background-position.
     Both are built by tools/build-hero.py; drop a custom crop in
     tools/raw/hero-mobile-source.png and re-run to replace this one. */
  .hero-shell::before {
    background-image: url("img/hero-bg-mobile.jpg");
    background-image: image-set(url("img/hero-bg-mobile.webp") type("image/webp"),
                                url("img/hero-bg-mobile.jpg") type("image/jpeg"));
    background-position: center;
  }
  /* Slightly heavier than the desktop scrim: the text runs the full width
     here and the phone crop is the brightest part of the picture. Measured
     against the worst pixel — cream 6.7:1, lede 5.3:1. */
  .hero-shell::after {
    background: linear-gradient(180deg, rgba(42,16,22,0.45) 0%, rgba(42,16,22,0.78) 100%);
  }
}

.hero { padding: 92px 0 104px; }
.hero-inner { display: flex; justify-content: flex-start; }
/* Held to the left half so the right stays clear for the sprout. */
.hero-text { flex: 0 1 auto; width: 60%; min-width: 0; }
.hero h1 { max-width: 17ch; }
.hero p.lede {
  font-size: 18px;
  /* Lighter than the site's usual muted tone. Measured over the brightest
     part of the hero image behind it — the standard --on-dark-soft came out
     at 3.8:1 there, which is below readable. */
  color: #e5dbd7;
  max-width: 40ch; margin-top: 22px;
}
.hero-actions { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; margin-top: 34px; }

/* Layout side of the same breakpoint. It has to sit AFTER the .hero rules
   above rather than fold into the media block higher up — media queries
   carry no extra weight, so a later plain rule would simply win.
   The scrim override lives up there with the mobile image it belongs to;
   it used to be duplicated here and the two had to be kept in step by hand. */
@media (max-width: 820px) {
  .hero { padding: 60px 0 68px; }
  .hero-text { width: 100%; }
}

/* ── Orientation strip ──────────────────────────────────────
   Sits at the bottom of the hero. Its whole job is to answer "so what is
   it" before anyone has to read a paragraph — the one thing a reader
   couldn't get from this page at a glance. */

.orient { border-top: 1px solid rgba(207, 214, 206, 0.16); }
.orient-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 30px;
  padding-top: 30px;
  padding-bottom: 34px;
}
.orient-item {
  font-size: 14px;
  line-height: 1.55;
  color: var(--on-dark-soft);
}
.orient-item .n {
  display: block;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.14em;
  color: var(--gold); margin-bottom: 9px;
}
.orient-item b {
  display: block;
  font-family: var(--serif); font-weight: 500; font-size: 17px;
  color: var(--on-dark); margin-bottom: 5px;
}
@media (max-width: 820px) {
  .orient-row { grid-template-columns: repeat(2, 1fr); gap: 24px; }
}
@media (max-width: 460px) {
  .orient-row { grid-template-columns: 1fr; gap: 20px; }
}

/* ── Where the ideas turn up ────────────────────────────────
   The opening paragraph already listed these in prose. Showing them makes
   the emotional beat land before anyone reads a word, which is the whole
   point of that section. */

.moments {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 14px;
  margin: 4px 0 34px;
}
.moment-i { text-align: center; color: var(--sage-deep); }
.moment-i .micon { width: 30px; height: 30px; margin: 0 auto 10px; display: block; }
.moment-i span {
  display: block;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--text-secondary); line-height: 1.4;
}
@media (max-width: 720px) {
  .moments { grid-template-columns: repeat(3, 1fr); gap: 20px; }
}

/* ── Buttons ────────────────────────────────────────────────── */

.btn {
  display: inline-block;
  font-family: var(--sans); font-size: 16px; font-weight: 500;
  padding: 13px 27px; border: none; border-radius: 999px;
  background: var(--gold); color: var(--wine-deep);
  text-decoration: none; cursor: pointer;
}
.btn:hover { filter: brightness(1.08); }
/* Stated again at higher specificity as a belt-and-braces guard: a link
   styled as a button must never inherit the link colour. */
.dark a.btn, a.btn { color: var(--wine-deep); }
/* Gold reads well on both cream and wine, so the button no longer needs a
   dark-background variant. The class is kept so existing markup still works. */
.btn-on-dark { background: var(--gold); color: var(--wine-deep); }

/* ── Sections and rhythm ────────────────────────────────────
   Uniform padding made every section equally important, which made none
   of them important. Four weights instead of one. */

section { padding: 64px 0; }
section.roomy { padding: 92px 0; }
section.breath { padding: 120px 0; }
/* Half again as tall as .roomy — for the two sections that want room to
   breathe rather than another colour to set them apart. */
section.spacious { padding: 138px 0; }
section.tight { padding: 44px 0; }
section + section { border-top: 1px solid var(--border); }
section.dark + section, section + section.dark, .dark + section,
section.charcoal + section, section + section.charcoal { border-top: none; }

.pull {
  font-family: var(--serif);
  font-size: clamp(21px, 2.6vw, 27px);
  line-height: 1.4;
  border-left: 3px solid var(--gold);
  padding-left: 24px;
  margin: 30px 0 0;
  max-width: 24ch;
}

/* ── Steps, on a growing stem ───────────────────────────────
   A sage line runs down through the numbers. Literal, and it's the only
   piece of illustration on the page that isn't a screenshot. */

.steps { position: relative; margin-top: 40px; padding-left: 4px; }
.steps::before {
  content: '';
  position: absolute;
  left: 20px; top: 12px; bottom: 26px;
  width: 2px;
  /* Sage at the top ripening to gold at the bottom — the stem is the one
     place the two accents meet, and it's growth turning into something. */
  background: linear-gradient(to bottom, var(--sage) 0%, var(--sage) 30%, var(--gold) 92%, rgba(200, 163, 74, 0.2) 100%);
}
.step { display: flex; gap: 22px; align-items: flex-start; position: relative; }
.step + .step { margin-top: 30px; }
.step .num {
  flex: none; width: 34px; height: 34px; border-radius: 50%;
  background: var(--gold); color: var(--wine-deep);
  font-family: var(--mono); font-size: 13px;
  display: grid; place-items: center;
  margin-top: 2px; position: relative; z-index: 1;
  box-shadow: 0 0 0 6px var(--bg);
}
.step p { color: var(--text-secondary); margin: 0; }

/* ── The story: one idea, told in beats ─────────────────────
   Replaces the grid of four screenshots. A grid documents an app; a
   sequence shows what happens to an idea. */

.beats { margin-top: 46px; display: flex; flex-direction: column; gap: 52px; }
.beat { display: flex; align-items: center; gap: 44px; }
.beat:nth-child(even) { flex-direction: row-reverse; }
.beat-text { flex: 1 1 auto; min-width: 0; }
.beat-shot { flex: 0 0 244px; }
.beat .when {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--gold-deep); margin-bottom: 8px;
}
.beat h3 { font-size: clamp(21px, 2.4vw, 26px); margin-bottom: 10px; }

/* The closing beat has no screenshot (2026-08-06). Without one, the text
   would stretch the full container width and look like a beat whose image
   failed to load. Centering it and holding it to a readable measure turns
   the missing phone into the point: the story stops, and the Cultivator
   section below gets the screenshot to itself. */
.beat-final { justify-content: center; text-align: center; }
.beat-final .beat-text { flex: 0 1 560px; }

.beat p { color: var(--text-secondary); margin: 0; }

@media (max-width: 760px) {
  .beats { gap: 40px; }
  .beat, .beat:nth-child(even) { flex-direction: column; align-items: flex-start; gap: 22px; }
  .beat-shot { flex: 0 0 auto; width: 210px; align-self: center; }
}

/* ── Phones ─────────────────────────────────────────────────
   Ratio matches an iPhone screenshot exactly (1290 x 2796), so a new one
   drops in with no cropping. */

.phone {
  display: block;
  border: 8px solid #16110f;
  border-radius: 30px;
  overflow: hidden;
  background: #16110f;
  box-shadow: 0 16px 36px rgba(43, 33, 30, 0.22);
  aspect-ratio: 1290 / 2796;
}
.dark .phone { box-shadow: 0 18px 44px rgba(0, 0, 0, 0.45); border-color: #0d0908; background: #0d0908; }
.phone picture { display: block; height: 100%; }
.phone img { width: 100%; height: 100%; object-fit: cover; display: block; }

.phone-btn { display: block; width: 100%; padding: 0; border: none; background: none; cursor: zoom-in; }
.phone-btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 5px; }
figure { margin: 0; }

/* Click to enlarge — no phone screenshot is readable at web scale, so the
   full-size version is a click away rather than shrunk until it stops
   being evidence. */
dialog.lightbox { border: none; background: none; padding: 0; max-width: none; max-height: none; width: 100%; height: 100%; }
dialog.lightbox::backdrop { background: rgba(26, 14, 16, 0.9); }
dialog.lightbox .inner { width: 100%; height: 100%; display: grid; place-items: center; padding: 26px; }
dialog.lightbox img { max-height: 92vh; max-width: 100%; width: auto; border-radius: 22px; box-shadow: 0 24px 60px rgba(0,0,0,0.55); }
dialog.lightbox .close {
  position: fixed; top: 18px; right: 22px;
  background: rgba(252,249,242,0.14); color: var(--on-dark);
  border: 1px solid rgba(252,249,242,0.3); border-radius: 999px;
  padding: 8px 18px; font-family: var(--sans); font-size: 15px; cursor: pointer;
}

/* ── Copy beside a screenshot — the Cultivator only ────────── */

.split { display: flex; gap: 48px; align-items: center; margin-top: 36px; }
.split .col-text { flex: 1 1 auto; min-width: 0; }
.split .col-shot { flex: 0 0 262px; }
.split figcaption {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.1em;
  text-transform: uppercase; text-align: center; margin-top: 13px; color: var(--sage);
}
@media (max-width: 820px) {
  .split { flex-direction: column; align-items: flex-start; gap: 32px; }
  .split .col-shot { flex: 0 0 auto; width: 232px; align-self: center; }
}

.inline-cta { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; margin-top: 36px; }

/* ── The one-line moment ────────────────────────────────────
   No eyebrow, no heading, nothing else in the section. Rhythm through
   type scale rather than through another colour band. */

.moment-wrap { text-align: center; }
.moment-wrap .sprig { width: 44px; opacity: 0.85; margin-bottom: 26px; }
.moment {
  font-family: var(--serif);
  font-size: clamp(32px, 5vw, 50px);
  line-height: 1.16;
  letter-spacing: -0.018em;
  max-width: 16ch;
  margin: 0 auto;
}
.moment-note {
  color: var(--text-secondary);
  max-width: 48ch;
  margin: 28px auto 0;
}
/* Overrides the page-wide prose measure, which is left-aligned by default. */
section .moment-note { max-width: 48ch; }

/* ── Who it's for ───────────────────────────────────────────── */

.fors {
  margin-top: 36px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}
.for {
  background: var(--card);
  border: 1px solid var(--border);
  border-top: 3px solid var(--sage);
  border-radius: 0 0 12px 12px;
  padding: 24px 22px 26px;
}
.for .icon {
  width: 30px; height: 30px;
  color: var(--sage-deep);
  display: block;
  margin-bottom: 14px;
}
.for .who {
  font-family: var(--serif);
  font-size: 20px;
  color: var(--sage-deep);
  margin-bottom: 8px;
}
.for p { margin: 0; color: var(--text-secondary); font-size: 16px; }
@media (max-width: 720px) {
  .fors { grid-template-columns: 1fr; }
}

/* ── FAQ ────────────────────────────────────────────────────── */

.faq { margin-top: 32px; }
.faq details { border-bottom: 1px solid var(--border); padding: 17px 0; }
.faq details:first-of-type { border-top: 1px solid var(--border); }
.faq summary {
  font-family: var(--serif); font-size: 19px;
  cursor: pointer; list-style: none;
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: '+'; font-family: var(--sans); font-size: 22px; color: var(--gold-deep); flex: none; line-height: 1; }
.faq details[open] summary::after { content: '–'; }
.faq details > p { margin: 13px 0 0; color: var(--text-secondary); }

/* ── Makers ─────────────────────────────────────────────────── */

.makers { display: flex; gap: 24px; align-items: flex-start; margin-top: 26px; }
.makers .sprig { flex: none; width: 54px; opacity: 0.9; }
@media (max-width: 560px) {
  .makers { flex-direction: column; gap: 14px; }
}

/* The closing section holds the story and the ask together — the personal
   bit earns the request, so they shouldn't be separated by a hairline. */
/* The invite section, on its own surface. Same two-layer treatment as the
   hero: the picture at 50%, then an even scrim — even rather than a ramp,
   because the text here runs the full width instead of sitting to one side.
   Measured against the brightest pixel: cream 5.8:1, body 5.2:1. */
.beta-shell {
  position: relative;
  isolation: isolate;
  /* "Who's building it" is dark too, so without this the two run together
     at the seam. The rule that strips borders between dark sections is
     right in general and wrong here. */
  border-top: 1px solid rgba(238, 221, 180, 0.22) !important;
}
.beta-shell::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: url("img/beta-bg.jpg");
  background-image: image-set(url("img/beta-bg.webp") type("image/webp"),
                              url("img/beta-bg.jpg") type("image/jpeg"));
  background-size: cover;
  background-position: center;
  opacity: 0.5;
  z-index: -2;
  pointer-events: none;
}
.beta-shell::after {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(42, 16, 22, 0.3);
  z-index: -1;
  pointer-events: none;
}
/* The app's gold comes out at 2.6:1 over the brightest part of this image.
   A paler gold keeps the accent and clears 4.5:1. */
.beta-shell .eyebrow { color: #eeddb4; }
/* The form needs a surface of its own, or the field disappears into the
   constellation behind it. */
.beta-shell .signup { background: rgba(42, 16, 22, 0.62); }
.beta-shell .signup input[type='email'] { background: rgba(0, 0, 0, 0.42); }
/* The sprout mark is dark sage; on any dark surface it needs lifting. */
.dark .sprig { filter: brightness(1.35); }

/* ── Signup ─────────────────────────────────────────────────── */

.signup {
  background: rgba(252, 249, 242, 0.06);
  border: 1px solid rgba(200, 163, 74, 0.28);
  border-radius: 18px;
  padding: 32px 30px;
  margin-top: 28px;
}
/* 2026-08-05 — the form asks more than an email now. Two short fields about
   what you make, because they do double duty: they tell us whether someone
   is the songwriter we're building for, and they're the first interview
   question asked before anyone has to sit down for an interview.
   Column layout rather than the old single inline row. */
.signup form { display: flex; flex-direction: column; gap: 12px; margin-top: 20px; }
.signup input[type='email'],
.signup input[type='text'] {
  width: 100%;
  font-family: inherit; font-size: 16px;
  padding: 13px 17px;
  border: 1px solid rgba(207, 214, 206, 0.32);
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.2);
  color: var(--on-dark);
}
.signup input::placeholder { color: #a08c8c; }
.signup input:focus { outline: 2px solid var(--gold); outline-offset: 1px; }
/* The button sits on its own line and stays hand-sized on a phone. */
.signup form .btn { align-self: flex-start; margin-top: 4px; }
@media (max-width: 560px) {
  .signup form .btn { align-self: stretch; text-align: center; }
}
.signup .field-note {
  font-size: 13px;
  color: #a08c8c;
  margin: -4px 0 2px 18px;
}
.hidden { position: absolute; left: -9999px; }

/* ── Confirmation pages ─────────────────────────────────────
   2026-08-05. Used by thanks.html. The real app icon — the wine square,
   not the flat sage mark — is the anchor of the page, because it's the
   thing they're about to install and the warmest artifact the brand has.

   Centred, because a confirmation is one short message and centring alone
   sets it apart from every other page without spending a colour band on it.
   Two earlier attempts failed by reaching for the homepage hero shell; this
   one owns its own small block of CSS instead. */

.confirm { text-align: center; padding: 104px 0 26px; }
.confirm .app-icon {
  display: block;
  width: 104px;
  height: 104px;
  margin: 0 auto 32px;
  /* drop-shadow, NOT box-shadow — the icon's corners are rounded in the
     PNG's alpha channel, and box-shadow would draw a hard square behind
     them. drop-shadow follows the alpha. */
  filter: drop-shadow(0 12px 26px rgba(43, 33, 30, 0.22));
}
.confirm h1 {
  font-size: clamp(30px, 5.2vw, 46px);
  line-height: 1.12;
  letter-spacing: -0.018em;
  max-width: 17ch;
  margin: 0 auto 20px;
}
.confirm p {
  max-width: 52ch;
  margin: 0 auto 16px;
  font-size: 17px;
  line-height: 1.62;
}
.confirm .eyebrow { margin-bottom: 14px; }
@media (max-width: 560px) {
  .confirm { padding-top: 72px; }
  .confirm .app-icon { width: 84px; height: 84px; margin-bottom: 26px; }
}

/* The quieter half, under a hairline rather than in its own colour band. */
.confirm-after {
  max-width: 52ch;
  margin: 0 auto;
  padding: 42px 0 96px;
  text-align: center;
  border-top: 1px solid var(--border);
}
.confirm-after h2 { font-size: 21px; margin-bottom: 12px; }
.confirm-after p { font-size: 16px; line-height: 1.62; margin-bottom: 14px; }

/* ── Footer ─────────────────────────────────────────────────── */

footer { border-top: 1px solid var(--border); padding: 36px 0 62px; font-size: 14px; color: var(--text-secondary); }
footer a { color: var(--text-secondary); }
footer .row { display: flex; gap: 18px; flex-wrap: wrap; margin-top: 8px; }

/* ── Inner pages ────────────────────────────────────────────── */

.page { padding: 44px 0 74px; }
.page h1 { font-size: clamp(28px, 5vw, 40px); margin-bottom: 22px; max-width: 22ch; }
.page h2 { font-size: 21px; margin-top: 34px; margin-bottom: 10px; }

/* ── Scroll reveal ──────────────────────────────────────────
   Adds life without gimmick. Only arms itself once JS runs, so with
   scripting off nothing is ever hidden. Honours reduced-motion. */

.js-reveal .reveal { opacity: 0; transform: translateY(16px); }
.js-reveal .reveal.in { opacity: 1; transform: none; transition: opacity .7s ease, transform .7s cubic-bezier(.22,.61,.36,1); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js-reveal .reveal { opacity: 1; transform: none; }
  .js-reveal .reveal.in { transition: none; }
}
