/* Colour tokens (landing feature 8). Values from the product's Wildwood palette
   in frontend/app/globals.css, plus --night and --error. Every colour in this file
   is one of these; no hex, rgb() or named colour appears outside :root. */
:root {
  --paper: #fcf7ee;
  --page: #f9f1e3;
  --ink: #3a2e2a;
  --bark: #6b5744;
  --ember: #b85c28;
  --ember-pressed: #96471e;
  --ember-ink: #8a5a2a;
  --lantern: #ffd88a;
  --night: #221a20;
  --night-text: #fcf7ee;
  --dusk-soft: #e0d0d4;
  --moss: #3f6b3a;
  --error: #a3271f;
  --rule: #ecdfc9;
  --fold: #f3e2c7;
  --on-ember: #ffffff;
  --night-veil: rgba(34,26,32,0.6);
  --lantern-glow: rgba(255,216,138,0.28);

  /* Spacing scale (px). */
  --space-4: 4px;
  --space-8: 8px;
  --space-12: 12px;
  --space-16: 16px;
  --space-24: 24px;
  --space-32: 32px;
  --space-48: 48px;
  --space-64: 64px;
  --space-96: 96px;

  /* Section padding top and bottom, and the text column width: phone values;
     tablet (600 px) and laptop (900 px) below. */
  --section-pad: 48px;
  --measure: 36ch;
}
@media (min-width: 600px) {
  :root { --section-pad: 72px; }
}
@media (min-width: 900px) {
  :root { --section-pad: 96px; --measure: 62ch; }
}

/* Typefaces (landing feature 7). Files in /fonts, latin subset; see fonts/README.txt.
   The two upright files are cut down by scripts/build-fonts.sh: Fraunces wght
   600-650 with SOFT fixed at 100, Literata wght 400-600 with opsz fixed at 12.
   The Fraunces italic file is cut too (landing feature 11 step 12): wght
   400-600, SOFT fixed at 100; it is not preloaded. */
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 600 650;
  font-display: swap;
  src: url(/fonts/fraunces-var.8768866a.woff2) format('woff2');
}
@font-face {
  font-family: 'Fraunces';
  font-style: italic;
  font-weight: 400 600;
  font-display: swap;
  src: url(/fonts/fraunces-var-italic.00e7f9fa.woff2) format('woff2');
}
@font-face {
  font-family: 'Literata';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url(/fonts/literata-var.827e8170.woff2) format('woff2');
}
@font-face {
  font-family: 'Literata';
  font-style: italic;
  font-weight: 200 900;
  font-display: swap;
  src: url(/fonts/literata-var-italic.07cc4f2b.woff2) format('woff2');
}
/* Only the digits 5-9 on the age chips. */
@font-face {
  font-family: 'Andika';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/fonts/andika-700.6b73917d.woff2) format('woff2');
  unicode-range: U+0035-0039;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-size: 1.0625rem;
  line-height: 1.5;
  font-family: 'Literata', Georgia, serif;
  font-weight: 400;
  font-variation-settings: 'opsz' 12, 'wght' 400;
}

h1, h2, .wordmark, .age-label, button {
  font-family: 'Fraunces', Georgia, 'Times New Roman', serif;
}

h1 {
  font-weight: 600;
  font-variation-settings: 'opsz' 144, 'SOFT' 100, 'wght' 600;
}

h2 {
  font-style: italic;
  font-weight: 500;
  font-variation-settings: 'opsz' 72, 'SOFT' 100, 'wght' 500;
}

.wordmark {
  font-weight: 650;
  font-variation-settings: 'opsz' 36, 'wght' 650;
  letter-spacing: 0.02em;
}

label {
  font-weight: 600;
  font-variation-settings: 'opsz' 12, 'wght' 600;
}

.age-digit {
  font-family: 'Andika', 'Comic Sans MS', sans-serif;
  font-weight: 700;
  font-variation-settings: normal;
}

section {
  padding-block: var(--section-pad);
}

p {
  max-width: var(--measure);
}

a {
  color: var(--ember-ink);
}

/* Pictures (landing feature 9). Each <img> carries its width and height; the
   layout features (10-20) size them further. */
img {
  display: block;
  max-width: 100%;
  height: auto;
}

/* Hero plate: full width; on phone the crop keeps the lit door and the
   figure with the lantern in frame. Height from landing feature 10 step 1;
   --hero-h is shared with the lantern glow layer (landing feature 21). */
.title-page {
  --hero-h: clamp(180px, 34svh, 300px);
}
.hero {
  width: 100%;
  height: var(--hero-h);
  object-fit: cover;
  object-position: 70% 75%;
}

/* Title page (landing feature 10): the plate, the wordmark over its top-left
   corner, then a paper panel whose torn top edge overlaps the plate by 14 px.
   On / the wordmark is in the <header> landmark before <main> (landing
   feature 32 step 1); the plate starts at the top-left of the page, so the
   header is placed over it, above the title page (z-index 1: the title page
   is positioned and comes later, so it would otherwise cover the header).
   On /thanks the wordmark is inside the title page. */
.title-page {
  position: relative;
}
.site-header,
.title-page .wordmark {
  position: absolute;
  top: 16px;
  left: 16px;
}
.site-header {
  z-index: 1;
}
.site-header .wordmark,
.title-page .wordmark {
  margin: 0;
  font-size: 20px;
  line-height: 1.2;
  color: var(--night-text);
  text-shadow: 0 1px 2px var(--night-veil);
}
.title-panel {
  position: relative;
  background: var(--paper);
  padding: var(--space-12) var(--space-16) var(--space-32);
}
/* The deckle: an irregular line 14 px tall, drawn as an SVG mask over a
   paper-coloured strip, so its colour comes from the token. The SVG is a
   file, not a data: URL, because the Content-Security-Policy's img-src
   allows 'self' only (landing feature 34 step 2). */
.title-panel::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: -14px;
  height: 14px;
  background: var(--paper);
  -webkit-mask: url(/img/deckle.113cbb0c.svg) repeat-x 0 0 / 240px 14px;
  mask: url(/img/deckle.113cbb0c.svg) repeat-x 0 0 / 240px 14px;
}
/* The ad-matched line (landing feature 17): added above the <h1> by the
   inline script in index.html when utm_content names S3, T1, A5 or P1. */
.ad-line {
  margin: 0 0 8px;
  font-family: 'Fraunces', Georgia, 'Times New Roman', serif;
  font-style: italic;
  font-size: 1rem;
  color: var(--ember-pressed);
}
.title-panel h1 {
  margin: 0;
  font-size: clamp(1.75rem, 1.2rem + 2.6vw, 3.25rem);
  line-height: 1.08;
  color: var(--ink);
  text-align: left;
  max-width: 18ch;
}
.title-panel h1 + p {
  margin: 12px 0 0;
  font-size: 1.0625rem;
  line-height: 1.5;
  color: var(--ink);
  max-width: 34ch;
}
.title-panel .cta-note {
  margin: 10px 0 0;
  font-size: 0.875rem;
  color: var(--bark);
}

/* The 'Sign up for beta' button: a bookmark ribbon with its right end notched. */
.cta {
  display: block;
  width: 100%;
  min-height: 56px;
  margin-top: 20px;
  padding: 0 34px 0 24px;
  border: 0;
  border-radius: 4px;
  background: var(--ember);
  color: var(--on-ember);
  font-size: 1.125rem;
  font-weight: 600;
  font-variation-settings: 'wght' 600;
  cursor: pointer;
  clip-path: polygon(0 0, 100% 0, calc(100% - 14px) 50%, 100% 100%, 0 100%);
}
.cta:hover,
.cta:active {
  background: var(--ember-pressed);
}
/* Pressed: down 1 px, at once; no bounce (landing feature 21 step 4). */
.cta:active {
  transform: translateY(1px);
}
/* clip-path cuts anything drawn outside the box, so the focus ring is drawn
   inside it: a 2 px night ring at the edge, 3 px lantern inside that. */
.cta:focus-visible {
  outline: 3px solid var(--lantern);
  outline-offset: -5px;
  box-shadow: inset 0 0 0 2px var(--night);
}

/* Chapter one (landing feature 11): the label, the title, one paragraph, the
   story shelf and the line naming the other stories, on the page colour. */
.chapter-one {
  background: var(--page);
  padding-inline: var(--space-16);
}
.chapter-label {
  margin: 0;
  font-family: 'Fraunces', Georgia, 'Times New Roman', serif;
  font-weight: 600;
  font-variation-settings: 'wght' 600;
  font-variant-caps: small-caps;
  font-size: 0.8125rem;
  letter-spacing: 0.12em;
  color: var(--ember-pressed);
}
.chapter-one h2 {
  margin: var(--space-4) 0 0;
  font-size: clamp(1.5rem, 1.1rem + 1.8vw, 2.25rem);
  line-height: 1.15;
  color: var(--ink);
}
.chapter-one h2 + p {
  margin: var(--space-12) 0 var(--space-24);
}

/* The shelf: a row of story plates that scrolls sideways and snaps to each
   item's start. Touch and the arrow keys scroll it; there are no buttons.
   The wrapping div is the focusable region and the scroller, so the <ul>
   keeps its list role (landing feature 11 step 7). */
.shelf {
  padding: 0 0 var(--space-8);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
}
.shelf ul {
  display: flex;
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.shelf:focus-visible {
  outline: 3px solid var(--lantern);
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--night);
}
.shelf li {
  flex: 0 0 78vw;
  max-width: 320px;
  scroll-snap-align: start;
}
.shelf img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
}
.story-interest {
  margin: var(--space-8) 0 0;
  font-size: 0.8125rem;
  color: var(--bark);
}
.story-title {
  margin: 0;
  font-family: 'Fraunces', Georgia, 'Times New Roman', serif;
  font-style: italic;
  font-weight: 500;
  font-variation-settings: 'SOFT' 100, 'wght' 500;
  font-size: 1.125rem;
  line-height: 1.3;
  color: var(--ink);
}
.story-summary {
  margin: var(--space-4) 0 0;
  font-size: 0.875rem;
  color: var(--ink);
}
.shelf-more {
  margin: var(--space-16) 0 0;
  max-width: var(--measure);
  font-size: 0.875rem;
  color: var(--bark);
}

/* Chapter two (landing feature 12): the night page. The evening plate runs
   full width at the top and meets the night colour at a straight edge; then
   the label, the title, one paragraph with a three-line drop cap, and three
   numbered notes. */
.chapter-two {
  padding-top: 0;
  background: var(--night);
  color: var(--night-text);
}
.evening {
  width: 100%;
}
.chapter-two-text {
  padding: var(--space-32) var(--space-16) 0;
}
.chapter-two .chapter-label {
  color: var(--lantern);
}
.chapter-two h2 {
  margin: var(--space-4) 0 0;
  font-size: clamp(1.5rem, 1.1rem + 1.8vw, 2.25rem);
  line-height: 1.15;
  color: var(--night-text);
}
.chapter-two .drop-cap {
  margin: var(--space-12) 0 0;
}
/* The drop cap sinks three lines. Browsers with initial-letter size and place
   it themselves; others float a letter sized to three lines of the body. */
.drop-cap::first-letter {
  float: left;
  margin: 0.07em var(--space-8) 0 0;
  font-family: 'Fraunces', Georgia, 'Times New Roman', serif;
  font-style: normal;
  font-weight: 600;
  font-variation-settings: 'wght' 600;
  font-size: 4.3em;
  line-height: 0.8;
  color: var(--lantern);
}
@supports (initial-letter: 3) or (-webkit-initial-letter: 3) {
  .drop-cap::first-letter {
    float: none;
    margin: 0 var(--space-8) 0 0;
    font-size: inherit;
    line-height: inherit;
    -webkit-initial-letter: 3;
    initial-letter: 3;
  }
}
.notes {
  max-width: var(--measure);
  margin: var(--space-24) 0 0;
  padding-left: 1.75em;
  color: var(--dusk-soft);
  font-size: 0.9375rem;
}
.notes li + li {
  margin-top: var(--space-8);
}
.notes li::marker {
  font-family: 'Fraunces', Georgia, 'Times New Roman', serif;
  font-weight: 600;
  font-variation-settings: 'wght' 600;
  color: var(--lantern);
}

/* Chapter three (landing feature 13): prose on the paper page with one pulled
   line in Fraunces italic and a thin ember rule at its left. */
.chapter-three {
  background: var(--paper);
  padding-inline: var(--space-16);
}
.chapter-three h2 {
  margin: var(--space-4) 0 0;
  font-size: clamp(1.5rem, 1.1rem + 1.8vw, 2.25rem);
  line-height: 1.15;
  color: var(--ink);
}
.chapter-three h2 + p {
  margin: var(--space-12) 0 0;
}
.pull {
  margin: var(--space-24) 0 0;
  padding-left: var(--space-16);
  border-left: 2px solid var(--ember);
  font-family: 'Fraunces', Georgia, 'Times New Roman', serif;
  font-style: italic;
  font-weight: 500;
  font-variation-settings: 'opsz' 72, 'SOFT' 100, 'wght' 500;
  font-size: 1.375rem;
  line-height: 1.3;
  color: var(--ember-pressed);
}

/* Chapter four (landing feature 14): the label, the title and one paragraph
   on the page colour. */
.chapter-four {
  background: var(--page);
  padding-inline: var(--space-16);
}
.chapter-four h2 {
  margin: var(--space-4) 0 0;
  font-size: clamp(1.5rem, 1.1rem + 1.8vw, 2.25rem);
  line-height: 1.15;
  color: var(--ink);
}
.chapter-four h2 + p {
  margin: var(--space-12) 0 0;
}

/* For you (landing feature 15): what the parent controls and sees, set like
   the notes at the back of a book: a definition list with a 1 px rule between
   the items. */
.for-you {
  background: var(--paper);
  padding-inline: var(--space-16);
}
.for-you h2 {
  margin: var(--space-4) 0 0;
  font-size: clamp(1.5rem, 1.1rem + 1.8vw, 2.25rem);
  line-height: 1.15;
  color: var(--ink);
}
.for-you-notes {
  margin: var(--space-24) 0 0;
  max-width: var(--measure);
}
.for-you-notes > div {
  padding-block: var(--space-16);
}
.for-you-notes > div + div {
  border-top: 1px solid var(--rule);
}
.for-you-notes dt {
  font-family: 'Fraunces', Georgia, 'Times New Roman', serif;
  font-weight: 600;
  font-variation-settings: 'wght' 600;
  font-size: 1.0625rem;
  line-height: 1.3;
}
.for-you-notes dd {
  margin: var(--space-4) 0 0;
}

/* The closing page (landing feature 16): a colophon on the paper, set
   centred: the two Captain portraits side by side on the paper itself (their
   backgrounds are transparent), the title, one line and the same button. */
.closing {
  background: var(--paper);
  padding-inline: var(--space-16);
  text-align: center;
}
.captains {
  display: flex;
  justify-content: center;
}
.captains img {
  width: 120px;
}
.closing h2 {
  margin: var(--space-24) 0 0;
  font-size: clamp(1.5rem, 1.1rem + 1.8vw, 2.25rem);
  line-height: 1.15;
  color: var(--ink);
}
.closing h2 + p {
  margin: var(--space-12) auto 0;
}
/* Full width of the text column on phone, as on the title page; from 600 px
   only as wide as its text. */
.closing .cta {
  max-width: var(--measure);
  margin-inline: auto;
}
@media (min-width: 600px) {
  .closing .cta {
    display: inline-block;
    width: auto;
  }
}

/* Footer (landing feature 16 step 5): centred like the closing page above
   it, on the page colour under a 1 px rule: the wordmark, then the privacy
   policy and the contact address side by side (wrapping onto two lines on a
   narrow phone), then the company line. */
.site-footer {
  padding: var(--space-32) var(--space-16);
  background: var(--page);
  border-top: 1px solid var(--rule);
  color: var(--bark);
  font-size: 0.8125rem;
  line-height: 1.5;
  text-align: center;
}
.site-footer > * {
  max-width: none;
}
.site-footer p {
  margin: 0;
}
.site-footer .wordmark {
  font-size: 1.0625rem;
  color: var(--ink);
}
.site-footer .footer-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  column-gap: var(--space-24);
  margin-top: var(--space-4);
}
.site-footer .footer-links + p {
  margin-top: var(--space-4);
}
.site-footer a {
  color: inherit;
}
/* Links inside a line of text (the footer's, and the consent sentence's on
   the ruled rows) get their 44 px target (landing feature 32 step 2) from
   padding above and below the words, which leaves the lines' spacing as it
   is. Positioned, the link is on top of the line under it, so a tap there
   lands on the link. The focus ring is drawn on the words (the inner
   <span>), not round the padding, so it does not cover the line above. */
.site-footer a,
.consent a {
  position: relative;
  white-space: nowrap;
}
.site-footer a {
  padding-block: 12.5px;
}
.consent a {
  padding-block: 10.5px;
}
.site-footer a:focus-visible,
.consent a:focus-visible {
  outline: none;
}
.site-footer a:focus-visible > span,
.consent a:focus-visible > span {
  outline: 3px solid var(--lantern);
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--night);
}

/* The sticky bottom bar (landing feature 18): under 900 px, the same button
   at full width on the night colour, fixed to the bottom of the screen.
   js/sticky-bar.js adds .is-shown once the title page's button has scrolled
   off screen and removes it when the closing page's button is in view. It
   slides up over 200 ms and is hidden at once; hidden, it is out of the tab
   order and the accessibility tree. */
.sticky-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 10;
  padding: 10px 16px calc(10px + env(safe-area-inset-bottom, 0px));
  background: var(--night);
  transform: translateY(100%);
  visibility: hidden;
}
.sticky-bar.is-shown {
  transform: none;
  visibility: visible;
  transition: transform 200ms ease-out;
}
.sticky-bar .cta {
  min-height: 52px;
  margin-top: 0;
}
@media (prefers-reduced-motion: reduce) {
  .sticky-bar,
  .sticky-bar.is-shown {
    transition: none;
  }
}
@media (min-width: 900px) {
  .sticky-bar {
    display: none;
  }
}

/* Tablet layout (landing feature 19), 600-899 px: 32 px side padding; the
   text column is at most 560 px wide and set at the left, not centred. The
   title page's plate is taller and its button only as wide as its text (at
   least 260 px); shelf items are 300 px wide; Chapter two puts the evening
   plate and the text side by side. */
@media (min-width: 600px) and (max-width: 899.98px) {
  :root { --measure: 560px; }
  .title-page {
    --hero-h: clamp(280px, 42svh, 420px);
  }
  .title-panel,
  .chapter-one,
  .chapter-three,
  .chapter-four,
  .for-you,
  .closing,
  .site-footer {
    padding-inline: var(--space-32);
  }
  .title-panel > *,
  .chapter-one > :not(.shelf),
  .chapter-two-text > *,
  .chapter-three > *,
  .chapter-four > *,
  .for-you > *,
  .site-footer > * {
    box-sizing: border-box;
    max-width: var(--measure);
  }
  /* The closing page keeps its text centred, inside the same left-set column:
     the section itself is the column (its paper matches the body's). */
  .closing {
    max-width: var(--measure);
  }
  .title-panel .cta,
  .closing .cta {
    display: inline-block;
    width: auto;
    min-width: 260px;
  }
  .shelf li {
    flex-basis: 300px;
  }
  .chapter-two {
    display: grid;
    grid-template-columns: 1fr 1fr;
    padding-block: 0;
  }
  .evening {
    height: 100%;
    object-fit: cover;
  }
  .chapter-two-text {
    padding: var(--section-pad) var(--space-32);
  }
}

/* Laptop layout (landing feature 20), 900 px and up. The title page is an
   open book spread: the hero plate fills the left page (58%), the paper page
   with the title text is on the right (42%), with a 1 px rule between them
   and a 12 px band of --fold down the right page's inside edge. Later
   sections lay their content on a 12-column grid at most 1120 px wide,
   centred on the page; each section's background still runs edge to edge.
   Chapter one, three and For you put their text in columns 2-7; Chapter two
   and four take the other side, text in 6-11, and Chapter two's plate in
   1-5. Chapter one's plates are the shelf, a full-width row under its text:
   all five items in one row once the grid is 948 px or wider, scrolling and
   snapping below that. */
@media (min-width: 900px) {
  .title-page {
    display: grid;
    grid-template-columns: 58% 42%;
  }
  .title-page {
    --hero-h: clamp(560px, 100svh, 900px);
  }
  .hero {
    grid-column: 1;
    grid-row: 1;
  }
  .title-panel {
    grid-column: 2;
    grid-row: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;
    padding: var(--space-64) 56px;
    border-left: 1px solid var(--rule);
    box-shadow: inset 12px 0 0 var(--fold);
  }
  .title-panel::before {
    display: none;
  }
  .title-panel .cta,
  .closing .cta {
    display: inline-block;
    width: auto;
    min-width: 260px;
  }

  .chapter-one,
  .chapter-two,
  .chapter-three,
  .chapter-four,
  .for-you {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--space-24);
    align-content: start;
    padding-block: var(--section-pad);
    padding-inline: max(var(--space-32), calc((100% - 1120px) / 2));
  }
  .closing,
  .site-footer {
    padding-inline: max(var(--space-32), calc((100% - 1120px) / 2));
  }
  .chapter-one > *,
  .chapter-three > *,
  .for-you > * {
    grid-column: 2 / 8;
  }
  .chapter-four > * {
    grid-column: 6 / 12;
  }
  .chapter-one > .shelf,
  .chapter-one > .shelf-more {
    grid-column: 1 / -1;
  }
  .shelf li {
    flex: 0 0 calc((100% - 4 * 12px) / 5);
    min-width: 180px;
    max-width: none;
  }
  .evening {
    grid-column: 1 / 6;
    grid-row: 1;
    align-self: center;
  }
  .chapter-two-text {
    grid-column: 6 / 12;
    grid-row: 1;
    padding: 0;
  }
}

/* The sign-up sheet (landing feature 22): one <dialog id="signup"> opened
   with showModal(), styled as a library card on the paper colour, with a
   1 px rule-coloured border. Under 600 px it sits at the bottom of the
   screen, full width, with square corners, at most 92svh tall and scrolling
   inside; from 600 px it is centred, 440 px wide. Its position does not use
   transform, which the opening motion (landing feature 21 step 3) animates.
   js/signup-sheet.js adds .sheet-open to <html> while it is open, so the
   page behind does not scroll. */
#signup {
  --sheet-row: 24px;
  box-sizing: border-box;
  inset: auto 0 0 0;
  margin: 0;
  width: 100%;
  max-width: 100%;
  max-height: 92svh;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--space-12) var(--space-16) calc(var(--space-24) + env(safe-area-inset-bottom, 0px));
  border: 1px solid var(--rule);
  border-radius: 0;
  background: var(--paper);
  color: var(--ink);
}
#signup::backdrop {
  background: var(--night-veil);
}
html.sheet-open {
  overflow: hidden;
}
@media (min-width: 600px) {
  #signup {
    inset: 0;
    margin: auto;
    width: 440px;
    max-height: calc(100svh - var(--space-48));
    padding: var(--space-16) var(--space-24) var(--space-24);
  }
}
.sheet-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-12);
}
/* The title, set like a library stamp: Fraunces small caps inside a 1.5 px
   ember rectangle. The rectangle is an inset shadow: Chromium rounds a 1.5 px
   border down to 1 px. */
#signup h2 {
  margin: var(--space-8) 0 0;
  padding: 4px 10px;
  box-shadow: inset 0 0 0 1.5px var(--ember);
  font-style: normal;
  font-weight: 600;
  font-variation-settings: 'opsz' 36, 'wght' 600;
  font-variant-caps: small-caps;
  font-size: 1.25rem;
  line-height: 1.2;
  letter-spacing: 0.04em;
  color: var(--ember-pressed);
}
/* 'Close': a text button with a 44x44 px target at the top right. */
.sheet-close {
  flex: none;
  min-width: 44px;
  min-height: 44px;
  margin-right: calc(-1 * var(--space-8));
  padding: 0 var(--space-8);
  border: 0;
  background: transparent;
  color: var(--ember-ink);
  font-family: 'Literata', Georgia, serif;
  font-size: 1rem;
  font-weight: 600;
  font-variation-settings: 'opsz' 12, 'wght' 600;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.sheet-close:hover {
  color: var(--ember-pressed);
}
.sheet-close:focus-visible,
.sheet-form input:focus-visible {
  outline: 3px solid var(--lantern);
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--night);
}
.sheet-intro {
  margin: var(--space-12) 0 0;
  line-height: var(--sheet-row);
}
/* Ruled lines one row apart behind the fields: the labels sit on them and
   each field row is a whole number of rows tall. */
.sheet-form {
  margin-top: var(--sheet-row);
  line-height: var(--sheet-row);
  background-image: repeating-linear-gradient(to bottom, transparent 0 calc(var(--sheet-row) - 1px), var(--rule) calc(var(--sheet-row) - 1px) var(--sheet-row));
}
.sheet-form .field {
  padding-bottom: var(--sheet-row);
}
.sheet-form label {
  display: block;
  font-size: 0.9375rem;
  line-height: var(--sheet-row);
}
.sheet-form input[type="text"],
.sheet-form input[type="email"],
.sheet-form input[type="tel"] {
  display: block;
  box-sizing: border-box;
  width: 100%;
  height: calc(2 * var(--sheet-row));
  margin: 0;
  padding: 0 var(--space-12);
  border: 1px solid var(--bark);
  border-radius: 2px;
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  font-size: 1.0625rem;
}

/* Landing feature 23: the fields. Labels, hints and errors are one row
   each line, inputs and the age chips two rows, so every field row stays a
   whole number of rows on the ruled lines. */
.sheet-form fieldset {
  min-width: 0;
  margin: 0;
  padding: 0 0 var(--sheet-row);
  border: 0;
}
.sheet-form legend {
  padding: 0;
  font-size: 0.9375rem;
  font-weight: 600;
  font-variation-settings: 'opsz' 14, 'wght' 600;
  line-height: var(--sheet-row);
}
.tel {
  position: relative;
}
/* The fixed +91 at the field's left edge; the input's text starts after it. */
.tel-prefix {
  position: absolute;
  left: var(--space-12);
  top: 0;
  line-height: calc(2 * var(--sheet-row));
  font-size: 1.0625rem;
  color: var(--bark);
  pointer-events: none;
}
.sheet-form input[type="tel"] {
  padding-left: 48px;
}
.field-hint,
.field-error {
  margin: 0;
  font-size: 0.9375rem;
  line-height: var(--sheet-row);
}
.field-hint {
  color: var(--bark);
}
.field-error {
  color: var(--error);
  font-weight: 600;
  font-variation-settings: 'opsz' 12, 'wght' 600;
}
/* An invalid field: a 3 px error-coloured left border. */
.sheet-form input[aria-invalid="true"] {
  border-left: 3px solid var(--error);
  padding-left: calc(var(--space-12) - 2px);
}
.sheet-form input[type="tel"][aria-invalid="true"] {
  padding-left: 46px;
}
/* For the age chips and the consent row the border sits in the sheet's side
   padding, so the chips keep their full row at 320 px. */
.ages.is-invalid .chips,
.consent.is-invalid {
  margin-left: -11px;
  padding-left: var(--space-8);
  border-left: 3px solid var(--error);
}
/* Child's age: six 44x44 px chips in one row. The radio covers its chip, so
   a tap or a click lands on the radio itself and the arrow keys move between
   them. */
.chips {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-4);
  max-width: 324px;
  height: calc(2 * var(--sheet-row));
}
.sheet-form .chip {
  position: relative;
  display: block;
  flex: none;
  width: 44px;
  height: 44px;
}
.chip input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.chip span {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  border: 1px solid var(--bark);
  border-radius: 10px;
  background: var(--paper);
  color: var(--ink);
  line-height: 1;
  pointer-events: none;
}
.chip .age-digit {
  font-size: 1.25rem;
}
.chip .age-other {
  font-size: 0.8125rem;
  font-weight: 600;
  font-variation-settings: 'opsz' 12, 'wght' 600;
}
.chip input:hover + span {
  border-color: var(--ember);
}
.chip input:checked + span {
  border-color: var(--ember);
  background: var(--ember);
  color: var(--on-ember);
}
.chip input:focus-visible + span {
  outline: 3px solid var(--lantern);
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--night);
}
/* Consent: the box beside the sentence, the error under both. */
/* The row's space below is a margin, so an invalid row's border stops at
   the error line. */
.consent {
  display: grid;
  grid-template-columns: 24px 1fr;
  column-gap: var(--space-12);
}
.sheet-form .consent {
  padding-bottom: 0;
  margin-bottom: var(--sheet-row);
}
.sheet-form .consent label {
  font-weight: 600;
}
.consent input {
  width: 20px;
  height: 20px;
  margin: 2px 0 0;
  accent-color: var(--ember);
  cursor: pointer;
}
.consent .field-error {
  grid-column: 1 / -1;
}
.consent a {
  color: var(--ember-ink);
}
/* The honeypot (landing feature 5 step 1): off-screen, out of the Tab order
   and hidden from screen readers. */
.hp {
  position: absolute;
  left: -10000px;
}
/* The submit button and the line under it sit on plain paper below the
   ruled rows. */
.sheet-actions {
  padding-top: var(--space-8);
  background: var(--paper);
}
.sheet-actions .cta {
  margin-top: 0;
}
/* While the form is being sent (landing feature 24): the button keeps its
   colours, so its text keeps its contrast, and does not darken on hover. */
.sheet-actions .cta:disabled {
  background: var(--ember);
  cursor: default;
  transform: none;
}
/* A rate-limit, server or network failure (landing feature 24 steps 4 and
   5): one line above the submit button. */
.form-error {
  margin: 0 0 var(--space-8);
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--error);
  font-weight: 600;
  font-variation-settings: 'opsz' 12, 'wght' 600;
}
.sheet-note {
  margin: 10px 0 0;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--bark);
}
/* The thank-you and repeat states (landing feature 25), in place of the
   intro and the form: a hand-drawn moss tick, the heading, one line of text
   and a Close button. */
.sheet-done {
  margin-top: var(--space-24);
}
.sheet-done .tick {
  display: block;
  width: 40px;
  height: 36px;
  fill: none;
  stroke: var(--moss);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.sheet-done h3 {
  margin: var(--space-12) 0 0;
  font-family: 'Fraunces', Georgia, 'Times New Roman', serif;
  font-style: italic;
  font-weight: 500;
  font-variation-settings: 'opsz' 72, 'SOFT' 100, 'wght' 500;
  font-size: 1.5rem;
  line-height: 1.25;
  color: var(--ink);
}
/* The heading takes focus from the script only (tabindex="-1"). */
.sheet-done h3:focus {
  outline: none;
}
.done-text {
  margin: var(--space-8) 0 0;
  line-height: 1.5;
}
.done-close {
  margin-top: var(--space-24);
}

/* Motion (landing feature 21). Only transform and opacity are animated.
   Lantern glow: a layer over the hero plate, a soft lantern-coloured circle
   over the lit door that brightens and dims over 4 s. */
.title-page::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: var(--hero-h);
  background: radial-gradient(circle at 70% 72%, var(--lantern-glow), transparent 18%);
  pointer-events: none;
  animation: lantern-glow 4s ease-in-out infinite;
}
/* From 900 px the plate is the left page, 58% wide. */
@media (min-width: 900px) {
  .title-page::after {
    width: 58%;
  }
}
@keyframes lantern-glow {
  0%, 100% { opacity: 0.6; }
  50% { opacity: 1; }
}

/* Chapter reveal: js/motion.js adds .reveal to <html> and .is-revealed to a
   chapter once 15% of it is in view; its title and first paragraph then rise
   8 px and fade in over 320 ms. Without JavaScript nothing is hidden. */
@media (prefers-reduced-motion: no-preference) {
  .reveal :is(.chapter-one, .chapter-two, .chapter-three, .chapter-four) :is(h2, h2 + p) {
    opacity: 0;
    transform: translateY(8px);
  }
  .reveal .is-revealed :is(h2, h2 + p) {
    opacity: 1;
    transform: none;
    transition: opacity 320ms ease-out, transform 320ms ease-out;
  }
}

/* The sign-up sheet (<dialog id="signup">, landing feature 22) opening: on
   phone it slides up from the bottom; from 600 px it fades in and grows from
   0.98. */
#signup[open] {
  animation: sheet-up 240ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
@keyframes sheet-up {
  from { transform: translateY(100%); }
}
@media (min-width: 600px) {
  #signup[open] {
    animation: sheet-in 180ms ease-out;
  }
}
@keyframes sheet-in {
  from { opacity: 0; transform: scale(0.98); }
}

/* The done state's tick fades in and grows from 0.9 over 400 ms; under
   reduced motion it is simply shown. */
@media (prefers-reduced-motion: no-preference) {
  .sheet-done:not([hidden]) .tick {
    animation: tick-in 400ms ease-out;
  }
}
@keyframes tick-in {
  from { opacity: 0; transform: scale(0.9); }
}

@media (prefers-reduced-motion: reduce) {
  .title-page::after,
  #signup[open] {
    animation: none;
  }
}

/* Landing feature 26: without JavaScript. The 'Sign up for beta' controls
   are links to the form (js/enhance.js turns them into buttons), set like
   the button. The form sits at the end of the closing page until
   js/enhance.js moves it into the sheet. There it shows only as the URL's
   target (#signup-form: each of those links, and the server's error page),
   so with JavaScript it is never drawn, nor its fonts loaded, before the move. */
a.cta {
  box-sizing: border-box;
  font-family: 'Fraunces', Georgia, 'Times New Roman', serif;
  line-height: 56px;
  text-align: center;
  text-decoration: none;
}
.closing .sheet-form:not(:target) {
  display: none;
}
.closing .sheet-form {
  --sheet-row: 24px;
  max-width: 408px;
  margin: var(--space-48) auto 0;
  text-align: left;
}
.closing .sheet-actions .cta {
  display: block;
  width: 100%;
  min-width: 0;
  max-width: none;
}

/* /thanks (landing feature 26): the title page's plate and panel, with the
   thank-you or repeat text and a link back to the page. */
.back-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-top: var(--space-16);
  font-weight: 600;
  font-variation-settings: 'opsz' 12, 'wght' 600;
}
.back-link:focus-visible {
  outline: 3px solid var(--lantern);
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--night);
}

/* /privacy (landing feature 27): the wordmark linking to /, then the policy
   in one column on the paper colour, and the landing page's footer. */
.policy-head {
  padding: var(--space-16);
  background: var(--page);
  border-bottom: 1px solid var(--rule);
}
.policy-head .wordmark {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 20px;
  line-height: 1.2;
  color: var(--ink);
  text-decoration: none;
}
.policy-head .wordmark:focus-visible {
  outline: 3px solid var(--lantern);
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--night);
}
.policy {
  max-width: var(--measure);
  margin: 0 auto;
  padding: var(--space-32) var(--space-16) var(--section-pad);
  overflow-wrap: anywhere;
}
.policy h1 {
  margin: 0 0 var(--space-8);
  font-size: clamp(1.75rem, 1.2rem + 2.6vw, 3.25rem);
  line-height: 1.15;
}
.policy-updated {
  margin: 0 0 var(--space-32);
  color: var(--bark);
  font-size: 0.875rem;
}
.policy h2 {
  margin: var(--space-32) 0 var(--space-8);
  font-size: 1.375rem;
  line-height: 1.25;
}
.policy p {
  margin: 0 0 var(--space-12);
}
