:root {
  --bg: #0b0d10;
  --bg-raised: #14181d;
  --bg-input: #1c2229;
  --border: #262d36;
  --text: #eef2f6;
  --text-muted: #8f9bab;
  --accent: #e82127; /* Tesla red */
  --ok: #35c46b;
  --warn: #e5a13a;
  --error: #f0555c;
  --radius: 14px;
  --touch: 56px;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

* {
  box-sizing: border-box;
}

/* Author-level display rules below outrank the UA stylesheet's [hidden] rule,
   so the attribute has to be enforced explicitly. */
[hidden] {
  display: none !important;
}

/* The root element has to carry the page background too. Body is a flex column
   that stops at the viewport, so on a phone the content runs past it and
   anything painted only on body leaves the rest of the scroll on the root
   colour, with ink-coloured text stranded on top of it. */
html,
body {
  margin: 0;
  min-height: 100%;
  background: var(--canvas);
  color: var(--text);
  -webkit-text-size-adjust: 100%;
}

body {
  display: flex;
  flex-direction: column;
  overscroll-behavior: none;
}

a {
  color: var(--text);
}

/* ---------- Layout ---------- */

.page {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 24px;
  gap: 24px;
  text-align: center;
}

.panel {
  width: 100%;
  max-width: 560px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 24px;
  text-align: left;
}

.panel + .panel {
  margin-top: 16px;
}

h1 {
  margin: 0;
  font-size: 28px;
  letter-spacing: -0.02em;
}

h2 {
  margin: 0 0 12px;
  font-size: 18px;
  letter-spacing: -0.01em;
}

p {
  margin: 0 0 12px;
  color: var(--text-muted);
  line-height: 1.5;
}

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

.muted {
  color: var(--quiet);
  font-size: 14px;
}

/* ---------- Pairing code ---------- */

.code {
  font-size: clamp(64px, 18vw, 156px);
  font-weight: 700;
  letter-spacing: 0.12em;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  margin: 8px 0;
  text-shadow: 0 0 60px rgba(232, 33, 39, 0.35);
}

.status {
  font-size: 16px;
  color: var(--text-muted);
  min-height: 24px;
}

.status--ok {
  color: var(--ok);
}
.status--warn {
  color: var(--warn);
}
.status--error {
  color: var(--error);
}

/* ---------- Controls ---------- */

button,
.button {
  min-height: var(--touch);
  padding: 0 22px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-input);
  color: var(--text);
  font-size: 17px;
  font-weight: 600;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  text-decoration: none;
}

button:hover:not(:disabled) {
  border-color: #39424e;
}

button:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

button.primary {
  background: var(--accent);
  border-color: var(--accent);
}

input,
select {
  width: 100%;
  min-height: var(--touch);
  padding: 0 16px;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text);
  font-size: 17px;
}

input:focus,
select:focus,
button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.field {
  margin-bottom: 16px;
}

.field label {
  display: block;
  margin-bottom: 8px;
  font-size: 14px;
  color: var(--text-muted);
}

.row {
  display: flex;
  gap: 12px;
}

.row > input {
  flex: 1;
}

.code-input {
  font-size: 32px;
  letter-spacing: 0.3em;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.mode-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
}

.mode-grid button {
  flex-direction: column;
  min-height: 96px;
  gap: 6px;
  font-size: 16px;
}

.mode-grid .mode-sub {
  font-size: 12px;
  font-weight: 400;
  color: var(--text-muted);
}

/* ---------- Notes ---------- */

/* A hairline box, not a slab with a coloured tab down one side: the thick
   accent border is the single most recognisable tell of a generated UI. */
.note {
  border: 1px solid color-mix(in srgb, var(--signal) 34%, transparent);
  background: var(--signal-soft);
  padding: 12px 16px;
  border-radius: var(--radius);
  font-size: 14px;
  /* Theme-aware, unlike the legacy muted token, and at full ink rather than
     muted: these carry warnings the user has to actually read. */
  color: var(--ink);
  line-height: 1.5;
}

.note--info {
  border-color: var(--hairline);
  background: color-mix(in srgb, var(--ink) 5%, transparent);
}

/* ---------- Stage (receiver) ---------- */

.stage {
  position: fixed;
  inset: 0;
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
}

.stage video,
.stage iframe {
  width: 100%;
  height: 100%;
  border: 0;
  background: #000;
}

.stage video {
  object-fit: contain;
}

/* iOS captures the physical display, which stays portrait however the device
   is held: rotating the phone rotates the picture inside an unchanged frame.
   The receiver has to undo that, so the video box is swapped and turned. */
.stage[data-rotate="90"] video,
.stage[data-rotate="270"] video {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100vh;
  height: 100vw;
}

.stage[data-rotate="90"] video {
  transform: translate(-50%, -50%) rotate(90deg);
}

.stage[data-rotate="270"] video {
  transform: translate(-50%, -50%) rotate(270deg);
}

.stage[data-rotate="180"] video {
  transform: rotate(180deg);
}

/* ---------- Device approval ---------- */

.approval {
  position: fixed;
  inset: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: color-mix(in srgb, var(--canvas) 78%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}

.approval-card {
  width: min(92vw, 520px);
  padding: clamp(28px, 4vw, 44px);
  border-radius: 28px;
  border: 1px solid var(--hairline);
  background: var(--solid);
  box-shadow: var(--product-shadow);
  text-align: center;
}

.approval-card h2 {
  margin: 0 0 12px;
  font-size: clamp(22px, 2.4vw, 30px);
  letter-spacing: -0.02em;
  color: var(--ink);
}

.approval-card .kicker {
  margin-bottom: 12px;
}

.approval-fingerprint {
  margin: 24px 0;
  font-size: clamp(38px, 5vw, 54px);
  font-weight: 700;
  letter-spacing: 0.22em;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.approval-actions {
  display: flex;
  gap: 12px;
  justify-content: center;
}

.approval-actions button {
  flex: 1 1 0;
  max-width: 200px;
}

/* ---------- Diagnostics ---------- */

/* Both readouts sit on a deliberately dark surface, so their colours are
   pinned rather than inherited: a theme-driven ink would land dark-on-dark. */
.stats-overlay,
.stats-inline {
  display: grid;
  gap: 2px 20px;
  margin: 0;
  font-variant-numeric: tabular-nums;
  color: #f4f6f7;
}

.stats-overlay {
  position: fixed;
  top: 16px;
  left: 16px;
  z-index: 2;
  grid-template-columns: 1fr;
  /* Room on the right for the close control, which overlaps the first row. */
  padding: 12px 52px 12px 16px;
  border-radius: var(--radius);
  background: rgba(12, 14, 16, 0.88);
  border: 1px solid rgba(255, 255, 255, 0.14);
  font-size: 13px;
}

.stats-inline {
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  margin-top: 16px;
  padding: 14px 16px;
  border-radius: var(--radius);
  background: #16191c;
  border: 1px solid rgba(255, 255, 255, 0.12);
  font-size: 13px;
}

.stats-overlay > div,
.stats-inline > div {
  display: flex;
  justify-content: space-between;
  gap: 12px;
}

.stats-overlay dt,
.stats-inline dt {
  color: rgba(244, 246, 247, 0.66);
}

.stats-overlay dd,
.stats-inline dd {
  margin: 0;
  font-weight: 600;
  color: #ffffff;
}

.stats-close {
  position: absolute;
  top: 6px;
  right: 6px;
  /* A car touchscreen gets a real target, even though the glyph is small. */
  width: 44px;
  height: 44px;
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: rgba(244, 246, 247, 0.72);
  display: flex;
  align-items: center;
  justify-content: center;
}

.stats-close:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.08);
  border-color: transparent;
  color: #ffffff;
}

.stats-close svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}

.checkrow {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin-top: 20px;
  cursor: pointer;
  line-height: 1.4;
}

.checkrow input {
  width: auto;
  min-height: 0;
  margin-top: 3px;
  flex: 0 0 auto;
  accent-color: var(--accent);
}

.checkrow .mode-sub {
  display: block;
  margin-top: 2px;
}

.controls {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 12px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms ease;
}

.controls.is-visible {
  opacity: 1;
  pointer-events: auto;
}

.link-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  background: rgba(11, 13, 16, 0.9);
  font-size: 14px;
}

.link-bar span {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-muted);
}

.link-bar .button {
  min-height: 40px;
  font-size: 14px;
}

/* ---------- Preview (sender) ---------- */

.preview-wrap {
  margin-top: 16px;
  border-radius: var(--radius);
  overflow: hidden;
  background: #000;
  border: 1px solid var(--border);
}

.preview-wrap video {
  display: block;
  width: 100%;
  max-height: 240px;
  object-fit: contain;
}

/* ---------- Report table ---------- */

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

th,
td {
  text-align: left;
  padding: 10px 8px;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}

th {
  font-weight: 600;
  white-space: nowrap;
}

td:last-child {
  color: var(--text-muted);
  word-break: break-word;
}

/* The verdict is the one thing a reader scans for, so it carries a dot in its
   own colour as well as the word. A tinted pill on its own would put the whole
   answer on a hue, which is the wrong thing to depend on in a bright car. */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .02em;
  text-transform: uppercase;
  white-space: nowrap;
}

.badge::before {
  content: "";
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
}

.badge--pass { color: var(--green); }
.badge--fail { color: var(--danger); }
.badge--warn { color: var(--signal); }
.badge--info { color: var(--quiet); }
.badge--warn::before,
.badge--info::before { background: none; box-shadow: inset 0 0 0 1.5px currentColor; }

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none !important;
  }
}

/* ---------- Relay product shell ---------- */

/* Instrument surface. Signal amber carries the surface; live green means a
   session is connected and nothing else. See DESIGN.md. */
:root {
  color-scheme: light;
  --canvas: #e9ebed;
  --glass: rgba(255, 255, 255, 0.82);
  --solid: #ffffff;
  --ink: #0d0f12;
  --quiet: #5c646d;
  --hairline: rgba(13, 15, 18, 0.12);
  --signal: #875306;
  --signal-soft: rgba(135, 83, 6, 0.11);
  --accent: #875306;
  --green: #146638;
  --frame: #0b0c0e;
  --frame-ink: #f2f4f6;
  --danger: #9d2220;
  --product-shadow: 0 28px 70px rgba(13, 15, 18, 0.14);
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --canvas: #0b0c0e;
  --glass: rgba(20, 22, 26, 0.82);
  --solid: #14161a;
  --ink: #f2f4f6;
  --quiet: #8b939c;
  --hairline: rgba(255, 255, 255, 0.10);
  --signal: #ffb020;
  --signal-soft: rgba(255, 176, 32, 0.14);
  --accent: #ffb020;
  --green: #3fd07e;
  --frame: #050607;
  --frame-ink: #f2f4f6;
  --danger: #ff7b72;
  --product-shadow: 0 34px 90px rgba(0, 0, 0, 0.55);
}

/* Lines should break where the sentence allows, not wherever the box happens
   to run out. `balance` evens out short blocks so a heading or a lead does not
   leave a long line above a stub, and `pretty` keeps a single word off the
   last line of running text. Older engines ignore both and wrap as before. */
h1,
h2,
h3,
.lead,
.readout,
.kicker,
.faq-item h3,
.support-row b,
.approval-card h2 {
  text-wrap: balance;
}

p,
dd,
td,
li,
figcaption,
.note,
.muted,
.mode-sub,
.faq-item p {
  text-wrap: pretty;
}

/* The parts nobody draws still carry the design. */
::selection { background: var(--signal); color: var(--frame); }
:root { accent-color: var(--signal); caret-color: var(--signal); }
:focus-visible { outline: 2px solid var(--signal); outline-offset: 3px; border-radius: 4px; }
* { scrollbar-width: thin; scrollbar-color: var(--quiet) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb { background: var(--quiet); border-radius: 99px; border: 3px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-track { background: transparent; }

.home-page,
.receiver-page {
  display: block;
  min-height: 100%;
  overflow: auto;
  background: var(--canvas);
  color: var(--ink);
  font-family: "Avenir Next", Avenir, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  transition: background 300ms ease, color 300ms ease;
}

.home-shell,
.receiver-shell {
  min-height: 100vh;
  padding: 26px clamp(28px, 5vw, 76px) 32px;
}

.receiver-shell {
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: 24px;
  overflow: hidden;
}

.topbar,
.receiver-footer,
.home-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: relative;
  z-index: 4;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  color: var(--ink);
  text-decoration: none;
  font-size: 21px;
  font-weight: 600;
  letter-spacing: -0.04em;
}

.brand-mark {
  width: 25px;
  height: 25px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.3;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.topbar-actions { display: flex; align-items: center; gap: 10px; }

.theme-toggle,
.live-state {
  width: 42px;
  height: 42px;
  min-height: 42px;
  padding: 0;
  border: 1px solid var(--hairline);
  border-radius: 50%;
  background: var(--glass);
  color: var(--ink);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
}

.theme-toggle svg {
  width: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

:root[data-theme="dark"] .moon-icon,
:root:not([data-theme="dark"]) .sun-icon { display: none; }

.live-state {
  width: auto;
  /* A stadium, not an ellipse: the 50% radius is shared with the round
     topbar buttons and bows the top and bottom edges once this gets wide. */
  border-radius: 999px;
  padding: 0 17px 0 14px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  max-width: min(46vw, 460px);
  overflow: hidden;
}

/* The dot carries the state; the label stays at full ink so it is readable at
   a glance from the driver's seat. Colouring the text instead left a green dot
   beside an amber sentence, which read as two different states at once. */
.live-state {
  --dot: var(--quiet);
  color: var(--ink);
}

.live-state[data-tone="ok"] { --dot: var(--green); }
.live-state[data-tone="warn"] { --dot: #e0a034; }
.live-state[data-tone="error"] { --dot: #e0574f; }

.live-state i {
  width: 8px;
  height: 8px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--dot);
  /* A tight ring reads as a status light; a wide soft one reads as a smudge,
     especially when the dot is the neutral grey. */
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--dot) 20%, transparent);
  transition: background 200ms ease, box-shadow 200ms ease;
}

/* The label can outrun the pill during long messages. */
.live-state .status {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Inside the pill the tone lives on the container, so the span must not
   repaint itself with the standalone status colours. */
.live-state .status,
.live-state .status--ok,
.live-state .status--warn,
.live-state .status--error {
  color: inherit;
}

.receiver-hero { min-height: 430px; position: relative; display: grid; place-items: center; }

.receiver-glow {
  position: absolute;
  width: min(75vw, 890px);
  aspect-ratio: 1.8;
  background: radial-gradient(ellipse at center, var(--signal-soft), transparent 66%);
  filter: blur(26px);
  opacity: .76;
}

.receiver-card {
  width: min(76vw, 920px);
  min-height: 430px;
  aspect-ratio: 16 / 8.7;
  position: relative;
  overflow: hidden;
  /* Flex rather than a fixed grid so the card closes up cleanly on the
     browsers where the QR never loads and the panel stays hidden. */
  display: flex;
  align-items: stretch;
  border: 1px solid var(--hairline);
  border-radius: 34px;
  /* Neutral panel. Tinting the surface with the signal colour drifts straight
     into the warm-cream look every generated interface lands on, and it spends
     a colour whose only job is to mean something. */
  background: linear-gradient(118deg, var(--solid), color-mix(in srgb, var(--solid) 94%, var(--ink)));
  box-shadow: var(--product-shadow);
}

.receiver-card::after { content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: inherit; box-shadow: inset 0 1px rgba(255,255,255,.32); }

.pair-copy { min-height: inherit; flex: 1 1 auto; min-width: 0; padding: clamp(36px, 5vw, 68px); display: flex; flex-direction: column; align-items: flex-start; justify-content: center; }

.pair-qr {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: clamp(28px, 3.5vw, 56px);
  padding-left: 0;
  text-align: center;
}

.pair-qr img {
  display: block;
  width: clamp(168px, 19vw, 248px);
  height: auto;
  padding: 12px;
  border-radius: 18px;
  /* The quiet zone has to stay white for a scanner to lock on, whatever
     theme the car display is using. */
  background: #ffffff;
  box-shadow: var(--product-shadow);
}

.pair-qr p {
  margin: 0;
  max-width: 210px;
  font-size: 13px;
  line-height: 1.4;
}

.kicker {
  margin: 0 0 19px;
  color: var(--quiet);
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .15em;
}

.receiver-page h1,
.home-page h1 {
  margin: 0;
  color: var(--ink);
  font-size: clamp(46px, 5.3vw, 76px);
  font-weight: 500;
  letter-spacing: -0.065em;
  line-height: .95;
}

.receiver-page .lead,
.home-page .lead { max-width: 520px; margin: 22px 0 25px; color: var(--quiet); font-size: clamp(14px, 1.35vw, 17px); line-height: 1.6; }
.receiver-page .lead strong { color: var(--ink); font-weight: 600; }

.receiver-page .code {
  margin: 0;
  color: var(--ink);
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: clamp(39px, 4.5vw, 62px);
  font-weight: 500;
  letter-spacing: .09em;
  line-height: 1;
  text-shadow: none;
}

.expiry { margin-top: 18px; display: flex; align-items: center; gap: 9px; color: var(--quiet); font-size: 10px; }
.expiry > .expiry-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--signal); box-shadow: 0 0 0 4px var(--signal-soft); }
.receiver-page .note { margin-top: 20px; max-width: 520px; border-left-color: var(--signal); background: var(--signal-soft); color: var(--quiet); }

.receiver-footer { justify-content: flex-start; gap: clamp(25px, 5vw, 70px); }
.fact { display: grid; gap: 4px; }
.fact span { color: var(--quiet); font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; font-size: 8px; text-transform: uppercase; letter-spacing: .14em; }
.fact strong { color: var(--ink); font-size: 10px; font-weight: 600; }

/* Without a ceiling the page keeps stretching on a wide monitor, and a two
   column row ends up with its label and its answer half a metre apart. */
.home-shell { display: grid; grid-template-rows: auto 1fr auto auto; gap: 30px; max-width: 1280px; margin-inline: auto; width: 100%; }

.home-page h1 .dim { color: var(--quiet); }
.home-hero {
  padding: clamp(40px, 7vh, 88px) 0 clamp(32px, 5vh, 64px);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(28px, 5vw, 72px);
  align-items: center;
}

.home-hero-copy { min-width: 0; }

/* ---------- The letterbox ----------
   A phone screen is tall; a car display is wide. Mirroring one into the other
   leaves a narrow lit field inside a dark frame, and that shape is what a
   Relay session actually looks like. It is the mark, not a flaw to hide. */

.letterbox {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: 14px;
  background: var(--frame);
  border: 1px solid var(--hairline);
  box-shadow: var(--product-shadow);
  display: grid;
  place-items: center;
  overflow: hidden;
}

/* Registration marks, not decoration: they measure the frame they sit in. */
.letterbox::before,
.letterbox::after {
  content: "";
  position: absolute;
  width: 9px;
  height: 9px;
  border: 1px solid rgba(242, 244, 246, 0.28);
  border-radius: 1px;
}
.letterbox::before { top: 12px; left: 12px; border-right: 0; border-bottom: 0; }
.letterbox::after { bottom: 12px; right: 12px; border-left: 0; border-top: 0; }

.letterbox-field {
  /* Sized in percentages of the frame rather than by aspect-ratio, so the
     shape can be animated on browsers that will not tween aspect-ratio. */
  width: 20.2%;
  height: 78%;
  border-radius: 8px;
  background: linear-gradient(176deg, #1a1d22, #101216);
  border: 1px solid rgba(242, 244, 246, 0.14);
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 10px;
  padding: 18px 12px;
  transform-origin: center;
}

.letterbox-label {
  font: 500 9px/1 ui-monospace, "SFMono-Regular", Menlo, monospace;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(242, 244, 246, 0.5);
}

.letterbox-code {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: clamp(20px, 2.6vw, 34px);
  letter-spacing: 0.06em;
  color: var(--frame-ink);
  line-height: 1;
  /* The code is one thing and never two lines. In the narrow phase there is no
     room for it, so it fades with the frame rather than breaking in half. */
  white-space: nowrap;
}

.letterbox-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--green) 22%, transparent);
}

/* The one authored moment: the tall field opens out and fills the wide frame,
   which is what the product delivers. The picture ends up upright and full,
   never sideways. Rotating the content here would advertise the defect the
   receiver exists to correct. Reduced motion holds the composed state. */
@media (prefers-reduced-motion: no-preference) {
  .letterbox-field {
    animation: letterbox-open 9s cubic-bezier(0.16, 1, 0.3, 1) 1.4s infinite;
  }

  .letterbox-field > * {
    animation: letterbox-contents 9s cubic-bezier(0.16, 1, 0.3, 1) 1.4s infinite;
  }
}

@keyframes letterbox-open {
  0%, 20% { width: 20.2%; height: 78%; }
  36%, 74% { width: 88%; height: 72%; }
  90%, 100% { width: 20.2%; height: 78%; }
}

/* Held back until the frame is wide enough to hold them. */
@keyframes letterbox-contents {
  0%, 24% { opacity: 0; }
  40%, 72% { opacity: 1; }
  84%, 100% { opacity: 0; }
}

/* ---------- Measured legend ----------
   Real figures from a recorded session, set as notation rather than as a
   statistics band. */

/* This used to hold figures, where the monospace was doing real work. It holds
   a sentence now, and monospace for prose is only a costume. */
.readout {
  display: block;
  max-width: 52ch;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--hairline);
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--quiet);
}

.readout b { color: var(--ink); font-weight: 600; }

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

/* ---------- Questions ----------
   Answers to what people actually type into a search box, set as running text
   rather than an accordion: hiding an answer behind a click serves nobody who
   came here to find out whether this works on their phone. */

.faq { max-width: 680px; padding-top: 30px; }
.faq h2 {
  margin: 0 0 4px;
  color: var(--quiet);
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: 10px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .15em;
}
.faq-item { padding: 16px 0; border-bottom: 1px solid var(--hairline); }
.faq-item:last-child { border-bottom: 0; }
.faq-item h3 { margin: 0 0 5px; color: var(--ink); font-size: 14px; font-weight: 600; letter-spacing: -0.01em; }
.faq-item p { margin: 0; color: var(--quiet); font-size: 13.5px; line-height: 1.6; }

.support { border-top: 1px solid var(--hairline); max-width: 680px; }

.support h2 {
  margin: 20px 0 4px;
  color: var(--quiet);
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: 10px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .15em;
}

.support-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 190px;
  gap: 20px;
  align-items: baseline;
  padding: 13px 0;
  border-bottom: 1px solid var(--hairline);
  font-size: 13px;
}

.support-row b { color: var(--ink); font-weight: 600; letter-spacing: -0.01em; }

/* The dot carries the verdict as well as the colour, so the answer survives a
   monochrome screen and a reader who cannot separate green from amber. */
.support-row span {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  color: var(--quiet);
}
.support-row span::before {
  content: "";
  flex: none;
  align-self: center;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  border: 1.5px solid currentColor;
}
.support-row[data-state="full"] span { color: var(--green); }
.support-row[data-state="full"] span::before { background: currentColor; }
.support-row[data-state="partial"] span { color: var(--signal); }


.home-page h1 {
  position: relative;
  z-index: 1;
  max-width: 12ch;
  /* The craft floor caps display type at 6rem; the hero also shares its row
     with the figure, so the ceiling is lower again. */
  font-size: clamp(40px, 5.2vw, 76px);
  text-wrap: balance;
}

.home-actions { display: flex; gap: 10px; margin-top: 30px; }
.home-page .button { border-color: var(--hairline); background: var(--glass); color: var(--ink); border-radius: 999px; font-size: 14px; }
.home-page .button.primary { background: var(--ink); border-color: var(--ink); color: var(--canvas); }
.product-strip { display: grid; grid-template-columns: repeat(3, 1fr); border-top: 1px solid var(--hairline); border-bottom: 1px solid var(--hairline); }
.product-strip > div { padding: 24px 24px 24px 0; display: grid; gap: 7px; }
.product-strip > div + div { border-left: 1px solid var(--hairline); padding-left: 24px; }
.product-strip span { color: var(--signal); font: 10px ui-monospace, "SFMono-Regular", Menlo, monospace; }
.product-strip strong { font-size: 13px; font-weight: 600; }
.product-strip p { margin: 0; color: var(--quiet); font-size: 11px; }
.home-footer p { margin: 0; color: var(--quiet); font-size: 11px; }
.home-footer a { color: var(--ink); font-size: 11px; text-decoration: none; font-weight: 600; }

.receiver-page .stage { z-index: 20; }
.receiver-page .controls button { border-color: rgba(255,255,255,.18); background: rgba(15,17,19,.78); color: #fff; border-radius: 999px; backdrop-filter: blur(18px); }

.sender-page {
  display: block;
  min-height: 100%;
  overflow: auto;
  background: var(--canvas);
  color: var(--ink);
  font-family: "Avenir Next", Avenir, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
/* ---------- Sender ----------
   This one is a tool, not a pitch. Somebody is standing next to a car holding
   a phone, so the page is a short column of controls on a fixed type scale:
   no display lettering, no fluid headings that grow on a tablet, one action
   obviously first. */

.sender-shell { width: min(100%, 620px); margin: 0 auto; padding: 22px 24px 80px; }

.sender-heading { padding: 34px 0 20px; }
.sender-heading h1 {
  margin: 0 0 12px;
  color: var(--ink);
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.15;
}

/* The dot inherits the tone class's colour, so the state reads without
   depending on the wording or on telling green from amber. */
.sender-page .status {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 20px;
  margin: 0;
  color: var(--quiet);
  font-size: 13px;
}
.sender-page .status::before {
  content: "";
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
}
.sender-page .status--ok { color: var(--green); }
.sender-page .status--warn { color: var(--signal); }
.sender-page .status--error { color: var(--danger); }

/* One elevation, declared once: a hairline on a solid surface. The panels used
   to be translucent with a 20px backdrop blur, which the car browser pays for
   on every scroll frame and which no state here depends on. */
.sender-page .panel {
  max-width: none;
  margin: 0 0 12px;
  padding: 20px;
  border: 1px solid var(--hairline);
  border-radius: 16px;
  background: var(--solid);
  color: var(--ink);
  box-shadow: none;
  backdrop-filter: none;
}
.sender-page .panel + .panel { margin-top: 0; }
.sender-page h2 { margin: 0 0 6px; color: var(--ink); font-size: 15px; font-weight: 600; letter-spacing: -0.01em; }
.sender-page .muted { margin: 0; color: var(--quiet); font-size: 13px; line-height: 1.5; }
.sender-page .field { margin-bottom: 14px; }
.sender-page .field label { margin-bottom: 7px; color: var(--quiet); font-size: 13px; }
.sender-page .mode-sub { color: var(--quiet); }

/* The checkbox is excluded deliberately: a 46px control floor is right for a
   thumb on a text field and wrong for a tick box, which would stretch into a
   tall rectangle beside its label. */
.sender-page input:not([type="checkbox"]),
.sender-page select,
.sender-page button:not(.theme-toggle):not(.language-toggle) {
  min-height: 46px;
  border: 1px solid var(--hairline);
  border-radius: 11px;
  background: var(--solid);
  color: var(--ink);
  font-size: 15px;
}
.sender-page input:not([type="checkbox"]),
.sender-page select { background: var(--canvas); }
.sender-page select { padding: 0 12px; }
.sender-page input::placeholder { color: var(--quiet); opacity: 1; }

.sender-page button:not(.theme-toggle):not(.language-toggle) { font-weight: 600; transition: background 160ms ease, border-color 160ms ease, color 160ms ease; }
.sender-page button:hover:not(:disabled) { border-color: color-mix(in srgb, var(--ink) 34%, transparent); }
.sender-page button:active:not(:disabled) { transform: translateY(1px); }
.sender-page button:disabled { opacity: 1; border-color: var(--hairline); background: var(--canvas); color: var(--quiet); cursor: not-allowed; }

.sender-page button.primary { width: 100%; border-color: var(--ink); background: var(--ink); color: var(--canvas); }
.sender-page button.primary:hover:not(:disabled) { background: color-mix(in srgb, var(--ink) 86%, var(--canvas)); }
/* Equal specificity to the .primary rule above, so it has to come after it
   or the button stays black while it is refusing clicks. */
.sender-page button.primary:disabled { border-color: var(--hairline); background: var(--canvas); color: var(--quiet); }
.sender-page button.ghost { border-color: transparent; background: transparent; color: var(--quiet); font-weight: 500; }
.sender-page button.ghost:hover { color: var(--ink); border-color: var(--hairline); }
.sender-page button.danger { border-color: color-mix(in srgb, var(--danger) 45%, transparent); color: var(--danger); }
.sender-page button.danger:hover { border-color: var(--danger); }

.sender-page .code-input {
  width: 100%;
  padding: 12px 0;
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: 30px;
  font-variant-numeric: tabular-nums;
  letter-spacing: .22em;
  text-indent: .22em;
  text-align: center;
}

.sender-page .pair-help { margin-top: 12px; }

/* Three ways in, given equal weight and read at a glance. A mode the browser
   cannot do stays visible and states why in its own sub-label, rather than
   disappearing and leaving a hole in the row. */
.sender-page .mode-grid { grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 18px; }
.sender-page .mode-grid button {
  min-height: 0;
  display: grid;
  justify-items: start;
  gap: 5px;
  padding: 14px 13px;
  text-align: left;
  font-size: 14px;
}
.sender-page .mode-grid .mode-sub { font-size: 11.5px; font-weight: 400; line-height: 1.35; }
.sender-page .mode-grid button:disabled .mode-icon { opacity: .45; }

.mode-icon {
  width: 21px;
  height: 21px;
  margin-bottom: 3px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.sender-page .checkrow { margin-top: 4px; font-size: 14px; }
.sender-page .checkrow input { width: 17px; height: 17px; margin-top: 1px; }
.sender-page .note { margin-bottom: 12px; }

/* The receiver's diagnostics sit on a black stage, so that readout pins its
   own dark colours. Here the same markup is inside a themed panel and has to
   follow the theme, with the label above its figure instead of pushed to the
   far side of the row. */
.sender-page .stats-inline {
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
  margin-top: 16px;
  padding: 14px 16px;
  border: 1px solid var(--hairline);
  border-radius: 12px;
  background: var(--canvas);
  color: var(--ink);
}
.sender-page .stats-inline > div { display: block; }
.sender-page .stats-inline dt { margin-bottom: 3px; color: var(--quiet); font-size: 11px; }
.sender-page .stats-inline dd { color: var(--ink); font-size: 13px; }

.sender-page .panel-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--hairline);
}
/* Stop takes the room when it is there; on its own, Forget stays a small quiet
   control rather than stretching into something that looks like the main act. */
.sender-page .panel-actions button.danger { flex: 1 1 auto; }
.sender-page .panel-actions button.ghost { flex: 0 1 auto; padding: 0 14px; }

.sender-page .row > button { flex: none; padding: 0 20px; }

/* ---------- Compatibility check ----------
   A diagnostic report. It is read once, under bad light, by somebody who wants
   a verdict and not a design: dense rows, one accent, nothing moving. */

.check-page {
  display: block;
  min-height: 100%;
  background: var(--canvas);
  color: var(--ink);
  font-family: "Avenir Next", Avenir, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

.check-shell { width: min(100%, 780px); margin: 0 auto; padding: 22px 24px 64px; }

.check-heading { padding: 34px 0 20px; }
.check-heading h1 { margin: 0 0 10px; color: var(--ink); font-size: 28px; font-weight: 600; letter-spacing: -0.025em; line-height: 1.15; }
.check-page .lead { max-width: 62ch; margin: 0; color: var(--quiet); font-size: 15px; line-height: 1.55; }

.check-page .panel {
  max-width: none;
  margin: 0 0 14px;
  padding: 6px 20px 20px;
  border: 1px solid var(--hairline);
  border-radius: 16px;
  background: var(--solid);
  color: var(--ink);
}

.check-page table { font-size: 14px; }
.check-page thead th {
  padding: 14px 0 10px;
  border-bottom: 1px solid var(--hairline);
  color: var(--quiet);
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: 10px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .13em;
}
.check-page tbody th,
.check-page td { padding: 12px 16px 12px 0; border-bottom: 1px solid var(--hairline); }
.check-page tbody th { color: var(--ink); font-weight: 600; }
.check-page td:last-child { padding-right: 0; color: var(--quiet); line-height: 1.5; }
.check-page tbody tr:last-child th,
.check-page tbody tr:last-child td { border-bottom: 0; }

.check-page .panel-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
.check-page .panel-actions button {
  min-height: 44px;
  padding: 0 18px;
  border: 1px solid var(--hairline);
  border-radius: 11px;
  background: var(--canvas);
  color: var(--ink);
  font-size: 14px;
  font-weight: 600;
}
.check-page .panel-actions button:hover:not(:disabled) { border-color: color-mix(in srgb, var(--ink) 34%, transparent); }
.check-page .panel-actions button:disabled { opacity: 1; color: var(--quiet); cursor: progress; }

.check-page .note { margin-bottom: 14px; font-size: 13px; }
.check-page .note strong { color: var(--ink); font-weight: 600; }

.check-footer { padding-top: 8px; font-size: 13px; }
.check-footer a { color: var(--quiet); text-decoration: none; }
.check-footer a:hover { color: var(--ink); }

@media (max-width: 620px) {
  .check-shell { padding: 20px 20px 56px; }
  .check-heading { padding: 26px 0 18px; }
  .check-heading h1 { font-size: 24px; }
  .check-page .panel { padding: 4px 16px 16px; }

  /* Three columns cannot hold a name, a verdict and a sentence of detail on a
     phone. Each check becomes a block: name and verdict on one line, the
     detail under them. */
  .check-page thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .check-page tbody tr { display: grid; grid-template-columns: 1fr auto; gap: 2px 12px; padding: 12px 0; border-bottom: 1px solid var(--hairline); }
  .check-page tbody th,
  .check-page td { padding: 0; border-bottom: 0; }
  .check-page td:last-child { grid-column: 1 / -1; margin-top: 3px; font-size: 13px; }
  .check-page tbody tr:last-child { border-bottom: 0; }
  .check-page .panel-actions button { flex: 1 1 auto; }
}

.language-toggle {
  min-width: 42px;
  min-height: 42px;
  padding: 0 10px;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: var(--glass);
  color: var(--ink);
  font: 600 10px ui-monospace, "SFMono-Regular", Menlo, monospace;
  letter-spacing: .08em;
}

@media (max-width: 720px) {
  .home-shell, .receiver-shell { padding: 20px; }
  .receiver-shell { gap: 18px; }
  .live-state { display: none; }
  .receiver-hero { min-height: 510px; }
  .home-hero { grid-template-columns: 1fr; gap: 30px; padding-top: 24px; }
  .home-page h1 { max-width: none; }
  .readout { max-width: none; }
  .support-row { grid-template-columns: 1fr; gap: 2px; }
  .support-row span { font-size: 12px; }
  .home-footer { display: grid; gap: 10px; justify-items: start; }
  .receiver-card { width: 100%; min-height: 500px; aspect-ratio: auto; border-radius: 26px; flex-direction: column; }
  .pair-copy { padding: 35px 27px; }
  .pair-qr { padding: 0 27px 35px; align-items: flex-start; text-align: left; }
  .receiver-page h1 { font-size: 48px; }
  .fact:nth-child(2), .fact:nth-child(3) { display: none; }
  .home-hero { padding: 8vh 0 3vh; }
  .home-page h1 { font-size: 58px; }
  .home-hero::after { width: 60vw; opacity: .7; }
  .product-strip { grid-template-columns: 1fr; }
  .product-strip > div + div { border-left: 0; border-top: 1px solid var(--hairline); padding-left: 0; }
  .home-footer { align-items: flex-start; gap: 20px; }
  .sender-shell { padding: 20px 20px 60px; }
  .sender-heading { padding: 26px 0 18px; }
  .sender-heading h1 { font-size: 24px; }

  /* Three columns of icon, label and reason do not survive a phone: every
     sub-label breaks into three lines. One per row instead, icon beside the
     text, which is also the easier thumb target. */
  .sender-page .mode-grid { grid-template-columns: 1fr; gap: 8px; }
  .sender-page .mode-grid button {
    grid-template-columns: auto 1fr;
    grid-template-rows: auto auto;
    align-items: center;
    column-gap: 12px;
    padding: 12px 14px;
  }
  .sender-page .mode-grid button > span:not(.mode-sub) { grid-column: 2; align-self: end; }
  .sender-page .mode-grid .mode-sub { grid-column: 2; align-self: start; }
  .mode-icon { grid-row: 1 / span 2; margin-bottom: 0; }

  .sender-page .stats-inline { grid-template-columns: 1fr 1fr; }
}
