/* GoWing waitlist — the palette is a direct port of
   ios/GoWing/DesignSystem/Palette.swift (Nox), so the page and the app
   are literally the same colours. Lilac paper, plum ink, one amber. */

@font-face {
  font-family: "Newsreader";
  src: url("/fonts/newsreader-regular.ttf") format("truetype");
  font-weight: 400;
  font-display: swap;
}

@font-face {
  font-family: "Newsreader";
  src: url("/fonts/newsreader-semibold.ttf") format("truetype");
  font-weight: 600;
  font-display: swap;
}

@font-face {
  font-family: "Karla";
  src: url("/fonts/karla-regular.ttf") format("truetype");
  font-weight: 400;
  font-display: swap;
}

@font-face {
  font-family: "Karla";
  src: url("/fonts/karla-semibold.ttf") format("truetype");
  font-weight: 600;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Mono";
  src: url("/fonts/ibmplexmono-regular.ttf") format("truetype");
  font-weight: 400;
  font-display: swap;
}

:root {
  --paper: #eeeaf4;
  --surface: #fbfafd;
  --ink: #2b2340;
  --divider: #dcd5e8;
  --link: #6b54a8;
  --done: #e9a93a;
  --done-soft: #fbf3e2;
  --done-text: #5a4a2a;
  --sky: #dcd3ec;
  --sky-dim: #c9bde0;
  --owl: #4b3f6b;
  --owl-belly: #f3eef8;

  /* Palette.swift's textSecondary, used only *inside* the phone so the
     mockup stays true to the shipped app. */
  --mute: #6e6684;

  /* The page's own secondary text. A step darker than the app's, because
     #6e6684 on lilac only just clears 4.5:1 and this page is aimed at
     people who are already re-reading things. */
  --mute-text: #5f5876;

  /* Deliberately not one radius everywhere: a 42px device, a 12px row
     and a 10px field are three different kinds of object. */
  --radius-row: 12px;
  --radius-cta: 12px;
  --radius-field: 10px;

  /* The app's own faces, served from this binary: Karla for the body,
     Newsreader for titles and buttons, Plex Mono for the receipt.
     Nothing is downloaded from anyone else. */
  --font: "Karla", ui-sans-serif, system-ui, -apple-system, "Segoe UI",
    Roboto, Helvetica, Arial, sans-serif;
  --font-display: "Newsreader", "Iowan Old Style", "Palatino Linotype",
    Palatino, Georgia, serif;
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, "SF Mono",
    Menlo, Consolas, monospace;
}

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

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100svh;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
p,
figure,
fieldset {
  margin: 0;
}

fieldset {
  border: 0;
  padding: 0;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------------------------------------------------------------- */
/* Stage                                                             */
/* ---------------------------------------------------------------- */

/* The two flexible spacers centre the page when the window is tall
   enough, and shrink to nothing when it is not. A plain
   `justify-content: center` does the opposite of that: the phone
   overflows off the top and that part can no longer be scrolled to. */
.stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  min-height: 100svh;
  margin: 0 auto;
  padding: 28px 20px 20px;
}

.stage::before,
.stage::after {
  content: "";
  flex: 1 1 auto;
  width: 100%;
  min-height: 8px;
}

/* ---------------------------------------------------------------- */
/* Masthead: the Watcher lockup and the tagline (brand book, 04)     */
/* ---------------------------------------------------------------- */

.masthead {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 4px 16px;
  width: min(100%, 320px);
  margin-bottom: 32px;
}

.masthead__tagline {
  color: var(--mute-text);
  font-family: var(--font-display);
  font-size: 15px;
  font-style: italic;
}

/* The mark sits at 1.1× the wordmark's cap height, on its baseline. */
.lockup {
  display: inline-flex;
  align-items: center;
  gap: 0.28em;
  color: var(--ink);
  font-size: 26px;
  line-height: 1;
}

.lockup--small {
  font-size: 15px;
  color: var(--mute-text);
}

.watcher {
  width: 1.1em;
  height: 1.1em;
  flex: none;
}

.watcher__head {
  fill: var(--owl);
}

.watcher__pupil {
  fill: var(--done);
}

.wordmark {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -0.015em;
}

/* ---------------------------------------------------------------- */
/* Hero: device first, then a caption-sized pitch                    */
/* ---------------------------------------------------------------- */

.hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 40px;
  width: min(100%, 320px);
}

.pitch {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  width: 100%;
  max-width: 300px;
  text-align: left;
}

/* The moment the reader recognises, set under the headline. */
.pitch__scene {
  color: var(--owl);
  font-size: 14px;
  font-weight: 500;
  line-height: 1.5;
  text-wrap: balance;
}

.pitch__title {
  font-family: var(--font-display);
  font-size: 31px;
  font-weight: 400;
  line-height: 1.12;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

.pitch__body {
  color: var(--mute-text);
  font-size: 14.5px;
  line-height: 1.65;
  text-wrap: pretty;
}

/* The one phrase the page is actually about. */
.pitch__body em {
  color: var(--ink);
  font-style: normal;
  box-shadow: inset 0 -0.42em 0 rgb(233 169 58 / 0.32);
}

/* ---------------------------------------------------------------- */
/* Signup                                                            */
/* ---------------------------------------------------------------- */

.signup {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
  margin-top: 4px;
}

.signup__row {
  display: flex;
  gap: 6px;
}

.signup__input {
  flex: 1;
  min-width: 0;
  height: 42px;
  padding: 0 12px;
  border: 1px solid var(--divider);
  border-radius: 12px;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
}

.signup__input::placeholder {
  color: var(--mute);
}

.signup__input:focus-visible {
  border-color: var(--link);
  outline: 2px solid var(--link);
  outline-offset: -1px;
}

.signup__input[aria-invalid="true"] {
  border-color: var(--ink);
}

.signup__button {
  flex: none;
  height: 42px;
  padding: 0 18px;
  border: 0;
  border-radius: 12px;
  background: var(--ink);
  color: #ffffff;
  font: inherit;
  font-family: var(--font-display);
  font-size: 16px;
  cursor: pointer;
}

.signup__button:hover {
  background: #3d3358;
}

.signup__button:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

.signup__error {
  color: var(--ink);
  font-size: 12.5px;
}

.signup__note {
  color: var(--mute-text);
  font-size: 12.5px;
  line-height: 1.5;
}

.signup__note strong {
  color: var(--link);
  font-weight: 600;
}

/* Reads as the app's sealed receipt rather than a toast: squared off,
   one hairline, no "undo", nothing that invites a second attempt. */
.receipt {
  width: 100%;
  margin-top: 4px;
  padding: 14px 16px 16px;
  border: 1px solid var(--divider);
  border-radius: 4px;
  background: var(--surface);
}

.receipt__head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-bottom: 10px;
  border-bottom: 1px dashed var(--divider);
}

.receipt__mark {
  display: grid;
  place-items: center;
  flex: none;
  width: 20px;
  height: 20px;
  border-radius: 999px;
  background: var(--done);
  color: var(--ink);
}

.receipt__mark svg {
  width: 11px;
  height: 11px;
}

.receipt__status {
  color: var(--done-text);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* The exact string that was written to the file. */
.receipt__email {
  margin-top: 10px;
  font-family: var(--font-mono);
  font-size: 13px;
  overflow-wrap: anywhere;
}

.receipt__detail {
  margin-top: 6px;
  color: var(--mute-text);
  font-size: 13px;
  line-height: 1.55;
}

/* ---------------------------------------------------------------- */
/* Phone mockup                                                      */
/* ---------------------------------------------------------------- */

.mockup {
  display: flex;
  flex-direction: column;
  gap: 26px;
  width: 264px;
  flex: none;
}

.mockup__device {
  position: relative;
}

/* A single soft contact shadow, so the device reads as an object set
   down on the paper rather than a screenshot pasted onto it. */
.mockup__ground {
  position: absolute;
  left: 50%;
  bottom: -22px;
  width: 78%;
  height: 26px;
  transform: translateX(-50%);
  border-radius: 999px;
  background: rgb(43 35 64 / 0.22);
  filter: blur(18px);
}

.phone {
  position: relative;
  border-radius: 40px;
  padding: 9px;
  background: var(--ink);
  box-shadow: 0 28px 50px -28px rgb(43 35 64 / 0.55);
}

.phone__screen {
  overflow: hidden;
  border-radius: 32px;
  background: var(--paper);
}

.phone__home {
  display: flex;
  justify-content: center;
  padding-bottom: 8px;
}

.phone__home span {
  width: 96px;
  height: 4px;
  border-radius: 999px;
  background: rgb(43 35 64 / 0.8);
}

.statusbar {
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  height: 44px;
  padding: 0 20px 4px;
}

.statusbar__time {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.statusbar__island {
  position: absolute;
  left: 50%;
  top: 8px;
  width: 86px;
  height: 22px;
  transform: translateX(-50%);
  border-radius: 999px;
  background: var(--ink);
}

.statusbar__icons {
  display: flex;
  align-items: center;
  gap: 4px;
}

.icon-signal {
  width: 14px;
  height: 10px;
}

.icon-battery {
  width: 20px;
  height: 10px;
}

.screen {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 4px 14px 10px;
}

.screen__eyebrow {
  font-size: 10px;
  font-weight: 600;
  color: var(--link);
}

.screen__title {
  margin-top: 2px;
  font-family: var(--font-display);
  font-size: 26px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.01em;
}

/* The star scene: Nox on its branch, one star per checked item. */
.scene {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 12px;
  background: var(--sky);
}

.scene__branch {
  fill: none;
  stroke: var(--mute);
  stroke-width: 5;
  stroke-linecap: round;
}

.scene__star {
  fill: var(--done);
}

.owl__body {
  fill: var(--owl);
}

.owl__belly {
  fill: var(--owl-belly);
}

.owl__feathers {
  fill: none;
  stroke: #d5cbe4;
  stroke-width: 2;
}

.owl__white {
  fill: #ffffff;
}

.owl__amber {
  fill: var(--done);
}

.owl__feet {
  fill: none;
  stroke: var(--done);
  stroke-width: 3;
  stroke-linecap: round;
}

/* The app's one idle motion: Nox blinks every five seconds. */
.owl__eyes {
  transform-box: fill-box;
  transform-origin: center;
  animation: owl-blink 5s infinite;
}

@keyframes owl-blink {
  0%,
  95%,
  100% {
    transform: scaleY(1);
  }

  97.5% {
    transform: scaleY(0.1);
  }
}

/* Nox's speech bubble: under the scene, right-aligned, overlapping its
   bottom edge, with the small corner at the bottom right. */
/* Nox's lines share one spot under the scene; the demo shows one at a
   time. At rest it's the last one. */
.bubbles {
  position: relative;
  display: grid;
  justify-items: end;
  margin-top: -22px;
  margin-right: 8px;
}

.bubbles .bubble {
  grid-area: 1 / 1;
  opacity: 0;
}

.bubbles .bubble--5 {
  opacity: 1;
}

.bubble--left {
  align-self: flex-end;
  margin-top: -20px;
  margin-right: 8px;
}

.bubble {
  position: relative;
  padding: 5px 9px;
  border: 1px solid var(--divider);
  border-radius: 10px 10px 3px 10px;
  background: var(--surface);
  font-size: 9.5px;
  color: var(--ink);
}

.scene-wrap {
  display: flex;
  flex-direction: column;
}

.scene__slot {
  fill: none;
  stroke: var(--sky-dim);
  stroke-width: 2;
}

.scene__star {
  transform-box: fill-box;
  transform-origin: center;
}

.scene__moon {
  fill: #fff6dd;
}

.scene__moon-cut {
  fill: var(--sky);
}

.owl__happy {
  opacity: 0;
}

.owl__line {
  fill: none;
  stroke: var(--ink);
  stroke-width: 3;
  stroke-linecap: round;
}

/* Both screens share one box; "Left." slides in over the list. */
.screens {
  position: relative;
}

.screen--left {
  position: absolute;
  inset: 0;
  gap: 10px;
  background: var(--paper);
  opacity: 0;
}

.screen__title--left {
  margin-top: 4px;
}

/* The sealed receipt, in the receipt face, with dashed rules like the
   app's Left. screen. */
.slip {
  display: grid;
  gap: 4px;
  padding: 10px 12px;
  border: 1px solid var(--divider);
  border-radius: var(--radius-row);
  background: var(--surface);
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--ink);
}

.slip__row {
  display: flex;
  justify-content: space-between;
}

.slip__row--sealed {
  margin-top: 4px;
  padding-top: 7px;
  border-top: 1px dashed var(--divider);
  letter-spacing: 0.04em;
}

.screen__again {
  margin-top: auto;
  padding-bottom: 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--link);
  text-align: center;
}

.section {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.section__label {
  padding: 0 4px;
  font-size: 10px;
  color: var(--mute);
}

/* An open row; its checked twin (`.row__done`) sits on top of it and is
   faded in when the demo ticks the item. */
.row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--divider);
  border-radius: var(--radius-row);
  background: var(--surface);
}

.row__ring {
  flex: none;
  width: 22px;
  height: 22px;
  border: 1.5px solid var(--mute);
  border-radius: 999px;
}

.row__done {
  position: absolute;
  inset: -1px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 13px;
  border: 1px solid var(--divider);
  border-radius: var(--radius-row);
  background: var(--done-soft);
}

/* The fingertip: a soft ring that blooms over the check when the demo
   ticks the item. */
.row__tap {
  position: absolute;
  z-index: 1;
  left: 9px;
  top: 50%;
  width: 28px;
  height: 28px;
  margin-top: -14px;
  border-radius: 999px;
  background: rgb(43 35 64 / 0.18);
  opacity: 0;
  pointer-events: none;
}

.row__box {
  position: relative;
  display: grid;
  place-items: center;
  flex: none;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  background: var(--done);
  color: var(--ink);
}

.icon-check {
  width: 12px;
  height: 12px;
}

.row__lock {
  position: absolute;
  right: -4px;
  bottom: -2px;
  display: grid;
  place-items: center;
  width: 12px;
  height: 12px;
  border-radius: 999px;
  background: var(--surface);
  color: var(--owl);
}

.icon-lock {
  width: 6px;
  height: 6px;
}

.row__title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 13px;
  color: var(--ink);
}

.row__done .row__title {
  color: var(--done-text);
  text-decoration: line-through;
  text-decoration-color: var(--done);
}

.row__kept {
  font-size: 10px;
  font-weight: 600;
  color: var(--done-text);
}

.screen__cta {
  position: relative;
  padding: 12px 0;
  border-radius: var(--radius-cta);
  background: var(--ink);
  color: #ffffff;
  font-family: var(--font-display);
  font-size: 17px;
  text-align: center;
}

/* ---------------------------------------------------------------- */
/* The parliament: one owl on the branch per person on the list      */
/* ---------------------------------------------------------------- */

.parliament {
  display: flex;
  flex-direction: column;
  gap: 14px;
  width: min(100%, 320px);
  margin-top: 40px;
}

.parliament__count {
  color: var(--mute-text);
  font-size: 13.5px;
  text-wrap: pretty;
}

.parliament__count strong {
  color: var(--ink);
  font-family: var(--font-display);
  font-size: 1.35em;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}

.parliament__band {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

.parliament__branch {
  fill: none;
  stroke: var(--mute);
  stroke-linecap: round;
}

.parliament__branch--0 {
  stroke-width: 4.5;
}

.parliament__branch--1 {
  stroke-width: 3.5;
  opacity: 0.75;
}

.parliament__branch--2 {
  stroke-width: 3;
  opacity: 0.5;
}

.parliament__more {
  fill: var(--mute-text);
  font-family: var(--font-display);
  font-size: 16px;
}

.parliament__you rect,
.parliament__you path {
  fill: var(--ink);
}

.parliament__you text {
  fill: #ffffff;
  font-family: var(--font);
  font-size: 9px;
  font-weight: 600;
}

/* Each owl is a <use> of one of Nox's three moods; these classes colour
   it. The tones stay inside Nox's plum family, so the parliament still
   reads as one brand. */
.owl {
  --b: var(--owl);
  --bl: var(--owl-belly);
  --d: 0ms;
  animation: owl-perch 600ms cubic-bezier(0.34, 1.56, 0.64, 1) var(--d) both;
}

.owl--tone1 { --b: #5a4c80; }
.owl--tone2 { --b: #6b54a8; }
.owl--tone3 { --b: #3d3358; }
.owl--tone4 { --b: #7e6ba8; }
.owl--moon { --bl: #fff6dd; }
.owl--delay1 { --d: 150ms; }
.owl--delay2 { --d: 300ms; }
.owl--delay3 { --d: 450ms; }
.owl--delay4 { --d: 600ms; }
.owl--delay5 { --d: 750ms; }
.owl--delay6 { --d: 900ms; }
.owl--delay7 { --d: 1050ms; }

.o-body { fill: var(--b); }
.o-belly { fill: var(--bl); }
.o-white { fill: #ffffff; }
.o-amber { fill: var(--done); }

.o-feathers {
  fill: none;
  stroke: #d5cbe4;
  stroke-width: 2;
}

.o-feet {
  fill: none;
  stroke: var(--done);
  stroke-width: 3;
  stroke-linecap: round;
}

.o-line {
  fill: none;
  stroke: var(--ink);
  stroke-width: 3;
  stroke-linecap: round;
}

/* Every idle owl blinks like Nox, each on its own beat. */
.o-eyes {
  transform-box: fill-box;
  transform-origin: center;
  animation: owl-blink 5s var(--d) infinite;
}

@keyframes owl-perch {
  from {
    opacity: 0;
    translate: 0 -14px;
  }
  to {
    opacity: 1;
    translate: 0 0;
  }
}

/* ---------------------------------------------------------------- */
/* Footer                                                            */
/* ---------------------------------------------------------------- */

/* A fixed baseline at the bottom of the page. Without it the content
   is a single block floating in dead space, which is the shape every
   generated landing page has. */
.colophon {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: min(100%, 320px);
  margin-top: 28px;
  padding-top: 14px;
  color: var(--mute-text);
  font-size: 11.5px;
}


/* ---------------------------------------------------------------- */
/* Respecting the reader                                             */
/* ---------------------------------------------------------------- */

/* The only motion on this page is the owl's blink — no scroll reveals,
   no fade-ups, no counters that tick. This stops it, and the hover tint. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

@media (prefers-contrast: more) {
  :root {
    --mute-text: #4a4360;
    --divider: #c4b9d6;
  }

  .signup__input {
    border-width: 2px;
  }
}

/* The palette is lilac paper by design, so there is no dark repaint —
   but the browser is told that plainly rather than left to invert it. */
@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: light;
  }
}

/* ---------------------------------------------------------------- */
/* The demo loop                                                     */
/* ---------------------------------------------------------------- */

/* One 14s loop, CSS only (the page serves no JavaScript):
     0.0s  the list is open, Nox keeps watch
     1.4s  Stove ticked, 2.8s Windows, 4.2s Lock, 5.6s Keys:
           a tap blooms, the row turns amber, a star lights, Nox says so
     6.6s  "That's all of them. You can go."; I'm Out pulses
     8.0s  I'm Out is tapped
     8.4s  the sealed Left. receipt slides in, Nox asleep under the moon
    13.6s  back to the open list
   The three steps under the device light in step with it. The keyframes
   below are written out per element because each one switches at its own
   moment of the same loop. */
.demo .row__done,
.demo .row__tap,
.demo .scene__star,
.demo .bubbles .bubble,
.demo .owl__happy,
.demo .screen--left,
.demo .screen__cta,
.demo .step,
.demo .step__n {
  animation-duration: 14s;
  animation-iteration-count: infinite;
  animation-timing-function: ease-out;
}
.demo .row--1 .row__done { animation-name: demo-row-1; }
@keyframes demo-row-1 {
  0.00% { opacity: 0; }
  10.00% { opacity: 0; }
  12.14% { opacity: 1; }
  64.29% { opacity: 1; }
  66.43% { opacity: 0; }
  100.00% { opacity: 0; }
}
.demo .row--1 .row__tap { animation-name: demo-tap-1; }
@keyframes demo-tap-1 {
  0%, 8.21% { opacity: 0; transform: scale(0.4); }
  9.64% { opacity: 1; transform: scale(0.9); }
  13.57%, 100% { opacity: 0; transform: scale(1.6); }
}
.demo .row--2 .row__done { animation-name: demo-row-2; }
@keyframes demo-row-2 {
  0.00% { opacity: 0; }
  20.00% { opacity: 0; }
  22.14% { opacity: 1; }
  64.29% { opacity: 1; }
  66.43% { opacity: 0; }
  100.00% { opacity: 0; }
}
.demo .row--2 .row__tap { animation-name: demo-tap-2; }
@keyframes demo-tap-2 {
  0%, 18.21% { opacity: 0; transform: scale(0.4); }
  19.64% { opacity: 1; transform: scale(0.9); }
  23.57%, 100% { opacity: 0; transform: scale(1.6); }
}
.demo .row--3 .row__done { animation-name: demo-row-3; }
@keyframes demo-row-3 {
  0.00% { opacity: 0; }
  30.00% { opacity: 0; }
  32.14% { opacity: 1; }
  64.29% { opacity: 1; }
  66.43% { opacity: 0; }
  100.00% { opacity: 0; }
}
.demo .row--3 .row__tap { animation-name: demo-tap-3; }
@keyframes demo-tap-3 {
  0%, 28.21% { opacity: 0; transform: scale(0.4); }
  29.64% { opacity: 1; transform: scale(0.9); }
  33.57%, 100% { opacity: 0; transform: scale(1.6); }
}
.demo .row--4 .row__done { animation-name: demo-row-4; }
@keyframes demo-row-4 {
  0.00% { opacity: 0; }
  40.00% { opacity: 0; }
  42.14% { opacity: 1; }
  64.29% { opacity: 1; }
  66.43% { opacity: 0; }
  100.00% { opacity: 0; }
}
.demo .row--4 .row__tap { animation-name: demo-tap-4; }
@keyframes demo-tap-4 {
  0%, 38.21% { opacity: 0; transform: scale(0.4); }
  39.64% { opacity: 1; transform: scale(0.9); }
  43.57%, 100% { opacity: 0; transform: scale(1.6); }
}
.demo .scene__star--1 { animation-name: demo-star-1; }
@keyframes demo-star-1 {
  0%, 10.00% { opacity: 0; transform: scale(0) rotate(-90deg); }
  13.93% { opacity: 1; transform: scale(1.15) rotate(8deg); }
  15.71%, 64.29% { opacity: 1; transform: none; }
  66.43%, 100% { opacity: 0; transform: scale(0) rotate(-90deg); }
}
.demo .scene__star--2 { animation-name: demo-star-2; }
@keyframes demo-star-2 {
  0%, 20.00% { opacity: 0; transform: scale(0) rotate(-90deg); }
  23.93% { opacity: 1; transform: scale(1.15) rotate(8deg); }
  25.71%, 64.29% { opacity: 1; transform: none; }
  66.43%, 100% { opacity: 0; transform: scale(0) rotate(-90deg); }
}
.demo .scene__star--3 { animation-name: demo-star-3; }
@keyframes demo-star-3 {
  0%, 20.00% { opacity: 0; transform: scale(0) rotate(-90deg); }
  23.93% { opacity: 1; transform: scale(1.15) rotate(8deg); }
  25.71%, 64.29% { opacity: 1; transform: none; }
  66.43%, 100% { opacity: 0; transform: scale(0) rotate(-90deg); }
}
.demo .scene__star--4 { animation-name: demo-star-4; }
@keyframes demo-star-4 {
  0%, 30.00% { opacity: 0; transform: scale(0) rotate(-90deg); }
  33.93% { opacity: 1; transform: scale(1.15) rotate(8deg); }
  35.71%, 64.29% { opacity: 1; transform: none; }
  66.43%, 100% { opacity: 0; transform: scale(0) rotate(-90deg); }
}
.demo .scene__star--5 { animation-name: demo-star-5; }
@keyframes demo-star-5 {
  0%, 40.00% { opacity: 0; transform: scale(0) rotate(-90deg); }
  43.93% { opacity: 1; transform: scale(1.15) rotate(8deg); }
  45.71%, 64.29% { opacity: 1; transform: none; }
  66.43%, 100% { opacity: 0; transform: scale(0) rotate(-90deg); }
}
.demo .bubbles .bubble--0 { animation-name: demo-bubble-0; }
@keyframes demo-bubble-0 {
  0.00% { opacity: 1; }
  10.00% { opacity: 1; }
  12.14% { opacity: 0; }
  97.14% { opacity: 0; }
  99.29% { opacity: 1; }
  100.00% { opacity: 1; }
}
.demo .bubbles .bubble--1 { animation-name: demo-bubble-1; }
@keyframes demo-bubble-1 {
  0.00% { opacity: 0; }
  10.00% { opacity: 0; }
  12.14% { opacity: 1; }
  20.00% { opacity: 1; }
  22.14% { opacity: 0; }
  100.00% { opacity: 0; }
}
.demo .bubbles .bubble--2 { animation-name: demo-bubble-2; }
@keyframes demo-bubble-2 {
  0.00% { opacity: 0; }
  20.00% { opacity: 0; }
  22.14% { opacity: 1; }
  30.00% { opacity: 1; }
  32.14% { opacity: 0; }
  100.00% { opacity: 0; }
}
.demo .bubbles .bubble--3 { animation-name: demo-bubble-3; }
@keyframes demo-bubble-3 {
  0.00% { opacity: 0; }
  30.00% { opacity: 0; }
  32.14% { opacity: 1; }
  40.00% { opacity: 1; }
  42.14% { opacity: 0; }
  100.00% { opacity: 0; }
}
.demo .bubbles .bubble--4 { animation-name: demo-bubble-4; }
@keyframes demo-bubble-4 {
  0.00% { opacity: 0; }
  40.00% { opacity: 0; }
  42.14% { opacity: 1; }
  47.14% { opacity: 1; }
  49.29% { opacity: 0; }
  100.00% { opacity: 0; }
}
.demo .bubbles .bubble--5 { animation-name: demo-bubble-5; }
@keyframes demo-bubble-5 {
  0.00% { opacity: 0; }
  47.14% { opacity: 0; }
  49.29% { opacity: 1; }
  64.29% { opacity: 1; }
  66.43% { opacity: 0; }
  100.00% { opacity: 0; }
}
.demo .owl__happy { animation-name: demo-happy; }
@keyframes demo-happy {
  0.00% { opacity: 0; }
  10.00% { opacity: 0; }
  12.14% { opacity: 1; }
  15.00% { opacity: 1; }
  17.14% { opacity: 0; }
  20.00% { opacity: 0; }
  22.14% { opacity: 1; }
  25.00% { opacity: 1; }
  27.14% { opacity: 0; }
  30.00% { opacity: 0; }
  32.14% { opacity: 1; }
  35.00% { opacity: 1; }
  37.14% { opacity: 0; }
  40.00% { opacity: 0; }
  42.14% { opacity: 1; }
  45.00% { opacity: 1; }
  47.14% { opacity: 0; }
  100.00% { opacity: 0; }
}
.demo .screen--left { animation-name: demo-left; }
@keyframes demo-left {
  0.00% { opacity: 0; transform: translateX(24px); }
  60.00% { opacity: 0; transform: translateX(24px); }
  62.14% { opacity: 1; transform: none; }
  97.14% { opacity: 1; transform: none; }
  99.29% { opacity: 0; transform: translateX(24px); }
  100.00% { opacity: 0; transform: translateX(24px); }
}
.demo .screen__cta { animation-name: demo-cta; }
@keyframes demo-cta {
  0%, 47.14% { box-shadow: 0 0 0 0 rgb(233 169 58 / 0); transform: none; background: var(--ink); }
  49.64% { box-shadow: 0 0 0 5px rgb(233 169 58 / 0.55); }
  52.14% { box-shadow: 0 0 0 0 rgb(233 169 58 / 0); }
  54.64% { box-shadow: 0 0 0 5px rgb(233 169 58 / 0.55); }
  56.79% { box-shadow: 0 0 0 0 rgb(233 169 58 / 0); transform: none; background: var(--ink); }
  58.00% { transform: scale(0.95); background: #4b3f6b; }
  60.00%, 100% { transform: none; background: var(--ink); }
}
.demo .step--1 { animation-name: demo-step-1; }
@keyframes demo-step-1 {
  0.00% { opacity: 1; }
  47.14% { opacity: 1; }
  49.29% { opacity: 0.38; }
  100.00% { opacity: 0.38; }
}
.demo .step--1 .step__n { animation-name: demo-step-n-1; }
@keyframes demo-step-n-1 {
  0.00% { background-color: var(--done); border-color: var(--done); }
  47.14% { background-color: var(--done); border-color: var(--done); }
  49.29% { background-color: var(--surface); border-color: var(--divider); }
  100.00% { background-color: var(--surface); border-color: var(--divider); }
}
.demo .step--2 { animation-name: demo-step-2; }
@keyframes demo-step-2 {
  0.00% { opacity: 0.38; }
  47.14% { opacity: 0.38; }
  49.29% { opacity: 1; }
  60.00% { opacity: 1; }
  62.14% { opacity: 0.38; }
  100.00% { opacity: 0.38; }
}
.demo .step--2 .step__n { animation-name: demo-step-n-2; }
@keyframes demo-step-n-2 {
  0.00% { background-color: var(--surface); border-color: var(--divider); }
  47.14% { background-color: var(--surface); border-color: var(--divider); }
  49.29% { background-color: var(--done); border-color: var(--done); }
  60.00% { background-color: var(--done); border-color: var(--done); }
  62.14% { background-color: var(--surface); border-color: var(--divider); }
  100.00% { background-color: var(--surface); border-color: var(--divider); }
}
.demo .step--3 { animation-name: demo-step-3; }
@keyframes demo-step-3 {
  0.00% { opacity: 0.38; }
  60.00% { opacity: 0.38; }
  62.14% { opacity: 1; }
  100.00% { opacity: 1; }
}
.demo .step--3 .step__n { animation-name: demo-step-n-3; }
@keyframes demo-step-n-3 {
  0.00% { background-color: var(--surface); border-color: var(--divider); }
  60.00% { background-color: var(--surface); border-color: var(--divider); }
  62.14% { background-color: var(--done); border-color: var(--done); }
  100.00% { background-color: var(--done); border-color: var(--done); }
}

/* The three steps under the device. At rest (and with reduced motion)
   all three read at full strength. */
.steps ol {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.step {
  display: grid;
  justify-items: center;
  gap: 6px;
  color: var(--ink);
  font-size: 12px;
  line-height: 1.3;
  text-align: center;
  text-wrap: balance;
}

.step__n {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border: 1px solid var(--divider);
  border-radius: 999px;
  background: var(--surface);
  font-weight: 600;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

/* With reduced motion the demo holds its resting frame: everything
   ticked, five stars, "You can go." */
@media (prefers-reduced-motion: reduce) {
  .demo *,
  .demo *::after {
    animation: none !important;
  }
}

/* ---------------------------------------------------------------- */
/* Computer screens: the whole page fits the window, no scrolling    */
/* ---------------------------------------------------------------- */

/* The page is mobile first: everything above is the phone layout, which
   scrolls. From 860px wide the page becomes one screen. The stage is a
   grid exactly the height of the window: masthead on top, the device on
   the left, the pitch and the parliament stacked on the right, the
   footer at the bottom. The hero box dissolves (`display: contents`) so
   the device and the pitch can sit in the same grid as the parliament.
   Everything that has height scales with the window's height, and the
   device steps down on shorter screens, so a 13-inch laptop sees the
   whole page too. */
@media (min-width: 860px) {
  .stage {
    display: grid;
    grid-template-columns: auto minmax(0, 540px);
    grid-template-rows: auto 1fr 1fr auto;
    grid-template-areas:
      "mast  mast"
      "phone pitch"
      "phone owls"
      "foot  foot";
    column-gap: clamp(48px, 7vw, 120px);
    justify-content: center;
    align-items: center;
    max-width: 1140px;
    height: 100svh;
    min-height: 600px;
    padding: clamp(16px, 3.5svh, 40px) 48px clamp(12px, 2.5svh, 28px);
  }

  .stage::before,
  .stage::after {
    display: none;
  }

  .hero {
    display: contents;
  }

  .masthead,
  .colophon,
  .parliament {
    width: auto;
  }

  .masthead {
    grid-area: mast;
    align-self: start;
    margin-bottom: clamp(12px, 3svh, 36px);
  }

  .mockup {
    grid-area: phone;
    width: auto;
    align-items: center;
  }

  /* Only the device scales with the window height; the steps under it
     keep a readable size. */
  .mockup__device {
    width: 280px;
  }

  .steps {
    width: max(100%, 250px);
  }

  .pitch {
    grid-area: pitch;
    align-self: end;
    width: auto;
    max-width: none;
    gap: clamp(10px, 1.8svh, 18px);
  }

  .pitch__scene {
    font-size: clamp(14px, 1.8svh, 16px);
  }

  .pitch__title {
    font-size: clamp(30px, 4.8svh, 50px);
  }

  .pitch__body {
    max-width: 60ch;
    font-size: clamp(14.5px, 1.9svh, 17px);
  }

  .parliament {
    grid-area: owls;
    align-self: start;
    margin-top: clamp(16px, 3.5svh, 40px);
    gap: clamp(6px, 1.2svh, 14px);
  }

  .parliament__band {
    height: clamp(84px, 18svh, 180px);
  }

  .colophon {
    grid-area: foot;
    align-self: end;
    align-items: center;
    margin-top: clamp(8px, 2svh, 24px);
    padding-top: 0;
  }
}

/* The device is ~620px tall at full size; on shorter windows it steps
   down so it never pushes the footer below the fold. */
@media (min-width: 860px) and (max-height: 860px) {
  .mockup__device {
    zoom: 0.86;
  }
}

@media (min-width: 860px) and (max-height: 760px) {
  .mockup__device {
    zoom: 0.74;
  }
}

@media (min-width: 860px) and (max-height: 670px) {
  .mockup__device {
    zoom: 0.64;
  }

  /* The pitch runs five lines; tighten it rather than scroll. */
  .pitch {
    gap: 8px;
  }

  .pitch__title {
    font-size: 28px;
    line-height: 1.08;
  }

  .pitch__body {
    line-height: 1.5;
  }
}

/* A large monitor: the device, the lockup and the form grow too. */
@media (min-width: 1100px) and (min-height: 860px) {
  .mockup__device {
    width: 300px;
  }

  .lockup {
    font-size: 32px;
  }

  .lockup--small {
    font-size: 16px;
  }

  .masthead__tagline {
    font-size: 18px;
  }

  .signup__input,
  .signup__button {
    height: 50px;
  }

  .signup__input {
    font-size: 16px;
  }

  .signup__button {
    padding: 0 26px;
    font-size: 18px;
  }

  .signup__note,
  .parliament__count {
    font-size: 15px;
  }
}
