:root {
  --paper: #eeeae0;
  --paper-bright: #f7f4ec;
  --paper-deep: #ddd7ca;
  --ink: #151713;
  --ink-soft: #292c27;
  --ink-wash: #454941;
  --muted: #676962;
  --line: rgba(21, 23, 19, 0.18);
  --dark-line: rgba(247, 244, 236, 0.16);
  --signal: #ed5a35;
  --signal-hot: #ff704b;
  --signal-dark: #87301b;
  --frost: #dfe6f2;
  --blue: #96a9ff;
  --mint: #79d8c8;
  --header-height: 70px;
  --max: 1480px;
  --side: clamp(20px, 4vw, 68px);
  --sans: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Helvetica Neue", Arial, sans-serif;
  --mono: "SFMono-Regular", "Cascadia Code", "Roboto Mono", Menlo, Consolas, monospace;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-height) + 20px);
}

body {
  margin: 0;
  min-width: 320px;
  overflow-x: hidden;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

body::before {
  position: fixed;
  z-index: 20;
  inset: 0;
  pointer-events: none;
  opacity: 0.035;
  content: "";
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
}

button,
input {
  font: inherit;
}

button,
a {
  -webkit-tap-highlight-color: transparent;
}

button {
  color: inherit;
}

a {
  color: inherit;
  text-decoration: none;
}

p,
h1,
h2,
h3,
h4,
ol,
ul,
dl,
dd {
  margin: 0;
}

ul,
ol {
  padding: 0;
}

img,
canvas {
  display: block;
  max-width: 100%;
}

::selection {
  background: var(--signal);
  color: #fff;
}

:focus-visible {
  outline: 3px solid var(--signal-hot);
  outline-offset: 4px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: fixed;
  z-index: 1000;
  top: 12px;
  left: 12px;
  padding: 12px 16px;
  transform: translateY(-160%);
  background: var(--paper-bright);
  color: var(--ink);
  border: 2px solid var(--ink);
  font-weight: 700;
}

.skip-link:focus {
  transform: translateY(0);
}

.site-header {
  position: fixed;
  z-index: 100;
  top: 0;
  left: 0;
  right: 0;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  height: var(--header-height);
  padding: 0 var(--side);
  color: var(--paper-bright);
  background: rgba(21, 23, 19, 0.92);
  border-bottom: 1px solid rgba(247, 244, 236, 0.13);
  backdrop-filter: blur(18px);
  transition: box-shadow 240ms ease, background 240ms ease;
}

.site-header.is-scrolled {
  background: rgba(21, 23, 19, 0.97);
  box-shadow: 0 10px 32px rgba(0, 0, 0, 0.2);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  width: max-content;
  font-size: 0.86rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.brand-mark {
  display: block;
  width: 44px;
  height: 44px;
  border-radius: 22%;
  flex-shrink: 0;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: clamp(18px, 2.3vw, 38px);
}

.site-nav a {
  position: relative;
  padding: 10px 0;
  color: rgba(247, 244, 236, 0.72);
  font-size: 0.76rem;
  font-weight: 600;
  transition: color 180ms ease;
}

.site-nav a::after {
  position: absolute;
  right: 0;
  bottom: 5px;
  left: 0;
  height: 1px;
  content: "";
  background: var(--signal-hot);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 220ms var(--ease);
}

.site-nav a:hover,
.site-nav a:focus-visible {
  color: #fff;
}

.site-nav a:hover::after,
.site-nav a:focus-visible::after {
  transform: scaleX(1);
  transform-origin: left;
}

.header-buy {
  justify-self: end;
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 40px;
  padding: 0 5px 0 15px;
  color: #fff;
  background: var(--signal);
  border: 1px solid rgba(255, 255, 255, 0.2);
  font-size: 0.76rem;
  font-weight: 700;
}

.header-buy span {
  display: grid;
  place-items: center;
  min-width: 46px;
  height: 30px;
  background: var(--ink);
  font-family: var(--mono);
}

.hero {
  position: relative;
  min-height: 100svh;
  padding: calc(var(--header-height) + clamp(54px, 7vw, 105px)) var(--side) 0;
  overflow: hidden;
  color: var(--paper-bright);
  background:
    linear-gradient(rgba(255, 255, 255, 0.028) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.028) 1px, transparent 1px),
    var(--ink);
  background-size: 56px 56px;
}

.hero::after {
  position: absolute;
  top: 14%;
  right: -12%;
  width: 46vw;
  height: 46vw;
  max-width: 760px;
  max-height: 760px;
  pointer-events: none;
  content: "";
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 50%;
  box-shadow: 0 0 0 8vw rgba(255, 255, 255, 0.012), 0 0 0 16vw rgba(255, 255, 255, 0.008);
}

.hero-grid {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(500px, 7fr);
  gap: clamp(40px, 6vw, 100px);
  align-items: center;
  width: min(100%, var(--max));
  min-height: calc(100svh - var(--header-height) - 150px);
  margin: 0 auto;
}

.eyebrow {
  font-family: var(--mono);
  font-size: clamp(0.68rem, 0.85vw, 0.78rem);
  font-weight: 600;
  letter-spacing: 0.12em;
  line-height: 1.4;
  text-transform: uppercase;
}

.hero-copy > .eyebrow {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: clamp(25px, 3vw, 44px);
  color: var(--signal-hot);
}

.hero-copy > .eyebrow::before {
  width: 8px;
  height: 8px;
  content: "";
  background: var(--signal-hot);
  border-radius: 50%;
  box-shadow: 0 0 15px rgba(255, 112, 75, 0.75);
}

.hero h1 {
  max-width: 850px;
  font-size: clamp(4rem, 7.2vw, 8.4rem);
  font-weight: 650;
  letter-spacing: -0.075em;
  line-height: 0.83;
}

.hero h1 em {
  color: var(--paper);
  font-family: ui-serif, "Iowan Old Style", "Times New Roman", serif;
  font-weight: 400;
  letter-spacing: -0.06em;
}

.hero-lede {
  max-width: 650px;
  margin-top: clamp(30px, 4vw, 54px);
  color: rgba(247, 244, 236, 0.7);
  font-size: clamp(1.05rem, 1.5vw, 1.28rem);
  line-height: 1.62;
}

.hero-lede kbd {
  display: inline-grid;
  place-items: center;
  min-width: 30px;
  padding: 2px 6px;
  color: var(--paper-bright);
  background: #30332e;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-bottom-width: 3px;
  border-radius: 4px;
  font-family: var(--mono);
  font-size: 0.72em;
}

.hero-actions,
.closing-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 32px;
}

.button {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 26px;
  min-height: 52px;
  padding: 0 18px;
  border: 1px solid transparent;
  border-radius: 0;
  cursor: pointer;
  font-size: 0.79rem;
  font-weight: 750;
  letter-spacing: -0.01em;
  transition: transform 160ms ease, box-shadow 160ms ease, background 160ms ease, color 160ms ease;
}

.button:active {
  transform: translateY(3px);
}

.button-signal {
  min-width: 240px;
  color: #fff;
  background: var(--signal);
  box-shadow: 0 6px 0 var(--signal-dark);
}

.button-signal:hover {
  background: var(--signal-hot);
}

.button-signal:active {
  box-shadow: 0 2px 0 var(--signal-dark);
}

.button-signal span,
.button-ink span {
  font-family: var(--mono);
  font-size: 0.88rem;
}

/* The price sits directly on --signal, where white measures only 3.4:1. Give it
   the same ink chip .header-buy already uses: accessible, and consistent with
   the buy control in the header. */
.button-signal span {
  padding: 3px 9px;
  border-radius: 3px;
  background: var(--ink);
}

.button-quiet,
.button-quiet-light {
  color: var(--paper-bright);
  background: transparent;
  border-color: rgba(247, 244, 236, 0.3);
}

.button-quiet:hover,
.button-quiet-light:hover {
  color: var(--ink);
  background: var(--paper-bright);
}

.button-ink {
  color: var(--paper-bright);
  background: var(--ink);
  box-shadow: 0 6px 0 #55584f;
}

.button-ink:hover {
  background: #2b2e29;
}

.button-line {
  min-width: 128px;
  color: var(--ink);
  background: transparent;
  border-color: var(--ink);
}

.button-line:hover {
  color: var(--paper-bright);
  background: var(--ink);
}

.hero-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 9px 20px;
  margin-top: 31px;
  color: rgba(247, 244, 236, 0.48);
  font-family: var(--mono);
  font-size: 0.64rem;
  letter-spacing: 0.06em;
  list-style: none;
  text-transform: uppercase;
}

.hero-facts li:not(:last-child)::after {
  margin-left: 20px;
  color: var(--signal-hot);
  content: "/";
}

.instrument {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: 750px;
  justify-self: end;
  padding: 18px;
  color: var(--paper-bright);
  background: #2b2e29;
  border: 1px solid rgba(255, 255, 255, 0.15);
  box-shadow: 0 16px 0 #090a09, 0 38px 70px rgba(0, 0, 0, 0.35), inset 0 1px rgba(255, 255, 255, 0.12);
}

.instrument::before,
.instrument::after {
  position: absolute;
  width: 5px;
  height: 5px;
  content: "";
  background: #090a09;
  border: 1px solid #62665d;
  border-radius: 50%;
  box-shadow: 0 0 0 1px #151713;
}

.instrument::before {
  top: 7px;
  left: 7px;
}

.instrument::after {
  right: 7px;
  bottom: 7px;
}

.instrument-topline,
.theater-topline {
  display: flex;
  justify-content: space-between;
  gap: 20px;
  padding: 3px 2px 14px;
  color: rgba(247, 244, 236, 0.55);
  font-family: var(--mono);
  font-size: 0.58rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.instrument-topline span:first-child {
  display: flex;
  align-items: center;
  gap: 8px;
  color: rgba(247, 244, 236, 0.78);
}

.status-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  background: #79d9a0;
  border-radius: 50%;
  box-shadow: 0 0 8px rgba(121, 217, 160, 0.6);
}

.editor-tabs {
  display: flex;
  gap: 1px;
  border-bottom: 1px solid #3a3d38;
}

.editor-tabs button {
  min-height: 38px;
  padding: 0 17px;
  cursor: pointer;
  color: #949890;
  background: #151713;
  border: 0;
  border-top: 2px solid transparent;
  font-family: var(--mono);
  font-size: 0.63rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.editor-tabs button[aria-pressed="true"] {
  color: var(--paper-bright);
  background: #1d1f1c;
  border-top-color: var(--signal-hot);
}

.editor {
  position: relative;
  min-height: clamp(220px, 25vw, 330px);
  overflow: hidden;
  background:
    linear-gradient(rgba(255, 255, 255, 0.025) 1px, transparent 1px),
    #171916;
  background-size: 100% 28px;
  border: 1px solid #3a3d38;
  border-top: 0;
}

.editor-chrome {
  display: flex;
  align-items: center;
  gap: 7px;
  height: 34px;
  padding: 0 13px;
  color: #888c85;
  background: #20221f;
  border-bottom: 1px solid #343732;
  font-family: var(--mono);
  font-size: 0.58rem;
}

.editor-chrome i {
  width: 7px;
  height: 7px;
  background: #4a4e47;
  border-radius: 50%;
}

.editor-chrome span {
  margin-left: 7px;
}

.editor-body {
  display: grid;
  grid-template-columns: 28px auto 1fr;
  align-items: start;
  padding: clamp(48px, 7vw, 80px) clamp(20px, 3.4vw, 44px);
  font-family: var(--mono);
  font-size: clamp(0.74rem, 1vw, 0.9rem);
  line-height: 1.75;
}

.line-no {
  color: #4a4e47;
  user-select: none;
}

.editor-prefix {
  color: #758ba1;
}

.editor-transcript {
  min-height: 4em;
  color: #d9e0d4;
}

.editor-transcript.is-inserted {
  color: var(--paper-bright);
}

.caret {
  display: inline-block;
  width: 7px;
  height: 1.2em;
  margin-left: 2px;
  vertical-align: -0.2em;
  background: var(--signal-hot);
  animation: caret-blink 1s step-end infinite;
}

@keyframes caret-blink {
  50% { opacity: 0; }
}

.hud-anchor {
  position: absolute;
  right: 50%;
  bottom: 19px;
  transform: translateX(50%);
  opacity: 0.28;
  transition: opacity 220ms ease, transform 400ms var(--ease);
}

.hud-anchor.is-active {
  opacity: 1;
  transform: translateX(50%) translateY(-2px);
}

.hud-pill {
  position: relative;
  display: grid;
  place-items: center;
  width: 92px;
  height: 28px;
  overflow: hidden;
  background: rgba(7, 8, 7, 0.96);
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 999px;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.38), inset 0 1px rgba(255, 255, 255, 0.08);
}

.hud-pill-hero {
  --hud-scale: 1;
  width: calc(110px * var(--hud-scale));
  height: calc(30px * var(--hud-scale));
  transition: width 240ms var(--ease), height 240ms var(--ease);
}

.hud-pill canvas {
  width: 84px;
  height: 24px;
}

/* The pricing thumbnails reproduce the shipped HUD's real geometry rather than
   the wave-shaped default above: Phantom Voice's Standard size draws a 32pt
   glyph in a 43pt pill with ~14.5pt of pill either side, so that is what a
   buyer sees here. The pill closes around the art the way it does in the app.
   `width: auto` on the canvas is load-bearing: the 84x24 rule above is shaped
   for White Wave's 4.2:1 waveform and stretched a 32x32 Retro Dog to 3.5:1. */
.addon-preview .hud-pill {
  width: auto;
  height: 43px;
  padding: 0 14px;
}

.hud-pill canvas.addon-canvas {
  width: auto;
  height: 32px;
}

.hud-pill-hero canvas {
  width: calc(102px * var(--hud-scale));
  height: calc(25px * var(--hud-scale));
}

/* Sprite styles get the 26px acceptance height and the pill closes in around
   them instead of leaving the wave's full width empty. Width follows the
   style's own aspect: Real Revolver's viewport is 128:104, not square, so a
   fixed square would letterbox it. main.js sets --sprite-aspect and the
   pixelated/auto rendering per style. */
/* The fallback lives in var(), never as a local `--sprite-aspect: 1`
   declaration on the canvas: a local declaration shadows the value main.js
   sets on the pill, which silently pinned Real Revolver back to a square. */
.hud-pill canvas.hero-sprite {
  width: calc(26px * var(--sprite-aspect, 1));
  height: 26px;
}

.hud-pill-hero canvas.hero-sprite {
  width: calc(26px * var(--sprite-aspect, 1) * var(--hud-scale));
  height: calc(26px * var(--hud-scale));
}

.hud-pill-hero.is-sprite {
  width: calc((26px * var(--sprite-aspect, 1) + 20px) * var(--hud-scale));
  transition: width 240ms var(--ease);
}

.style-picker {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
  padding: 11px 4px 0;
}

.style-picker-label,
.style-picker-note {
  margin: 0;
  color: #949890;
  font-family: var(--mono);
  font-size: 0.63rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.style-picker-note {
  flex: 1 1 100%;
  text-transform: none;
  letter-spacing: 0.02em;
  opacity: 0.72;
}

/* Each control keeps its label on the same line as the buttons it names. As one
   flat wrapping flex container, the picker broke between "HUD size" and the
   size buttons, stranding the label at the end of the style row. */
.style-picker-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
  flex: 1 1 100%;
}

.style-picker-options {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.style-picker-options button {
  /* Still under the 44px touch guideline, which the instrument panel's density
     does not have room for, but the catalog went from three chips to four and
     34px is a materially easier target on a phone than 28px. */
  min-height: 34px;
  padding: 0 12px;
  cursor: pointer;
  color: #949890;
  background: #151713;
  border: 1px solid #3a3d38;
  border-radius: 999px;
  font-family: var(--mono);
  font-size: 0.63rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  transition: color 160ms ease, background 160ms ease, border-color 160ms ease;
}

.style-picker-options button:hover {
  color: var(--paper-bright);
  border-color: #5a5e57;
}

.style-picker-options button[aria-pressed="true"] {
  color: var(--paper-bright);
  background: #1d1f1c;
  border-color: var(--signal-hot);
}

.instrument-console {
  position: relative;
  padding: 15px 4px 2px;
}

.state-rail {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
  margin-bottom: 17px;
  color: #9da197;
  font-family: var(--mono);
  font-size: 0.56rem;
  letter-spacing: 0.04em;
  list-style: none;
  text-transform: uppercase;
}

.state-rail li {
  position: relative;
  padding-top: 11px;
  border-top: 1px solid #53574f;
}

.state-rail li::before {
  position: absolute;
  top: -3px;
  left: 0;
  width: 5px;
  height: 5px;
  content: "";
  background: #55594f;
  border-radius: 50%;
}

.state-rail li.is-active {
  color: var(--paper-bright);
  border-color: var(--signal-hot);
}

.state-rail li.is-active::before {
  background: var(--signal-hot);
  box-shadow: 0 0 8px rgba(255, 112, 75, 0.7);
}

.hold-area {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  min-height: 94px;
  padding: 12px 14px 12px 18px;
  background: #242622;
  border: 1px solid #454941;
  box-shadow: inset 0 1px rgba(255, 255, 255, 0.06);
}

.console-label {
  margin-bottom: 7px;
  color: #a0a49a;
  font-family: var(--mono);
  font-size: 0.55rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
}

.console-status {
  color: #d4d7cf;
  font-size: clamp(0.74rem, 1vw, 0.88rem);
}

.fn-key {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 25px;
  min-width: 176px;
  min-height: 66px;
  padding: 10px 12px;
  cursor: pointer;
  color: var(--paper-bright);
  background: #171916;
  border: 1px solid #666b62;
  border-bottom-width: 5px;
  border-radius: 5px;
  box-shadow: 0 5px 0 #090a09, inset 0 1px rgba(255, 255, 255, 0.12);
  user-select: none;
  transition: transform 100ms ease, box-shadow 100ms ease, border-color 180ms ease;
  touch-action: none;
}

.fn-key:hover {
  border-color: #9ea398;
}

.fn-key.is-held {
  transform: translateY(5px);
  border-bottom-width: 2px;
  box-shadow: 0 1px 0 #090a09, inset 0 1px 4px rgba(0, 0, 0, 0.5);
}

/* Cued when "Try the HUD" is pressed: visitors did not realize this key IS
   the demo and went hunting for a Download button instead (real feedback).
   A ring alone was too easy to miss - it reads as ambient chrome rather than
   "press this" - so a mint arrow nudges at it as well. Clears on first press
   or after a few seconds. */
.fn-key--cue {
  position: relative;
  border-color: var(--signal-hot);
  box-shadow:
    0 5px 0 #090a09,
    inset 0 1px rgba(255, 255, 255, 0.12),
    0 0 0 5px rgba(255, 112, 75, 0.34),
    0 0 30px rgba(255, 112, 75, 0.6);
  animation: fn-key-cue-pulse 1.05s ease-in-out 6;
}

@keyframes fn-key-cue-pulse {
  0%, 100% { box-shadow: 0 5px 0 #090a09, inset 0 1px rgba(255, 255, 255, 0.12), 0 0 0 5px rgba(255, 112, 75, 0.34), 0 0 30px rgba(255, 112, 75, 0.6); }
  50% { box-shadow: 0 5px 0 #090a09, inset 0 1px rgba(255, 255, 255, 0.12), 0 0 0 10px rgba(255, 112, 75, 0.16), 0 0 46px rgba(255, 112, 75, 0.85); }
}

/* Drawn with clip-path rather than an image or a glyph: it stays crisp at
   any scale, needs no markup, and exists only while the cue is running.
   The shape is a variable so the key's arrow and the picker arrows cannot
   quietly drift apart. */
:root {
  --cue-arrow: polygon(0 36%, 60% 36%, 60% 0, 100% 50%, 60% 100%, 60% 64%, 0 64%);
}

.fn-key--cue::before {
  content: "";
  position: absolute;
  top: 50%;
  right: calc(100% + 13px);
  width: 38px;
  height: 14px;
  margin-top: -7px;
  background: var(--mint);
  clip-path: var(--cue-arrow);
  filter: drop-shadow(0 0 9px rgba(121, 216, 200, 0.8));
  animation: fn-key-cue-arrow 880ms var(--ease) infinite;
  pointer-events: none;
}

/* The style and size chips are the other two things in this panel that
   respond to a click without looking like it. Same arrow, same rhythm, and
   a ring around the whole group rather than nine separate glows. */
.style-picker-line--cue .style-picker-label {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  color: var(--mint);
}

.style-picker-line--cue .style-picker-label::after {
  content: "";
  width: 26px;
  height: 11px;
  background: var(--mint);
  clip-path: var(--cue-arrow);
  filter: drop-shadow(0 0 8px rgba(121, 216, 200, 0.8));
  animation: fn-key-cue-arrow 880ms var(--ease) infinite;
}

.style-picker-line--cue .style-picker-options {
  border-radius: 999px;
  animation: picker-cue-pulse 1.05s ease-in-out 6;
}

@keyframes picker-cue-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 112, 75, 0), 0 0 0 rgba(255, 112, 75, 0); }
  50%      { box-shadow: 0 0 0 4px rgba(255, 112, 75, 0.2), 0 0 22px rgba(255, 112, 75, 0.55); }
}

@keyframes fn-key-cue-arrow {
  0%, 100% { transform: translateX(-7px); opacity: 0.5; }
  50%      { transform: translateX(3px);  opacity: 1; }
}

/* Same nudge, turned a quarter so it points down at a full-width key. The
   rotation comes first, so translateX runs along the rotated axis. */
@keyframes fn-key-cue-arrow-down {
  0%, 100% { transform: rotate(90deg) translateX(-6px); opacity: 0.5; }
  50%      { transform: rotate(90deg) translateX(3px);  opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  /* The arrows stay - they are the signal. Only their motion goes. */
  .fn-key--cue,
  .style-picker-line--cue .style-picker-options { animation: none; }
  .fn-key--cue::before,
  .style-picker-line--cue .style-picker-label::after {
    animation: none;
    transform: none;
    opacity: 1;
  }
  /* Without the pulse the ring has to be stated outright, or the chips get
     an arrow pointing at nothing visibly changed. */
  .style-picker-line--cue .style-picker-options {
    box-shadow: 0 0 0 3px rgba(255, 112, 75, 0.28);
  }
}

.fn-key span {
  font-family: var(--mono);
  font-size: 1.4rem;
  line-height: 1;
}

.fn-key small {
  color: #adb1a7;
  font-family: var(--mono);
  font-size: 0.53rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.hero-ledger {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  width: calc(100% + var(--side) * 2);
  margin-top: clamp(80px, 9vw, 140px);
  margin-left: calc(var(--side) * -1);
  padding: 0 var(--side);
  border-top: 1px solid var(--dark-line);
}

.hero-ledger span {
  min-height: 76px;
  padding: 28px clamp(12px, 2.2vw, 34px);
  color: rgba(247, 244, 236, 0.5);
  border-right: 1px solid var(--dark-line);
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.hero-ledger span:first-child {
  border-left: 1px solid var(--dark-line);
}

.section-light {
  padding: clamp(90px, 10vw, 160px) var(--side);
  background: var(--paper);
}

/* ============================================================
   CONFIDENTIALITY - prove the architecture before making the
   ownership argument. The proof belongs directly under the
   heading, where a reader can verify the promise before being
   asked to consider the consequence of sending someone else's
   words to a hosted service.
   ============================================================ */
.confidence-section > * {
  width: min(100%, var(--max));
  margin-right: auto;
  margin-left: auto;
}

/* This section has one argument, not two parallel ideas. Keep its label,
   headline, proof, and explanation on one shared edge instead of reserving
   a mostly empty editorial column. */
.confidence-section .section-heading {
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(16px, 2vw, 28px);
  max-width: 1100px;
  margin-left: 0;
}

.confidence-section .section-heading .eyebrow {
  padding-top: 0;
}

/* Smaller than the slogan headings elsewhere: this one is a full
   sentence and has to stay readable as a sentence. */
.confidence-section .section-heading h2 {
  max-width: 20ch;
  font-size: clamp(2.35rem, 4.8vw, 4.9rem);
  letter-spacing: -0.05em;
  line-height: 1.02;
}

.confidence-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  row-gap: clamp(30px, 3.5vw, 52px);
  width: min(100%, 1100px);
  margin-top: clamp(34px, 4vw, 58px);
  margin-right: 0;
  margin-left: 0;
}

/* Each piece shares the headline's left edge. */
.confidence-copy {
  grid-column: 1;
  max-width: 64ch;
}

.confidence-copy p {
  margin: 0;
  color: var(--ink-soft);
  font-size: clamp(1.04rem, 1.3vw, 1.24rem);
  line-height: 1.62;
}

.confidence-copy p + p {
  margin-top: 1.05em;
}

.confidence-ledger {
  display: grid;
  grid-column: 1;
  grid-template-columns: 1fr;
  margin: 0;
  /* Closed on all four sides. This borrowed the hero-ledger device, which is
     open at the bottom on purpose - there it is a strip resting on the
     section edge. As one standalone box that reads as a missing line. */
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.confidence-ledger > div {
  padding: clamp(26px, 3vw, 42px) clamp(20px, 2.4vw, 40px);
  border-right: 1px solid var(--line);
}

.confidence-ledger > div:first-child {
  border-left: 1px solid var(--line);
}

.confidence-ledger dt {
  margin-bottom: 13px;
  color: var(--signal-dark);
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.confidence-ledger dd {
  /* The box spans the full column now that there is one claim in it, but
     the sentence inside must not: unconstrained it ran past 110 characters
     a line, well beyond a readable measure. */
  max-width: 68ch;
  margin: 0;
  color: var(--ink-soft);
  font-size: clamp(1rem, 1.15vw, 1.1rem);
  line-height: 1.6;
}

.confidence-ledger strong {
  color: var(--ink);
  font-weight: 650;
}

@media (max-width: 900px) {
  .confidence-body {
    grid-template-columns: 1fr;
  }

  .confidence-copy {
    grid-column: 1;
  }
}

@media (max-width: 640px) {
  .confidence-ledger {
    grid-template-columns: 1fr;
  }

}

.section-heading {
  display: grid;
  grid-template-columns: 3fr 7fr;
  gap: clamp(28px, 5vw, 80px);
  align-items: start;
}

.section-heading .eyebrow {
  padding-top: 12px;
  color: var(--signal-dark);
}

.section-heading h2,
.indicator-heading h2,
.pricing-heading h2,
.faq-heading h2,
.closing-copy h2 {
  max-width: 1000px;
  font-size: clamp(3.15rem, 6.5vw, 7.4rem);
  font-weight: 620;
  letter-spacing: -0.075em;
  line-height: 0.94;
}

.step-number {
  color: var(--signal);
  font-family: var(--mono);
  font-size: 0.68rem;
}

.indicator-heading,
.indicator-workshop,
.pricing-heading,
.voice-offer,
.addon-ledger,
.license-note,
.faq-heading,
.faq-list,
.closing-section,
.site-footer {
  width: min(100%, var(--max));
  margin-right: auto;
  margin-left: auto;
}

@keyframes signal-travel {
  to { left: 120%; }
}

.indicator-section {
  padding: clamp(100px, 11vw, 180px) var(--side);
  overflow: hidden;
  color: #c8cdd8;
  background:
    radial-gradient(70% 48% at 16% 0%, rgba(96, 114, 164, 0.16), transparent 68%),
    radial-gradient(55% 42% at 88% 4%, rgba(64, 129, 124, 0.11), transparent 72%),
    #090b10;
}

.indicator-heading {
  display: grid;
  grid-template-columns: 8fr 3fr;
  gap: clamp(30px, 6vw, 100px);
  align-items: end;
}

.indicator-heading .eyebrow {
  margin-bottom: 28px;
  color: #aab8dc;
}

.pricing-heading .eyebrow,
.faq-heading .eyebrow {
  margin-bottom: 28px;
  color: var(--signal-dark);
}

.indicator-heading h2 {
  max-width: 1050px;
  color: #f4f6fb;
  text-shadow: 0 0 32px rgba(202, 216, 255, 0.12);
}

.indicator-heading > p {
  padding-bottom: 10px;
  color: #8d95a5;
  line-height: 1.7;
}

.indicator-workshop {
  max-width: 960px;
  margin-top: clamp(70px, 8vw, 120px);
}

.atelier-group + .atelier-group {
  margin-top: 52px;
}

.atelier-group-heading {
  margin-bottom: 18px;
}

/* "Import your own" badge + featured card - a real user-supplied GIF, not a
   synthetic canvas preview like the bundled styles above it, so it gets its
   own visual weight rather than reusing the two-cell grid layout built for
   listening/transcribing pairs. */
.atelier-badge {
  display: inline-block;
  margin-left: 8px;
  padding: 3px 9px;
  color: #0b0d12;
  background: linear-gradient(135deg, #ffe27a, #ffb454);
  border-radius: 999px;
  font-family: var(--mono);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  vertical-align: middle;
}

.indicator-preview-card-featured {
  border-color: rgba(255, 180, 84, 0.35);
  box-shadow: 0 18px 55px rgba(0, 0, 0, 0.24), 0 0 0 1px rgba(255, 180, 84, 0.12) inset, 0 0 40px rgba(255, 180, 84, 0.08);
}

.indicator-preview-stage-featured {
  height: 220px;
}

.indicator-preview-gif {
  max-width: 100%;
  max-height: 180px;
  width: auto;
  height: auto;
  border-radius: 8px;
  image-rendering: pixelated;
}

.atelier-group-heading h3 {
  color: #e8ebf2;
  font-size: 1.06rem;
  font-weight: 620;
  letter-spacing: 0.01em;
}

.atelier-group-heading p {
  margin-top: 4px;
  color: #7f8797;
  font-size: 0.84rem;
}

.indicator-preview-card {
  padding: 20px;
  margin-bottom: 18px;
  background: linear-gradient(145deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.018));
  border: 1px solid rgba(207, 216, 238, 0.11);
  border-radius: 20px;
  box-shadow: 0 18px 55px rgba(0, 0, 0, 0.24), inset 0 1px rgba(255, 255, 255, 0.04);
}

.indicator-preview-card > h3 {
  margin-bottom: 16px;
  color: #bcc5d7;
  font-family: var(--mono);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1;
}

.indicator-preview-note {
  max-width: 62ch;
  margin: -10px 0 16px;
  color: #99a2b2;
  font-size: 0.82rem;
  line-height: 1.55;
}

.indicator-preview-cells {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

.indicator-preview-cell {
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: center;
  min-width: 0;
  padding: 18px 14px 15px;
  background: rgba(5, 7, 11, 0.3);
  border: 1px solid rgba(255, 255, 255, 0.055);
  border-radius: 15px;
}

.indicator-preview-stage {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 150px;
  background:
    linear-gradient(rgba(255, 255, 255, 0.025) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.025) 1px, transparent 1px),
    radial-gradient(circle at 50% 45%, rgba(112, 133, 181, 0.11), transparent 60%);
  background-size: 16px 16px, 16px 16px, auto;
  border-radius: 12px;
}

/* Height-driven so a non-square style keeps its proportions. Real Revolver's
   viewport is 128:104; the old fixed 128x128 square would stretch it.
   Pixelated-vs-smooth rendering is set per style by main.js, not by a CSS
   class the markup had to remember to carry. */
.preview-canvas.preview-big {
  width: auto;
  height: 128px;
  max-width: 100%;
}

.preview-canvas.preview-big.preview-wave {
  width: 126px;
  height: 52px;
}

.indicator-preview-samples {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: center;
}

.indicator-preview-sample {
  display: flex;
  flex-direction: column;
  gap: 5px;
  align-items: center;
}

.indicator-preview-sample > span {
  /* 5.3:1 on the cell background. The previous #737b89 measured 4.36:1, under
     AA for text this small (0.56rem uppercase). */
  color: #808999;
  font-family: var(--mono);
  font-size: 0.56rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  line-height: 1;
  text-transform: uppercase;
}

/* Width follows the art rather than a fixed 92px. A square sprite in a pill
   sized for the 4.2:1 wave left the glyph adrift, and made the 26px sample
   look wider than the larger shipped-HUD sample sitting next to it. The wave
   still lands at ~91px, so it is unchanged. */
.preview-pill {
  display: flex;
  align-items: center;
  justify-content: center;
  width: auto;
  height: 26px;
  padding: 0 14px;
  overflow: hidden;
  border-radius: 999px;
}

.preview-pill-dark {
  background: rgba(24, 28, 36, 0.84);
  border: 0.75px solid rgba(213, 222, 242, 0.25);
  box-shadow: 0 0 14px rgba(180, 196, 228, 0.11);
}

/* Both samples set height only and let `width: auto` follow the canvas's
   intrinsic aspect, which main.js sizes from the style's viewport. */
.preview-canvas.preview-acceptance {
  width: auto;
  height: 26px;
}

/* The honest shipped fit. Phantom Voice's Standard HUD size draws a 32pt
   glyph inside a 43pt pill (indicatorHeight + 11), with 14.5pt of pill either
   side of the art (normalWidth = content + 29). Those numbers come from
   HUDLayout in the app; keep them in step if HUDLayout changes. */
.preview-canvas.preview-shipped {
  width: auto;
  height: 32px;
}

.preview-pill-shipped {
  width: auto;
  height: 43px;
  padding: 0 14.5px;
  background: rgba(24, 28, 36, 0.84);
  border: 0.75px solid rgba(213, 222, 242, 0.25);
  box-shadow: 0 0 14px rgba(180, 196, 228, 0.11);
}

/* Pricing-row thumbnails share the atelier player rather than a second
   hardcoded-fps sprite path. Their sizing lives with the .hud-pill rules
   above, not here: a bare `.addon-canvas` selector (0-1-0) loses to
   `.hud-pill canvas` (0-1-1), so a rule written here is silently dead and the
   sprite gets stretched to the waveform's 84x24. That is exactly what
   happened, so do not re-add one. */

.indicator-preview-cell > h4 {
  color: #aab2c1;
  font-size: 0.625rem;
  font-weight: 620;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.indicator-preview-cell > h4 span {
  margin-left: 6px;
  color: #838b98;
  letter-spacing: 0;
  text-transform: none;
}


[hidden] {
  display: none !important;
}

.pricing-section {
  position: relative;
}

.pricing-heading {
  display: grid;
  grid-template-columns: 3fr 7fr 2fr;
  gap: clamp(26px, 5vw, 78px);
  align-items: start;
}

.pricing-heading .eyebrow {
  padding-top: 13px;
}

.pricing-heading > p:last-child {
  padding-top: 13px;
  color: var(--muted);
}

.store-status {
  width: min(100%, var(--max));
  margin: 42px auto 0;
  padding: 16px 18px;
  color: var(--signal-dark);
  background: rgba(237, 90, 53, 0.08);
  border: 1px solid rgba(135, 48, 27, 0.35);
  font-family: var(--mono);
  font-size: 0.67rem;
  line-height: 1.6;
}

.voice-offer {
  display: grid;
  grid-template-columns: 1fr 5fr 2.4fr;
  gap: clamp(24px, 4vw, 68px);
  align-items: start;
  margin-top: clamp(75px, 9vw, 135px);
  padding: clamp(28px, 4vw, 56px);
  /* Ink, not white: measured against --signal (#ed5a35), white body copy is
     only 2.5-3.1:1 and fails WCAG AA. Ink is 5.2:1 and passes. The two display
     elements below opt back into paper-bright, where the large-text 3:1
     threshold applies and the contrast is comfortable. */
  color: var(--ink);
  background: var(--signal);
  border: 1px solid var(--ink);
  box-shadow: 0 14px 0 var(--ink);
}

.offer-index {
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.offer-main {
  display: flex;
  justify-content: space-between;
  gap: 30px;
}

.offer-main h3 {
  color: var(--paper-bright);
  font-size: clamp(2.5rem, 5vw, 5.5rem);
  font-weight: 640;
  letter-spacing: -0.07em;
  line-height: 0.9;
}

.offer-main p {
  max-width: 430px;
  margin-top: 20px;
  color: var(--ink);
}

.offer-price {
  text-align: right;
}

.offer-price strong,
.offer-price span {
  display: block;
}

.offer-price strong {
  color: var(--paper-bright);
  font-size: clamp(3.2rem, 6vw, 6.8rem);
  font-weight: 580;
  letter-spacing: -0.08em;
  line-height: 0.75;
}

.offer-price span {
  margin-top: 18px;
  font-family: var(--mono);
  font-size: 0.58rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.voice-offer ul {
  grid-column: 2;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 9px 28px;
  color: var(--ink);
  font-size: 0.79rem;
  list-style: none;
}

.voice-offer li::before {
  margin-right: 9px;
  content: "✓";
}

.voice-offer .button {
  grid-column: 3;
  grid-row: 2;
}

.addon-ledger {
  margin-top: clamp(80px, 9vw, 130px);
  border-top: 1px solid var(--ink);
}

/* Every row is its own grid, so `auto` tracks size to that row's content and
   nothing lines up between rows: "Buy Real Revolver" is 21px wider than "Buy
   Retro Dog", which pushed that row's price and button off the column its
   neighbours sat on. The last two tracks are therefore fixed, so three
   independent grids resolve to identical geometry. 170px clears the widest
   label (149px) with room for a longer one. */
.addon-row {
  display: grid;
  grid-template-columns: minmax(120px, 1.2fr) 5fr 72px 170px;
  gap: clamp(18px, 3vw, 48px);
  align-items: center;
  min-height: 150px;
  padding: 24px 0;
  border-bottom: 1px solid var(--line);
}

/* Prices right-align like a ledger, so the figures stack under each other
   whether they read $3 or $10. */
.addon-row > strong {
  justify-self: end;
}

/* `.button` is space-between so a trailing price span sits on the right edge.
   These carry a label only, so in a fixed-width track that leaves it stranded
   at the left with dead space beside it. */
.addon-row .button {
  width: 100%;
  justify-content: center;
}

.addon-preview {
  display: grid;
  place-items: center;
  width: 118px;
  height: 70px;
  background: var(--ink);
}

.addon-row > div:nth-child(2) > span {
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.58rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.addon-row h3 {
  margin-top: 3px;
  font-size: clamp(1.45rem, 2.5vw, 2.5rem);
  font-weight: 620;
  letter-spacing: -0.045em;
}

.addon-row p {
  margin-top: 4px;
  color: var(--muted);
  font-size: 0.8rem;
}

.addon-row > strong {
  font-family: var(--mono);
  font-size: 1.35rem;
}

.license-note {
  margin-top: 25px;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.63rem;
  line-height: 1.7;
}

/* Download band, sitting between the indicator atelier and pricing.
   Ink on paper: the page is light, so the one section whose whole job is a
   single action inverts to carry weight without inventing a new visual
   language. It reuses the download card's treatment from documents.css, so
   the two places a visitor can start a download look like the same object. */
.download-band {
  width: min(100%, var(--max));
  margin: clamp(80px, 9vw, 130px) auto 0;
  padding: 0 var(--side);
}

.download-band-inner {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: clamp(28px, 5vw, 72px);
  align-items: center;
  padding: clamp(30px, 4.5vw, 62px);
  color: var(--paper-bright);
  background: var(--ink);
  box-shadow: 10px 10px 0 var(--signal);
}

.download-band-copy .eyebrow {
  color: var(--signal-hot);
}

.download-band-copy h2 {
  margin-top: 14px;
  font-size: clamp(2rem, 4vw, 3.6rem);
  font-weight: 640;
  letter-spacing: -0.055em;
  line-height: 0.98;
}

.download-band-copy p {
  max-width: 46ch;
  margin-top: 16px;
  /* 0.58 alpha on ink measures ~7:1; the muted ink token is a light-section
     colour and would be unreadable here. */
  color: rgba(248, 245, 237, 0.66);
  font-size: 0.88rem;
}

.download-band-action {
  display: grid;
  justify-items: stretch;
  min-width: 260px;
}

.download-band-button {
  justify-content: center;
  min-height: 56px;
  font-size: 0.82rem;
}

/* Version and size arrive from catalog.json, so each span holds a non-breaking
   space until it is filled: the row keeps its height and the button never
   moves under a cursor that is already on it. */
.download-band-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  margin-top: 16px;
  color: rgba(248, 245, 237, 0.52);
  font-family: var(--mono);
  font-size: 0.57rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.download-band-links {
  margin-top: 14px;
  font-size: 0.76rem;
}

.download-band-links a {
  color: rgba(248, 245, 237, 0.66);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.download-band-links a:hover {
  color: var(--paper-bright);
}

/* Real sale and download counts, read from /api/stats.
   A ledger line, not a badge: the section is already a ledger, and a recorded
   entry reads as a fact at any size where "1,200+ happy users" would read as a
   boast at a large one and as an embarrassment at a small one. The dotted
   leader is the whole device — label on the left, figure on the right, the way
   a printed ledger or a table of contents sets a value against its key.

   Space is reserved rather than added: the line occupies its height from first
   paint and only becomes visible once a real number arrives (`is-known`), so a
   count landing after the fetch resolves cannot shift the row it sits in. That
   is also why it uses visibility rather than the `hidden` attribute, and why
   the figures are tabular — 4 and 44 must occupy the same width. */
.ledger-count {
  display: flex;
  gap: 10px;
  align-items: baseline;
  visibility: hidden;
  max-width: 220px;
  margin-top: 12px;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.58rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.ledger-count.is-known {
  visibility: visible;
}

.ledger-count-rule {
  flex: 1;
  border-bottom: 1px dotted currentColor;
  opacity: 0.5;
  transform: translateY(-2px);
}

.ledger-count-value {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  letter-spacing: 0.04em;
}

/* On the $10 offer the surface is --signal, where --muted has no contrast.
   Ink measures 5.2:1 there (see .voice-offer), which small text needs. */
.offer-price .ledger-count {
  margin-top: 14px;
  margin-left: auto;
  color: var(--ink);
}

/* ---------------------------------------------------------------------------
   What's new — the release ledger.

   A changelog is the same kind of object as the pricing ledger below it: a
   record, in order, where the entry and its date are the data and everything
   else is commentary. So it borrows that section's vocabulary rather than
   inventing a second one — mono tabular figures, a dotted leader, ink on
   paper — and sits on --paper-bright so it reads as a separate sheet from the
   --paper pricing section immediately after it.

   Like .ledger-count, the whole ledger is laid out at first paint and only
   made visible once real data arrives, so nothing below it moves when the
   fetch resolves. That is why this uses visibility and not the hidden
   attribute: hidden would collapse the space it is reserving.
   --------------------------------------------------------------------------- */
.updates-section {
  padding: clamp(90px, 10vw, 160px) var(--side);
  background: var(--paper-bright);
}

.updates-heading {
  display: grid;
  grid-template-columns: 3fr 9fr;
  column-gap: clamp(25px, 5vw, 80px);
  row-gap: 0;
  align-items: start;
  width: min(100%, var(--max));
  margin: 0 auto;
}

.updates-heading .eyebrow {
  padding-top: 12px;
  color: var(--signal-dark);
}

.updates-heading h2 {
  font-size: clamp(2rem, 5vw, 4.1rem);
  font-weight: 560;
  letter-spacing: -0.045em;
  line-height: 0.98;
}

.updates-heading > p:last-child {
  grid-column: 2;
  max-width: 620px;
  margin-top: 22px;
  color: var(--ink-wash);
  font-size: 0.98rem;
  line-height: 1.7;
}

.release-ledger {
  width: min(100%, var(--max));
  margin: clamp(55px, 6vw, 90px) auto 0;
  border-top: 1px solid var(--ink);
  visibility: hidden;
}

.release-ledger.is-loaded {
  visibility: visible;
}

/* Same 3fr/9fr as the section heading above, so the notes begin on exactly the
   left edge of "What's new." and the section reads as one document. The ledger
   line itself still spans the full width — the leader running the whole measure
   is the thing that makes it a ledger entry rather than a paragraph. */
.release-entry {
  display: grid;
  grid-template-columns: 3fr 9fr;
  column-gap: clamp(25px, 5vw, 80px);
  border-bottom: 1px solid var(--line);
}

.release-line,
details.release-entry > summary,
.release-entry.is-skeleton .release-notes {
  grid-column: 1 / -1;
}

.release-notes {
  grid-column: 2;
}

/* The ledger line is the entry: version, leader, date. Fixed height so a row
   occupies exactly the same space before and after the fetch. */
.release-line,
.release-entry > summary {
  display: flex;
  gap: 18px;
  align-items: baseline;
  min-height: 62px;
  margin: 0;
  padding: 20px 0 18px;
  font-family: var(--mono);
  font-size: 0.58rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted);
}

.release-version {
  color: var(--ink);
  font-size: 0.72rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
}

.release-rule {
  flex: 1;
  border-bottom: 1px dotted currentColor;
  opacity: 0.5;
  transform: translateY(-3px);
}

.release-date {
  font-variant-numeric: tabular-nums;
}

/* The newest release is the one people came for, so it is open and not a
   disclosure at all. Everything older is a <details>. The badge is real text
   rather than generated content: it is the only thing marking which build you
   would actually get, so it has to survive into the accessibility tree. */
.release-tag {
  padding: 3px 7px;
  border: 1px solid var(--signal-dark);
  border-radius: 2px;
  color: var(--signal-dark);
  font-size: 0.5rem;
  font-weight: 500;
  letter-spacing: 0.09em;
}

details.release-entry > summary {
  cursor: pointer;
  list-style: none;
}

details.release-entry > summary::-webkit-details-marker {
  display: none;
}

details.release-entry > summary::after {
  content: "+";
  width: 24px;
  color: var(--signal-dark);
  font-size: 1.1rem;
  text-align: center;
  transition: transform 240ms var(--ease);
}

details.release-entry[open] > summary::after {
  transform: rotate(45deg);
}

details.release-entry > summary:focus-visible {
  outline: 2px solid var(--signal-dark);
  outline-offset: 3px;
}

.release-notes {
  max-width: 68ch;
  padding-bottom: 34px;
  color: var(--ink-wash);
  font-size: 0.95rem;
  line-height: 1.72;
}

.release-notes > *:first-child {
  margin-top: 0;
}

.release-notes h4 {
  margin: 26px 0 8px;
  color: var(--ink);
  font-size: 1.02rem;
  font-weight: 560;
  letter-spacing: -0.015em;
  text-transform: none;
}

.release-notes p,
.release-notes li {
  margin: 0 0 12px;
}

.release-notes ul {
  margin: 0 0 12px;
  padding-left: 20px;
  list-style: disc;
}

.release-notes small {
  color: var(--muted);
  font-size: 0.82rem;
}

/* Reads as another ledger line rather than a call to action: it is a way to
   see more of a record, not something anyone is being asked to do. */
.release-more {
  display: block;
  width: 100%;
  padding: 20px 0 18px;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: none;
  color: var(--signal-dark);
  cursor: pointer;
  font-family: var(--mono);
  font-size: 0.58rem;
  letter-spacing: 0.07em;
  text-align: left;
  text-transform: uppercase;
}

.release-more:hover {
  color: var(--ink);
}

.release-more:focus-visible {
  outline: 2px solid var(--signal-dark);
  outline-offset: 3px;
}

.release-fallback {
  width: min(100%, var(--max));
  margin: 34px auto 0;
  color: var(--ink-wash);
  font-size: 0.92rem;
}

.release-fallback a {
  border-bottom: 1px solid var(--signal-dark);
}

@media (max-width: 860px) {
  .updates-heading {
    grid-template-columns: 1fr;
    gap: 18px;
  }

  .updates-heading > p:last-child {
    grid-column: 1;
    margin-top: 4px;
  }

  /* One column: a phone has no room to give a third of its width to an indent
     the notes were only aligned to on desktop. */
  .release-entry {
    grid-template-columns: 1fr;
  }

  .release-notes {
    grid-column: 1;
  }

  /* The leader is the first thing to go: at this width the version and date
     need the room more than the rule does. */
  .release-rule {
    display: none;
  }

  .release-line,
  .release-entry > summary {
    flex-wrap: wrap;
    gap: 6px 14px;
  }
}

@media (prefers-reduced-motion: reduce) {
  details.release-entry > summary::after {
    transition: none;
  }
}

.faq-section {
  padding: clamp(100px, 12vw, 190px) var(--side);
  color: var(--paper-bright);
  background: var(--ink);
}

.faq-heading {
  display: grid;
  grid-template-columns: 3fr 9fr;
  gap: clamp(25px, 5vw, 80px);
  align-items: start;
}

.faq-heading .eyebrow {
  padding-top: 12px;
  color: var(--signal-hot);
}

.faq-list {
  margin-top: clamp(70px, 8vw, 125px);
  border-top: 1px solid rgba(247, 244, 236, 0.5);
}

.faq-list details {
  border-bottom: 1px solid var(--dark-line);
}

.faq-list summary {
  position: relative;
  display: grid;
  grid-template-columns: 0.5fr 7fr 30px;
  gap: 20px;
  align-items: center;
  min-height: 104px;
  padding: 20px 0;
  cursor: pointer;
  list-style: none;
  font-size: clamp(1.2rem, 2.2vw, 2.1rem);
  font-weight: 540;
  letter-spacing: -0.035em;
}

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

.faq-list summary span {
  color: rgba(247, 244, 236, 0.5);
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.06em;
}

.faq-list summary::after {
  grid-column: 3;
  content: "+";
  color: var(--signal-hot);
  font-family: var(--mono);
  font-size: 1.4rem;
  font-weight: 400;
  text-align: center;
  transition: transform 240ms var(--ease);
}

.faq-list details[open] summary::after {
  transform: rotate(45deg);
}

.faq-list details > p {
  max-width: 760px;
  margin: -5px 60px 38px calc(8.333% + 18px);
  color: rgba(247, 244, 236, 0.55);
  font-size: 0.94rem;
  line-height: 1.75;
}

.faq-list details a {
  color: var(--paper-bright);
  border-bottom: 1px solid var(--signal-hot);
}

.closing-section {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(340px, 4fr);
  gap: clamp(60px, 10vw, 160px);
  align-items: center;
  padding: clamp(100px, 12vw, 190px) var(--side);
  background: var(--paper-bright);
}

.closing-copy .eyebrow {
  margin-bottom: 25px;
  color: var(--signal-dark);
}

.closing-copy h2 {
  max-width: 880px;
}

.closing-copy > p:nth-of-type(2) {
  margin-top: 28px;
  color: var(--muted);
  font-size: 1.05rem;
}

.button-quiet-light {
  color: var(--ink);
  border-color: var(--ink);
}

.button-quiet-light:hover {
  color: var(--paper-bright);
  background: var(--ink);
}

.waitlist-card {
  padding: clamp(28px, 4vw, 52px);
  color: var(--paper-bright);
  background: var(--ink);
  box-shadow: 10px 10px 0 var(--signal);
}

.waitlist-card .eyebrow {
  color: var(--signal-hot);
}

.waitlist-card h3 {
  margin-top: 45px;
  font-size: clamp(1.8rem, 3vw, 3rem);
  font-weight: 600;
  letter-spacing: -0.055em;
  line-height: 1;
}

.waitlist-card > p:nth-of-type(2) {
  margin-top: 15px;
  color: rgba(247, 244, 236, 0.5);
  font-size: 0.84rem;
}

.waitlist-form {
  margin-top: 38px;
}

.waitlist-form label {
  display: block;
  margin-bottom: 9px;
  color: rgba(247, 244, 236, 0.48);
  font-family: var(--mono);
  font-size: 0.58rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.waitlist-form > div {
  display: flex;
}

.waitlist-form input {
  min-width: 0;
  flex: 1;
  height: 50px;
  padding: 0 14px;
  color: var(--paper-bright);
  background: #252824;
  border: 1px solid #55594f;
  border-right: 0;
  border-radius: 0;
}

.waitlist-form input::placeholder {
  color: #7b8075;
}

.waitlist-form button {
  min-width: 105px;
  height: 50px;
  padding: 0 15px;
  cursor: pointer;
  /* Ink, not #fff: white on --signal measures 3.43:1, below AA for a control
     label. Ink is 5.2:1 and keeps the orange. */
  color: var(--ink);
  background: var(--signal);
  border: 0;
  font-size: 0.72rem;
  font-weight: 700;
}

.form-status {
  min-height: 1.4em;
  margin-top: 12px;
  color: #9bd7b2;
  font-family: var(--mono);
  font-size: 0.63rem;
}

.site-footer {
  display: grid;
  grid-template-columns: 2fr 2fr 5fr auto;
  gap: 25px;
  align-items: center;
  padding: 34px var(--side);
  color: rgba(247, 244, 236, 0.5);
  background: #0e100d;
  border-top: 1px solid var(--dark-line);
  font-size: 0.68rem;
}

.footer-brand {
  color: var(--paper-bright);
}

.site-footer nav {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
}

.site-footer nav a:hover {
  color: var(--paper-bright);
}

.copyright {
  justify-self: end;
  font-family: var(--mono);
}

.js .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 700ms ease, transform 850ms var(--ease);
}

.js .reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

@media (max-width: 1180px) {
  .hero-grid {
    grid-template-columns: minmax(0, 1fr) minmax(460px, 1.1fr);
    gap: 40px;
  }

  .hero h1 {
    font-size: clamp(4rem, 7vw, 6.2rem);
  }

  .voice-offer {
    grid-template-columns: 0.8fr 5fr 2fr;
  }
}

@media (max-width: 900px) {
  :root {
    --header-height: 62px;
  }

  .site-header {
    grid-template-columns: 1fr auto;
  }

  .site-nav {
    display: none;
  }

  /* Stack the band and let the button run full width: below this breakpoint
     the site nav is hidden entirely, so this section is the only route to the
     trial on a phone and must not be cramped. */
  .download-band-inner {
    grid-template-columns: 1fr;
    align-items: start;
    box-shadow: 6px 6px 0 var(--signal);
  }

  .download-band-action {
    min-width: 0;
  }

  .hero {
    min-height: auto;
  }

  .hero-grid {
    grid-template-columns: 1fr;
    gap: 72px;
    min-height: auto;
  }

  .hero-copy {
    padding-top: 35px;
  }

  .hero h1 {
    max-width: 720px;
    font-size: clamp(4rem, 12vw, 7rem);
  }

  .instrument {
    max-width: 760px;
    justify-self: center;
  }

  .section-heading {
    grid-template-columns: 1fr;
  }

  .section-heading {
    gap: 26px;
  }

  .indicator-heading,
.pricing-heading,
.faq-heading,
.closing-section {
    grid-template-columns: 1fr;
  }

  @keyframes signal-travel-vertical {
    to { top: 120%; }
  }

  .pricing-heading > p:last-child {
    max-width: 460px;
  }

  .voice-offer {
    grid-template-columns: 1fr 4fr 1.5fr;
  }

  .addon-row {
    grid-template-columns: 130px 1fr auto;
  }

  .addon-row .button {
    grid-column: 2 / -1;
    width: 100%;
  }

  .closing-section {
    width: 100%;
  }

  .waitlist-card {
    max-width: 580px;
  }

  .site-footer {
    grid-template-columns: 1fr 1fr;
  }

  .site-footer nav {
    justify-self: end;
  }

  .copyright {
    grid-column: 2;
  }
}

@media (max-width: 640px) {
  :root {
    --side: 18px;
  }

  .site-header {
    padding: 0 14px;
  }

  .brand {
    font-size: 0.77rem;
  }

  .brand-mark {
    width: 36px;
    height: 36px;
  }

  .header-buy {
    min-height: 38px;
    padding-left: 11px;
  }

  .header-buy span {
    display: none;
  }

  .hero {
    padding-top: calc(var(--header-height) + 45px);
  }

  .hero h1 {
    font-size: clamp(3.35rem, 16.6vw, 5.3rem);
    letter-spacing: -0.075em;
  }

  .hero-lede {
    font-size: 0.98rem;
  }

  .hero-actions,
  .closing-actions {
    display: grid;
    grid-template-columns: 1fr;
  }

  .hero-actions .button,
  .closing-actions .button {
    width: 100%;
  }

  .hero-facts {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }

  .hero-facts li::after {
    display: none;
  }

  .instrument {
    width: calc(100% + 12px);
    padding: 12px;
    transform: translateX(-6px);
    box-shadow: 0 10px 0 #090a09, 0 28px 45px rgba(0, 0, 0, 0.4);
  }

  .instrument-topline span:last-child {
    display: none;
  }

  .editor {
    min-height: 210px;
  }

  .editor-body {
    grid-template-columns: 22px auto 1fr;
    padding: 46px 15px;
    font-size: 0.68rem;
  }

  .state-rail {
    font-size: 0.48rem;
  }

  .hold-area {
    display: grid;
    grid-template-columns: 1fr;
  }

  .fn-key {
    width: 100%;
    min-width: 0;
  }

  /* The key goes full-width here, so there is no room beside it. The arrow
     moves above and points down, held to the right where the status line
     has already ended, so the two never share the same space. */
  .fn-key--cue::before {
    top: auto;
    bottom: calc(100% + 4px);
    right: 26px;
    width: 26px;
    height: 12px;
    margin-top: 0;
    animation-name: fn-key-cue-arrow-down;
  }

  .hero-ledger {
    grid-template-columns: 1fr;
    margin-top: 80px;
  }

  .hero-ledger span {
    min-height: 48px;
    padding: 16px 18px;
    border-right: 1px solid var(--dark-line);
    border-bottom: 1px solid var(--dark-line);
    border-left: 1px solid var(--dark-line);
  }

  .section-heading h2,
.indicator-heading h2,
.pricing-heading h2,
.faq-heading h2,
.closing-copy h2 {
    font-size: clamp(2.65rem, 13.5vw, 4rem);
  }

  .indicator-heading {
    gap: 30px;
  }

  .indicator-preview-card {
    padding: 12px;
  }

  .indicator-preview-cells {
    grid-template-columns: 1fr;
  }

  .voice-offer {
    grid-template-columns: 1fr;
  }

  .offer-index,
  .offer-main,
  .voice-offer ul,
  .voice-offer .button {
    grid-column: 1;
  }

  .offer-main {
    display: grid;
  }

  .offer-price {
    margin-top: 12px;
    text-align: left;
  }

  .voice-offer ul {
    grid-template-columns: 1fr;
  }

  .voice-offer .button {
    grid-row: auto;
    width: 100%;
  }

  .addon-row {
    grid-template-columns: 1fr auto;
    gap: 18px;
    padding: 30px 0;
  }

  .addon-preview {
    grid-column: 1 / -1;
    width: 100%;
  }

  .addon-row > div:nth-child(2) {
    min-width: 0;
  }

  .addon-row .button {
    grid-column: 1 / -1;
  }

  .faq-list summary {
    grid-template-columns: 32px 1fr 24px;
    min-height: 90px;
    font-size: 1.06rem;
  }

  .faq-list details > p {
    margin: -2px 0 30px 52px;
    font-size: 0.84rem;
  }

  .waitlist-card {
    box-shadow: 7px 7px 0 var(--signal);
  }

  .waitlist-form > div {
    display: grid;
    gap: 8px;
  }

  .waitlist-form input {
    border-right: 1px solid #55594f;
  }

  .site-footer {
    grid-template-columns: 1fr;
    padding-top: 45px;
    padding-bottom: 45px;
  }

  .site-footer nav,
  .copyright {
    grid-column: 1;
    justify-self: start;
  }
}

@media (max-height: 520px) and (orientation: landscape) {
  .hero-grid {
    padding-top: 30px;
  }

  .instrument {
    max-width: 700px;
  }

  .editor {
    min-height: 180px;
  }

  .editor-body {
    padding-top: 35px;
    padding-bottom: 35px;
  }
}

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

  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }

  .js .reveal {
    opacity: 1;
    transform: none;
  }
}

@media (forced-colors: active) {
  .button,
.hud-pill,
.preview-pill,
.instrument,
.indicator-preview-card,
.voice-offer {
    border: 2px solid CanvasText;
  }

  .status-dot {
    forced-color-adjust: none;
  }
}

/* ============================================================
   RECEPTION + ASKED BY READERS
   Reviews and reader questions, collected on this page because
   this is the product they are about. Filled stars take the
   orange signal, the one accent this page already spends on
   "this matters". Answered questions reuse the FAQ accordion
   exactly: a reader's question and a written FAQ entry look
   like the same kind of thing because they are.
   ============================================================ */
:root {
  --star-clip: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
  --ok-ink: #1f6b4d;   /* success text, dark enough to read on paper */
}

/* Several rules below set an explicit display, which would otherwise beat
   the `hidden` attribute the review markup relies on. */
[hidden] { display: none !important; }

.reception-section {
  padding: clamp(90px, 10vw, 160px) var(--side);
  background: var(--paper);
}

.asked-section {
  padding: clamp(90px, 10vw, 160px) var(--side);
  background: var(--paper-bright);
}

.network-section {
  padding: clamp(90px, 10vw, 160px) var(--side);
  background: var(--paper-bright);
  border-top: 1px solid var(--line);
}

.reception-section > *,
.asked-section > *,
.network-section > * {
  width: min(100%, var(--max));
  margin-right: auto;
  margin-left: auto;
}

/* Sentences, not slogans, so smaller than the display headings elsewhere. */
.reception-section .section-heading h2,
.asked-section .section-heading h2 {
  max-width: 18ch;
  font-size: clamp(2.35rem, 4.8vw, 4.9rem);
  letter-spacing: -0.05em;
  line-height: 1.02;
}

.network-heading {
  max-width: 68rem;
}

.network-heading h2 {
  max-width: 16ch;
  margin: 0;
  color: var(--ink);
  font-size: clamp(2.35rem, 4.8vw, 4.9rem);
  letter-spacing: -0.05em;
  line-height: 1.02;
}

.network-heading > p:last-child {
  max-width: 68ch;
  margin: clamp(22px, 2.8vw, 34px) 0 0;
  color: var(--ink-soft);
  font-size: clamp(1rem, 1.25vw, 1.25rem);
  line-height: 1.62;
}

.network-table-wrap {
  margin-top: clamp(42px, 5vw, 72px);
  border-top: 1px solid var(--ink);
}

.network-table {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}

.network-table th,
.network-table td {
  padding: clamp(18px, 2vw, 30px) clamp(14px, 1.8vw, 28px);
  border-bottom: 1px solid var(--line);
  vertical-align: top;
  text-align: left;
}

.network-table thead th {
  padding-top: 14px;
  padding-bottom: 14px;
  color: var(--signal-dark);
  font-family: var(--mono);
  font-size: 0.67rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  line-height: 1.45;
  text-transform: uppercase;
}

.network-table th:first-child,
.network-table td:first-child { padding-left: 0; }

.network-table th:last-child,
.network-table td:last-child { padding-right: 0; }

.network-table tbody th {
  width: 19%;
  color: var(--ink);
  font-size: clamp(1rem, 1.25vw, 1.2rem);
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.25;
}

.network-table tbody td {
  color: var(--ink-soft);
  font-size: clamp(0.92rem, 1.05vw, 1.06rem);
  line-height: 1.58;
}

.network-host {
  display: block;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 0.76em;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1.55;
  overflow-wrap: anywhere;
}

.network-detail {
  display: block;
  margin-top: 5px;
  color: var(--muted);
  font-size: 0.88em;
  line-height: 1.4;
}

.network-footnotes {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(22px, 4vw, 56px);
  padding: clamp(24px, 3vw, 38px) 0 0;
}

.network-footnotes p {
  max-width: 58ch;
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.9rem;
  line-height: 1.65;
}

.network-footnotes strong { color: var(--ink); }

.reception-body {
  display: grid;
  grid-template-columns: 3fr 7fr;
  column-gap: clamp(28px, 5vw, 80px);
  row-gap: clamp(30px, 3.5vw, 48px);
  margin-top: clamp(44px, 5vw, 76px);
}

/* Everything lines up under the headline, not under the eyebrow. */
.reception-body > * {
  grid-column: 2;
  min-width: 0;
}

/* ---------- the aggregate, stated as a ledger ---------- */
.reception-ledger {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px clamp(22px, 3vw, 42px);
  padding-bottom: clamp(22px, 3vw, 32px);
  border-bottom: 1px solid var(--line);
}

.reception-stat {
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.reception-stat b {
  margin-right: 7px;
  color: var(--ink);
  font-size: 1.55rem;
  font-weight: 750;
  letter-spacing: -0.03em;
}

.reception-stat-stars {
  display: inline-flex;
  gap: 3px;
}

/* ---------- stars ---------- */
/* clip-path rather than a glyph: ★ is missing from plenty of the system
   fonts this page falls back to, and renders as a box when it is. */
.star {
  display: inline-block;
  width: 15px;
  height: 15px;
  background: var(--signal);
  clip-path: var(--star-clip);
}

.star.is-off {
  background: rgba(21, 23, 19, 0.2);
}

/* ---------- published reviews ---------- */
.review-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.review-entry {
  padding: clamp(22px, 3vw, 30px) 0;
  border-bottom: 1px solid var(--line);
}

.review-entry:first-child { padding-top: 0; }
.review-entry:last-child { padding-bottom: 0; border-bottom: 0; }

.review-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 16px;
  margin-bottom: 12px;
}

.review-stars {
  display: inline-flex;
  flex: none;
  gap: 3px;
}

.review-name {
  color: var(--ink);
  font-size: 1.02rem;
  font-weight: 750;
  letter-spacing: -0.01em;
}

.review-date {
  margin-left: auto;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
}

.review-text {
  max-width: 64ch;
  margin: 0;
  color: var(--ink-soft);
  font-size: 1.02rem;
  line-height: 1.62;
}

.reception-empty {
  max-width: 52ch;
  margin: 0;
  color: var(--muted);
  font-size: 1rem;
  font-style: italic;
}

/* Written beside the section when a visitor arrives from an email link. */
.reception-note {
  max-width: 54ch;
  margin: 0;
  padding: 14px 17px;
  color: var(--ink-soft);
  background: var(--paper-bright);
  border-left: 3px solid var(--signal);
  font-size: 0.98rem;
  line-height: 1.6;
}

.asked-section .reception-note { background: var(--paper); }
.reception-note.is-error { border-left-color: var(--signal-dark); }

.reception-actions { display: flex; }

/* ---------- the form ---------- */
.review-form-wrap { max-width: 40rem; }

.review-form-wrap .field { margin-bottom: 20px; }

.review-form-wrap label,
.rating-input legend {
  display: block;
  padding: 0;
  margin-bottom: 8px;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.67rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.field-hint {
  text-transform: none;
  letter-spacing: 0.02em;
  opacity: 0.82;
}

.review-form-wrap input,
.review-form-wrap textarea {
  display: block;
  width: 100%;
  min-height: 48px;
  padding: 12px 14px;
  color: var(--ink);
  background: var(--paper-bright);
  border: 1px solid var(--line);
  border-radius: 3px;
  /* 1rem = 16px: anything smaller makes iOS zoom the page on focus. */
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.5;
  transition: border-color 160ms ease, box-shadow 160ms ease;
}

.asked-section .review-form-wrap input,
.asked-section .review-form-wrap textarea { background: var(--paper); }

.review-form-wrap textarea {
  min-height: 130px;
  resize: vertical;
}

.review-form-wrap input:focus,
.review-form-wrap textarea:focus {
  outline: none;
  border-color: var(--signal);
  box-shadow: 0 0 0 3px rgba(237, 90, 53, 0.18);
}

/* ---------- the rating ---------- */
.rating-input {
  margin: 0 0 22px;
  padding: 0;
  border: 0;
}

/* row-reverse so the markup can run 5 down to 1, which is what makes the
   sibling selector below work, while the eye still reads 1 up to 5. */
.rating-stars {
  display: flex;
  flex-direction: row-reverse;
  justify-content: flex-end;
}

.rating-stars input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.rating-stars label {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  cursor: pointer;
}

.rating-stars label::before {
  content: "";
  width: 26px;
  height: 26px;
  background: rgba(21, 23, 19, 0.2);
  clip-path: var(--star-clip);
  transition: background 160ms ease;
}

/* Fills the chosen star and every lower one: the labels that follow it in
   the DOM are exactly the ones to its left on screen. */
.rating-stars input:checked ~ label::before { background: var(--signal); }

@media (hover: hover) {
  .rating-stars:hover label::before { background: rgba(21, 23, 19, 0.2); }
  .rating-stars label:hover::before,
  .rating-stars label:hover ~ label::before { background: var(--signal-hot); }
}

.rating-stars input:focus-visible + label {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
  border-radius: 3px;
}

/* Off-screen rather than display:none - a bot that skips undisplayed fields
   would sail straight through the honeypot. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.cf-turnstile { margin-bottom: 18px; }

.form-status {
  max-width: 46ch;
  margin: 14px 0 0;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.73rem;
  line-height: 1.75;
}

.form-status.is-error { color: var(--signal-dark); }
.form-status.is-ok { color: var(--ok-ink); }

/* On success the form has done its job - where to go next is the only thing
   left worth reading. */
form.is-done > *:not(.form-status) { display: none; }
form.is-done .form-status { margin-top: 0; font-size: 0.88rem; }

@media (max-width: 900px) {
  .reception-body { grid-template-columns: 1fr; }
  .reception-body > * { grid-column: 1; }

  .network-footnotes { grid-template-columns: 1fr; }
}

@media (max-width: 720px) {
  .network-table,
  .network-table tbody,
  .network-table tr,
  .network-table th,
  .network-table td {
    display: block;
    width: 100%;
  }

  .network-table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }

  .network-table tbody tr {
    padding: clamp(24px, 6vw, 34px) 0;
    border-bottom: 1px solid var(--line);
  }

  .network-table tbody th,
  .network-table tbody td {
    padding: 0;
    border: 0;
  }

  .network-table tbody td {
    display: grid;
    grid-template-columns: minmax(7.5rem, 0.8fr) minmax(0, 1.5fr);
    gap: 14px;
    margin-top: 15px;
  }

  .network-table tbody td::before {
    content: attr(data-label);
    color: var(--signal-dark);
    font-family: var(--mono);
    font-size: 0.64rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    line-height: 1.5;
    text-transform: uppercase;
  }
}

@media (max-width: 640px) {
  /* The date stops being a right-hand column and takes its own line, rather
     than being squeezed against the reviewer's name. */
  .review-date { margin-left: 0; width: 100%; }
}

/* .faq-list is written for .faq-section, which is ink-on-dark. Reader
   questions reuse the same accordion on paper, so every colour in it has to
   be inverted - left alone, the "01" numbers are near-white on cream and
   simply do not appear. */
.asked-section .faq-list {
  margin-top: 0;
  border-top-color: var(--line);
}

.asked-section .faq-list details { border-bottom-color: var(--line); }
.asked-section .faq-list summary { color: var(--ink); }
.asked-section .faq-list summary span { color: var(--muted); }
.asked-section .faq-list summary::after { color: var(--signal); }
.asked-section .faq-list details > p { color: var(--ink-soft); }

.asked-section .faq-list details a {
  color: var(--ink);
  border-bottom-color: var(--signal);
}

/* The answer's left indent is measured against the FAQ's own full-width
   layout; in this narrower column it has to line up with the summary's
   0.5fr number track instead (0.5 of 7.5fr, plus the 20px gap). */
.asked-section .faq-list details > p {
  margin-left: calc(6.7% + 20px);
  margin-right: 30px;
}

.asked-section .faq-list summary { min-height: 84px; }

/* ============================================================
   FILM - the real recording, as the honest counterpart to the
   hero's scripted demo. Paper, so it reads as evidence rather
   than as another dark product panel.
   ============================================================ */
.film-section {
  padding: clamp(90px, 10vw, 150px) var(--side);
  background: var(--paper-bright);
}

.film-section > * {
  width: min(100%, var(--max));
  margin-right: auto;
  margin-left: auto;
}

/* The label introduces the evidence rather than consuming a dedicated
   desktop column beside it. */
.film-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  row-gap: clamp(16px, 2vw, 28px);
}

.film-body .eyebrow {
  padding-top: 0;
  margin: 0;
  color: var(--signal-dark);
}

/* width/height on the element are there for the aspect before CSS lands;
   the ratio here is what actually governs it at every width. */
.film-embed {
  display: block;
  grid-column: 1;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  background: var(--ink);
  border: 1px solid var(--line);
  border-radius: 4px;
}

@media (max-width: 900px) {
  .film-body { grid-template-columns: 1fr; }
  .film-embed { grid-column: 1; }
}
