/* ============================================================
   HolterTek — "phosphor on graphite"
   Technical, dark, measured. One accent; nothing fades in;
   no radius, no shadows; nothing ever holds up the scroll.
   ============================================================ */

/* ----- Fonts (self-hosted) ----- */
@font-face {
  font-family: 'Space Grotesk';
  src: url('../fonts/space-grotesk-var.woff2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('../fonts/plex-mono-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('../fonts/plex-mono-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* ----- Tokens ----- */
:root {
  --ink: #0B0E0C;        /* page — near-black, green cast */
  --ink-2: #111612;      /* raised panels */
  --rule: #22291F;       /* hairlines, lattice */
  --bone: #E6EAE2;       /* primary text — ~15:1 on ink */
  --dim: #8B948A;        /* secondary text — ~7:1 on ink */
  --phos: #6BDD8B;       /* THE accent — ~9:1 on ink */
  --phos-dim: #3E7A50;   /* accent, quiet form (decorative only) */

  --font-display: 'Space Grotesk', system-ui, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', monospace;

  --text-hero: clamp(2.6rem, 7.5vw, 6rem);
  --text-xl: clamp(1.7rem, 3.6vw, 3rem);
  --text-lg: clamp(1.25rem, 2vw, 1.7rem);
  --text-md: clamp(0.98rem, 1.15vw, 1.1rem);
  --text-mono: clamp(0.72rem, 0.82vw, 0.82rem);

  --gutter: clamp(1.25rem, 5vw, 5.5rem);
  --section-gap: clamp(5rem, 13vh, 9rem);
  --status-h: 1.9rem;
  --ease-scan: cubic-bezier(0.16, 1, 0.3, 1);
}

/* ----- Base ----- */
*, *::before, *::after { box-sizing: border-box; border-radius: 0; box-shadow: none; }
html { background: var(--ink); }
body {
  margin: 0;
  background: var(--ink);
  color: var(--bone);
  font-family: var(--font-display);
  font-size: var(--text-md);
  line-height: 1.65;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
  padding-bottom: var(--status-h); /* room for the status line */
}

/* Dot lattice — the page sits on graph paper, barely */
body::before {
  content: '';
  position: fixed; inset: 0;
  pointer-events: none; z-index: 0;
  background-image: radial-gradient(var(--rule) 1px, transparent 1px);
  background-size: 8rem 8rem;
  opacity: .5;
}

h1, h2, h3 { font-family: var(--font-display); font-weight: 550; line-height: 1.08; margin: 0; letter-spacing: -0.015em; }
p { margin: 0; }
a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
::selection { background: var(--phos); color: var(--ink); }
:focus-visible { outline: 2px solid var(--phos); outline-offset: 3px; }

/* Instant anchor jumps land clear of the fixed header. Applies to every
   jump target, not just sections — the About contact card is a div. */
:target, section[id], h2[id], [id].contact-card { scroll-margin-top: 5rem; }

.skip-link {
  position: absolute; left: var(--gutter); top: -3rem;
  background: var(--ink-2); color: var(--phos);
  padding: .5rem 1rem; z-index: 100; font-family: var(--font-mono); font-size: var(--text-mono);
  transition: top .2s;
}
.skip-link:focus { top: .75rem; }

/* ----- Utilities ----- */
.wrap { padding-inline: var(--gutter); max-width: 90rem; margin-inline: auto; position: relative; z-index: 1; }
.mono {
  font-family: var(--font-mono); font-size: var(--text-mono);
  font-weight: 400; letter-spacing: .14em; text-transform: uppercase;
}
.label { color: var(--dim); }
.accent { color: var(--phos); }
.rule { height: 1px; background: var(--rule); border: 0; margin: 0; }
.rule[data-draw] { transform-origin: left; transform: scaleX(0); transition: transform .9s var(--ease-scan); }
.rule[data-draw].is-in, .is-in .rule[data-draw] { transform: scaleX(1); }

/* Bracketed targets — interactive things are bracketed, never filled */
.bkt {
  font-family: var(--font-mono); font-size: var(--text-mono);
  font-weight: 500; letter-spacing: .14em; text-transform: uppercase;
  color: var(--phos);
  display: inline-flex; align-items: center; gap: .6em;
  padding: .55em .9em;
  border: 1px solid var(--rule);
  position: relative;
  background: linear-gradient(to right, var(--phos) 50%, transparent 50%) no-repeat;
  background-size: 220% 100%;
  background-position: 100% 0;
  transition: background-position .22s var(--ease-scan), color .18s linear, border-color .18s linear;
}
.bkt::before { content: '['; color: var(--phos-dim); transition: color .18s; }
.bkt::after { content: ']'; color: var(--phos-dim); transition: color .18s; }
.bkt:hover, .bkt:focus-visible {
  background-position: 0 0;
  color: var(--ink); border-color: var(--phos);
}
.bkt:hover::before, .bkt:hover::after,
.bkt:focus-visible::before, .bkt:focus-visible::after { color: var(--ink); }
.bkt--lg { font-size: calc(var(--text-mono) * 1.35); padding: .8em 1.2em; }
.bkt--bare { border-color: transparent; padding-inline: .2em; }
.bkt--bare:hover, .bkt--bare:focus-visible { border-color: transparent; }

/* ----- Entrances: scan wipe (clip on the CHILD — the wrapper is
   observed, so Chromium's clip-path/IntersectionObserver quirk
   never bites) ----- */
[data-scan] { position: relative; }
[data-scan] > .scan-body {
  clip-path: inset(0 0 100% 0);
  transition: clip-path .8s var(--ease-scan);
}
[data-scan].is-in > .scan-body { clip-path: inset(0 0 -6% 0); }
[data-scan]::after {              /* the 1px sweep line */
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 1px;
  background: var(--phos); opacity: 0;
  pointer-events: none;
}
[data-scan].is-in::after { animation: sweep .8s var(--ease-scan) forwards; }
@keyframes sweep {
  0% { top: 0; opacity: .8; }
  90% { opacity: .8; }
  100% { top: 100%; opacity: 0; }
}

/* Horizontal variant for rows */
[data-scan="x"] > .scan-body { clip-path: inset(0 100% 0 0); }
[data-scan="x"].is-in > .scan-body { clip-path: inset(0 -2% 0 0); }
[data-scan="x"]::after { display: none; }

/* Staggered children (each child is its own scan wrapper via JS delay) */
[data-stagger] > [data-scan] > .scan-body { transition-delay: var(--d, 0s); }

/* ----- Header ----- */
.site-head {
  position: fixed; inset: 0 0 auto 0; z-index: 50;
  display: flex; align-items: center; justify-content: space-between;
  padding: .95rem var(--gutter);
  background: color-mix(in srgb, var(--ink) 86%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid transparent;
  transition: border-color .3s;
}
.site-head.is-scrolled { border-bottom-color: var(--rule); }
.wordmark { font-family: var(--font-mono); font-weight: 500; font-size: .95rem; letter-spacing: .18em; text-transform: uppercase; }
.wordmark b { font-weight: 500; color: var(--phos); }
.site-nav { display: flex; gap: clamp(.5rem, 2vw, 1.4rem); align-items: center; }

/* ----- Status line (bottom edge; every value is measured) ----- */
.status-line {
  position: fixed; inset: auto 0 0 0; z-index: 55;
  height: var(--status-h);
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem;
  padding-inline: var(--gutter);
  background: var(--ink);
  border-top: 1px solid var(--rule);
  font-family: var(--font-mono); font-size: .68rem;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--dim);
  white-space: nowrap; overflow: hidden;
}
.status-line .sep { color: var(--rule); }
.status-line .val { color: var(--phos); }
@media (max-width: 640px) { .status-line .hide-s { display: none; } }

/* ----- Hero ----- */
.hero {
  position: relative;

  --mark-aspect: 1.292;   /* mark-field.webp is 815x631 */

  /* The mark's rendered height, in absolute terms rather than a percentage of
     the hero — the hero is sized FROM this, so a percentage would be circular
     and could never exceed 100% without cropping. The second term caps the
     height so the mark's width can never exceed the viewport, which is what
     keeps narrow screens from clipping it left and right. */
  --mark-h: min(clamp(20rem, 46vw, 52rem), calc((100vw - 4rem) / var(--mark-aspect)));
  --mark-w: calc(var(--mark-h) * var(--mark-aspect));

  /* Clearance above and below the mark. The mark is bottom-anchored, so adding
     to the TOP gap is what moves it down the banner — the banner grows with it
     rather than the mark sliding off the bottom edge. */
  --mark-gap-top: calc(4rem + var(--mark-h) * 0.10);
  --mark-gap-bottom: 4rem;

  /* Content is top-anchored, so a full-viewport floor leaves a void on tall
     screens — hence the 40rem cap. But the banner must also be tall enough to
     hold the mark plus both clearances, so take whichever is larger. This is
     why the hero now extends past 40rem on wide screens. */
  min-height: max(
    min(calc(100svh - var(--status-h)), 40rem),
    calc(var(--mark-h) + var(--mark-gap-top) + var(--mark-gap-bottom))
  );
  display: flex; flex-direction: column; justify-content: flex-start;
  padding: clamp(6.5rem, 13vh, 9rem) var(--gutter) clamp(2.5rem, 8vh, 5rem);
  overflow: hidden;
}
/* ---------------------------------------------------------------
   DISABLED 2026-08-07 — landing background logo, parked not deleted.

   The HolterTek mark as texture: baked to a green-graphite tritone by
   documents/make_logo_field.py, sat under the decode field, anchored to the
   bottom-right corner with a fixed clearance (a centre offset could push it
   past a short hero's bottom edge and crop it).

   To bring it back: uncomment this block and disable the monogram rule below.
   The plate is still at assets/img/logo-field.webp. Its responsive size steps
   have since been removed as dead code — they were --logo-size 58% below
   900px and 67% (with --logo-x calc(100% - 1.25rem), --logo-y
   calc(100% - 2rem)) below 540px.

.hero::before {
  content: '';
  position: absolute; inset: 0;
  z-index: 0; pointer-events: none;
  background: url('../img/logo-field.webp') no-repeat;
  background-size: var(--logo-size, 44%) auto;
  background-position: var(--logo-x, calc(100% - 3rem)) var(--logo-y, calc(100% - 3rem));
  opacity: var(--logo-opacity, .36);
}
   --------------------------------------------------------------- */

/* Landing background — the HolterTek monogram as texture. Baked to a
   green-graphite plate by documents/make_mark_field.py, sat under the decode
   field and above nothing else, so the hero copy (z-index 2) always reads on
   top of it.

   Sized by --mark-h (see .hero above), which the banner's own height is
   derived from — so the mark is never cropped no matter how large it gets;
   the banner extends to hold it. Bottom-anchored against --mark-gap-bottom,
   with the vertical placement set by --mark-gap-top on .hero.

   Horizontally it sits left of centre, then shifted right by 20% of its own
   width so the offsets scale with the mark rather than drifting at different
   viewport sizes. The max() floor keeps the offset from ever pushing it off
   the left edge on a narrow screen. */
.hero::before {
  content: '';
  position: absolute; inset: 0;
  z-index: 0; pointer-events: none;
  background: url('../img/mark-field.webp') no-repeat;
  background-size: auto var(--mark-size, var(--mark-h));
  background-position:
    var(--mark-x, max(1.5rem, calc(50% - 9rem + var(--mark-w) * 0.20)))
    var(--mark-y, calc(100% - var(--mark-gap-bottom)));
  opacity: var(--mark-opacity, .3);
}
.hero-canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.hero-inner { position: relative; z-index: 2; max-width: 64rem; }
.hero-kicker { margin-bottom: 1.4rem; color: var(--dim); }
.hero-kicker .accent { color: var(--phos); }
.hero h1 {
  font-size: var(--text-hero);
  font-weight: 560;
  letter-spacing: -0.025em;
  max-width: 16ch;
  min-height: 2.1em; /* reserve space so decode doesn't reflow */
}
.hero-lede {
  margin-top: 1.6rem;
  font-family: var(--font-mono); font-size: calc(var(--text-mono) * 1.12);
  letter-spacing: .04em; text-transform: none;
  color: var(--dim); max-width: 52ch; line-height: 1.8;
  min-height: 3.6em;
}
.caret {
  display: inline-block; width: .55em; height: 1.1em;
  background: var(--phos); vertical-align: text-bottom;
  margin-left: .15em;
  animation: caret-blink 1.1s steps(1) infinite;
}
@keyframes caret-blink { 50% { opacity: 0; } }
.hero-actions { display: flex; flex-wrap: wrap; gap: 1rem; margin-top: 2.2rem; }

/* 404 — one-line headline, no typed lede, so drop the reserved heights the
   home hero uses to stop the decode and type-on effects reflowing. */
.hero--error h1 { min-height: 0; }
.hero--error .hero-lede { min-height: 0; }

/* ----- Sections ----- */
.section { padding-top: var(--section-gap); position: relative; z-index: 1; }
.section-head {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 1.4rem;
  margin-bottom: clamp(2rem, 5vh, 3.4rem);
}
.section-head .sec-id { color: var(--phos-dim); }

/* Vision — numbered register */
.vision-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: clamp(2rem, 4.5vw, 4.5rem) clamp(2.5rem, 6vw, 7rem); }
.vision-item { border-top: 1px solid var(--rule); padding-top: 1.3rem; }
.vision-item .num { color: var(--phos); }
.vision-item h3 { font-size: var(--text-lg); font-weight: 540; margin: .6rem 0 .65rem; max-width: 22ch; }
.vision-item p { color: var(--dim); max-width: 44ch; font-size: .95rem; }

/* ----- Work ledger (native flow — never holds the scroll) ----- */
.ledger { border-top: 1px solid var(--rule); }
.ledger-group-label { padding: .8rem 0 .5rem; color: var(--phos-dim); }
.ledger details { border-bottom: 1px solid var(--rule); }
.ledger summary {
  list-style: none; cursor: pointer;
  display: grid;
  grid-template-columns: 5.5rem minmax(0, 1fr) 8rem 9rem 2rem;
  align-items: baseline; gap: 1.5rem;
  padding: 1.05rem 0;
  transition: color .15s linear;
}
.ledger summary::-webkit-details-marker { display: none; }
.ledger summary .id { color: var(--phos); }
.ledger summary .name { font-size: var(--text-lg); font-weight: 540; letter-spacing: -.01em; }
.ledger summary .cls, .ledger summary .dom { color: var(--dim); text-align: left; }
.ledger summary .tgl { color: var(--phos-dim); text-align: right; transition: transform .18s var(--ease-scan); }
.ledger summary:hover .name, .ledger summary:focus-visible .name { color: var(--phos); }
.ledger summary:hover .tgl { color: var(--phos); }
.ledger details[open] summary .tgl { transform: rotate(45deg); color: var(--phos); }
.ledger details[open] summary .id { color: var(--phos); }
.ledger .row-body {
  padding: 0 0 1.4rem;
  color: var(--dim); max-width: 56ch; font-size: .95rem;
}
@media (min-width: 900px) { .ledger .row-body { margin-left: 7rem; } }

/* ----- Web design ----- */
.design-grid { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(2.5rem, 6vw, 7rem); align-items: start; }
.design-copy h3 { font-size: var(--text-xl); font-weight: 540; max-width: 16ch; margin-bottom: 1.3rem; }
.design-copy p { color: var(--dim); max-width: 46ch; margin-bottom: 1rem; }
.design-case { margin-top: 1.8rem; border-left: 1px solid var(--phos-dim); padding-left: 1.2rem; }
.design-case .mono { color: var(--phos); }
.design-case p { margin-top: .5rem; font-size: .95rem; }

.tiers { container: tiers / inline-size; }
.price-table { width: 100%; border-collapse: collapse; }
.price-table th, .price-table td { text-align: left; vertical-align: top; padding: 1.1rem 1rem 1.2rem 0; border-top: 1px solid var(--rule); }
.price-table tr:last-child th, .price-table tr:last-child td { border-bottom: 1px solid var(--rule); }
.price-table th { font-size: var(--text-lg); font-weight: 540; white-space: nowrap; padding-right: 2rem; }
.price-table .inc { color: var(--dim); font-size: .95rem; max-width: 46ch; }
.price-table .num {
  font-family: var(--font-mono); font-size: var(--text-mono); font-weight: 500;
  letter-spacing: .1em; text-transform: uppercase; color: var(--phos);
  text-align: right; white-space: nowrap; padding-right: 0;
  font-variant-numeric: tabular-nums;
}
.price-table .num .lead { display: block; color: var(--dim); font-weight: 400; margin-top: .4rem; }
.tiers-note { margin-top: 1rem; color: var(--dim); font-size: .9rem; }

/* ----- Contact ----- */
.contact {
  margin-top: var(--section-gap);
  background: var(--ink-2);
  border-top: 1px solid var(--rule);
  padding: clamp(4rem, 12vh, 7rem) var(--gutter) clamp(4.5rem, 13vh, 8rem);
  position: relative; z-index: 1;
}
.contact h2 { font-size: clamp(2.2rem, 5.5vw, 4.6rem); font-weight: 560; letter-spacing: -.02em; margin: 1.1rem 0 2.4rem; max-width: 18ch; }
.contact-links { display: flex; flex-wrap: wrap; gap: 1rem; }
.contact-meta { margin-top: 2.4rem; display: flex; flex-wrap: wrap; gap: .8rem 2.4rem; color: var(--dim); }
.contact-meta .val { color: var(--phos); }

/* ----- Cookie notice -----
   Deliberately a NOTICE, not a consent gate. The site sets no cookies of its
   own and loads nothing third-party; the only cookie in play is Cloudflare's
   strictly necessary __cf_bm, which is consent-exempt. So there is no
   accept/reject pair — offering one would imply a choice that does not exist.
   Non-modal: it never traps focus, never dims the page, never blocks reading.
   Sits above the status line so the two never overlap. */
.cookie-note {
  position: fixed;
  left: var(--gutter);
  bottom: calc(var(--status-h) + 1rem);
  z-index: 60;
  width: min(30rem, calc(100vw - var(--gutter) * 2));
  background: var(--ink-2);
  border: 1px solid var(--rule);
  padding: 1rem 1.15rem 1.15rem;
  color: var(--dim);
  transform: translateY(calc(100% + var(--status-h) + 2rem));
  transition: transform .55s var(--ease-scan);
}
.cookie-note[hidden] { display: none; }
.cookie-note.is-in { transform: translateY(0); }
.cookie-note-head { color: var(--dim); margin-bottom: .6rem; }
.cookie-note p { font-size: .88rem; line-height: 1.6; }
.cookie-note-actions { display: flex; flex-wrap: wrap; gap: .7rem 1rem; align-items: center; margin-top: 1rem; }
.cookie-note .bkt { background-color: transparent; font-family: var(--font-mono); cursor: pointer; }
.cookie-note button.bkt { border: 1px solid var(--rule); }

/* ----- Document pages (privacy) ----- */
.doc-hero { padding: calc(6rem + 3vh) var(--gutter) 0; position: relative; z-index: 1; max-width: 90rem; margin-inline: auto; }
.doc-hero h1 { font-size: clamp(2.2rem, 5vw, 4rem); font-weight: 560; letter-spacing: -.02em; margin: 1rem 0 1.5rem; max-width: 18ch; }
.doc-lede { color: var(--dim); max-width: 54ch; }
.doc-updated { margin-top: 1.6rem; color: var(--dim); }
.doc-updated .val { color: var(--phos); }
.doc-body p { color: var(--dim); max-width: 68ch; margin-bottom: 1.1rem; }
.doc-body p:last-child { margin-bottom: 0; }
.doc-note { border-left: 1px solid var(--phos-dim); padding-left: 1.2rem; }
.doc-link { color: var(--bone); border-bottom: 1px solid var(--rule); transition: color .15s, border-color .15s; }
.doc-link:hover, .doc-link:focus-visible { color: var(--phos); border-color: var(--phos-dim); }
.doc-table { width: 100%; border-collapse: collapse; margin: 0 0 1.4rem; }
.doc-table th, .doc-table td { text-align: left; vertical-align: top; padding: 1.1rem 1rem 1.2rem 0; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
.doc-table th { white-space: nowrap; padding-right: 2rem; font-weight: 400; }
.doc-table th .mono { color: var(--phos); }
.doc-table .inc { color: var(--dim); font-size: .95rem; max-width: 48ch; }
.doc-table .num {
  font-family: var(--font-mono); font-size: var(--text-mono); font-weight: 500;
  letter-spacing: .1em; text-transform: uppercase; color: var(--phos);
  text-align: right; white-space: nowrap; padding-right: 0;
}
.doc-table .num .lead { display: block; color: var(--dim); font-weight: 400; margin-top: .4rem; }
.doc-body .contact-card { margin-top: 2.2rem; }

@media (max-width: 640px) {
  .doc-table tr { display: flex; flex-direction: column; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); padding: 1.15rem 0 1.35rem; }
  .doc-table th, .doc-table td { border: 0; padding: 0; max-width: none; }
  .doc-table th { white-space: normal; margin-bottom: .55rem; }
  .doc-table .num { order: 1; text-align: left; margin-bottom: .75rem; }
  .doc-table .num .lead { display: inline; margin-top: 0; margin-left: .9rem; }
  .doc-table .inc { order: 2; }
}

/* ----- Footer ----- */
.site-foot {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: .8rem 1.5rem;
  padding: 1.4rem var(--gutter);
  background: var(--ink-2); color: var(--dim);
  border-top: 1px solid var(--rule);
}

/* ============================================================
   About page
   ============================================================ */
.about-hero { padding: calc(6rem + 3vh) var(--gutter) 0; position: relative; z-index: 1; }
.about-grid {
  display: grid; grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
  gap: clamp(2.5rem, 6vw, 6.5rem); align-items: start;
}
.about-copy h1 { font-size: var(--text-hero); font-weight: 560; letter-spacing: -.025em; margin: 1rem 0 1.6rem; min-height: 1.1em; }
.about-copy p { max-width: 52ch; margin-bottom: 1.1rem; }
.about-copy p.muted { color: var(--dim); }

/* Sleek contact card — below the bio text */
.contact-card {
  margin-top: 2.6rem; max-width: 30rem;
  border-top: 1px solid var(--rule);
}
.contact-card > div {
  display: grid; grid-template-columns: 7rem minmax(0, 1fr);
  gap: 1.5rem; align-items: baseline;
  padding: .75rem 0;
  border-bottom: 1px solid var(--rule);
}
.contact-card .k { color: var(--dim); }
.contact-card a { color: var(--bone); transition: color .15s linear; }
.contact-card a:hover, .contact-card a:focus-visible { color: var(--phos); }
.contact-card .val { color: var(--phos); }

.plate { position: relative; }
.plate img { width: 100%; height: auto; border: 1px solid var(--rule); }
.plate figcaption {
  margin-top: .6rem;
  display: flex; justify-content: space-between; gap: 1rem;
  color: var(--dim);
}
.plate figcaption .val { color: var(--phos); }

/* Background timeline — same ledger system as Home */
.timeline { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--rule); }
.timeline li { border-bottom: 1px solid var(--rule); }
.timeline li > .scan-body {
  display: grid; grid-template-columns: 10rem minmax(0, 1fr); gap: .8rem 2.5rem;
  padding: 1.3rem 0 1.5rem;
}
.timeline .when { color: var(--phos); font-variant-numeric: tabular-nums; }
.timeline h3 { font-size: var(--text-lg); font-weight: 540; margin-bottom: .45rem; }
.timeline p { color: var(--dim); max-width: 54ch; font-size: .95rem; }

/* Values — cells on ink-2 */
.values { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--rule); border: 1px solid var(--rule); }
.value { background: var(--ink-2); padding: 1.4rem 1.3rem 1.6rem; }
.value .mono { color: var(--phos-dim); }
.value h3 { font-size: 1.08rem; font-weight: 560; margin: .6rem 0 .5rem; }
.value p { color: var(--dim); font-size: .92rem; }

/* ----- Responsive ----- */
@media (max-width: 899px) {
  .vision-grid { grid-template-columns: 1fr; }
  .design-grid { grid-template-columns: 1fr; }
  .about-grid { grid-template-columns: 1fr; }
  .plate { max-width: 26rem; }
  .values { grid-template-columns: 1fr 1fr; }
  .timeline li > .scan-body { grid-template-columns: 1fr; gap: .25rem; }
  .ledger summary { grid-template-columns: 4rem minmax(0, 1fr) 2rem; }
  .ledger summary .cls, .ledger summary .dom { display: none; }
  .ledger .row-body { margin-left: 0; }
  .price-table .num { white-space: normal; }
  /* Narrow frames: drop the viewport-width cap so the mark keeps its presence
     behind the copy rather than shrinking to a stamp. Here it deliberately
     bleeds past the right edge — only the vertical fit is guaranteed, and the
     banner height is derived from that. */
  .hero { --mark-h: clamp(20rem, 100vw, 34rem); }
}
/* The tier table is crushed by its COLUMN width, not the viewport: at 900–1100px
   the two-column design grid leaves it ~440px and the description cell drops to
   ~140px. A container query catches both that band and small phones. */
@container tiers (max-width: 36rem) {
  .price-table tr {
    display: flex; flex-direction: column;
    border-top: 1px solid var(--rule);
    padding: 1.15rem 0 1.35rem;
  }
  .price-table tr:last-child { border-bottom: 1px solid var(--rule); }
  .price-table th, .price-table td { border: 0; padding: 0; max-width: none; }
  .price-table th { white-space: normal; padding-right: 0; margin-bottom: .55rem; }
  .price-table .num { order: 1; text-align: left; margin-bottom: .75rem; }
  .price-table .num .lead { display: inline; margin-top: 0; margin-left: .9rem; }
  .price-table .inc { order: 2; }
}

/* Below ~430px the wordmark plus three bracketed nav targets overrun the header
   and [ CONTACT ] was being clipped by the body's overflow-x. Tighten the
   header's own rhythm rather than dropping an item. */
@media (max-width: 430px) {
  .site-head { padding-inline: 1rem; }
  .wordmark { font-size: .82rem; letter-spacing: .1em; }
  .site-nav { gap: .3rem; }
  .site-nav .bkt { padding-inline: .5em; letter-spacing: .08em; gap: .4em; }
  /* The email address is the longest bracketed target on the site and cannot
     wrap (inline-flex) — step it down so it fits a 320px frame. */
  .contact-links .bkt--lg { font-size: var(--text-mono); padding-inline: .7em; letter-spacing: .07em; }
}
@media (max-width: 360px) {  /* 320px is the stated floor — keep all three targets */
  .wordmark { font-size: .72rem; }
  .site-nav { gap: .15rem; }
  .site-nav .bkt { font-size: .62rem; padding-inline: .35em; letter-spacing: .06em; gap: .3em; }
}

@media (max-width: 540px) {
  .values { grid-template-columns: 1fr; }
  .contact-card > div { grid-template-columns: 5.5rem minmax(0, 1fr); gap: 1rem; }
}

/* ----- Reduced motion: content identical, motion removed ----- */
@media (prefers-reduced-motion: reduce) {
  [data-scan] > .scan-body { clip-path: none !important; transition: none !important; }
  [data-scan]::after { animation: none !important; opacity: 0 !important; }
  .rule[data-draw] { transform: none !important; transition: none !important; }
  .caret { animation: none; }
  .bkt { transition: none; }
  .ledger summary .tgl { transition: none; }
  .cookie-note { transition: none !important; transform: none !important; }
}
