:root {
  --font-ui: "Bahnschrift", sans-serif;
  --font-mono: "Cascadia Mono", monospace;
  --camera-black: #070908;
  --nitrile: #131515;
  --optic-surface-1: #121414;
  --optic-surface-2: #1a1c1c;
  --optic-surface-3: #242727;
  --optic-surface-4: #2f3333;
  --signal-amber: #d89122;
  --signal-amber-bright: #f4b840;
  --signal-amber-dim: #886421;
  --signal-wash: rgba(227, 161, 40, 0.14);
  --gel: #a3b4bf;
  --gel-deep: #536270;
  --air-gap: rgba(190, 205, 214, 0.15);
  --readout: #eef0ee;
  --readout-secondary: #c3c8c4;
  --readout-tertiary: #9da39f;
  --readout-dim: #939994;
  --optic-ring: rgba(255, 255, 255, 0.12);
  --optic-ring-soft: rgba(255, 255, 255, 0.066);
  --optic-grid: rgba(255, 255, 255, 0.052);
  --focus: #ffc04a;
  --pressure: 0;
  --signal-level: 0%;
  --coupling-width: 0%;
  --coupling-strength: 0;
  --reflection-opacity: 0.76;
  --camera-darkness: 0.18;
  --camera-response-opacity: 0;
  --annulus-strength: 0.12;
  --camera-contact-width: 42px;
  --camera-contact-height: 24px;
  --indenter-y: 34px;
  /*
   * Three-step type scale for all interface and diagram text. Seven distinct
   * sizes (7-13px) previously coexisted inside the mechanism panel alone;
   * every small-text rule now maps to fine (annotations), label (readouts and
   * controls) or title (panel headings).
   */
  --text-fine: 12px;
  --text-label: 14px;
  --text-title: 16px;
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  color: var(--readout);
  background: var(--camera-black);
  font-family: var(--font-ui);
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  scrollbar-color: var(--optic-surface-4) var(--camera-black);
}

body {
  margin: 0;
  min-width: 320px;
  background:
    radial-gradient(circle at 74% 3%, rgba(227, 161, 40, 0.03), transparent 24rem),
    var(--camera-black);
}

a {
  color: inherit;
}

button,
input {
  font: inherit;
}

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

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

[hidden] {
  display: none !important;
}

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 4px;
}

.skip-link {
  position: fixed;
  z-index: 100;
  top: 12px;
  left: -9999px;
  /* Measured 41px tall; a real target once focus reveals it. */
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  padding: 12px 16px;
  color: var(--camera-black);
  background: var(--signal-amber-bright);
  font-size: var(--text-title);
  font-weight: 700;
}

.skip-link:focus-visible {
  left: 12px;
}

.instrument-header,
.instrument-footer,
main {
  width: min(1560px, calc(100% - 64px));
  margin-inline: auto;
}

.instrument-header {
  position: relative;
  z-index: 20;
  min-height: 88px;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  box-shadow: inset 0 -1px var(--optic-ring);
}

.instrument-brand {
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-self: start;
  gap: 10px;
  text-decoration: none;
}

.instrument-brand strong {
  font-size: var(--text-title);
  letter-spacing: 0.08em;
}

.instrument-brand > span:last-child {
  color: var(--readout-dim);
  font-family: var(--font-mono);
  font-size: var(--text-fine);
  letter-spacing: 0.12em;
}

.status-lamp {
  width: 7px;
  height: 7px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--signal-amber);
  box-shadow: 0 0 12px rgba(227, 161, 40, 0.56);
}

.instrument-header nav {
  display: flex;
  gap: 28px;
}

.instrument-header nav a {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  color: var(--readout-secondary);
  font-size: var(--text-label);
  letter-spacing: 0.08em;
  text-decoration: none;
  text-transform: uppercase;
  transition: color 140ms var(--ease-out);
}

.instrument-header nav a:hover {
  color: var(--signal-amber-bright);
}

.signal-hero {
  /* Capped: a phone in desktop mode lays out at about 980px on a 2100px-tall
     viewport, and 100svh floated the copy 880px below the header (2026-09-27). */
  min-height: min(calc(100svh - 72px), 860px);
  display: grid;
  grid-template-columns: minmax(390px, 0.78fr) minmax(560px, 1.22fr);
  grid-template-rows: 1fr auto;
  gap: 40px clamp(48px, 6vw, 112px);
  padding-block: clamp(54px, 7vh, 96px) 24px;
}

.hero-copy {
  align-self: center;
  padding-block: 20px;
}

.signal-label {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 28px;
  color: var(--signal-amber);
  font-family: var(--font-mono);
  font-size: var(--text-fine);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.signal-label::before {
  width: 24px;
  height: 1px;
  flex: 0 0 auto;
  background: var(--signal-amber);
  content: "";
}

.signal-label span {
  color: var(--signal-amber);
}

.hero-copy h1,
.section-header h2,
.research-heading h2,
.module-header h3 {
  font-family: var(--font-ui);
  font-stretch: condensed;
  text-wrap: balance;
}

/* The hero is the one uppercase display setting on the page; every other
   heading is sentence case on one of two clamps (h2, h3). */
.hero-copy h1 {
  text-transform: uppercase;
}

.hero-copy h1 {
  max-width: 680px;
  margin: 0;
  font-size: clamp(58px, 6.5vw, 108px);
  font-weight: 650;
  letter-spacing: -0.065em;
  line-height: 0.82;
}

.hero-summary {
  max-width: 590px;
  margin: 36px 0 0;
  color: var(--readout-secondary);
  font-size: 16px;
  line-height: 1.65;
  text-wrap: pretty;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 34px;
}

.button {
  min-height: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
  padding: 0 18px;
  border: 1px solid transparent;
  font-family: var(--font-mono);
  font-size: var(--text-label);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-decoration: none;
  text-transform: uppercase;
  transition:
    color 150ms var(--ease-out),
    background-color 150ms var(--ease-out),
    border-color 150ms var(--ease-out),
    transform 120ms var(--ease-out);
}

.button:active {
  transform: scale(0.98);
}

.button--primary {
  color: var(--camera-black);
  background: var(--signal-amber-bright);
}

.button--primary:hover {
  background: #ffd077;
}

.button--quiet {
  color: var(--readout-secondary);
  border-color: var(--optic-ring);
  background: var(--optic-surface-1);
}

.button--quiet:hover {
  color: var(--readout);
  border-color: rgba(255, 255, 255, 0.16);
}

/* An action that exists but is not live yet: a span, not a link (verify.py
 * forbids placeholder hrefs) and not a disabled button (disabled text would
 * fall under AA). Same size as its live neighbours. */
.button--pending {
  color: var(--readout-tertiary);
  border-color: var(--optic-ring);
  background: transparent;
  cursor: default;
}

.button--pending small {
  color: var(--readout-dim);
  font-size: var(--text-fine);
  font-weight: 500;
  letter-spacing: 0.08em;
}

.hero-figure {
  align-self: center;
  margin: 0;
}

.hero-figure__frame {
  position: relative;
  padding: 10px;
  background: var(--optic-surface-1);
  box-shadow:
    inset 0 0 0 1px var(--optic-ring),
    0 22px 70px rgba(0, 0, 0, 0.18);
}

.hero-figure__frame::before {
  position: absolute;
  inset: 10px;
  z-index: 1;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.16);
  pointer-events: none;
  content: "";
}

.hero-figure img {
  width: 100%;
  height: auto;
  max-height: min(72svh, 820px);
  object-fit: contain;
  background: #e9e9e5;
}

.figure-corner {
  position: absolute;
  z-index: 2;
  width: 32px;
  height: 32px;
  pointer-events: none;
}

.figure-corner--top {
  top: 3px;
  left: 3px;
  border-top: 1px solid var(--signal-amber);
  border-left: 1px solid var(--signal-amber);
}

.figure-corner--bottom {
  right: 3px;
  bottom: 3px;
  border-right: 1px solid var(--signal-amber);
  border-bottom: 1px solid var(--signal-amber);
}

.hero-figure figcaption {
  display: grid;
  grid-template-columns: auto minmax(220px, 1fr);
  gap: 28px;
  align-items: start;
  padding: 14px 2px 0;
}

.hero-figure figcaption span {
  color: var(--readout-tertiary);
  font-family: var(--font-mono);
  font-size: var(--text-fine);
  letter-spacing: 0.12em;
}

.hero-figure figcaption p {
  max-width: 520px;
  justify-self: end;
  margin: 0;
  color: var(--readout-tertiary);
  font-size: var(--text-label);
  line-height: 1.5;
  text-align: right;
}

/* Sections alternate two grounds so a phone reads bands, not one black
   field: hero, forms and record on camera-black; mechanism and results on
   nitrile. The shadow + clip pair bleeds the band to the viewport edges
   without changing the centred layout. */
.mechanism,
.results {
  background: var(--nitrile);
  box-shadow: 0 0 0 100vmax var(--nitrile);
  clip-path: inset(0 -100vmax);
}

/* The eyebrows that used to space the section heads were removed on
   2026-09-27; the bands carry their own head room instead. */
.mechanism,
.forms,
.results,
.live {
  padding-top: clamp(124px, 15vw, 240px);
}

.section-header {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(280px, 0.7fr);
  gap: 48px;
  align-items: end;
  margin-bottom: 42px;
}

.section-header .signal-label {
  margin-bottom: 22px;
}

.section-header h2 {
  max-width: 940px;
  margin: 0;
  font-size: clamp(34px, 4vw, 52px);
  font-weight: 640;
  letter-spacing: -0.048em;
  line-height: 0.88;
}

.section-header > p {
  max-width: 480px;
  justify-self: end;
  margin: 0 0 6px;
  color: var(--readout-secondary);
  font-size: var(--text-title);
  line-height: 1.58;
  text-wrap: pretty;
}

.mechanism-shell {
  overflow: hidden;
  background: var(--optic-surface-1);
  box-shadow: inset 0 0 0 1px var(--optic-ring);
}

.mechanism-toolbar {
  min-height: 50px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px 24px;
  padding: 6px 22px;
  background: var(--nitrile);
  box-shadow: inset 0 -1px var(--optic-ring);
}

.toolbar-identity {
  display: flex;
  align-items: center;
  gap: 12px;
}

.toolbar-identity div,
.toolbar-status {
  display: grid;
  gap: 4px;
}

.toolbar-identity strong,
.toolbar-status output {
  color: var(--readout);
  font-size: var(--text-label);
  font-weight: 650;
  letter-spacing: 0.08em;
}

.toolbar-identity div > span,
.toolbar-status > span {
  color: var(--readout-dim);
  font-family: var(--font-mono);
  font-size: var(--text-fine);
  letter-spacing: 0.12em;
}

.toolbar-status {
  text-align: right;
}

.toolbar-status output {
  color: var(--signal-amber-bright);
}

.mechanism-grid {
  display: grid;
  /*
   * 6:4. The microscope and sensor views carry as much of the explanation
   * as the device schematic, and at 1.72/0.88 (66/34) they were cramped.
   */
  grid-template-columns: minmax(0, 6fr) minmax(380px, 4fr);
  grid-template-rows: minmax(300px, auto) minmax(250px, auto);
}

.instrument-view {
  min-width: 0;
  background: var(--optic-surface-2);
  box-shadow:
    inset -1px -1px var(--optic-ring),
    inset 1px 1px var(--optic-ring-soft);
}

.macro-view {
  grid-row: 1 / span 2;
  /*
   * The device view spans both rows, so the microscope + camera column sets
   * its height. Its header and stage did not absorb that extra height, which
   * left ~130px of empty panel below the legend. Letting the stage take the
   * free space keeps the schematic optically centred in whatever height the
   * neighbouring column dictates.
   */
  display: grid;
  grid-template-rows: auto 1fr;
}

.view-header {
  min-height: 48px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 0 18px;
  background: rgba(8, 10, 9, 0.22);
  box-shadow: inset 0 -1px var(--optic-ring);
}

.view-header > div:first-child {
  display: grid;
  gap: 4px;
}

.view-header span,
.view-badge {
  color: var(--readout-dim);
  font-family: var(--font-mono);
  font-size: var(--text-fine);
  letter-spacing: 0.12em;
}

.view-header h3 {
  margin: 0;
  color: var(--readout);
  font-size: var(--text-title);
  font-weight: 580;
  letter-spacing: -0.01em;
}

.view-badge {
  padding: 7px 8px;
  color: var(--readout-tertiary);
  box-shadow: inset 0 0 0 1px var(--optic-ring);
}

.macro-stage {
  position: relative;
  min-height: 548px;
  display: grid;
  align-content: center;
  padding: 10px 18px 18px;
  overflow: hidden;
  background:
    radial-gradient(circle at 50% 45%, rgba(227, 161, 40, 0.03), transparent 34%),
    var(--optic-surface-1);
}

#macro-svg {
  width: 100%;
  height: auto;
  overflow: visible;
}

.macro-grid-lines path {
  fill: none;
  stroke: var(--optic-grid);
  stroke-width: 1;
  opacity: 0.62;
}

#macro-indenter {
  transform: translateY(var(--indenter-y));
  transition: transform 100ms linear;
}

#macro-indenter > path:first-child {
  fill: #121612;
  stroke: rgba(255, 255, 255, 0.16);
  stroke-width: 2;
}

#macro-indenter .indenter-highlight {
  fill: none;
  stroke: rgba(255, 255, 255, 0.08);
  stroke-linecap: round;
  stroke-width: 4;
}

#macro-indenter text {
  fill: var(--readout-dim);
  font-family: var(--font-mono);
  font-size: var(--text-label);
  letter-spacing: 0.12em;
}

.macro-air-gap {
  fill: var(--air-gap);
  stroke: rgba(177, 204, 198, 0.14);
  stroke-dasharray: 2 5;
  stroke-width: 1;
}

/*
 * The membrane is drawn as a filled band (its 3 mil body) bounded by two
 * edges: the shadow path now traces the lit TOP surface the indenter presses
 * on, and .macro-membrane traces the underside facing the air gap. The old
 * single 13px stroke both understated the film and leaked half its width
 * into the air gap below the drawn boundary.
 */
.macro-membrane-body {
  fill: #1d241f;
  stroke: none;
}

.macro-membrane-shadow {
  fill: none;
  stroke: rgba(215, 231, 222, 0.38);
  stroke-linecap: round;
  stroke-width: 3;
  filter: url("#soft-glow");
}

.macro-membrane {
  fill: none;
  stroke: #0c100d;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 3;
}

.macro-gel {
  fill: url("#gel-gradient");
}

.macro-texture-line {
  fill: none;
  stroke: rgba(226, 240, 235, 0.92);
  stroke-linecap: round;
  stroke-width: 7;
}

.macro-acrylic {
  fill: url("#acrylic-gradient");
  stroke: rgba(255, 255, 255, 0.08);
  stroke-width: 1;
}

.macro-coupling-glow {
  fill: url("#coupling-gradient");
  opacity: calc(0.03 + var(--coupling-strength) * 0.2);
  transform-box: fill-box;
  transform-origin: center;
  transform: scaleX(calc(0.25 + var(--pressure) * 1.05));
}

.macro-coupling-line {
  fill: none;
  stroke: var(--signal-amber-bright);
  stroke-linecap: round;
  stroke-width: 1.9;
  opacity: calc(0.24 + var(--coupling-strength) * 0.76);
  filter: drop-shadow(0 0 3px rgba(244, 184, 64, calc(var(--coupling-strength) * 0.42)));
}

.macro-rays {
  color: var(--signal-amber-bright);
}

.macro-rays .ray {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-width: 1.45;
}

.macro-rays .ray--incident {
  opacity: 0.22;
}

.macro-rays .ray--reflected {
  opacity: calc(var(--reflection-opacity) * 0.7);
}

.macro-rays .ray--center {
  opacity: calc(0.18 - var(--pressure) * 0.13);
}

.macro-label path {
  fill: none;
  stroke: rgba(255, 255, 255, 0.18);
  stroke-width: 1;
}


/*
 * The sampled-window marker is annotation, not signal: a single faint dashed
 * outline centred on the contact, no leader, no label. The micro panel header
 * already names the window, so the schematic stays clean. It brightens
 * slightly on hover for anyone who goes looking for it.
 */
.macro-scale-marker path {
  fill: none;
  stroke: rgba(196, 210, 202, 0.16);
  stroke-width: 1;
  stroke-dasharray: 4 4;
  transition: stroke 200ms linear;
}

.macro-stage:hover .macro-scale-marker path {
  stroke: rgba(196, 210, 202, 0.4);
}

.macro-camera-body,
.macro-camera-mount {
  fill: #0e130f;
  stroke: rgba(215, 228, 222, 0.56);
  stroke-width: 1.5;
}

.macro-camera-sensor {
  fill: rgba(24, 31, 27, 0.92);
  stroke: rgba(255, 192, 74, 0.2);
  stroke-width: 1;
}

.macro-camera-ring {
  fill: #101511;
  stroke: rgba(214, 230, 223, 0.68);
  stroke-width: 4;
}

.macro-camera-lens {
  fill: #010201;
  stroke: rgba(255, 192, 74, 0.42);
  stroke-width: 2.5;
}

.macro-camera-glass {
  fill: rgba(181, 209, 198, 0.22);
  stroke: none;
}

.macro-camera-aperture {
  fill: #000;
  stroke: rgba(255, 192, 74, 0.5);
  stroke-width: 1.25;
}


.macro-led {
  fill: none;
  stroke: var(--signal-amber);
  stroke-linecap: round;
  stroke-width: 2;
}

.macro-led circle {
  fill: var(--signal-amber);
  filter: url("#soft-glow");
}

.macro-legend {
  /* In flow under the drawing: at the label size the three entries wrap to
     two rows on a phone, and an overlay then sat on the camera. */
  display: flex;
  flex-wrap: wrap;
  gap: 12px 20px;
  margin-top: 18px;
  padding: 0 6px;
  color: var(--readout-secondary);
  font-family: var(--font-mono);
  font-size: var(--text-label);
  letter-spacing: 0.08em;
}

/*
 * Diagram labels live in HTML, positioned over the drawing, never as SVG
 * <text>: SVG text scales with the viewBox and measured 8.7px on the 1280
 * layout (2026-09-27). The frame matches the svg box exactly, so the
 * percentages below are the leader-line endpoints in viewBox units.
 */
.stage-frame {
  position: relative;
  width: 100%;
}

.stage-label {
  position: absolute;
  margin: 0;
  color: var(--readout-secondary);
  font-family: var(--font-mono);
  font-size: var(--text-label);
  letter-spacing: 0.12em;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
  pointer-events: none;
  text-shadow:
    0 0 6px rgba(7, 9, 8, 0.9),
    0 1px 2px rgba(7, 9, 8, 0.8);
}

.stage-label--membrane {
  left: 10.9%;
  bottom: calc(62.2% + 6px);
}

.stage-label--gel {
  right: 15.4%;
  bottom: calc(30.4% + 6px);
}

.stage-label--gap {
  right: 6.5%;
  bottom: calc(74.4% + 6px);
}

.stage-label--surface {
  /* Sits on the light gel fill: a small dark plate instead of dark text. */
  right: 6.5%;
  bottom: calc(24.4% + 4px);
  padding: 4px 6px;
  background: rgba(7, 9, 8, 0.78);
  text-shadow: none;
}

.macro-legend span {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.macro-legend i {
  width: 18px;
  height: 2px;
  display: inline-block;
}

.legend-ray {
  background: var(--signal-amber);
}

.legend-gap {
  background: var(--gel);
  opacity: 0.35;
}

.legend-coupling {
  background: var(--signal-amber-bright);
  box-shadow: 0 0 8px rgba(227, 161, 40, 0.42);
}

.view-header--tabs {
  align-items: stretch;
}

.view-header--tabs > div:first-child {
  align-self: center;
}

.micro-tabs {
  display: flex;
  align-self: stretch;
}

.micro-tabs button {
  min-width: 54px;
  min-height: 44px;
  border: 0;
  border-left: 1px solid var(--optic-ring);
  color: var(--readout-dim);
  background: transparent;
  font-family: var(--font-mono);
  font-size: var(--text-fine);
  font-weight: 700;
  letter-spacing: 0.08em;
  cursor: pointer;
  transition:
    color 140ms var(--ease-out),
    background-color 140ms var(--ease-out);
}

.micro-tabs button:hover {
  color: var(--readout);
}

.micro-tabs button[aria-selected="true"] {
  color: var(--camera-black);
  background: var(--signal-amber-bright);
}

/* The Camera tab exists for the phone layout only; the desktop grid shows
 * the sensor output beside the microscope. */
.micro-tab--phone {
  display: none;
}

.micro-window-label {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.micro-panel {
  position: relative;
  min-height: 244px;
  overflow: hidden;
  background:
    radial-gradient(circle at 50% 48%, rgba(163, 180, 191, 0.05), transparent 55%),
    var(--optic-surface-1);
}

/*
 * Scale the microscope drawing by its own aspect ratio rather than pinning a
 * pixel height. At 1920 the fixed 210px box letterboxed the 520x320 artwork,
 * wasting the column's width on empty margin while the mechanism animation --
 * the analytical centre of the page -- rendered smaller than any other panel.
 * The max-height keeps the right column from outgrowing the device view.
 */
.micro-panel svg,
.micro-panel canvas {
  width: 100%;
  height: auto;
  /*
   * Bound the drawing by WIDTH, not height. Capping the height re-introduced
   * the letterboxing this rule exists to remove: at 1920 a 528px-wide column
   * clipped to 300px tall rendered at 1.76 instead of the artwork's 1.63.
   * Constraining width lets aspect-ratio hold the proportion exactly while
   * still bounding the height that feeds the 920px shell budget.
   */
  max-width: 460px;
  margin-inline: auto;
  aspect-ratio: 520 / 320;
}

.micro-panel canvas {
  background: transparent;
}

.micro-gap-area {
  fill: rgba(160, 193, 184, 0.1);
  stroke: rgba(160, 193, 184, 0.12);
  stroke-width: 1;
}

.micro-surface-fill {
  fill: url("#micro-gel-gradient");
}

.micro-surface-line {
  fill: none;
  stroke: rgba(202, 224, 218, 0.84);
  stroke-linejoin: round;
  stroke-width: 2;
}

/*
 * In the ~100 um section a 3 mil membrane is a slab whose far side is out of
 * frame, so the body fills from the draped underside past the top of the
 * panel and the stroked paths become its lower edge, not the film itself.
 */
.micro-membrane-body {
  fill: rgba(6, 8, 7, 0.94);
  stroke: none;
}

.micro-membrane-shadow {
  fill: none;
  stroke: rgba(227, 161, 40, 0.18);
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 11;
}

.micro-membrane {
  fill: none;
  stroke: #030403;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 5;
}

.micro-contact-segment {
  /* A filled seam that hugs the interface, not a stroked curve over it. */
  fill: var(--signal-amber-bright);
  stroke: var(--signal-amber-bright);
  stroke-linejoin: round;
  stroke-width: 0.8;
  opacity: calc(0.32 + var(--coupling-strength) * 0.68);
  filter: drop-shadow(0 0 2px rgba(244, 184, 64, calc(var(--coupling-strength) * 0.32)));
}

.micro-annotation path {
  fill: none;
  stroke: rgba(255, 255, 255, 0.17);
  stroke-width: 1;
}


.micro-annotation--surface path {
  stroke: rgba(10, 18, 15, 0.42);
}


.micro-scale {
  position: absolute;
  right: 14px;
  bottom: 10px;
  left: 14px;
  display: flex;
  justify-content: space-between;
  gap: 20px;
  color: var(--readout-dim);
  font-family: var(--font-mono);
  font-size: var(--text-fine);
  /* Legible when the row lands on the light gel area in stacked layouts. */
  text-shadow:
    0 0 6px rgba(7, 9, 8, 0.9),
    0 1px 2px rgba(7, 9, 8, 0.8);
  letter-spacing: 0.08em;
}

.micro-scale span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.micro-scale i {
  width: 8px;
  height: 8px;
  display: inline-block;
  background: var(--signal-amber);
  box-shadow: 0 0 8px rgba(227, 161, 40, 0.42);
}

.canvas-fallback {
  position: absolute;
  top: 16px;
  right: 16px;
  max-width: 170px;
  margin: 0;
  color: var(--readout-dim);
  font-size: var(--text-fine);
  line-height: 1.45;
  text-align: right;
  pointer-events: none;
}

.microscope-readout,
.camera-readout {
  min-height: 34px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 0 16px;
  color: var(--readout-dim);
  background: rgba(8, 10, 9, 0.35);
  box-shadow: inset 0 1px var(--optic-ring);
  font-family: var(--font-mono);
  font-size: var(--text-fine);
  letter-spacing: 0.08em;
}

.microscope-readout output,
.camera-readout output {
  color: var(--signal-amber);
  font-size: var(--text-fine);
}

.camera-stage {
  position: relative;
  aspect-ratio: 4 / 3;
  /*
   * Widening the microscope column also widened this 4:3 stage, which grew
   * it from 249px to 309px tall and pushed the whole mechanism shell past
   * the 920px desktop budget. The cap decouples the sensor readout's height
   * from the column width; the response is a centred disc, so losing the
   * strict 4:3 costs nothing.
   */
  /*
   * Sized as the sensor's actual ROI (320x240) and centred in its column:
   * the stage previously computed a 293px width from its height cap and
   * then sat flush left, which read as off-centre on the page.
   */
  max-height: 220px;
  max-width: 293px;
  margin-inline: auto;
  min-height: 0;
  overflow: hidden;
  background:
    radial-gradient(circle at 50% 50%, rgba(224, 231, 219, calc(0.09 + var(--camera-response-opacity) * 0.09)), transparent 43%),
    linear-gradient(rgba(255, 255, 255, 0.01) 1px, transparent 1px) 0 0 / 22px 22px,
    linear-gradient(90deg, rgba(255, 255, 255, 0.01) 1px, transparent 1px) 0 0 / 22px 22px,
    #7f8b80;
}

.camera-vignette,
.camera-noise,
.camera-contact,
.camera-reticle {
  position: absolute;
  inset: 0;
}

.camera-vignette {
  background: radial-gradient(circle, transparent 30%, rgba(10, 18, 14, 0.72) 100%);
}

.camera-noise {
  opacity: 0.16;
  background:
    repeating-linear-gradient(0deg, rgba(18, 25, 21, 0.09) 0 1px, transparent 1px 6px),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.09) 0 1px, transparent 1px 10px);
  mix-blend-mode: multiply;
}

.camera-contact {
  inset: auto;
  top: 50%;
  left: 50%;
  width: clamp(6%, var(--camera-contact-span), 72%);
  height: auto;
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background:
    radial-gradient(circle closest-side at 50% 50%, rgba(4, 6, 5, calc(var(--camera-darkness) * 0.94)) 0 74%, rgba(9, 13, 11, calc(var(--camera-darkness) * 0.82)) 84%, rgba(34, 43, 37, calc(var(--annulus-strength) * 0.56)) 92%, rgba(84, 96, 88, calc(var(--annulus-strength) * 0.18)) 97%, transparent 100%),
    radial-gradient(circle closest-side at 50% 50%, transparent 68%, rgba(30, 39, 33, calc(var(--annulus-strength) * 0.28)) 84%, transparent 96%),
    rgba(82, 93, 85, calc(var(--camera-darkness) * 0.18));
  box-shadow:
    0 0 18px 6px rgba(12, 17, 14, calc(var(--camera-response-opacity) * 0.14)),
    0 0 0 1px rgba(255, 255, 255, calc(var(--camera-response-opacity) * 0.08));
  opacity: var(--camera-response-opacity);
  transform: translate(-50%, -50%);
  clip-path: var(--probe-clip, none);
  transition: background-color 100ms linear, box-shadow 100ms linear, opacity 120ms linear;
}

/*
 * Annular dimming for a clipped footprint. The disk gets its soft outer ring
 * from a radial gradient, which a polygon clip cuts away -- so the star and
 * the triangle would lose the halo the round probe keeps. This is that ring,
 * drawn as a slightly larger copy of the same footprint and blurred on its
 * own layer, where the blur cannot touch the speckle texture.
 */
.camera-contact::after {
  position: absolute;
  inset: -7%;
  clip-path: var(--probe-clip, none);
  border-radius: inherit;
  background: rgba(46, 57, 49, calc(var(--annulus-strength) * 0.42));
  filter: blur(5px);
  opacity: var(--camera-response-opacity);
  content: "";
  z-index: -1;
}

.camera-reference {
  position: absolute;
  inset: -8%;
  border-radius: inherit;
  background:
    linear-gradient(rgba(175, 187, 176, calc(0.04 + var(--camera-response-opacity) * 0.04)), rgba(175, 187, 176, 0)),
    url("./assets/camera-response-screw-cross.png") center / 86px 86px repeat;
  filter: grayscale(0.5) contrast(calc(0.62 + var(--camera-response-opacity) * 0.16)) brightness(1.08);
  mix-blend-mode: multiply;
  opacity: calc(var(--camera-response-opacity) * 0.13);
}

.camera-contact i {
  position: absolute;
  width: 34%;
  height: 1px;
  border-radius: 999px;
  background: rgba(36, 44, 39, calc(var(--camera-response-opacity) * 0.055));
}

.camera-contact i:nth-child(1) { transform: translateY(-14px); }
.camera-contact i:nth-child(2) { transform: translateY(-7px); }
.camera-contact i:nth-child(4) { transform: translateY(7px); }
.camera-contact i:nth-child(5) { transform: translateY(14px); }

/*
 * A 1px rule placed at 50% has its leading edge, not its centre, on the
 * midline, so the crosshair landed half a pixel below and right of the
 * response blob it is meant to register against. Pull each line back by half
 * its own thickness.
 */
.camera-reticle--x {
  top: 50%;
  height: 1px;
  transform: translateY(-50%);
  background: rgba(34, 44, 38, 0.28);
}

.camera-reticle--y {
  left: 50%;
  width: 1px;
  transform: translateX(-50%);
  background: rgba(34, 44, 38, 0.28);
}


.mechanism-console {
  display: grid;
  grid-template-columns: 132px minmax(240px, 1fr) minmax(360px, 1.2fr);
  grid-template-areas:
    "play pressure rail"
    "explanation explanation explanation";
  background: var(--nitrile);
  box-shadow: inset 0 1px var(--optic-ring);
}

.sequence-control,
.pressure-control,
.state-rail {
  min-height: 68px;
  padding: 9px 16px;
  box-shadow: inset -1px 0 var(--optic-ring);
}

.sequence-control {
  grid-area: play;
}

.sequence-control > span,
.pressure-control label > span {
  display: block;
  color: var(--readout-dim);
  font-family: var(--font-mono);
  font-size: var(--text-fine);
  letter-spacing: 0.12em;
}

.sequence-control button {
  width: 100%;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-top: 9px;
  border: 0;
  color: var(--camera-black);
  background: var(--signal-amber-bright);
  font-family: var(--font-mono);
  font-size: var(--text-fine);
  font-weight: 700;
  letter-spacing: 0.08em;
  cursor: pointer;
  transition:
    background-color 140ms var(--ease-out),
    transform 120ms var(--ease-out);
}

.sequence-control button:hover {
  background: #ffd077;
}

.sequence-control button:active {
  transform: scale(0.98);
}

.play-icon {
  width: 0;
  height: 0;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  border-left: 7px solid currentColor;
}

.sequence-control button[aria-pressed="true"] .play-icon,
.recon-control button[aria-pressed="true"] .play-icon {
  width: 7px;
  height: 8px;
  border: 0;
  border-right: 2px solid currentColor;
  border-left: 2px solid currentColor;
}

.pressure-control {
  grid-area: pressure;
}

.pressure-control label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}

.pressure-control output {
  color: var(--signal-amber-bright);
  font-family: var(--font-mono);
  font-size: var(--text-title);
  font-variant-numeric: tabular-nums;
}

.pressure-control input {
  width: 100%;
  /*
   * This slider drives the whole mechanism animation, so it is the single
   * most important touch target on the page -- and at 32px it was under the
   * 44px minimum on phones and tablets. The track and thumb are unchanged;
   * only the hit area grows, with the extra height taken out of the margin
   * so the layout does not shift.
   */
  height: 44px;
  margin-top: 4px;
  appearance: none;
  background: transparent;
  cursor: pointer;
}

.pressure-control input::-webkit-slider-runnable-track {
  height: 3px;
  background:
    linear-gradient(
      90deg,
      var(--signal-amber-bright) 0 var(--signal-level),
      rgba(255, 255, 255, 0.12) var(--signal-level) 100%
    );
}

.pressure-control input::-webkit-slider-thumb {
  width: 16px;
  height: 16px;
  margin-top: -6px;
  border: 4px solid var(--signal-amber-bright);
  border-radius: 50%;
  appearance: none;
  background: var(--camera-black);
  box-shadow: 0 0 0 4px rgba(227, 161, 40, 0.14);
}

.pressure-control input::-moz-range-track {
  height: 3px;
  background: rgba(255, 255, 255, 0.12);
}

.pressure-control input::-moz-range-progress {
  height: 3px;
  background: var(--signal-amber-bright);
}

.pressure-control input::-moz-range-thumb {
  width: 10px;
  height: 10px;
  border: 4px solid var(--signal-amber-bright);
  border-radius: 50%;
  background: var(--camera-black);
}

.state-rail {
  grid-area: rail;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0;
  margin: 0;
  list-style: none;
}

.state-rail li {
  position: relative;
  min-width: 0;
  display: grid;
  align-content: center;
  gap: 7px;
  padding: 0 18px 0 24px;
  color: var(--readout-dim);
  box-shadow: inset 1px 0 var(--optic-ring-soft);
}

.state-rail li::before {
  position: absolute;
  top: 50%;
  left: 8px;
  width: 7px;
  height: 7px;
  border: 1px solid var(--readout-dim);
  border-radius: 50%;
  transform: translateY(-50%);
  content: "";
}

.state-rail span {
  font-family: var(--font-mono);
  font-size: var(--text-fine);
}

.state-rail strong {
  overflow: hidden;
  font-size: var(--text-label);
  font-weight: 550;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.state-rail li.is-active {
  color: var(--readout);
}

.state-rail li.is-active::before {
  border-color: var(--signal-amber);
  background: var(--signal-amber);
  box-shadow: 0 0 10px rgba(227, 161, 40, 0.56);
}

.state-explanation {
  grid-area: explanation;
  min-height: 46px;
  display: grid;
  grid-template-columns: 148px minmax(0, 1fr);
  align-items: center;
  box-shadow: inset 0 1px var(--optic-ring);
}

.state-explanation span {
  padding-left: 18px;
  color: var(--readout-tertiary);
  font-family: var(--font-mono);
  font-size: var(--text-fine);
  letter-spacing: 0.08em;
}

.state-explanation p {
  max-width: 900px;
  margin: 0;
  padding: 8px 18px;
  color: var(--readout-secondary);
  box-shadow: inset 1px 0 var(--optic-ring);
  font-size: var(--text-label);
  line-height: 1.55;
}

.instrument-disclosure {
  margin: 0;
  padding: 7px 16px 8px;
  color: var(--readout-dim);
  background: #0b0d0b;
  box-shadow: inset 0 1px var(--optic-ring);
  font-family: var(--font-mono);
  font-size: var(--text-fine);
  letter-spacing: 0.02em;
  line-height: 1.55;
}

.record-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.68fr) minmax(330px, 0.72fr);
  gap: 1px;
  background: var(--optic-ring);
  box-shadow: 0 0 0 1px var(--optic-ring);
}

.video-module {
  min-width: 0;
  margin: 0;
  padding: 10px;
  background: var(--optic-surface-1);
}

.video-module video {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: contain;
  background: #020302;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.06);
}

.video-module figcaption,
.recon-card figcaption {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  color: var(--readout-dim);
  font-family: var(--font-mono);
  font-size: var(--text-fine);
  letter-spacing: 0.08em;
}

.video-module figcaption {
  padding: 14px 4px 4px;
}

.video-module figcaption span:first-child {
  color: var(--signal-amber);
}

.form-comparison {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  background: var(--optic-surface-1);
  box-shadow: inset 0 0 0 1px var(--optic-ring);
}

.form-comparison article {
  min-width: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto auto 1fr;
  gap: 16px 0;
  padding: clamp(28px, 3.5vw, 58px);
  overflow: hidden;
  box-shadow: inset -1px 0 var(--optic-ring);
}

.form-comparison article:last-child {
  box-shadow: none;
}


/* Photographs from the deck: the two exploded CAD views sit on a pale plate
   (their own white ground), the hand photograph fills its frame. */
.form-photo {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  background: var(--nitrile);
  box-shadow: inset 0 0 0 1px var(--optic-ring);
}

.form-photo--plate {
  box-sizing: border-box;
  padding: 8px;
  object-fit: contain;
  background: var(--readout);
}

.form-comparison article > div:last-child {
  align-self: center;
}

.form-comparison h3 {
  margin: 0;
  font-family: var(--font-ui);
  /*
   * The heading's text box is narrow (the glyph shares the card) and its
   * width doesn't track the viewport linearly, so no static clamp keeps
   * OMNIDIRECTIONAL whole everywhere. A soft hyphen in the markup lets it
   * break as OMNI-DIRECTIONAL only when the box is genuinely too narrow.
   */
  font-size: clamp(22px, 1.8vw, 24px);
  font-weight: 640;
  letter-spacing: -0.045em;
  /*
   * overflow-wrap: anywhere licensed arbitrary mid-word breaks, and at
   * phone width OMNIDIRECTIONAL rendered as "OMNIDIRECTION AL". The floor
   * of the size clamp drops instead, so the longest label fits whole.
   */
  overflow-wrap: normal;
}

.form-comparison p {
  margin: 12px 0 0;
  color: var(--readout-tertiary);
  font-size: var(--text-label);
  line-height: 1.55;
}

/*
 * Turntable gallery. One card per pressed object, all of them GlowTact
 * output: the rotating reconstruction is the subject, and the tactile frame
 * it was computed from rides in the caption as a 48px thumbnail. The
 * thumbnail sat over the render first, where it covered relief on half the
 * objects and put mono type on a white plate; in the caption it stays legible
 * and the card still reads input-to-output without a second column.
 */
.recon-control {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  margin-bottom: 14px;
  padding: 9px 16px;
  background: var(--optic-surface-1);
  box-shadow: 0 0 0 1px var(--optic-ring);
}

.recon-control > span {
  color: var(--readout-dim);
  font-family: var(--font-mono);
  font-size: var(--text-fine);
  letter-spacing: 0.12em;
}

.recon-control button {
  min-width: 180px;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  border: 0;
  color: var(--readout);
  background: var(--optic-surface-2);
  box-shadow: inset 0 0 0 1px var(--optic-ring);
  font-family: var(--font-mono);
  font-size: var(--text-fine);
  font-weight: 700;
  letter-spacing: 0.08em;
  cursor: pointer;
  transition:
    background-color 140ms var(--ease-out),
    transform 120ms var(--ease-out);
}

.recon-control button:hover {
  background: #ffd077;
}

.recon-control button:active {
  transform: scale(0.98);
}

.recon-gallery {
  /* Four objects: one row on a laptop, two by two on a phone. */
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  background: var(--optic-ring);
  box-shadow: 0 0 0 1px var(--optic-ring);
}

.recon-card {
  min-width: 0;
  margin: 0;
  padding: 10px;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  background: var(--optic-surface-1);
}

.recon-stage {
  background: #0a0c0a;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
}

.recon-spin {
  display: block;
  width: 100%;
  aspect-ratio: 720 / 508;
  object-fit: contain;
  background: #0a0c0a;
}

.recon-card figcaption {
  display: grid;
  /* Photograph and tactile input split the card width, title below. Fixed
     150px columns overflowed the 303px card at 1280 (2026-09-27). */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  padding: 12px 4px 2px;
}

.recon-object,
.recon-input {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  box-shadow: 0 0 0 1px var(--optic-ring);
}

.recon-caption-text {
  grid-column: 1 / -1;
  display: grid;
  gap: 3px;
}

.recon-card figcaption strong {
  color: var(--readout);
  font-size: var(--text-label);
  font-weight: 550;
}

.research-console {
  display: grid;
  grid-template-columns: minmax(320px, 0.72fr) minmax(520px, 1.28fr);
  gap: 1px;
  margin-top: clamp(124px, 15vw, 240px);
  background: var(--optic-ring);
  box-shadow: 0 0 0 1px var(--optic-ring);
}

.research-heading,
.research-meta {
  padding: clamp(32px, 4vw, 68px);
  background: var(--optic-surface-1);
}

.research-heading .signal-label {
  margin-bottom: 34px;
}

.research-heading h2 {
  margin: 0;
  font-size: clamp(34px, 4vw, 52px);
  font-weight: 650;
  letter-spacing: -0.03em;
  line-height: 0.9;
}

.research-heading > h2 + p {
  max-width: 580px;
  margin: 24px 0 0;
  color: var(--readout-secondary);
  font-size: var(--text-title);
  line-height: 1.6;
}

.research-authors,
.research-affiliations {
  max-width: 580px;
  margin: 18px 0 0;
  color: var(--readout-secondary);
  font-size: var(--text-label);
  line-height: 1.6;
}

/* Author names are inline links; the vertical padding and negative margin
   give each a 44px target without changing the line spacing. */
.research-authors a {
  display: inline-block;
  padding-block: 12px;
  margin-block: -12px;
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--optic-ring);
  text-underline-offset: 3px;
}

.research-authors a:hover {
  color: var(--readout);
  text-decoration-color: var(--signal-amber);
}

.research-affiliations {
  margin-top: 6px;
  color: var(--readout-tertiary);
  font-size: var(--text-fine);
}

.research-links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 22px;
  margin: 20px 0 0;
  font-family: var(--font-mono);
  font-size: var(--text-label);
  letter-spacing: 0.08em;
}

.research-links a {
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  color: var(--readout);
  text-decoration: none;
  box-shadow: inset 0 -1px 0 var(--signal-amber);
}

.research-links a:hover {
  color: var(--signal-amber-bright);
}

.research-abstract {
  max-width: 580px;
  margin: 22px 0 0;
  color: var(--readout-secondary);
  font-size: var(--text-label);
  line-height: 1.6;
}

.research-heading sup {
  /* On the scale: 0.7em made 8.4px and 9.8px, two sizes the census rejects. */
  font-size: var(--text-fine);
  line-height: 0;
}

.research-meta {
  display: grid;
  align-content: space-between;
  gap: 42px;
}

.research-meta pre {
  max-width: 100%;
  margin: 0;
  /* Wrap rather than scroll: a sideways-scrolling BibTeX on a phone hides
     the author and year, and the entry is short enough to wrap cleanly. */
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  padding: 22px;
  color: var(--readout-tertiary);
  background: var(--nitrile);
  box-shadow: inset 0 0 0 1px var(--optic-ring);
  font-family: var(--font-mono);
  font-size: var(--text-fine);
  line-height: 1.65;
}

.instrument-footer {
  min-height: 116px;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  margin-top: 80px;
  box-shadow: inset 0 1px var(--optic-ring);
}

.instrument-footer a,
.instrument-footer p {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  color: var(--readout-dim);
  font-family: var(--font-mono);
  font-size: var(--text-fine);
  letter-spacing: 0.08em;
  text-decoration: none;
  text-transform: uppercase;
}

.instrument-footer a:last-child {
  justify-self: end;
}

.instrument-footer a:hover {
  color: var(--signal-amber);
}

@media (max-width: 1180px) {
  .signal-hero {
    grid-template-columns: minmax(330px, 0.82fr) minmax(470px, 1.18fr);
    gap: 36px 44px;
  }

  .mechanism-grid {
    grid-template-columns: minmax(0, 1.5fr) minmax(310px, 1fr);
  }

  .macro-stage {
    min-height: 520px;
  }

  .mechanism-console {
    grid-template-columns: 132px minmax(220px, 0.82fr) minmax(360px, 1.18fr);
  }

  .record-layout {
    grid-template-columns: minmax(0, 1.4fr) minmax(320px, 0.8fr);
  }

  .form-comparison article {
    grid-template-columns: 1fr;
  }

  .form-index {
    grid-column: auto;
  }
}

@media (max-width: 900px) {
  .instrument-header,
  .instrument-footer,
  main {
    width: min(100% - 40px, 760px);
  }

  /*
   * Stacked layout: the 4:3 camera stage at full column width became a
   * ~550px gray monolith that dwarfed every other panel. Cap and centre it.
   */
  .camera-stage {
    max-width: 560px;
    margin-inline: auto;
  }

  /*
   * The micro views were letterboxed: a fixed pixel height centred the
   * 520x320 drawing with dead space either side. Scale by aspect ratio so
   * the section fills the column and its labels scale up with it.
   */
  .micro-panel svg,
  .micro-panel canvas {
    height: auto;
    /* Stacked layouts get the full column; the desktop cap would letterbox. */
    max-height: none;
    aspect-ratio: 520 / 320;
  }

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

  .instrument-header nav {
    display: none;
  }

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

  .signal-hero {
    min-height: auto;
    grid-template-columns: 1fr;
    grid-template-rows: auto;
    gap: 52px;
    padding-block: 72px 18px;
  }

  .hero-copy {
    padding: 0;
  }

  .hero-copy h1 {
    max-width: 720px;
    font-size: clamp(72px, 15vw, 112px);
  }

  .hero-summary {
    max-width: 640px;
  }

  .hero-figure {
    width: 100%;
  }

  .hero-figure img {
    max-height: none;
  }

  .section-header {
    grid-template-columns: 1fr;
    gap: 28px;
  }

  .section-header > p {
    justify-self: start;
  }

  .mechanism-grid {
    grid-template-columns: 1fr;
    grid-template-rows: auto;
  }

  .micro-tab--phone {
    display: inline-flex;
  }

  /* One stage on a phone: Camera hides the microscope's panels and readout,
     and the sensor-output article shows only while Camera is selected. */
  .mechanism-grid[data-micro-view="camera"] .microscope-view .micro-scale {
    display: none;
  }

  .mechanism-grid:not([data-micro-view="camera"]) .output-view {
    display: none;
  }

  .macro-view {
    grid-row: auto;
  }

  .macro-stage {
    min-height: 500px;
  }

  .mechanism-console {
    grid-template-columns: 150px 1fr;
    grid-template-areas:
      "play pressure"
      "rail rail"
      "explanation explanation";
  }

  .state-rail {
    min-height: 86px;
  }

  .record-layout,
  .research-console {
    grid-template-columns: 1fr;
  }

  .recon-gallery {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .capability-stack {
    grid-template-columns: repeat(3, 1fr);
  }

  .capability-stack article {
    padding: 28px;
    box-shadow: inset -1px 0 var(--optic-ring);
  }

  .form-comparison {
    grid-template-columns: 1fr;
  }

  .form-comparison article {
    /* Sensor and exploded view side by side, the words under both. */
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: auto auto;
    gap: 12px;
    box-shadow: inset 0 -1px var(--optic-ring);
  }

  .form-photo {
    grid-row: 1;
  }

  .form-comparison article > div:last-child {
    grid-column: 1 / -1;
    grid-row: 2;
  }

}

@media (max-width: 640px) {
  .instrument-header,
  .instrument-footer,
  main {
    width: min(100% - 28px, 520px);
  }

  .instrument-header {
    min-height: 64px;
  }

  .signal-hero {
    padding-top: 56px;
  }

  .signal-label {
    align-items: flex-start;
    line-height: 1.45;
  }

  .hero-copy h1 {
    font-size: clamp(60px, 19vw, 92px);
    line-height: 0.84;
  }

  .hero-actions {
    /* Two by two: the two live links on one row, the pending pair below. */
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .button--pending {
    flex-direction: column;
    gap: 2px;
    padding-block: 8px;
  }

  .hero-capabilities {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .hero-capabilities div {
    padding: 10px 10px 10px 0;
  }

  .hero-capabilities div + div {
    padding-left: 10px;
  }

  .hero-capabilities dd {
    margin-top: 5px;
  }

  .hero-figure__frame {
    padding: 6px;
  }

  .hero-figure__frame::before {
    inset: 6px;
  }

  .hero-figure figcaption {
    grid-template-columns: 1fr;
    gap: 8px;
  }

  .hero-figure figcaption p {
    justify-self: start;
    text-align: left;
  }

  .mechanism,
  .record,
  .forms,
  .reconstruction {
    padding-top: 120px;
  }

  .mechanism-toolbar {
    align-items: flex-start;
    padding-block: 14px;
  }

  .toolbar-status {
    max-width: 140px;
  }

  .view-header {
    padding-inline: 14px;
  }

  .macro-stage {
    /* The schematic renders about 200px tall at 375px; a fixed floor left
       130px of empty well around it. */
    min-height: 0;
    padding: 10px 6px 14px;
  }

  .macro-label {
    display: none;
  }

  .macro-legend {
    gap: 10px 14px;
    margin-top: 12px;
  }

  .micro-panel {
    min-height: 0;
  }

  .micro-panel svg,
  .micro-panel canvas {
    height: auto;
    /* Stacked layouts get the full column; the desktop cap would letterbox. */
    max-height: none;
    aspect-ratio: 520 / 320;
  }

  /*
   * At phone width the schematic text scales below ~5px -- unreadable ink
   * that only adds clutter. The diagrams read as pure schematics here; the
   * HTML legend and panel headers carry the words.
   */
  .micro-annotation,
  .macro-stage svg text {
    display: none;
  }

  .canvas-fallback {
    max-width: 130px;
  }

  .mechanism-console {
    grid-template-columns: 1fr;
    grid-template-areas:
      "pressure"
      "rail"
      "play"
      "explanation";
  }

  .sequence-control,
  .pressure-control,
  .state-rail {
    min-height: auto;
    box-shadow: inset 0 -1px var(--optic-ring);
  }

  .state-rail {
    padding: 0;
  }

  .state-rail li {
    min-height: 76px;
    padding-right: 8px;
    padding-left: 22px;
  }

  .state-rail strong {
    font-size: var(--text-fine);
  }

  .sequence-control {
    display: grid;
    grid-template-columns: auto 150px;
    align-items: center;
    gap: 18px;
  }

  .sequence-control button {
    margin-top: 0;
  }

  .state-explanation {
    grid-template-columns: 1fr;
  }

  .state-explanation span {
    padding: 14px 16px 0;
  }

  .state-explanation p {
    padding: 10px 16px 16px;
    box-shadow: none;
  }

  .record-layout {
    gap: 0;
  }

  .capability-stack {
    grid-template-columns: 1fr;
  }

  .capability-stack article {
    box-shadow: inset 0 -1px var(--optic-ring);
  }

  .form-comparison article {
    gap: 10px;
    padding: 22px 20px;
  }

  .recon-gallery {
    /* Turntables in one column ran 3573px on a phone; two columns keep
       every clip above 160px wide and halve the scroll. */
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .recon-card figcaption {
    gap: 8px;
    padding: 10px 4px 2px;
  }

  .recon-control {
    flex-direction: column;
    align-items: stretch;
    gap: 9px;
  }

  .recon-control button {
    width: 100%;
  }

  .research-console {
    margin-top: 120px;
  }

  .research-heading,
  .research-meta {
    padding: 28px 22px;
  }

  .research-meta pre {
    padding: 16px;
    font-size: var(--text-fine);
  }

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

  .instrument-footer p {
    display: none;
  }
}

@media (max-width: 380px) {
  .instrument-header,
  .instrument-footer,
  main {
    width: calc(100% - 20px);
  }

  .hero-copy h1 {
    /* 58px was 15% of a 375px viewport; the hero took 1.7 screens. */
    font-size: clamp(40px, 11vw, 48px);
  }

  .view-header h3 {
    font-size: var(--text-label);
  }

  .micro-tabs button {
    min-width: 48px;
  }

  .state-rail strong {
    white-space: normal;
  }
}

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

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

.build-stamp {
  opacity: 0.45;
  font-family: monospace;
  font-size: var(--text-fine);
  letter-spacing: 0.08em;
}

/* ------------------------------------------------------------------ *
 * Results region
 *
 * Five modules sharing one skeleton: eyebrow carrying the doubt each
 * result answers, declarative headline, a claim line whose numbers are
 * bound to design/data/results.json by data-metric, the evidence stage,
 * and a scope footnote stating what the evidence is not. The skeleton is
 * what keeps five different kinds of evidence reading as one section.
 *
 * No new type sizes or colour tokens: everything maps onto the existing
 * three-step scale and the established amber/readout palette.
 * ------------------------------------------------------------------ */

.results-index {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  margin: 0 0 clamp(64px, 7vw, 116px);
  padding: 1px;
  list-style: none;
  background: var(--optic-ring-soft);
  border: 1px solid var(--optic-ring-soft);
}

.results-index a {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 88px;
  padding: 18px 20px;
  color: var(--readout);
  background: var(--optic-surface-1);
  font-size: var(--text-title);
  text-decoration: none;
  transition: background 0.25s var(--ease-out), color 0.25s var(--ease-out);
}

.results-index a > span {
  color: var(--readout-tertiary);
  font-family: var(--font-mono);
  font-size: var(--text-fine);
  letter-spacing: 0.14em;
}

.results-index a:hover,
.results-index a:focus-visible {
  color: var(--signal-amber-bright);
  background: var(--optic-surface-2);
}

.results-index a:hover > span,
.results-index a:focus-visible > span {
  color: var(--signal-amber);
}

.result-module {
  padding-top: clamp(96px, 11vw, 176px);
  border-top: 1px solid var(--optic-ring-soft);
}

.result-module:first-of-type {
  padding-top: 0;
  border-top: 0;
}

.module-header {
  margin-bottom: clamp(40px, 4.5vw, 72px);
}

.module-header h3 {
  max-width: 900px;
  margin: 0 0 24px;
  font-size: clamp(28px, 3.2vw, 44px);
  font-weight: 640;
  letter-spacing: -0.042em;
  line-height: 0.94;
}

.module-claim {
  max-width: 640px;
  margin: 0;
  color: var(--readout-secondary);
  font-size: var(--text-title);
  line-height: 1.6;
  text-wrap: pretty;
}

.module-claim strong {
  color: var(--signal-amber-bright);
  font-weight: 640;
  font-variant-numeric: tabular-nums;
}

/* The scope footnote is deliberately quiet but never below AA: it states
 * what each result is not, which is the part a reviewer checks first. */
.module-scope {
  max-width: 660px;
  margin: clamp(28px, 3vw, 44px) 0 0;
  padding-left: 18px;
  border-left: 1px solid var(--optic-ring);
  color: var(--readout-tertiary);
  font-size: var(--text-label);
  line-height: 1.62;
  text-wrap: pretty;
}

/* DAT / 01: the two passive-placement clips and the fingerprint press in one row. */
.passive-pair {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
}

/* 16:9, 16:10 and a square source; one shared box keeps the row level. */
.passive-pair .evidence-figure video {
  aspect-ratio: 16 / 10;
  object-fit: cover;
  background: #000;
}

/* The fingerprint contact sits at about 63% of the square frame's height. */
.evidence-figure--fingerprint video {
  object-position: 50% 63%;
}

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

  .fig9-head,
  .fig9-row {
    grid-template-columns: 72px repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 900px) {
  .results-index {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 560px) {
  .results-index {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .results-index a {
    min-height: 56px;
  }
}

#snr-chart {
  display: block;
  width: 100%;
  height: auto;
}

.evidence-figure {
  margin: 0;
  background: var(--optic-surface-1);
  border: 1px solid var(--optic-ring-soft);
}

.evidence-figure img,
.evidence-figure video {
  display: block;
  width: 100%;
  height: auto;
}

.evidence-figure figcaption {
  padding: 18px 20px 20px;
  color: var(--readout-secondary);
  font-size: var(--text-label);
  line-height: 1.6;
}

/* The eyebrow only. Unscoped, this also caught the inline data-metric spans
 * in the caption body and stacked each number onto its own line. */
.evidence-figure figcaption > span:first-child {
  display: block;
  margin-bottom: 8px;
  color: var(--readout-tertiary);
  font-family: var(--font-mono);
  font-size: var(--text-fine);
  letter-spacing: 0.14em;
}


/* ------------------------------------------------------------------ *
 * DAT / 03 -- shear tracking
 * ------------------------------------------------------------------ */

.shear-layout {
  display: grid;
  gap: clamp(28px, 3vw, 48px);
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}

/* Three clips side by side on a laptop; the tabs only exist for the phone,
   where they show one clip at a time (2026-09-30). */
.shear-clips {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--optic-ring-soft);
}

.shear-tabs {
  display: none;
  flex-wrap: wrap;
  gap: 1px;
  margin-bottom: 1px;
  background: var(--optic-ring-soft);
}

.shear-tabs button {
  flex: 1 1 auto;
  min-height: 44px;
  padding: 12px 18px;
  color: var(--readout-secondary);
  background: var(--optic-surface-1);
  border: 0;
  font-family: var(--font-mono);
  font-size: var(--text-label);
  letter-spacing: 0.04em;
  cursor: pointer;
  transition: color 0.2s var(--ease-out), background 0.2s var(--ease-out);
}

.shear-tabs button:hover {
  color: var(--readout);
  background: var(--optic-surface-2);
}

.shear-tabs button[aria-selected="true"] {
  color: var(--camera-black);
  background: var(--signal-amber);
  font-weight: 600;
}

.shear-stage,
.live-stage {
  margin: 0;
  background: var(--optic-surface-1);
  border: 1px solid var(--optic-ring-soft);
}

.shear-stage video,
.live-stage video {
  display: block;
  width: 100%;
  height: auto;
  background: var(--camera-black);
}

.shear-stage figcaption,
.live-stage figcaption {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  padding: 16px 20px;
  color: var(--readout-secondary);
  font-size: var(--text-label);
}

.shear-clip-label,
.live-stage figcaption span:first-child {
  color: var(--readout-tertiary);
  font-family: var(--font-mono);
  font-size: var(--text-fine);
  letter-spacing: 0.14em;
}

.shear-stage figcaption {
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr);
  grid-template-rows: auto auto;
  gap: 4px 14px;
  align-items: center;
}

.shear-object {
  grid-row: 1 / 3;
  width: 64px;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  box-shadow: inset 0 0 0 1px var(--optic-ring);
}

/* The live clip closes the page at full content width: the tablet feed is
   the content. */
.live-layout {
  display: grid;
  gap: 1px;
}

.shear-legend {
  max-width: 620px;
  margin: 18px 0 0;
  color: var(--readout-tertiary);
  font-size: var(--text-label);
  line-height: 1.6;
}

@media (max-width: 900px) {
  .shear-layout {
    grid-template-columns: minmax(0, 1fr);
  }

  .shear-tabs {
    display: flex;
  }

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

  .shear-stage:not(.is-active) {
    display: none;
  }
}

/* Why simple: the mechanism band's closing module. Each dt/dd pair is
   wrapped so the grid never splits a title from its line. */
.principles {
  margin-top: clamp(56px, 7vw, 96px);
}

.principles-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 24px 28px;
  margin: 0;
  max-width: 880px;
}

.principles-list dt {
  margin: 0 0 6px;
  color: var(--signal-amber);
  font-family: var(--font-sans);
  font-size: var(--text-title);
  font-weight: 550;
  letter-spacing: 0;
  line-height: 1.25;
}

.principles-list dd {
  margin: 0;
  color: var(--readout-secondary);
  font-family: var(--font-sans);
  font-size: var(--text-label);
  letter-spacing: 0;
  line-height: 1.5;
}
