/* reset.css — minimal modern reset. */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }
html, body { height: 100%; }
body {
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, picture, video, canvas, svg { display: block; max-width: 100%; }
input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: none; cursor: pointer; }
p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; }
table { border-collapse: collapse; border-spacing: 0; }
:focus-visible { outline: 2px solid var(--jn-coral); outline-offset: 2px; }

/* ============================================================
   Jeremy Novy — Design Tokens (canonical)

   Ported from `Kovalik Design/Clients/Jeremy Novy/site/src/styles/tokens.css`
   (Astro reference, branch master @ 73e884e). Verified against
   `site/docs/design-system.html` and audits 1-4.

   PRINCIPLE: cream-dominant. Dark is PUNCTUATION (header, hero,
   footer, frame border, hero-highlight). White is never used.
   Three-font stack: paralucent-stencil + Roboto + Open Sans.

   Per-component CSS in `styles/comp-*.css` and per-page CSS in
   `styles/pages-*.css` reads these tokens. `--jn-*` aliases at the
   bottom map the v2 scaffold's original namespace to canonical
   values so existing references continue to compile.
   ============================================================ */

:root {
  /* ── Surfaces (cream-dominant, no white) ── */
  --bg: #F0ECE1;                     /* CREAM — the canonical light surface */
  --bg-warm: #ECEBE9;                /* alternate band */
  --bg-soft: #E8E2D4;                /* deeper cream for cards on cream */
  --bg-dark: #111427;                /* hero / footer */
  --bg-dark-2: #121214;              /* header / frame border / hero-highlight */

  /* ── Text (verified body{color:#676767} h-tags{color:#444}) ── */
  --fg-body: #676767;
  --fg-heading: #444444;
  --fg: var(--fg-body);
  --fg-muted: #888888;
  --fg-faint: #6A6A6A; /* AUDIT-4 NEW-2: clears 4.5:1 normal-text threshold on cream */
  --fg-on-dark: #F0ECE1;
  --fg-muted-on-dark: rgba(240, 236, 225, 0.72);

  /* ── Cool family ── */
  --cool-50: #C0F1FF;
  --cool-100: #9ADAF5;
  --cool-300: #00B8FF;
  --cool-500: #248EE2;
  --cool-700: #1950CE;               /* link color — WCAG AA on cream */
  --cool-800: #21325E;
  --cool-900: #111427;

  /* ── Warm family — VERIFIED button colors ── */
  --warm-300: #FAC136;               /* gold */
  --warm-500: #F9A140;               /* amber — extra-color-3, primary CTA */
  --warm-700: #F26C49;               /* coral — extra-color-2, outbound CTA */
  --signature-orange: #FB532B;       /* AR app accent */

  /* ── Submenu hover (verified salient-dynamic.css) ── */
  --submenu-hover: #294377;

  /* ── Semantic ── */
  --cyan: #6BCDE8;                   /* decorative accent, focus ring base */
  --link: var(--cool-700);           /* AA-passing on cream */
  --link-hover: var(--cool-500);
  --accent: var(--cyan);

  /* ── Focus + glow ── */
  /* Per AUDIT-4 §4.5: cyan @ 50% alpha over cream is 1.1:1 (fails 3:1 SC 1.4.11).
     Layer a 3px outer cyan glow + 1px inner cool-700 solid stroke. cool-700
     measures 5.78:1 on cream — provides a definite edge contour even when the
     glow softens. */
  --focus-ring: 0 0 0 3px rgba(107, 205, 232, 0.5), 0 0 0 1px var(--cool-700);
  --glow-cyan-lg: 0 30px 90px #6BCDE8;
  --glow-cyan-sm: 0 10px 30px rgba(107, 205, 232, 0.5);

  /* ── Backward-compat cyan aliases ── */
  --cyan-100: var(--cool-50);
  --cyan-300: var(--cool-100);
  --cyan-500: var(--cyan);
  --cyan-700: var(--cool-300);
  --blue-500: var(--cool-500);
  --blue-700: var(--cool-700);
  --blue-900: var(--cool-800);
  --warm-coral: var(--warm-700);
  --bg-cream: var(--bg-soft);

  /* ── Borders ── */
  --border: rgba(17, 20, 39, 0.12);
  --border-strong: rgba(17, 20, 39, 0.24);
  --border-dark: rgba(240, 236, 225, 0.16);

  /* ── Typography ── */
  /* paralucent-stencil Heavy — Adobe TypeKit kit osq5phz (weights: 200, 500, 700)
     USE FOR: h1, h2, large CTA labels, "Like What You See?" / "Get emails..."
     Roboto — Google Fonts (weights: 400, 500, 700, 900)
     USE FOR: everything else (body, h3-h6, nav, labels, captions, inline buttons)
     `--font-display` retained as legacy alias → Roboto. */
  --font-stencil: "paralucent-stencil", "Bebas Neue", Impact, "Arial Narrow", sans-serif;
  --font-body: "Roboto", system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  --font-display: var(--font-body);

  --fw-light: 300;
  --fw-regular: 400;
  --fw-semibold: 600;
  --fw-bold: 700;
  --fw-black: 900;

  /* Type scale — fluid */
  --text-xs:   clamp(0.75rem, 0.72rem + 0.15vw, 0.8125rem);
  --text-sm:   clamp(0.8125rem, 0.79rem + 0.15vw, 0.875rem);
  --text-base: clamp(0.9375rem, 0.91rem + 0.15vw, 1rem);
  --text-lg:   clamp(1.0625rem, 1.02rem + 0.25vw, 1.1875rem);
  --text-xl:   clamp(1.25rem, 1.18rem + 0.4vw, 1.4375rem);
  --text-2xl:  clamp(1.625rem, 1.5rem + 0.7vw, 2rem);
  --text-3xl:  clamp(2rem, 1.8rem + 1vw, 2.625rem);
  --text-4xl:  clamp(2.625rem, 2.3rem + 1.6vw, 3.5rem);
  --text-5xl:  clamp(3.5rem, 3rem + 2.5vw, 5rem);
  --text-6xl:  clamp(4.5rem, 3.6rem + 4.5vw, 7.5rem);
  --text-7xl:  clamp(5.5rem, 4.4rem + 5.5vw, 9.5rem);

  --lh-tight: 1;
  --lh-snug: 1.15;
  --lh-normal: 1.5;
  --lh-relaxed: 1.7;

  --tracking-tight: -0.02em;
  --tracking-normal: 0;
  --tracking-wide: 0.04em;
  --tracking-wider: 0.08em;
  --tracking-widest: 0.16em;

  /* ── Spacing ── */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4rem;
  --space-9: 6rem;
  --space-10: 8rem;
  --space-hero-y: 250px;             /* matches live site parallax hero padding */

  /* ── Layout ── */
  --content-max: 1440px;
  --content-narrow: 720px;
  --content-medium: 960px;
  --gutter: clamp(1rem, 4vw, 2rem);

  /* ── Radius ── */
  --radius-sm: 2px;
  --radius-md: 4px;
  --radius-lg: 8px;
  --radius-full: 9999px;

  /* ── Motion ── */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --duration-fast: 150ms;
  --duration-base: 280ms;
  --duration-slow: 480ms;

  /* ── Elevation ── */
  --shadow-sm: 0 1px 3px rgba(17, 20, 39, 0.08);
  --shadow-md: 0 6px 18px rgba(17, 20, 39, 0.12);
  --shadow-lg: 0 16px 48px rgba(17, 20, 39, 0.18);

  /* Flank shadows — symmetric directional drops at left+right corners.
     Used to lift hero photos / feature images off dark surfaces (Stefan
     2026-05-17). See `docs/design-system.html` for the full set.
     amber = like-what feature; cyan + coral variants live in legacy. */
  --shadow-flank-amber:
    -16px 24px 48px rgba(249, 161, 64, 0.18),
    16px 24px 48px rgba(249, 161, 64, 0.18);
  --shadow-flank-cyan:
    -16px 24px 48px rgba(107, 205, 232, 0.18),
    16px 24px 48px rgba(107, 205, 232, 0.18);
  --shadow-flank-coral:
    -16px 24px 48px rgba(242, 108, 73, 0.18),
    16px 24px 48px rgba(242, 108, 73, 0.18);
  --shadow-flank-neutral:
    -12px 18px 36px rgba(17, 20, 39, 0.22),
    12px 18px 36px rgba(17, 20, 39, 0.22);

  /* ──────────────────────────────────────────────────────────
     v2 scaffold legacy aliases (`--jn-*`)
     Map the original v2 namespace to canonical values so existing
     comp-*.css and pages-*.css files continue to compile against
     correct colors and fonts. New rules should reference the flat
     tokens above directly — these aliases are for transitional
     compatibility only and will be removed once all comp-* / pages-*
     stylesheets are normalized.
     ────────────────────────────────────────────────────────── */
  --jn-ink:           var(--bg-dark);
  --jn-cream:         var(--bg);
  --jn-coral:         var(--warm-700);
  --jn-pride-red:     var(--signature-orange);
  --jn-fog:           var(--fg-muted);
  --jn-bg-dark-1:     var(--bg-dark);
  --jn-bg-dark-2:     var(--bg-dark-2);
  --jn-text-on-cream: var(--fg-heading);
  --jn-text-on-dark:  var(--fg-on-dark);
  --jn-link-on-dark:  var(--cyan-500);
  --jn-font-display:  var(--font-stencil);
  --jn-font-body:     var(--font-body);
  --jn-font-mono:     "JetBrains Mono", "Courier New", monospace;
  --jn-fs-h1:         var(--text-6xl);
  --jn-fs-h2:         var(--text-3xl);
  --jn-fs-h3:         var(--text-xl);
  --jn-fs-body:       var(--text-base);
  --jn-fs-small:      var(--text-sm);
  --jn-space-section: var(--space-10);
  --jn-space-section-sm: var(--space-9);
  --jn-space-block:   var(--space-7);
  --jn-space-gap:     var(--space-5);
  --jn-container-max: var(--content-max);
  --jn-radius-sm:     var(--radius-sm);
  --jn-radius-md:     var(--radius-md);
  --jn-radius-lg:     var(--radius-lg);
  --jn-dur-fast:      var(--duration-fast);
  --jn-dur-base:      var(--duration-base);
  --jn-dur-slow:      var(--duration-slow);
  --jn-ease:          var(--ease-out);
  --jn-ease-in-out:   var(--ease-in-out);
}

/* global.css — site-wide base styles + utility classes. */

body {
  background-color: var(--jn-cream);
  color: var(--jn-text-on-cream);
  font-family: var(--jn-font-body);
  font-size: var(--jn-fs-body);
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--jn-font-display);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.05;
  text-transform: uppercase;
}
h1 { font-size: var(--jn-fs-h1); }
h2 { font-size: var(--jn-fs-h2); }
h3 { font-size: var(--jn-fs-h3); }

a {
  color: var(--jn-coral);
  text-underline-offset: 0.18em;
}
a:hover { text-decoration: underline; }

.container {
  width: 100%;
  max-width: var(--jn-container-max);
  margin-inline: auto;
  padding-inline: clamp(1rem, 3vw, 2rem);
}

.eyebrow {
  font-family: var(--jn-font-mono);
  font-size: var(--jn-fs-small);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--jn-fog);
}

.section {
  padding-block: var(--jn-space-section);
}

.section--dark {
  background-color: var(--jn-bg-dark-1);
  color: var(--jn-text-on-dark);
}

.section--dark .eyebrow { color: var(--jn-fog); }

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.875rem 1.5rem;
  font-weight: 600;
  border-radius: var(--jn-radius-sm);
  transition: transform var(--jn-dur-fast) var(--jn-ease),
              background-color var(--jn-dur-fast) var(--jn-ease);
  white-space: nowrap;
}
.btn:hover { transform: translateY(-1px); text-decoration: none; }

.btn--primary {
  background-color: var(--jn-coral);
  color: var(--jn-ink);
}
.btn--primary:hover { background-color: #ff7d57; }

.btn--ghost {
  background-color: transparent;
  color: var(--jn-ink);
  border: 1.5px solid currentColor;
}

.btn--on-dark {
  background-color: transparent;
  color: var(--jn-cream);
  border: 1.5px solid var(--jn-cream);
}

.skip-link {
  position: absolute;
  left: -10000px;
  top: 0;
  background: var(--jn-ink);
  color: var(--jn-cream);
  padding: 0.75rem 1rem;
  z-index: 100;
}
.skip-link:focus { left: 0; }

/* ============================================================
   Canonical buttons — single-dash convention from Astro global.css.
   Used by hero CTAs + new home sections. BEM `.btn--primary` aliases
   above kept for backwards compat with existing v2 components that
   reference them (newsletter_band, contact_form, etc.).
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.04em;
  padding: 14px 22px;
  border-radius: 5px;
  cursor: pointer;
  border: 0;
  white-space: nowrap;
  line-height: 20px;
  text-decoration: none !important;
  color: var(--bg-dark);
  transition: background 0.18s ease, transform 0.18s var(--ease-out),
              filter 0.18s ease, box-shadow 0.18s ease;
}
.btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.btn[disabled], .btn:disabled { opacity: 0.45; cursor: not-allowed; pointer-events: none; }
.btn:hover { text-decoration: none; }

.btn-primary { background: var(--warm-700); }
.btn-primary:hover { filter: brightness(1.08); transform: translateY(-1px); }
.btn-outbound, .btn-accent { background: var(--warm-500); }
.btn-outbound:hover, .btn-accent:hover { background: var(--warm-300); transform: translateY(-1px); }
.btn-on-dark { background: var(--cyan-500); }
.btn-on-dark:hover { background: var(--cyan-700); transform: translateY(-1px); }
.btn-ghost {
  background: transparent;
  color: var(--fg-heading) !important;
  box-shadow: inset 0 0 0 2px var(--border-strong);
}
.btn-ghost:hover {
  box-shadow: inset 0 0 0 2px var(--cool-700);
  color: var(--cool-700) !important;
}
.btn-lg {
  padding: 18px 32px;
  font-size: 15px;
  font-family: var(--font-stencil);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  gap: 14px;
}
.btn-sm { padding: 9px 16px; font-size: 11px; }
.btn__fa { font-size: 16px; line-height: 1; flex-shrink: 0; }
.btn-lg .btn__fa { font-size: 18px; }
.btn-sm .btn__fa { font-size: 13px; }

/* ============================================================
   Filled-block stencil glyph (.ds-stencil-block) — used by hero
   headline + any inline filled-block stencil emphasis. Black text
   on cream block; stencil typography overrides applied.
   Surface-only variant `.ds-stencil-pad` keeps the cream pill
   background WITHOUT overriding the element's typography — for
   eyebrows / body text floating on photo overlays.
   ============================================================ */
.ds-stencil-block {
  display: inline-block;
  background-color: var(--bg);
  color: var(--bg-dark);
  padding: 0 0.25em 0.04em 0.08em;
  font-family: var(--font-stencil);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0;
  line-height: 1;
}
.ds-stencil-block--inverse {
  background-color: var(--bg-dark);
  color: var(--bg);
}
.ds-stencil-pad {
  display: inline-block;
  background-color: var(--bg);
  padding: 0.18em 0.4em 0.22em 0.4em;
  line-height: 1.3;
}
.ds-stencil-pad--inverse {
  background-color: var(--bg-dark);
}

/* ============================================================
   Eyebrow chip badge — 11px stencil ALL-CAPS 0.16em tracked, hard-
   edge border. Used as filter chips, tags, small tabs. `--filled`
   modifier indicates the active-state visual (filled w/ accent).
   ============================================================ */
.ds-eyebrow-badge {
  display: inline-block;
  font-family: var(--font-stencil);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 6px 14px;
  border: 1px solid var(--border-strong);
  border-radius: 0;
  background: transparent;
  color: var(--fg-heading);
  cursor: pointer;
  line-height: 1.2;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.ds-eyebrow-badge:hover { border-color: var(--cyan); color: var(--cool-300); }
.ds-eyebrow-badge:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.ds-eyebrow-badge--filled.is-active {
  background: var(--warm-500);
  border-color: var(--warm-500);
  color: var(--bg-dark);
}

/* ============================================================
   Forms — floating-label outlined input (used by newsletter form +
   contact form). Astro `.field` system, BEM unmodified.
   ============================================================ */
.field { position: relative; flex: 1 1 240px; min-width: 0; }
.field__input, .field__textarea {
  width: 100%;
  box-sizing: border-box;
  padding: 18px 14px 8px;
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.4;
  color: var(--fg-heading);
  background: transparent;
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
.field__input:focus, .field__textarea:focus {
  outline: none;
  border-color: var(--cyan);
  box-shadow: 0 0 0 3px rgba(107, 205, 232, 0.25);
}
.field__label {
  position: absolute;
  top: 50%;
  left: 14px;
  transform: translateY(-50%);
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--fg-muted);
  pointer-events: none;
  transition: top 0.18s ease, transform 0.18s ease, font-size 0.18s ease, color 0.18s ease;
  background: transparent;
  padding: 0;
}
.field__input:focus + .field__label,
.field__input:not(:placeholder-shown) + .field__label,
.field__textarea:focus + .field__label,
.field__textarea:not(:placeholder-shown) + .field__label {
  top: -7px;
  transform: none;
  font-size: 11px;
  background: var(--bg);
  padding: 0 6px;
  color: var(--cool-700);
}
.field--on-dark .field__input,
.field--on-dark .field__textarea {
  color: var(--fg-on-dark);
  border-color: rgba(240, 236, 225, 0.28);
}
.field--on-dark .field__label { color: var(--fg-muted-on-dark); }
.field--on-dark .field__input:focus + .field__label,
.field--on-dark .field__input:not(:placeholder-shown) + .field__label,
.field--on-dark .field__textarea:focus + .field__label,
.field--on-dark .field__textarea:not(:placeholder-shown) + .field__label {
  background: var(--bg-dark);
  color: var(--cyan-500);
}
.honeypot {
  position: absolute;
  left: -10000px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ============================================================
   Container variants (max-width: medium / narrow). The default
   `.container` is max-width 1440 (var(--content-max)). These two
   constrain the column for prose / forms / centered CTAs.
   ============================================================ */
.container-narrow { max-width: var(--content-narrow); margin-inline: auto; padding-inline: var(--gutter); }
.container-medium { max-width: var(--content-medium); margin-inline: auto; padding-inline: var(--gutter); }

/* ============================================================
   Section helpers — surface and spacing modifiers used by inner
   pages (cream band, dark band, tight / loose vertical rhythm).
   ============================================================ */
.section-cream { background: var(--bg-warm); color: var(--fg-heading); }
.section-tight { padding-block: var(--space-7); }
.section-loose { padding-block: var(--space-10); }

/* ============================================================
   Layout helpers
   ============================================================ */
.cta-row { display: flex; gap: var(--space-3); justify-content: center; flex-wrap: wrap; }
.lead { font-size: 18px; line-height: 1.55; max-width: 60ch; }

/* ============================================================
   Utilities
   ============================================================ */
.text-center { text-align: center; }
.text-balance { text-wrap: balance; }
.text-pretty { text-wrap: pretty; }
.muted { color: var(--fg-muted); }
.faint { color: var(--fg-faint); }

/* ---------- Markdown body (news posts) ---------- */
.prose {
  max-width: var(--jn-prose-max);
  font-size: 1.125rem;
  line-height: 1.6;
}
.prose > * + * { margin-top: 1.25em; }
.prose h2 { margin-top: 2em; font-size: 1.5rem; }
.prose h3 { font-size: 1.25rem; }
.prose a { text-decoration: underline; }
.prose ul, .prose ol { padding-inline-start: 1.5em; }
.prose li { margin-block: 0.4em; }
.prose blockquote {
  border-inline-start: 3px solid var(--jn-coral);
  padding-inline-start: 1rem;
  color: var(--jn-fog);
  font-style: italic;
}

/* Stencil scrollbar — thin, palette-aligned, hard edges, 0 radius (style guide). */
html { scrollbar-width: thin; scrollbar-color: var(--bg-dark-2) transparent; }
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--bg-dark-2); border: 2px solid transparent; background-clip: padding-box; border-radius: 0; }
::-webkit-scrollbar-thumb:hover { background: var(--bg-dark); background-clip: padding-box; }
::-webkit-scrollbar-corner { background: transparent; }

/* sr-only — visually hidden, screen-reader accessible (a11y heading labels, etc.). */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* BlurHighlight — viewport-triggered blur→sharp + sweep highlight on terms.
   Ported from Astro BlurHighlight.astro <style>. */

.blur-highlight {
  display: inline-block;
  will-change: filter, opacity;
  filter: blur(var(--bh-blur, 8px));
  opacity: var(--bh-inactive, 0.3);
  transition:
    filter var(--bh-duration, 800ms) cubic-bezier(0.25, 0.1, 0.25, 1),
    opacity var(--bh-duration, 800ms) ease;
}
.blur-highlight.is-revealed {
  filter: blur(0);
  opacity: 1;
}

.blur-highlight__hl {
  background-image: linear-gradient(var(--bh-color), var(--bh-color));
  background-repeat: no-repeat;
  background-size: 0% 100%;
  background-position: 0% 0%;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  transition: background-size var(--hl-duration, 1000ms) cubic-bezier(0.4, 0, 0.2, 1) var(--hl-delay, 400ms);
  padding: 0 0.08em;
}
.blur-highlight[data-highlight-direction="right"] .blur-highlight__hl {
  background-position: 100% 0%;
}
.blur-highlight.is-revealed .blur-highlight__hl { background-size: 100% 100%; }

@media (prefers-reduced-motion: reduce) {
  .blur-highlight {
    filter: none;
    opacity: 1;
    transition: none;
  }
  .blur-highlight__hl {
    background-size: 100% 100%;
    transition: none;
  }
}

/* Contact form. */
.jn-contact-form {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  max-width: 640px;
}

.jn-contact-form__row { display: grid; gap: 1.25rem; }
.jn-contact-form__row--split { grid-template-columns: 1fr 1fr; }
@media (max-width: 600px) { .jn-contact-form__row--split { grid-template-columns: 1fr; } }

.jn-contact-form__field { display: flex; flex-direction: column; gap: 0.4rem; }

.jn-contact-form__label {
  font-family: var(--jn-font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--jn-text-on-cream);
}

.jn-contact-form__req { color: var(--jn-pride-red); }

.jn-contact-form__input,
.jn-contact-form__select,
.jn-contact-form__textarea {
  width: 100%;
  padding: 0.75rem 0.875rem;
  border: 1px solid rgba(14, 12, 10, 0.16);
  background-color: white;
  color: var(--jn-ink);
  border-radius: var(--jn-radius-sm);
  font-size: 1rem;
  font-family: var(--jn-font-body);
}

.jn-contact-form__textarea { resize: vertical; min-height: 8rem; }

.jn-contact-form__input:focus-visible,
.jn-contact-form__select:focus-visible,
.jn-contact-form__textarea:focus-visible {
  outline: 2px solid var(--jn-coral);
  outline-offset: 2px;
  border-color: var(--jn-coral);
}

.jn-contact-form__conditional {
  padding: 1rem;
  background-color: rgba(242, 108, 73, 0.05);
  border-radius: var(--jn-radius-md);
  display: flex; flex-direction: column; gap: 1rem;
}

.jn-contact-form__submit-row {
  display: flex; align-items: center; gap: 1.25rem; flex-wrap: wrap;
  margin-top: 0.5rem;
}

.jn-contact-form__status:not(:empty) { color: var(--jn-coral); }

/* DepthCard — 3D mouse-tilt wrapper + spotlight. Ported from Astro
   DepthCard.astro <style>. */

.depth-card {
  perspective: var(--depth-perspective, 1000px);
  transform-style: preserve-3d;
  will-change: transform;
}
.depth-card__inner {
  position: relative;
  transform-style: preserve-3d;
  transition: transform 0.18s cubic-bezier(0.16, 1, 0.3, 1);
  will-change: transform;
}
.depth-card__spot {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
    circle 200px at var(--mx, 50%) var(--my, 50%),
    var(--depth-spot),
    transparent 60%
  );
  opacity: 0;
  transition: opacity 0.25s ease;
  mix-blend-mode: screen;
  z-index: 5;
}
.depth-card.is-hovering .depth-card__spot { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .depth-card__inner { transition: none; }
  .depth-card.is-hovering .depth-card__inner { transform: none !important; }
}

/* Flicker — canvas particle overlay. Absolute-positioned over a relative
   parent. Ported from Astro Flicker.astro <style>. */

.flicker {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}
.flicker__canvas {
  width: 100%;
  height: 100%;
  display: block;
}
@media (prefers-reduced-motion: reduce) {
  .flicker { opacity: 0.5; }
}

/* ============================================================
   Footer — brand + link columns + newsletter mini-form.
   Ported from Astro `Footer.astro` (branch master @ 73e884e).

   Replaces the previous `.jn-footer*` scaffold rules with the
   canonical `.site-footer*` ruleset so the v2 footer matches the
   Astro reference exactly (cyan column links, inline socials,
   mobile 3-row grid, scoped floating-label override).
   ============================================================ */

.site-footer {
  background: var(--bg-dark);
  color: var(--fg-on-dark);
  padding: var(--space-9) 0 var(--space-5);
  margin-top: var(--space-9);
}
.site-footer h2 {
  font-family: var(--font-stencil);
  font-size: 18px;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--fg-on-dark);
  margin-bottom: var(--space-3);
  line-height: 1.2;
}
.site-footer ul {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0;
  padding: 0;
}
/* Footer column links — cyan default, cream on hover. */
.site-footer ul a {
  color: var(--cyan-500);
  background: transparent !important;
  font-size: 14px;
  line-height: 1.5;
  text-decoration: none;
  transition: color var(--duration-fast);
}
.site-footer ul a:hover { color: var(--fg-on-dark); }
.site-footer p {
  font-size: 14px;
  color: rgba(240, 236, 225, 0.85);
  line-height: 1.55;
  margin-bottom: var(--space-3);
}

.footer-grid {
  display: grid;
  grid-template-columns: 1.2fr 1fr 1fr 1.4fr;
  gap: var(--space-6);
  margin-bottom: var(--space-7);
}
@media (max-width: 880px) {
  /* Brand + newsletter span full row; Art + About pair as 2 cols. */
  .footer-grid {
    grid-template-columns: 1fr 1fr;
  }
  .footer-brand,
  .footer-grid > div:last-child {
    grid-column: 1 / -1;
  }
}

/* Brand column — logo sized to roughly match the visual mass of the other
   columns' stencil h2 (so the column starts at parity). */
.footer-brand { display: flex; flex-direction: column; }
.footer-logo img { height: 72px; width: auto; }
.footer-tagline {
  font-family: var(--font-stencil);
  font-size: 18px;
  text-transform: uppercase;
  line-height: 1.2;
  color: var(--fg-on-dark);
  margin-top: var(--space-4);
  margin-bottom: 0;
  max-width: 260px;
}
.footer-meta {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: rgba(240, 236, 225, 0.55);
  margin: 0;
}
/* Meta + socials on one compact line below the tagline. */
.footer-meta-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-3);
}

.footer-subscribe-copy {
  font-size: 14px;
  color: rgba(240, 236, 225, 0.92);
  line-height: 1.55;
  margin-bottom: var(--space-3);
}
.footer-subscribe {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
/* Reset the global field flex-basis so the field hugs its input. */
.footer-subscribe .field { flex: 0 0 auto; }
/* Force the input bg to stay --bg-dark on focus + autofill. */
.footer-subscribe .field__input,
.footer-subscribe .field__input:focus {
  background-color: var(--bg-dark) !important;
}
/* Tone down the focus state — global focus ring is too bright on this dark band. */
.footer-subscribe .field__input:focus {
  border-color: rgba(240, 236, 225, 0.55) !important;
  box-shadow: none !important;
}
.footer-subscribe .field__input:-webkit-autofill,
.footer-subscribe .field__input:-webkit-autofill:hover,
.footer-subscribe .field__input:-webkit-autofill:focus,
.footer-subscribe .field__input:-webkit-autofill:active {
  -webkit-box-shadow: 0 0 0 1000px var(--bg-dark) inset !important;
  -webkit-text-fill-color: var(--fg-on-dark) !important;
  caret-color: var(--fg-on-dark);
  transition: background-color 9999s ease-out 0s;
}
/* Floating-label active state — scoped explicit override. The global
   `.field__input:not(:placeholder-shown) + .field__label` cascade doesn't
   reliably win in the scoped-CSS pipeline. */
.footer-subscribe .field__input:focus + .field__label,
.footer-subscribe .field__input:not(:placeholder-shown) + .field__label {
  top: -7px !important;
  transform: none !important;
  font-size: 11px !important;
  padding: 0 6px !important;
  z-index: 2;
  background: var(--bg-dark) !important;
  color: var(--cyan-500) !important;
}

.footer-base {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  padding-top: var(--space-5);
  border-top: 1px solid var(--border-dark);
}
.footer-base p { margin-bottom: 0; }

/* Social icons — compact pair that sits inline with the "Since 2006" meta. */
.footer-social {
  display: inline-flex;
  gap: var(--space-2);
  align-items: center;
}
.footer-social a {
  color: rgba(240, 236, 225, 0.92);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  transition: color var(--duration-fast);
}
.footer-social a i { font-size: 16px; line-height: 1; }
.footer-social a:hover { color: var(--cyan-500); }

.kicker a { color: var(--cyan-500); }

/* ============================================================
   Header — primary nav, submenu hover dropdowns, mobile hamburger.

   Ported from `Kovalik Design/Clients/Jeremy Novy/site/src/components/
   Header.astro` (branch master @ 73e884e). Visual rules:

   - Fixed flush to viewport top, full-width, dark band.
   - Sits OVER the body's 25px frame (passe-partout): top edge of body
     border is hidden behind the header bar.
   - Primary nav: 12px Roboto / weight 600 / 0.16em tracked / ALL-CAPS.
   - Cyan 2px animated underline on hover and current page.
   - Submenu: 3px cyan top-border accent, hard-cut (no shadow). 11px
     Roboto items, same tracking.
   - Hamburger: zero border-radius, three stripes, X on open.
   - Mobile nav: cyan stencil-bar ::before per item (8px parent, 4px
     sub, 16px current/hover).
   ============================================================ */

.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  background: var(--bg-dark-2);
  padding: 14px 0 0 0;
  border-bottom: 0;
}
@media (max-width: 999px) {
  .site-header { padding: 12px 0; }
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding-bottom: 14px;
}

#logo {
  background: transparent !important;
  padding: 0 !important;
  margin: 0 !important;
}
#logo img {
  width: auto;
  height: 50px;
  display: block;
  transition: opacity var(--duration-base);
}
#logo:hover img { opacity: 0.85; }

.primary-nav { display: block; }
.primary-nav > ul {
  display: flex;
  list-style: none;
  align-items: center;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
}
.primary-nav > ul > li { position: relative; }

/* Primary nav — small-caps tracked metadata pattern (Aurochs eyebrow spec). */
.primary-nav > ul > li > a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 12px 18px;
  color: var(--fg-on-dark);
  background: transparent !important;
  text-decoration: none;
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  position: relative;
  transition: color var(--duration-fast);
}
.primary-nav > ul > li > a span:first-child { position: relative; }

/* Animated cyan underline — 2px, confidence-level for irreverent brand voice. */
.primary-nav > ul > li > a span:first-child::after {
  content: '';
  position: absolute;
  bottom: -4px;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--cyan-500);
  transform-origin: left;
  transform: scaleX(0);
  transition: transform var(--duration-base) var(--ease-out);
}
.primary-nav > ul > li > a:hover span:first-child::after,
.primary-nav > ul > li > a.is-current span:first-child::after { transform: scaleX(1); }
.primary-nav > ul > li > a:hover { color: var(--cyan-500); }

.submenu-arrow {
  font-size: 10px;
  opacity: 0.7;
  line-height: 1;
  margin-left: 4px;
  transition: transform var(--duration-fast);
}
.has-submenu:hover .submenu-arrow { transform: translateY(2px); }

/* Submenu — hard-cut dark band with a 3px cyan top-border accent (halftone-
   cyan signature applied as a structural edge, NOT shadowed). No soft
   shadow per "Dark Punctuation". border-left would be the AI-slop tell. */
.submenu {
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 200px;
  background: var(--bg-dark);
  border-top: 3px solid var(--cyan-500);
  list-style: none;
  padding: var(--space-2) 0;
  margin: 0;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity var(--duration-fast), transform var(--duration-fast), visibility var(--duration-fast);
}
.has-submenu:hover .submenu,
.has-submenu:focus-within .submenu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.submenu li a {
  display: block;
  padding: 10px 18px;
  background: transparent !important;
  color: var(--fg-muted-on-dark);
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  transition: color var(--duration-fast), background-color var(--duration-fast);
}
.submenu li a:hover {
  color: var(--fg-on-dark);
  background: rgba(107, 205, 232, 0.08) !important;
}

/* Hamburger — hard-edge stripes, zero border-radius per "stencil aesthetic". */
.menu-toggle {
  display: none;
  width: 44px;
  height: 44px;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  padding: 0;
  background: transparent !important;
  border: 0;
  cursor: pointer;
}
.menu-toggle span {
  display: block;
  height: 2px;
  width: 24px;
  margin-inline: auto;
  background: var(--fg-on-dark);
  border-radius: 0;
  transition: transform var(--duration-fast) var(--ease-out), opacity var(--duration-fast);
}
.menu-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(8px) rotate(45deg); }
.menu-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.menu-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }
.menu-toggle:hover span { background: var(--cyan-500); }

/* Mobile nav — cyan stencil-bar ::before per item. Width + opacity encode
   hierarchy:
     Parent item:   8px bar at 60% opacity
     Submenu item:  4px bar at 35% opacity (visually demoted)
     Current page:  16px bar at 100% opacity + cyan text
     Hover/focus:   bar grows to 16px, opacity to 100%
   PFD-quick scanning of menu structure in one glance. */
.mobile-nav {
  border-top: 1px solid var(--border-dark);
  padding: 0 var(--gutter) var(--space-3);
  background: var(--bg-dark);
}
.mobile-nav ul {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0;
  margin: 0;
  padding: 0;
}
.mobile-nav li { border-bottom: 1px solid var(--border-dark); }
.mobile-nav li:last-child { border-bottom: 0; }
.mobile-nav a {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 8px;
  color: var(--fg-muted-on-dark);
  background: transparent !important;
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  transition: color var(--duration-fast);
}
.mobile-nav a::before {
  content: '';
  display: block;
  flex: 0 0 auto;
  width: 4px;
  height: 2px;
  background: var(--cyan-500);
  opacity: 0.35;
  transition: width var(--duration-base) var(--ease-out), opacity var(--duration-fast);
}
.mobile-nav a.is-parent { color: var(--fg-on-dark); }
.mobile-nav a.is-parent::before {
  width: 8px;
  opacity: 0.6;
}
.mobile-nav a.is-current { color: var(--cyan-500); }
.mobile-nav a.is-current::before {
  width: 16px;
  opacity: 1;
}
.mobile-nav a:hover,
.mobile-nav a:focus-visible { color: var(--cyan-500); }
.mobile-nav a:hover::before,
.mobile-nav a:focus-visible::before {
  width: 16px;
  opacity: 1;
}

@media (max-width: 999px) {
  .primary-nav { display: none; }
  .menu-toggle { display: inline-flex; }
}

/* Spacer — push body content below the fixed header. Calc matches the
   intrinsic header height: logo (50) + top padding (14) + bottom padding
   (14) + frame (25). Mobile uses a tighter total. */
body { padding-top: 0; }
main { margin-top: calc(50px + 14px + 14px + 25px); }
@media (max-width: 999px) {
  main { margin-top: calc(50px + 24px); }
}

/* ============================================================
   Hero3DText — letters fold from rotateX(-90deg) into place.
   Ported from Astro Hero3DText.astro <style> (branch master @ 73e884e).
   ============================================================ */

.hero-3d {
  perspective: var(--h3d-persp, 1200px);
  transform-style: preserve-3d;
  line-height: 1.18;
  margin: 0;
}
.hero-3d__line { display: block; }
.hero-3d__highlight {
  background-color: var(--bg-dark-2);
  padding: 0 4%;
  display: inline-block;
  transform-style: preserve-3d;
}
.hero-3d__char {
  display: inline-block;
  transform-origin: 50% 100%;
  transform: rotateX(-92deg) translateY(-30%);
  opacity: 0;
  will-change: transform, opacity;
  transition:
    transform var(--duration, 720ms) cubic-bezier(0.16, 1, 0.3, 1)
      calc(var(--line-i, 0) * var(--line-delay, 280ms) + var(--char-i, 0) * var(--stagger, 32ms)),
    opacity var(--duration, 720ms) ease
      calc(var(--line-i, 0) * var(--line-delay, 280ms) + var(--char-i, 0) * var(--stagger, 32ms));
}
.hero-3d.is-revealed .hero-3d__char {
  transform: rotateX(0deg) translateY(0);
  opacity: 1;
}

/* sr-only — visible to screen readers, hidden visually. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  .hero-3d__char {
    transform: none !important;
    opacity: 1 !important;
    transition: none !important;
  }
}

/* Image lightbox. */
.jn-lightbox__dialog {
  border: 0;
  padding: 0;
  background-color: transparent;
  max-width: min(95vw, 1400px);
  max-height: 95vh;
}

.jn-lightbox__dialog::backdrop {
  background-color: rgba(14, 12, 10, 0.92);
  backdrop-filter: blur(4px);
}

.jn-lightbox__img {
  display: block;
  max-width: 100%;
  max-height: 86vh;
  width: auto;
  height: auto;
  border-radius: var(--jn-radius-md);
}

.jn-lightbox__close {
  position: fixed;
  top: 1rem; right: 1rem;
  color: var(--jn-cream);
  font-size: 2.5rem;
  line-height: 1;
  width: 3rem; height: 3rem;
  background-color: rgba(14, 12, 10, 0.6);
  border-radius: 999px;
  border: 1px solid rgba(244, 236, 216, 0.2);
}
.jn-lightbox__close:hover { background-color: var(--jn-coral); color: var(--jn-ink); }

.jn-lightbox__cap {
  color: var(--jn-cream);
  text-align: center;
  margin-top: 1rem;
  font-family: var(--jn-font-mono);
  font-size: var(--jn-fs-small);
  letter-spacing: 0.08em;
}

/* ============================================================
   InnerHero — page-header bg-image + H1 overlay.
   Ported from Astro InnerHero.astro <style> (branch master @ 73e884e).
   Used on art, koi-numerology, books, press-kit, ar, about, contact.
   ============================================================ */

.inner-hero {
  position: relative;
  padding: 120px 0;
  background: var(--bg-dark);
  color: var(--fg-on-dark);
  overflow: hidden;
  margin-top: calc(0px - var(--space-8));
}
.inner-hero__bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  z-index: 0;
}
.inner-hero__bg::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(17, 20, 39, 0.5), rgba(17, 20, 39, 0.7));
}
.inner-hero .container {
  position: relative;
  z-index: 1;
  text-align: left;
}
.inner-hero h1 {
  color: var(--fg-on-dark);
  font-size: clamp(2.5rem, 7vw, 5rem);
  line-height: 1;
}
.inner-hero__subtitle {
  font-family: var(--font-display);
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  color: var(--fg-muted-on-dark);
  margin-top: var(--space-4);
}
@media (max-width: 999px) { .inner-hero { padding: 80px 0; } }

/* ============================================================
   Koi counter — homepage hero aside.
   Ported from Astro `KoiCounter.astro` (branch master @ 73e884e).
   ============================================================ */

.koi-counter {
  display: inline-flex;
  flex-direction: column;
  gap: 4px;
  padding: 18px 24px;
  color: var(--fg-on-dark);
  font-family: var(--font-display);
}
/* Tablet + below — hero stacks to single column. Zero horizontal padding so
   the counter content (cream stencil block + number) aligns with the H1's
   left edge. Vertical padding stays for breathing room between rows. */
@media (max-width: 999px) {
  .koi-counter { padding-inline: 0; }
}
/* Stencil-block surface comes from `.ds-stencil-block` utility (global.css).
   `align-self: flex-start` so the inline-block sizes to content inside the
   flex column instead of stretching full width. */
.koi-counter__label {
  font-size: 11px;
  letter-spacing: 0.16em;
  align-self: flex-start;
}
.koi-counter__num {
  font-family: var(--font-stencil);
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(2.5rem, 5vw, 4rem);
  line-height: 1;
  color: var(--fg-on-dark);
  font-variant-numeric: tabular-nums;
}
.koi-counter__plus {
  color: var(--warm-700);
  margin-left: 4px;
}
.koi-counter__latest {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: rgba(240, 236, 225, 0.65);
  line-height: 1;
}

/* KoiDivider — traced-koi SVG section divider. Ported from Astro
   KoiDivider.astro <style>. */

.koi-divider {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding-block: var(--space-6);
}
.koi-divider--center {
  justify-content: center;
  max-width: 720px;
  margin-inline: auto;
}
.koi-divider--left {
  justify-content: flex-start;
  max-width: none;
  margin-inline: 0;
}
.koi-divider__rule {
  flex: 1;
  height: 1px;
  background: var(--border);
  max-width: 200px;
}
.koi-divider--left .koi-divider__rule--trailing { max-width: none; }
.koi-divider__icon {
  height: var(--koi-size, 80px);
  width: auto;
  transform: rotate(var(--koi-rotate, 0deg));
  opacity: 0.85;
  transition: transform 0.6s var(--ease-out);
  flex-shrink: 0;
}
.koi-divider:hover .koi-divider__icon {
  transform: rotate(calc(var(--koi-rotate, 0deg) + 6deg));
}
@media (prefers-reduced-motion: reduce) {
  .koi-divider__icon { transition: none; }
  .koi-divider:hover .koi-divider__icon { transform: rotate(var(--koi-rotate, 0deg)); }
}

/* ============================================================
   Koi heatmap — full-bleed dark Leaflet map with bottom-anchored
   overlay text. Ported from Astro `KoiHeatmap.astro` (master @ 73e884e).

   Replaces the previous `.jn-heatmap*` scaffold rules with the
   canonical `.koi-heatmap*` ruleset so the v2 component matches
   the Astro reference behaviour exactly.
   ============================================================ */

.koi-heatmap {
  position: relative;
  width: 100vw;
  margin-inline: calc(50% - 50vw);
  margin-bottom: calc(-1 * var(--space-9));
  padding-block: 0;
  min-height: clamp(560px, 78vh, 820px);
  background: var(--bg-dark);
  overflow: hidden;
  isolation: isolate;
  /* Passe-partout bottom stripe matching the body's 25px frame. The
     section breaks out of the body frame horizontally (width: 100vw);
     this border re-establishes the bottom edge of the frame inside the
     full-bleed section. */
  border-bottom: 25px solid var(--bg-dark-2);
}

.koi-heatmap__map-wrap {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--bg-dark-2);
}
.koi-heatmap__map {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* Explicit z-index creates a stacking context so Leaflet's internal
     pane z-indexes (tilePane 200, markerPane 600, etc.) are confined
     here instead of escaping above the ocean-koi overlays. */
  z-index: 0;
}

/* Markers (circleMarker SVG dots in overlay-pane) fade during fly —
   Leaflet's CSS-scale zoom animation makes 2px dots blow up to ~30px
   mid-zoom otherwise. */
.koi-heatmap__map .leaflet-overlay-pane svg {
  transition: opacity 0.28s ease-out;
  will-change: opacity;
}
.koi-heatmap__map.is-autopanning .leaflet-overlay-pane svg {
  opacity: 0;
}

/* Heat canvas fades during fly. Leaflet.heat 0.2.0 draws blobs at FIXED
   screen-pixel radii (22px) — scaling the canvas during flyTo blows the
   radii up to ~352px on a 4-level zoom. Hide for the brief fly and snap
   back crisp at the destination once the plugin's _reset redraws. */
.koi-heatmap__map canvas.leaflet-heatmap-layer {
  transition: opacity 0.22s ease-out !important;
}
.koi-heatmap__map.is-autopanning canvas.leaflet-heatmap-layer {
  opacity: 0 !important;
}

/* Atmospheric overlay markup retained (display: none) for backwards-compat. */
.koi-heatmap__grain,
.koi-heatmap__vignette {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  display: none;
}

/* Decorative ocean koi imageOverlays — anchored to lat/lng so they pan
   and zoom with the map tiles. Mix-blend multiply against the dark
   basemap so they read as part of the continent silhouettes. */
.koi-heatmap__ocean-overlay {
  pointer-events: none;
  user-select: none;
  mix-blend-mode: multiply;
}

/* Heatmap canvas — Leaflet.heat 0.2.0 sets HTML width/height attrs but
   .leaflet-zoom-animated CSS forces width: 0. Override. */
.koi-heatmap__map canvas.leaflet-heatmap-layer {
  display: block !important;
  width: auto !important;
  height: auto !important;
  max-width: none !important;
  max-height: none !important;
}

.koi-heatmap__overlay {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 3;
  /* Generous bottom padding — gives the CTAs breathing room above the
     section's passe-partout border and matches the site's 8rem-ish
     section rhythm rule. */
  padding: var(--space-7) 0 var(--space-10);
  background: transparent;
  pointer-events: none;
}

/* Container row — non-interactive itself so empty space to the right
   passes drag to the underlying map; the inner text block re-enables
   pointer-events for content. */
.koi-heatmap__overlay-inner {
  pointer-events: none;
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.koi-heatmap__overlay-text {
  pointer-events: auto;
  max-width: 720px;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* Text-shadow on overlay text — soft drop shadow + tight halo for
   legibility over varied map content (heatmap bright zones). */
.koi-heatmap__overlay .eyebrow,
.koi-heatmap__heading,
.koi-heatmap__lead,
.koi-heatmap__stats strong,
.koi-heatmap__stats span {
  text-shadow: 0 2px 8px rgba(17, 20, 39, 0.75), 0 0 4px rgba(17, 20, 39, 0.55);
}

.koi-heatmap__overlay .eyebrow { color: var(--cyan-500); margin: 0; }

/* Desktop-only interaction hint — `shift+wheel` zoom doesn't exist on
   touch. Muted cream so it reads as a parenthetical annotation. */
.koi-heatmap__hint {
  display: none;
  color: rgba(240, 236, 225, 0.45) !important;
  font-size: 10px;
  margin-top: 2px !important;
}
@media (hover: hover) and (pointer: fine) {
  .koi-heatmap__overlay-text .koi-heatmap__hint { display: block; }
}

/* Tour toggle — inline button styled to match the surrounding eyebrow. */
.koi-heatmap__tour-toggle {
  background: transparent;
  border: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  letter-spacing: inherit;
  text-transform: inherit;
  transition: color 0.18s ease;
}
.koi-heatmap__tour-toggle:hover,
.koi-heatmap__tour-toggle:focus-visible {
  color: var(--cyan-500) !important;
  outline: 0;
}

.koi-heatmap__heading {
  font-family: var(--font-stencil);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0;
  font-size: clamp(2rem, 5vw, 3.5rem);
  line-height: 1;
  color: var(--fg-on-dark);
  margin: 0;
}
.koi-heatmap__lead {
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.65;
  color: var(--fg-muted-on-dark);
  max-width: 60ch;
  margin: 0;
}
.koi-heatmap__lead strong { color: var(--fg-on-dark); font-weight: 900; }

.koi-heatmap__stats {
  list-style: none;
  margin: var(--space-3) 0 var(--space-5);
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-6);
}
.koi-heatmap__stats li {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-top: var(--space-2);
  border-top: 3px solid var(--warm-700);
}
.koi-heatmap__stats strong {
  font-family: var(--font-stencil);
  font-weight: 700;
  font-size: clamp(1.5rem, 3vw, 2rem);
  line-height: 1;
  color: var(--fg-on-dark);
}
.koi-heatmap__stats span {
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--fg-muted-on-dark);
}

.koi-heatmap__cta { display: flex; gap: var(--space-3); flex-wrap: wrap; }

@media (max-width: 700px) {
  .koi-heatmap { min-height: clamp(640px, 88vh, 900px); }
  .koi-heatmap__overlay { padding-top: var(--space-7); }
  .koi-heatmap__stats { gap: var(--space-5); }
}

/* Leaflet container reset — kill default white tile borders. */
.leaflet-container {
  background: var(--bg-dark-2) !important;
  font-family: var(--font-body) !important;
}

/* Top-right zoom control stack — cream against the dark map, 40x40 hit
   targets inset inside the section edge so they clear the body frame. */
.koi-heatmap__map .leaflet-top.leaflet-right {
  top: 32px;
  right: 56px;
}
.koi-heatmap__map .leaflet-control-zoom {
  border: 0 !important;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.55) !important;
  margin: 0 !important;
  border-radius: 4px !important;
  overflow: hidden;
}
.koi-heatmap__map .leaflet-control-zoom a {
  background: rgba(240, 236, 225, 0.96) !important;
  color: var(--bg-dark) !important;
  border: 0 !important;
  border-bottom: 1px solid rgba(17, 20, 39, 0.18) !important;
  width: 40px !important;
  height: 40px !important;
  line-height: 40px !important;
  font-size: 22px !important;
  font-weight: 700;
}
.koi-heatmap__map .leaflet-control-zoom a:last-child {
  border-bottom: 0 !important;
}
.koi-heatmap__map .leaflet-control-zoom a:hover {
  background: var(--warm-700) !important;
  color: var(--fg-on-dark) !important;
}
.koi-heatmap__map .leaflet-control-zoom a.leaflet-disabled {
  background: rgba(240, 236, 225, 0.4) !important;
  color: rgba(17, 20, 39, 0.45) !important;
}

/* News card. */
.jn-news-card {
  display: block;
  background-color: white;
  border-radius: var(--jn-radius-md);
  overflow: hidden;
  box-shadow: var(--jn-shadow-card);
  color: inherit;
  transition: transform var(--jn-dur-fast) var(--jn-ease);
}
.jn-news-card:hover { transform: translateY(-2px); text-decoration: none; }

.jn-news-card__img-wrap { aspect-ratio: 16 / 9; overflow: hidden; }
.jn-news-card__img { width: 100%; height: 100%; object-fit: cover; }

.jn-news-card__body { padding: 1.25rem 1.5rem 1.5rem; }
.jn-news-card__date {
  font-family: var(--jn-font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--jn-fog);
}
.jn-news-card__title { margin-top: 0.5rem; font-size: 1.25rem; text-transform: none; letter-spacing: 0; line-height: 1.25; }
.jn-news-card__excerpt { margin-top: 0.75rem; color: var(--jn-text-on-cream); line-height: 1.5; }

.jn-news-card__tags { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1rem; }
.jn-news-card__tag {
  display: inline-block;
  font-family: var(--jn-font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 0.25rem 0.5rem;
  background-color: var(--jn-cream);
  border-radius: var(--jn-radius-sm);
}

/* Newsletter band. */
.jn-newsletter {
  padding-block: var(--jn-space-section);
  background-color: var(--jn-bg-dark-2);
  color: var(--jn-cream);
}

.jn-newsletter__container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4rem;
  align-items: center;
}

.jn-newsletter__copy .eyebrow { color: var(--jn-fog); margin-bottom: 0.5rem; }
.jn-newsletter__lead { margin-top: 0.75rem; color: var(--jn-fog); max-width: 38ch; }

.jn-newsletter__form {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.jn-newsletter__input {
  width: 100%;
  padding: 0.875rem 1rem;
  border: 1px solid rgba(244, 236, 216, 0.2);
  background-color: rgba(244, 236, 216, 0.04);
  color: var(--jn-cream);
  border-radius: var(--jn-radius-sm);
  font-size: 1rem;
}

.jn-newsletter__input:focus-visible { outline: 2px solid var(--jn-coral); outline-offset: 2px; }

.jn-newsletter__btn { width: max-content; }

.jn-newsletter__spinner {
  display: none;
  margin-left: 0.5rem;
}

.htmx-request .jn-newsletter__spinner { display: inline; }

.jn-newsletter__legal { font-size: var(--jn-fs-small); color: var(--jn-fog); }

@media (max-width: 820px) {
  .jn-newsletter__container { grid-template-columns: 1fr; gap: 2rem; }
}

/* ============================================================
   NumerologyHook — depth-narrative section, koi watermark + 3-cell
   numeral grid. Ported from Astro NumerologyHook.astro <style>
   (branch master @ 73e884e). Cream surface, hairline borders,
   coral numerals + top-border accents.
   ============================================================ */

.numerology-hook {
  position: relative;
  padding-block: var(--space-9);
  background: var(--bg);
  border-block: 1px solid var(--border);
  overflow: hidden; /* clips the koi watermark if it overflows */
}
.numerology-hook__container {
  position: relative;
  z-index: 1; /* lifts content above the watermark */
}

/* Koi watermark — large, low-opacity, right-side, slightly rotated.
   Sized to roughly match the grid height; positioned so it bleeds off
   the right edge for movement. */
.numerology-hook__bg-koi {
  position: absolute;
  top: 50%;
  right: -6%;
  width: clamp(380px, 42vw, 720px);
  height: auto;
  transform: translateY(-50%) rotate(-12deg);
  transform-origin: center;
  opacity: 0.07;
  filter: saturate(0) brightness(0.4);
  pointer-events: none;
  user-select: none;
  z-index: 0;
}
@media (max-width: 720px) {
  .numerology-hook__bg-koi {
    right: -25%;
    width: 90vw;
    opacity: 0.05;
  }
}

/* Eyebrow — concrete location/time. Coral mirrors the numerals so it
   reads as the same narrative voice. */
.numerology-hook__eyebrow {
  color: var(--warm-700);
  font-weight: 900;
}

.numerology-hook__title {
  margin-block: var(--space-3) var(--space-5);
}

/* Lead — 3 short paragraphs (setup / continuity / tension). The
   "one refused" closer gets slightly larger + heading-tinted text. */
.numerology-hook__lead {
  max-width: 64ch;
  margin-bottom: var(--space-7);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.numerology-hook__lead p {
  font-size: 17px;
  color: var(--fg);
  line-height: 1.55;
  margin: 0;
}
.numerology-hook__lead p:last-child {
  font-size: 18px;
  color: var(--fg-heading);
}

/* Numeral grid — 1 / 2 / 3 sequential. Uniform structure; narrative
   arc lives in the meaning labels, not in per-cell treatments. */
.numerology-hook__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-5);
  list-style: none;
  margin-bottom: var(--space-7);
  padding: 0;
}
@media (max-width: 720px) {
  .numerology-hook__grid { grid-template-columns: 1fr; gap: var(--space-4); }
}

.numerology-hook__cell {
  padding-top: var(--space-4);
  border-top: 3px solid var(--warm-700);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* Plain span — uniform stencil glyph, no scatter animation. */
.numerology-hook__num {
  display: block;
  font-family: var(--font-stencil);
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(4rem, 9vw, 6.5rem);
  line-height: 0.85;
  color: var(--warm-700);
  letter-spacing: -0.04em;
  margin-bottom: var(--space-2);
}

.numerology-hook__meaning {
  font-family: var(--font-stencil);
  font-weight: 700;
  text-transform: uppercase;
  font-size: 22px;
  color: var(--fg-heading);
  line-height: 1.1;
  margin: 0;
}
.numerology-hook__detail {
  font-size: 14px;
  color: var(--fg);
  line-height: 1.55;
  margin: 0;
}

.numerology-hook__cta {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin: 0;
}

/* Portfolio card. */
.jn-portfolio-card {
  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: 1 / 1;
  background-color: var(--jn-bg-dark-1);
  border-radius: var(--jn-radius-sm);
  cursor: pointer;
  text-align: left;
  padding: 0;
}

.jn-portfolio-card__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--jn-dur-base) var(--jn-ease);
}

.jn-portfolio-card:hover .jn-portfolio-card__img { transform: scale(1.04); }

.jn-portfolio-card__cap {
  position: absolute;
  inset: auto 0 0 0;
  padding: 0.75rem 1rem;
  background: linear-gradient(180deg, transparent 0%, rgba(14, 12, 10, 0.85) 100%);
  color: var(--jn-cream);
  opacity: 0;
  transition: opacity var(--jn-dur-fast) var(--jn-ease);
}

.jn-portfolio-card:hover .jn-portfolio-card__cap,
.jn-portfolio-card:focus-visible .jn-portfolio-card__cap { opacity: 1; }

.jn-portfolio-card__title {
  font-family: var(--jn-font-mono);
  font-size: var(--jn-fs-small);
  letter-spacing: 0.06em;
}

/* ============================================================
   Portfolio grid — 5-column responsive grid of square image tiles.
   Ported from Astro `PortfolioGrid.astro` (branch master @ 73e884e).
   Tiles are either lightbox triggers (<button>) or category links (<a>).
   ============================================================ */

.portfolio-grid {
  display: grid;
  /* 5 cols at desktop. Each tile is 1:1 aspect-ratio so as viewport grows
     past 1440 content-max the tiles scale up — still squares, just larger. */
  grid-template-columns: repeat(5, 1fr);
  gap: 4px;
}
@media (max-width: 1200px) { .portfolio-grid { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 900px)  { .portfolio-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 600px)  { .portfolio-grid { grid-template-columns: repeat(2, 1fr); } }

.portfolio-tile {
  display: block;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--bg-dark);
  position: relative;
  text-decoration: none !important;
  border: 0;
  padding: 0;
  cursor: pointer;
  transition: transform 0.4s var(--ease-out);
}
.portfolio-tile:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  z-index: 2;
}
.portfolio-tile img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.6s var(--ease-out), filter 0.4s ease;
  will-change: transform;
}
.portfolio-tile:hover { transform: translateY(-2px); }
.portfolio-tile:hover img {
  transform: scale(1.06);
  filter: brightness(0.78);
}
/* Client-side filter chip hides tiles whose data-categories don't include
   the active filter. */
.portfolio-tile.is-filtered-out { display: none !important; }

/* Solid punctuation tile — coral square breaking the rhythm. */
.portfolio-tile--solid {
  aspect-ratio: 1 / 1;
  display: block;
  cursor: default;
}

/* VIEW-ALL tile — coral cell filling the trailing empty slot at certain
   breakpoints (4-col 901-1200, 2-col ≤600). Hidden by default. */
.portfolio-tile--view-all {
  display: none;
  aspect-ratio: 1 / 1;
  background: var(--warm-700);
  color: var(--bg-dark);
  text-decoration: none !important;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-family: var(--font-stencil);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  line-height: 1.05;
  font-size: clamp(1rem, 1.6vw, 1.375rem);
  transition: background 0.18s ease, transform 0.4s var(--ease-out);
  padding: var(--space-3);
}
.portfolio-tile--view-all:hover {
  background: var(--warm-500);
  transform: translateY(-2px);
}
.portfolio-tile--view-all:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}
@media (min-width: 901px) and (max-width: 1200px) {
  .portfolio-tile--view-all { display: inline-flex; }
}
@media (max-width: 600px) {
  .portfolio-tile--view-all { display: inline-flex; }
}
@media (prefers-reduced-motion: reduce) {
  .portfolio-tile--view-all { transition: none; }
  .portfolio-tile--view-all:hover { transform: none; }
}

/* Caption overlay — bottom-anchored eyebrow + zoom icon on hover. */
.portfolio-tile__caption {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  padding: var(--space-4);
  color: var(--fg-on-dark);
  background: linear-gradient(180deg, transparent 55%, rgba(17, 20, 39, 0.78));
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.32s ease, transform 0.32s var(--ease-out);
  pointer-events: none;
}
.portfolio-tile:hover .portfolio-tile__caption,
.portfolio-tile:focus-visible .portfolio-tile__caption {
  opacity: 1;
  transform: translateY(0);
}
.portfolio-tile__caption-cats {
  font-family: var(--font-display);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-weight: 900;
  color: var(--cyan);
}
.portfolio-tile__caption-zoom {
  font-size: 18px;
  color: var(--fg-on-dark);
  line-height: 1;
}

@media (prefers-reduced-motion: reduce) {
  .portfolio-tile,
  .portfolio-tile img,
  .portfolio-tile__caption { transition: none; }
  .portfolio-tile:hover img { transform: none; }
}

/* ============================================================
   PRESS MAGAZINE — full-bleed image canvas with overlaid text.
   Ported from Astro `PressEditorial.astro` <style> block
   (branch master @ 73e884e), V4 asymmetric layout accepted
   2026-05-06 (Stefan). Image extends viewport-edge-to-edge
   (within the 25px body passe-partout frame); text overlays sit
   in a max-width 1440 centered band.
   ============================================================ */

.press-magazine {
  position: relative;
  width: 100%;
  background: var(--bg-dark-2);
  color: var(--fg-on-dark);
  /* 25px matches the body passe-partout — image inset by 25px on all
     four sides relative to the visible frame. */
  padding-block: 25px;
}

/* Viewport — the image canvas. Full width, aspect 16:10 with a max-
   height cap so tall viewports don't get a 1600px-high section. */
.press-magazine__viewport {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 10;
  max-height: 820px;
  overflow: hidden;
  background: var(--bg-dark-2);
}

/* Image stack — full-bleed, opacity-toggled. Gradient overlay removed
   2026-05-06 (Stefan, "hard cuts not gradients"). Legibility instead
   provided by per-overlay frosted pills on the index + identity. */
.press-magazine__spread-figure {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.42s cubic-bezier(0.16, 1, 0.3, 1);
}
.press-magazine__spread-figure.is-active { opacity: 1; }
.press-magazine__spread-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Overlay — absolute over the viewport. Pointer-events restored on
   interactive children only. */
.press-magazine__overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}
.press-magazine__overlay-inner {
  position: relative;
  width: 100%;
  height: 100%;
  max-width: var(--content-max);
  margin: 0 auto;
  padding: var(--space-5) var(--gutter);
}

/* Top-left head — eyebrow pill stacked above title pill. Both are
   inline-block via .ds-stencil-* surfaces; flex column with
   align-items: flex-start forces each onto its own line, sized to
   content. */
.press-magazine__head {
  position: absolute;
  top: var(--space-5);
  left: var(--gutter);
  right: var(--gutter);
  max-width: 70%;
  pointer-events: auto;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
}
/* Surface from .ds-stencil-pad. Eyebrow text uses coral. */
.press-magazine__eyebrow {
  font-family: var(--font-stencil);
  font-weight: 500;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--warm-700);
  margin: 0;
}
/* Surface (cream bg + black letters + asymmetric padding + stencil
   type) comes from .ds-stencil-block. Element-specific size only. */
.press-magazine__title {
  font-size: clamp(1.75rem, 3.5vw, 2.75rem);
  margin: 0;
}

/* Bottom-left identity (per-spread, opacity-toggled).
   No backdrop — text floats over the image with per-element pills. */
.press-magazine__identity {
  position: absolute;
  left: var(--gutter);
  bottom: var(--space-5);
  width: min(60%, 540px);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.42s cubic-bezier(0.16, 1, 0.3, 1);
}
.press-magazine__identity.is-active {
  opacity: 1;
  pointer-events: auto;
}
.press-magazine__id-eyebrow {
  font-family: var(--font-stencil);
  font-weight: 500;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--warm-700);
  align-self: flex-start;
}
.press-magazine__id-name {
  font-size: clamp(1.5rem, 3vw, 2.25rem);
  margin: 0;
  align-self: flex-start;
}
.press-magazine__id-desc {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.9375rem;
  line-height: 1.4;
  color: var(--fg-heading);
  margin: 0;
  max-width: 50ch;
  align-self: flex-start;
}
.press-magazine__id-cta {
  align-self: flex-start;
  margin-top: var(--space-2);
}

/* Right edge index — overlaid on the image, vertical numbered list.
   Cream "stencil paper" pill matches the head + identity treatment.
   Coral top accent rule anchors the panel. Sized to fit content. */
.press-magazine__index {
  position: absolute;
  top: 50%;
  right: var(--gutter);
  transform: translateY(-50%);
  width: 220px;
  display: flex;
  flex-direction: column;
  pointer-events: auto;
  background: var(--bg);
  border-top: 2px solid var(--warm-700);
  padding: var(--space-3);
  max-height: calc(100% - 2 * var(--space-5));
}
.press-magazine__index-scroll {
  list-style: none;
  margin: 0 0 var(--space-3);
  padding: 0;
  flex: 0 1 auto;
  overflow-y: auto;
  scrollbar-width: none;
}
.press-magazine__index-scroll::-webkit-scrollbar { display: none; }

.press-magazine__index-item {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  width: 100%;
  background: transparent;
  border: 0;
  padding: 6px 0;
  font-family: var(--font-stencil);
  font-weight: 500;
  font-size: 0.875rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--fg);
  text-align: left;
  cursor: pointer;
  line-height: 1.3;
  border-bottom: 1px solid rgba(17, 20, 39, 0.10);
  transition: color 0.18s ease, border-color 0.18s ease;
}
.press-magazine__index-item:hover { color: var(--bg-dark); }
.press-magazine__index-item.is-active {
  color: var(--bg-dark);
  font-weight: 700;
  border-bottom-color: var(--warm-700);
}
.press-magazine__index-item.is-active::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -3px;
  height: 2px;
  background: var(--warm-700);
  transform-origin: left center;
  transform: scaleX(0);
  animation: pressMagIndexProgress 6s linear forwards;
}
.press-magazine--paused .press-magazine__index-item.is-active::after {
  animation-play-state: paused;
}
@keyframes pressMagIndexProgress {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}
@media (prefers-reduced-motion: reduce) {
  .press-magazine__index-item.is-active::after {
    animation: none;
    transform: scaleX(0);
  }
}
.press-magazine__index-item:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}
.press-magazine__index-num {
  color: var(--warm-700);
  font-size: 10px;
  min-width: 22px;
  flex-shrink: 0;
}
.press-magazine__index-name { flex: 1; min-width: 0; }

.press-magazine__index-more {
  font-family: var(--font-display);
  font-size: 10px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--warm-700);
  text-decoration: none;
  border-top: 1px solid rgba(242, 108, 73, 0.5);
  padding-top: var(--space-3);
  transition: color 0.18s ease;
}
.press-magazine__index-more:hover { color: var(--bg-dark); }
.press-magazine__index-more:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

/* Mobile nav — hidden on desktop, shown below viewport at <768px. */
.press-magazine__mobile-nav { display: none; }

@media (max-width: 768px) {
  .press-magazine__index { display: none; }
  .press-magazine__head { max-width: 100%; }
  .press-magazine__identity { width: calc(100% - 2 * var(--gutter)); }
  .press-magazine__viewport {
    aspect-ratio: 4 / 5;
    max-height: 720px;
  }
  .press-magazine__mobile-nav {
    display: block;
    padding: var(--space-3) 0;
  }
  .press-magazine__mobile-scroll {
    display: flex;
    gap: var(--space-2);
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding: 0 var(--gutter);
  }
  .press-magazine__mobile-scroll::-webkit-scrollbar { display: none; }
  .press-magazine__mobile-pill {
    flex-shrink: 0;
    padding: 10px 16px;
    min-height: 44px;
    font-family: var(--font-stencil);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: rgba(240, 236, 225, 0.7);
    background: transparent;
    border: 1px solid rgba(240, 236, 225, 0.18);
    border-radius: 100px;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease;
  }
  .press-magazine__mobile-pill:hover {
    color: var(--fg-on-dark);
    border-color: rgba(107, 205, 232, 0.6);
  }
  .press-magazine__mobile-pill.is-active {
    color: var(--bg-dark);
    background: var(--cyan);
    border-color: var(--cyan);
  }
  .press-magazine__mobile-pill:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
  }
}

@media (prefers-reduced-motion: reduce) {
  .press-magazine__spread-figure,
  .press-magazine__identity { transition: none; }
}

/* Press modal — vanilla <dialog>. */
.jn-press-modal__dialog {
  border: 0;
  padding: 0;
  background-color: var(--jn-cream);
  color: var(--jn-ink);
  max-width: 640px;
  width: calc(100% - 2rem);
  border-radius: var(--jn-radius-md);
  box-shadow: var(--jn-shadow-modal);
}

.jn-press-modal__dialog::backdrop {
  background-color: rgba(14, 12, 10, 0.7);
  backdrop-filter: blur(2px);
}

.jn-press-modal__inner { padding: 2rem; position: relative; }

.jn-press-modal__close {
  position: absolute;
  top: 0.5rem; right: 0.75rem;
  font-size: 1.75rem; line-height: 1;
  color: var(--jn-fog);
  width: 2rem; height: 2rem;
  border-radius: var(--jn-radius-sm);
}
.jn-press-modal__close:hover { color: var(--jn-ink); background-color: rgba(0, 0, 0, 0.04); }

.jn-press-modal__outlet {
  font-family: var(--jn-font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--jn-coral);
}

.jn-press-modal__title {
  margin-top: 0.5rem;
  font-size: 1.5rem;
  letter-spacing: 0;
  text-transform: none;
  line-height: 1.2;
}

.jn-press-modal__meta { color: var(--jn-fog); font-size: var(--jn-fs-small); margin-top: 0.5rem; }
.jn-press-modal__summary { margin-top: 1rem; line-height: 1.55; }
.jn-press-modal__attribution { margin-top: 0.75rem; color: var(--jn-fog); }
.jn-press-modal__cta { margin-top: 1.5rem; }

/* Product card. */
.jn-product-card {
  display: block;
  background-color: white;
  border-radius: var(--jn-radius-md);
  overflow: hidden;
  box-shadow: var(--jn-shadow-card);
  transition: transform var(--jn-dur-fast) var(--jn-ease), box-shadow var(--jn-dur-fast) var(--jn-ease);
  color: inherit;
}

.jn-product-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(14, 12, 10, 0.06), 0 16px 40px rgba(14, 12, 10, 0.1);
  text-decoration: none;
}

.jn-product-card__img-wrap {
  position: relative;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background-color: var(--jn-cream);
}

.jn-product-card__img { width: 100%; height: 100%; object-fit: cover; }

.jn-product-card__badge {
  position: absolute;
  top: 0.75rem; right: 0.75rem;
  background-color: var(--jn-ink);
  color: var(--jn-cream);
  font-family: var(--jn-font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 0.25rem 0.5rem;
  border-radius: var(--jn-radius-sm);
}

.jn-product-card__body { padding: 1rem 1.25rem 1.25rem; }
.jn-product-card__cat {
  font-family: var(--jn-font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--jn-fog);
  margin-bottom: 0.5rem;
}

.jn-product-card__title { font-size: 1.125rem; text-transform: none; letter-spacing: 0; line-height: 1.2; }
.jn-product-card__sub { color: var(--jn-fog); font-size: var(--jn-fs-small); margin-top: 0.25rem; }
.jn-product-card__price {
  font-family: var(--jn-font-mono);
  font-weight: 700;
  margin-top: 0.75rem;
  color: var(--jn-coral);
}
.jn-product-card__edition { color: var(--jn-fog); font-weight: 400; }

/* SilkWaves — WebGL2 backdrop layer. Use absolute-positioned inside a
   relative parent (or `position: fixed`/`absolute` on a utility class).
   Ported from Astro SilkWaves.astro <style>. */

.silk-waves {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  pointer-events: none;
  background: transparent;
}
.silk-waves__canvas {
  width: 100%;
  height: 100%;
  display: block;
}

/* ============================================================
   SmoothCursor — canvas overlay for cursor trail.
   Ported from Astro SmoothCursor.astro <style> (branch master @ 73e884e).
   Disabled on touch + reduced-motion.
   ============================================================ */

.smooth-cursor {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 80;
  opacity: 0;
  transition: opacity 0.4s ease;
}
.smooth-cursor.is-active { opacity: 1; }
.smooth-cursor__canvas { width: 100%; height: 100%; display: block; }

@media (prefers-reduced-motion: reduce),
       (hover: none),
       (pointer: coarse) {
  .smooth-cursor { display: none !important; }
}

/* World map. */
.jn-world-map { display: block; }

.jn-world-map__list { padding-block: var(--jn-space-section); }
.jn-world-map__list h2 { margin-bottom: 2rem; }

.jn-world-map__list-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}

@media (max-width: 980px) { .jn-world-map__list-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .jn-world-map__list-grid { grid-template-columns: 1fr; } }

.jn-world-map__list-item { background-color: rgba(244, 236, 216, 0.04); border-radius: var(--jn-radius-md); }

.jn-world-map__list-link { display: block; padding: 1.25rem 1.5rem; color: var(--jn-cream); }
.jn-world-map__list-link:hover { color: var(--jn-coral); text-decoration: none; }

.jn-world-map__list-title { font-size: 1.125rem; text-transform: none; letter-spacing: 0; }
.jn-world-map__list-meta { font-family: var(--jn-font-mono); font-size: 0.75rem; color: var(--jn-fog); margin-top: 0.25rem; letter-spacing: 0.06em; }

/* ============================================================
   /about/ — bio, credentials, resume.
   Ported from Astro `about.astro` <style> (branch master @ 73e884e).
   Animation components (Hero3DText, SilkWaves, Flicker, BlurHighlight,
   DepthCard, KoiDivider) deferred — :global() wrappers and animation-
   layer styles removed.
   ============================================================ */

/* HERO */
.about-hero {
  position: relative;
  padding: 180px 0 140px;
  color: var(--fg-on-dark);
  overflow: hidden;
  margin-top: calc(0px - var(--space-8));
  background: var(--bg-dark);
}
/* SilkWaves backdrop — full-bleed, behind the hero content. */
.about-hero__silk {
  position: absolute !important;
  inset: 0;
  z-index: 0;
  mix-blend-mode: screen;
  pointer-events: none;
}
/* Flicker overlay — particles on top of the silk waves. */
.about-hero__flicker {
  position: absolute !important;
  inset: 0;
  z-index: 0;
  mix-blend-mode: screen;
  opacity: 0.6;
  pointer-events: none;
}
.about-hero__container {
  position: relative;
  z-index: 1;
  text-align: left;
}
.about-hero .eyebrow {
  color: var(--cyan-500);
  margin-bottom: var(--space-3);
}
/* Hero3DText drops in for the "Jeremy / Novy" headline — override the
   component's default highlight padding (cream block) to render trans-
   parent against the dark hero. Scale matches the legacy proportion. */
.about-hero .hero-3d {
  color: var(--fg-on-dark);
  font-size: clamp(3.5rem, 11vw, 8rem);
  margin: 0;
}
.about-hero .hero-3d__highlight {
  background-color: transparent;
  padding: 0;
}
.about-hero__tagline {
  font-family: var(--font-display);
  font-size: clamp(1rem, 1.6vw, 1.25rem);
  color: var(--fg-muted-on-dark);
  margin-top: var(--space-5);
  max-width: 540px;
  line-height: 1.5;
}
@media (max-width: 999px) {
  .about-hero { padding: 130px 0 90px; }
}

/* CREDENTIALS */
.about-credentials { padding-block: var(--space-9); }
.about-credentials__head { margin-bottom: var(--space-6); }
.about-credentials__head h2 { margin-top: var(--space-2); }
.credentials-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: var(--space-4);
  list-style: none;
  padding: 0;
  margin: 0;
}
.cred-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
  background: var(--bg);
  border: 1px solid var(--border);
  border-top: 3px solid var(--warm-700);
  height: 100%;
  min-height: 132px;
  transition: transform 0.18s var(--ease-out), box-shadow 0.18s ease;
}
.cred-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(17, 20, 39, 0.06);
}
.cred-card__label {
  font-family: var(--font-display);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  color: var(--fg-heading);
  font-weight: 900;
}
.cred-card__detail {
  font-size: 14px;
  color: var(--fg-body);
  line-height: 1.5;
}
.cred-card__detail em { color: var(--fg-heading); font-style: italic; }

/* BIO */
.about-bio { padding-block: var(--space-9); }
.about-bio__head { margin-bottom: var(--space-6); }
.about-bio__head h2 { margin-top: var(--space-2); max-width: 720px; }
.about-bio__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  max-width: 720px;
}
.about-bio__body p {
  display: block;
  font-size: clamp(1rem, 1.4vw, 1.125rem);
  line-height: 1.75;
  color: var(--fg-body);
  margin: 0;
}
.about-bio__lead { font-weight: var(--fw-regular); }

/* RESUME */
.about-resume {
  padding-block: var(--space-9);
  background: var(--bg);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.about-resume__head { margin-bottom: var(--space-6); }
.about-resume__head h2 { margin-top: var(--space-2); }
.resume-list {
  list-style: none;
  max-width: 760px;
  margin: 0;
  padding: 0;
}
.resume-list li {
  display: grid;
  grid-template-columns: 90px 1fr;
  gap: var(--space-4);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--border);
  line-height: 1.55;
}
.resume-list li:last-child { border-bottom: 0; }
.resume-list strong {
  font-family: var(--font-stencil);
  color: var(--warm-700);
  font-size: 22px;
  letter-spacing: 0;
}
.resume-list em { color: var(--fg-heading); font-style: italic; }

/* /ar/ — WebAR landing. Ported from Astro ar.astro <style>. */

.ar-launch { padding-block: var(--space-9); }
.ar-frame {
  aspect-ratio: 9 / 16;
  max-height: 80vh;
  margin: 0 auto;
  background: var(--bg-dark);
  overflow: hidden;
}
.ar-frame iframe { width: 100%; height: 100%; border: 0; }
.ar-fallback {
  text-align: center;
  color: var(--fg-faint);
  margin-top: var(--space-3);
}

.ar-how { padding-block: var(--space-7); }
.ar-how h2 { margin-bottom: var(--space-5); }
.ar-how ol {
  list-style: none;
  counter-reset: step;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  max-width: 720px;
  padding: 0;
  margin: 0;
}
.ar-how li {
  counter-increment: step;
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--space-4);
  padding-left: var(--space-3);
  border-left: 2px solid var(--cyan-500);
}
.ar-how li::before {
  content: counter(step, decimal-leading-zero);
  font-family: var(--font-stencil);
  font-size: 28px;
  color: var(--cyan-500);
}
.ar-how strong {
  display: block;
  color: var(--fg-heading);
  margin-bottom: 4px;
}

/* ============================================================
   /art/ + /art/[category]/ — InnerHero + filter chip rail + grid
   + "Want a piece?" cream CTA band. Ported from Astro art/index.astro
   and art/[category].astro <style> blocks (branch master @ 73e884e).
   ============================================================ */

.art-filters { padding-block: var(--space-6) var(--space-3); }
.filter-list {
  display: flex;
  gap: var(--space-2);
  list-style: none;
  flex-wrap: wrap;
  justify-content: center;
  padding: 0;
  margin: 0;
}
.filter-list a {
  padding: 8px 16px;
  font-family: var(--font-display);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  color: var(--fg-body);
  background: transparent !important;
  border: 1px solid var(--border);
  border-radius: 4px;
  text-decoration: none;
  transition: border-color 0.15s ease, color 0.15s ease;
  display: inline-block;
}
.filter-list a:hover, .filter-list a.is-current {
  border-color: var(--cyan-500);
  color: var(--cool-300) !important;
}

.art-grid { padding-block: var(--space-6) var(--space-9); }

/* Bottom CTA — cream surface, on /art/[category]/ only. */
.art-cta { padding-block: var(--space-9); }
.art-cta h2 { margin-bottom: var(--space-3); }
.art-cta p { margin-bottom: var(--space-5); }

/* /books/ — bibliography. Ported from Astro books.astro <style>. */

.books-list { padding-block: var(--space-9); }
.book-row {
  display: grid;
  grid-template-columns: 1fr 3fr;
  gap: var(--space-6);
  padding: var(--space-7) 0;
  border-bottom: 1px solid var(--border);
  align-items: start;
}
.book-row:last-child { border-bottom: none; }
@media (max-width: 720px) {
  .book-row { grid-template-columns: 1fr; }
}

.book-row__cover {
  aspect-ratio: 2 / 3;
  background: var(--bg-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--space-3);
  border: 1px solid var(--border);
}
.book-row__cover .kicker {
  font-family: var(--font-stencil);
  text-transform: uppercase;
  color: var(--fg-heading);
  font-size: 16px;
  line-height: 1.2;
}

.book-row h2 {
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  margin-bottom: var(--space-2);
}
.book-row__author {
  font-family: var(--font-display);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  color: var(--fg-faint);
  margin-bottom: var(--space-3);
}
.book-row__summary {
  color: var(--fg-body);
  line-height: 1.7;
  margin-bottom: var(--space-4);
  max-width: 640px;
}

/* ============================================================
   CONTACT PAGE — based on matt.aurochs.agency/contact/ pattern.
   Two-column inquiry section over cream, then a dark commissions
   band that anchors the existing /about/#commissions link.
   Ported from Astro `contact.astro` <style> (branch master @ 73e884e).
   ============================================================ */

.contact-primary { padding-block: var(--space-9); }
.contact-primary__grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  gap: clamp(32px, 5vw, 80px);
  align-items: start;
}
@media (max-width: 880px) {
  .contact-primary__grid { grid-template-columns: 1fr; gap: var(--space-7); }
}
.contact-primary__head { margin-bottom: var(--space-6); }
.contact-primary__head h2 { margin-top: var(--space-2); }
.contact-primary__lead {
  margin-top: var(--space-3);
  color: var(--fg);
  font-size: 16px;
  max-width: 56ch;
  line-height: 1.6;
}

.contact-form { display: flex; flex-direction: column; gap: var(--space-3); }
.contact-form__row { display: flex; flex-direction: column; gap: var(--space-3); }
/* Critical override — the global `.field` rule has `flex: 1 1 240px`,
   which makes sense in a flex ROW. Inside `.contact-form` we use column
   flex, where flex-basis 240px makes each field 240px tall, parking the
   absolute-positioned floating label halfway down an empty box. Reset
   flex so it sizes to its content. */
.contact-form .field { flex: 0 0 auto; }
.contact-form__row--split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
}
@media (max-width: 560px) {
  .contact-form__row--split { grid-template-columns: 1fr; }
}
.contact-form__actions {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-top: var(--space-3);
}

/* CONDITIONAL FIELD GROUPS — visually distinct band that reveals when
   the inquiry-type dropdown selects a value that has extra context to
   gather. Soft cream-tint background + left coral rule reads as "this
   section is contextual, not the main form" — keeps the user oriented
   that they're answering a follow-up, not a parallel form.

   IMPORTANT: scope every visual rule to `:not([hidden])`. Otherwise the
   class's `display: flex` overrides the `[hidden]` attribute's default
   `display: none` (equal specificity, later-rule-wins) and every group
   renders simultaneously. */
.contact-form__conditional[hidden] { display: none !important; }
.contact-form__conditional:not([hidden]) {
  background: rgba(242, 108, 73, 0.04);
  padding: var(--space-4) var(--space-4) var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  animation: contactConditionalReveal 0.32s var(--ease-out) both;
}
@keyframes contactConditionalReveal {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .contact-form__conditional { animation: none; }
}
.contact-form__conditional-label {
  margin: 0;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--warm-700);
}
.form-status {
  margin: 0;
  font-family: var(--font-display);
  font-size: 13px;
  color: var(--fg-faint);
}
.form-status.is-error { color: var(--warm-700); font-weight: 700; }
.form-status.is-ok    { color: var(--cool-700); }

/* Select rendered with the same floating-label .field treatment.
   Native control with custom chevron — preserves keyboard a11y. */
.field--select { position: relative; }
.field__select {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  padding: 22px 36px 6px 14px;
  background: transparent;
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--fg);
  cursor: pointer;
  line-height: 1.5;
  min-height: 56px;
}
.field__select:focus {
  outline: none;
  border-color: var(--cyan-500);
  box-shadow: var(--focus-ring);
}
.field--select::after {
  content: '';
  position: absolute;
  right: 14px;
  top: 50%;
  width: 10px;
  height: 10px;
  border-right: 2px solid var(--fg-faint);
  border-bottom: 2px solid var(--fg-faint);
  transform: translateY(-65%) rotate(45deg);
  pointer-events: none;
}

/* RIGHT — direct contact + studio + social. */
.contact-primary__info-col {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
.contact-info-card {
  background: var(--bg-warm);
  border: 1px solid var(--border);
  border-top: 3px solid var(--warm-700);
  padding: var(--space-4) var(--space-5);
}
.contact-info-card__heading {
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--warm-700);
  margin: 0 0 var(--space-3) 0;
}
.contact-info-card__addr {
  margin: 0;
  color: var(--fg);
  line-height: 1.6;
}
.contact-info-card__addr-note {
  margin: var(--space-2) 0 0 0;
  color: var(--fg-faint);
  font-size: 13px;
}

.contact-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.contact-list li {
  display: grid;
  grid-template-columns: 110px 1fr;
  gap: var(--space-2);
  align-items: baseline;
  padding-block: 6px;
  border-bottom: 1px solid rgba(17, 20, 39, 0.06);
}
.contact-list li:last-child { border-bottom: 0; }
.contact-list strong {
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--fg-faint);
}
.contact-list a { word-break: break-word; }

.contact-social {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.contact-social a {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--fg);
  text-decoration: none;
  transition: color 0.18s ease;
}
.contact-social a:hover { color: var(--warm-700); }
.contact-social i { width: 18px; text-align: center; color: var(--fg-faint); }

/* COMMISSIONS BAND — dark surface, same content that was on
   /about/#commissions. */
.contact-commissions {
  background: var(--bg-dark);
  color: var(--fg-on-dark);
  padding-block: var(--space-9);
  position: relative;
}
.contact-commissions__head { margin-bottom: var(--space-6); max-width: 60ch; }
.contact-commissions__head .eyebrow { color: var(--cyan-500); }
.contact-commissions__head h2 { color: var(--fg-on-dark); margin-top: var(--space-2); }

.commissions-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}
@media (max-width: 880px) { .commissions-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .commissions-grid { grid-template-columns: 1fr; } }
.commissions-card {
  background: rgba(240, 236, 225, 0.05);
  border-top: 3px solid var(--warm-700);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.commissions-card strong {
  font-family: var(--font-stencil);
  font-weight: 700;
  font-size: clamp(2.5rem, 5vw, 3.5rem);
  line-height: 0.9;
  color: var(--warm-700);
}
.commissions-card span {
  font-family: var(--font-display);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--fg-on-dark);
}

.contact-commissions__cta { margin: 0 0 var(--space-3); }
.contact-commissions__note {
  margin: 0;
  font-family: var(--font-display);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--fg-faint);
  font-style: italic;
}

/* ============================================================
   Home page — section-by-section styles.
   Ported from Astro `src/pages/index.astro` <style> block
   (branch master @ 73e884e).
   ============================================================ */

/* ── HERO — photograph as thesis statement ──────────────────── */
.hero {
  position: relative;
  /* Desktop: no viewport-based height. On tall monitors (1440p portrait,
     4K) 88vh produces an over-tall hero; the 250px symmetric padding
     gives the headline + CTAs the room they need, and content height
     settles around 640-720px naturally. Mobile (<=999px) uses vh-based
     min-height because the hero IS the fold on a phone. */
  padding: 250px 0;
  background: var(--bg-dark);
  color: var(--fg-on-dark);
  overflow: hidden;
  margin-top: calc(0px - var(--space-8));
}
.hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image: url('/images/hero-koi-los-sanchez.jpg');
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  will-change: transform;
  /* scale(1.4) = 40% extra each direction → 20% overscan top + 20% bottom.
     Pairs with STRENGTH=0.2 in the parallax script — max bg travel = 20%
     of hero height, fits exactly in the 20% overscan buffer so edges never
     reveal. */
  transform: translate3d(0, 0, 0) scale(1.4);
  transform-origin: center;
}
/* Overlay scoped inside the bg layer so it stacks below .hero__container
   (no z-index race against text/buttons). Light gradient — enough contrast
   for the stencil headline without dimming the CTAs. */
.hero__bg::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    rgba(10, 13, 24, 0.08) 0%,
    rgba(10, 13, 24, 0.20) 60%,
    rgba(10, 13, 24, 0.32) 100%
  );
}
@media (prefers-reduced-motion: reduce) {
  .hero__bg { transform: none; will-change: auto; }
}
.hero__container {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: var(--space-7);
  align-items: end;
}
@media (max-width: 999px) {
  .hero__container { grid-template-columns: 1fr; gap: var(--space-6); }
  .hero { padding: 120px 0; min-height: 75vh; }
}

/* Stencil h1 — filled-block: black text on cream blocks, one word per line. */
.hero-stencil {
  font-family: var(--font-stencil);
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(2.75rem, 9vw, 6rem);
  line-height: 1;
  letter-spacing: 0;
  color: var(--fg-on-dark);
  margin: 0 0 var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.hero-stencil__line {
  display: block;
  width: fit-content;
}
.hero-stencil__highlight {
  display: inline-block;
  background: var(--bg);
  color: var(--bg-dark-2);
  padding: 0.05em 0.5em 0.05em 0.2em;
  line-height: 1.1;
}

.hero__cta {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.hero__aside {
  display: flex;
  justify-content: flex-end;
  align-items: flex-end;
}
@media (max-width: 999px) {
  .hero__aside { justify-content: flex-start; }
}

/* ============================================================
   PORTFOLIO — full-width gallery on dark surface (Stefan 2026-05-06).
   Header (eyebrow + All work + chips) in a max-width 1440 inner wrap;
   grid extends edge-to-edge of the body content area (matches press-
   magazine pattern). KoiDivider retired — dark-on-dark transition
   between press and portfolio already provides visual rhythm.
   ============================================================ */
.home-portfolio {
  padding-block: 25px; /* matches the body 25px passe-partout frame */
  background: var(--bg-dark-2);
  color: var(--fg-on-dark);
}
.home-portfolio__head-wrap {
  max-width: var(--content-max);
  margin: 0 auto;
  padding: 0 var(--gutter) var(--space-4);
}
.home-portfolio__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}
.home-portfolio__head .eyebrow {
  margin: 0;
  color: var(--cyan-500);
}
/* "All work →" CTA — outlined pill matching the eyebrow's typographic
   register (11px stencil ALL-CAPS 0.16em). Hard-edge border. */
.home-portfolio__all {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-stencil);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 6px 14px;
  border: 1px solid var(--cyan);
  border-radius: 0;
  line-height: 1.2;
  color: var(--cyan);
  transition: background 0.15s ease, color 0.15s ease;
}
.home-portfolio__all:hover {
  background: var(--cyan);
  color: var(--bg-dark-2);
}
.home-portfolio__all:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

/* Filter chip row above portfolio grid — uses .ds-eyebrow-badge--filled
   for active state. Dark-surface overrides — chips read on near-black. */
.home-portfolio__chips {
  list-style: none;
  margin: 0 0 var(--space-5);
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.home-portfolio__chips .ds-eyebrow-badge {
  border-color: rgba(240, 236, 225, 0.28);
  color: var(--fg-on-dark);
}
.home-portfolio__chips .ds-eyebrow-badge:hover {
  border-color: var(--cyan);
  color: var(--cyan);
}
.home-portfolio__chips .ds-eyebrow-badge--filled.is-active {
  background: var(--cyan);
  border-color: var(--cyan);
  color: var(--bg-dark-2);
}

/* ============================================================
   LIKE WHAT YOU SEE — 2-col: dark + stencil + CTAs / single feature image.
   Slideshow runs animationend-driven cycle matching the press-magazine
   rhythm. 7 images opacity-toggled in place. Dots above the eyebrow.
   ============================================================ */
.like-what {
  background: var(--bg-dark-2);
  color: var(--fg-on-dark);
  padding-block: 0;
}
.like-what__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: stretch;
  min-height: 640px;
}
@media (max-width: 999px) {
  .like-what__grid { grid-template-columns: 1fr; }
  .like-what__feature { aspect-ratio: 4 / 3; }
}
.like-what__copy {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-block: clamp(40px, 6vw, 96px);
  padding-left: max(var(--gutter), calc((100vw - var(--content-max)) / 2 + var(--gutter)));
  padding-right: clamp(24px, 5vw, 80px);
  gap: var(--space-4);
}
@media (max-width: 999px) {
  .like-what__copy { padding-inline: var(--gutter); }
}
.like-what__heading {
  margin: 0;
  line-height: 1.18;
  font-family: var(--font-stencil);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0;
  font-size: clamp(2rem, 5vw, 3.5rem);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
}
.like-what__heading span {
  color: var(--fg-on-dark);
  display: inline-block;
}
.like-what__caption {
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--fg-muted-on-dark);
  margin: 0;
  letter-spacing: 0;
}
/* Primer — single 12-word claim. Cyan stencil credibility ribbon. */
.like-what__primer {
  font-family: var(--font-stencil);
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cyan);
  margin: 0;
}
.like-what__cta {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-top: var(--space-3);
}

.like-what__feature {
  position: relative;
  margin: 0;
  background: var(--bg-dark-2);
  overflow: hidden;
  isolation: isolate;
  box-shadow: var(--shadow-flank-amber);
}
.like-what__feature-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.6s var(--ease-out);
  will-change: opacity;
}
.like-what__feature-img.is-active { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .like-what__feature-img { transition: none; }
}

.like-what__caption-overlay {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 2;
  padding: clamp(20px, 3vw, 32px) clamp(20px, 3vw, 32px) clamp(24px, 3vw, 36px);
  background: linear-gradient(180deg, transparent 0%, rgba(10, 10, 14, 0.85) 100%);
  color: var(--fg-on-dark);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.like-what__dots {
  display: flex;
  gap: 10px;
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-2) 0;
}
.like-what__dot {
  width: 9px;
  height: 9px;
  padding: 0;
  border: 1px solid rgba(240, 236, 225, 0.55);
  background: transparent;
  border-radius: 50%;
  cursor: pointer;
  transition: background 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}
.like-what__dot:hover { border-color: var(--warm-700); }
.like-what__dot.is-active {
  background: var(--warm-700);
  border-color: var(--warm-700);
  transform: scale(1.15);
}
.like-what__dot:focus-visible { outline: none; box-shadow: var(--focus-ring); }

.like-what__cap-stack {
  display: none;
  flex-direction: column;
  gap: 4px;
}
.like-what__cap-stack.is-active { display: flex; }
.like-what__cap-eyebrow {
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--cyan-500);
}
.like-what__cap-title {
  position: relative;
  font-family: var(--font-stencil);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0;
  font-size: clamp(1.25rem, 2.2vw, 1.75rem);
  line-height: 1.1;
  color: var(--fg-on-dark);
  padding-bottom: 8px;
  display: inline-block;
  border-bottom: 1px solid rgba(240, 236, 225, 0.18);
}
.like-what__cap-stack.is-active .like-what__cap-title::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: var(--warm-700);
  transform-origin: left center;
  transform: scaleX(0);
  animation: likeWhatProgress 6s linear forwards;
}
.like-what--paused .like-what__cap-stack.is-active .like-what__cap-title::after {
  animation-play-state: paused;
}
@keyframes likeWhatProgress {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}
@media (prefers-reduced-motion: reduce) {
  .like-what__cap-stack.is-active .like-what__cap-title::after {
    animation: none;
    transform: scaleX(0);
  }
}

/* ============================================================
   HOME-NEWSLETTER — photo-bg variant (Stefan 2026-05-17).
   Full-bleed Asian Art Museum scale-dots photo + dark overlay for
   legibility + cream type. Segmented-bar form (input + submit fused).
   ============================================================ */
.home-newsletter {
  position: relative;
  isolation: isolate;
  padding-block: var(--space-9);
  color: var(--fg-on-dark);
  background: var(--bg-dark);
  overflow: hidden;
  border-top: 25px solid var(--bg-dark-2);
  border-bottom: 25px solid var(--bg-dark-2);
}
.home-newsletter__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image: url("/images/newsletter/asian-art-museum-scale-dots.jpg");
  background-size: cover;
  background-position: center 75%;
  background-repeat: no-repeat;
  pointer-events: none;
}
@media (max-width: 720px) {
  .home-newsletter__bg { background-position: center center; }
}
.home-newsletter__overlay {
  position: absolute;
  inset: 0;
  z-index: 0;
  background:
    linear-gradient(90deg, rgba(10, 10, 14, 0.55) 0%, rgba(10, 10, 14, 0.70) 60%, rgba(10, 10, 14, 0.78) 100%);
  pointer-events: none;
}
.home-newsletter .container { position: relative; z-index: 1; }
.newsletter-grid {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: var(--space-7);
  align-items: center;
}
@media (max-width: 880px) { .newsletter-grid { grid-template-columns: 1fr; } }
.home-newsletter__heading {
  font-family: var(--font-stencil);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0;
  font-size: clamp(2.25rem, 5vw, 3.75rem);
  line-height: 1.05;
  color: var(--fg-on-dark);
  margin: 0 0 var(--space-3) 0;
}
.home-newsletter__subhead {
  font-family: var(--font-stencil);
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(0.95rem, 1.4vw, 1.125rem);
  line-height: 1.3;
  color: var(--fg-on-dark);
  margin: 0 0 var(--space-3) 0;
  max-width: 28ch;
}
.newsletter__inline {
  font-family: var(--font-body);
  color: rgba(240, 236, 225, 0.85) !important;
  font-style: normal;
  font-size: 13px;
  margin: 0;
}
.newsletter__form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  align-items: stretch;
  position: relative;
}
/* SEGMENTED BAR — input + button fused into a single visual element.
   4px outer radius on the wrapper, internal 1px cream-alpha seam, unified
   focus-ring via :focus-within. Reads as "two slots in one bar". */
.newsletter__form-row {
  display: flex;
  flex-direction: row;
  gap: 0;
  align-items: stretch;
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(17, 20, 39, 0.30);
  transition: box-shadow 0.18s ease;
}
.newsletter__form-row:focus-within {
  box-shadow:
    0 0 0 3px rgba(107, 205, 232, 0.5),
    0 1px 3px rgba(17, 20, 39, 0.30);
}
.newsletter__form-row .field {
  flex: 1 1 auto;
  min-width: 0;
}
.newsletter__form-row .btn-primary {
  flex: 0 0 auto;
  align-self: stretch;
  border-radius: 0;
  box-shadow: none;
}
.newsletter__form .field--on-dark .field__input {
  background: var(--bg-dark-2);
  border: 0;
  border-right: 1px solid rgba(240, 236, 225, 0.14);
  border-radius: 0;
  height: 100%;
  box-sizing: border-box;
}
.newsletter__form .field--on-dark .field__input:focus {
  outline: none;
  box-shadow: none;
}
.newsletter__form .field--on-dark .field__label {
  background: var(--bg-dark-2);
}
.newsletter__form .form-status {
  min-height: 18px;
  font-family: var(--font-display);
  font-size: 12px;
  color: rgba(240, 236, 225, 0.85);
  transition: color 0.18s ease;
  margin: 0;
}
.newsletter__form .form-status.is-error {
  color: var(--warm-700);
  font-weight: 700;
}
.newsletter__form .form-status.is-ok { color: var(--cyan-500); }

/* ============================================================
   Koi numerology page.
   Ported from Astro `koi-numerology.astro` <style> (branch master @ 73e884e).
   ============================================================ */

.numerology-intro { padding-block: var(--space-7); }
.numerology-intro p {
  font-size: 16px;
  line-height: 1.8;
  max-width: 720px;
}

.numerology-list { padding-block: var(--space-5) var(--space-9); }
.numerology-list ol { list-style: none; padding: 0; margin: 0; }

.num-row {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: var(--space-7);
  align-items: start;
  padding: var(--space-7) 0;
  border-bottom: 1px solid var(--border);
}
.num-row:last-child { border-bottom: none; }
@media (max-width: 720px) {
  .num-row { grid-template-columns: 1fr; gap: var(--space-3); }
}

.num-row__digit {
  display: block;
  font-family: var(--font-stencil);
  font-size: clamp(5rem, 12vw, 9rem);
  line-height: 0.9;
  color: var(--cyan-500);
  text-transform: uppercase;
}
/* Four is the absence — the message. Render the digit faded so the
   gap reads as intentional. */
.num-row.is-avoided .num-row__digit {
  color: var(--fg-faint);
  opacity: 0.5;
}
.num-row__name {
  font-family: var(--font-display);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  color: var(--fg-faint);
}
.num-row__body h2 {
  margin-bottom: var(--space-3);
  font-size: clamp(1.75rem, 4vw, 2.5rem);
}
.num-row__body p {
  font-size: 16px;
  line-height: 1.7;
  max-width: 640px;
}

.numerology-cta { padding-block: var(--space-9); }
.numerology-cta h2 {
  font-size: clamp(2rem, 4vw, 3rem);
  margin-bottom: var(--space-3);
}
.numerology-cta p {
  margin-bottom: var(--space-5);
  max-width: 640px;
  margin-inline: auto;
}

/* Privacy + terms. */
.jn-legal { padding-block: var(--jn-space-section); }
.jn-legal__article { max-width: 70ch; margin-inline: auto; }
.jn-legal__article h1 { font-size: clamp(2rem, 3.5vw + 1rem, 3rem); }
.jn-legal__article h2 { font-size: 1.25rem; text-transform: none; letter-spacing: 0; margin-top: 2em; }

/* ============================================================
   Misc pages — one-off small pages that don't warrant their own
   stylesheet. Keep additions minimal here; if a page grows past
   ~30 lines of styles, give it its own pages-*.css file.
   ============================================================ */

/* /404/ */
.not-found { padding-block: var(--space-10); }
.not-found h1 {
  font-size: clamp(2.5rem, 6vw, 4.5rem);
  margin: var(--space-3) auto var(--space-4);
}
.not-found p { margin-bottom: var(--space-5); }

/* News pages. */
.jn-news-hero { padding-block: 6rem; }
.jn-news-hero .eyebrow { margin-bottom: 1rem; color: var(--jn-fog); }
.jn-news-hero__lead { color: var(--jn-fog); margin-top: 1rem; max-width: 56ch; }

.jn-news-list { padding-block: var(--jn-space-section); background-color: var(--jn-cream); }
.jn-news-list__ul {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.5rem;
}
@media (max-width: 720px) { .jn-news-list__ul { grid-template-columns: 1fr; } }

/* News post detail */
.jn-news-post { padding-block: var(--jn-space-section); }
.jn-news-post__article { max-width: 68ch; margin-inline: auto; }
.jn-news-post__date { font-family: var(--jn-font-mono); font-size: 0.75rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--jn-fog); }
.jn-news-post__title { font-size: clamp(2rem, 5vw + 1rem, 4rem); margin-top: 0.5rem; }
.jn-news-post__excerpt { color: var(--jn-fog); margin-top: 1rem; font-size: 1.25rem; }
.jn-news-post__cover { margin-block: 2rem; }
.jn-news-post__cover img { width: 100%; border-radius: var(--jn-radius-md); }
.jn-news-post__body { margin-top: 2rem; }
.jn-news-post__back { margin-top: 3rem; }
.jn-news-post__back a { color: var(--jn-coral); font-family: var(--jn-font-mono); font-size: var(--jn-fs-small); letter-spacing: 0.06em; text-transform: uppercase; }

/* /press-kit/ — journalist resource page. Ported from Astro press-kit.astro. */

.kit-section { padding-block: var(--space-9); }
.kit-block { padding: var(--space-5) 0; }
.kit-block h2 {
  margin-bottom: var(--space-5);
  font-size: clamp(1.75rem, 4vw, 2.5rem);
}

.kit-downloads {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: 0;
  margin: 0;
}
.kit-downloads li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
  gap: var(--space-3);
}
.kit-downloads li span {
  font-weight: var(--fw-semibold);
  color: var(--fg-heading);
}

.bio-variant { margin-bottom: var(--space-5); }
.bio-variant h3 {
  font-family: var(--font-display);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  color: var(--cyan-500);
  margin-bottom: var(--space-3);
  font-weight: var(--fw-black);
}
.bio-variant blockquote {
  padding: var(--space-4) var(--space-5);
  border-left: 3px solid var(--cyan-500);
  background: var(--bg-soft);
  color: var(--fg-heading);
  line-height: 1.7;
  margin: 0;
}

.fact-sheet {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--space-3) var(--space-5);
}
.fact-sheet dt {
  font-family: var(--font-display);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  color: var(--cyan-500);
  font-weight: var(--fw-black);
}
.fact-sheet dd { color: var(--fg-heading); margin: 0; }

/* Copy-to-clipboard affordance on bios — interactive blockquote */
.kit-downloads__hint, .bio-hint {
  font-family: var(--font-display);
  font-size: 13px;
  color: var(--fg-muted);
  margin-bottom: var(--space-3);
}
.bio-variant blockquote[data-copy] {
  cursor: pointer;
  transition: background 0.18s ease, transform 0.18s ease;
}
.bio-variant blockquote[data-copy]:hover {
  background: rgba(107, 205, 232, 0.08);
}
.bio-variant blockquote[data-copy]:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}
.bio-variant blockquote[data-copy].is-copied {
  background: rgba(107, 205, 232, 0.18);
}
.bio-copy-status {
  min-height: 22px;
  margin-top: var(--space-2);
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  color: var(--cool-700);
  transition: opacity 0.18s ease;
}

/* /press/ — full archive grouped by year. Ported from Astro press/index.astro. */

.press-list { padding-block: var(--space-9); }
.press-year + .press-year { margin-top: var(--space-7); }
.press-year h2 {
  font-size: clamp(2rem, 5vw, 3rem);
  color: var(--cyan-500);
  margin-bottom: var(--space-5);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--border);
}
.press-year ul {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  padding: 0;
  margin: 0;
}
.press-year li {
  padding: var(--space-4) 0;
  border-bottom: 1px solid var(--border);
}
.press-year li:last-child { border-bottom: none; }

.press-item__head {
  display: flex;
  gap: var(--space-3);
  align-items: baseline;
  flex-wrap: wrap;
  margin-bottom: var(--space-2);
}
.press-item__outlet {
  font-family: var(--font-stencil);
  font-size: 18px;
  text-transform: uppercase;
  color: var(--fg-heading);
}
.press-item__type {
  font-family: var(--font-display);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  color: var(--fg-faint);
}
.press-item__title {
  font-size: 16px;
  font-weight: var(--fw-semibold);
  color: var(--fg-heading);
  margin-bottom: var(--space-2);
  font-style: italic;
  max-width: 720px;
}
.press-item__summary {
  color: var(--fg-body);
  line-height: 1.6;
  max-width: 720px;
  margin-bottom: var(--space-2);
}

.press-cta { padding-block: var(--space-9); }
.press-cta h2 { margin-bottom: var(--space-3); }
.press-cta p {
  margin-bottom: var(--space-5);
  max-width: 640px;
  margin-inline: auto;
}

/* Shop pages. */
.jn-shop-hero { padding-block: 6rem; }
.jn-shop-hero .eyebrow { margin-bottom: 1rem; color: var(--jn-fog); }
.jn-shop-hero__lead { color: var(--jn-fog); margin-top: 1rem; max-width: 60ch; }

.jn-shop-grid { padding-block: var(--jn-space-section); background-color: var(--jn-cream); }
.jn-shop-grid__ul {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2rem;
}
@media (max-width: 980px) { .jn-shop-grid__ul { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .jn-shop-grid__ul { grid-template-columns: 1fr; } }

/* Product detail */
.jn-product { padding-block: var(--jn-space-section); }
.jn-product__grid { display: grid; grid-template-columns: 1.1fr 1fr; gap: 4rem; align-items: start; }
@media (max-width: 880px) { .jn-product__grid { grid-template-columns: 1fr; } }

.jn-product__img-wrap { background-color: var(--jn-cream); border-radius: var(--jn-radius-md); overflow: hidden; aspect-ratio: 4 / 5; }
.jn-product__img { width: 100%; height: 100%; object-fit: cover; }

.jn-product__title { font-size: clamp(2rem, 3.5vw + 1rem, 3rem); margin-top: 0.5rem; }
.jn-product__sub { color: var(--jn-fog); margin-top: 0.5rem; }
.jn-product__price { font-family: var(--jn-font-mono); font-size: 1.75rem; color: var(--jn-coral); margin-top: 1.25rem; font-weight: 700; }

.jn-product__meta { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-top: 1.5rem; padding-block: 1.5rem; border-block: 1px solid rgba(14, 12, 10, 0.08); }
.jn-product__meta dt { font-family: var(--jn-font-mono); font-size: 0.6875rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--jn-fog); }
.jn-product__meta dd { margin-top: 0.25rem; font-weight: 600; }

.jn-product__desc { margin-top: 1.5rem; }
.jn-product__cta { margin-top: 2rem; }
.jn-product__legal { margin-top: 1rem; color: var(--jn-fog); font-size: var(--jn-fs-small); max-width: 50ch; }

/* /shop/thank-you/ — Stripe checkout success redirect */
.thanks { padding-block: var(--space-10); }
.thanks h1 { margin: var(--space-3) auto var(--space-4); }
.thanks p { margin-bottom: var(--space-5); }

/* /shop/ — cream "Don't see what you want?" CTA band at the bottom. */
.shop-grid-section { padding-block: var(--space-9); }
.shop-cta { padding-block: var(--space-9); }
.shop-cta h2 { margin-bottom: var(--space-3); }
.shop-cta p {
  margin-bottom: var(--space-5);
  max-width: 540px;
  margin-inline: auto;
}

/* ============================================================
   /world-map/ + /projects/[slug]/ — interactive map page + per-
   sighting detail. Ported from Astro `world-map.astro` <style>
   (branch master @ 73e884e). Project-detail rules retain the
   v2 `.jn-project` namespace until the project route is restyled.
   ============================================================ */

/* WORLD MAP PAGE */
.map-section { padding-block: var(--space-9); }

.sighting { padding-block: var(--space-9); }
.sighting h2 { margin-bottom: var(--space-3); }
.sighting p { margin-bottom: var(--space-5); max-width: 640px; }
.sighting-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  max-width: 720px;
}
.form-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.form-row--split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}
@media (max-width: 540px) {
  .form-row--split { grid-template-columns: 1fr; }
}
.sighting-form label {
  font-family: var(--font-display);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  color: var(--fg-heading);
  font-weight: var(--fw-black);
}
.sighting-form input[type="text"],
.sighting-form input[type="email"] {
  padding: 12px 14px;
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  font-family: var(--font-body);
  font-size: 15px;
  background: transparent;
  color: var(--fg);
}
.sighting-form input[type="file"] {
  padding: 8px 0;
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--fg);
}
.sighting-form input:focus {
  outline: none;
  border-color: var(--cyan-500);
  box-shadow: var(--focus-ring);
}
.sighting-form button { align-self: flex-start; }

.commission-cta { padding-block: var(--space-9); text-align: center; }
.commission-cta h2 { margin-bottom: var(--space-3); }
.commission-cta p {
  max-width: 540px;
  margin: 0 auto var(--space-5);
}

/* Sighting list — tile triggers below the map. */
.jn-world-map__list { padding-block: var(--space-9); }
.jn-world-map__list-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
  gap: var(--space-4);
  list-style: none;
  padding: 0;
  margin: 0;
}
.jn-world-map__list-item { padding: 0; }
.jn-world-map__list-link {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: 0;
  border-left: 2px solid var(--cyan-500);
  padding: var(--space-3) var(--space-4);
  cursor: pointer;
  color: var(--fg-on-dark);
  transition: background 0.18s ease, transform 0.18s var(--ease-out);
}
.jn-world-map__list-link:hover {
  background: rgba(107, 205, 232, 0.06);
  transform: translateX(2px);
}
.jn-world-map__list-link:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}
.jn-world-map__list-title {
  font-family: var(--font-stencil);
  font-size: clamp(1.125rem, 1.6vw, 1.375rem);
  text-transform: uppercase;
  letter-spacing: 0;
  margin: 0 0 var(--space-2);
  color: var(--fg-on-dark);
}
.jn-world-map__list-meta {
  font-family: var(--font-display);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--fg-muted-on-dark);
  margin: 0;
}

/* Sighting dialog (drawer) — opens on tile click; ESC + backdrop close. */
.jn-sighting-modals { display: contents; }
.jn-sighting-modal__dialog {
  border: 0;
  background: var(--bg);
  color: var(--fg-heading);
  padding: 0;
  max-width: min(560px, 92vw);
  width: 100%;
  border-top: 3px solid var(--warm-700);
  box-shadow: 0 20px 60px rgba(17, 20, 39, 0.35);
}
.jn-sighting-modal__dialog::backdrop {
  background: rgba(10, 13, 24, 0.66);
}
.jn-sighting-modal__inner {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.jn-sighting-modal__close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgba(17, 20, 39, 0.08);
  border: 0;
  border-radius: 999px;
  cursor: pointer;
  font-size: 18px;
  color: var(--fg-heading);
  line-height: 1;
  z-index: 2;
}
.jn-sighting-modal__close:hover { background: rgba(17, 20, 39, 0.18); }
.jn-sighting-modal__media { margin: 0; }
.jn-sighting-modal__img {
  width: 100%;
  height: auto;
  display: block;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}
.jn-sighting-modal__meta {
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: var(--tracking-widest);
  text-transform: uppercase;
  color: var(--cyan-500);
  margin: var(--space-3) var(--space-5) 0;
}
.jn-sighting-modal__title {
  font-size: clamp(1.5rem, 3vw, 2rem);
  margin: 0 var(--space-5);
  color: var(--fg-heading);
}
.jn-sighting-modal__desc {
  font-size: 15px;
  line-height: 1.6;
  color: var(--fg-body);
  margin: 0 var(--space-5);
}
.jn-sighting-modal__cta {
  margin: var(--space-3) var(--space-5) var(--space-5);
}

/* /projects/[slug]/ — kept from v2 stub for now (will be re-themed when
   the project detail page is reworked). */
.jn-project { padding-block: var(--jn-space-section); }
.jn-project__article { max-width: 68ch; margin-inline: auto; }
.jn-project__title { font-size: clamp(2rem, 5vw + 1rem, 4rem); margin-top: 0.5rem; }
.jn-project__meta {
  font-family: var(--font-display);
  font-size: var(--text-sm);
  color: var(--fg-muted);
  margin-top: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.jn-project__cover { margin-block: 2.5rem; }
.jn-project__cover img { width: 100%; border-radius: var(--radius-md); }
.jn-project__body { margin-top: 2rem; }
.jn-project__back { margin-top: 3rem; }
.jn-project__back a {
  color: var(--warm-700);
  font-family: var(--font-display);
  font-size: var(--text-sm);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}


