/*
 * The whole site's stylesheet. There is no build step and no framework: three
 * static documents do not need one, and a privacy policy that cannot be served
 * because a bundler broke is worse than a plain one that always works.
 *
 * ⚠️ **Nothing here reaches a third party.** No CDN, no Google Fonts, no
 * analytics, no embedded anything. A German court has already fined a site
 * operator for leaking visitor IP addresses to Google Fonts, and doing it on a
 * page that explains how carefully we handle location would be its own answer.
 * The one font is served from this origin; everything else is the system's.
 *
 * The palette is `src/theme/tokens.ts`, value for value, so the web and the app
 * are recognisably one product. The chrome follows the reader's setting for the
 * same reason the app's does — see the design notes in CLAUDE.md.
 */

@font-face {
  font-family: 'Space Grotesk';
  /* Copied from the same package the app loads, so the wordmark is the
     wordmark rather than something that resembles it. */
  src: url('SpaceGrotesk-Bold.ttf') format('truetype');
  font-weight: 700;
  font-style: normal;
  /* Text first, character second. A legal document nobody can read for 300ms
     is a worse trade than one that reflows. */
  font-display: swap;
}

:root {
  color-scheme: light dark;

  --background: #efeff2;
  --surface: #ffffff;
  --surface-high: #e3e3e9;
  --ink: #111114;
  --ink-muted: #55555e;
  --ink-faint: #6a6a73;
  --hairline: #d4d4db;
  --accent: #c6f432;

  --measure: 34rem;
  --gutter: 1.5rem;
}

@media (prefers-color-scheme: dark) {
  :root {
    --background: #0b0b0d;
    --surface: #17171a;
    --surface-high: #202024;
    --ink: #f7f7f8;
    --ink-muted: #9a9aa3;
    --ink-faint: #84848e;
    --hairline: #2a2a2f;
  }
}

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

html {
  /* Nothing is pinned to the viewport, so a tap that lands on a heading does
     not need to be chased by the browser. */
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

body {
  margin: 0;
  padding: 0 var(--gutter) 6rem;
  background: var(--background);
  color: var(--ink);
  /* The app uses Inter here. On the web the system's own UI face is already
     Inter-adjacent on every platform this is read on, and it costs nothing to
     download — 340 KB of body text for a document somebody reads once is a
     bad trade on a South African mobile connection. */
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  font-size: 1.0625rem;
  line-height: 1.65;
  /* Not justified, and not hyphenated. Both look tidier and both make long
     legal text measurably harder to read. */
  text-wrap: pretty;
}

main,
header,
footer {
  max-width: var(--measure);
  margin: 0 auto;
}

/* ---- The wordmark ------------------------------------------------------ */

header.masthead {
  padding: 3rem 0 2rem;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: 'Space Grotesk', Futura, 'Trebuchet MS', sans-serif;
  font-weight: 700;
  font-size: 1.25rem;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-decoration: none;
}

.wordmark .mark {
  width: auto;
  height: 1.3rem;
  display: block;
}

/*
 * The accent as a fill and never as text.
 *
 * Acid lime is 1.1:1 against a light page, which is invisible rather than dim,
 * and darkening it far enough to read turns it into a muddy olive that reads as
 * a different colour. So it does the one job it is good at on paper: a small
 * solid shape that means live, go, now. Same conclusion the app reached — see
 * `accentText` in tokens.ts.
 */
.live-dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--accent);
  display: inline-block;
}

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

h1 {
  font-family: 'Space Grotesk', Futura, 'Trebuchet MS', sans-serif;
  font-weight: 700;
  font-size: clamp(2rem, 7vw, 2.75rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin: 0 0 0.5rem;
}

h2 {
  font-family: 'Space Grotesk', Futura, 'Trebuchet MS', sans-serif;
  font-weight: 700;
  font-size: 1.375rem;
  line-height: 1.25;
  letter-spacing: -0.01em;
  margin: 3rem 0 0.75rem;
  /* Scroll targets: the table of contents jumps here, and a heading welded to
     the top edge of the viewport reads as the start of nothing. */
  scroll-margin-top: 1.5rem;
}

h3 {
  font-size: 1.0625rem;
  font-weight: 600;
  margin: 2rem 0 0.5rem;
}

p,
ul,
ol,
dl {
  margin: 0 0 1rem;
}

ul,
ol {
  padding-left: 1.25rem;
}

li {
  margin-bottom: 0.5rem;
}

li > ul,
li > ol {
  margin-top: 0.5rem;
}

strong {
  font-weight: 600;
}

a {
  color: var(--ink);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

a:hover {
  text-decoration-thickness: 2px;
}

a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.9em;
  background: var(--surface-high);
  padding: 0.1em 0.35em;
  border-radius: 4px;
}

.lede {
  font-size: 1.1875rem;
  color: var(--ink-muted);
  margin-bottom: 2rem;
}

.stamp {
  font-size: 0.875rem;
  color: var(--ink-faint);
  margin: 0 0 2.5rem;
}

.quiet {
  color: var(--ink-muted);
  font-size: 0.9375rem;
}

/* ---- Blocks ------------------------------------------------------------ */

.card {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  padding: 1.25rem 1.5rem;
  margin: 0 0 1.5rem;
}

.card > :last-child {
  margin-bottom: 0;
}

.card h2,
.card h3 {
  margin-top: 0;
}

/*
 * The plain-English summary that sits above each document.
 *
 * Not a substitute for the terms below it and not a legal instrument — it says
 * so. It is here because a policy nobody reads protects nobody, and the
 * honest fix is a version that can be read in a minute rather than a shorter
 * document that leaves things out.
 */
.short-version {
  border-left: 3px solid var(--accent);
  background: var(--surface);
  border-radius: 0 12px 12px 0;
  padding: 1.25rem 1.5rem;
  margin: 0 0 2.5rem;
}

.short-version h2 {
  margin-top: 0;
  font-size: 1.125rem;
}

.short-version > :last-child {
  margin-bottom: 0;
}

/*
 * ⚠️ Deliberately loud, and deliberately visible to readers rather than hidden
 * in a comment. Everything inside one of these is a decision that belongs to a
 * person and not to whoever wrote the page: a registered company name, an
 * address, a mailbox that has to actually exist. A placeholder somebody can
 * see is a placeholder somebody removes; one in an HTML comment ships.
 *
 * Deleting the class deletes the styling. Search the repo for `to-confirm`.
 */
.to-confirm {
  border: 2px dashed var(--accent);
  border-radius: 12px;
  padding: 1rem 1.25rem;
  margin: 0 0 1.5rem;
  background: var(--surface-high);
  font-size: 0.9375rem;
}

.to-confirm > :last-child {
  margin-bottom: 0;
}

.to-confirm::before {
  content: 'Before launch';
  display: block;
  font-weight: 600;
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: 0.4rem;
}

/* ---- Contents ---------------------------------------------------------- */

nav.contents {
  margin: 0 0 3rem;
}

nav.contents ol {
  list-style: none;
  padding: 0;
  margin: 0;
  /* Two columns where there is room. A twenty-item list in one column pushes
     the document itself below the fold. */
  columns: 2;
  column-gap: 2rem;
}

@media (max-width: 30rem) {
  nav.contents ol {
    columns: 1;
  }
}

nav.contents li {
  margin-bottom: 0.35rem;
  font-size: 0.9375rem;
  break-inside: avoid;
}

nav.contents a {
  color: var(--ink-muted);
  text-decoration: none;
}

nav.contents a:hover {
  color: var(--ink);
  text-decoration: underline;
}

/* ---- Tables ------------------------------------------------------------ */

.table-scroll {
  margin: 0 0 1.5rem;
}

/*
 * Wider than the text around it, where the window allows.
 *
 * The measure is 34rem because that is comfortable for prose, and a
 * three-column table squeezed into it was giving two words a line — "The
 * coordinates of a pin, once, with nothing attached that identifies you"
 * broke across eight lines. Prose keeps the measure; tables get to breathe.
 */
@media (min-width: 56rem) {
  .table-scroll {
    width: calc(100% + 8rem);
    margin-left: -4rem;
  }
}

table {
  border-collapse: collapse;
  width: 100%;
  font-size: 0.9375rem;
}

th,
td {
  text-align: left;
  vertical-align: top;
  padding: 0.6rem 0.75rem 0.6rem 0;
  border-bottom: 1px solid var(--hairline);
}

th {
  font-weight: 600;
  color: var(--ink-muted);
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

/*
 * On a phone, a table stops being a table.
 *
 * Three columns on a 390-point screen is unreadable however it is sliced, and
 * the two usual escapes are both worse than this: scrolling sideways hides
 * half the content of a privacy policy behind a gesture nobody knows is there,
 * and shrinking the type puts it under the size anybody can read.
 *
 * So each row becomes a block and each cell carries its own column heading,
 * taken from the `th` and written into `data-label` — which is why every cell
 * in these documents has one. The heading row itself goes, because it has been
 * distributed into the rows.
 */
@media (max-width: 38rem) {
  table,
  tbody,
  tr,
  td {
    display: block;
    width: 100%;
  }

  thead {
    /* Not `display: none` — that would take it from a screen reader too, and
       the labels below are visual. Clipped, so it stays in the accessibility
       tree and out of the page. */
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }

  tr {
    padding: 0.75rem 0;
    border-bottom: 1px solid var(--hairline);
  }

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

  td {
    border-bottom: 0;
    padding: 0.35rem 0;
  }

  td::before {
    content: attr(data-label);
    display: block;
    font-weight: 600;
    font-size: 0.75rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ink-faint);
    margin-bottom: 0.15rem;
  }

  /* A cell whose heading would say nothing twice. */
  td[data-label='']::before {
    content: none;
  }
}

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

footer {
  margin-top: 5rem;
  padding-top: 2rem;
  border-top: 1px solid var(--hairline);
  font-size: 0.9375rem;
  color: var(--ink-muted);
}

footer nav a {
  margin-right: 1.25rem;
  white-space: nowrap;
}

/* Open data credit, under the footer's links. A class rather than a style
   attribute so the content security policy can refuse inline styles outright
   — see `_headers`. */
.attribution {
  margin-top: 1rem;
}

/* ---- Home -------------------------------------------------------------- */

.hero {
  padding: 1rem 0 3rem;
}

.hero p {
  font-size: 1.1875rem;
  color: var(--ink-muted);
}

.home-links {
  list-style: none;
  padding: 0;
}

.home-links li {
  margin-bottom: 1rem;
}

.home-links a {
  font-weight: 600;
  text-decoration: none;
  border-bottom: 2px solid var(--accent);
  padding-bottom: 1px;
}

.home-links a:hover {
  border-bottom-width: 3px;
}

.home-links .quiet {
  display: block;
  font-weight: 400;
  border: 0;
  margin-top: 0.15rem;
}

/* Printed by somebody's lawyer, eventually. */
@media print {
  body {
    background: #fff;
    color: #000;
    padding: 0;
    font-size: 11pt;
  }

  nav.contents,
  .to-confirm {
    break-inside: avoid;
  }

  a {
    text-decoration: none;
  }

  /* A cross-reference is useless on paper unless it says where it went. */
  main a[href^='http']::after {
    content: ' (' attr(href) ')';
    font-size: 0.85em;
    color: #444;
  }
}
