:root {
  color-scheme: light dark;

  /* Grounds and inks are sampled from the app icon's tile and dish. */
  --ground: #f7f8fa;
  --tile: #eceef2;
  --ink: #16171b;
  --ink-soft: #5b5f6a;
  --rule: #e3e6eb;

  /* The signal green from the app icon's dish, kept for the few marks that
     answer the visitor: the focus ring and an open question. */
  --accent: #127638;

  /* The app's own meanings: a variable no environment defines, and a 4xx. */
  --unresolved-text: #b3261e;
  --caution-text: #8c6309;

  --window-shadow: drop-shadow(0 1px 1px rgb(22 23 27 / 0.1))
    drop-shadow(0 22px 44px rgb(22 23 27 / 0.16));

  /* A window on the desktop: a hairline where it meets the wallpaper, a
     close contact shadow and a wide, soft one, as macOS draws them. */
  --stage-window-shadow: drop-shadow(0 0 0.5px rgb(0 0 0 / 0.4))
    drop-shadow(0 6px 10px rgb(16 24 40 / 0.14)) drop-shadow(0 28px 56px rgb(16 24 40 / 0.3));

  --font-text: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial,
    sans-serif;
  --font-data: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 1rem;
  --space-4: 1.5rem;
  --space-5: 2rem;
  --space-6: 3rem;
  --space-7: 4rem;
  --section-gap: clamp(5rem, 12vw, 9rem);
  --gutter: clamp(1.25rem, 5vw, 2.5rem);

  /* Chapter screenshots are 1000 pt windows, so the column shows them 1:1. */
  --measure: 1000px;
  --stage-measure: 1360px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --ground: #030305;
    --tile: #141417;
    --ink: #f2f3f5;
    --ink-soft: #a0a4ae;
    --rule: #2a2b31;

    --accent: #4cd37e;

    --unresolved-text: #ff8a80;
    --caution-text: #d1b06f;

    --window-shadow: drop-shadow(0 0 1px rgb(255 255 255 / 0.14));
    --stage-window-shadow: drop-shadow(0 0 0.5px rgb(255 255 255 / 0.3))
      drop-shadow(0 6px 12px rgb(0 0 0 / 0.4)) drop-shadow(0 32px 64px rgb(0 0 0 / 0.6));
  }
}

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

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

/* A cool wash at the top of the page, behind the header and hero alike, so
   the page opens out of light instead of sitting on flat paper. */
body {
  margin: 0;
  background:
    radial-gradient(ellipse 80% 44rem at 50% -8rem, var(--tile), transparent) no-repeat,
    var(--ground);
  color: var(--ink);
  font: 400 1.0625rem/1.55 var(--font-text);
  -webkit-font-smoothing: antialiased;
  /* Windows that bleed off a side are cut at the screen's edge, never
     scrolled to. Clip, unlike hidden, leaves the page its own scroller. */
  overflow-x: clip;
}

img {
  display: block;
  max-width: 100%;
  height: auto;
}

a {
  color: inherit;
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
}

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

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

code {
  font-family: var(--font-data);
  font-size: 0.92em;
}

kbd {
  font-family: inherit;
  white-space: nowrap;
}

.unresolved {
  color: var(--unresolved-text);
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

.wrap {
  width: min(100% - 2 * var(--gutter), var(--measure));
  margin-inline: auto;
}

.lead {
  margin: var(--space-4) 0 0;
  max-width: 34em;
  color: var(--ink-soft);
  font-size: clamp(1.125rem, 1rem + 0.6vw, 1.3125rem);
  line-height: 1.45;
  text-wrap: pretty;
}

.note {
  margin: var(--space-4) 0 0;
  max-width: 62ch;
  color: var(--ink-soft);
  font-size: 0.9375rem;
}

/* Header and footer */

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-block: var(--space-4);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: 600;
  letter-spacing: -0.01em;
  text-decoration-line: none;
}

.site-nav {
  display: flex;
  gap: var(--space-4);
  font-size: 0.9375rem;
}

.site-nav a {
  color: var(--ink-soft);
  text-decoration-line: none;
}

.site-nav a:hover {
  color: var(--ink);
}

.site-footer {
  display: grid;
  grid-template-columns: 1fr auto;
  row-gap: var(--space-3);
  padding-block: var(--space-5) var(--space-6);
  border-top: 1px solid var(--rule);
  color: var(--ink-soft);
  font-size: 0.875rem;
}

.site-footer p {
  margin: 0;
}

.site-footer .site-nav {
  font-size: inherit;
}

.trademarks {
  grid-column: 1 / -1;
  max-width: 70ch;
  font-size: 0.8125rem;
}

/* Screenshots are captured without the system shadow so one shadow, drawn
   here, follows the window's own rounded corners in both appearances. */
.window {
  margin: var(--space-6) 0 0;
}

.window img {
  width: 100%;
  filter: var(--window-shadow);
}

/* Hero */

.hero {
  padding-top: clamp(3rem, 8vw, 6rem);
  text-align: center;
}

.hero h1 {
  margin: 0;
  font-size: clamp(2rem, 9.2vw, 5rem);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.04em;
}

.hero h1 span {
  display: block;
}

.hero .lead {
  margin-inline: auto;
}

/* What a Mac needs, said next to where visitors decide, not only in the
   details far below. */
.requirement {
  margin: var(--space-2) 0 0;
  color: var(--ink-soft);
  font-size: 0.9375rem;
}

.availability {
  margin: var(--space-5) 0 0;
  font-weight: 500;
  text-wrap: balance;
}

/* The hero window sits on a desktop of its own: a painted landscape, drawn
   by scripts/backdrop.mjs, framed like a display with rounded corners. */
.hero-stage {
  position: relative;
  isolation: isolate;
  width: min(100% - 2 * var(--gutter), var(--stage-measure));
  /* The window keeps its full 1200 points wherever the screen allows, and
     the desktop gives up its margin first: it is all margin on a wide
     screen and a narrow 2rem border on a laptop. Percentages here are of
     the screen's width, which the stage spans less its gutters. */
  --stage-pad: clamp(2rem, (100% - 2 * var(--gutter) - 1200px) / 2, 5rem);

  margin: clamp(2.5rem, 6vw, 4.5rem) auto 0;
  padding: calc(var(--stage-pad) * 0.85) var(--stage-pad);
  border-radius: clamp(14px, 2.2vw, 28px);
  overflow: clip;
}

/* A hairline inside the frame, so a pale wallpaper still has an edge. */
.hero-stage::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.06);
  pointer-events: none;
}

.backdrop img {
  position: absolute;
  z-index: -1;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hero-window {
  margin: 0;
}

.hero-window img {
  filter: var(--stage-window-shadow);
}

/* Chapters */

.chapter {
  padding-top: var(--section-gap);
}

.chapter h2 {
  margin: 0;
  font-size: clamp(1.75rem, 1.1rem + 2.6vw, 2.75rem);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

.chapter h2 span {
  color: var(--ink-soft);
}

.chapter-copy {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  column-gap: var(--space-6);
  align-items: end;
}

.chapter-copy p {
  margin: 0;
}

/* The chapters take turns, so the page has a rhythm rather than a
   template: copy over a window, a window that runs off the left edge with
   the copy beside it, then copy and window centred. */

/* The window keeps its true size and pushes left past the column, where
   the screen's edge cuts into the sidebar, the part every screenshot
   repeats. What the chapter is about stays whole on the right. */
.chapter-bleed {
  display: grid;
  grid-template-columns: minmax(0, 62fr) minmax(0, 38fr);
  grid-template-areas: "window copy";
  column-gap: var(--space-6);
  align-items: center;
}

.chapter-bleed .chapter-copy {
  grid-area: copy;
  grid-template-columns: minmax(0, 1fr);
  row-gap: var(--space-4);
}

.chapter-bleed .window {
  grid-area: window;
  justify-self: end;
  width: var(--measure);
  max-width: none;
  margin: 0;
}

.chapter-centred .chapter-copy {
  display: block;
  text-align: center;
}

.chapter-centred .chapter-copy p {
  max-width: 36em;
  margin: var(--space-4) auto 0;
  color: var(--ink-soft);
}

.promises {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-6) var(--space-7);
  margin: var(--space-7) 0 0;
}

.promises dt,
.specs dt {
  font-weight: 600;
}

.promises dd {
  margin: var(--space-2) 0 0;
  color: var(--ink-soft);
}

/* Specs are looked up by name, so they stay a list: a label column and a
   value beside it. Space between the rows, not rules, keeps them apart. */
.specs {
  margin: var(--space-6) 0 0;
}

.specs div {
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(0, 9fr);
  column-gap: var(--space-5);
}

.specs div + div {
  margin-top: var(--space-4);
}

.specs dd {
  margin: 0;
  max-width: 62ch;
  color: var(--ink-soft);
}

/* The plans are set apart by space alone; the recommended one leads by
   order and size, not by a box. */
.plans {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  column-gap: var(--space-7);
  margin-top: var(--space-6);
}

.plans + .note {
  margin-top: var(--space-6);
}

.plan-note {
  margin-left: var(--space-2);
  color: var(--ink-soft);
  font-weight: 400;
}

.plan h3 {
  margin: 0;
  font-size: inherit;
  font-weight: 600;
}

.plan p {
  margin: var(--space-2) 0 0;
  color: var(--ink-soft);
}

.plan .price {
  color: var(--ink);
  font-size: clamp(2rem, 1.4rem + 2.4vw, 3rem);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.03em;
}

/* The plan beside the recommended one is priced as plainly, a size down. */
.plan + .plan .price {
  font-size: clamp(1.75rem, 1.3rem + 1.6vw, 2.25rem);
}

.price span {
  color: var(--ink-soft);
  font-size: 1.0625rem;
  font-weight: 400;
  letter-spacing: 0;
}

.questions {
  margin-top: var(--space-5);
  border-bottom: 1px solid var(--rule);
}

.questions details {
  border-top: 1px solid var(--rule);
}

.questions summary {
  /* An odd size with a 1px stroke centres the bars on whole pixels, on
     Retina and standard displays alike, so they stay sharp. */
  --marker-size: 11px;
  --marker-stroke: 1px;

  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding-block: var(--space-3);
  font-weight: 600;
  list-style: none;
  cursor: pointer;
}

.questions summary::-webkit-details-marker {
  display: none;
}

/* A plus drawn as two bars, so opening can fold the upright one away and
   leave a minus. It sits on the first line of a question that wraps. */
.questions summary::after {
  content: "";
  flex: none;
  width: var(--marker-size);
  height: var(--marker-size);
  margin-top: calc((1lh - var(--marker-size)) / 2);
  color: var(--ink-soft);
  background:
    linear-gradient(currentColor, currentColor) center / 100% var(--marker-stroke) no-repeat,
    linear-gradient(currentColor, currentColor) center / var(--marker-stroke) 100% no-repeat;
}

.questions details[open] summary::after {
  color: var(--accent);
  background-size:
    100% var(--marker-stroke),
    var(--marker-stroke) 0;
}

.questions details p {
  margin: 0 0 var(--space-4);
  max-width: 62ch;
}

.closing {
  padding-block: var(--section-gap) clamp(4rem, 9vw, 6.5rem);
  text-align: center;
}

.closing img {
  margin-inline: auto;
}

.closing-name {
  margin: var(--space-3) 0 0;
  font-size: clamp(1.75rem, 1.1rem + 2.6vw, 2.75rem);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.03em;
}

.closing .availability {
  margin-top: var(--space-2);
  color: var(--ink-soft);
  font-weight: 400;
}

/* Privacy, support and the 404 page */

.prose {
  max-width: 40rem;
  padding-block: clamp(3rem, 8vw, 5.5rem) clamp(4rem, 10vw, 7rem);
}

.prose h1 {
  margin: 0;
  font-size: clamp(2.25rem, 1.5rem + 3.2vw, 3.5rem);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.035em;
}

.prose h2 {
  margin: var(--space-6) 0 0;
  font-size: 1.375rem;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.015em;
}

.prose h3 {
  margin: var(--space-4) 0 0;
  font-size: inherit;
  font-weight: 600;
}

.prose p,
.prose ul {
  margin: var(--space-3) 0 0;
}

.prose h3 + p {
  margin-top: var(--space-1);
}

.prose ul {
  padding-left: 1.2em;
}

.prose li + li {
  margin-top: var(--space-2);
}

.prose .status {
  margin: 0 0 var(--space-3);
  font-family: var(--font-data);
  font-size: 0.9375rem;
}

.status-code {
  color: var(--caution-text);
}

/* Motion

   All of it lives in this one block, so a visitor who asks the system for
   less motion gets none. Apart from the hero's entrance, each one answers
   something the visitor did. */

@media (prefers-reduced-motion: no-preference) {
  .hero-window {
    animation: window-arrives 800ms cubic-bezier(0.2, 0.8, 0.2, 1) 120ms both;
  }

  @keyframes window-arrives {
    from {
      opacity: 0;
      transform: translateY(24px) scale(0.985);
    }
  }

  /* Following a link between pages: the header holds still and the rest
     cross-fades, where the browser can do that without a script. */
  @view-transition {
    navigation: auto;
  }

  .site-header {
    view-transition-name: site-header;
  }

  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation-duration: 200ms;
  }

  /* Opening a question: the answer fades in. It is an animation keyed to
     the open state, not a transition, because Firefox does not transition
     an answer's styles as it opens. */
  .questions details[open] p {
    animation: answer-arrives 260ms ease both;
  }

  @keyframes answer-arrives {
    from {
      opacity: 0;
    }
  }

  /* Where the browser can animate to a content-sized height, the answer
     grows open and folds shut instead, staying drawn until it has closed. */
  @supports (interpolate-size: allow-keywords) {
    .questions {
      interpolate-size: allow-keywords;
    }

    .questions details[open] p {
      animation: none;
    }


    .questions details::details-content {
      height: 0;
      overflow-y: clip;
      opacity: 0;
      transition:
        height 260ms ease,
        opacity 260ms ease,
        content-visibility 260ms allow-discrete;
    }

    .questions details[open]::details-content {
      height: auto;
      opacity: 1;
    }
  }

  .questions summary::after {
    transition: background-size 200ms ease;
  }

  a {
    transition:
      color 120ms ease,
      text-decoration-color 120ms ease;
  }
}

@media (max-width: 960px) {
  .chapter-bleed {
    display: block;
  }

  .chapter-bleed .chapter-copy {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  }

  .chapter-bleed .window {
    width: auto;
    margin-top: var(--space-6);
  }
}

@media (max-width: 720px) {
  .specs div,
  .chapter-copy,
  .promises,
  .plans {
    grid-template-columns: minmax(0, 1fr);
  }

  .chapter-copy {
    row-gap: var(--space-3);
  }

  .plans {
    row-gap: var(--space-6);
  }

  .specs div {
    row-gap: var(--space-1);
  }

  .site-footer {
    grid-template-columns: minmax(0, 1fr);
  }

  /* A whole window shrunk to a phone is unreadable, so show its leading part
     at a legible size and let the rest run off the edge of the screen. */
  .window {
    margin-right: calc(-1 * var(--gutter));
    overflow-x: clip;
  }

  /* The desktop runs off the right edge with the window on it, and the
     frame, not the window, does the clipping. */
  .hero-stage {
    width: auto;
    margin-left: var(--gutter);
    margin-right: 0;
    padding: var(--space-4) 0 var(--space-4) var(--space-4);
    border-radius: 14px 0 0 14px;
  }

  .hero-window {
    margin: 0;
    overflow-x: visible;
  }

  .window img {
    width: 170%;
    max-width: none;
  }

  /* The broker's window shows its right side, where the stream is, and
     runs off the left edge instead. */
  .chapter-bleed .chapter-copy {
    grid-template-columns: minmax(0, 1fr);
  }

  .chapter-bleed .window {
    margin-right: 0;
    margin-left: calc(-1 * var(--gutter));
  }

  .chapter-bleed .window img {
    margin-left: -70%;
  }

  /* Six centred lines read poorly on a phone. */
  .chapter-centred .chapter-copy {
    text-align: left;
  }

  .chapter-centred .chapter-copy p {
    margin-inline: 0;
  }
}
