/*
  Wordhoard's site.

  Plain CSS, no build step, no framework, no fonts fetched from anywhere. That last one is not
  minimalism for its own sake: this site's whole argument is that the app does not send your
  reading anywhere, and a page that phones a font CDN to say so is a page that has quietly told
  Google which privacy policy you were reading. The faces below are served from `fonts/`,
  converted from the very cuts in `Wordhoard/Resources/Fonts` that the app draws with.

  The palette is the app's, taken from `Wordhoard/Design/WordhoardTheme.swift`. When one moves
  the other has to.
*/

@font-face {
  font-family: "Newsreader"; src: url("fonts/newsreader-regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Newsreader"; src: url("fonts/newsreader-lightitalic.woff2") format("woff2");
  font-weight: 300; font-style: italic; font-display: swap;
}
@font-face {
  font-family: "Archivo"; src: url("fonts/archivo-regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Archivo"; src: url("fonts/archivo-medium.woff2") format("woff2");
  font-weight: 500 600; font-style: normal; font-display: swap;
}

:root {
  /* The app's palette, from `WordhoardTheme.swift`. It was warm — #F7F1E9 and a brown ink —
     and the app moved to slate; these pages were the last thing still wearing the old one,
     which made the privacy policy look like a different company's. */
  --ink:      #1D2226;
  --ink-2:    rgba(29, 34, 38, .62);
  --ink-3:    rgba(29, 34, 38, .45);
  --paper:    #EDF1F4;
  --surface:  #F9FBFC;
  --line:     rgba(29, 34, 38, .14);
  --soft:     #DDE3E8;
  --accent:   #B4460F;
  --accent-2: #8F3709;

  --measure: 1120px;
  --radius: 20px;

  /*
    Hero tuning, as variables rather than numbers buried in gradients.

    They are here so `site-tools/editor.html` can move them live against the real page and hand
    back a block that pastes straight into this file. Every one of these was previously arrived
    at by editing a gradient, reloading, and squinting — which is a slow way to make a decision
    that takes two seconds to judge and no time at all to get wrong.

    The values are exactly what the page had before they were named; naming them changed
    nothing on screen.
  */
  --hero-height: 100svh;   /* how much of the first screen the photograph takes */
  --hero-focus-x: 50%;     /* which part of the photo survives the crop, across */
  --hero-focus-y: 50%;     /* and down */
  --scrim-left: 0.84;      /* darkening under the headline; mid and outer stops derive from it */
  --scrim-top: 0.58;       /* the band that carries the floating header */
  --scrim-flat: 0.16;      /* an even wash over everything — the expensive one, see below */
  --card-glass: 0.66;      /* how dark the glass cards are */
  --cards-x: 62%;          /* where the card cluster sits across the frame */
  --rail-alpha: 0.66;      /* the Look up / Review / Library rail */

  /* The app's own two faces. Newsreader carries headings and headwords — a word being defined
     should look like a word in a dictionary rather than like interface text — and Archivo
     carries everything else. Georgia and the system sans stay as the fallback, so a blocked
     font request degrades to what this file used to ship rather than to nothing. */
  --serif: Newsreader, Georgia, "Iowan Old Style", "Times New Roman", serif;
  --sans: Archivo, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation: none !important; transition: none !important; }
}

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

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

a { color: var(--accent); }
a:hover { color: var(--accent-2); }

/* ── Header ──────────────────────────────────────────────────────────────── */

.top {
  position: sticky;
  top: 0;
  z-index: 40;
  background: rgba(237, 241, 244, 0.86);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}

.top .wrap {
  display: flex;
  align-items: center;
  gap: 20px;
  height: 66px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--ink);
  text-decoration: none;
}

/* The magpie, as on the homepage. The line-drawn book that used to sit here was a
   different mark from the one on the app icon, which is the one people will have
   tapped to get here. */
.brand img { width: 26px; height: 26px; border-radius: 7px; display: block; }
.brand svg { width: 24px; height: 24px; display: block; }

.top nav {
  display: flex;
  gap: 24px;
  margin-left: auto;
  font-size: 15px;
}

.top nav a { color: var(--ink-2); text-decoration: none; }
.top nav a:hover { color: var(--ink); }

/*
  On a page with a hero, the header floats on the photograph instead of sitting in a bar above
  it. That is the whole of what makes the first screen read as one image rather than as a strip
  of furniture and then a picture.

  Scoped with `:has()` so it applies to exactly the pages that have a hero. Privacy, terms and
  support keep the solid bar, and they must: a transparent header over those pages is dark text
  on cream at best and white text on cream at worst. Doing this with a `home` class on `<body>`
  would work too and would rot the first time a page was added without it; `:has()` asks the
  document what it contains rather than trusting a label.

  Browsers without `:has()` fall back to the solid sticky header — the old design, which is
  correct and merely less striking. Nothing breaks.

  It is `absolute`, not `sticky`. The two cannot be reconciled without script: a transparent
  header that stays put would be white-on-cream the moment it scrolled over the page below, and
  `check.mjs` fails the build if a `<script>` appears on these pages. So the header scrolls away
  with the hero, which is what the bench did.
*/
body:has(.hero) .top {
  position: absolute;
  left: 0;
  right: 0;
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-bottom: none;
}

/* A shadow as well as the gradient behind them. The gradient handles the general case; the
   shadow is what keeps these legible if the photograph is ever replaced by a lighter one, and
   costs nothing when it is not needed. */
body:has(.hero) .top .brand,
body:has(.hero) .top nav a { text-shadow: 0 1px 10px rgba(0,0,0,0.55); }

body:has(.hero) .top .brand { color: #fff; }
body:has(.hero) .top nav a { color: rgba(255,255,255,0.86); }
body:has(.hero) .top nav a:hover { color: #fff; }

/* The pill was ink-on-cream, which on a photograph reads as a hole. White on the picture is
   what the bench used and it is also the app's own primary button. */
body:has(.hero) .top .button {
  background: var(--surface);
  color: var(--ink);
}

.button {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 11px 20px;
  border-radius: 999px;
  background: var(--ink);
  color: var(--surface);
  font-size: 15px;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
}

.button:hover { background: #2c2620; color: var(--surface); }

.button.quiet {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--line);
}

.button.quiet:hover { background: var(--soft); color: var(--ink); }

/* ── Type ────────────────────────────────────────────────────────────────── */

/* Newsreader, like the app and like the homepage. Weight 400 because that is the only
   upright cut served — asking for 500 gets a synthesised bold, which on a text face
   reads as a smudge rather than as emphasis. */
h1, h2, h3 { font-family: var(--serif); letter-spacing: -0.025em; line-height: 1.12; margin: 0; font-weight: 400; }

h1 { font-size: clamp(38px, 5.2vw, 62px); }
h2 { font-size: clamp(27px, 3.2vw, 38px); }
h3 { font-size: 19px; letter-spacing: -0.015em; }

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

.lead {
  font-size: clamp(17px, 1.5vw, 20px);
  line-height: 1.55;
  color: var(--ink-2);
  max-width: 58ch;
}

.eyebrow {
  display: inline-block;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 14px;
}

.muted { color: var(--ink-3); }
.small { font-size: 14.5px; }

section { padding: 76px 0; }
section + section { border-top: 1px solid var(--line); }

.head { max-width: 62ch; margin-bottom: 40px; }

/* ── Hero ────────────────────────────────────────────────────────────────── */

.hero {
  position: relative;
  padding: 0;
  border-top: 0;
  overflow: hidden;
  background: #17140f;
}

/*
  The first screen is the photograph, edge to edge — 78vh capped at 820px meant that on most
  laptops you landed on a hero with the next section already peeking under it, which reads as a
  band rather than as an image.

  `svh` rather than `vh`, and this matters on phones specifically. `100vh` is the viewport with
  the browser's address bar *hidden*, so a hero set to it is taller than the screen on landing
  and its bottom edge sits behind the bar. `100svh` is the smallest viewport — bar showing —
  so the hero fits at the moment somebody arrives, which is the moment being designed for.
  `dvh` would track the bar as it hides and reveals, and reflow the whole hero while scrolling.

  The `vh` line above it is the fallback for browsers that do not know `svh`; they get the old
  behaviour of a slightly over-tall hero, which is what everybody had before `svh` existed.
*/
.hero .stage {
  position: relative;
  min-height: 620px;
  height: 100vh;
  height: var(--hero-height);
  display: flex;
  align-items: center;
}

.hero img.photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--hero-focus-x) var(--hero-focus-y);
}

/*
  The scrim does one job: make white text legible without burying the photograph.

  The flat layer used to be 0.30, which suited a dark photo that needed only a little help.
  The picture here is pale — cream paper, white table — and its subject is small black letters,
  so a flat wash costs more than it buys: every point of it greys down exactly the detail that
  makes the photo worth having. It is 0.16 now, and the left-hand gradient does the work
  instead, which is where the headline is and nowhere else.
*/
.hero .scrim {
  position: absolute;
  inset: 0;
  background:
    /* One knob, three stops. The mid and outer stops are derived rather than named so that
       dragging `--scrim-left` keeps the shape of the falloff instead of flattening it — the
       ratios 0.45 and 0.05 are the ones the hand-tuned version had. */
    linear-gradient(90deg,
      rgba(12,10,8, var(--scrim-left)) 0%,
      rgba(12,10,8, calc(var(--scrim-left) * 0.45)) 46%,
      rgba(12,10,8, calc(var(--scrim-left) * 0.05)) 72%),
    /* The top band carries the header now that it floats on the photograph rather than sitting
       in its own bar. 0.42 was enough when it only had to soften an edge; the navigation lands
       on the lit page, which is the brightest thing in the frame, and needed more. */
    linear-gradient(180deg, rgba(12,10,8, var(--scrim-top)) 0%, rgba(12,10,8,0) 24%),
    rgba(12, 10, 8, var(--scrim-flat));
}

.hero .wrap { position: relative; z-index: 2; }
.hero h1, .hero .lead { color: #fff; }
/* 46ch when the hero held one card against the right edge. The cluster sits further in, and at
   46ch the last words of each line ran underneath it — not wrapped early, overlapped, which
   reads as a rendering fault rather than a layout choice. */
.hero .lead { color: rgba(255,255,255,0.76); max-width: 38ch; }
/* The chip from the bench, scoped to the hero on purpose: `.eyebrow` is also the small caps
   above every section heading further down the page, and making that rule a pill would put a
   glass capsule on five headings that want a plain word. */
.hero .eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 7px 15px 7px 9px;
  border-radius: 999px;
  background: rgba(255,255,255,0.13);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid rgba(255,255,255,0.16);
  color: #fff;
  font-weight: 500;
  letter-spacing: 0.09em;
}

.hero .eyebrow i {
  width: 22px; height: 22px;
  border-radius: 7px;
  background: rgba(255,255,255,0.22);
  display: grid; place-items: center;
  font-style: normal; font-size: 12px;
}

.hero .actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 32px; }
.hero .button { background: var(--surface); color: var(--ink); }
.hero .button:hover { background: #fff; }

.hero .button.quiet {
  background: rgba(255,255,255,0.10);
  color: #fff;
  border-color: rgba(255,255,255,0.26);
}

.hero .button.quiet:hover { background: rgba(255,255,255,0.18); }

/*
  The card cluster, ported from `site-tools/hero-test.html` where it was designed.

  Three cards rather than one, and the order is the argument: the word, then the sentence it
  was met in, then what is waiting today. Look it up, keep the context, come back to it.

  ## Dark glass, where the bench used light

  The bench's cards are `rgba(255,255,255,0.16)` — light panes, which is right over the dark
  frame it was tuned against. This photograph is pale paper and a white table, and a 16%-white
  pane over that is a pane over nothing, with white text landing on cream. So the glass is
  tinted dark here instead. It is the one deliberate departure from the bench, it is forced by
  the photograph rather than preferred, and it happens to look more like the app, whose cards
  sit on a dark ground anyway.

  The solid card keeps the bench's paper colour exactly. It is the only place on the hero where
  the app's own cream appears, and it is what stops the whole thing reading as generic dark
  glass over a stock photo.
*/
.hero .cards {
  position: absolute;
  left: var(--cards-x);
  top: 50%;
  transform: translate(-50%, -50%);
  width: 340px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  z-index: 3;
}

/* 0.66, not the 0.56 this started at. Glass takes its legibility from whatever is behind it,
   and this photograph is not evenly lit: a pane that reads well over the spilled letters goes
   milky over the lit page above them, which is exactly where the headword sits. The tint has to
   carry the text on the brightest thing in the frame, not the average. */
.hero .card {
  padding: 20px 22px;
  border-radius: 22px;
  background: rgba(20, 17, 13, var(--card-glass));
  backdrop-filter: blur(26px) saturate(1.2);
  -webkit-backdrop-filter: blur(26px) saturate(1.2);
  border: 1px solid rgba(255,255,255,0.16);
  box-shadow: 0 18px 50px rgba(0,0,0,0.30);
  color: #fff;
}

.hero .card .card-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
}

.hero .card .word { font-family: var(--serif); font-size: 30px; line-height: 1.1; letter-spacing: -0.01em; }
.hero .card .phon { margin-top: 3px; font-size: 13px; color: rgba(255,255,255,0.62); }

.hero .card .pos {
  margin-top: 14px; font-size: 11.5px; letter-spacing: 0.08em;
  text-transform: uppercase; color: rgba(255,255,255,0.55);
}

.hero .card .def { margin-top: 6px; font-size: 15.5px; line-height: 1.45; color: rgba(255,255,255,0.94); }

/* The mastery ring: one number, read at a glance, that says the thing is working. */
.hero .ring { width: 54px; height: 54px; flex: none; }
.hero .ring circle { fill: none; stroke-width: 4; }
.hero .ring .track { stroke: rgba(255,255,255,0.20); }
.hero .ring .fill { stroke: #fff; stroke-linecap: round; }
.hero .ring text {
  fill: #fff; font-size: 15px; font-weight: 600;
  text-anchor: middle; dominant-baseline: central; font-family: var(--sans);
}

.hero .card .rule { height: 1px; margin: 18px 0 14px; background: rgba(255,255,255,0.16); }

.hero .card .meta {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 13px; color: rgba(255,255,255,0.62);
}
.hero .card .meta b { color: #fff; font-weight: 500; }

.hero .card .label {
  font-size: 11.5px; letter-spacing: 0.09em;
  text-transform: uppercase; color: rgba(255,255,255,0.55);
}

.hero .card .quote {
  margin-top: 12px; padding-left: 14px;
  border-left: 2px solid rgba(255,255,255,0.30);
  font-family: var(--serif); font-style: italic; font-size: 16px; line-height: 1.5;
  color: rgba(255,255,255,0.94);
}

.hero .card .source { margin-top: 12px; font-size: 12.5px; color: rgba(255,255,255,0.58); }

.hero .card.solid {
  background: var(--surface);
  border-color: rgba(0,0,0,0.06);
  color: var(--ink);
  display: flex; align-items: center; gap: 16px;
  padding: 16px 20px;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.hero .card.solid .n { font-size: 27px; font-weight: 600; letter-spacing: -0.02em; line-height: 1; }
.hero .card.solid .t { margin-top: 3px; font-size: 13.5px; color: var(--ink-3); }

.hero .card.solid .go {
  margin-left: auto;
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--accent);
  display: grid; place-items: center;
  color: #fff; font-size: 16px;
}

/* The app's three places, standing where a phone's tab bar would. Decoration, not navigation.

   The bench had this at 45% white with no shadow, which is right over a dark frame and vanishes
   over this one — the rail lands on the palest part of the photograph, the white table. Raised
   and given a shadow so it survives there. It is still the quietest thing in the hero, which is
   the point; quiet and absent are different. */
.hero .rail {
  position: absolute;
  right: 54px;
  top: 50%;
  transform: translateY(-50%);
  display: flex; flex-direction: column; align-items: flex-end; gap: 16px;
  z-index: 3;
  font-size: 17px;
  color: rgba(255,255,255, var(--rail-alpha));
  text-shadow: 0 1px 12px rgba(0,0,0,0.55);
}

.hero .rail .on { color: #fff; }

/*
  Below 1180 the rail is the first thing to go: it is decoration, and it is what collides with
  the cards as the frame narrows. The cards themselves survive further, moving out of the
  centre and back towards the right, before going at 1080 where they would otherwise sit on
  top of the headline.
*/
@media (max-width: 1180px) {
  .hero .rail { display: none; }
  .hero .cards { left: auto; right: 5vw; transform: translate(0, -50%); }
}

@media (max-width: 1080px) {
  .hero .cards { display: none; }
}

/*
  The hero on a narrow screen, which is a different picture — now literally so, because the
  `<picture>` above hands phones `hero-portrait.jpg` rather than a slice of the wide crop.

  That change is what retired the old rule here. `object-fit: cover` crops whatever the box does
  not need, and a 3:2 image in a phone-shaped box loses its *sides*; the previous photograph had
  its one bright area dead centre, so the sub-heading landed as white text on a lit page and
  could not be read. The fix then was to pull the crop back towards the dark edge. There is
  nothing left to pull: a 2:3 image in a box of roughly 2:3 is cropped by about a tenth of its
  width, so it sits centred and nearly whole.

  What still applies is the scrim direction. The horizontal gradient exists to clear a column
  beside the photograph; on a phone there is no column — the text is simply on top of everything
  — so the whole frame has to come down instead. It is heavier here than on the desktop for that
  reason, and that is a real cost: the letters are quieter on a phone than they deserve to be.
  Legible beats pretty when the two disagree.
*/
@media (max-width: 860px) {
  /*
    Weighted to the middle, which is where the words are — not to the bottom, which is where
    the letters are. The first attempt had it the wrong way round: lightest at 38%, exactly
    behind the sub-heading, and heaviest at the foot of the frame, exactly over the thing worth
    looking at. The sub-heading had to compete with a page of Spanish prose while the spill it
    was sitting above went grey.
  */
  .hero .scrim {
    background:
      linear-gradient(180deg, rgba(12,10,8,0.60) 0%, rgba(12,10,8,0.62) 46%, rgba(12,10,8,0.28) 100%),
      rgba(12, 10, 8, 0.22);
  }

  /* The headline already carries one. On a phone the body copy is over the picture too. */
  .hero .lead { text-shadow: 0 1px 16px rgba(0,0,0,0.5); }
}

/* ── Blocks ──────────────────────────────────────────────────────────────── */

.grid {
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fit, minmax(268px, 1fr));
}

.tile {
  padding: 26px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--line);
}

.tile h3 { margin-bottom: 8px; }
.tile p { color: var(--ink-2); font-size: 15.5px; }

.chip {
  display: inline-grid;
  place-items: center;
  width: 38px; height: 38px;
  margin-bottom: 16px;
  border-radius: 12px;
  background: var(--soft);
  font-size: 18px;
}

.steps { counter-reset: step; display: grid; gap: 28px; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }

.step { position: relative; padding-top: 46px; }

.step::before {
  counter-increment: step;
  content: counter(step);
  position: absolute;
  top: 0; left: 0;
  width: 34px; height: 34px;
  border-radius: 50%;
  background: var(--ink);
  color: var(--surface);
  display: grid; place-items: center;
  font-size: 15px; font-weight: 600;
}

.step p { color: var(--ink-2); font-size: 15.5px; }

/* The before/after that makes the whole argument. */
.compare { display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }

.compare > div {
  padding: 24px 26px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--surface);
}

.compare .after { border-color: #e2c9b4; background: #fdf6ef; }

.compare .who {
  font-size: 12px; font-weight: 600; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--ink-3); margin-bottom: 12px;
}

.compare .after .who { color: var(--accent); }
.compare .body { font-family: var(--serif); font-size: 18px; line-height: 1.5; }
.compare .note { margin-top: 14px; font-size: 14.5px; color: var(--ink-2); }

/* ── Pricing ─────────────────────────────────────────────────────────────── */

.plans { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); align-items: start; }

.plan {
  padding: 30px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--line);
}

.plan.paid { border-color: var(--ink); }

.plan .price { font-size: 34px; letter-spacing: -0.03em; margin: 6px 0 4px; }
.plan .price small { font-size: 15px; color: var(--ink-3); letter-spacing: 0; }

.plan ul { margin: 20px 0 0; padding: 0; list-style: none; }

.plan li {
  position: relative;
  padding: 7px 0 7px 26px;
  font-size: 15.5px;
  color: var(--ink-2);
}

.plan li::before {
  content: "";
  position: absolute;
  left: 4px; top: 15px;
  width: 9px; height: 5px;
  border-left: 1.8px solid var(--accent);
  border-bottom: 1.8px solid var(--accent);
  transform: rotate(-45deg);
}

/* ── Prose pages ─────────────────────────────────────────────────────────── */

.prose { max-width: 72ch; padding: 56px 0 84px; }
.prose h1 { font-size: clamp(32px, 4vw, 44px); margin-bottom: 10px; }
.prose h2 { font-size: 23px; margin: 46px 0 12px; }
.prose h3 { font-size: 17.5px; margin: 30px 0 8px; }
.prose p, .prose li { color: var(--ink-2); }
.prose ul { padding-left: 22px; }
.prose li { margin-bottom: 8px; }
.prose strong { color: var(--ink); font-weight: 600; }

.prose .updated {
  font-size: 14.5px;
  color: var(--ink-3);
  padding-bottom: 26px;
  margin-bottom: 34px;
  border-bottom: 1px solid var(--line);
}

/* The summary at the top of the policy. Somebody who reads only this should still come away
   with an accurate picture, which is the actual test of a privacy policy. */
.summary {
  padding: 24px 26px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--line);
  margin-bottom: 40px;
}

.summary ul { margin: 0; padding-left: 20px; }
.summary li { margin-bottom: 7px; }
.summary li:last-child { margin-bottom: 0; }

table {
  width: 100%;
  border-collapse: collapse;
  margin: 18px 0 26px;
  font-size: 15px;
}

th, td {
  text-align: left;
  vertical-align: top;
  padding: 11px 14px 11px 0;
  border-bottom: 1px solid var(--line);
  color: var(--ink-2);
}

th { color: var(--ink); font-weight: 600; font-size: 13px; letter-spacing: 0.04em; text-transform: uppercase; }

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

footer {
  border-top: 1px solid var(--line);
  padding: 44px 0 56px;
  font-size: 15px;
  color: var(--ink-3);
}

footer .wrap { display: flex; flex-wrap: wrap; gap: 14px 30px; align-items: center; }
footer nav { display: flex; flex-wrap: wrap; gap: 22px; margin-left: auto; }
footer a { color: var(--ink-2); text-decoration: none; }
footer a:hover { color: var(--ink); }

.credit { width: 100%; margin-top: 22px; font-size: 13.5px; line-height: 1.6; }

@media (max-width: 720px) {
  .top nav { display: none; }
  section { padding: 56px 0; }
  .hero .stage { min-height: 540px; }
}
