/* WinDuo — scene painter's flat.
 *
 * Prussian blue distemper at page scale, chalk snap-lines struck across it,
 * oxide red as the only saturated mark. Rules and graticules are drawn; there
 * are no cards anywhere in this sheet.
 */

:root {
  /* Distemper blue, mixed three ways. The ground carries the page. */
  --blue-deep: #0d2135;
  --blue: #123049;
  --blue-lift: #1a3d59;
  --blue-line: #2d5875;

  /* Chalk, struck and rubbed back. All three pass AA on --blue. */
  --chalk: #f4f0e6;      /* 12.4:1 */
  --chalk-soft: #c6cdd2;  /* 7.8:1 */
  --chalk-faint: #93a3af; /* 4.6:1 */

  /* Oxide red, the working mark. Only ever on the blue, never as body text. */
  --oxide: #d2542c;
  --oxide-lift: #ea6c3f;
  --linen: #d9cdb4;

  --measure: 34rem;
  --gap: clamp(1.5rem, 4vw, 4rem);
  --bay-y: clamp(4.5rem, 11vh, 9rem);

  --display: "Big Shoulders Display", "Arial Narrow", sans-serif;
  --text: "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* Exponential ease-out. One curve for the whole sheet. */
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

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

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

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

body {
  margin: 0;
  background: var(--blue);
  color: var(--chalk);
  font-family: var(--text);
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.12rem);
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

h1, h2, h3 {
  font-family: var(--display);
  font-weight: 700;
  line-height: 0.94;
  letter-spacing: -0.01em;
  text-wrap: balance;
  margin: 0;
}

h2 {
  font-size: clamp(2.1rem, 1.4rem + 3vw, 3.6rem);
  margin-bottom: 0.7em;
}

h3 {
  font-size: clamp(1.25rem, 1.1rem + 0.7vw, 1.6rem);
  margin-bottom: 0.35em;
  letter-spacing: 0.005em;
}

p { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }

a {
  color: var(--chalk);
  text-decoration-color: var(--oxide);
  text-decoration-thickness: 2px;
  text-underline-offset: 0.18em;
  transition: color 180ms var(--ease);
}

a:hover { color: var(--oxide-lift); }

:focus-visible {
  outline: 2px solid var(--oxide-lift);
  outline-offset: 3px;
}

code {
  font-family: ui-monospace, "Cascadia Mono", "Consolas", monospace;
  font-size: 0.88em;
  color: var(--linen);
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 20;
  background: var(--oxide);
  color: #fff;
  padding: 0.7rem 1.1rem;
  text-decoration: none;
}

.skip:focus { left: 0.6rem; top: 0.6rem; }

/* --- Snap lines: the page's only divider ------------------------------ */

.snap {
  border: 0;
  height: 1px;
  margin: 0;
  background: var(--blue-line);
  position: relative;
}

/* A struck line has a mark where the chalk was pinned. */
.snap::after {
  content: "";
  position: absolute;
  left: clamp(1.5rem, 6vw, 6rem);
  top: -2px;
  width: 5px;
  height: 5px;
  background: var(--oxide);
  border-radius: 50%;
}

/* --- Nav bar ---------------------------------------------------------- */

.bar {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(13, 33, 53, 0.94);
  border-bottom: 1px solid var(--blue-line);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
}

.bar__inner {
  max-width: 78rem;
  margin: 0 auto;
  padding: 0 var(--gap);
  height: 46px;
  display: flex;
  align-items: center;
  gap: 1rem;
}

/* Only present on pages reached by navigating away from the main page (the
   download destination). A back affordance sits leading, beside identity,
   never among the trailing action list where the eye does not expect it. */
.bar__link--back {
  color: var(--chalk-soft);
  padding-left: 0;
}

.bar__link--back:hover { color: var(--chalk); background: transparent; }

.bar__name {
  font-size: 0.84rem;
  color: var(--chalk-faint);
  text-decoration: none;
  white-space: nowrap;
  flex: none;
  transition: color 180ms var(--ease);
}

.bar__name:hover { color: var(--chalk-soft); }

.bar__name strong {
  color: var(--chalk-soft);
  font-weight: 600;
}

.bar__links {
  display: flex;
  align-items: center;
  gap: 0.15rem;
  list-style: none;
  padding: 0;
  margin: 0 0 0 auto;
}

.bar__divider {
  width: 1px;
  height: 16px;
  background: var(--blue-line);
  margin: 0 0.4rem;
  flex: none;
}

.bar__link {
  display: inline-flex;
  align-items: center;
  gap: 0.38rem;
  padding: 0.3rem 0.65rem;
  font-size: 0.82rem;
  text-decoration: none;
  color: var(--chalk-soft);
  border-radius: 2px;
  transition: color 180ms var(--ease), background 180ms var(--ease);
  white-space: nowrap;
}

.bar__link:hover { color: var(--chalk); background: rgba(255, 255, 255, 0.06); }
.bar__link:focus-visible { outline: 2px solid var(--oxide-lift); }

/* The primary download stands out slightly but does not shout. */
.bar__link--primary {
  color: var(--oxide-lift);
}

.bar__link--primary:hover { color: var(--oxide-lift); background: rgba(210, 84, 44, 0.12); }

/* Support links are quieter than navigation; they should not compete for eye. */
.bar__link--dim { color: var(--chalk-faint); }
.bar__link--dim:hover { color: var(--chalk-soft); }

/* A glyph-only link (the X follow button) gets a square hit target instead of
   the text link's asymmetric horizontal padding. */
.bar__link--icon {
  padding: 0.4rem;
  color: var(--chalk-soft);
}

/* On narrow screens, collapse the attribution to just the icon by hiding the
   text, and drop the divider. The follow icon stays even when Support's text
   links go, since it costs almost no width. */
@media (max-width: 35rem) {
  .bar__name { display: none; }
  .bar__divider { display: none; }
  .bar__links { margin-left: auto; }
}

@media (max-width: 28rem) {
  .bar__link--dim { display: none; }
}

.flat {
  position: relative;
  background:
    radial-gradient(120% 90% at 18% 8%, var(--blue-lift) 0%, transparent 55%),
    linear-gradient(178deg, var(--blue) 0%, var(--blue-deep) 100%);
  isolation: isolate;
}

/* Canvas weave. A flat is stretched cloth, not a flat colour. */
.flat__grain {
  position: absolute;
  inset: 0;
  z-index: -1;
  opacity: 0.5;
  background-image:
    repeating-linear-gradient(90deg, rgba(255,255,255,0.028) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(0deg, rgba(0,0,0,0.05) 0 1px, transparent 1px 3px);
}

.snap--head { display: none; }

.flat__inner {
  max-width: 78rem;
  margin: 0 auto;
  padding: clamp(3rem, 8vh, 6rem) var(--gap) clamp(3.5rem, 9vh, 6.5rem);
  display: grid;
  gap: clamp(2.5rem, 6vw, 5rem);
  grid-template-columns: 1fr;
  align-items: center;
}

@media (min-width: 62rem) {
  .flat__inner {
    grid-template-columns: minmax(0, 27rem) minmax(0, 1fr);
    min-height: 100svh;
  }
}

.wordmark {
  font-size: clamp(4rem, 2rem + 11vw, 8.5rem);
  font-weight: 800;
  letter-spacing: -0.028em;
  line-height: 0.82;
  margin-bottom: 0.34em;
}

/* The sightline: the seat the painted illusion is built for. */
.wordmark::after {
  content: "";
  display: block;
  height: 3px;
  width: 100%;
  margin-top: 0.22em;
  background: linear-gradient(90deg, var(--oxide) 0 22%, var(--blue-line) 22% 100%);
}

.lede {
  font-size: clamp(1.16rem, 1rem + 0.7vw, 1.5rem);
  line-height: 1.42;
  max-width: 26ch;
  margin-bottom: 0.85em;
}

.lede--quiet {
  color: var(--chalk-soft);
  font-size: clamp(1rem, 0.95rem + 0.25vw, 1.12rem);
  line-height: 1.55;
  max-width: 34ch;
  margin-bottom: 1.9em;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
  margin-bottom: 1.2rem;
}

.button {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.78rem 1.35rem;
  font-family: var(--text);
  font-size: 0.98rem;
  font-weight: 600;
  text-decoration: none;
  color: var(--chalk);
  border: 1.5px solid var(--blue-line);
  background: transparent;
  transition: border-color 200ms var(--ease), background 200ms var(--ease),
              transform 200ms var(--ease), color 200ms var(--ease);
}

.button:hover {
  color: var(--chalk);
  border-color: var(--chalk-faint);
  background: rgba(244, 240, 230, 0.06);
}

.button--primary {
  background: var(--oxide);
  border-color: var(--oxide);
  color: #fff8f4;
  /* Paint sits on the cloth: a real offset and a soft blur, not a halo. */
  box-shadow: 0 3px 0 #9c3a1c, 0 10px 22px -10px rgba(0, 0, 0, 0.7);
}

.button--primary:hover {
  background: var(--oxide-lift);
  border-color: var(--oxide-lift);
  color: #fff8f4;
  transform: translateY(-1px);
  box-shadow: 0 4px 0 #9c3a1c, 0 14px 26px -10px rgba(0, 0, 0, 0.7);
}

.button--primary:active { transform: translateY(1px); box-shadow: 0 1px 0 #9c3a1c; }

.icon { width: 1em; height: 1em; flex: none; }

/* --- Dropdown menu ------------------------------------------------------
 * One system for every details/summary menu on the site: the hero's "Get
 * WinDuo" choice and the nav bar's "Support" choice both use it. A native
 * details element, so both work with scripting off and are keyboard operable
 * for free. `.grab` is the hero's larger button-triggered variant; `.drop` is
 * the compact nav-bar trigger. Both share the `__menu`/`__option` panel.
 * -------------------------------------------------------------------- */

.grab, .drop { position: relative; }

.grab > summary, .drop > summary {
  cursor: pointer;
  list-style: none;
}

.grab > summary::-webkit-details-marker,
.drop > summary::-webkit-details-marker { display: none; }

.grab__chevron, .drop__chevron {
  transition: transform 200ms var(--ease);
  opacity: 0.8;
}

.grab[open] > summary .grab__chevron,
.drop[open] > summary .drop__chevron { transform: rotate(180deg); }

/* The compact trigger is a bar__link already; it only needs the chevron. */
.drop__chevron { width: 0.7em; height: 0.7em; margin-left: 0.1rem; }

.drop__menu, .grab__menu {
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 0;
  z-index: 10;
  min-width: min(22rem, calc(100vw - 2 * var(--gap)));
  background: var(--blue-deep);
  border: 1.5px solid var(--blue-line);
  box-shadow: 0 18px 40px -14px rgba(0, 0, 0, 0.8);
}

/* The nav bar's menu opens near the right edge of the viewport, so it grows
   leftward from the trigger instead of overflowing off screen. */
.drop__menu--right { left: auto; right: 0; }

.drop__option, .grab__option {
  display: block;
  padding: 0.9rem 1.1rem;
  text-decoration: none;
  color: var(--chalk);
  border-bottom: 1px solid var(--blue-line);
  transition: background 180ms var(--ease);
}

.drop__option:last-child, .grab__option:last-child { border-bottom: 0; }

.drop__option:hover, .drop__option:focus-visible,
.grab__option:hover, .grab__option:focus-visible {
  background: rgba(244, 240, 230, 0.06);
  color: var(--chalk);
}

.drop__name, .grab__name {
  display: block;
  font-family: var(--display);
  font-weight: 700;
  margin-bottom: 0.15rem;
}

.grab__name { font-size: 1.2rem; }
.drop__name { font-size: 1.05rem; }

/* The recommended route gets the working mark, so the choice is not a coin flip. */
.grab__option:first-child .grab__name::after {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-left: 0.5rem;
  vertical-align: 0.28em;
  border-radius: 50%;
  background: var(--oxide);
}

.drop__note, .grab__note {
  display: block;
  font-size: 0.86rem;
  line-height: 1.5;
  color: var(--chalk-faint);
}

/* --- The recording --------------------------------------------------- */

/* The clip itself is landscape (16:9), but it sits beside a narrow column of
   text in a hero that reads top-to-bottom, so the frame around it is cut
   tall rather than wide: a portrait card with the true 16:9 picture floating
   inside it, letterboxed rather than cropped. object-fit: contain keeps
   every frame of the source intact; the frame's own height is what supplies
   the longitudinal shape. */
.reel {
  width: 100%;
  max-width: 22rem;
  margin: 0 auto;
}

.reel__frame {
  width: 100%;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  background: var(--blue-deep);
  border: 1px solid var(--blue-line);
  box-shadow: 0 26px 50px -24px rgba(0, 0, 0, 0.85);
}

.reel__video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #071521;
}

.reel__fallback {
  padding: 1.2rem;
  font-size: 0.9rem;
  color: var(--chalk-soft);
}

.reel figcaption {
  margin-top: 0.9rem;
  font-size: 0.86rem;
  color: var(--chalk-faint);
}

.fineprint {
  font-size: 0.86rem;
  color: var(--chalk-faint);
  max-width: 36ch;
}

/* --- The stage: the demonstration ------------------------------------ */

.stage { margin: 0; }

.stage__label,
.dial__label {
  font-family: var(--text);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--chalk-faint);
}

.stage__label { display: block; margin-bottom: 0.9rem; }

/* Perspective on the room, not on the screen, so the hinge behaves like a
 * hinge: the bottom edge stays put and the top edge recedes. */
.stage__room {
  position: relative;
  perspective: 1500px;
  perspective-origin: 50% 82%;
  padding-bottom: 2.2rem;
}

.screen {
  --travel: 0;            /* degrees closed, set by CSS animation or JS */
  --lean: calc(var(--travel) * 1deg);
  /* Trigger at 10 degrees, full strength 60 degrees later, matching the app's
   * own defaults so the page is not advertising a ramp nobody gets. */
  --progress: clamp(0, calc((var(--travel) - 10) / 60), 1);

  position: relative;
  aspect-ratio: 16 / 10;
  transform-origin: 50% 100%;
  /* Positive rotateX tips the top edge away from the viewer, so the far edge
   * recedes and converges while the hinge edge stays put. Negative would lean
   * the top toward the viewer and make it wider, which is a lid opening. */
  transform: rotateX(var(--lean));
  transform-style: preserve-3d;
  will-change: transform;
}

.screen__face {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: #0a0f14;
  border: 1px solid var(--blue-line);
  box-shadow: 0 26px 50px -24px rgba(0, 0, 0, 0.85);
}

/* Progressive blur, the same idea the shader uses: several copies at
 * increasing softness, each masked to reveal a band further from the hinge. */
.screen__layer {
  position: absolute;
  inset: 0;
  background: inherit;
}

.screen__layer--sharp { background: #0f151c; }

.screen__layer--soft,
.screen__layer--softer,
.screen__layer--softest {
  backdrop-filter: blur(var(--b));
  -webkit-backdrop-filter: blur(var(--b));
  opacity: var(--progress);
  -webkit-mask-image: linear-gradient(to top, transparent var(--from), #000 var(--to));
  mask-image: linear-gradient(to top, transparent var(--from), #000 var(--to));
}

.screen__layer--soft    { --b: 4px;  --from: 30%; --to: 58%; }
.screen__layer--softer  { --b: 12px; --from: 52%; --to: 80%; }
.screen__layer--softest { --b: 28px; --from: 72%; --to: 100%; }

/* Dimming from the hinge upward.
 *
 * Held well short of the app's own maximum on purpose. The app takes the far
 * edge to black, which is right when the lid is nearly shut and nobody is
 * looking, but a demonstration that goes black has hidden the blur and the
 * perspective it exists to show. Same shape, two thirds of the depth.
 */
.screen__dim {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(4, 8, 12, 0.06) 0%, rgba(4, 8, 12, 0.86) 94%);
  opacity: calc(var(--progress) * 0.78);
}

.paper {
  padding: clamp(1rem, 3.4%, 2.2rem);
  color: #cfd8de;
  font-size: clamp(0.72rem, 0.55rem + 0.55vw, 0.94rem);
  line-height: 1.5;
}

.paper__h {
  font-family: var(--display);
  font-size: 1.85em;
  line-height: 1;
  color: var(--chalk);
  margin-bottom: 0.5em;
}

.paper p { margin-bottom: 0.75em; }

.paper__rule {
  height: 1px;
  background: #2a3b48;
  margin: 1.1em 0 !important;
}

/* Sits near the hinge, where nothing is ever blurred or dimmed, so the
 * contrast against the far edge is visible in a single glance. */
.paper__foot {
  color: var(--linen);
  margin-top: 1.4em;
}

.hinge {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 2.2rem;
  height: 3px;
  background: var(--oxide);
  box-shadow: 0 0 14px rgba(210, 84, 44, 0.5);
}

.base {
  position: absolute;
  left: 4%;
  right: 4%;
  bottom: 1.5rem;
  height: 0.7rem;
  background: linear-gradient(180deg, var(--blue-lift), var(--blue-deep));
  border: 1px solid var(--blue-line);
  border-top: 0;
  transform: perspective(600px) rotateX(58deg);
  transform-origin: 50% 0;
}

/* --- The control ----------------------------------------------------- */

.dial {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 0.9rem;
  margin-top: 0.6rem;
}

.dial__readout {
  font-family: var(--display);
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--oxide-lift);
  min-width: 3.2ch;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.dial__input {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 1.4rem;
  background: transparent;
  cursor: ew-resize;
  margin: 0;
}

/* A degree graticule, struck into the groove. */
.dial__input::-webkit-slider-runnable-track {
  height: 2px;
  background:
    repeating-linear-gradient(90deg, var(--blue-line) 0 1px, transparent 1px 10%),
    var(--blue-line);
}

.dial__input::-moz-range-track {
  height: 2px;
  background: var(--blue-line);
}

.dial__input::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 15px;
  height: 15px;
  margin-top: -6.5px;
  border-radius: 50%;
  background: var(--chalk);
  border: none;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.55);
  transition: background 160ms var(--ease);
}

.dial__input::-moz-range-thumb {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: var(--chalk);
  border: none;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.55);
}

.dial__input:hover::-webkit-slider-thumb { background: var(--oxide-lift); }
.dial__input:hover::-moz-range-thumb { background: var(--oxide-lift); }

.dial__note {
  margin-top: 0.7rem;
  font-size: 0.83rem;
  color: var(--chalk-faint);
}

/* Scroll-driven, so the effect works with JavaScript switched off. The
 * slider is the enhancement, not the other way round. */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .screen {
      animation: close linear both;
      /* Root scroll rather than view(), so the start of the range is the top of
       * the document. A view() timeline is already partway through when the
       * element loads in the middle of the viewport, which would show a leaning
       * screen next to a readout saying nothing has moved. */
      animation-timeline: scroll(root block);
      animation-range: 0 70vh;
    }
    /* Once the slider is touched, JS adds this and the scroll lets go. */
    .stage[data-held="true"] .screen { animation: none; }
  }
}

@keyframes close {
  from { --travel: 0; }
  to   { --travel: 60; }
}

@property --travel {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

/* No scroll timelines: show it part-closed, so a still image still makes the
 * point. JavaScript, when present, takes over from here. */
@supports not (animation-timeline: scroll()) {
  .screen { --travel: 38; }
}

@media (prefers-reduced-motion: reduce) {
  .screen { --travel: 38; transition: none; }
  .dial__note { display: none; }
}

/* --- Bays: the reading sections -------------------------------------- */

.bay {
  max-width: 78rem;
  margin: 0 auto;
  padding: var(--bay-y) var(--gap);
  display: grid;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}

@media (min-width: 62rem) {
  .bay { grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr); }
  .bay--stack, .bay--quiet, .bay--limits, .bay--close, .bay--try { grid-template-columns: 1fr; }
}

.bay__measure { max-width: var(--measure); }
.bay__wide { max-width: 46rem; }

.bay p { color: var(--chalk-soft); }
.bay h2 { color: var(--chalk); }

.bay--quiet {
  background: var(--blue-deep);
  max-width: none;
  padding-inline: 0;
}

.bay--quiet > .bay__wide {
  max-width: 46rem;
  margin: 0 auto;
  padding-inline: var(--gap);
}

.statement {
  font-family: var(--display);
  font-size: clamp(1.45rem, 1.1rem + 1.6vw, 2.35rem);
  line-height: 1.14;
  color: var(--chalk) !important;
  margin-bottom: 1.1em;
  text-wrap: balance;
}

/* The lineage. A genuine sequence, so the numerals carry information. */
.lineage {
  list-style: none;
  counter-reset: step;
  margin: 2.2rem 0 0;
  padding: 0;
  display: grid;
  gap: 0;
}

.lineage li {
  counter-increment: step;
  display: grid;
  /* Exactly two columns, and exactly two items per row: the generated numeral
   * and one wrapper div. The markup wraps each item's prose for that reason. */
  grid-template-columns: 2.6rem minmax(0, 1fr);
  gap: 1rem;
  padding: 1.3rem 0;
  border-top: 1px solid var(--blue-line);
  color: var(--chalk-soft);
  font-size: 0.98rem;
}

.lineage li::before {
  content: counter(step);
  font-family: var(--display);
  font-size: 2rem;
  font-weight: 800;
  line-height: 0.82;
  color: var(--oxide);
}

.lineage strong { color: var(--chalk); font-weight: 600; }

/* The one this page is about. */
.lineage li:last-child { border-bottom: 1px solid var(--blue-line); }
.lineage li:last-child::before { color: var(--chalk); }

.aside {
  max-width: 44rem;
  padding-left: 1.2rem;
  border-left: 1px solid var(--blue-line);
  font-size: 0.95rem;
  color: var(--chalk-faint) !important;
}

/* --- Plate: the sliding-frame diagram -------------------------------- */

.plate { margin: 0; }

.slide {
  width: 100%;
  max-width: 30rem;
  height: auto;
  display: block;
}

/* The scene slides up as one rigid piece, because that is what pitch does to
 * an image. Nothing inside it moves relative to anything else. */
.slide__scene {
  animation: rise 5.5s var(--ease) infinite alternate;
}

@keyframes rise {
  from { transform: translateY(46px); }
  to   { transform: translateY(-8px); }
}

@media (prefers-reduced-motion: reduce) {
  .slide__scene { animation: none; transform: translateY(14px); }
}

.plate figcaption,
.stage figcaption:not(.stage__label) {
  margin-top: 1rem;
  font-size: 0.88rem;
  color: var(--chalk-faint);
  max-width: 34rem;
}

/* --- Steps ----------------------------------------------------------- */

.steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1px;
  background: var(--blue-line);
}

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

.step {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  background: var(--blue);
  padding: clamp(1.4rem, 3vw, 2.2rem) clamp(1.2rem, 2.4vw, 1.9rem);
}

.step__num {
  font-family: var(--display);
  font-size: 2.4rem;
  font-weight: 800;
  line-height: 0.8;
  color: var(--oxide);
  margin: 0;
  flex: none;
}

.step h3 { color: var(--chalk); }
.step p { margin: 0; font-size: 0.94rem; }

/* --- Limits ---------------------------------------------------------- */

.limits {
  margin: 0;
  display: grid;
  gap: 0;
}

@media (min-width: 52rem) {
  .limits {
    grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
    column-gap: clamp(1.5rem, 4vw, 3.5rem);
  }
}

.limits dt {
  font-family: var(--display);
  font-size: 1.28rem;
  font-weight: 700;
  color: var(--chalk);
  padding: 1.35rem 0 0.3rem;
  border-top: 1px solid var(--blue-line);
}

.limits dd {
  margin: 0;
  padding: 1.35rem 0 1.5rem;
  color: var(--chalk-soft);
  font-size: 0.97rem;
}

@media (min-width: 52rem) {
  .limits dd { border-top: 1px solid var(--blue-line); }
  .limits dt { padding-bottom: 1.5rem; }
}

@media (max-width: 51.99rem) {
  .limits dd { padding-top: 0.2rem; }
}

/* --- Code ------------------------------------------------------------ */

.code {
  margin: 0 0 1.4rem;
  padding: 1.1rem 1.3rem;
  background: var(--blue-deep);
  border: 1px solid var(--blue-line);
  border-left: 2px solid var(--oxide);
  overflow-x: auto;
  font-size: 0.94rem;
  line-height: 1.75;
}

.code code { color: var(--linen); }

.bay--close { padding-bottom: clamp(5rem, 12vh, 8rem); }

/* --- Download / support page --------------------------------------------
 * Built from the same primitives as the main page: .bay, .snap, .steps'
 * numbered rows, .support's flat link row. No cards, no rounded panels, no
 * emoji as icon stand-ins; every symbol here is a drawn stroke SVG matching
 * the ones already used for GitHub/download elsewhere on the site.
 * -------------------------------------------------------------------- */

.thanks-hero {
  background:
    radial-gradient(120% 90% at 18% 8%, var(--blue-lift) 0%, transparent 55%),
    linear-gradient(178deg, var(--blue) 0%, var(--blue-deep) 100%);
  padding: clamp(3rem, 8vh, 5.5rem) var(--gap) clamp(2.5rem, 6vh, 4rem);
}

.thanks-hero__inner {
  max-width: 40rem;
  margin: 0 auto;
}

.thanks__status {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.86rem;
  color: var(--chalk-soft);
  margin-bottom: 2rem;
}

.thanks__spin {
  width: 1.15rem;
  height: 1.15rem;
  color: var(--chalk-faint);
  flex: none;
  animation: spin 1.1s linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .thanks__spin { animation: none; }
}

.thanks-hero h1 {
  font-family: var(--display);
  font-size: clamp(2.3rem, 1.5rem + 3.2vw, 3.8rem);
  font-weight: 800;
  line-height: 0.98;
  letter-spacing: -0.02em;
  color: var(--chalk);
  margin: 0 0 0.5em;
  text-wrap: balance;
}

.thanks-hero h1::after {
  content: "";
  display: block;
  height: 3px;
  width: 3.5rem;
  margin-top: 0.6em;
  background: var(--oxide);
}

.thanks-hero p {
  color: var(--chalk-soft);
  font-size: clamp(1rem, 0.95rem + 0.2vw, 1.08rem);
  max-width: 42ch;
}

/* The support list, exactly the .support component already used in the main
   page's footer, laid out as the page's primary content instead of a
   secondary line. Same anatomy, more room to breathe. */
.thanks-hero .support {
  margin: 1.6rem 0 0;
  max-width: none;
}

.thanks-hero .support a {
  padding: 0.55rem 1rem;
  font-size: 0.92rem;
}

.thanks-hero .support a:first-child {
  border-color: var(--oxide);
  color: var(--chalk);
}

.thanks-hero .support a:first-child:hover { background: rgba(210, 84, 44, 0.12); }

.thanks__skip {
  font-size: 0.88rem;
  color: var(--chalk-faint);
  margin-top: 1.8rem;
}

/* --- Support --------------------------------------------------------- */

.support {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  /* Same measure and centring as .foot p, which it sits directly beneath.
   * Without this the list runs flush to the page edge while the prose above it
   * is centred. */
  max-width: 46rem;
  margin: 1.1rem auto 0;
  padding: 0;
  list-style: none;
}

.support a {
  display: inline-block;
  padding: 0.4rem 0.85rem;
  border: 1px solid var(--blue-line);
  font-size: 0.88rem;
  text-decoration: none;
  color: var(--chalk-soft);
  transition: border-color 180ms var(--ease), color 180ms var(--ease);
}

.support a:hover {
  border-color: var(--oxide);
  color: var(--chalk);
}

/* --- Foot ------------------------------------------------------------ */

.foot {
  border-top: 1px solid var(--blue-line);
  background: var(--blue-deep);
  padding: clamp(2.5rem, 6vh, 4rem) var(--gap);
}

.foot p {
  max-width: 46rem;
  margin: 0 auto 0.6rem;
  font-size: 0.92rem;
  color: var(--chalk-soft);
}

.foot__quiet { color: var(--chalk-faint) !important; margin-bottom: 0 !important; }
