/* Palette lifted from src/theme/tokens.ts so the site and the app are the same
   product. Dark only, deliberately: the app's own identity is the dark scheme,
   and a marketing page that renders light on a phone in a dark room reads as a
   different app than the one you are about to install. */
:root {
  --ink: #0B0E14;
  --surface: #141922;
  --raised: #1B2130;
  --edge: #3A4557;
  --emulsion: #F2EDE4;
  --silver: #8A94A6;
  --safelight: #FF5C38;
  --shift: #4CC9E8;
  --measure: 62ch;
  --pad: clamp(20px, 5vw, 40px);
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

body {
  margin: 0;
  /*
    A backstop, not the fix. The masthead was overflowing at 390px and dragging
    the whole document wider than the viewport, which cut every heading on the
    page off mid-word. The masthead is fixed properly below; this is here so
    that the next element to misbehave costs a scrollbar instead of the entire
    layout.
  */
  overflow-x: hidden;
  background: var(--ink);
  color: var(--emulsion);
  font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--safelight); }
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--shift);
  outline-offset: 3px;
}

.wrap { width: min(1080px, 100% - var(--pad) * 2); margin-inline: auto; }

/* ---------------------------------------------------------------- masthead */
.mast {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 10px 16px; padding: 22px 0;
}
.mark {
  font-family: "Bricolage Grotesque", Inter, sans-serif;
  font-weight: 700; font-size: 19px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--emulsion); text-decoration: none;
  white-space: nowrap;
}
.mark span { color: var(--safelight); }
.mast nav { display: flex; flex-wrap: wrap; gap: 10px 20px; font-size: 15px; }
/*
  Below about a phone's width the two section links are the first thing to go.
  They are shortcuts to content the reader is about to scroll past anyway,
  whereas Support is the one link somebody might have come here specifically to
  find, so it stays at every size.
*/
@media (max-width: 480px) {
  .mast nav a[href^="#"] { display: none; }
}
.mast nav a { color: var(--silver); text-decoration: none; }
.mast nav a:hover { color: var(--emulsion); }

/* -------------------------------------------------------------------- hero */
.hero { display: grid; gap: clamp(32px, 6vw, 72px); padding: clamp(28px, 6vw, 64px) 0 clamp(48px, 8vw, 96px); }
@media (min-width: 880px) { .hero { grid-template-columns: 1fr 0.85fr; align-items: center; } }

h1 {
  font-family: "Bricolage Grotesque", Inter, sans-serif;
  font-weight: 700;
  font-size: clamp(42px, 7.2vw, 76px);
  line-height: 1.02;
  letter-spacing: -0.03em;
  margin: 0 0 20px;
  text-wrap: balance;
}
h1 em { font-style: normal; color: var(--safelight); }

.lede { font-size: clamp(18px, 2.2vw, 21px); color: var(--silver); max-width: 46ch; margin: 0 0 14px; }
.sub { font-size: 15px; color: var(--silver); max-width: 46ch; margin: 0 0 30px; }

.cta { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }
.btn {
  display: inline-flex; align-items: center; gap: 10px;
  background: var(--safelight); color: #1A0900;
  font-weight: 600; font-size: 16px;
  padding: 14px 26px; border-radius: 999px; text-decoration: none;
  border: 0; cursor: pointer;
}
.btn:hover { filter: brightness(1.08); }
.btn.ghost { background: transparent; color: var(--emulsion); border: 1px solid var(--edge); }
.note { font-size: 13px; color: var(--silver); }

/* ------------------------------------------------------------ phone mockup */
.phone {
  position: relative; width: min(320px, 82vw); margin-inline: auto;
  aspect-ratio: 320 / 660;
  border-radius: 46px; padding: 11px;
  background: linear-gradient(160deg, #2A3140, #0D1017);
  box-shadow: 0 40px 90px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.06);
}
.screen {
  height: 100%; border-radius: 36px; overflow: hidden;
  background: var(--ink); display: flex; flex-direction: column;
}
.screen-top { text-align: center; padding: 26px 12px 10px; }
.screen-mark { font-family: "Bricolage Grotesque", Inter, sans-serif; font-weight: 700; font-size: 13px; letter-spacing: 0.18em; }
.screen-mark span { color: var(--safelight); }
.screen-sub { font-size: 11px; color: var(--silver); margin-top: 6px; }
.card {
  flex: 1; margin: 10px 12px 0; border-radius: 20px; overflow: hidden;
  position: relative; background: var(--raised);
}
.card img { width: 100%; height: 100%; object-fit: cover; display: block; }
.verdicts { display: flex; justify-content: center; gap: 34px; padding: 16px 0 20px; }
.verdict {
  width: 54px; height: 54px; border-radius: 999px;
  display: grid; place-items: center; font-size: 24px;
  background: rgba(255,255,255,0.04);
}
.verdict.fire { border: 2px solid var(--safelight); }
.verdict.meh { border: 2px solid var(--shift); }

/* ---------------------------------------------------------------- sections */
section { padding: clamp(48px, 8vw, 96px) 0; border-top: 1px solid var(--edge); }
h2 {
  font-family: "Bricolage Grotesque", Inter, sans-serif;
  font-weight: 700; font-size: clamp(28px, 4vw, 42px);
  letter-spacing: -0.02em; line-height: 1.1; margin: 0 0 14px; text-wrap: balance;
}
.eyebrow {
  font-family: JetBrains Mono, ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--safelight); margin: 0 0 12px;
}
.section-lede { color: var(--silver); max-width: var(--measure); margin: 0 0 36px; }

.steps { display: grid; gap: 20px; counter-reset: step; }
@media (min-width: 760px) { .steps { grid-template-columns: repeat(3, 1fr); } }
.step { background: var(--surface); border: 1px solid var(--edge); border-radius: 18px; padding: 26px 24px; }
.step::before {
  counter-increment: step; content: counter(step, decimal-leading-zero);
  font-family: JetBrains Mono, ui-monospace, monospace;
  font-size: 12px; letter-spacing: 0.1em; color: var(--safelight);
  display: block; margin-bottom: 14px;
}
.step h3 { font-size: 19px; margin: 0 0 8px; font-weight: 600; }
.step p { margin: 0; color: var(--silver); font-size: 15px; }

.nots { display: grid; gap: 12px; }
@media (min-width: 620px) { .nots { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px) { .nots { grid-template-columns: repeat(3, 1fr); } }
.not {
  display: flex; align-items: center; gap: 12px;
  background: var(--surface); border: 1px solid var(--edge);
  border-radius: 14px; padding: 16px 18px; font-size: 15px; color: var(--silver);
}
.not b { color: var(--emulsion); font-weight: 600; }
.x { color: var(--safelight); font-family: JetBrains Mono, monospace; flex: none; }

.faces { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-top: 36px; }
.faces img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; border-radius: 14px; display: block; filter: saturate(0.95); }

.statgrid { display: grid; gap: 18px; }
@media (min-width: 760px) { .statgrid { grid-template-columns: 1.1fr 1fr; align-items: start; } }
.panel { background: var(--surface); border: 1px solid var(--edge); border-radius: 20px; padding: 26px; }
.bigstat {
  font-family: JetBrains Mono, ui-monospace, monospace; font-weight: 700;
  font-size: clamp(44px, 8vw, 68px); color: var(--safelight);
  line-height: 1; letter-spacing: -0.03em; font-variant-numeric: tabular-nums;
}
.bigstat + p { margin: 10px 0 0; font-size: 18px; }
.bars { display: grid; gap: 14px; margin-top: 6px; }
.bar-row { display: grid; grid-template-columns: 9ch 1fr 5ch; gap: 12px; align-items: center; font-size: 14px; }
.bar-row span:first-child { color: var(--silver); }
.bar-row span:last-child { font-family: JetBrains Mono, monospace; color: var(--emulsion); text-align: right; font-variant-numeric: tabular-nums; }
.bar { height: 8px; border-radius: 99px; background: rgba(255,255,255,0.07); overflow: hidden; }
.bar i { display: block; height: 100%; border-radius: 99px; background: var(--safelight); }

.callout {
  border-left: 3px solid var(--shift); padding: 4px 0 4px 18px;
  color: var(--silver); max-width: var(--measure); margin-top: 28px; font-size: 15px;
}
.callout b { color: var(--emulsion); font-weight: 600; }

/* ------------------------------------------------------------------ footer */
footer { border-top: 1px solid var(--edge); padding: 40px 0 60px; color: var(--silver); font-size: 14px; }
.foot { display: flex; flex-wrap: wrap; gap: 16px 28px; align-items: center; justify-content: space-between; }
.foot nav { display: flex; flex-wrap: wrap; gap: 20px; }
.foot a { color: var(--silver); text-decoration: none; }
.foot a:hover { color: var(--emulsion); }

/* -------------------------------------------------------------------- form */
.form { display: grid; gap: 18px; max-width: 620px; }
label { display: grid; gap: 7px; font-size: 14px; color: var(--silver); }
input, select, textarea {
  font: inherit; font-size: 16px; color: var(--emulsion);
  background: var(--surface); border: 1px solid var(--edge);
  border-radius: 12px; padding: 13px 14px; width: 100%;
}
textarea { min-height: 170px; resize: vertical; }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.formnote { font-size: 13px; color: var(--silver); }
.status { border-radius: 12px; padding: 14px 16px; font-size: 15px; display: none; }
.status.ok { display: block; background: rgba(76,201,232,0.10); border: 1px solid var(--shift); }
.status.bad { display: block; background: rgba(255,92,56,0.10); border: 1px solid var(--safelight); }

.faq { display: grid; gap: 14px; margin-top: 12px; }
details { background: var(--surface); border: 1px solid var(--edge); border-radius: 14px; padding: 16px 18px; }
summary { cursor: pointer; font-weight: 600; }
details p { color: var(--silver); font-size: 15px; margin: 10px 0 0; }

/* --------------------------------------------------------- the live swipe deck
   The app's sign-in deck, about three times the size.

   ONE animated card, not four. The first version ran four cards on the same
   loop with negative delays and fixed z-indexes, which cannot work: the paint
   order is static while the animation constantly changes which card is at the
   front, so the card visually in the front slot was painted behind the others
   and the stack looked scrambled.

   Here a single card takes four turns per loop, and the FACE INSIDE IT swaps
   with a step function during the moment the card is off screen and at zero
   opacity. Nothing ever cross-fades into anything, which is the other bug the
   app's own deck had: two translucent photographs on top of each other read as
   four eyes and a rendering fault, not as a transition.

   The two cards behind are decoration and never move. They are what makes it a
   deck rather than a photo. */
.deckwrap {
  display: grid; justify-items: center; gap: 34px;
  /* Generous above: the throw and the fan both need air, and the deck was
     colliding with the step cards overhead. */
  padding: clamp(48px, 8vw, 96px) 0 clamp(8px, 3vw, 24px);
  /* The thrown card travels a card and a half sideways. Without this it widens
     the document and the whole page gains a horizontal scrollbar, which is the
     one thing the layout rules here forbid outright. Clipping at the wrapper
     rather than at the deck lets the throw play out full length and disappear
     at the edge of the page, which is where it should vanish anyway. */
  overflow: hidden;
}
.deck { position: relative; width: min(330px, 74vw); aspect-ratio: 0.74; margin-bottom: 4%; }

.deck-back {
  position: absolute; inset: 0;
  border-radius: 24px; overflow: hidden;
  background: var(--raised);
  border: 1px solid var(--edge);
}
/*
  Fanned, not stacked dead centre. At 6% and 12% straight down the back cards
  sat almost entirely behind the front one and the whole thing read as a single
  floating photograph rather than a deck. A few degrees of rotation and a small
  sideways offset is what makes it obvious there are more underneath, which is
  the only job these two have.
*/
/*
  z-index 2 and 1, ABOVE the front card's resting z-index of 0, and that
  inversion is the whole fix for the flash.

  With one animated card faking a four-card deck, the thrown card has to come
  back. Reappearing on top of the stack in a spot where no card had been is a
  pop: a whole photograph materialising mid-air. It now returns to exactly b1's
  position and size while painted underneath it, so at the moment it reappears
  there is literally nothing to see, and it emerges only by growing past the
  card in front of it. That growth is what reads as the promotion.
*/
.deck-back.b1 { transform: translate(-7%, 3%) rotate(-7deg) scale(0.94); z-index: 2; }
.deck-back.b2 { transform: translate(7%, 6%) rotate(7deg) scale(0.89); z-index: 1; }

/*
  THE CARDS BEHIND CARRY FACES TOO, and that is not decoration.

  They were empty panels at first, and the moment the front card was thrown it
  left a large blank rectangle sitting in the middle of the page. A deck of
  photographs whose second card is blank does not read as a deck, it reads as
  an image that failed to load.

  Each one runs the same face cycle offset by one turn, so the card behind is
  always showing the face that is about to arrive. When the front card is
  thrown and comes back, it comes back holding exactly the face the second card
  was already showing, which is what makes the promotion look continuous.
*/
.deck-back img,
.deck-card img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; display: block;
  opacity: 0;
  /* `steps(1)` so the swap is a cut. An eased opacity here would put two faces
     on screen together, which is the exact artefact this layout avoids. */
  animation: deckface 9.6s steps(1) infinite;
}
/* One turn ahead of the front card. */
.deck-back.b1 img:nth-child(1) { animation-delay: -2.4s; }
.deck-back.b1 img:nth-child(2) { animation-delay: 0s; }
.deck-back.b1 img:nth-child(3) { animation-delay: 2.4s; }
.deck-back.b1 img:nth-child(4) { animation-delay: 4.8s; }
/* Two turns ahead, and dimmed, because depth is what it is for. */
.deck-back.b2 { opacity: 0.55; }
.deck-back.b2 img:nth-child(1) { animation-delay: -4.8s; }
.deck-back.b2 img:nth-child(2) { animation-delay: -2.4s; }
.deck-back.b2 img:nth-child(3) { animation-delay: 0s; }
.deck-back.b2 img:nth-child(4) { animation-delay: 2.4s; }

.deck-card {
  position: absolute; inset: 0;
  /* Animated in the keyframes: 0 while returning so it hides behind the stack,
     3 once it is the front card. */
  z-index: 0;
  border-radius: 24px; overflow: hidden;
  background: var(--raised);
  border: 1px solid var(--edge);
  box-shadow: 0 30px 70px rgba(0,0,0,0.55);
  animation: deckcard 9.6s linear infinite;
  will-change: transform, opacity;
}
.deck-card img:nth-child(1) { animation-delay: 0s; }
.deck-card img:nth-child(2) { animation-delay: 2.4s; }
.deck-card img:nth-child(3) { animation-delay: 4.8s; }
.deck-card img:nth-child(4) { animation-delay: 7.2s; }

.deck-marks { display: flex; gap: clamp(40px, 12vw, 90px); }
.deck-mark {
  width: 58px; height: 58px; border-radius: 999px;
  display: grid; place-items: center; font-size: 26px;
  background: rgba(255,255,255,0.04); opacity: 0.3;
}
.deck-mark.meh { border: 2px solid var(--shift); animation: deckmeh 9.6s linear infinite; }
.deck-mark.fire { border: 2px solid var(--safelight); animation: deckfire 9.6s linear infinite; }

@keyframes deckcard {
  0% { transform: translate(-7%, 3%) rotate(-7deg) scale(0.94); opacity: 1; z-index: 0; }
  5.9% { transform: translate(-7%, 3%) rotate(-7deg) scale(0.94); opacity: 1; z-index: 0; }
  7% { transform: translate(0, 0) rotate(0deg) scale(1); opacity: 1; z-index: 3; }
  16% { transform: translate(0, 0) rotate(0deg) scale(1); opacity: 1; z-index: 3; }
  19% { transform: translate(14%, 0) rotate(5deg) scale(1); opacity: 1; z-index: 3; }
  23% { transform: translate(105%, 4%) rotate(14deg) scale(1); opacity: 1; z-index: 3; }
  24.8% { transform: translate(150%, 7%) rotate(17deg) scale(1); opacity: 0; z-index: 3; }
  24.99% { transform: translate(-7%, 3%) rotate(-7deg) scale(0.94); opacity: 0; z-index: 0; }
  25% { transform: translate(-7%, 3%) rotate(-7deg) scale(0.94); opacity: 1; z-index: 0; }
  30.9% { transform: translate(-7%, 3%) rotate(-7deg) scale(0.94); opacity: 1; z-index: 0; }
  32% { transform: translate(0, 0) rotate(0deg) scale(1); opacity: 1; z-index: 3; }
  41% { transform: translate(0, 0) rotate(0deg) scale(1); opacity: 1; z-index: 3; }
  44% { transform: translate(-14%, 0) rotate(-5deg) scale(1); opacity: 1; z-index: 3; }
  48% { transform: translate(-105%, 4%) rotate(-14deg) scale(1); opacity: 1; z-index: 3; }
  49.8% { transform: translate(-150%, 7%) rotate(-17deg) scale(1); opacity: 0; z-index: 3; }
  49.99% { transform: translate(-7%, 3%) rotate(-7deg) scale(0.94); opacity: 0; z-index: 0; }
  50% { transform: translate(-7%, 3%) rotate(-7deg) scale(0.94); opacity: 1; z-index: 0; }
  55.9% { transform: translate(-7%, 3%) rotate(-7deg) scale(0.94); opacity: 1; z-index: 0; }
  57% { transform: translate(0, 0) rotate(0deg) scale(1); opacity: 1; z-index: 3; }
  66% { transform: translate(0, 0) rotate(0deg) scale(1); opacity: 1; z-index: 3; }
  69% { transform: translate(-14%, 0) rotate(-5deg) scale(1); opacity: 1; z-index: 3; }
  73% { transform: translate(-105%, 4%) rotate(-14deg) scale(1); opacity: 1; z-index: 3; }
  74.8% { transform: translate(-150%, 7%) rotate(-17deg) scale(1); opacity: 0; z-index: 3; }
  74.99% { transform: translate(-7%, 3%) rotate(-7deg) scale(0.94); opacity: 0; z-index: 0; }
  75% { transform: translate(-7%, 3%) rotate(-7deg) scale(0.94); opacity: 1; z-index: 0; }
  80.9% { transform: translate(-7%, 3%) rotate(-7deg) scale(0.94); opacity: 1; z-index: 0; }
  82% { transform: translate(0, 0) rotate(0deg) scale(1); opacity: 1; z-index: 3; }
  91% { transform: translate(0, 0) rotate(0deg) scale(1); opacity: 1; z-index: 3; }
  94% { transform: translate(14%, 0) rotate(5deg) scale(1); opacity: 1; z-index: 3; }
  98% { transform: translate(105%, 4%) rotate(14deg) scale(1); opacity: 1; z-index: 3; }
  99.8% { transform: translate(150%, 7%) rotate(17deg) scale(1); opacity: 0; z-index: 3; }
  99.99% { transform: translate(-7%, 3%) rotate(-7deg) scale(0.94); opacity: 0; z-index: 0; }
  100% { transform: translate(-7%, 3%) rotate(-7deg) scale(0.94); opacity: 1; z-index: 0; }
}

@keyframes deckface {
  0%, 24.99% { opacity: 1; }
  25%, 100% { opacity: 0; }
}

@keyframes deckfire {
  0%, 100% { opacity: 0.3; transform: scale(1); }
  16% { opacity: 0.3; transform: scale(1); }
  21% { opacity: 1; transform: scale(1.12); }
  24.8% { opacity: 0.3; transform: scale(1); }
  91% { opacity: 0.3; transform: scale(1); }
  96% { opacity: 1; transform: scale(1.12); }
  99.8% { opacity: 0.3; transform: scale(1); }
}
@keyframes deckmeh {
  0%, 100% { opacity: 0.3; transform: scale(1); }
  41% { opacity: 0.3; transform: scale(1); }
  46% { opacity: 1; transform: scale(1.12); }
  49.8% { opacity: 0.3; transform: scale(1); }
  66% { opacity: 0.3; transform: scale(1); }
  71% { opacity: 1; transform: scale(1.12); }
  74.8% { opacity: 0.3; transform: scale(1); }
}

/* Reduce Motion gets the resting state: a neat stack, the first face, both
   verdicts lit. The same rule the app itself follows. */
@media (prefers-reduced-motion: reduce) {
  .deck-card, .deck-card img, .deck-back img, .deck-mark { animation: none; }
  .deck-card { transform: none; opacity: 1; z-index: 3; }
  .deck-card img:nth-child(1) { opacity: 1; }
  .deck-back.b1 img:nth-child(2) { opacity: 1; }
  .deck-back.b2 img:nth-child(3) { opacity: 1; }
  .deck-mark { opacity: 1; }
}

/* ------------------------------------------------------------------ screens
   The App Store set, shown in the order it was designed in: Rate, then You,
   then Stats. The active tab is lit in each one, so swiping the strip traces
   the actual product flow rather than showing three unrelated pictures.

   Scrolls horizontally on a narrow screen instead of stacking, because these
   are tall portrait frames and three of them stacked is a very long page for
   very little added information. */
.screens {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: min(300px, 72vw);
  gap: clamp(14px, 2.5vw, 28px);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  padding-bottom: 14px;
  /* The section is inside `.wrap`, so bleed back out to the page edges: a
     horizontally scrolling strip that stops short of the edge looks truncated
     rather than scrollable. */
  margin-inline: calc(var(--pad) * -1);
  padding-inline: var(--pad);
  scrollbar-width: thin;
}
.screens img {
  width: 100%; height: auto; display: block;
  border-radius: 16px;
  scroll-snap-align: center;
  background: var(--ink);
}
@media (min-width: 1000px) {
  /* Enough room for all three at once, so no scrolling and no snap. */
  .screens { grid-auto-flow: row; grid-template-columns: repeat(3, 1fr); overflow: visible; margin-inline: 0; padding-inline: 0; }
}
