/* ============================================================
 * THE SITE V4 SURFACE SHEET. One stylesheet, every cut surface.
 * ============================================================
 *
 * WHY THIS FILE EXISTS. OEG-DESIGN-2026-11-the-twelve-surfaces names twelve
 * surfaces and landed one of them, /commerce, as the worked exemplar. Cutting
 * the rest by copying that page's style block would put the same nine hundred
 * lines in nine files, and the orbit direction's own warning is exactly about
 * that: light now does the work borders and shadows used to do, and a very
 * close dark value written out per page drifts until two surfaces that should
 * be the same plane are visibly not, with nobody able to see it because they
 * sit on different routes. So the shared half of the surface is here, once, and
 * a page's own <style> block carries only what is particular to that page.
 *
 * WHAT IT DOES NOT OWN. Colour, type, motion and the camera's geometry all
 * still come from /_shared/site-v4-tokens.css, scoped under .site-v4. Nothing
 * below writes a brand value, a duration or an easing: every one redirects
 * through the --v4-* layer, so re-pointing the token file re-skins and re-times
 * every surface at once. The wordmark is /_shared/oddly-mark.css and is not
 * redefined here; a surface on ink re-points that sheet's ink property and
 * leaves the gold terminal period alone.
 *
 * THE TWO RENDER DEFECTS THIS FILE IS BUILT NOT TO REGRESS, both found by a
 * real browser on the front door and both silent when they are wrong:
 *
 *   1. @keyframes hold OPENS AT OPACITY 1. Shot one is the frame a reader sees
 *      before they have scrolled at all. A landing frame that fades in from
 *      nothing is a page with no first impression.
 *   2. overflow:hidden BELONGS ON .stage AND NEVER ON .orbit. The stage is the
 *      sticky element and may clip itself; a clipping ANCESTOR silently kills
 *      position:sticky, and the failure is silent because the camera simply
 *      stops sticking and nothing goes red.
 *
 * THE PHONE CUT is at the bottom of this file, under its own heading, with the
 * reasoning beside it.
 * ============================================================ */

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
/* The camera's only structural requirement: a sticky stage cannot work inside a
   scroll container that clips, so nothing between html and .stage may carry
   overflow hidden. */
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body {
  background: var(--v4-canvas);
  color: var(--v4-ink);
  font-family: var(--v4-font-text);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
a { color: inherit; }
:focus-visible { outline: none; box-shadow: var(--v4-focus); border-radius: var(--v4-radius); }
.mono { font-family: var(--v4-font-figures); }
.eyebrow { font-size: 0.6875rem; font-weight: 600; letter-spacing: var(--v4-tracking-label); text-transform: uppercase; }
/* A value the estate cannot yet compute renders bracketed and visibly muted, so
   a placeholder can never be mistaken for a reading. The brackets come from the
   markup, the mute from here; the script removes the attribute the day the value
   is real, never before. */
[data-bracketed] { color: var(--v4-ink-muted); font-weight: 400; }
.vh { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ---- Nav: chrome floating on the field, with no ground of its own. ---- */
.nav { position: absolute; z-index: 3; top: 0; left: 0; right: 0; display: flex; align-items: center; justify-content: space-between; gap: var(--oddly-space-5); padding: 1.75rem var(--v4-gutter); flex-wrap: wrap; }
/* The one line of the mark a surface owns: the word goes cream on ink by
   re-pointing the sheet's ink property. The accent glyph is not touched, so the
   terminal period stays the ruled gold from the file that owns it. */
.brand { display: flex; align-items: baseline; gap: var(--oddly-space-4); --oddly-mark-ink: var(--v4-ink); }
/* Colour and form are the mark and live in oddly-mark.css. Size and family are
   layout and live here, which is the split that file states about itself. */
.oc-mark { font-family: var(--v4-font-text); font-size: 1.375rem; font-weight: 600; letter-spacing: -0.01em; text-decoration: none; }
.tagline { font-size: 0.6875rem; letter-spacing: var(--v4-tracking-label); text-transform: uppercase; color: var(--v4-ink-muted); }
.nav-links { display: flex; gap: 2rem; font-size: 0.875rem; }
.nav-links a { color: var(--v4-ink-secondary); text-decoration: none; transition: color var(--v4-motion-fast) var(--v4-ease-enter); }
.nav-links a:hover, .nav-links a[aria-current="page"] { color: var(--v4-ink); }
.nav-actions { display: flex; gap: 0.75rem; align-items: center; }
.nav-actions .signin { font-size: 0.875rem; color: var(--v4-ink-secondary); text-decoration: none; padding: 0.625rem 0.875rem; }
.btn { font-size: 0.875rem; font-weight: 600; color: var(--v4-canvas); background: var(--v4-accent); padding: 0.625rem 1rem; border-radius: var(--v4-radius); text-decoration: none; transition: background-color var(--v4-motion-fast) var(--v4-ease-enter); }
.btn:hover { background: var(--v4-accent-hover); }

/* ================= THE ORBIT =================
   Static composition first. This is the whole page for a browser with no
   scroll-driven animations, for a visitor who asked for less motion, and for
   every phone. */
.orbit { position: relative; }
/* See the header note: the clip is on the STAGE, in the base rule and not only
   inside the camera gate, because the bloom is wider than the viewport by
   design and the sideways scroll was measured in the STATIC fallback. */
.stage { position: relative; overflow: hidden; display: flex; flex-direction: column; gap: 4.5rem; padding: 9rem var(--v4-gutter) 5rem; }
.sky { position: absolute; z-index: 0; inset: 0; display: grid; place-items: center; overflow: hidden; pointer-events: none; }
.sky svg { width: 100%; height: 100%; opacity: 0.42; }
.sky .land { stroke: var(--v4-map-land); fill: none; }
.sky .pt { fill: var(--v4-accent-2); }
.sky .pt-t { fill: var(--v4-grey); }
.veil { position: absolute; z-index: 1; inset: 0; background: var(--v4-scrim); pointer-events: none; }
/* The landing light. One source per shot is the whole depth model: no borders,
   no drop shadows, no card chrome. It is lit faintly from the first shot,
   because an establishing shot has to answer the move before it is asked; the
   animation brightens it on arrival and never introduces it. */
.bloom { position: absolute; z-index: 1; left: 50%; top: 50%; width: 46vmax; height: 46vmax; transform: translate(-50%, -50%); border-radius: 50%; background: radial-gradient(circle, var(--v4-glow) 0%, transparent 62%); opacity: 0.34; pointer-events: none; }
/* The floor under the lit object: the one place a plane is stated by light
   rather than by a border. */
.floor { position: absolute; z-index: 1; left: 0; right: 0; bottom: 0; height: 46vh; background: linear-gradient(to top, var(--v4-glow-white), transparent); opacity: 0; pointer-events: none; }
.shot { position: relative; z-index: 2; max-width: 44rem; display: flex; flex-direction: column; gap: 1.375rem; }
h1 { margin: 0; font-family: var(--v4-font-display); font-size: var(--v4-display-1); line-height: 0.98; font-weight: 400; letter-spacing: var(--v4-tracking-display); color: var(--v4-ink); max-width: 17ch; }
.lede { margin: 0; max-width: 54ch; font-size: 1.1875rem; line-height: 1.55; color: var(--v4-ink-secondary); }
.shot .eyebrow { color: var(--v4-accent); }
.shot h2 { margin: 0; font-family: var(--v4-font-display); font-size: var(--v4-display-2); line-height: 1.06; font-weight: 400; letter-spacing: var(--v4-tracking-display); color: var(--v4-ink); }
.actions { display: flex; gap: 0.875rem; align-items: center; margin-top: 0.5rem; flex-wrap: wrap; }
.cta { display: inline-block; text-decoration: none; font-size: 0.9375rem; font-weight: 600; color: var(--v4-canvas); background: var(--v4-accent); padding: 0.875rem 1.375rem; border-radius: var(--v4-radius); transition: background-color var(--v4-motion-fast) var(--v4-ease-enter), transform var(--v4-motion-fast) var(--v4-ease-enter); }
.cta:hover { background: var(--v4-accent-hover); transform: translateY(-1px); }
.method-link { font-size: 0.9375rem; color: var(--v4-ink); text-decoration: none; padding: 0.875rem 0.375rem; }
.method-link:hover { color: var(--v4-accent); }

/* The live line carries the base of the establishing shot. Every figure arrives
   from a live read; a cell stays hidden until its figure is real and in horizon,
   and no numeral is in the markup. */
.live-line { display: flex; flex-wrap: wrap; gap: 1.75rem; font-size: 0.8125rem; color: var(--v4-ink-secondary); letter-spacing: 0.01em; }
.live-line b { font-weight: 400; color: var(--v4-accent); }
.live-line i { font-style: normal; color: var(--v4-ink); }
.live-line em { font-style: normal; color: var(--v4-premium); }
/* A day root is 64 hex characters with nowhere to break, and at 390 that one
   word is wider than the viewport. The flex item may shrink below its one word
   and the word may break anywhere. */
.live-line > span { min-width: 0; }
.live-line em { word-break: break-all; }
.note { margin: 0; font-size: 0.75rem; color: var(--v4-ink-muted); max-width: 54ch; }
.note b { font-weight: 400; color: var(--v4-ink-secondary); }

/* ---- THE CAMERA. Everything above is the resting page; everything here is the
     travel. Gated three times, outermost first: a browser without view()
     timelines, a visitor who asked for less motion, and a viewport too narrow to
     hold a frame all fall back to the static composition rather than to a broken
     stage, because the absolute positioning that stacks the shots lives inside
     this gate too. The width gate's reasoning is under THE PHONE CUT below. ---- */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    @media (min-width: 700px) {
      /* EVERY RULE IN THIS GATE IS SCOPED UNDER .orbit, AND THAT IS LOAD
         BEARING RATHER THAN TIDY. A surface with no camera (the paper, the map
         at full page, the reference, the price list) still uses .shot for a
         beat of type. An unscoped .shot rule in here sets opacity: 0 on it with
         no animation-name to bring it back, so the hero of every camera-less
         surface renders invisible on a desktop with motion enabled, and the
         only symptom is a blank frame. The camera belongs to the orbit; a page
         with no orbit takes the static composition above. */
      .orbit { height: var(--v4-orbit-track); view-timeline: --orbit block; }
      .orbit .stage { position: sticky; top: 0; height: 100vh; overflow: hidden; display: block; padding: 0; }
      .orbit .shot { position: absolute; z-index: 2; left: var(--v4-gutter); right: var(--v4-gutter); top: 50%; transform: translateY(-50%); max-width: 44rem; opacity: 0; animation-timeline: --orbit; animation-fill-mode: both; animation-timing-function: var(--v4-ease-enter); }
      /* Three cuts. The ranges overlap by a few percent so the stage is never
         empty. A surface whose landing is the sheet rather than a frame on the
         field plays one shot fewer than the front door, which is why the last
         cut runs to 100 rather than handing over to a fourth. */
      .orbit .shot-1 { animation-name: hold; animation-range: contain 0% contain 34%; }
      .orbit .shot-2 { animation-name: cut; animation-range: contain 30% contain 68%; }
      .orbit .shot-3 { animation-name: cut; animation-range: contain 64% contain 100%; }
      /* The push-in. Linear, because a camera on a track does not ease: easing it
         would imply an intent the scroll does not have. The field dims as it
         magnifies so a two degree grid never resolves into blur. A surface with
         no field to fly over sets --v4-orbit-zoom to 1 in its own block, and the
         same rule then moves nothing. */
      .orbit .sky svg { animation: push linear both; animation-timeline: --orbit; animation-range: contain 0% contain 100%; }
      .orbit .sky { animation: arrive linear both; animation-timeline: --orbit; animation-range: contain 46% contain 100%; }
      .orbit .bloom { animation: light linear both; animation-timeline: --orbit; animation-range: contain 52% contain 88%; }
      .orbit .floor { animation: floorlit linear both; animation-timeline: --orbit; animation-range: contain 64% contain 92%; }
    }
  }
}
/* Shot 1 opens ON and only leaves. A landing frame that fades in from nothing is
   a page with no first impression, and it is the one frame the reader sees
   before scrolling at all. */
@keyframes hold { 0% { opacity: 1; } 78% { opacity: 1; } 100% { opacity: 0; } }
@keyframes cut { 0% { opacity: 0; } 14% { opacity: 1; } 78% { opacity: 1; } 100% { opacity: 0; } }
@keyframes push { from { transform: scale(1); } to { transform: scale(var(--v4-orbit-zoom)); } }
@keyframes arrive { from { opacity: 1; } to { opacity: 0.28; } }
@keyframes light { from { opacity: 0.34; } to { opacity: 0.92; } }
@keyframes floorlit { from { opacity: 0; } to { opacity: 1; } }

/* ---- THE FOLD. Sections 2, 3 and 4, type only, on a ground that lightens
     toward the paper register as the reader descends. Three grounds and not
     three panels: a panel is a card, and three cards with icons is the first
     item on the slop list. ---- */
.fold { padding: 5.5rem var(--v4-gutter); display: grid; grid-template-columns: 1fr; gap: 3rem; }
@media (min-width: 900px) { .fold { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4rem; } }
.fold-lede { display: flex; flex-direction: column; gap: 1.125rem; }
.fold h2 { margin: 0; font-family: var(--v4-font-display); font-size: var(--v4-display-2); line-height: 1.04; font-weight: 400; letter-spacing: var(--v4-tracking-display); }
.fold-lede p { margin: 0; font-size: 1.0625rem; line-height: 1.6; max-width: 56ch; }
.lines { border-top: 1px solid currentColor; }
.line { padding: 1.375rem 0; display: grid; grid-template-columns: 9rem 1fr; gap: 1.5rem; }
.line .key { font-family: var(--v4-font-figures); font-size: 0.75rem; }
.line p { margin: 0; font-size: 1.0625rem; line-height: 1.5; }
/* Step 1 of the lightening: still the instrument's ground. */
.fold-1 { background: var(--v4-canvas); color: var(--v4-ink); }
.fold-1 .eyebrow { color: var(--v4-accent); }
.fold-1 .fold-lede p { color: var(--v4-ink-secondary); }
.fold-1 .lines { border-top-color: var(--v4-rule); }
.fold-1 .line { border-bottom: 1px solid var(--v4-rule); }
.fold-1 .line .key { color: var(--v4-ink-muted); }
/* Step 2: dusk. Section 3 sits immediately under section 2 because the swap
   between them is the argument, and the ground moving one step is what makes the
   swap feel like one movement rather than two bands. */
.fold-2 { background: var(--v4-step-dusk); color: var(--v4-ink); }
.fold-2 .eyebrow { color: var(--v4-accent); }
.fold-2 .fold-lede p { color: var(--v4-ink-secondary); }
.fold-2 .lines { border-top-color: var(--v4-rule); }
.fold-2 .line { border-bottom: 1px solid var(--v4-rule); }
.fold-2 .line .key { color: var(--v4-ink-muted); }
/* Step 3: dawn, the last ground before paper. */
.fold-3 { background: var(--v4-step-dawn); color: var(--v4-paper-ink); padding-bottom: calc(5.5rem + var(--v4-sheet-lift)); }
.fold-3 .eyebrow { color: var(--v4-paper-accent); }
.fold-3 .fold-lede p { color: var(--v4-paper-ink-secondary); }
.fold-3 .lines { border-top-color: var(--v4-paper-ink); }
.fold-3 .line { border-bottom: 1px solid var(--v4-paper-rule); }
.fold-3 .line .key { color: var(--v4-paper-ink-muted); }

/* ---- THE SHEET. The one surface change on a page, and it is done as a plane
     with a deep radius rising over the field rather than as a band butted
     against it. Ink is the instrument, paper is the record. A page that changes
     surface twice has made the change decorative. ---- */
.sheet { position: relative; z-index: 4; margin-top: calc(var(--v4-sheet-lift) * -1); border-radius: var(--v4-sheet-radius) var(--v4-sheet-radius) 0 0; overflow: hidden; }
.proof { background: var(--v4-paper); color: var(--v4-paper-ink); padding: 5.5rem var(--v4-gutter); display: flex; flex-direction: column; gap: 2.5rem; }
.proof .eyebrow { color: var(--v4-paper-accent); }
.proof h2 { margin: 0; font-family: var(--v4-font-display); font-size: var(--v4-display-2); line-height: 1.04; font-weight: 400; letter-spacing: var(--v4-tracking-display); max-width: 24ch; }
.proof-lede { display: flex; flex-direction: column; gap: 1.125rem; }
.proof-lede p { margin: 0; font-size: 1.0625rem; color: var(--v4-paper-ink-secondary); max-width: 60ch; }
.proof a { color: var(--v4-paper-accent); }
/* The object on the sheet is ruled type, not a card. A card would need a border,
   and a border is the chrome this direction removed. */
.receipt { margin: 0; border-top: 1px solid var(--v4-paper-ink); display: grid; grid-template-columns: minmax(8rem, 11rem) minmax(0, 1fr); gap: 0 1.5rem; font-size: 0.875rem; }
.receipt dt { padding: 0.55rem 0; border-bottom: 1px solid var(--v4-paper-rule); color: var(--v4-paper-ink-muted); font-family: var(--v4-font-figures); font-size: 0.75rem; }
.receipt dd { margin: 0; padding: 0.55rem 0; border-bottom: 1px solid var(--v4-paper-rule); font-family: var(--v4-font-figures); color: var(--v4-paper-ink); overflow-wrap: anywhere; word-break: break-all; }
.receipt dd[data-bracketed] { color: var(--v4-paper-ink-muted); }
.receipt dd.seal { color: var(--v4-bronze); }
.proof .note { color: var(--v4-paper-ink-muted); max-width: 64ch; }
.proof .note b { color: var(--v4-paper-ink-secondary); }

/* ---- A LIVE ROW LIST. Rows the script writes from a read and nothing else
     writes at all: the markup ships the list empty with its own resting line, so
     an unread endpoint leaves a stated absence rather than an invented row. ---- */
.rows { margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--v4-rule); }
.rows li { display: flex; justify-content: space-between; align-items: baseline; gap: 1.5rem; padding: 0.7rem 0; border-bottom: 1px solid var(--v4-rule); font-size: 0.9375rem; }
.rows li span:first-child { min-width: 0; overflow-wrap: anywhere; }
.rows li span:last-child { font-family: var(--v4-font-figures); font-size: 0.8125rem; color: var(--v4-accent); white-space: nowrap; }
.rows-empty { color: var(--v4-ink-muted); font-size: 0.8125rem; }
.proof .rows { border-top-color: var(--v4-paper-rule); }
.proof .rows li { border-bottom-color: var(--v4-paper-rule); }
.proof .rows li span:last-child { color: var(--v4-paper-accent); }
.proof .rows-empty { color: var(--v4-paper-ink-muted); }

/* ---- A CALL AT REST. A command a reader can paste, set in the figures face
     because it is a literal and not prose. ---- */
.call { margin: 0; font-family: var(--v4-font-figures); font-size: 0.8125rem; line-height: 1.8; overflow-wrap: anywhere; white-space: pre-wrap; color: var(--v4-paper-ink); }
.call b { font-weight: 400; color: var(--v4-paper-accent); }

/* ---- THE FORM. Carried onto the paper register from the page it used to live
     on, unchanged in what it posts. Inputs are 16px so a phone does not zoom the
     viewport on focus, which is the one mobile defect a form can ship. ---- */
.form { display: grid; gap: 0.875rem; max-width: 34rem; }
.form .pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.875rem; }
.form label { display: block; font-size: 0.6875rem; font-weight: 600; letter-spacing: var(--v4-tracking-label); text-transform: uppercase; color: var(--v4-paper-ink-muted); margin-bottom: 0.35rem; }
.form input, .form textarea { width: 100%; font: inherit; font-size: 1rem; padding: 0.7rem 0.8rem; border: 1px solid var(--v4-paper-rule); border-radius: var(--v4-radius); background: var(--v4-paper-2); color: var(--v4-paper-ink); }
.form input:focus, .form textarea:focus { outline: none; border-color: var(--v4-paper-accent); box-shadow: 0 0 0 2px var(--v4-paper); }
.form textarea { resize: vertical; }
.form .send { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
.form button { font: inherit; font-size: 0.9375rem; font-weight: 600; cursor: pointer; color: var(--v4-paper); background: var(--v4-paper-accent); border: 0; border-radius: var(--v4-radius); padding: 0.8rem 1.375rem; }
.form button[disabled] { opacity: 0.6; cursor: default; }
.form .said { font-size: 0.875rem; color: var(--v4-paper-ink-secondary); min-width: 0; }

/* ---- FOOTER AS A LEDGER ROW: the site is in its own corpus. ---- */
.ledger-row { position: relative; z-index: 4; background: var(--v4-canvas); color: var(--v4-ink-secondary); padding: 2.5rem var(--v4-gutter); display: flex; justify-content: space-between; align-items: center; gap: var(--oddly-space-5); border-top: 1px solid var(--v4-rule); flex-wrap: wrap; }
.ledger-row .row-cells { font-size: 0.75rem; display: flex; gap: 1.5rem; flex-wrap: wrap; }
.ledger-row .row-cells > span { min-width: 0; }
.ledger-row .row-cells [data-chain] { word-break: break-all; }
.ledger-row .verify { color: var(--v4-accent); text-decoration: none; }
.ledger-row .verify:hover { color: var(--v4-accent-hover); }
.ledger-row .imprint { font-size: 0.75rem; color: var(--v4-ink-muted); }

/* ============================================================
 * THE PHONE CUT
 * ============================================================
 *
 * Kyle, 2026-09-18: "the mobile web version needs a serious rethinking." It is
 * not a width problem and it was not solved by shrinking anything. At 390 the
 * orbit camera is WRONG, and these are the four reasons, in the order they cost
 * a reader something:
 *
 *   1. A SHOT IS A FRAME A READER HOLDS, AND THE FRAME IS TOO SMALL. The sticky
 *      stage is one viewport tall. At 390 by roughly 670 usable px, one shot's
 *      own type (an eyebrow, a display line, a lede, the actions and a four cell
 *      live line) is taller than that on its own. The stage clips, because the
 *      stage is the element that clips, so the camera cuts away from words the
 *      reader has not finished. Cropping a sentence is not a camera move.
 *   2. THE STAGE CHANGES HEIGHT WHILE THE READER SCROLLS. A phone toolbar
 *      collapses on the first downward scroll, 100vh changes with it, and every
 *      shot is absolutely positioned and vertically centred inside it. The type
 *      moves under the thumb. Nothing about that reads as a camera.
 *   3. THERE IS NOTHING TO FLY TO. The push-in stops at 4.2 because the land is
 *      drawn at a two degree grid and past roughly 4x the grid stops reading as
 *      land. At 390 the whole world is about 390 px across, so the grid is
 *      already below that threshold before the camera starts moving.
 *   4. THE DIRECTION ALREADY RULES THE ANSWER. "The page degrades to a page, not
 *      to a broken film", and everything meant to be read is readable at rest.
 *      The phone takes that fallback DELIBERATELY rather than by accident.
 *
 * SO THE PHONE GETS THE PAGE, NOT A SMALLER FILM. Below 700 the sticky camera
 * does not run at all: the shots are a plain vertical sequence in normal flow,
 * over the same continuous field, with no per-section background. The one bold
 * move that survives is the sheet rising over the ink, because that move is the
 * one carrying meaning rather than variety, and it costs nothing at any width.
 *
 * The width test is a THIRD nested query inside the existing two, never a
 * replacement for either: a phone whose visitor asked for less motion, and a
 * phone with no scroll-driven animations, must still take the same fallback.
 */
@media (max-width: 700px) {
  /* The stage stands in normal flow and still clips, because the bloom is wider
     than the viewport at every width and the clip is what keeps the document at
     the viewport. */
  .stage { overflow: hidden; gap: 3.25rem; padding: 7.5rem var(--v4-gutter) 4rem; }
  /* A 2.25:1 map sliced into a narrow viewport crops to a vertical strip, which
     stops reading as a world and starts reading as a texture. Fitted, not
     sliced. */
  .sky svg { height: auto; opacity: 0.52; }
  .bloom { width: 78vmax; height: 78vmax; }
  .tagline { display: none; }
  .nav { padding: 1.25rem var(--v4-gutter); gap: 0.75rem; }
  .shot { gap: 1.125rem; }
  .live-line { gap: 1rem 1.25rem; }
  .fold { padding: 3.5rem var(--v4-gutter); gap: 2rem; }
  .fold-3 { padding-bottom: calc(3.5rem + var(--v4-sheet-lift)); }
  .line { grid-template-columns: 1fr; gap: 0.375rem; }
  .proof { padding: 3.5rem var(--v4-gutter); gap: 2rem; }
  .receipt { grid-template-columns: 1fr; }
  .receipt dt { border-bottom: 0; padding-bottom: 0; }
  .form .pair { grid-template-columns: 1fr; }
  .rows li { flex-direction: column; gap: 0.15rem; align-items: flex-start; }
  .ledger-row { padding: 2rem var(--v4-gutter); gap: 1.25rem; }
}
@media (max-width: 900px) { .nav-links { display: none; } }
