/* One stylesheet for every page.
 *
 * No CDN, no webfont service, no analytics. That is not tidiness — /privacy
 * claims the site makes no third-party requests, and a Google Fonts <link>
 * would hand every reader's address to a third party while the page beside
 * it says otherwise. The CSP (`default-src 'self'; style-src 'self'`) holds
 * it to that: no inline style, so every visual decision lives here, and the
 * invitation art is inline SVG drawn with `currentColor`.
 *
 * The site wears the app's own clothes. The tokens below are DHDesignSystem
 * (`Palette`, `Typeface`, `Layout`, `Radius`, `Size`, `Space`) written out in
 * CSS, so the page somebody reads before installing is the page they then
 * hold. The app sets SF Pro and SF Mono, licensed for Apple platforms only,
 * so the site names the system font: an iPhone or a Mac draws the app's own
 * faces, anything else its own system face. Nothing is downloaded for type,
 * and nothing is tracked: SF sets its own tracking by size. */

/* Tokens ------------------------------------------------------------------ */

:root {
  color-scheme: light dark;

  /* Palette.swift, to the digit. Neutral greys (2026-10-06). */
  --ground: #f2f2f7;
  --card: #ffffff;
  /* An edge is a tone lighter than the surface it edges. In light the card is
   * already white, so its rim is the card itself and the fill alone stands it
   * off the grouped grey; in dark the rim is what does. */
  --card-rim: #ffffff;
  --ink: #111110;
  --body: #3a3a3f;
  --meta: #545459;
  --label: #6c6c71;
  --chip-fill: #e5e5ea;
  --on-ink: var(--ground);
  /* Rules: ink at the app's fixed strengths and no others. */
  --wash: rgb(17 17 16 / 0.06);
  --faint-edge: rgb(17 17 16 / 0.08);
  --divider: rgb(17 17 16 / 0.1);
  --edge: rgb(17 17 16 / 0.18);
  /* A hue is a role. Blue: current or tappable, a link. Tomato: a dietary
   * warning and nothing else. Red: an act that loses something. */
  --accent: #0068d9;
  --restriction: #c23d19;
  --destructive: #d70015;

  /* Invitation tones (`InvitationTone`): a wash for the poster's ground, a
   * deeper tone for its drawn art, a rim a tone lighter than the wash. Never
   * text, never green, never the paid blue. */
  --taste-wash: #fbf2d9;
  --taste-art: #a87612;
  --taste-rim: #fffaec;
  --recipes-wash: #f2eefa;
  --recipes-art: #6e56b5;
  --recipes-rim: #faf8fe;
  --household-wash: #e3f2f0;
  --household-art: #1c7e74;
  --household-rim: #f2faf9;

  --sans: -apple-system, BlinkMacSystemFont, system-ui, 'Segoe UI', Roboto, sans-serif;
  --mono: ui-monospace, 'SF Mono', SFMono-Regular, Menlo, Consolas, monospace;

  /* The closed type scale, in rem of a 16px root so a reader's own text size
   * still scales the page. BodySize: caption 12, footnote 13, body 15,
   * title 17. DisplaySize: card title 20, section 24, page 34. */
  --t-caption: 0.75rem;
  --t-footnote: 0.8125rem;
  --t-body: 0.9375rem;
  --t-title: 1.0625rem;
  --d-card: 1.25rem;
  --d-section: 1.5rem;
  --d-page: 2.125rem;

  /* Space, closed: 4, 6, 10, 14, 20, 28. */
  --s-hairline: 4px;
  --s-tight: 6px;
  --s-snug: 10px;
  --s-regular: 14px;
  --s-loose: 20px;
  --s-section: 28px;

  /* Radius and Layout. A region's card is 24 with 18 inside; a control's
   * face 14; a small mark 6. Corners nest: a shape within 14 of its holder's
   * edge takes the holder's radius less the gap, never under 6. */
  --radius-card: 24px;
  --radius-control: 14px;
  --radius-mark: 6px;
  --card-padding: 18px;
  --row-height: 52px;
  --control-height: 50px;
  --item-gap: 8px;

  --gutter: 16px;
  --measure: 36rem;
}

/* The app's dark cut, to the digit: the same relationships re-cut for a
 * near-black ground, never an inversion and never pure black or white.
 * Cards stand a step above the ground and carry a rim a tone lighter. */
@media (prefers-color-scheme: dark) {
  :root {
    --ground: #0f0f11;
    --card: #1c1c1e;
    --card-rim: #2c2c2e;
    --ink: #f2f2f7;
    --body: #d1d1d6;
    --meta: #b0b0b5;
    --label: #98989d;
    --chip-fill: #242426;
    --wash: rgb(242 242 247 / 0.06);
    --faint-edge: rgb(242 242 247 / 0.08);
    --divider: rgb(242 242 247 / 0.1);
    --edge: rgb(242 242 247 / 0.18);
    --accent: #4da3ff;
    --restriction: #eb6a45;
    --destructive: #ff5a4f;

    --taste-wash: #2b2517;
    --taste-art: #e8b94a;
    --taste-rim: #3b3320;
    --recipes-wash: #221e2e;
    --recipes-art: #ae9af0;
    --recipes-rim: #302a42;
    --household-wash: #152624;
    --household-art: #4ec2b4;
    --household-rim: #203733;
  }
}

@media (min-width: 40rem) {
  :root {
    --gutter: 28px;
  }
}

/* Base -------------------------------------------------------------------- */

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

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

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--t-title);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

::selection {
  background: var(--ink);
  color: var(--on-ink);
}

/* A link is the accent's words (`TextLink`). Inside a sentence it keeps an
 * underline in the accent at the tinted-rule strength, so it reads as a
 * link without the colour alone carrying it. */
a {
  color: var(--accent);
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: color-mix(in srgb, var(--accent) 35%, transparent);
  text-underline-offset: 0.2em;
}

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

a:active {
  opacity: 0.45;
}

/* Keyboard focus is an ink rim, the app's focus edge. Mouse focus draws
 * nothing, so a click does not leave a ring behind. */
:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: var(--radius-mark);
}

.wrap {
  max-width: calc(46rem + 2 * var(--gutter));
  margin: 0 auto;
  padding-inline: var(--gutter);
}

/* A figure among words: SF Mono at the words' own size and weight, medium
 * by default. The faces share a cap height, so nothing is rescaled. */
.fig {
  font-family: var(--mono);
  font-weight: 500;
}

/* A Tabler outline glyph. Sized by the words beside it, never a number of
 * its own: a glyph is 1em of its line. */
.glyph {
  display: inline-block;
  width: 1em;
  height: 1em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Type roles -------------------------------------------------------------- */

/* `Kicker`: SF Pro semibold at the caption step in the label grey, sentence
 * case. Its figures stay mono. As tall as a kicker holding a figure. */
.kicker {
  margin: 0;
  font-size: var(--t-caption);
  font-weight: 600;
  line-height: 1.4;
  color: var(--label);
}

.kicker--stop {
  color: var(--restriction);
}

/* `ScreenTitle`: SF Pro Bold, sentence case, at the page step. No tracking:
 * SF sets its own Display tracking at this size. */
.display {
  margin: 0;
  font-size: var(--d-page);
  font-weight: 700;
  line-height: 1.12;
  text-wrap: balance;
}

/* `HeadingPlate`: a 17 bold title with a hairline running out from its
 * shoulder to the edge. The rule is what makes it a section. */
.plate {
  display: flex;
  align-items: center;
  gap: var(--s-snug);
  margin: 0 0 var(--s-loose);
  font-size: var(--t-title);
  font-weight: 700;
  line-height: 1.3;
}

.plate::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--divider);
}

/* A standalone link that goes somewhere: the words, 4 after them a chevron
 * at their step, a size smaller and semibold — one "words ›" whatever the
 * link. No underline: standing alone, the blue is the whole signal. */
.go {
  display: inline-flex;
  align-items: baseline;
  gap: var(--s-hairline);
  text-decoration: none;
}

.go .glyph {
  width: 0.75em;
  height: 0.75em;
  stroke-width: 2.5;
  align-self: center;
}

/* Header ------------------------------------------------------------------ */

header.site {
  padding: var(--s-loose) 0 0;
}

header.site .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-regular);
  min-height: 44px;
}

/* The door names the product once. The app's icon at a glyph box's size and
 * the name in ink; `capitalize` keeps the name whole on a page whose words
 * this sheet may not touch. */
.mark {
  display: inline-flex;
  align-items: center;
  gap: var(--s-snug);
  font-size: var(--t-title);
  font-weight: 600;
  text-transform: capitalize;
  text-decoration: none;
  color: var(--ink);
}

.mark::before {
  content: '';
  width: 30px;
  height: 30px;
  border-radius: 22%;
  background: url('app-icon.png?v=2026-10-05') center / cover;
}

.mark:active {
  opacity: 0.45;
}

header.site nav a {
  text-decoration: none;
}

/* Hero -------------------------------------------------------------------- */

/* The icon, the name, one line and the app itself: the sign-in screen's own
 * words beside the sign-in screen. Side by side where there is room; on a
 * phone the screen follows the words. */
.hero {
  display: grid;
  gap: var(--s-section) 3rem;
  align-items: center;
  padding-top: 3rem;
  padding-bottom: 3.5rem;
}

@media (min-width: 46rem) {
  .hero {
    grid-template-columns: 1fr 17rem;
  }
}

.app-icon {
  display: block;
  width: 88px;
  height: 88px;
  border-radius: 22%;
}

.hero h1.display {
  margin-top: var(--s-loose);
}

.lede {
  max-width: var(--measure);
  margin: var(--s-snug) 0 0;
  font-size: var(--t-title);
  line-height: 1.5;
  color: var(--body);
}

.lede strong {
  color: var(--ink);
  font-weight: 600;
}

.cta {
  margin: var(--s-loose) 0 0;
}

/* Apple's own badge, unmodified, in the two variants they publish: black on
 * a light page and white on a dark one, which is the app's ink face in each
 * appearance. Their guidelines forbid redrawing it, so it is the one act on
 * the site that is not our own pill; both files are served from here. */
.badge {
  display: inline-block;
  line-height: 0;
  border-radius: 10px;
  text-decoration: none;
}

.badge img {
  width: 150px;
  height: auto;
}

.badge:hover {
  opacity: 0.88;
}

.badge-dark {
  display: none;
}

@media (prefers-color-scheme: dark) {
  .badge-light {
    display: none;
  }

  .badge-dark {
    display: inline-block;
  }
}

/* How it works ------------------------------------------------------------ */

/* Four steps, each a kicker, a heading and one line beside a stack of the
 * app's own screens. On a wide page the stacks alternate sides; on a phone
 * the words come first and the screens follow. */
.home .wrap {
  max-width: calc(58rem + 2 * var(--gutter));
}

.flow {
  padding-bottom: 3rem;
  /* A tilted phone's corners reach past its box; the section clips what
   * would otherwise push a phone-width page sideways. */
  overflow-x: clip;
}

.steps {
  display: grid;
  gap: 4rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.step {
  display: grid;
  gap: var(--s-section);
  align-items: center;
}

@media (min-width: 52rem) {
  .step {
    grid-template-columns: minmax(15rem, 1fr) minmax(0, 28rem);
    gap: 4rem;
  }

  .step:nth-child(even) {
    grid-template-columns: minmax(0, 28rem) minmax(15rem, 1fr);
  }

  .step:nth-child(even) > :last-child {
    order: -1;
  }
}

/* A step is a section: a sheet title's step on a phone, a page title's on a
 * wide page, where it stands beside a stack of phones. */
.step h3 {
  margin: var(--s-tight) 0 var(--s-snug);
  font-size: var(--d-section);
  font-weight: 700;
  line-height: 1.15;
  text-wrap: balance;
}

@media (min-width: 52rem) {
  .step h3 {
    font-size: var(--d-page);
  }
}

.step-text p:not(.kicker) {
  max-width: 24rem;
  margin: 0;
  color: var(--body);
}

/* The phone ------------------------------------------------------------- */

/* An iPhone drawn in CSS around a real capture, which is shown exactly as
 * captured. An ink body, a bezel about 3.5% of the width, and the screen's
 * corner concentric inside the body's (outer less the bezel). No shadow, as
 * the app has none: its edge is a rim a tone lighter than the body, which is
 * what keeps a black phone off a near-black page in dark. Sizes are in `em`
 * of the frame's own font size, so one number scales the whole phone. */
.device {
  --bezel: 0.6em;
  --corner: 2.9em;
  font-size: 16px;
  width: 16rem;
  max-width: 100%;
  margin: 0 auto;
  padding: calc(var(--bezel) - 1px);
  border: 1px solid #2c2c2e;
  border-radius: var(--corner);
  background: #0b0b0a;
}

.device img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: calc(var(--corner) - var(--bezel));
  background: var(--ground);
}

@media (max-width: 40rem) {
  .device {
    width: min(16rem, 78vw);
  }
}

/* The stack ------------------------------------------------------------- */

/* A few phones scattered over one another, the one in front last in the
 * markup. Every length is in `cqw` of the stack, so a stack keeps its shape
 * from a phone column to a 28rem desktop one: `--x`, `--y` and `--w` place a
 * phone in hundredths of the stack's width and `--r` tilts it. The scatter
 * is set by hand, never random, so a reload shows the same page. */
.stack {
  container-type: inline-size;
  position: relative;
  width: 100%;
  max-width: 28rem;
  margin: 0 auto;
}

.flow .stack .device {
  --r: 0deg;
  position: absolute;
  left: calc(var(--x) * 1cqw);
  top: calc(var(--y) * 1cqw);
  width: calc(var(--w) * 1cqw);
  max-width: none;
  margin: 0;
  font-size: calc(var(--w) * 1cqw / 16);
  transform: rotate(var(--r));
}

.stack--profile {
  aspect-ratio: 100 / 124;
}

.stack--profile .device:nth-child(1) {
  --x: 4;
  --y: 2;
  --w: 48;
  --r: -6deg;
}

.stack--profile .device:nth-child(2) {
  --x: 40;
  --y: 16;
  --w: 54;
  --r: 3deg;
}

.stack--handbook {
  aspect-ratio: 100 / 128;
}

.stack--handbook .device:nth-child(1) {
  --x: 5;
  --y: 4;
  --w: 36;
  --r: -9deg;
}

.stack--handbook .device:nth-child(2) {
  --x: 56;
  --y: 0;
  --w: 41;
  --r: 7deg;
}

.stack--handbook .device:nth-child(3) {
  --x: 17;
  --y: 14;
  --w: 54;
  --r: -2deg;
}

.stack--plan {
  aspect-ratio: 100 / 126;
}

.stack--plan .device:nth-child(1) {
  --x: 3;
  --y: 16;
  --w: 42;
  --r: -7deg;
}

.stack--plan .device:nth-child(2) {
  --x: 57;
  --y: 6;
  --w: 40;
  --r: 5deg;
}

.stack--plan .device:nth-child(3) {
  --x: 24;
  --y: 0;
  --w: 54;
  --r: 1.5deg;
}

.stack--cook {
  aspect-ratio: 100 / 130;
}

.stack--cook .device:nth-child(1) {
  --x: 62;
  --y: 26;
  --w: 36;
  --r: 9deg;
}

.stack--cook .device:nth-child(2) {
  --x: 3;
  --y: 4;
  --w: 44;
  --r: -5deg;
}

.stack--cook .device:nth-child(3) {
  --x: 27;
  --y: 12;
  --w: 54;
  --r: 2deg;
}

/* Where the browser can tie an animation to scrolling, a stack arrives
 * gathered and square and fans out to its scatter as it comes into view.
 * Elsewhere, and for anyone who has asked for less motion, it is simply
 * drawn scattered. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .flow .stack .device {
      animation: fan-out linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 45%;
    }
  }
}

@keyframes fan-out {
  from {
    transform: translate(
        calc((50 - var(--x) - var(--w) / 2) * 0.5cqw),
        calc(var(--y) * -0.5cqw)
      )
      rotate(0deg);
  }

  to {
    transform: rotate(var(--r));
  }
}

.photo-credit {
  max-width: var(--measure);
  margin: 3rem 0 0;
  font-size: var(--t-footnote);
  line-height: 1.5;
  color: var(--label);
}

/* Cards ------------------------------------------------------------------- */

/* `Card`: white on the grouped grey, 24 round, 18 inside, its rim a tone
 * lighter than its fill, and no shadow. Cards in a list stand 8 apart. */
.card,
.point {
  background: var(--card);
  border: 1px solid var(--card-rim);
  border-radius: var(--radius-card);
  padding: var(--card-padding);
}

.points-section {
  padding-bottom: 3rem;
}

.points {
  display: grid;
  gap: var(--item-gap);
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 46rem) {
  .points {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* A heading inside a card, with its picture before it: the glyph at the
 * heading's step in the label grey, as a heading plate's sign is. */
.point h3 {
  display: flex;
  gap: var(--s-snug);
  align-items: flex-start;
  margin: 0 0 var(--s-tight);
  font-size: var(--d-card);
  font-weight: 700;
  line-height: 1.2;
}

.point h3 .glyph {
  color: var(--label);
  margin-top: 0.1em;
}

.point p {
  margin: 0;
  color: var(--body);
  font-size: var(--t-body);
  line-height: 1.5;
}

/* The one notice surface (`noticeSurface`): the card's shape, washed in its
 * tone at 6%. Tomato, because this is the one dietary caveat on the site. */
.note {
  display: grid;
  gap: var(--s-tight);
  margin: var(--item-gap) 0 0;
  padding: var(--card-padding);
  border: 1px solid var(--card-rim);
  border-radius: var(--radius-card);
  background: color-mix(in srgb, var(--restriction) 6%, var(--card));
}

.note p {
  margin: 0;
}

.note p:not(.kicker) {
  color: var(--body);
  font-size: var(--t-body);
  line-height: 1.5;
}

.note .kicker {
  display: flex;
  align-items: center;
  gap: var(--s-tight);
}

/* The poster ------------------------------------------------------------- */

/* `InvitationCard`: an invitation is a poster, not a row. The card stands in
 * its tone's wash with a rim a tone lighter, a 24 bold title, one line and
 * the act at its words' width; its art is three Tabler glyphs in the tone's
 * deeper colour, one large and turned, bleeding off the trailing edge and
 * cut by the card's own corner. Still flat: no shadow, no frame.
 *
 * The drawing is in points, not type, so it keeps its size whatever the
 * reader's text does; `--s` scales the app's own figure up on a wide page. */
.poster {
  --s: 1;
  --pad: var(--card-padding);
  --wash: var(--card);
  --art: var(--ink);
  --rim: var(--card-rim);
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) calc(96px * var(--s));
  gap: var(--s-regular);
  align-items: start;
  padding: var(--pad);
  overflow: hidden;
  border: 1px solid var(--rim);
  border-radius: var(--radius-card);
  background: var(--wash);
}

@media (min-width: 40rem) {
  .poster {
    --s: 1.6;
    --art-height: 150px;
    --pad: var(--s-section);
  }
}

.poster--taste {
  --wash: var(--taste-wash);
  --art: var(--taste-art);
  --rim: var(--taste-rim);
}

.poster--recipes {
  --wash: var(--recipes-wash);
  --art: var(--recipes-art);
  --rim: var(--recipes-rim);
}

.poster--household {
  --wash: var(--household-wash);
  --art: var(--household-art);
  --rim: var(--household-rim);
}

.poster-words {
  display: grid;
  gap: var(--s-tight);
  justify-items: start;
}

.poster h1,
.poster h2 {
  margin: 0;
  font-size: var(--d-section);
  font-weight: 700;
  line-height: 1.15;
  color: var(--ink);
  text-wrap: balance;
}

.poster p {
  margin: 0;
  font-size: var(--t-body);
  line-height: 1.5;
  color: var(--meta);
}

.poster .cta {
  margin-top: var(--s-snug);
}

/* On a landing page the app's icon heads the words, so the reader knows
 * what to look for in the App Store. */
.poster .app-icon {
  width: 64px;
  height: 64px;
  margin-bottom: var(--s-snug);
}

/* The art column. Glyphs are placed in the app's own points (`InvitationFigure`)
 * times `--s`; the large one is set from the card's trailing edge so that a
 * third of it always runs past, to be cut by the corner, however wide the
 * column and padding are. Drawn thin, so its line reads as its companions'
 * does. The column stretches with the words, so a poster is never taller
 * than what it says. */
.poster-art {
  position: relative;
  align-self: stretch;
  min-height: var(--art-height, 124px);
  color: var(--art);
}

.poster-art .glyph {
  position: absolute;
  stroke-width: 1.75;
}

.poster-art .glyph:nth-child(1) {
  --size: 88px;
  left: calc(100% + var(--pad) - var(--size) * var(--s) * 0.68);
  top: calc(30px * var(--s));
  rotate: -8deg;
  stroke-width: 1;
}

/* A glyph whose ink runs the full width of its square (`users`) is drawn
 * smaller from the same place, so its second figure is not lost to the
 * corner: only its edge bleeds. */
.poster-art .glyph--wide:nth-child(1) {
  --size: 70px;
  left: calc(100% + var(--pad) - var(--size) * var(--s) * 0.85);
}

.poster-art .glyph:nth-child(2) {
  --size: 30px;
  left: 0;
  top: calc(46px * var(--s));
  rotate: 8deg;
}

.poster-art .glyph:nth-child(3) {
  --size: 22px;
  left: calc(18px * var(--s));
  top: calc(4px * var(--s));
  rotate: -6deg;
}

.poster-art .glyph {
  width: calc(var(--size) * var(--s));
  height: calc(var(--size) * var(--s));
}

/* It arrives once, settling in, each glyph a beat after the one before;
 * under Reduce Motion it is simply there. */
@media (prefers-reduced-motion: no-preference) {
  .poster-art .glyph {
    animation: settle 560ms cubic-bezier(0.2, 0.9, 0.3, 1.15) both;
  }

  .poster-art .glyph:nth-child(2) {
    animation-delay: 60ms;
  }

  .poster-art .glyph:nth-child(3) {
    animation-delay: 120ms;
  }
}

@keyframes settle {
  from {
    opacity: 0;
    scale: 0.82;
    translate: 0 14px;
  }

  to {
    opacity: 1;
    scale: 1;
    translate: 0 0;
  }
}

.invite {
  padding-bottom: 0;
}

/* The landing pages (join/, r/): the page is the poster. */
.landing {
  padding-top: 3rem;
  padding-bottom: 4rem;
}

.landing .poster {
  max-width: 40rem;
}

/* Prose (the policy, the credits) ---------------------------------------- */

.prose {
  padding-block: 3rem 1rem;
}

.prose .stamp {
  margin-top: var(--s-snug);
}

.prose > p:first-of-type {
  margin-top: var(--s-section);
}

/* A section on a page: the card title's step, bold. A sub-section is a
 * row's title. */
.prose h2 {
  margin: 3rem 0 var(--s-snug);
  font-size: var(--d-card);
  font-weight: 700;
  line-height: 1.25;
}

.prose h3 {
  margin: var(--s-section) 0 var(--s-tight);
  font-size: var(--t-title);
  font-weight: 700;
}

.prose p,
.prose li {
  max-width: var(--measure);
  color: var(--body);
}

.prose strong {
  color: var(--ink);
  font-weight: 600;
}

.prose ul {
  padding-left: 1.1rem;
}

.prose li {
  margin-bottom: var(--s-snug);
}

.prose li::marker {
  color: var(--label);
}

/* A host name: SF Mono in a well (a well inside nothing is `chip-fill`, a
 * step below the ground), at a small mark's corner. `clone` gives each
 * wrapped fragment its own corners. */
.prose code {
  font-family: var(--mono);
  font-weight: 500;
  font-size: 0.875em;
  padding: 0.1em 0.35em;
  border-radius: var(--radius-mark);
  background: var(--chip-fill);
  color: var(--ink);
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/* A table is a card of rows: white on the ground, 24 round, 18 in at the
 * sides, rows of at least 52 split by dividers. It scrolls inside itself if
 * it ever has to, never the page. */
.scroller {
  overflow-x: auto;
  margin: var(--s-regular) 0 var(--s-loose);
  padding: 0 var(--card-padding);
  background: var(--card);
  border: 1px solid var(--card-rim);
  border-radius: var(--radius-card);
}

table {
  border-collapse: collapse;
  width: 100%;
  margin: 0;
  font-size: var(--t-body);
  line-height: 1.45;
}

th,
td {
  text-align: left;
  vertical-align: top;
  padding: 15px var(--s-regular) 15px 0;
  border-bottom: 1px solid var(--divider);
  color: var(--body);
}

th:last-child,
td:last-child {
  padding-right: 0;
}

tbody tr:last-child td {
  border-bottom: 0;
}

/* Column names are kickers. */
th {
  font-size: var(--t-caption);
  font-weight: 600;
  color: var(--label);
  white-space: nowrap;
  padding-top: var(--card-padding);
  padding-bottom: var(--s-snug);
}

td:first-child {
  color: var(--ink);
  font-weight: 600;
}

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

footer.site {
  margin-top: 3rem;
  padding: var(--s-section) 0 3rem;
  border-top: 1px solid var(--divider);
  font-size: var(--t-body);
}

footer.site nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-tight) var(--s-loose);
  margin-bottom: var(--s-snug);
}

footer.site nav a {
  text-decoration: none;
}

footer.site p {
  margin: 0;
  font-size: var(--t-caption);
  color: var(--label);
}

/* Motion ------------------------------------------------------------------ */

/* The hero arrives rather than appears: a short rise, staggered by line.
 * Nothing moves at all for somebody who has asked for that. */
@media (prefers-reduced-motion: no-preference) {
  .hero > * {
    animation: rise 480ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
  }

  .hero > :nth-child(2) {
    animation-delay: 120ms;
  }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(8px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

/* Phones ------------------------------------------------------------------ */

/* A three-column table on a 375pt phone is three columns of one word each.
 * Below 40rem each row becomes a block with its column name, a kicker, in
 * front of each value: the same information with no sideways scroll. */
@media (max-width: 40rem) {
  .hero {
    padding-top: var(--s-section);
    padding-bottom: 3rem;
  }

  table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }

  table tbody tr {
    display: block;
    padding: var(--s-regular) 0;
    border-bottom: 1px solid var(--divider);
  }

  table tbody tr:last-child {
    border-bottom: 0;
  }

  table tbody td {
    display: block;
    border: 0;
    padding: 0 0 var(--s-snug);
  }

  table tbody td::before {
    content: attr(data-label);
    display: block;
    margin-bottom: 2px;
    font-size: var(--t-caption);
    font-weight: 600;
    color: var(--label);
  }

  table tbody td:last-child {
    padding-bottom: 0;
  }
}
