/* Signet by ASPIRIUM — coming-soon page.
   Mode B tokens as custom properties (web_build_brief_v1_1 §9; hexes provisional until identity lock).
   Technical-drawing details only: mono labels, generous void. No glows, gradients, shimmers or hover
   sparkle — the only light on the page is inside the render. Divider rules removed 2026-09-07 (Eric). */

/* Three faces, all SIL OFL 1.1: free for commercial use and web embedding, never sellable alone,
   licence text shipped beside the files in assets/fonts/. Built by dev/build-fonts.sh. */
@font-face {
  /* display: labels, the submit control, the footer, the scroll cue */
  font-family: "ASPIRIUM";
  font-weight: 300;
  font-style: normal;
  font-display: swap;                       /* the mono labels never invisible-text */
  src: url("../assets/fonts/ASPIRIUM-Light.65eee249.woff2") format("woff2");
}
@font-face {
  /* the lockup (Eric, 2026-09-09). Variable opsz 7..72 + wght 200..900 from one file: the lockup
     runs from ~24 px to ~64 px in one composition, so optical sizing earns its bytes here. */
  font-family: "Literata";
  font-weight: 200 900;
  font-style: normal;
  font-display: swap;
  src: url("../assets/fonts/Literata-var.39654aa7.woff2") format("woff2-variations"),
       url("../assets/fonts/Literata-var.39654aa7.woff2") format("woff2");
}
@font-face {
  /* body and UI (Eric, 2026-09-09), replacing the provisional Source Code Pro. Variable wght
     200..900; its optical-size axis is pinned at 20 because body copy sits at one size. */
  font-family: "Source Serif 4";
  font-weight: 200 900;
  font-style: normal;
  font-display: swap;
  src: url("../assets/fonts/SourceSerif4-var.77631a25.woff2") format("woff2-variations"),
       url("../assets/fonts/SourceSerif4-var.77631a25.woff2") format("woff2");
}

:root {
  --field: #000000;                          /* ruled 2026-09-07: pure black (was #141414) */
  --field-2: #1D1D1B;
  --text: #EAE7E1;
  --muted: #9B968C;
  --metal: #B08D57;
  --metal-2: #C9A36B;
  --band-h: clamp(360px, 48vh, 640px);      /* R2: desktop 45–50 vh, tuned live (dev/tune.html) */
  --rule: color-mix(in srgb, var(--muted) 30%, var(--field));
  --display: "ASPIRIUM", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --body: "Source Serif 4", "Source Serif Pro", Georgia, "Times New Roman", serif;
  --lockup: "Literata", Georgia, "Times New Roman", serif;
  --col: 44rem;
  --col-mark: 52rem;                        /* the lockup runs wider than the text column */
  --gutter: 1.5rem;
  --light: var(--muted);                    /* the one accent; moves to --metal when the wordmark lights */
}
:root[data-light="warm"] { --light: var(--metal); }

/* R4: on phones the band is ~1:1 and never more than ~60% of the screen — the camera is
   vertical-fit, so a full-portrait band would crop the ring's sides. The hero panel around it
   is a full screen; R3 (touch-action: pan-y) is what lets a finger on the band reach panel 2. */
@media (max-width: 767px) {
  :root { --band-h: min(100vw, 60vh); --col-mark: 44rem; }
  @supports (height: 1svh) { :root { --band-h: min(100vw, 60svh); } }
}

*, *::before, *::after { box-sizing: border-box; }
html { color-scheme: dark; background: var(--field); -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--field);
  color: var(--text);
  font: 400 1rem/1.6 var(--body);
  font-feature-settings: "kern";
  min-height: 100vh;
}
[hidden] { display: none !important; }
:focus-visible { outline: 1px solid var(--muted); outline-offset: 3px; }
::selection { background: var(--muted); color: var(--field); }

/* ---- panels: one screen each (Eric, 2026-09-09) ----
   The hero sticks while the capture panel scrolls up over it; the hero's contents drift and fade
   against that, which is the parallax. --p (0…1 across the first screen) is set by js/main.js. */
.page { position: relative; }
.panel { position: relative; }
.panel--hero {
  position: sticky; top: 0; z-index: 0;
  height: 100vh;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: clamp(1.5rem, 4vh, 3rem);
  overflow: hidden;
}
.hero__inner {
  position: relative;                       /* the drag hint is placed against this box */
  width: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: clamp(1.5rem, 4vh, 3rem);
  transform: translate3d(0, calc(var(--p, 0) * var(--drift, 9) * -1vh), 0);
  opacity: calc(1 - var(--pf, 0) * var(--fade, .95));   /* --pf is --p remapped to finish early */
  will-change: transform, opacity;
}
.cue {
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: calc(1.25rem + env(safe-area-inset-bottom, 0px));
  margin: 0; display: flex; line-height: 0;
  color: var(--muted);
  opacity: calc(1 - var(--p, 0) * var(--cue-fade, 3));
  pointer-events: none;
}
.panel--capture {
  z-index: 4;                               /* opaque, so it covers the hero, and the live ring (z 2) as it leaves */
  background: var(--field);
  min-height: 100vh;
  /* the form sits in the middle of the screen, both axes (Eric, 2026-09-09 pm); the footer is
     taken out of flow so it cannot pull the centring off-axis */
  display: flex; align-items: center; justify-content: center;
  padding: 5rem var(--gutter);
}
.panel--capture .sheet { padding: 0; }
.panel--capture .foot { position: absolute; left: 0; right: 0; bottom: 0; }
@supports (height: 1svh) {
  .panel--hero { height: 100svh; }
  .panel--capture { min-height: 100svh; }
}
@media (prefers-reduced-motion: reduce) {
  .hero__inner { transform: none; opacity: 1; }
  .cue { opacity: 1; }
}

/* ---- about: the live ring and the intro (2026-09-30, after neoconda.com) ----
   The canvas is fixed over the whole page and draws nothing until the scroll starts (js/ring3d.js).
   The panel is taller than the screen and its inside is sticky: a stretch where the ring stands
   still on the left to be turned, before the capture panel comes up over both. */
.ring3d {
  position: fixed; inset: 0; width: 100%; height: 100%;
  z-index: 2; pointer-events: none; opacity: 0;
}
/* The lit dot matrix (js/cursor-fx.js): over every panel, blended by difference, so the dots show
   orange on the black ground and text under a dot turns to its complement. */
.pixels {
  position: fixed; inset: 0; width: 100%; height: 100%;
  z-index: 10; pointer-events: none; mix-blend-mode: difference;
}
.panel--about { z-index: 1; background: var(--field); height: 170vh; }
.about__inner {
  position: sticky; top: 0; height: 100vh;
  display: grid; grid-template-columns: 1fr 1fr; align-items: center;
  gap: clamp(2rem, 5vw, 6rem);
  max-width: 88rem; margin: 0 auto; padding: 0 clamp(1.5rem, 6vw, 7rem);
}
.about__stage { position: relative; height: min(70vh, 40vw); touch-action: pan-y; user-select: none; -webkit-user-select: none; }
.about__stage.is-live { cursor: grab; }
.about__stage.is-dragging { cursor: grabbing; }
/* no live ring (no WebGL2, or it failed): the film's last frame stands in */
.no-ring3d .about__stage {
  background: url("../assets/poster/gemtronic-end-pose-1x1.a959e4d6.jpg") center / contain no-repeat;
  -webkit-mask-image: radial-gradient(closest-side, #000 70%, transparent);
  mask-image: radial-gradient(closest-side, #000 70%, transparent);
}
.about__copy { position: relative; z-index: 3; max-width: 34rem; }
/* each line arrives from the right in turn as the ring lands; --ap (0…1) is set by js/ring3d.js */
.about__copy > * {
  --o: clamp(0, (var(--ap, 1) - var(--i, 0) * .18) / .46, 1);
  opacity: var(--o);
  transform: translate3d(calc((1 - var(--o)) * 2.5rem), 0, 0);
}
.about__copy > :nth-child(2) { --i: 1; }
.about__copy > :nth-child(3) { --i: 2; }
.about__copy > :nth-child(4) { --i: 3; }
.eyebrow {
  margin: 0 0 1.25rem;
  font: 400 .8125rem/1 var(--body); letter-spacing: .18em; text-transform: uppercase; color: var(--metal);
}
.about__title {
  margin: 0 0 1.5rem;
  font: 300 clamp(2.25rem, 4.4vw, 4rem)/1.08 var(--lockup); letter-spacing: -.01em; color: var(--text);
  text-wrap: balance;
}
.about__body { margin: 0; color: var(--muted); }
.about__hint {
  margin: 2rem 0 0;
  font: 400 .6875rem/1 var(--body); letter-spacing: .18em; text-transform: uppercase; color: var(--muted);
}
.no-ring3d .about__hint { display: none; }
@media (max-width: 767px) {
  .panel--about { height: 150svh; }
  .about__inner {
    height: 100svh; grid-template-columns: 1fr; grid-template-rows: auto auto;
    align-content: center; gap: 1.5rem; padding: 0 var(--gutter);
  }
  .about__stage { height: 42svh; }
  .about__title { margin-bottom: 1rem; }
  .about__hint { margin-top: 1.25rem; }
}
@media (prefers-reduced-motion: reduce) {
  .about__copy > * { transform: none; }
}

/* ---- features: the ring at the centre, the list passing on both sides (2026-10-01, after
   neoconda.com). The stage is the ring's place; js/ring3d.js follows its box. Odd items run down
   the left, even down the right, a row each. The item nearest the middle of the screen is lit
   (js/features.js); the rest wait in the dark. */
.panel--features { z-index: 1; background: var(--field); padding: 18vh 0 30vh; }
.features__head { text-align: center; padding: 0 var(--gutter); margin: 0 auto 12vh; max-width: 52rem; }
.features__head .eyebrow { margin-bottom: 1.5rem; }
.features__title {
  margin: 0; font: 300 clamp(2rem, 4vw, 3.5rem)/1.1 var(--lockup); letter-spacing: -.01em;
  color: var(--text); text-wrap: balance;
}
.features__body {
  --fs-h: min(64vh, 34vw);
  display: grid; grid-template-columns: 1fr minmax(0, var(--fs-h)) 1fr;
  grid-template-rows: repeat(9, 23vh);
  column-gap: clamp(1.5rem, 4vw, 5rem);
  max-width: 92rem; margin: 0 auto; padding: 0 clamp(1.5rem, 5vw, 6rem);
}
.features__stage {
  grid-column: 2; grid-row: 1 / -1; align-self: start;
  position: sticky; top: calc(50vh - var(--fs-h) / 2); height: var(--fs-h);
}
.features__list { display: contents; list-style: none; }
.features__list > li { align-self: center; max-width: 22rem; }
.features__list > li:nth-child(odd) { grid-column: 1; justify-self: end; }
.features__list > li:nth-child(even) { grid-column: 3; justify-self: start; }
/* a zigzag, each item half a row below the last, so each one in turn crosses the middle of the
   screen alone and gets lit (side by side, the left one always won) */
.features__list > li:nth-child(1) { grid-row: 1 / span 2; }
.features__list > li:nth-child(2) { grid-row: 2 / span 2; }
.features__list > li:nth-child(3) { grid-row: 3 / span 2; }
.features__list > li:nth-child(4) { grid-row: 4 / span 2; }
.features__list > li:nth-child(5) { grid-row: 5 / span 2; }
.features__list > li:nth-child(6) { grid-row: 6 / span 2; }
.features__list > li:nth-child(7) { grid-row: 7 / span 2; }
.features__list > li:nth-child(8) { grid-row: 8 / span 2; }
.feat {
  display: grid; grid-template-columns: auto 1fr; column-gap: 1.1rem; row-gap: .45rem; align-items: center;
  width: 100%; padding: .75rem .5rem; margin: 0; border: 0; background: none; text-align: left;
  color: inherit; font: inherit; cursor: pointer;
  opacity: .32; transition: opacity .35s ease;
}
.feat:hover, .feat.is-active { opacity: 1; }
.feat:focus-visible { outline: 1px solid var(--muted); outline-offset: 4px; }
.feat__n {
  grid-row: 1 / span 2; align-self: start;
  display: grid; place-items: center; width: 2.6rem; height: 2.6rem;
  border: 1px solid var(--rule); font: 400 .8125rem/1 var(--body); letter-spacing: .08em; color: var(--muted);
  transition: border-color .35s ease, color .35s ease;
}
.feat.is-active .feat__n { border-color: var(--metal); color: var(--metal); }
.feat__t { font: 400 1.25rem/1.2 var(--lockup); color: var(--text); }
.feat__d { grid-column: 2; font-size: .9375rem; line-height: 1.5; color: var(--muted); }
@media (max-width: 767px) {
  .panel--features { padding: 12vh 0 16vh; }
  .features__head { margin-bottom: 4vh; }
  .features__body {
    --fs-h: 36svh;
    grid-template-columns: 1fr; grid-template-rows: none; row-gap: 0; padding: 0 var(--gutter);
  }
  .features__stage { grid-column: 1; grid-row: 1; top: 8svh; z-index: 0; }
  .features__list > li, .features__list > li:nth-child(n) {
    grid-column: 1; grid-row: auto; justify-self: stretch; max-width: none;
    padding: 6svh 0;
  }
}
@media (prefers-reduced-motion: reduce) {
  .feat, .feat__n { transition: none; }
}

/* ---- hero band ---- */
.band {
  position: relative;
  width: 100%;
  height: var(--band-h);
  background: var(--field);                 /* black until the viewer is ready; the intro opens on black anyway */
  overflow: hidden;
}
.band__mount, .band__poster { position: absolute; inset: 0; }
.band__mount > canvas, .band__mount > iframe, .band__mount > .stub, .band__mount > .film {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block; border: 0;
}
.stub { overflow: hidden; touch-action: pan-y; user-select: none; -webkit-user-select: none; }
.stub img { width: 100%; height: 100%; object-fit: contain; display: block; opacity: 0; }
.band__poster { display: none; }
.band[data-state="poster"] .band__poster { display: block; }
.band__poster img { width: 100%; height: 100%; object-fit: contain; display: block; background: transparent; }
/* The film (2026-09-30) is square and its background is a gradient, black at the top and grey at the
   bottom. A round fade sized to the square melts that background into the page's black, so it reads
   as a spotlight rather than a box. Solid to 62% of the radius, which keeps the whole ring clear. */
/* Bigger and with more glow (Linzhi, 2026-09-30): on desktop the film is drawn 1.3x the band and
   spills past it. Only the faded glow spills; the ring itself still ends above the lockup. Phones
   stay at 1x, because the band is already the full screen width and the glow would hit its edges. */
.band { --film-scale: 1.3; }
@media (max-width: 767px) { .band { --film-scale: 1; } }
.band:has(.film), .band[data-state="poster"] { overflow: visible; }
.film { object-fit: contain; background: transparent; }
.film, .band__poster img {
  transform: scale(var(--film-scale));
  --spot: radial-gradient(circle calc(var(--band-h) / 2) at 50% 50%,
          #000 70%, rgba(0,0,0,.84) 77%, rgba(0,0,0,.5) 86%, rgba(0,0,0,.16) 94%, transparent 100%);
  -webkit-mask-image: var(--spot); mask-image: var(--spot);
}

/* ---- the capture panel's column ---- */
.sheet { width: 100%; max-width: var(--col); margin: 0 auto; padding: 2rem var(--gutter) 3rem; }

.serial {
  margin: 0 0 2.5rem;
  display: flex; flex-wrap: wrap; column-gap: .75em; row-gap: .25em;
  font: 300 .9375rem/1.5 var(--display);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
}
.serial > span:has(+ span:not(:empty))::after { content: "\2014"; margin-left: .75em; }
.serial .slot:empty { display: none; }     /* R6: OPEN slots exist in the markup and render nothing */

.headline {
  margin: 0 0 1.5rem;
  font: 300 clamp(1.75rem, 4vw, 3.25rem)/1.15 var(--display);
  letter-spacing: .09em;
  text-transform: uppercase;
  text-wrap: balance;
  color: var(--text);
}
.lede { margin: 0 0 2.5rem; max-width: 36rem; }

/* ---- drag hint ----
   Ported from the pipeline's check page. It lands in the void the lockup's --mark-drop opens up:
   the band occupies 0..--band-h, the gap runs from there to --band-h * (1 + drop), so the centre
   of that gap is --band-h * (1 + drop/2). The check page's pill, blur and drop-shadows are all
   dropped — the brand law allows no glow, and white on black does not need one. */
.drag {
  position: absolute; left: 50%;
  top: calc(var(--band-h) * (1 + var(--mark-drop, .25) / 2));
  transform: translate(-50%, -50%);
  display: flex; flex-direction: column; align-items: center; gap: .5rem;
  color: var(--muted);
  opacity: 0; visibility: hidden;
  transition: opacity .6s ease, visibility 0s linear .6s;
  pointer-events: none;                     /* the ring underneath keeps every gesture */
}
.drag.is-on { opacity: 1; visibility: visible; transition: opacity .6s ease; }
.drag__pointer { display: block; animation: drag-swipe 2.8s cubic-bezier(.45, 0, .55, 1) infinite; }
.drag__label { font: 400 .6875rem/1 var(--body); letter-spacing: .18em; text-transform: uppercase; }
@keyframes drag-swipe {
  0%, 6%     { transform: translateX(-44px) rotate(-9deg); }
  50%        { transform: translateX(44px)  rotate(9deg); }
  94%, 100%  { transform: translateX(-44px) rotate(-9deg); }
}
@media (prefers-reduced-motion: reduce) { .drag__pointer { animation: none; } }

/* ---- the lockup: live text in Literata, below the band and clear of the render ---- */
.mark {
  /* dropped by 25% of the band's height (Eric, 2026-09-09 pm). The hero centres its contents, so
     this opens the gap by that much: the ring rises by half of it and the lockup falls by half. */
  margin: calc(var(--band-h) * var(--mark-drop, .25)) 0 0;
  max-width: min(92vw, var(--col-mark));
  text-align: center; color: var(--text);          /* both lines white; the muted sub line is retired */
  font-family: var(--lockup); font-weight: 300; font-style: normal;
  font-optical-sizing: auto;                       /* Literata's opsz axis: text cut small, display cut large */
  user-select: none; -webkit-user-select: none;
}
.mark__line { display: block; white-space: nowrap; }
/* sizes swapped between the two lines, then both halved (Eric, 2026-09-09) */
.mark__line--sub {
  font-size: clamp(1.175rem, 4.3vw, 2.625rem);
  letter-spacing: .09em;
  line-height: 1.2;
}
.mark__line--name {
  font-size: clamp(.525rem, 1.55vw, 1rem);
  letter-spacing: .17em;
  line-height: 1.05;
  margin-top: 1em;                                 /* doubled from .5em (Eric); em here is this line's own size */
  text-indent: .17em;                              /* balance the trailing letter-space so the line reads centred */
}

/* One cell per character (js/mark.js). The real glyph alone drives layout; the code glyph rides
   over it absolutely, so nothing reflows at any size and no width is ever measured. */
.ch { position: relative; display: inline-block; }
.ch.is-pending .ch__real,
.ch.is-fx .ch__real { visibility: hidden; }
.ch__fx {
  position: absolute; left: 0; top: 0; width: 100%;
  text-align: center; letter-spacing: 0; pointer-events: none;
}

/* The opening beat: nothing is lit until the ring's animation starts and the decode's first frame
   draws. The brief's intro already opens on 1.2 s of black, so the cue waits with the lockup.
   Set by the inline script in <head> so there is no flash before js/main.js runs, and lifted by
   main.js — either on the decode's first frame or, if the effect is not live, immediately. */
:root.is-opening .mark,
:root.is-opening .cue { opacity: 0; }

.capture { max-width: 36rem; margin: 0 auto; position: relative; text-align: center; }
.capture__row { justify-content: center; }
.label {
  display: block; margin-bottom: .75rem;
  font: 400 .8125rem/1 var(--body); letter-spacing: .16em; text-transform: uppercase; color: var(--muted);
}
.capture__row { display: flex; }
/* Field and submit share one pill treatment (Eric, 2026-09-09): the same grey at rest, both going
   white on hover and on focus. The border is the focus indicator, so `outline: none` is safe only
   because grey-to-white is a large, obvious contrast step. */
.capture input[type="email"] {
  flex: 1 1 auto; min-width: 0; height: 3rem; padding: 0 .875rem;
  background: transparent; border: 1px solid var(--rule); border-radius: 0;
  color: var(--text); font: 400 1rem var(--body); outline: none;
  transition: border-color .18s ease;
}
.capture input[type="email"]:hover,
.capture input[type="email"]:focus { border-color: #fff; outline: none; }
/* Its own line beneath the consent line, twice the padding (Eric, 2026-09-09). The pill now matches
   the field's grey and goes white on hover and focus, exactly as the field does. The submit no
   longer carries the brief's §2 warm-accent wiring — .received is the only element still on --light. */
.submit {
  display: block; margin: 1.75rem auto 0;
  /* pill and label both at 75% of their previous size (Eric, 2026-09-09): 48 -> 36 px tall,
     40 -> 30 px of side padding, 13 -> 9.75 px of type. */
  height: 2.25rem; padding: 0 1.875rem;
  background: transparent; border: 1px solid var(--rule); border-radius: 0;
  color: var(--muted);                                  /* the consent line's grey */
  font: 400 .609375rem/1 var(--body); letter-spacing: .16em; text-transform: uppercase;
  cursor: pointer;
  transition: border-color .18s ease, color .18s ease;
}
/* label brightens with the pill: a white-bordered control with grey type reads half-lit */
.submit:hover,
.submit:focus-visible { border-color: #fff; color: #fff; outline: none; }
.submit:disabled { cursor: default; opacity: .6; }
.consent { margin: 1rem 0 0; font-size: .8125rem; color: var(--muted); }
.status { margin: .75rem 0 0; min-height: 1.6em; font-size: .875rem; color: var(--text); }
.received {
  margin: 0; padding: .9rem 0;
  font: 400 1rem/1.5 var(--body); letter-spacing: .14em; text-transform: uppercase; color: var(--light);
}
.hp { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }

/* ---- 6. footer ---- */
/* bottom-left and bottom-right corners of the panel, half the previous size (Eric, 2026-09-09) */
.foot {
  max-width: none; margin: 0;
  padding: 1.25rem var(--gutter) calc(1.25rem + env(safe-area-inset-bottom, 0px));
  display: flex; justify-content: space-between; align-items: flex-end; gap: 1rem;
  font: 400 .375rem/1.6 var(--body); letter-spacing: .14em; text-transform: uppercase; color: var(--muted);
}
.foot a { color: inherit; text-decoration: none; border-bottom: 1px solid var(--rule); }
.foot a:hover { color: var(--text); }
.foot .slot:empty { display: none; }

/* short desktop viewports: keep the form above the fold at ≥ 768 px tall (§2 item 5) */
/* short desktop viewports: the band's clamp already gives way, so only the rhythm tightens */
@media (min-width: 768px) and (max-height: 820px) {
  .sheet { padding-top: 1.25rem; }
  .serial { margin-bottom: 1.25rem; font-size: .875rem; }
  .headline { margin-bottom: .75rem; line-height: 1.1; font-size: clamp(1.75rem, min(4vw, 6.4vh), 3.25rem); }
  .lede { margin-bottom: 1.25rem; }
  .label { margin-bottom: .5rem; }
  .consent { margin-top: .75rem; }
}
@media (max-width: 480px) {
  .serial { font-size: .8125rem; letter-spacing: .12em; }
}
@media (prefers-reduced-motion: reduce) {
  .submit, .stub, .stub img { transition: none !important; }
}

/* ---- contact and pre-order (2026-10-11, Linzhi) ----
   Contact sits under the capture form, not in the footer: the footer type is 6 px and an address
   has to be readable. The pre-order page reuses the sheet column and the submit pill. */
.contact {
  max-width: 36rem; margin: 3.5rem auto 0; text-align: center;
  font-size: .875rem; color: var(--muted);
}
.contact .label { margin-bottom: .75rem; }
.contact__list { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem 2rem; }
.contact a, .link { color: var(--text); text-decoration: none; border-bottom: 1px solid var(--rule); transition: border-color .18s ease; }
.contact a:hover, .contact a:focus-visible, .link:hover, .link:focus-visible { border-color: #fff; outline: none; }
.preorder-cta { margin: 2.5rem 0 0; text-align: center; font-size: .875rem; color: var(--muted); }
a.submit { display: inline-flex; align-items: center; text-decoration: none; }

.panel--preorder { min-height: 100vh; display: flex; flex-direction: column; }
@supports (height: 1svh) { .panel--preorder { min-height: 100svh; } }
.panel--preorder .sheet { flex: 1; padding-top: clamp(3rem, 10vh, 7rem); }
.preorder__body { margin: 0 0 2.5rem; color: var(--muted); max-width: 36rem; }
.terms { margin: 0 0 2.5rem; border-top: 1px solid var(--rule); }
.terms > div {
  display: flex; justify-content: space-between; gap: 1rem;
  padding: .875rem 0; border-bottom: 1px solid var(--rule);
}
.terms dt { font: 400 .8125rem/1.6 var(--body); letter-spacing: .16em; text-transform: uppercase; color: var(--muted); }
.terms dd { margin: 0; text-align: right; color: var(--text); }
.preorder__action { text-align: center; }
.preorder__action .submit { margin-top: 0; }
.preorder .contact { margin-top: 4rem; }
.foot--plain { font-size: .6875rem; }
.terms .was { color: var(--muted); margin-right: .4em; }
.terms .note { display: block; font-size: .8125rem; color: var(--metal); }

/* pre-order form: same field and pill treatment as the capture form */
.reserve { position: relative; text-align: center; }
.reserve__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem 1rem; text-align: left; }
.field { display: block; min-width: 0; }
.field .label { margin-bottom: .5rem; }
.field--wide { grid-column: 1 / -1; }
.reserve input:not([type="hidden"]), .reserve select {
  width: 100%; height: 3rem; padding: 0 .875rem;
  background: transparent; border: 1px solid var(--rule); border-radius: 0;
  color: var(--text); font: 400 1rem var(--body); outline: none;
  transition: border-color .18s ease;
}
.reserve select { appearance: none; -webkit-appearance: none; cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 1.15rem) 50%, calc(100% - .8rem) 50%; background-size: .35rem .35rem; background-repeat: no-repeat; }
.reserve select option { background: var(--field-2); color: var(--text); }
.reserve input:hover, .reserve input:focus, .reserve select:hover, .reserve select:focus { border-color: #fff; }
.reserve .submit { margin-top: 2rem; }
@media (max-width: 480px) { .reserve__grid { grid-template-columns: 1fr; } }

/* top navigation (2026-10-11, Linzhi). Fixed over every panel; waits with the lockup during the
   opening beat so nothing is lit before the ring. */
.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 20;
  display: flex; justify-content: center; gap: clamp(1.25rem, 4vw, 2.75rem);
  padding: calc(1.1rem + env(safe-area-inset-top, 0px)) var(--gutter) 1.1rem;
  background: var(--field);                 /* solid, not a fade: the brand allows no gradients, and the page is black anyway */
  transition: opacity .6s ease;
}
.nav a {
  color: var(--muted); text-decoration: none;
  font: 400 .75rem/1 var(--body); letter-spacing: .18em; text-transform: uppercase;
  padding: .35rem 0; border-bottom: 1px solid transparent;
  transition: color .18s ease, border-color .18s ease;
}
.nav a:hover, .nav a:focus-visible, .nav a[aria-current="page"] { color: var(--text); border-color: var(--rule); outline: none; }
:root.is-opening .nav { opacity: 0; }
html { scroll-behavior: smooth; }
#about, #contact { scroll-margin-top: 4rem; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } .nav { transition: none; } }
.contact__note { margin: .75rem 0 0; min-height: 1.4em; font-size: .8125rem; color: var(--metal); }
