/* ── Vendera marketing site ───────────────────────────────────────────────────
   Tokens mirror the app (src/index.css) so the site and the product read as one
   thing. The gold keeps the app's two-role split: --gold is a FILL that dark ink
   sits on; --gold-ink is the gold pushed dark enough to be legible AS text on
   paper. Never use --gold for text on --paper.
   ──────────────────────────────────────────────────────────────────────────── */
@font-face {
  font-family: 'Source Serif 4';
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url('../assets/fonts/source-serif-4-normal-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: 'Source Serif 4';
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url('../assets/fonts/source-serif-4-normal-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 {
  /* Ground and ink — the app's light palette */
  --paper: #f7f6f3;
  --paper-2: #f1efea;
  --card: #ffffff;
  --rule: #ddd9d0;
  --ink: #1f1e24;
  --ink-2: #5b5966;
  --ink-3: #85828f;

  /* Gold, split by role exactly as the app does */
  --gold: #d4a24c;      /* FILL only */
  --gold-ink: #8a6220;  /* gold as TEXT on paper (5.1:1) */
  --gold-soft: #f6ecd9;
  --on-gold: #1f1a10;

  --green: #0d6e4c;
  --green-soft: #e4efe8;

  /* Night section */
  --night: #0f0f12;
  --night-2: #18181e;
  --night-3: #212129;
  --night-rule: #2c2c36;
  --night-ink: #e8e6e0;
  --night-ink-2: #a09eaa;

  /* One warm light from the top left, so every shadow agrees */
  --shadow-1: 0 1px 2px rgb(28 25 20 / 0.06), 0 1px 1px rgb(28 25 20 / 0.04);
  --shadow-2: 0 2px 8px rgb(28 25 20 / 0.07), 0 1px 2px rgb(28 25 20 / 0.05);
  --shadow-3: 0 8px 28px rgb(28 25 20 / 0.12), 0 2px 6px rgb(28 25 20 / 0.06);
  --shadow-4: 0 26px 70px rgb(28 25 20 / 0.17), 0 8px 22px rgb(28 25 20 / 0.09);

  --serif: 'Source Serif 4', ui-serif, Georgia, 'Times New Roman', serif;
  --sans: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  --measure: 62ch;
  --gutter: clamp(20px, 5vw, 64px);
  --shell: 1180px;

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* A paper tooth, not a texture. Two per cent of a grain, fixed so it never
   scrolls with the content and never lands on text. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.35;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%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='160' height='160' filter='url(%23n)' opacity='0.055'/%3E%3C/svg%3E");
}
main, header, footer { position: relative; z-index: 1; }

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

a { color: var(--gold-ink); text-underline-offset: 3px; text-decoration-thickness: 1px; }
a:hover { color: var(--ink); }

:focus-visible {
  outline: 2px solid var(--gold-ink);
  outline-offset: 3px;
  border-radius: 4px;
}

.shell { width: min(100% - (var(--gutter) * 2), var(--shell)); margin-inline: auto; }

.skip {
  position: absolute; left: -9999px; top: 0;
  background: var(--ink); color: var(--paper);
  padding: 12px 18px; border-radius: 0 0 10px 0; z-index: 100;
}
.skip:focus { left: 0; }

/* ── Type ──────────────────────────────────────────────────────────────────── */
/* The serif carries language: words, headlines, the vocabulary itself.
   The system sans carries interface, exactly as the app does. */
h1, h2, h3, .serif { font-family: var(--serif); font-weight: 600; letter-spacing: -0.015em; }

h1 {
  font-size: clamp(2.6rem, 7.2vw, 4.6rem);
  line-height: 1.02;
  margin: 0 0 1.1rem;
  letter-spacing: -0.03em;
  text-wrap: balance;
}
h2 {
  font-size: clamp(1.9rem, 4vw, 2.9rem);
  line-height: 1.1;
  margin: 0 0 1rem;
  letter-spacing: -0.022em;
  text-wrap: balance;
}
h3 { font-size: 1.22rem; line-height: 1.3; margin: 0 0 0.45rem; }

p { margin: 0 0 1.1rem; max-width: var(--measure); }
.lede { font-size: clamp(1.08rem, 2vw, 1.3rem); color: var(--ink-2); line-height: 1.55; }

.eyebrow {
  font-family: var(--sans);
  font-size: 0.735rem;
  font-weight: 650;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--gold-ink);
  margin: 0 0 1.1rem;
  display: flex;
  align-items: center;
  gap: 0.7rem;
}
.eyebrow::after { content: ''; flex: 1; height: 1px; background: var(--rule); max-width: 90px; }

section { padding-block: clamp(3.6rem, 7vw, 6.2rem); }

/* ── Buttons ───────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.55rem;
  min-height: 52px; padding: 0 1.55rem;
  border-radius: 13px; border: 1px solid transparent;
  font-family: var(--sans); font-size: 1.02rem; font-weight: 600;
  text-decoration: none; cursor: pointer;
  transition: transform 0.18s var(--ease), box-shadow 0.18s var(--ease), background-color 0.18s var(--ease);
}
.btn-primary { background: var(--gold); color: var(--on-gold); box-shadow: 0 4px 14px rgb(168 122 36 / 0.26); }
.btn-primary:hover { background: #c08f37; color: var(--on-gold); transform: translateY(-1px); box-shadow: 0 8px 22px rgb(168 122 36 / 0.3); }
.btn-ghost { background: transparent; color: var(--ink); border-color: var(--rule); }
.btn-ghost:hover { background: var(--card); color: var(--ink); border-color: #c9c4b8; }
.btn:active { transform: translateY(0); }
.btn-row { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; }

.note { font-size: 0.875rem; color: var(--ink-2); margin: 0.95rem 0 0; }

/* ── Header ────────────────────────────────────────────────────────────────── */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s var(--ease), background-color 0.2s var(--ease);
}
.site-header.is-stuck { border-bottom-color: var(--rule); }
.site-header .shell { display: flex; align-items: center; justify-content: space-between; min-height: 70px; gap: 1rem; }

/* The real logo, not the name set in the body serif.
   Two images rather than one lockup, because the delivered artwork stacks the mark above
   the word and a header bar needs them side by side. Sized by height so the pair scales
   together and neither drifts. */
.wordmark {
  display: inline-flex; align-items: center; gap: 0.5rem;
  text-decoration: none; line-height: 0;
}
.wordmark .mark { height: 26px; width: auto; flex: none; }
.wordmark .logotype { height: 17px; width: auto; flex: none; }
.wordmark-sm .mark { height: 20px; }
.wordmark-sm .logotype { height: 13px; }

/* On the narrowest phones the header carries the logo and the call to action, and the
   full lockup is 30px wider than the old text wordmark it replaced, which was enough to
   push the row past the viewport. The mark alone still says whose site this is. */
@media (max-width: 400px) {
  .site-header .wordmark .logotype { display: none; }
}

.nav-links { display: flex; align-items: center; gap: 1.7rem; }
.nav-links a { color: var(--ink-2); text-decoration: none; font-size: 0.95rem; font-weight: 500; }
.nav-links a:hover { color: var(--ink); }
.site-header .btn { min-height: 42px; padding: 0 1.1rem; font-size: 0.94rem; border-radius: 11px; }
@media (max-width: 820px) { .nav-links { display: none; } }

/* ── Hero ──────────────────────────────────────────────────────────────────── */
.hero { padding-top: clamp(2.6rem, 6vw, 4.6rem); padding-bottom: clamp(3rem, 6vw, 5rem); }
/* Three areas, so a narrow screen can put the scene between the headline and
   the buttons instead of pushing the product under the fold. */
.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.02fr) minmax(0, 1fr);
  grid-template-areas: 'copy scene' 'cta scene';
  grid-template-rows: auto auto;
  column-gap: clamp(2rem, 5vw, 4.5rem);
  align-content: center;
}
.hero-copy { grid-area: copy; max-width: 33rem; align-self: end; }
.hero-cta  { grid-area: cta;  max-width: 33rem; align-self: start; margin-top: 1.7rem; }
.scene-wrap { grid-area: scene; align-self: center; }
.hero h1 .accent {
  /* Gold as text must use the darkened role, never the fill. */
  color: var(--gold-ink);
  position: relative; white-space: nowrap;
}
.hero h1 .accent::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0.07em; height: 0.09em;
  background: var(--gold); border-radius: 2px; opacity: 0.55;
}
.hero .lede { margin-bottom: 1.7rem; }
.hero-note { margin-top: 1.1rem; font-size: 0.83rem; color: var(--ink-3); }

/* One-shot entrance, in reading order: headline, then the promise, then the
   buttons. It sequences attention towards the scene, which is already composed
   at first paint and is deliberately not part of this. */
.hero-copy > *, .hero-cta > * {
  animation: heroIn 0.48s var(--ease-out) both;
}
/* The headline is the largest text on the page, so it is what Chrome measures
   as the Largest Contentful Paint. Text at opacity 0 does not count as painted,
   so fading it in would push LCP out by the length of the animation. It rises
   without fading, and LCP stays at first paint. */
.hero-copy > h1 { animation-name: heroRise; }
@keyframes heroRise {
  from { transform: translateY(12px); }
  to   { transform: none; }
}
.hero-copy > :nth-child(2) { animation-delay: 0.08s; }
.hero-cta > :nth-child(1)  { animation-delay: 0.16s; }
.hero-cta > :nth-child(2)  { animation-delay: 0.22s; }
.hero-cta > :nth-child(3)  { animation-delay: 0.28s; }
@keyframes heroIn {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

.hero-facts { display: flex; flex-wrap: wrap; gap: 0.5rem 1.35rem; margin: 1.5rem 0 0; padding: 0; list-style: none; }
.hero-facts li { display: flex; align-items: center; gap: 0.45rem; font-size: 0.9rem; color: var(--ink-2); }
.hero-facts svg { width: 15px; height: 15px; color: var(--green); flex: none; }

@media (max-width: 940px) {
  .hero-grid {
    grid-template-columns: 1fr;
    grid-template-areas: 'copy' 'scene' 'cta';
    row-gap: 0.4rem;
  }
  .hero-copy, .hero-cta { max-width: 100%; }
  .hero-cta { margin-top: 0.6rem; }
  .hero { padding-top: 1.2rem; padding-bottom: 3rem; }
  .hero .lede { margin-bottom: 0; }
  /* Full width beats two cramped buttons on one line at 390px. */
  .hero-cta .btn { flex: 1 1 100%; }
  .hero-facts { gap: 0.45rem 1.1rem; margin-top: 1.1rem; }
}

/* ── The 3D scene ──────────────────────────────────────────────────────────
   Three objects in one perspective space: the sentence a word is met in (back
   left), the phone it is captured into (front right), and the deck it is filed
   into (lower left). The card travels between them, so the composition reads as
   a loop rather than a row of props. */
.scene-wrap { position: relative; }
.scene {
  position: relative;
  height: clamp(430px, 46vw, 545px);
  perspective: 1500px;
  perspective-origin: 50% 46%;
  contain: layout paint style;
}
.stage {
  position: absolute; inset: 0;
  transform-style: preserve-3d;
  transform: rotateX(var(--rx, 7deg)) rotateY(var(--ry, -15deg)) scale(var(--sc, 1));
  will-change: transform;
}
.layer { position: absolute; left: 50%; top: 50%; transform-style: preserve-3d; }

/* The phone: a slab with a real edge behind the face, so it reads as solid. */
.phone {
  width: 248px; height: 510px;
  margin: -255px 0 0 -124px;
  transform: translate3d(96px, 0, 0);
}
.phone-body {
  position: absolute; inset: 0;
  border-radius: 36px;
  background: linear-gradient(150deg, #fbfaf8 0%, #efece6 52%, #e3dfd6 100%);
  box-shadow:
    0 54px 84px -30px rgb(28 25 20 / 0.32),
    0 22px 40px -18px rgb(28 25 20 / 0.19),
    inset 0 1px 0 rgb(255 255 255 / 0.9);
  transform-style: preserve-3d;
}
.phone-edge {
  position: absolute; inset: 0;
  border-radius: 36px;
  background: linear-gradient(150deg, #cdc7ba, #a9a294);
  transform: translateZ(-12px);
}
.phone-screen {
  position: absolute; inset: 8px;
  border-radius: 29px;
  background: var(--paper);
  overflow: hidden;
  transform: translateZ(1px);
  box-shadow: inset 0 0 0 1px rgb(28 25 20 / 0.06);
  display: flex; flex-direction: column;
}
/* One specular band, angled with the light. It is what sells the material. */
.phone-gloss {
  position: absolute; inset: 0; border-radius: 36px; pointer-events: none;
  background: linear-gradient(126deg, rgb(255 255 255 / 0.46) 0%, rgb(255 255 255 / 0.09) 22%, transparent 42%, transparent 100%);
  transform: translateZ(2px);
  mix-blend-mode: screen;
}

/* Phone screen content, built from the app's own components */
.scr { padding: 13px 12px 0; flex: 1; display: flex; flex-direction: column; min-height: 0; }
.scr-title { font-family: var(--serif); font-size: 19px; font-weight: 600; letter-spacing: -0.02em; margin: 4px 0 2px; }
.scr-sub { font-size: 11px; color: var(--ink-2); margin: 0 0 11px; }
.scr-field {
  background: var(--card); border: 1px solid var(--rule); border-radius: 13px;
  padding: 10px 11px; box-shadow: var(--shadow-1);
}
/* The field holds either the placeholder or the word being typed. Both are one
   line at the same height, so the field never resizes and the page never
   shifts. `white-space: pre` keeps the caret against the last character. */
.scr-field-label {
  /* The placeholder is the app's own wording and needs all 32 characters to fit
     the 184px field on one line, so it sits a notch below the typed word. Both
     states are one line at the same height, so the field never resizes. */
  font-size: 11.5px; color: var(--ink-2);
  min-height: 19px; line-height: 19px; white-space: pre;
}
.scr-field-label.filled { font-size: 13.5px; color: var(--ink); font-weight: 500; }
.scr-field-label.typing::after {
  content: ''; display: inline-block; vertical-align: -2px;
  width: 1.5px; height: 13px; margin-left: 1px;
  background: var(--gold-ink);
  animation: caret 0.9s steps(1, end) infinite;
}
@keyframes caret { 0%, 55% { opacity: 1; } 56%, 100% { opacity: 0; } }
.scr-field-value { font-size: 13.5px; color: var(--ink); font-weight: 500; }
.scr-add {
  position: relative; overflow: hidden;
  margin-top: 8px; border: 1px solid var(--rule); border-radius: 10px;
  padding: 7px; text-align: center; font-size: 12px; color: var(--ink-2); background: var(--paper-2);
  transition: background-color 0.16s var(--ease), color 0.16s var(--ease),
              border-color 0.16s var(--ease), transform 0.16s var(--ease);
}
/* The tap itself. A press this small needs the colour change to read, so the
   button fills gold for the moment it is held, with one ripple out of the
   centre. Transform and opacity only, so it costs nothing. */
.scr-add.pressed {
  background: var(--gold); color: var(--on-gold);
  border-color: transparent; font-weight: 600;
  transform: scale(0.97);
}
.scr-add.pressed::after {
  content: ''; position: absolute; left: 50%; top: 50%;
  width: 120px; height: 120px; margin: -60px 0 0 -60px;
  border-radius: 999px; background: rgb(255 255 255 / 0.55);
  animation: tap 0.3s var(--ease-out) forwards;
}
@keyframes tap {
  from { transform: scale(0.1); opacity: 0.8; }
  to   { transform: scale(1);   opacity: 0; }
}
.scr-since { font-size: 9.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-3); margin: 13px 0 6px; }
.scr-row {
  background: var(--card); border: 1px solid var(--rule); border-radius: 12px;
  padding: 8px 10px; margin-top: 6px; box-shadow: var(--shadow-1);
}
.scr-row.pending { display: none; }
.scr-row.pending.on { display: block; animation: rowIn 0.45s var(--ease) both; }
@keyframes rowIn { from { opacity: 0; transform: translateY(7px); } to { opacity: 1; transform: none; } }
.scr-row-word { font-size: 13px; font-weight: 600; letter-spacing: -0.01em; }
.scr-row-meta { font-size: 10.5px; color: var(--ink-2); margin-top: 1px; }
.chip {
  display: inline-block; font-size: 9px; font-weight: 600; padding: 2px 5px;
  border-radius: 999px; background: var(--gold-soft); color: var(--gold-ink); margin-left: 5px;
  vertical-align: 1px;
}
.chip.green { background: var(--green-soft); color: var(--green); }

#scrReview:not([hidden]) { flex: 1; display: flex; flex-direction: column; min-height: 0; }
#scrCapture[hidden], #scrReview[hidden] { display: none; }
#scrCapture { min-height: 0; }
.scr-grades { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; margin-top: auto; padding-bottom: 9px; }
.scr-grade { font-size: 9.5px; font-weight: 600; text-align: center; padding: 6px 2px; border-radius: 8px; background: var(--paper-2); color: var(--ink-2); border: 1px solid var(--rule); transition: transform 0.16s var(--ease), box-shadow 0.16s var(--ease); }
.scr-grade.good { background: var(--gold); color: var(--on-gold); border-color: transparent; }
/* Answering is the other tap in the loop. Good is already gold, so the press
   reads as depth rather than colour. */
.scr-grade.pressed { transform: scale(0.94); box-shadow: 0 0 0 2px rgb(212 162 76 / 0.45); }

.scr-cal { background: var(--card); border: 1px solid var(--rule); border-radius: 13px; padding: 9px; box-shadow: var(--shadow-1); }
.scr-cal-days { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; text-align: center; }
.scr-cal-days span { font-size: 8.5px; color: var(--ink-3); }
.scr-cal-nums { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; text-align: center; margin-top: 3px; }
.scr-cal-nums b { font-size: 11px; font-weight: 500; color: var(--ink-2); padding: 3px 0; }
.scr-cal-nums b.today { color: var(--gold-ink); font-weight: 700; box-shadow: inset 0 0 0 1.5px var(--gold); border-radius: 999px; }

.scr-tabs {
  margin-top: auto; display: grid; grid-template-columns: repeat(4, 1fr);
  border-top: 1px solid var(--rule); padding: 6px 0 8px; background: var(--paper);
}
.scr-tab { text-align: center; font-size: 9px; color: var(--ink-3); display: flex; flex-direction: column; align-items: center; gap: 3px; }
.scr-tab svg { width: 14px; height: 14px; }
.scr-tab.on { color: var(--gold-ink); font-weight: 600; }

/* The sentence the word is met in */
.source {
  width: 290px; margin: -86px 0 0 -145px;
  transform: translate3d(-232px, -148px, -150px) rotateY(7deg);
  font-family: var(--serif);
  font-size: 17.5px; line-height: 1.5; color: var(--ink-2);
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 15px;
  padding: 15px 17px;
  box-shadow: var(--shadow-3);
}
.source .said { display: block; font-family: var(--sans); font-size: 9.5px; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ink-2); margin-bottom: 7px; }
.source mark {
  background: none; color: var(--ink); font-weight: 600;
  box-shadow: inset 0 -0.42em 0 rgb(212 162 76 / 0.34);
  border-radius: 2px; padding: 0 1px;
  transition: box-shadow 0.5s var(--ease), color 0.5s var(--ease);
}
.source.lifted mark { box-shadow: inset 0 -0.42em 0 rgb(212 162 76 / 0); color: var(--ink-3); }

/* The travelling card: a solid object with a front and a back */
.wordcard {
  width: 244px; height: 146px;
  margin: -73px 0 0 -122px;
  will-change: transform;
  /* The opening pose, written here as well as in the script, so the scene is
     already composed on the first paint and with no JavaScript at all. The
     script's first call sets these same values, so there is nothing to flash. */
  opacity: 0;
  transform: translate3d(-232px, -148px, -140px) rotateY(7deg) scale(0.7);
}
.face {
  position: absolute; inset: 0;
  backface-visibility: hidden;
  border-radius: 16px;
  background: var(--card);
  border: 1px solid var(--rule);
  box-shadow: var(--shadow-4);
  padding: 17px 19px;
  display: flex; flex-direction: column; justify-content: center;
}
.face-back { transform: rotateY(180deg); background: linear-gradient(160deg, #fffdf8, #f8f4ea); }
.face .word { font-family: var(--serif); font-size: 26px; font-weight: 600; letter-spacing: -0.02em; line-height: 1.1; }
.face .pos { font-size: 10.5px; color: var(--ink-2); margin-top: 5px; letter-spacing: 0.04em; }
.face .mean { font-size: 14px; color: var(--ink); line-height: 1.4; }
.face .ex { font-family: var(--serif); font-size: 12.5px; color: var(--ink-2); line-height: 1.45; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--rule); }
.face .ex b { font-weight: 600; color: var(--ink); }
/* The example is the context the word was met in, so it gets named on the card
   the same way the meaning is. */
.face .ex-label {
  display: block; font-family: var(--sans); font-size: 8.5px; font-weight: 650;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-3);
  margin-bottom: 4px;
}
.face-label { font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--gold-ink); font-weight: 650; margin-bottom: 6px; }

.due-ring {
  position: absolute; inset: -9px; border-radius: 22px;
  border: 1.5px solid var(--gold);
  opacity: 0;
  transition: opacity 0.45s var(--ease);
}
.wordcard.due .due-ring { opacity: 0.85; }

/* The deck the cards are filed into, lower left, clearly a stack */
.deck {
  width: 168px; height: 54px;
  margin: 92px 0 0 -300px;
  transform: translate3d(0, 0, -120px);
}
.deck-card {
  position: absolute; inset: 0; border-radius: 12px;
  background: var(--card); border: 1px solid var(--rule);
  box-shadow: var(--shadow-2);
  display: flex; align-items: center; padding: 0 13px;
  font-family: var(--serif); font-size: 13.5px; color: var(--ink-2);
  transition: transform 0.6s var(--ease), opacity 0.6s var(--ease);
}
.deck-label {
  position: absolute; left: 2px; top: -34px;
  font-family: var(--sans); font-size: 9.5px; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--ink-2);
}

/* Beat labels: the story in words, readable before the animation gets there */
.beats { display: flex; gap: 0; margin-top: 1.3rem; border-top: 1px solid var(--rule); list-style: none; padding: 0; }
.beats li { flex: 1; }
.beats button {
  width: 100%; text-align: left; background: none; border: 0; cursor: pointer;
  padding: 0.7rem 0.5rem 0; font-family: var(--sans); color: var(--ink-2);
  border-top: 2px solid transparent; margin-top: -1px;
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease);
}
.beats button .n { display: block; font-size: 0.66rem; letter-spacing: 0.12em; font-weight: 650; }
.beats button .t { display: block; font-size: 0.85rem; font-weight: 500; margin-top: 2px; }
.beats button[aria-current='true'] { color: var(--ink); border-top-color: var(--gold); }
.beats button:hover { color: var(--ink-2); }

/* Narrow screens get their own composition, not a shrunken wide one: the
   sentence sits above the phone, and the card files itself into the Deck tab
   instead of a separate stack there is no room for. */
@media (max-width: 940px) {
  .scene { height: 386px; perspective: 1150px; }
  .stage { --sc: 0.7; }
  .phone { height: 430px; margin-top: -215px; transform: translate3d(0, 26px, 0); }
  .source {
    width: 268px; margin-left: -134px;
    transform: translate3d(-4px, -252px, -120px) rotateY(4deg);
    font-size: 16px; padding: 13px 15px;
  }
  .deck { display: none; }
}
/* The captured word is a long word in a large serif inside a narrow grid column, and on
   a 320px screen it pushed the page sideways. Predates the logo work; found while
   checking that the new lockup had not. */
@media (max-width: 400px) {
  .beat .word { max-width: 100%; font-size: 1.15rem; padding: 0.55rem 0.75rem; gap: 0.4rem; }
  .beat .word svg { width: 15px; height: 15px; }
}

@media (max-width: 460px) {
  .scene { height: 360px; }
  .stage { --sc: 0.6; }
  /* Each label has to hold one line in a quarter of a 390px screen, so the
     labels trade a little side padding for the width two words need. */
  .beats button { padding-left: 0.2rem; padding-right: 0.2rem; }
  .beats button .t { font-size: 0.74rem; white-space: nowrap; }
  .beats button .n { font-size: 0.6rem; }
}

/* ── Sections ──────────────────────────────────────────────────────────────── */
.split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(2rem, 6vw, 5rem); align-items: center; }
@media (max-width: 900px) { .split { grid-template-columns: 1fr; gap: 2.4rem; } }

/* Names the graphic before it is read, so the 0:00 / 0:07 column is not a
   puzzle. Without this the clock reads as decoration. */
.moment-lead {
  display: flex; align-items: baseline; gap: 0.8rem;
  margin: 0 0 1.5rem; padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--rule);
  font-size: 0.76rem; letter-spacing: 0.13em; text-transform: uppercase;
}
.moment-lead span:first-child { font-weight: 650; color: var(--gold-ink); }
.moment-lead span:last-child { margin-left: auto; letter-spacing: 0.04em; text-transform: none; font-size: 0.84rem; color: var(--ink-2); }

/* The moment: one capture, in seconds. The timestamps carry the whole point,
   so they lead the row and the content hangs off a single connecting rule. */
.moment { margin: 0; }
.beat {
  display: grid;
  grid-template-columns: 3.4rem 1fr;
  column-gap: 1.15rem;
  position: relative;
  padding-bottom: 1.5rem;
}
.beat:last-child { padding-bottom: 0.2rem; }
/* The rule that joins one second to the next. */
.beat:not(:last-child)::before {
  content: '';
  position: absolute;
  left: 0.42rem; top: 1.55rem; bottom: 0.35rem;
  width: 1px; background: linear-gradient(var(--rule), var(--gold));
}
.beat .t {
  font-size: 0.78rem; font-weight: 600; color: var(--gold-ink);
  font-variant-numeric: tabular-nums; padding-top: 0.15rem;
  position: relative;
}
.beat .t::before {
  content: ''; position: absolute; left: -0.72rem; top: 0.42rem;
  width: 7px; height: 7px; border-radius: 999px;
  background: var(--paper); box-shadow: inset 0 0 0 1.5px var(--gold);
}
.beat.landed .t::before { background: var(--gold); box-shadow: none; }
.beat .b { min-width: 0; }
.beat .note { display: block; font-size: 0.85rem; color: var(--ink-2); margin-top: 0.4rem; }

.beat .said {
  font-family: var(--serif); font-size: 1.12rem; line-height: 1.45;
  color: var(--ink-2); margin: 0;
}
.beat .said mark {
  background: none; color: var(--ink); font-weight: 600;
  box-shadow: inset 0 -0.42em 0 rgb(212 162 76 / 0.34); border-radius: 2px; padding: 0 1px;
}
.beat .act {
  display: inline-flex; align-items: center; gap: 0.45rem;
  background: var(--gold); color: var(--on-gold);
  font-size: 0.86rem; font-weight: 600;
  padding: 0.42rem 0.8rem; border-radius: 10px;
  box-shadow: 0 2px 8px rgb(168 122 36 / 0.18);
}
.beat .act svg { width: 15px; height: 15px; }
.beat .word {
  display: inline-flex; align-items: center; gap: 0.6rem;
  font-family: var(--serif); font-size: 1.55rem; font-weight: 600; letter-spacing: -0.02em;
  background: var(--card); border: 1px solid var(--rule); border-radius: 14px;
  padding: 0.68rem 1.1rem; box-shadow: var(--shadow-3);
}
.beat .word svg { width: 18px; height: 18px; color: var(--green); flex: none; }
.lookup-note { font-size: 0.9rem; color: var(--ink-2); margin: 1.4rem 0 0; }

/* How it works */
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1.4rem, 3vw, 2.6rem); margin-top: 3rem; }
@media (max-width: 860px) { .steps { grid-template-columns: 1fr; gap: 2.4rem; } }
.step-n {
  font-family: var(--serif); font-size: 0.95rem; font-weight: 600; color: var(--gold-ink);
  display: flex; align-items: center; gap: 0.7rem; margin-bottom: 0.9rem;
}
.step-n::after { content: ''; flex: 1; height: 1px; background: var(--rule); }
.step p { font-size: 0.97rem; color: var(--ink-2); margin-bottom: 0; }
.step-art {
  margin-bottom: 1.2rem; border-radius: 15px; background: var(--card);
  border: 1px solid var(--rule); box-shadow: var(--shadow-2); padding: 15px;
  min-height: 168px; display: flex; flex-direction: column; justify-content: center;
}

/* Night section */
.night { background: var(--night); color: var(--night-ink); }
.night h2 { color: var(--night-ink); }
.night p { color: var(--night-ink-2); }
.night .eyebrow { color: var(--gold); }
.night .eyebrow::after { background: var(--night-rule); }
.night .btn-ghost { color: var(--night-ink); border-color: var(--night-rule); }
.night .btn-ghost:hover { background: var(--night-2); color: var(--night-ink); }
/* Where each word came from. This is what makes the deck personal, so the
   source line carries as much weight as the word itself. */
.provenance { list-style: none; margin: 2.2rem 0 0; padding: 0; }
.provenance li {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.3rem 1rem;
  padding: 0.95rem 0;
  border-bottom: 1px solid var(--night-rule);
}
.provenance li:first-child { padding-top: 0; }
.provenance .w {
  font-family: var(--serif); font-size: 1.24rem; font-weight: 600;
  letter-spacing: -0.02em; color: var(--night-ink);
}
.provenance time {
  font-size: 0.8rem; color: var(--gold);
  font-variant-numeric: tabular-nums; align-self: center;
}
.provenance .src {
  grid-column: 1 / -1;
  font-size: 0.93rem; color: var(--night-ink-2); line-height: 1.45;
}
.provenance-note { font-size: 0.88rem; color: var(--night-ink-2); margin: 1.3rem 0 0; }

/* Feature list */
.features { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; margin-top: 3rem; background: var(--rule); border: 1px solid var(--rule); border-radius: 16px; overflow: hidden; }
.feature { background: var(--paper); padding: 1.7rem 1.6rem; }
.feature h3 { font-family: var(--sans); font-size: 1rem; font-weight: 650; letter-spacing: -0.005em; }
.feature p { font-size: 0.93rem; color: var(--ink-2); margin: 0; }
.feature .ico { width: 20px; height: 20px; color: var(--gold-ink); margin-bottom: 0.85rem; }
@media (max-width: 1000px) { .features { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px)  { .features { grid-template-columns: 1fr; } }

/* FAQ */
.faq { max-width: 760px; margin-top: 2.6rem; }
.faq details { border-bottom: 1px solid var(--rule); }
.faq summary {
  cursor: pointer; list-style: none; padding: 1.25rem 2.2rem 1.25rem 0; position: relative;
  font-family: var(--serif); font-size: 1.14rem; font-weight: 600; letter-spacing: -0.01em;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ''; position: absolute; right: 6px; top: 50%; width: 10px; height: 10px;
  border-right: 1.6px solid var(--ink-2); border-bottom: 1.6px solid var(--ink-2);
  transform: translateY(-70%) rotate(45deg); transition: transform 0.25s var(--ease);
}
.faq details[open] summary::after { transform: translateY(-30%) rotate(-135deg); }
.faq .answer { padding-bottom: 1.35rem; }
.faq .answer p { font-size: 0.99rem; color: var(--ink-2); margin-bottom: 0.7rem; }
.faq .answer p:last-child { margin-bottom: 0; }

/* Closing */
.closing { text-align: center; }
.closing h2 { font-size: clamp(2.1rem, 5.2vw, 3.4rem); }
.closing p { margin-inline: auto; }
.closing .btn-row { justify-content: center; }

/* Footer */
.site-footer { border-top: 1px solid var(--rule); padding-block: 2.8rem 3.4rem; font-size: 0.9rem; color: var(--ink-2); }
.site-footer .shell { display: flex; flex-wrap: wrap; gap: 1.4rem 2.4rem; align-items: center; justify-content: space-between; }
.site-footer nav { display: flex; flex-wrap: wrap; gap: 1.4rem; }
.site-footer a { color: var(--ink-2); text-decoration: none; }
.site-footer a:hover { color: var(--ink); text-decoration: underline; }

/* ── Scroll reveal ─────────────────────────────────────────────────────────── */
/* Nothing is hidden by CSS alone. Script arms only the sections that are still
   below the fold, so with no JavaScript (or a failed script) the whole page is
   simply visible, and nothing above the fold ever flashes. */
.reveal.armed { opacity: 0; transform: translateY(14px); }
.reveal.armed.in { opacity: 1; transform: none; transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out); }

@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal.armed, .reveal.armed.in { opacity: 1; transform: none; transition: none; }
  .btn { transition: none; }
  .scr-row { transition: none; }
  /* The hero arrives already in place, and nothing in the frozen scene blinks
     or presses. */
  .hero-copy > *, .hero-cta > * { animation: none; opacity: 1; transform: none; }
  .scr-add, .scr-grade { transition: none; }
  .scr-add.pressed::after { animation: none; opacity: 0; }
  .scr-field-label.typing::after { animation: none; opacity: 1; }
}

/* ── Legal pages ───────────────────────────────────────────────────────────── */
/* Privacy and Impressum. One column, generous measure, no scene and no motion:
   somebody reading these wants to find one fact and leave. */
.legal { padding-block: clamp(2.4rem, 5vw, 4rem) clamp(4rem, 8vw, 7rem); }
.legal .shell { max-width: 46rem; }
.legal h1 { font-size: clamp(2.1rem, 5vw, 3.1rem); margin-bottom: 0.6rem; }
.legal .lede { margin-bottom: 2.6rem; }
.legal h2 {
  font-size: clamp(1.25rem, 2.4vw, 1.5rem);
  margin: 2.6rem 0 0.7rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--rule);
}
.legal h2:first-of-type { border-top: 0; padding-top: 0; }
.legal h3 { font-family: var(--sans); font-size: 1rem; font-weight: 650; margin: 1.4rem 0 0.35rem; }
.legal p, .legal li { color: var(--ink-2); font-size: 1rem; line-height: 1.65; }
.legal ul { margin: 0 0 1.1rem; padding-left: 1.15rem; }
.legal li { margin-bottom: 0.45rem; }
.legal dl { margin: 0 0 1.1rem; }
.legal dt { font-weight: 650; color: var(--ink); margin-top: 0.9rem; }
.legal dd { margin: 0.15rem 0 0; color: var(--ink-2); }
.legal .box {
  background: var(--card); border: 1px solid var(--rule); border-radius: 14px;
  padding: 1.1rem 1.25rem; margin: 0 0 1.4rem; box-shadow: var(--shadow-1);
}
.legal .box p:last-child { margin-bottom: 0; }
.legal .updated { margin-top: 3rem; font-size: 0.88rem; color: var(--ink-3); }
.legal address { font-style: normal; line-height: 1.7; color: var(--ink-2); }
