/* Layout: the home page is a diff that resolves.

   The page starts on two sides of a seam: the old side on the left, tinted
   red, and the new side on the right, tinted green. The merge window opens
   the seam into three lanes: left, merged and right, as in the app. After the
   merge window, the content runs in the merged lane, between the two outer
   lanes. At the download, the outer lanes turn in and join the merged lane,
   which leads into the Download button.

   On a phone, the seam of the headline is horizontal, as in a unified diff,
   and the outer lanes run down the two edges of the page.

   Colour means a change, as in the app: red for removed, green for added,
   blue for modified and purple for a conflict. The surfaces stay neutral.
   Every font is a system font, so the page loads no font files.

   The other pages use the same colours and type, with a seam under the
   header. */

/* The progress of a scroll animation, from 0 to 1. At rest, and when the
   reader asks for reduced motion, it is 1: the lanes are open and joined. */
@property --p {
  syntax: "<number>";
  inherits: true;
  initial-value: 1;
}

:root {
  color-scheme: light;
  --paper: #FAFAFB;
  --sheet: #FFFFFF;
  --ink: #111114;
  --ink-2: #45454E;
  --ink-3: #686872;
  --rule: #E3E3E9;
  --rule-2: #CFCFD8;
  --focus: #0A66D8;
  --btn: #111114;
  --btn-hover: #2C2C33;
  --btn-ink: #FAFAFB;
  --shadow: rgba(17, 17, 30, .2);

  /* The changes, in the colours of the app. A stroke is a line of the lanes.
     Ink is for text. A field is the tint of a lane. A line is the background
     of a changed line of code. A highlight marks the changed characters. */
  --red: #EB5A50;
  --red-ink: #C0362C;
  --red-field: rgba(235, 90, 80, .075);
  --red-line: rgba(235, 90, 80, .14);
  --red-hl: rgba(235, 90, 80, .3);
  --green: #3FAA5C;
  --green-ink: #1C7A38;
  --green-field: rgba(65, 175, 95, .085);
  --green-line: rgba(65, 175, 95, .15);
  --green-hl: rgba(65, 175, 95, .32);
  --blue-ink: #1F6FD6;
  --blue-line: rgba(10, 132, 255, .09);
  --purple: #6C5CE7;
  --purple-ink: #5A47D6;
  --purple-line: rgba(108, 92, 231, .14);
  --syntax-keyword: #111114;
  --syntax-string: #9A5B00;

  /* The window frame */
  --win-bg: #FFFFFF;
  --win-bar: #F2F2F5;
  --win-rule: #E2E2E8;
  --win-edge: rgba(0, 0, 0, .1);
  --win-pane: #FFFFFF;
  --win-ink: #1D1D1F;
  --win-ink-2: #6E6E78;
  --light-r: #FF5F57;
  --light-y: #FEBC2E;
  --light-g: #28C840;

  --font-body: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", system-ui, sans-serif;
  --font-display: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Helvetica Neue", system-ui, sans-serif;
  --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* The geometry of the page and of the lanes */
  --pad: max(20px, env(safe-area-inset-left, 0px));
  --max: 1200px;
  /* The space from the edge of the window to the content */
  --outer: max(var(--pad), (100vw - var(--max)) / 2);
  /* The width of one stroke of the lanes */
  --seam: 3px;
  /* Half the width of the merged lane */
  --M: clamp(250px, 31vw, 400px);
  /* The space between the seam and the content of one side */
  --side-gap: clamp(28px, 4vw, 56px);
  /* The space between an outer lane and the content of the merged lane */
  --lane-gap: clamp(24px, 3vw, 40px);
  /* The inner edges of the left and the right lane. At the seam, they meet. */
  --L: 50%;
  --R: 50%;
}

/* The dark colours. The same block applies to the system setting and to a
   choice of dark in the appearance switch. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --paper: #111114; --sheet: #1A1A1F; --ink: #F4F4F6; --ink-2: #BEBEC8; --ink-3: #8F8F9B;
    --rule: #2A2A31; --rule-2: #3B3B44; --focus: #5AA2FF;
    --btn: #F4F4F6; --btn-hover: #FFFFFF; --btn-ink: #111114; --shadow: rgba(0, 0, 0, .65);
    --red: #EB5A50; --red-ink: #FF7B70; --red-field: rgba(235, 90, 80, .11); --red-line: rgba(235, 90, 80, .2); --red-hl: rgba(235, 90, 80, .42);
    --green: #41AF5F; --green-ink: #5CCB7B; --green-field: rgba(65, 175, 95, .11); --green-line: rgba(65, 175, 95, .2); --green-hl: rgba(65, 175, 95, .42);
    --blue-ink: #5AA2FF; --blue-line: rgba(10, 132, 255, .17);
    --purple: #7C6DF0; --purple-ink: #A99CFF; --purple-line: rgba(124, 109, 240, .26);
    --syntax-keyword: #F4F4F6; --syntax-string: #E8B16A;
    --win-bg: #18181D; --win-bar: #222228; --win-rule: #2E2E36; --win-edge: rgba(255, 255, 255, .1);
    --win-pane: #18181D; --win-ink: #ECECF0; --win-ink-2: #8F8F9B;
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --paper: #111114; --sheet: #1A1A1F; --ink: #F4F4F6; --ink-2: #BEBEC8; --ink-3: #8F8F9B;
  --rule: #2A2A31; --rule-2: #3B3B44; --focus: #5AA2FF;
  --btn: #F4F4F6; --btn-hover: #FFFFFF; --btn-ink: #111114; --shadow: rgba(0, 0, 0, .65);
  --red: #EB5A50; --red-ink: #FF7B70; --red-field: rgba(235, 90, 80, .11); --red-line: rgba(235, 90, 80, .2); --red-hl: rgba(235, 90, 80, .42);
  --green: #41AF5F; --green-ink: #5CCB7B; --green-field: rgba(65, 175, 95, .11); --green-line: rgba(65, 175, 95, .2); --green-hl: rgba(65, 175, 95, .42);
  --blue-ink: #5AA2FF; --blue-line: rgba(10, 132, 255, .17);
  --purple: #7C6DF0; --purple-ink: #A99CFF; --purple-line: rgba(124, 109, 240, .26);
  --syntax-keyword: #F4F4F6; --syntax-string: #E8B16A;
  --win-bg: #18181D; --win-bar: #222228; --win-rule: #2E2E36; --win-edge: rgba(255, 255, 255, .1);
  --win-pane: #18181D; --win-ink: #ECECF0; --win-ink-2: #8F8F9B;
}

* { box-sizing: border-box; }
html { background: var(--paper); }
body { margin: 0; }
img { max-width: 100%; }
[hidden] { display: none !important; }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
main[id], section[id], div[id] { scroll-margin-top: 24px; }
body {
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
a {
  color: inherit;
  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
  text-decoration-thickness: 1.5px;
  text-underline-offset: .2em;
}
a:hover { text-decoration-color: currentColor; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; border-radius: 4px; }
h1, h2, h3 { margin: 0; text-wrap: balance; }
p { margin: 0; }
code { font-family: var(--font-mono); font-size: .9em; }

/* Text that only a screen reader reads */
.vh {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* A full-width block, with its content in the middle of the page and no
   wider than --max. Its middle is the middle of the page, at the seam. */
.wrap, .split, .stage {
  padding-inline: max(var(--pad), (100% - var(--max)) / 2);
}
.label {
  font-family: var(--font-mono);
  font-size: .74rem;
  font-weight: 500;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.display {
  font-family: var(--font-display);
  font-weight: 800;
  letter-spacing: -.035em;
  line-height: 1.02;
}

.button {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  padding: 14px 24px;
  border-radius: 12px;
  font: 600 1rem/1 var(--font-body);
  text-decoration: none;
  border: 1.5px solid transparent;
  cursor: pointer;
  transition: background .2s, border-color .2s, transform .15s;
}
.button.primary { background: var(--btn); color: var(--btn-ink); }
.button.primary:hover { background: var(--btn-hover); }
.button.secondary { background: var(--sheet); color: var(--ink); border-color: var(--rule-2); }
.button.secondary:hover { border-color: var(--ink); }
.button svg { width: 18px; height: 18px; flex: none; }
.button.large { padding: 19px 32px; font-size: 1.12rem; border-radius: 14px; }
@media (prefers-reduced-motion: no-preference) { .button:hover { transform: translateY(-1px); } }

/* The app icon: the light or the dark picture, as the reader’s appearance */
.app-icon { display: block; }
.app-icon img { display: block; width: 100%; height: auto; }

/* The lanes. Each lane is a tinted field, with a stroke at its inner edge.
   --L and --R are the inner edges of the left and the right field. When they
   are the same, the two strokes meet at the seam. The strokes are boxes, not
   gradients, so that they stay sharp at each width of the window. */
body:has(.lanes-3),
.lanes-3 {
  position: relative;
  isolation: isolate;
  background-image: linear-gradient(90deg, var(--red-field) var(--L), transparent 0 var(--R), var(--green-field) 0);
}
body:has(.lanes-3)::before,
body:has(.lanes-3)::after,
.lanes-3::before,
.lanes-3::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: -1;
  width: var(--seam);
  pointer-events: none;
}
body:has(.lanes-3)::before,
.lanes-3::before { left: calc(var(--L) - var(--seam)); background: var(--red); }
body:has(.lanes-3)::after,
.lanes-3::after { left: var(--R); background: var(--green); }
/* After the merge window, the seam is open: the merged lane is between the
   two outer lanes. It starts to open when 20% of the height of the viewport
   shows the merge window, so that the reader sees it open. */
.lanes-3 {
  --L: calc(50% - var(--M) * var(--p));
  --R: calc(50% + var(--M) * var(--p));
  --from: 20%;
  --to: 75%;
  background-color: var(--paper);
}
/* The content of the merged lane */
.lane-wrap {
  width: min(100% - 2 * var(--pad), 2 * var(--M) - 2 * var(--lane-gap));
  margin-inline: auto;
}

/* Two sides of the seam: the old side on the left and the new side on the
   right. A heading on the old side aligns to the seam. */
.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: calc(2 * var(--side-gap));
}
.split > .old { grid-column: 1; }
.split > .new { grid-column: 2; }

/* Header */
.site-header { position: relative; }
.site-header .wrap { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding-block: 18px; }
.brand { display: flex; align-items: center; gap: 10px; color: var(--ink); text-decoration: none; }
.brand .app-icon { width: 32px; height: 32px; }
.brand span { font-family: var(--font-display); font-weight: 800; font-size: 1.25rem; letter-spacing: -.03em; }
.site-nav { display: flex; align-items: center; gap: clamp(14px, 2.4vw, 28px); font-size: .93rem; font-weight: 500; }
.site-nav a { color: var(--ink-2); text-decoration: none; }
.site-nav a:not(.button):hover { color: var(--ink); }
.site-nav .button { padding: 9px 16px; font-size: .9rem; border-radius: 9px; }
/* On a page with no lanes, a seam under the header: red, then green */
body:not(:has(.lanes-3)) .site-header::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: 0;
  height: var(--seam);
  background: linear-gradient(90deg, var(--red) 50%, var(--green) 0);
}
/* In a narrow window, the links to the sections of the home page would cross
   the seam, so only the documentation and the download stay. */
@media (max-width: 1180px) { .site-nav a[href^="/#"]:not(.button) { display: none; } }
@media (max-width: 720px) { .site-nav a:not(.button) { display: none; } }

/* Hero: the headline is a diff of two lines, across the seam. The line
   numbers are in the gutters beside the seam, and the change bars are at the
   edges of the page, as in the app. */
.hero { padding-block: clamp(28px, 6vh, 72px) clamp(72px, 10vw, 136px); }
.hero-label { grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; margin-bottom: clamp(18px, 3vw, 36px); }
.hero-label .old { grid-column: 1; text-align: right; }
.hero-label .new { grid-column: 2; }
.hero-title {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: subgrid;
  position: relative;
  font-size: clamp(3.25rem, 11vw, 10rem);
  line-height: .9;
  letter-spacing: -.055em;
  isolation: isolate;
}
/* Each side is a stacking context, so that a highlight stays above the
   background of its side and below the letters before it. */
.hero-title .side { display: block; position: relative; z-index: 0; }
.hero-title .old { grid-column: 1; }
.hero-title .new { grid-column: 2; }
.hero-title .line { display: flex; align-items: baseline; }
.hero-title .old .line { justify-content: flex-end; margin-right: calc(-1 * var(--side-gap)); }
.hero-title .new .line { margin-left: calc(-1 * var(--side-gap)); }
.hero-title .line::before,
.hero-title .line::after {
  flex: none;
  width: var(--side-gap);
  font: 500 .875rem/1 var(--font-mono);
  letter-spacing: 0;
  color: var(--ink-3);
}
.hero-title .old .line::after { content: attr(data-n) / ""; text-align: right; padding-right: 16px; }
.hero-title .new .line::before { content: attr(data-n) / ""; padding-left: 16px; }
.hero-title .hl {
  display: inline-block;
  position: relative;
  line-height: .8;
}
.hero-title .hl::before {
  content: "";
  position: absolute;
  inset: 0 -.025em;
  z-index: -1;
  border-radius: .06em;
}
/* A highlight in the middle of a word starts a little after the letter
   before it, because the tight tracking puts the end of that letter over the
   start of the highlight. */
.hero-title .hl.mid::before { left: .02em; }
.hero-title .old .hl::before { background: var(--red-hl); }
.hero-title .new .hl::before { background: var(--green-hl); }
.hero-title .old::before,
.hero-title .new::after {
  content: "";
  position: absolute;
  top: .1em; bottom: .02em;
  width: 6px;
  border-radius: 3px;
}
.hero-title .old::before { left: calc(16px - var(--outer)); background: var(--red); }
.hero-title .new::after { right: calc(16px - var(--outer)); background: var(--green); }
.subhead {
  margin-top: clamp(40px, 5.5vw, 72px);
  text-align: right;
  font-size: clamp(1.6rem, 2.9vw, 2.5rem);
  line-height: 1.08;
  letter-spacing: -.03em;
}
.hero-old { display: flex; flex-direction: column; }
.gap-hatch {
  flex: 1;
  min-height: 48px;
  margin: 28px calc(var(--seam) - var(--side-gap)) 0 calc(-1 * var(--outer));
  background: repeating-linear-gradient(135deg, transparent 0 9px, var(--red-line) 9px 10px);
}
.hero-copy { grid-column: 2; margin-top: clamp(40px, 5.5vw, 72px); display: grid; gap: 18px; max-width: 32em; }
.lede { font-size: 1.12rem; color: var(--ink-2); }
.cta { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin-top: 6px; }
.provenance { color: var(--ink-2); }
.provenance a { color: var(--ink); font-weight: 600; }
.requirements { font-family: var(--font-mono); font-size: .8rem; color: var(--ink-3); }

/* The comparisons: a row of two sides for each kind, then its figure */
.compare { padding-bottom: clamp(56px, 8vw, 104px); }
.row-head { align-items: start; }
.row-head > .old { display: grid; gap: 12px; justify-items: end; text-align: right; }
.row-head > .new { padding-top: 1.95rem; }
.row-head > .new p { color: var(--ink-2); font-size: 1.1rem; max-width: 32em; }
.row-head h2 { font-size: clamp(2.2rem, 4.6vw, 3.75rem); }
.row-head.sub { margin-top: clamp(80px, 11vw, 144px); }
.row-head.sub h3 { font-size: clamp(1.75rem, 3.2vw, 2.6rem); }
.row-head.sub > .new { padding-top: 1.85rem; }
.stage { margin-top: clamp(32px, 4vw, 48px); }

/* A window of the app, drawn with HTML: a title bar, then panes of code. The
   divider between two panes is the seam of the page: red, then green. */
.window {
  background: var(--win-bg);
  color: var(--win-ink);
  border-radius: 12px;
  overflow: hidden;
  font-size: 13px;
  line-height: 1.35;
  box-shadow: 0 0 0 1px var(--win-edge), 0 40px 80px -32px var(--shadow), 0 10px 24px -12px var(--shadow);
  min-width: 0;
}
.titlebar {
  display: flex; align-items: center; gap: 14px;
  height: 40px; padding: 0 14px;
  background: var(--win-bar);
  border-bottom: 1px solid var(--win-rule);
}
.lights { display: flex; gap: 8px; flex: none; }
.lights i { width: 12px; height: 12px; border-radius: 50%; background: var(--light-r); }
.lights i:nth-child(2) { background: var(--light-y); }
.lights i:nth-child(3) { background: var(--light-g); }
.titlebar .title { flex: 1; min-width: 0; text-align: center; color: var(--win-ink-2); font-size: 12px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-right: 50px; }
.panes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.pane { background: var(--win-pane); padding: 10px 0 12px; min-width: 0; }
.pane.left { border-right: var(--seam) solid var(--red); }
.pane.right { border-left: var(--seam) solid var(--green); }
.pane-head { display: flex; justify-content: space-between; gap: 8px; padding: 0 12px 8px; color: var(--win-ink-2); font-size: 11px; white-space: nowrap; }
.pane-head b { color: var(--win-ink); font-weight: 600; overflow: hidden; text-overflow: ellipsis; }
.pane-head span { overflow: hidden; text-overflow: ellipsis; }
/* A line of code: its number, then its text. A gap is the empty line that
   keeps the sides in line, across from a line that only one side has. */
.code { --row: 21px; margin: 0; font: 12px/var(--row) var(--font-mono); color: var(--win-ink-2); }
.code [data-n] { display: block; height: var(--row); padding-right: 12px; white-space: pre; overflow: hidden; text-overflow: ellipsis; }
.code [data-n]::before { content: attr(data-n) / ""; display: inline-block; width: 2.2em; margin-right: 10px; text-align: right; opacity: .6; }
.code .k { color: var(--syntax-keyword); font-weight: 600; }
.code .s { color: var(--syntax-string); }
.code .ins { background: var(--green-line); color: var(--win-ink); }
.code .del { background: var(--red-line); color: var(--win-ink); }
.code .chg { background: var(--blue-line); color: var(--win-ink); }
.code .gap { background: repeating-linear-gradient(135deg, transparent 0 5px, var(--win-rule) 5px 6px); }
.code .ins-char { font-weight: inherit; border-radius: 3px; background: var(--green-hl); }
.statusbar { display: flex; flex-wrap: wrap; gap: 6px 16px; padding: 9px 14px; border-top: 1px solid var(--win-rule); background: var(--win-bar); color: var(--win-ink-2); font-size: 11.5px; }
.statusbar .count { display: inline-flex; align-items: center; gap: 6px; font-weight: 500; }
.statusbar .count::before { content: ""; width: 8px; height: 8px; border-radius: 2px; background: currentColor; }
.statusbar .removed { color: var(--red-ink); }
.statusbar .modified { color: var(--blue-ink); }
.statusbar .added { color: var(--green-ink); }
.statusbar .conflict { color: var(--purple-ink); }

/* The merge window: left, merged and right, as in the app. The merged pane
   is the merged lane of the page, so it opens with the lanes. */
.merge-panes {
  display: grid;
  grid-template-columns: minmax(0, 1fr) calc(2 * var(--M) * var(--p)) minmax(0, 1fr);
}
.merge-panes .merged { overflow: hidden; }
.merge-panes .merged > * { opacity: clamp(0, var(--p) * 2.5 - 1.2, 1); }
.merge-panes .merged .code [data-n] { padding-left: 28px; padding-right: 32px; }
.code .conflict-block { display: block; position: relative; background: var(--purple-line); }
.code .cf { color: var(--win-ink); }
.code .cf-split { box-shadow: inset 0 1px 0 color-mix(in srgb, var(--purple) 60%, transparent); }
.margin-buttons { position: absolute; top: 2px; display: grid; gap: 3px; }
.margin-buttons.use-left { left: 6px; }
.margin-buttons.use-right { right: 6px; }
.margin-buttons i {
  display: grid; place-items: center;
  width: 17px; height: 17px;
  border-radius: 5px;
  background: var(--win-bg);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--purple) 45%, transparent);
  font: 700 11px/1 var(--font-body);
  font-style: normal;
  color: var(--purple-ink);
}

/* The other kinds of comparison: a card for each, on the two sides */
.cards { list-style: none; margin: clamp(64px, 8vw, 104px) 0 0; padding-block: 0; row-gap: clamp(24px, 3vw, 40px); }
.mode {
  display: flex; flex-direction: column; gap: 12px;
  background: var(--sheet);
  border: 1px solid var(--rule);
  border-radius: 14px;
  padding: clamp(22px, 2.4vw, 32px);
  min-width: 0;
  transition: border-color .2s;
}
.mode:hover { border-color: var(--rule-2); }
.mode h3 { font-family: var(--font-display); font-size: 1.35rem; font-weight: 800; letter-spacing: -.02em; line-height: 1.2; }
.mode > p { color: var(--ink-2); font-size: .97rem; line-height: 1.55; }
.fig {
  margin-top: auto;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 9px;
  padding: 14px;
  font: 12px/1.5 var(--font-mono);
  color: var(--ink-2);
  min-width: 0;
}
.images { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.images figure { margin: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; justify-items: center; }
.images figcaption { font-size: 11px; color: var(--ink-3); }
.swatch-image {
  width: 100%; aspect-ratio: 3 / 2; border-radius: 6px; border: 1px solid var(--rule);
  background:
    radial-gradient(circle at 30% 60%, var(--red) 0 18%, transparent 19%),
    linear-gradient(160deg, var(--sheet), var(--rule));
}
.swatch-image.after {
  background:
    radial-gradient(circle at 62% 42%, var(--green) 0 18%, transparent 19%),
    linear-gradient(160deg, var(--sheet), var(--rule));
}
/* The other views of the image demo: one picture, the size of one side */
.image-view[hidden] { display: none; }
.images.single { grid-template-columns: minmax(0, 1fr); }
.images.single figure > .swatch-image { width: calc(50% - 5px); }
/* Overlay, as in the app: the new version over the old version, with the
   opacity of the slider */
.swatch-image:has(.overlay) { position: relative; overflow: hidden; }
.swatch-image.overlay {
  position: absolute; inset: 0;
  width: auto; height: auto; aspect-ratio: auto;
  border: 0; border-radius: 0;
  opacity: var(--overlay, .5);
}
.overlay-mix { display: flex; align-items: center; gap: 6px; width: max(50% - 5px, min(100%, 220px)); }
.overlay-mix input { flex: 1; min-width: 0; margin: 0; accent-color: var(--ink); }
/* Difference, as in the app: the changed pixels red, the others dark grey */
.swatch-image.difference {
  background:
    radial-gradient(circle at 30% 60%, #FF0000 0 18%, transparent 19%),
    radial-gradient(circle at 62% 42%, #FF0000 0 18%, transparent 19%),
    #141414;
}
.segments { display: flex; flex-wrap: wrap; margin-top: 12px; border: 1px solid var(--rule-2); border-radius: 6px; overflow: hidden; width: fit-content; max-width: 100%; }
.segments button {
  font: inherit;
  font-size: 12px;
  padding: 5px 11px;
  border: 0;
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
}
.segments button + button { border-left: 1px solid var(--rule-2); }
.segments button:hover { color: var(--ink); }
.segments button:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }
.segments button[aria-pressed="true"] { background: var(--ink); color: var(--paper); }
/* A phone: the segments fill the width, on one line */
@media (max-width: 720px) {
  .segments { width: 100%; flex-wrap: nowrap; }
  .segments button { flex: 1 1 auto; padding: 5px 6px; font-size: 11px; }
}
.tree { list-style: none; margin: 0; padding: 0; display: grid; gap: 3px; }
.tree li { display: grid; grid-template-columns: 1.4em minmax(0, 1fr); gap: 4px; overflow: hidden; white-space: nowrap; }
.tree li::before { content: attr(data-mark) / ""; text-align: center; font-weight: 600; }
.tree .indent { padding-left: 1.4em; }
.tree .added { color: var(--green-ink); }
.tree .removed { color: var(--red-ink); }
.tree .modified { color: var(--blue-ink); }
.tree span { overflow: hidden; text-overflow: ellipsis; }
.terminal { margin: 0; display: grid; gap: 3px; white-space: pre-wrap; overflow-wrap: anywhere; }
.terminal .prompt { color: var(--green-ink); margin-right: .6em; user-select: none; }
.terminal .comment { color: var(--ink-3); }
.tags { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.tags li { padding: 2px 9px; border-radius: 20px; background: var(--sheet); border: 1px solid var(--rule); font-size: 11px; color: var(--ink-2); }

/* A link to the documentation: the label Docs, then the title of the page or
   the section. It follows the text that it gives more detail about. */
.docs-link a { font-size: .92rem; font-weight: 600; }
.docs-link .label { display: inline-block; margin-right: .7em; }

/* The merged lane: the sections after the merge window */
.merge-stage { margin-top: 0; }
.section { padding-top: clamp(88px, 12vw, 160px); }
.lanes-3 > .section:last-child { padding-bottom: clamp(88px, 12vw, 160px); }
.section-head { display: grid; gap: 14px; margin-bottom: clamp(32px, 4vw, 52px); }
.section-head h2 { font-size: clamp(2.2rem, 4.6vw, 3.6rem); }
.section-head p:not(.label) { color: var(--ink-2); font-size: 1.1rem; }

.features { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 36px 40px; }
.feature { display: flex; flex-direction: column; gap: 8px; border-top: 1px solid var(--rule-2); padding-top: 16px; min-width: 0; }
.feature h3 { font-size: 1.12rem; font-weight: 700; }
.feature p { color: var(--ink-2); font-size: .97rem; line-height: 1.55; }

.points { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.points li { display: grid; align-content: start; gap: 6px; padding: 18px; border-radius: 14px; background: var(--sheet); border: 1px solid var(--rule); }
.points b { font-weight: 700; }
.points b::before { content: "✓" / ""; margin-right: .45em; color: var(--green-ink); }
.points span { color: var(--ink-2); font-size: .93rem; line-height: 1.5; }

.faq-list { display: grid; }
.faq-list details { border-top: 1px solid var(--rule-2); }
.faq-list details:last-child { border-bottom: 1px solid var(--rule-2); }
.faq-list summary { list-style: none; cursor: pointer; display: flex; justify-content: space-between; gap: 20px; padding: 18px 0; font-weight: 600; font-size: 1.06rem; }
.faq-list summary::-webkit-details-marker { display: none; }
.faq-list summary::after { content: "+" / ""; font: 500 1.3rem/1 var(--font-mono); color: var(--ink-3); }
.faq-list details[open] summary::after { content: "−" / ""; }
.faq-list details p { color: var(--ink-2); padding-bottom: 20px; }
.faq-list details p.docs-link { margin-top: -8px; }

.pricing { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); gap: clamp(24px, 3vw, 40px); align-items: start; }
.plan { background: var(--sheet); border: 1px solid var(--rule); border-radius: 18px; padding: clamp(24px, 3vw, 34px); display: grid; gap: 18px; min-width: 0; box-shadow: 0 24px 48px -32px var(--shadow); }
.plan h3 { font-size: 1.05rem; font-weight: 600; color: var(--ink-3); }
.price { display: grid; gap: 6px; }
.price b { font-family: var(--font-display); font-weight: 800; font-size: clamp(2.8rem, 5vw, 3.6rem); line-height: 1; letter-spacing: -.04em; font-variant-numeric: tabular-nums; }
.price span { color: var(--ink-3); font-size: .95rem; }
.plan-list { list-style: none; margin: 0; padding: 0; display: grid; }
.plan-list li { display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: 8px; padding: 8px 0; border-bottom: 1px solid var(--rule); font-size: .95rem; }
.plan-list li::before { content: "✓" / ""; color: var(--green-ink); font-weight: 700; }
.plan .button { width: 100%; font-size: 1.05rem; }
.plan-notes { display: grid; gap: 12px; font-size: .95rem; }
.plan-notes .trust { color: var(--ink-2); }

/* Download: the outer lanes turn in and come together in the middle, where
   their arrowheads meet. The two arrowheads turn into one arrow, which goes
   down and points at the Download button. The fields of the outer lanes
   taper to the turn. */
/* The join runs in the last part of the scroll, so that it ends exactly at
   the bottom of the page, at each height of the window. The arrow and the
   space under the button grow with the height of the window, so that the
   join stays near the middle of a tall window. */
.download { --tail: 300px; background: var(--paper); }
.join {
  --L: calc(50% - var(--M));
  --R: calc(50% + var(--M));
  /* The space between the heading and the turn, and between the turn and
     the button */
  --drop: clamp(56px, 7vw, 96px);
  --stem-length: clamp(72px, 12svh, 180px);
  /* The space between the point of the arrow and the button */
  --gap: 12px;
  /* The length of the arrow, from the middle of the line to its point */
  --reach: calc(var(--stem-length) + var(--seam) / 2 - var(--gap));
  --radius: clamp(36px, 5vw, 72px);
  /* The space between the middle and the point of an arrowhead, while the
     two arrowheads face each other */
  --tip: 10px;
  /* First the lanes turn in and grow until their arrowheads face each other
     in the middle. Then the points of the arrowheads meet. At that moment
     the two arrowheads become one black arrow, and the arrow goes down to
     the button. */
  --arms: clamp(0, var(--p) / .4, 1);
  --meet: clamp(0, (var(--p) - .4) / .1, 1);
  /* 0 until the points meet, then 1 */
  --joined: clamp(0, (var(--meet) - 1) * 1000 + 1, 1);
  --stem: clamp(0, (var(--p) - .5) / .5, 1);
  position: relative;
  padding-top: clamp(88px, 12vw, 160px);
  padding-bottom: calc(var(--drop) + var(--stem-length));
}
.download-head { position: relative; display: grid; justify-items: center; text-align: center; gap: 18px; }
.download-head .app-icon { width: 96px; height: 96px; filter: drop-shadow(0 16px 22px var(--shadow)); }
.download-head h2 { font-size: clamp(2.4rem, 5.4vw, 4.4rem); }
.download-head p { color: var(--ink-2); font-size: 1.12rem; }
.join .field {
  position: absolute;
  top: 0;
  bottom: calc(var(--stem-length) + var(--radius) * .4);
}
.join .field.left { left: 0; width: var(--L); background: var(--red-field); border-bottom-left-radius: 100% 80%; }
.join .field.right { right: 0; width: calc(100% - var(--R)); background: var(--green-field); border-bottom-right-radius: 100% 80%; }
/* An arm continues its lane down, turns in and runs to the middle. While it
   is short, its corner is small, so the lane bends in as the arm grows. */
.join .arm {
  position: absolute;
  top: 0;
  bottom: var(--stem-length);
  border: 0 solid;
  border-bottom-width: var(--seam);
}
.join .arm.left {
  left: calc(var(--L) - var(--seam));
  width: calc(var(--seam) + (50% - var(--L) - var(--tip)) * var(--arms) + var(--tip) * var(--meet));
  border-left-width: var(--seam);
  border-bottom-left-radius: var(--radius);
  color: var(--red);
}
.join .arm.right {
  right: calc(100% - var(--R) - var(--seam));
  width: calc(var(--seam) + (var(--R) - 50% - var(--tip)) * var(--arms) + var(--tip) * var(--meet));
  border-right-width: var(--seam);
  border-bottom-right-radius: var(--radius);
  color: var(--green);
}
/* An arrowhead at the end of each arm: > on the left, < on the right. Its
   point is on the end of the line. Its centre is on the middle of the line,
   which is the bottom border of the arm. */
.join .head {
  position: absolute;
  bottom: calc(-12px - var(--seam) / 2);
  width: 14px;
  height: 24px;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-width: var(--seam);
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: clamp(0, var(--arms) * 8, 1);
  transform: translateY(calc(var(--reach) * var(--stem)));
}
/* When the points meet, the two arrowheads make an X, and its upper half is
   an arrow that points down. Then the lower legs go, and the upper legs are
   black, so that one black arrow stays. */
.join .arm.left .head { right: -2px; color: color-mix(in oklab, var(--red), var(--ink) calc(var(--joined) * 100%)); }
.join .arm.right .head { left: -2px; color: color-mix(in oklab, var(--green), var(--ink) calc(var(--joined) * 100%)); }
.join .head .lower { opacity: calc(1 - var(--joined)); }
/* The shaft of the arrow. It starts in the middle of the line, under the
   arms, and ends at the point of the arrow. */
.join .stem {
  position: absolute;
  left: calc(50% - var(--seam) / 2);
  bottom: var(--gap);
  height: var(--reach);
  width: var(--seam);
  background: var(--ink);
  transform-origin: top;
  transform: scaleY(var(--stem));
}
.download-action { display: grid; justify-items: center; gap: 16px; padding-bottom: clamp(80px, 12svh, 200px); }

/* The scroll animations. A browser with scroll-driven animations drives --p
   from the scroll position. `data-progress` follows the entry of its element
   into the viewport, over the range from --from to --to.
   `data-progress="page-end"` follows the last --tail of the scroll of the
   page. Other browsers get --p from motion.js. With reduced motion, --p stays
   at 1. */
@keyframes lane-progress {
  from { --p: 0; }
  to { --p: 1; }
}
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    [data-progress] {
      animation: lane-progress linear both;
      animation-timeline: view();
      animation-range: entry var(--from) entry var(--to);
    }
    [data-progress="page-end"] {
      animation-timeline: scroll(root);
      animation-range: calc(100% - var(--tail)) 100%;
    }
  }
}

/* Footer */
.site-footer { background: var(--paper); border-top: 1px solid var(--rule); }
.site-footer .wrap { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px 32px; padding-block: 28px 40px; font-size: .88rem; color: var(--ink-3); }
.site-footer nav { display: flex; gap: 20px; flex-wrap: wrap; }
.site-footer a { color: var(--ink-2); text-decoration: none; }
.site-footer a:hover { color: var(--ink); }
.site-footer .legal { flex-basis: 100%; font-size: .8rem; }
/* The appearance switch: auto, light or dark */
.appearance { display: inline-flex; align-items: center; gap: 4px; }
.appearance .label { margin-right: 6px; }
.appearance button {
  font: 500 .8rem/1 var(--font-body);
  padding: 6px 11px;
  border-radius: 999px;
  border: 1px solid var(--rule-2);
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
}
.appearance button:hover { color: var(--ink); border-color: var(--ink-3); }
.appearance button[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper); }

/* Text pages: support, privacy, terms, release notes */
.text-page { padding-block: clamp(40px, 7vw, 80px) clamp(72px, 10vw, 120px); display: grid; gap: clamp(24px, 4vw, 36px); }
.text-page h1 { font-size: clamp(2.6rem, 6vw, 4rem); letter-spacing: -.045em; }
.prose { max-width: 40em; display: grid; gap: 16px; }
.prose h2 { font-size: 1.3rem; font-weight: 700; margin-top: 16px; letter-spacing: -.01em; }
.prose p, .prose li { color: var(--ink-2); }
.prose ul { margin: 0; padding-left: 1.2em; display: grid; gap: 6px; }
.prose .updated { font-family: var(--font-mono); font-size: .8rem; color: var(--ink-3); }
.email { font-weight: 600; font-size: 1.15rem; }
.release { max-width: 40em; display: grid; gap: 14px; border-top: 1px solid var(--rule-2); padding-top: 20px; }
.release-head { display: flex; align-items: baseline; gap: 16px; flex-wrap: wrap; }
.release-head h2 { font-family: var(--font-display); font-weight: 800; font-size: 2rem; line-height: 1; letter-spacing: -.03em; }
.release h3 { font-size: 1rem; font-weight: 700; margin: 10px 0 0; }
.release p, .release li { color: var(--ink-2); }
.release ul { margin: 0; padding-left: 1.2em; display: grid; gap: 6px; }

/* The purchase: the problem line of the checkout, and the keys on the thank-you page. */
.buy-status { margin-top: 16px; color: var(--ink-2); }
.licence-keys { display: grid; gap: 10px; }
.licence-key {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--rule); border-radius: 12px;
  background: var(--sheet);
}
.licence-key code {
  flex: 1; min-width: 0;
  font-family: var(--font-mono); font-size: .78rem; line-height: 1.5;
  color: var(--ink); word-break: break-all;
}
.licence-key .button { padding: 10px 16px; font-size: .92rem; border-radius: 8px; }
.waiting { display: flex; align-items: center; gap: 12px; }
.spinner {
  flex: none; width: 20px; height: 20px;
  border-radius: 50%;
  border: 2.5px solid var(--rule); border-top-color: var(--ink);
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation-duration: 2.4s; } }

/* Documentation: a sidebar of pages, and an article. On a narrow screen the
   sidebar goes after the article, and a link at the top jumps to it. */
.docs {
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr);
  gap: clamp(32px, 5vw, 64px);
  align-items: start;
  padding-block: clamp(32px, 5vw, 56px) clamp(64px, 9vw, 112px);
}
.docs-nav { grid-column: 1; grid-row: 1; position: sticky; top: 24px; max-height: calc(100vh - 48px); overflow-y: auto; display: grid; gap: 22px; font-size: .92rem; padding-bottom: 8px; }
.docs-article { grid-column: 2; grid-row: 1; min-width: 0; max-width: 46em; }
.docs-home { font-weight: 700; color: var(--ink); text-decoration: none; }
.docs-group { display: grid; gap: 8px; }
.docs-nav ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.docs-nav a { color: var(--ink-2); text-decoration: none; }
.docs-nav a:hover { color: var(--ink); }
.docs-nav a[aria-current="page"] { color: var(--ink); font-weight: 600; }
.docs-nav .docs-toc { margin: 6px 0 6px 2px; padding-left: 12px; border-left: var(--seam) solid var(--rule-2); gap: 3px; font-size: .86rem; }
.docs-nav .docs-toc a { color: var(--ink-3); }
.docs-nav .docs-toc a:hover { color: var(--ink); }
.docs-jump { display: none; margin-bottom: 16px; font-size: .92rem; }
.docs-article h1 { font-size: clamp(2.3rem, 5vw, 3.4rem); letter-spacing: -.045em; margin-bottom: clamp(20px, 3vw, 28px); }

.docs-body { display: grid; gap: 16px; }
.docs-body > * { margin: 0; }
.docs-body h2, .docs-body h3 { scroll-margin-top: 24px; }
.docs-body h2 { font-size: 1.5rem; font-weight: 800; letter-spacing: -.02em; line-height: 1.25; margin-top: 28px; padding-top: 20px; border-top: 1px solid var(--rule-2); }
.docs-body h3 { font-size: 1.1rem; font-weight: 700; line-height: 1.3; margin-top: 12px; }
.docs-body p, .docs-body li, .docs-body td { color: var(--ink-2); }
.docs-body strong { color: var(--ink); font-weight: 600; }
.docs-body ul, .docs-body ol { padding-left: 1.3em; display: grid; gap: 6px; }
.docs-body li > ul, .docs-body li > ol { margin-top: 6px; }
.docs-body li > p { margin: 0; }
.docs-body code {
  font-family: var(--font-mono); font-size: .84em;
  padding: .1em .35em; border-radius: 5px;
  background: var(--sheet); border: 1px solid var(--rule);
  overflow-wrap: anywhere;
}
.docs-body pre {
  padding: 14px 16px; border-radius: 10px;
  background: var(--sheet); border: 1px solid var(--rule);
  overflow-x: auto; line-height: 1.5;
}
.docs-body pre code { padding: 0; border: 0; background: none; font-size: .82rem; overflow-wrap: normal; }
.docs-body kbd {
  font-family: var(--font-body); font-size: .85em; font-weight: 600;
  padding: .05em .4em; border-radius: 5px;
  border: 1px solid var(--rule-2); border-bottom-width: 2px; background: var(--sheet); color: var(--ink);
}
.docs-body blockquote {
  padding: 14px 18px; border-left: var(--seam) solid var(--ink); border-radius: 0 8px 8px 0;
  background: var(--sheet); display: grid; gap: 10px;
}
.docs-body blockquote p { margin: 0; }
.table-wrap { overflow-x: auto; }
.docs-body table { border-collapse: collapse; width: 100%; font-size: .94rem; }
.docs-body th, .docs-body td { text-align: left; vertical-align: top; padding: 9px 12px; border-bottom: 1px solid var(--rule); }
.docs-body th { color: var(--ink); font-weight: 600; border-bottom-color: var(--ink-3); }

.shot { margin: 12px 0; display: grid; gap: 10px; justify-items: center; }
.shot img { display: block; max-width: 100%; height: auto; }
.shot-app img { filter: drop-shadow(0 10px 24px var(--shadow)); }
.shot-browser img { border-radius: 10px; border: 1px solid var(--rule); box-shadow: 0 10px 28px var(--shadow); }
.shot figcaption { font-size: .88rem; color: var(--ink-3); text-align: center; max-width: 36em; }

.docs-pager { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: clamp(40px, 6vw, 56px); }
.docs-pager a { display: grid; gap: 4px; padding: 14px 16px; border: 1px solid var(--rule); border-radius: 12px; background: var(--sheet); color: var(--ink); text-decoration: none; font-weight: 600; }
.docs-pager a:hover { border-color: var(--ink-3); }
.docs-pager a[rel="next"] { text-align: right; grid-column: 2; }

.docs-contents { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px 36px; margin-top: 16px; }
.docs-contents:empty { display: none; }
.docs-section { display: grid; gap: 12px; align-content: start; }
.docs-section h2.label { margin: 0; padding: 0; border: 0; font-size: .74rem; font-weight: 500; }
.docs-section ul { list-style: none; padding: 0; display: grid; gap: 12px; }
.docs-section li { display: grid; gap: 2px; }
.docs-section a { font-weight: 600; text-decoration: none; }
.docs-section a:hover { text-decoration: underline; }
.docs-section span { font-size: .92rem; color: var(--ink-3); }

@media (max-width: 860px) {
  .docs { grid-template-columns: minmax(0, 1fr); }
  .docs-article, .docs-nav { grid-column: 1; grid-row: auto; }
  .docs-nav { position: static; max-height: none; overflow: visible; border-top: 1px solid var(--rule); padding-top: 28px; }
  .docs-jump { display: block; }
}

/* A narrow window: one column for the content of the merged lane */
@media (max-width: 1000px) {
  .features, .pricing { grid-template-columns: minmax(0, 1fr); }
  .points { grid-template-columns: minmax(0, 1fr); }
  .plan { max-width: 480px; }
}

/* A phone: one column. The headline is a unified diff, with the old lines
   above the new lines, and the outer lanes run down the edges of the page. */
@media (max-width: 720px) {
  :root { --pad: max(26px, env(safe-area-inset-left, 0px)); --M: calc(25vw - 13px); }
  body:has(.lanes-3), .lanes-3, .join { --L: 10px; --R: calc(100% - 10px); }
  .split { grid-template-columns: minmax(0, 1fr); }
  .split > .old, .split > .new { grid-column: 1; }

  .hero { padding-top: 16px; }
  .hero-label { display: block; }
  .hero-label .vh { position: static; width: auto; height: auto; clip-path: none; }
  .hero-title {
    font-size: clamp(3rem, 18vw, 5.25rem);
    margin-inline: calc(-1 * var(--pad));
  }
  .hero-title .old, .hero-title .new { grid-column: 1; }
  .hero-title .side { padding: 14px var(--pad) 16px 12px; }
  .hero-title .old {
    border-bottom: var(--seam) solid var(--red);
    background: linear-gradient(90deg, transparent 7px, var(--red) 0 10px, transparent 0), linear-gradient(var(--red-field), var(--red-field)), var(--paper);
  }
  .hero-title .new {
    border-top: var(--seam) solid var(--green);
    background: linear-gradient(270deg, transparent 7px, var(--green) 0 10px, transparent 0), linear-gradient(var(--green-field), var(--green-field)), var(--paper);
  }
  .hero-title .old .line, .hero-title .new .line { justify-content: flex-start; margin: 0; }
  .hero-title .side .line::before { width: 5.4ch; margin-right: 10px; padding: 0 0 0 4px; text-align: left; white-space: pre; }
  .hero-title .old .line::after { content: none; }
  .hero-title .old .line::before { content: attr(data-n) "   −" / ""; }
  .hero-title .new .line::before { content: "  " attr(data-n) " +" / ""; }
  .hero-title .old::before, .hero-title .new::after { content: none; }
  .subhead { text-align: left; margin-top: 32px; }
  .hero-copy { margin-top: 18px; }

  .row-head > .old { justify-items: start; text-align: left; }
  .row-head > .new { padding-top: 14px; }
  .cards { margin-top: 56px; }
  .merge-panes .pane:not(.merged) .code [data-n]::before { content: none; }
  .merge-panes .pane:not(.merged) .code [data-n] { padding-left: 8px; }
  .merge-panes .merged .code [data-n] { padding-left: 24px; padding-right: 24px; }
  .merge-panes .merged .code [data-n]::before { width: 1.2em; margin-right: 6px; }
  .pane-head span { display: none; }
  .lane-wrap { width: auto; margin-inline: var(--pad); }
  .join { --radius: 28px; }
  .gap-hatch { display: none; }
}
