/* SimpleStack: minimal and current. Warm paper, ink type, one vermilion accent. */

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/inter-latin-wght-5.3.0.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  color-scheme: light dark;

  /* Light: ink 16.8:1 and secondary 6.6:1 on paper. Accent is 4.2:1: shapes and large type only. */
  --paper: #fbfaf7;
  --ink: #1b1916;
  --ink-2: #5f5a53;
  --line: #e7e4de;
  --accent: #d9431f;

  --font: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --gutter: clamp(1.25rem, 0.6rem + 3.2vw, 4.5rem);

  /* Motion: pick from these, never a bespoke value. */
  --motion-fast: 120ms;
  --motion-base: 200ms;
  --motion-medium: 280ms;
  --motion-slow: 400ms;
  --motion-slower: 600ms;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-emphasized: cubic-bezier(0.2, 0, 0, 1);
}

/* Dark: ink 16.2:1, secondary 7.1:1, accent 6.6:1. It follows the system unless the theme
   button (theme.js) has set data-theme on <html>; the two blocks below must stay identical. */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #131210;
    --ink: #f1eee8;
    --ink-2: #a59f95;
    --line: #2b2925;
    --accent: #ff6b47;
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --paper: #131210;
  --ink: #f1eee8;
  --ink-2: #a59f95;
  --line: #2b2925;
  --accent: #ff6b47;
}

:root[data-theme="light"] {
  color-scheme: light;
}

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

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

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  font-size: 1rem;
  line-height: 1.6;
  letter-spacing: -0.011em;
  font-feature-settings: "cv11";
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

main {
  flex: 1;
}

h1,
h2,
p,
dl,
dd {
  margin: 0;
}

::selection {
  background: color-mix(in srgb, var(--accent) 28%, transparent);
}

a {
  color: inherit;
}

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

/* Hairlines are pseudo-elements so they can draw in on scroll. */

.section-head::after,
.list > div::after,
.doc-row::before,
.doc-row:last-child::after,
.legal::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--line);
  transform-origin: left center;
}

.section-head::after,
.list > div::after,
.doc-row:last-child::after {
  bottom: 0;
}

.doc-row::before,
.legal::before {
  top: 0;
}

/* Masthead: mark and name on the left, one link on the right. */

.masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: calc(var(--gutter) * 0.6 + env(safe-area-inset-top)) var(--gutter) 0;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1;
}

.brand a {
  display: inline-flex;
  align-items: center;
  gap: inherit;
  text-decoration: none;
}

.mark {
  display: block;
  width: 1.125em;
  height: auto;
  overflow: visible;
  fill: currentColor;
}

.mark rect {
  transform-box: fill-box;
}

.mark-top {
  fill: var(--accent);
}

/* Quiet links (nav, footer): colour deepens and a hairline grows from the left. */

.nav a,
.legal a {
  position: relative;
  color: var(--ink-2);
  font-weight: 500;
  text-decoration: none;
  background: linear-gradient(currentColor, currentColor) no-repeat 0 100% / 0% 1px;
  padding-bottom: 2px;
  transition:
    color var(--motion-fast) var(--ease-out),
    background-size var(--motion-fast) var(--ease-out),
    opacity var(--motion-fast) var(--ease-out);
}

/* A larger, invisible hit area for small links on touch screens. */
.nav a::before,
.legal a::before {
  content: "";
  position: absolute;
  inset: -0.75rem -0.5rem;
}

.nav a {
  font-size: 0.9375rem;
}

.masthead-end {
  display: flex;
  align-items: center;
  gap: 1.25rem;
}

/* Theme button: a half-filled circle that turns over when the theme changes. */

.theme-toggle {
  position: relative;
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  margin: -0.5rem -0.5rem -0.5rem 0;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--ink-2);
  cursor: pointer;
  transition:
    color var(--motion-fast) var(--ease-out),
    opacity var(--motion-fast) var(--ease-out);
}

.theme-toggle[hidden] {
  display: none;
}

/* 44px to touch, 32px to see. */
.theme-toggle::before {
  content: "";
  position: absolute;
  inset: -0.375rem;
}

.theme-toggle svg {
  width: 1.0625rem;
  height: auto;
}

:root[data-theme="dark"] .theme-toggle svg {
  transform: rotate(180deg);
}

.theme-toggle:active {
  opacity: 0.6;
}

.legal a[aria-current="page"] {
  color: var(--ink);
  background-size: 100% 1px;
}

/* Hero: one big line, one small one. */

.hero {
  padding: clamp(6rem, 2rem + 17vh, 15rem) var(--gutter) clamp(2rem, 1rem + 4vh, 4rem);
}

.lede {
  max-width: 15ch;
  font-size: clamp(2.875rem, 0.9rem + 7.6vw, 8.75rem);
  font-weight: 500;
  line-height: 0.95;
  letter-spacing: -0.05em;
  text-wrap: balance;
}

.line {
  display: block;
}

.line > span {
  display: inline-block;
}

.dot {
  /* Stays inline: an inline-block here would put a space before the full stop in the heading's
     accessible name. */
  color: var(--accent);
}

.sub {
  max-width: 36ch;
  margin-top: clamp(1.5rem, 1rem + 1.6vw, 2.75rem);
  color: var(--ink-2);
  font-size: clamp(1.0625rem, 1rem + 0.35vw, 1.3125rem);
  line-height: 1.5;
  text-wrap: balance;
}

.back {
  margin-top: clamp(2rem, 1.5rem + 2vw, 3rem);
  font-size: 1.0625rem;
  font-weight: 500;
}

/* Sections: a label over a hairline, then the content. */

.section {
  margin: 0 var(--gutter);
  padding-top: clamp(4.5rem, 2.5rem + 6vw, 9rem);
}

.section-head {
  position: relative;
  padding-bottom: 1rem;
  font-size: 0.875rem;
  font-weight: 500;
  letter-spacing: 0;
}

.list > div {
  position: relative;
  display: grid;
  gap: 0.375rem 2rem;
  padding: clamp(1.125rem, 0.7rem + 1.4vw, 2rem) 0;
}

@media (min-width: 48rem) {
  .list > div {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: baseline;
  }
}

.list dt {
  font-size: clamp(2rem, 1.2rem + 3.2vw, 4rem);
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.045em;
}

.list dd {
  color: var(--ink-2);
  font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);
  line-height: 1.45;
}

/* About: a short paragraph, aligned with the list descriptions on wide screens. */

.statement {
  max-width: 34ch;
  margin-top: clamp(1.75rem, 1rem + 2.5vw, 3.25rem);
  font-size: clamp(1.375rem, 1rem + 1.5vw, 2.25rem);
  font-weight: 450;
  line-height: 1.3;
  letter-spacing: -0.03em;
  text-wrap: pretty;
}

@media (min-width: 48rem) {
  .statement {
    margin-left: calc(50% + 1rem);
  }
}

/* Big links: the address is the call to action. The accent underline sits below the
   descenders; on hover an ink line sweeps over it from the left. */

.big-link {
  margin-top: clamp(1.75rem, 1rem + 2.5vw, 3.25rem);
  font-size: clamp(1.25rem, 0.45rem + 4.1vw, 4rem);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.045em;
}

.big-link a,
.back a {
  --rule: max(2px, 0.05em);
  text-decoration: none;
  background:
    linear-gradient(currentColor, currentColor) no-repeat 0 100% / 0% var(--rule),
    linear-gradient(var(--accent), var(--accent)) no-repeat 0 100% / 100% var(--rule);
  padding-bottom: 0.04em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  transition:
    background-size var(--motion-base) var(--ease-out),
    opacity var(--motion-fast) var(--ease-out);
}


.note {
  margin-top: 1.25rem;
  color: var(--ink-2);
  font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);
}

/* Document pages (support, privacy): the hero, then rows with a heading beside the prose. */

.hero .big-link {
  margin-top: clamp(2rem, 1.5rem + 2vw, 3rem);
}

.updated {
  margin-top: 1rem;
  color: var(--ink-2);
  font-size: 0.875rem;
}

.doc {
  margin: 0 var(--gutter);
  padding-top: clamp(2.5rem, 1.5rem + 4vw, 5.5rem);
}

.doc-row {
  position: relative;
  display: grid;
  gap: 0.75rem 2rem;
  padding: clamp(1.5rem, 1rem + 1.6vw, 2.5rem) 0;
}

@media (min-width: 48rem) {
  .doc-row {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: baseline;
  }
}

.doc-row h2 {
  font-size: clamp(1.375rem, 1.1rem + 1.1vw, 2rem);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.035em;
}

.prose {
  max-width: 36rem;
  color: var(--ink-2);
  font-size: clamp(1rem, 0.97rem + 0.2vw, 1.125rem);
  text-wrap: pretty;
}

.prose > * + * {
  margin-top: 0.875rem;
}

.prose ul {
  margin-bottom: 0;
  padding-left: 1.1em;
}

.prose li + li {
  margin-top: 0.25rem;
}

.prose a {
  color: var(--ink);
  text-decoration-color: var(--accent);
  text-decoration-thickness: 1.5px;
  text-underline-offset: 0.2em;
  transition: text-decoration-color var(--motion-fast) var(--ease-out);
}


/* Colophon: the name set edge to edge, then the small print. */

.colophon {
  margin: clamp(6rem, 3rem + 10vw, 13rem) var(--gutter) 0;
  padding-bottom: calc(1.25rem + env(safe-area-inset-bottom));
  container-type: inline-size;
}

.giant {
  /* Inter 600 at -0.055em: the ink starts 0.046em in and is 5.42em wide, so this spans the column
     exactly. The bottom padding clears the descender of the p, and the clip hides the word below
     that line while it rises in. */
  margin-left: -0.046em;
  padding-bottom: 0.2em;
  font-size: calc(100cqw / 5.42);
  font-weight: 600;
  line-height: 0.8;
  letter-spacing: -0.055em;
  white-space: nowrap;
  user-select: none;
  clip-path: inset(-0.5em -0.5em 0 -0.5em);
  view-timeline: --giant block;
}

.giant > span {
  display: block;
}

.legal {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.5rem 1.5rem;
  padding-top: 1.25rem;
  color: var(--ink-2);
  font-size: 0.875rem;
}

.legal nav {
  display: flex;
  gap: 1.25rem;
}

.legal small {
  font-size: inherit;
}

/* Hover: only where there is a real pointer, so a tap on a phone never leaves a sticky state.
   Entrances here run slower than the exits set on the resting rules above. */

@media (hover: hover) and (pointer: fine) {
  .nav a:hover,
  .legal a:hover {
    color: var(--ink);
    background-size: 100% 1px;
    transition-duration: var(--motion-fast), var(--motion-base), var(--motion-fast);
  }

  .big-link a:hover,
  .back a:hover {
    background-size: 100% var(--rule), 100% var(--rule);
    transition-duration: var(--motion-medium), var(--motion-fast);
  }

  .prose a:hover {
    text-decoration-color: currentColor;
  }

  .theme-toggle:hover {
    color: var(--ink);
  }
}

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  /* The slabs swap sides, a small restack, one after another. */
  .brand a:hover .mark rect {
    transition-duration: var(--motion-base);
  }

  .brand a:hover .mark rect:nth-child(2) {
    transition-delay: 30ms;
  }

  .brand a:hover .mark rect:nth-child(3) {
    transition-delay: 60ms;
  }

  .brand a:hover .mark rect:nth-child(odd) {
    transform: translateX(-3px);
  }

  .brand a:hover .mark rect:nth-child(even) {
    transform: translateX(3px);
  }
}

/* Pressed: every link dims for a moment, so a tap always answers. */

.nav a:active,
.legal a:active,
.big-link a:active,
.back a:active,
.brand a:active {
  opacity: 0.6;
}

/* Motion. Nothing here is needed to read the page: with reduced motion, or in a browser
   without scroll timelines, every element simply sits in its final place. */

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }

  /* Page to page: a short crossfade while the masthead holds still. */
  @view-transition {
    navigation: auto;
  }

  .masthead {
    view-transition-name: masthead;
  }

  ::view-transition-group(*) {
    animation-duration: var(--motion-medium);
    animation-timing-function: var(--ease-out);
  }

  /* Load, once per page: the stack builds itself, bottom slab first, accent last. */
  .mark rect {
    animation: slab-in var(--motion-slow) var(--ease-out) backwards;
  }

  .mark rect:nth-child(2) {
    animation-delay: 50ms;
  }

  .mark rect:nth-child(1) {
    animation-delay: 100ms;
  }

  /* Then the headline rises out of a mask, line by line, and the full stop lands last. */
  .line {
    clip-path: inset(-0.25em -0.2em -0.3em -0.2em);
  }

  .line > span {
    animation: line-in var(--motion-slower) var(--ease-emphasized) backwards;
  }

  .line + .line > span {
    animation-delay: 80ms;
  }

  .dot {
    animation: dot-in var(--motion-medium) var(--ease-out) 480ms backwards;
  }

  .hero > :not(.lede) {
    animation: rise var(--motion-slow) var(--ease-out) 200ms backwards;
  }

  .hero > :not(.lede) ~ :not(.lede) {
    animation-delay: 280ms;
  }

  .theme-toggle svg {
    transition: transform var(--motion-medium) var(--ease-out);
  }

  /* Theme change (theme.js): the new theme grows in a circle from the button. */
  html.theme-switching::view-transition-old(root) {
    animation: none;
  }

  html.theme-switching::view-transition-new(root) {
    animation: theme-reveal var(--motion-slow) var(--ease-out);
  }

  /* The brand link's slabs settle back quickly when the pointer leaves. */
  .brand a .mark rect {
    transition: transform var(--motion-fast) var(--ease-out);
  }

  /* Scroll: hairlines draw in from the left and content rises into place as it enters. Every
     range ends by the time its element is fully on screen, so even the last rows on a page
     finish at the bottom of the scroll. */
  @supports (animation-timeline: view()) {
    .section-head,
    .list > div,
    .doc-row {
      view-timeline: --row block;
    }

    .colophon {
      view-timeline: --foot block;
    }

    .section-head,
    .section-head::after {
      animation: rise var(--ease-out) both;
      animation-timeline: --row;
      animation-range: entry 0% cover 20%;
    }

    .section-head::after {
      animation-name: draw;
    }

    .list > div::after,
    .doc-row::before,
    .doc-row:last-child::after {
      animation: draw var(--ease-out) both;
      animation-timeline: --row;
      animation-range: entry 0% entry 100%;
    }

    .legal::before {
      animation: draw var(--ease-out) both;
      animation-timeline: --foot;
      animation-range: entry 0% entry 90%;
    }

    .list dt,
    .doc-row h2 {
      animation: rise var(--ease-out) both;
      animation-timeline: --row;
      animation-range: entry 0% entry 100%;
    }

    .list dd,
    .prose {
      animation: rise var(--ease-out) both;
      animation-timeline: --row;
      animation-range: entry 25% entry 100%;
    }

    .statement,
    .section > .big-link,
    .note {
      animation: rise var(--ease-out) both;
      animation-timeline: view();
      animation-range: entry 0% entry 100%;
    }

    .giant > span {
      animation: giant-in var(--ease-out) both;
      animation-timeline: --giant;
      animation-range: entry 0% entry 100%;
    }
  }
}

@keyframes slab-in {
  from {
    opacity: 0;
    transform: translateY(-120%);
  }
}

@keyframes line-in {
  from {
    transform: translateY(calc(100% + 0.35em));
  }
}

@keyframes dot-in {
  from {
    opacity: 0;
  }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(1rem);
  }
}

@keyframes draw {
  from {
    transform: scaleX(0);
  }
}

@keyframes theme-reveal {
  from {
    clip-path: circle(0 at var(--reveal-x) var(--reveal-y));
  }

  to {
    clip-path: circle(var(--reveal-r) at var(--reveal-x) var(--reveal-y));
  }
}

@keyframes giant-in {
  from {
    transform: translateY(calc(100% + 0.25em));
  }
}
