/* ============================================================================
   Renesoft AB — "wc-instrument" · the precision-instrument variant (world-class)
   ----------------------------------------------------------------------------
   Built on the Skogsljus "Instrument, quieted" system and pushed to a precision-
   instrument bar: a visible underlying hairline grid, aperture/crosshair motifs,
   mono telemetry + coordinate readouts, tabular numerals everywhere, and crisp,
   mechanical motion (spring physics on magnetic elements, deliberate easing).

   SIGNATURE: the hero tagline COMPILES — each glyph starts as a random JetBrains
   Mono character and settles, left-to-right with a stagger, into its final
   Archivo letterform (~700-1100ms, one-shot), while a mono build-log prints a
   few lines then quiets. Zero layout shift; honoured under reduced-motion.

   Linear's restraint + Teenage Engineering's labelled-instrument precision.
   "Complex yet minimal": restrained surface, deep craft underneath.

   Palette: Skogsljus greenish-pastels (light primary), deep-green dark variant.
   Display + body: Archivo. Labels/telemetry: JetBrains Mono. Self-hosted, 0 CLS.
   ========================================================================== */

/* ---------- self-hosted fonts ----------
   Archivo and JetBrains Mono served from assets/fonts/ (woff2, Latin +
   Latin-Ext subsets) — no Google Fonts dependency, no single point of failure.
   `font-display: swap` + matching `unicode-range` keep the swap minimal; the
   metric-matched fallback faces below (size-adjust + ascent/descent overrides,
   measured in Chrome against the real woff2) make the swap layout-neutral → 0 CLS.
   url()s resolve relative to this stylesheet (site root), so /en/ loads them too. */
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("assets/fonts/archivo-400-700-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("assets/fonts/archivo-400-700-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/jetbrains-mono-400-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/jetbrains-mono-400-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("assets/fonts/jetbrains-mono-500-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("assets/fonts/jetbrains-mono-500-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("assets/fonts/jetbrains-mono-600-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("assets/fonts/jetbrains-mono-600-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Metric-matched fallback faces — measured in Chrome against the real woff2
   (Archivo→Arial 0.9912; JetBrains Mono→monospace 1.0913) so the fallback box
   equals the web-font box and the swap shifts nothing → 0 CLS. */
@font-face {
  font-family: "Archivo Fallback";
  src: local("Arial");
  size-adjust: 99.12%;
  ascent-override: 88.58%;
  descent-override: 21.19%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "JetBrains Mono Fallback";
  src: local("Consolas"), local("Menlo"), local("monospace");
  size-adjust: 109.13%;
  ascent-override: 93.47%;
  descent-override: 27.49%;
  line-gap-override: 0%;
}

/* ---------- tokens ----------
   "Skogsljus" revival — greenish pastels, LIGHT-primary. The same instrument
   discipline as the monochrome flagship, recoloured to a soft, premium
   Scandinavian palette: paper ground, ink-green body, spruce display/links/
   buttons, sage/seafoam/mist soft fills. Brass is a *sparing* hairline accent
   only (never type). Every readable token passes WCAG AA on the surfaces it
   appears on (see the contrast contract in BRAND.md). */
:root {
  /* greenish-pastel scale — light, primary */
  --bg:     #f3f7f2;   /* page — paper (pale green-white) */
  --bg-1:   #fbfdfa;   /* raised panels / cards — lighter than paper */
  --bg-2:   #e9f1e7;   /* sunken / alt bands / mocks — mist */
  --bg-3:   #d9e8d6;   /* hover / inset — sage */
  --fg:     #16291f;   /* primary text + display — deep ink-green */
  --fg-2:   #38503f;   /* secondary text — AA on every surface (≥7:1 on paper) */
  --fg-3:   #4d6557;   /* tertiary readable text (labels, nav, chips) — AA */
  --fg-meta:#4f6759;   /* faintest *readable* metadata (the rare datum / build) — AA */
  --fg-4:   #a9c2b0;   /* decoration ONLY — dashes, borders, aria-hidden ornament */
  --line:   #d3e0d2;   /* hairlines */
  --line-2: #c0d4be;   /* stronger borders */
  --on-fg:  #f3f7f2;   /* text on a spruce fill (paper) */
  --accent: #2e5944;   /* spruce — headings/links/emphasis/buttons */
  --accent-deep: #1c3a2c; /* spruce-deep — hover/active, dark band */
  --brass:  #b3914f;   /* sparing hairline accent only — never type */
  --seafoam:#c5e2d4;   /* hero glow / soft fills */

  /* type */
  --disp: "Archivo", "Archivo Fallback", "Helvetica Neue", Arial, sans-serif;
  --mono: "JetBrains Mono", "JetBrains Mono Fallback", ui-monospace, "SFMono-Regular", Menlo, monospace;

  /* rhythm — wider gutter + a single roomy max so the page breathes like B */
  --gutter: clamp(22px, 5.5vw, 96px);
  --maxw:   1200px;
  --col-gap: clamp(20px, 3vw, 56px);

  --radius: 3px;
  /* one shared ease — the motion language is unified, so is its curve */
  --ease: cubic-bezier(.22, 1, .3, 1);
  /* a crisp mechanical spring for magnetic / instrument elements — a touch of
     overshoot so things "snap" into a detent rather than glide */
  --spring: cubic-bezier(.34, 1.56, .42, 1);
  /* a deliberate, instrument-grade in-out for measured motions */
  --mech: cubic-bezier(.65, .02, .18, 1);

  /* the visible underlying grid — one module governs the whole instrument */
  --grid: 26px;
  --hair: color-mix(in srgb, var(--accent) 14%, transparent);

  color-scheme: light;
}

/* tasteful DEEP-GREEN dark variant — spruce-deep / ink-green grounds, pastel-
   green accents. Not pure black; a forest at dusk. */
:root[data-theme="dark"] {
  --bg:     #10211a;   /* page — deep ink-green */
  --bg-1:   #163026;   /* raised panels / cards */
  --bg-2:   #112019;   /* sunken / alt bands / mocks */
  --bg-3:   #1e3b2e;   /* hover / inset */
  --fg:     #eaf3ea;   /* primary text — pale paper-green */
  --fg-2:   #aec8b6;   /* secondary text — AA on every dark surface */
  --fg-3:   #93b3a0;   /* tertiary readable text (labels, nav, chips) — AA */
  --fg-meta:#8fb09c;   /* faintest *readable* metadata — AA */
  --fg-4:   #3f5d4c;   /* decoration ONLY — dashes, borders, aria-hidden ornament */
  --line:   #294939;   /* hairlines — lifted so cards/dividers read on the dark ground */
  --line-2: #3a604c;   /* stronger borders */
  --on-fg:  #10211a;   /* text on a pastel-green fill (buttons) */
  --accent: #9ed7b6;   /* pastel spruce — links/emphasis/buttons on dark */
  --accent-deep: #c5e2d4; /* lighter pastel — hover/active */
  --brass:  #cda867;   /* brass lifted for the dark ground */
  --seafoam:#244a39;   /* hero glow on dark */
  --hair: color-mix(in srgb, var(--accent) 16%, transparent);
  color-scheme: dark;
}

/* ---------- reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  font-family: var(--disp);
  font-weight: 400;
  font-size: clamp(16px, .55vw + 14px, 18px);
  line-height: 1.62;
  letter-spacing: -.006em;
  color: var(--fg);
  /* two gentle green radial glows (seafoam up top, mist at the foot) so the
     paper field has air and depth without ever banding flat — decoration only,
     behind everything, no layout */
  background:
    radial-gradient(120% 78% at 50% -8%, color-mix(in srgb, var(--seafoam) 60%, transparent), transparent 48%),
    radial-gradient(120% 64% at 50% 112%, color-mix(in srgb, var(--bg-2) 70%, transparent), transparent 52%),
    var(--bg);
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-optical-sizing: auto;
  font-feature-settings: "kern" 1, "liga" 1, "ss01" 1;
  overflow-x: hidden;
}

/* a hair of film grain so the paper field never banks flat. Soft on paper, a
   touch more on the deep-green dark. */
body::after {
  content: "";
  position: fixed; inset: 0;
  pointer-events: none; z-index: 0;
  opacity: .02; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
:root[data-theme="dark"] body::after { opacity: .04; mix-blend-mode: overlay; }

/* the VISIBLE underlying grid — this is the instrument's character. A faint
   hairline graph (governed by --grid) bounded inside the twin content-edge rails,
   masked so it's strongest at the rails and dissolves toward the centre column so
   it never fights the copy. The rails themselves are the persistent structure. */
.grid-field {
  position: fixed; inset: 0;
  pointer-events: none; z-index: 0;
  max-width: var(--maxw);
  margin-inline: auto;
  border-left: 1px solid var(--line);
  border-right: 1px solid var(--line);
  overflow: hidden;
}
.grid-field::before {
  content: "";
  position: absolute; inset: 0;
  background-image:
    linear-gradient(to right,  var(--hair) 0 1px, transparent 1px),
    linear-gradient(to bottom, var(--hair) 0 1px, transparent 1px);
  background-size: var(--grid) var(--grid);
  -webkit-mask-image: linear-gradient(to right, #000 0, transparent 26%, transparent 74%, #000 100%);
          mask-image: linear-gradient(to right, #000 0, transparent 26%, transparent 74%, #000 100%);
  opacity: .9;
}
/* register crosshairs pinned to the four rail corners — the instrument signs its
   own frame (Teenage Engineering labelled-corner detailing) */
.grid-field span {
  position: absolute; width: 11px; height: 11px;
  border: 0 solid var(--line-2);
  opacity: .85;
}
.grid-field span::before, .grid-field span::after {
  content: ""; position: absolute; background: var(--line-2);
}
.grid-field span::before { left: 50%; top: 0; bottom: 0; width: 1px; transform: translateX(-.5px); }
.grid-field span::after  { top: 50%; left: 0; right: 0; height: 1px; transform: translateY(-.5px); }
.grid-field .tl { left: -6px; top: 84px; }
.grid-field .tr { right: -6px; top: 84px; }
.grid-field .bl { left: -6px; bottom: 22px; }
.grid-field .br { right: -6px; bottom: 22px; }
@media (max-width: 1296px) { .grid-field { display: none; } }
@media (prefers-reduced-motion: no-preference) {
  /* the grid breathes in once, very faintly — part of the load choreography */
  .js .grid-field { animation: grid-in 1.1s var(--mech) both; }
  @keyframes grid-in { from { opacity: 0; } to { opacity: 1; } }
}

img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
em { font-style: normal; }
strong, b { font-weight: 600; color: var(--fg); }

::selection { background: var(--accent); color: var(--on-fg); }

/* ---------- layout primitives ---------- */
.container {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
  position: relative;
}
main, header, footer { position: relative; z-index: 1; }

/* generous section rhythm — the page breathes (B's discipline) */
.section { padding-block: clamp(88px, 12vw, 184px); position: relative; }
.section + .section { border-top: 1px solid var(--line); }

/* ---------- skip link ---------- */
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--accent); color: var(--on-fg);
  padding: .7rem 1.1rem; font: 600 .8rem/1 var(--mono);
}
.skip-link:focus { left: 1rem; top: 1rem; }

/* custom focus — an instrument-style ring, never the UA blur halo */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 1px;
}

/* ---------- shared mono labels ---------- */
.kicker, .section-label, .tag, .stamp, .hero-meta, .chips span,
.lang-switch, .proof, .product-meta, .foot-base, .foot-col h4 {
  font-family: var(--mono);
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
}
/* the rare numeric readouts align their digits */
.hero-meta, .product-meta, .foot-base, .principle .no, .proof, .build {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "kern" 1;
}

/* section index — "01 — Filosofi ———————————"  (quiet, no coordinate spam).
   The trailing rule is part of the ONE motion language: it draws on reveal. */
.section-label {
  display: flex; align-items: center; gap: 1rem;
  font-size: .72rem; color: var(--fg-3);
  margin-bottom: clamp(40px, 6vw, 76px);
}
.section-label .no { color: var(--fg-meta); }
.section-label .no::after { content: " —"; color: var(--fg-3); }
.section-label::after {
  content: ""; flex: 1; height: 1px; background: var(--line);
  transform: scaleX(0); transform-origin: left;
  transition: transform 1s var(--mech);
}
.js .section-label.in::after,
.js .sec-head.in .section-label::after { transform: scaleX(1); }
/* a faint trailing coordinate readout on each section label — a measured datum
   at the right end of the rule. Decorative-but-legible mono, tabular. */
.section-label .coord {
  font-weight: 500; letter-spacing: .14em;
  color: var(--fg-meta); flex: none;
  opacity: 0; transition: opacity .9s var(--ease) .25s;
}
.js .section-label.in .coord { opacity: 1; }

/* display emphasis: an outlined "ghost" word in spruce — engineered, not
   decorative. Stroke width scales with the headline so the outline stays
   optically even; spruce reads clearly as the brand accent on paper. */
h1 em, h2 em {
  font-style: normal;
  color: transparent;
  -webkit-text-stroke: var(--ghost-w, 1px) var(--accent);
  text-stroke: var(--ghost-w, 1px) var(--accent);
  paint-order: stroke;
}
h1 em { --ghost-w: clamp(1.1px, .85px + .12vw, 2px); }
h2 em { --ghost-w: clamp(1px, .8px + .07vw, 1.5px); }

/* ============================================================================
   HEADER
   ========================================================================== */
.site-head {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  backdrop-filter: saturate(110%) blur(14px);
  -webkit-backdrop-filter: saturate(110%) blur(14px);
  border-bottom: 1px solid var(--line);
}
.site-head .container {
  display: flex; align-items: center; justify-content: space-between;
  height: 70px;
}
.brand { display: flex; align-items: center; gap: .62rem; color: var(--fg); }
.brand .mark { color: var(--accent); width: 26px; height: 26px; }
.brand .name {
  font-family: var(--disp);
  font-size: 1.2rem; font-weight: 600; letter-spacing: -.045em;
  line-height: 1;
}
.brand .ab {
  font-family: var(--mono); font-size: .56rem; font-weight: 600;
  letter-spacing: .24em; color: var(--fg-3);
  align-self: flex-start; margin-top: .15rem;
}

.site-nav { display: flex; align-items: center; gap: clamp(.9rem, 2vw, 2rem); }
.nav-links { display: flex; align-items: center; gap: clamp(.9rem, 2vw, 2rem); }
.nav-links > a {
  font-family: var(--mono);
  font-size: .72rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--fg-3);
  position: relative; padding-block: .3rem;
  transition: color .22s var(--ease);
}
/* the datum-line again — a hairline that grows under the link (the one motion idea) */
.nav-links > a::after {
  content: ""; position: absolute; left: 0; bottom: -.1rem;
  width: 100%; height: 1px; background: var(--accent);
  transform: scaleX(0); transform-origin: left;
  transition: transform .28s var(--ease);
}
.nav-links > a:hover { color: var(--accent); }
.nav-links > a:hover::after { transform: scaleX(1); }

/* minimal nav toggle — two hairlines that fold into an × when open */
.nav-toggle {
  display: none;
  width: 36px; height: 36px; padding: 0;
  background: none; border: 1px solid var(--line-2); border-radius: 2px;
  color: var(--fg-3); cursor: pointer; position: relative;
  transition: border-color .25s var(--ease), color .25s var(--ease);
}
.nav-toggle:hover { color: var(--accent); border-color: var(--accent); }
.nav-toggle span {
  position: absolute; left: 9px; right: 9px; height: 1.5px;
  background: currentColor; border-radius: 1px;
  transition: transform .3s var(--ease), opacity .2s var(--ease);
}
.nav-toggle span:nth-child(1) { top: 14px; }
.nav-toggle span:nth-child(2) { bottom: 14px; }
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(4px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { transform: translateY(-4px) rotate(-45deg); }

.lang-switch {
  font-size: .64rem; font-weight: 500; letter-spacing: .14em;
  color: var(--fg-3);
  border: 1px solid var(--line-2);
  padding: .38rem .58rem; border-radius: 2px;
  transition: border-color .25s var(--ease), color .25s var(--ease);
}
.lang-switch:hover { color: var(--accent); border-color: var(--accent); }

.theme-toggle {
  display: grid; place-items: center;
  width: 36px; height: 36px; padding: 0;
  background: none; border: 1px solid var(--line-2); border-radius: 2px;
  color: var(--fg-3); cursor: pointer;
  transition: border-color .25s var(--ease), color .25s var(--ease);
}
.theme-toggle:hover { color: var(--accent); border-color: var(--accent); }
.theme-toggle svg { width: 16px; height: 16px; }
/* light is primary → show the moon (offer dark) by default; show the sun on dark */
.theme-toggle .i-sun { display: none; }
.theme-toggle .i-moon { display: block; }
:root[data-theme="dark"] .theme-toggle .i-moon { display: none; }
:root[data-theme="dark"] .theme-toggle .i-sun { display: block; }

@media (max-width: 760px) {
  .nav-toggle { display: grid; place-items: center; }
  .nav-links {
    position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; align-items: stretch; gap: 0;
    background: color-mix(in srgb, var(--bg) 94%, transparent);
    backdrop-filter: saturate(120%) blur(16px);
    -webkit-backdrop-filter: saturate(120%) blur(16px);
    border-bottom: 1px solid var(--line);
    padding: .4rem var(--gutter) 1rem;
    transform: translateY(-8px);
    opacity: 0; visibility: hidden; pointer-events: none;
    transition: opacity .26s var(--ease), transform .26s var(--ease), visibility 0s linear .26s;
  }
  .nav-links > a {
    padding: 1rem 0; font-size: .82rem;
    border-bottom: 1px solid var(--line);
  }
  .nav-links > a::after { display: none; }
  .site-nav.open .nav-links {
    opacity: 1; visibility: visible; pointer-events: auto; transform: none;
    transition: opacity .26s var(--ease), transform .26s var(--ease), visibility 0s;
  }
}

/* ============================================================================
   HERO — the compiling headline over a living AI MESH
   The aperture instrument is retired; the ambient AI mesh (canvas) is now the
   hero's primary visual, with the compiling-tagline signature on top. A faint
   forest-light warmth is kept under the mesh. Giant Archivo headline, lots of air.
   ========================================================================== */
.hero {
  position: relative;
  isolation: isolate;            /* own stacking context: the forest field is
                                    contained here and never fights the global grid */
  padding-block: clamp(64px, 11vw, 150px) clamp(56px, 9vw, 116px);
  overflow: hidden;
  border-bottom: 1px solid var(--line);
  /* greenish-pastel revival — soft seafoam + mist glows over a paper wash so the
     hero breathes; the AI mesh threads over it. Themed via tokens so the deep-green
     dark variant inherits coherently. */
  background:
    radial-gradient(52rem 36rem at 80% -10%, color-mix(in srgb, var(--seafoam) 75%, transparent), transparent 60%),
    radial-gradient(42rem 30rem at 8% 6%, color-mix(in srgb, var(--bg-2) 80%, transparent), transparent 62%),
    linear-gradient(180deg, color-mix(in srgb, var(--bg-1) 60%, var(--bg)), var(--bg));
}

/* ---- RESIDUAL FOREST WARMTH (under the AI mesh) ---------------------------
   Just TWO heavily-blurred radial blooms in seafoam/mist that slowly drift and
   parallax gently toward the cursor (JS eases --fx/--fy). It sits at the very
   BOTTOM of the hero's isolated stacking context (z-index 0, painted under the
   mesh and copy), and is masked to dissolve well before the lower hero so it reads
   as a faint atmospheric warmth UNDER the mesh — the mesh leads. GPU-only
   (transform/opacity). Dialled well down so it never competes with the network.
   The pale blooms sit BEHIND the dark spruce headline → text contrast is untouched
   (verified AA in both themes). Skipped under reduced motion. */
.forest {
  /* Pinned to the hero's TOP with a viewport-derived extent that does NOT depend
     on the hero's (reflowing) height — so the headline compile / font-swap never
     resizes this box → it contributes ZERO layout shift. `contain: layout paint`
     isolates it as its own paint layer (a sibling that can't shift others). */
  position: absolute; top: -80px; left: -8%; right: -8%;
  height: clamp(420px, 62vh, 760px);    /* fixed px/vh extent: upper hero only, never the copy */
  z-index: 0; pointer-events: none;
  overflow: hidden;
  contain: strict;                      /* size+layout+paint isolation → never shifts siblings */
  /* the parallax handle — JS eases --fx/--fy in px; the field shifts gently */
  transform: translate3d(var(--fx, 0px), var(--fy, 0px), 0);
  transition: transform 1.1s var(--ease);
  /* Fade the warmth out high so it dissolves into the page above the lede/CTA, AND
     pull a soft radial falloff into the top-right corner so the .fl-1 bloom never
     edges bright on wide viewports. The two mask layers INTERSECT (vertical fade ∩
     corner falloff): the corner layer is opaque everywhere except a gentle dim
     toward 100% 0%. */
  -webkit-mask-image:
    linear-gradient(180deg, #000 0, #000 44%, transparent 86%),
    radial-gradient(120% 130% at 100% 0%, transparent 0, rgba(0,0,0,.45) 24%, #000 52%);
          mask-image:
    linear-gradient(180deg, #000 0, #000 44%, transparent 86%),
    radial-gradient(120% 130% at 100% 0%, transparent 0, rgba(0,0,0,.45) 24%, #000 52%);
  -webkit-mask-composite: source-in;
          mask-composite: intersect;
}
.fl {
  position: absolute;
  border-radius: 50%;
  filter: blur(52px);
  opacity: .4;                          /* reduced further → just a HINT of warmth under the mesh */
  will-change: transform;
}
/* only TWO light pools remain (down from four) so the AI mesh dominates — a faint
   seafoam warmth top-right, a cooler mist pooled lower-left. color-mix keeps them
   themed (light + deep-green dark both inherit). */
.fl-1 {
  top: -16%; right: -8%; width: 50vw; height: 50vw; max-width: 700px; max-height: 700px;
  background: radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--seafoam) 92%, white), transparent 66%);
  animation: drift-a 34s var(--ease) infinite alternate;
}
.fl-2 {
  top: 18%; left: -12%; width: 44vw; height: 44vw; max-width: 580px; max-height: 580px;
  background: radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--bg-3) 80%, var(--seafoam)), transparent 64%);
  opacity: .3;
  animation: drift-b 46s var(--ease) infinite alternate;
}
/* deep-green dark: the blooms become faint luminous pools against the forest-at-
   dusk ground — kept low so the mesh leads */
:root[data-theme="dark"] .fl-1 { background: radial-gradient(circle at 50% 50%, color-mix(in srgb, #4f8e6e 88%, transparent), transparent 66%); opacity: .3; }
:root[data-theme="dark"] .fl-2 { background: radial-gradient(circle at 50% 50%, color-mix(in srgb, #2f6249 90%, transparent), transparent 64%); opacity: .32; }

/* a faint extra grain confined to the canopy so the light field has tooth
   (dappled, not gradient-smooth). Cheap data-URI noise, multiply on paper. */
.fl-grain {
  position: absolute; inset: 0;
  opacity: .4; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='fn'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.7' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23fn)' opacity='0.045'/%3E%3C/svg%3E");
}
:root[data-theme="dark"] .fl-grain { mix-blend-mode: overlay; opacity: .5; }

/* slow, lazy drifts — each bloom breathes on its own clock so the canopy never
   shows a seam. Small translate + scale only → pure GPU compositing, cheap. */
@keyframes drift-a { from { transform: translate3d(0,0,0) scale(1); }    to { transform: translate3d(-4%, 5%, 0) scale(1.12); } }
@keyframes drift-b { from { transform: translate3d(0,0,0) scale(1.05); } to { transform: translate3d(6%, -4%, 0) scale(1); } }

@media (prefers-reduced-motion: reduce) {
  .fl { animation: none !important; }
  .forest { transition: none; }
}
/* on small screens the warmth is anchored top-right and kept very faint so the
   copy column always wins (the mesh leads everywhere) */
@media (max-width: 760px) {
  .forest { top: -14%; left: -10%; right: -10%; height: clamp(320px, 46vh, 520px); }
  .fl { opacity: .3; }
}

.hero .container { position: relative; z-index: 1; }

/* ambient AI MESH — the hero's PRIMARY visual. A denser "thinking" network with
   cross-layer links + hub nodes; signals flow left→right (drawn in app.js, z-index 0,
   under the copy). Now that it leads, the mask lets it read strongly across the whole
   field while keeping the type column legible: bright toward the open right, gently
   dimmed (never fully cut) behind the headline so the AA-readable spruce/paper type
   always wins. A faint scanline veil (::after) adds terminal-CRT tooth. */
.neuralnet {
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%;
  pointer-events: none;
  -webkit-mask-image: radial-gradient(135% 118% at 76% 44%, #000 44%, rgba(0,0,0,.62) 74%, rgba(0,0,0,.22) 100%);
          mask-image: radial-gradient(135% 118% at 76% 44%, #000 44%, rgba(0,0,0,.62) 74%, rgba(0,0,0,.22) 100%);
}
/* a hairline CRT scanline veil over the hero — very faint, pure decoration, no
   layout. Terminal-nerd texture; a touch stronger on the deep-green dark. Sits at
   z-index 0 (under the copy at z-index 1), masked to the mesh's bright zone. */
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: 0;
  pointer-events: none;
  background: repeating-linear-gradient(
    to bottom,
    color-mix(in srgb, var(--accent) 4%, transparent) 0 1px,
    transparent 1px 4px);
  opacity: .35;
  -webkit-mask-image: radial-gradient(135% 118% at 76% 44%, #000 30%, transparent 86%);
          mask-image: radial-gradient(135% 118% at 76% 44%, #000 30%, transparent 86%);
}
:root[data-theme="dark"] .hero::after {
  background: repeating-linear-gradient(
    to bottom,
    color-mix(in srgb, var(--accent) 7%, transparent) 0 1px,
    transparent 1px 4px);
  opacity: .45;
}
@media (prefers-reduced-motion: reduce) { .hero::after { opacity: .25; } }
@media (max-width: 760px) { .hero::after { opacity: .22; } }

/* the giant confident headline — bigger and airier than A. The emphasized word
   carries the datum-line underline (the one signature motion). */
h1 {
  font-family: var(--disp);
  font-weight: 700;
  font-size: clamp(3.3rem, 11vw, 10rem);
  line-height: .9;
  letter-spacing: -.05em;
  max-width: 13ch;
  margin-bottom: clamp(30px, 3.4vw, 48px);
  text-wrap: balance;
  position: relative;        /* anchors the one-shot .bloom wash (::after) */
}

/* ---- the COMPILING tagline (signature centerpiece) ----------------------
   The headline is split into per-glyph <span class="g">; JS scrambles each in
   JetBrains Mono and settles it, left-to-right, into the final Archivo glyph.
   0 CLS by construction: the FINAL Archivo letter is always the in-flow,
   layout-determining content of each cell, and the scrambling mono char is
   painted by an OUT-OF-FLOW .scz overlay on top — so a mono glyph's (different)
   width can never re-wrap the line. On lock the overlay is removed, revealing the
   already-placed final letter. (Overlay technique ported from variant B.) */
h1 .g {
  display: inline-block;
  position: relative;
  will-change: transform, opacity;
}
/* 0-CLS by construction. The FINAL Archivo character is ALWAYS the in-flow,
   layout-determining content of each .g cell — it never changes, so wrapping,
   baselines and line-box heights are fixed from first paint. The scrambling mono
   character is painted by an absolutely-positioned overlay (.scz) that is fully
   OUT OF FLOW, so it can be any width without ever moving a neighbour. While a
   glyph is "scramble" its final letter is hidden (transparent) and the overlay
   shows the mono char; on "locked" we remove the overlay, revealing the
   already-placed final letter. (Ported from variant B's overlay technique.) */
h1.compiling .g[data-state="scramble"] { color: transparent; }
/* inside the outlined ghost word the final letter is a stroke, not a fill — hide
   the stroke while scrambling so only the overlay's outlined mono char shows */
h1.compiling .u-word em .g[data-state="scramble"] {
  -webkit-text-stroke-color: transparent; text-stroke-color: transparent;
}
/* the scrambling overlay — absolutely centred over its glyph cell, mono + accent.
   Out of flow → its (variable) mono width never shifts a neighbour. */
h1 .g .scz {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  font-family: var(--mono);
  font-weight: 500;
  letter-spacing: -.02em;
  color: var(--accent);
  opacity: .85;
  pointer-events: none;
  white-space: pre;
}
/* overlays inside the emphasized ghost word scramble as OUTLINED mono glyphs, so
   the "source → compiled" effect respects the ghost-word treatment (no solid fill) */
h1 .u-word em .g .scz {
  color: transparent;
  -webkit-text-stroke: 1.1px var(--accent);
  text-stroke: 1.1px var(--accent);
  paint-order: stroke;
  opacity: .8;
}
/* the instant a glyph locks, it snaps down into its detent (mechanical settle) AND
   blooms a soft seafoam glow that fades out — A's spring detent + B's warm bloom,
   grafted together so each letter settles with both. The bloom is pure
   filter/text-shadow/opacity (no layout impact) and lives only for the lock moment.
   The settle (.4s) outlasts the detent's translate so the glow lingers a beat. */
h1.compiling .g[data-state="locked"] {
  animation: glyph-lock .4s var(--spring) both;
  will-change: filter, opacity;
}
@keyframes glyph-lock {
  0%   { transform: translateY(-.06em); opacity: .55;
         filter: blur(4px) brightness(1.4);
         text-shadow: 0 0 16px color-mix(in srgb, var(--seafoam) 90%, transparent); }
  45%  { transform: none; opacity: 1;
         filter: blur(0) brightness(1.1);
         text-shadow: 0 0 13px color-mix(in srgb, var(--seafoam) 65%, transparent); }
  100% { transform: none; opacity: 1;
         filter: none; text-shadow: none; }
}
/* a one-shot wash of seafoam bloom over the whole headline as the build finishes
   resolving (app.js adds .bloom on completion, removes it after the wash) —
   the warm "build complete" exhale, grafted from B. Behind the type (z-index -1),
   pure opacity, so it never touches text contrast or layout. */
.hero-title::after {
  content: ""; position: absolute; inset: -.2em -.3em;
  pointer-events: none; z-index: -1;
  background: radial-gradient(60% 120% at 32% 52%, color-mix(in srgb, var(--seafoam) 50%, transparent), transparent 70%);
  opacity: 0;
}
.hero-title.bloom::after { animation: title-bloom 1.2s var(--ease) forwards; }
@keyframes title-bloom { 0% { opacity: 0; } 30% { opacity: .85; } 100% { opacity: 0; } }
/* the moving "compile cursor" — a thin accent caret that rides the resolving
   edge left-to-right, like a build head scanning the line */
h1 .g.caret::after {
  content: ""; position: absolute;
  right: -.02em; top: .08em; bottom: .12em; width: .055em;
  background: var(--accent);
  box-shadow: 0 0 12px color-mix(in srgb, var(--accent) 60%, transparent);
  animation: caret-blink .5s steps(2, end) infinite;
}
@keyframes caret-blink { 50% { opacity: .15; } }

/* the build-log — a few mono lines that print under the headline while it
   compiles, then quiet. Space reserved so it never shifts the CTA. */
.build-log {
  font-family: var(--mono);
  font-size: clamp(.62rem, .9vw, .72rem);
  line-height: 1.7;
  letter-spacing: .02em;
  color: var(--fg-meta);
  font-variant-numeric: tabular-nums;
  margin: 0 0 clamp(8px, 1.6vw, 16px);
  min-height: calc(3 * 1.7em);   /* reserve 3 lines → 0 CLS */
  max-width: 46ch;
}
.build-log .ln {
  display: block; opacity: 0;
  white-space: nowrap; overflow: hidden;
}
.build-log .ln.show { opacity: 1; }
.build-log .ln b { color: var(--fg-3); font-weight: 500; }
.build-log .ln .ok { color: var(--accent); font-weight: 600; }
.build-log .ln .dim { color: var(--fg-4); }
/* once the build quiets, the whole log fades to a single faint resting state, and a
   terminal caret blinks at the prompt — the nerdy "ready" wink under the headline */
.build-log.quiet { color: var(--fg-4); transition: color .8s var(--ease); }
.build-log.quiet .ln { opacity: .55; }
.build-log.quiet .ln:last-child::after {
  content: "_"; display: inline-block; margin-left: .35ch;
  color: var(--accent); opacity: .9;
  animation: log-caret 1.05s steps(2, end) infinite;
}
@keyframes log-caret { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .build-log.quiet .ln:last-child::after { animation: none; opacity: .5; }
}
/* reduced-motion: final text is rendered immediately; the log is static + dim.
   Also neutralise the grafted seafoam bloom (per-glyph + whole-title wash) so the
   compile is fully motion-free. */
@media (prefers-reduced-motion: reduce) {
  /* final letter always visible (overlay is never created under reduced motion) */
  h1.compiling .g[data-state="scramble"] { color: inherit; }
  h1.compiling .u-word em .g[data-state="scramble"] { -webkit-text-stroke-color: var(--accent); text-stroke-color: var(--accent); }
  h1 .g .scz { display: none; }
  h1 .g.caret::after { display: none; }
  h1.compiling .g[data-state="locked"] { animation: none; filter: none; text-shadow: none; }
  .hero-title::after, .hero-title.bloom::after { animation: none; opacity: 0; }
  .build-log .ln { opacity: .55; }
}
/* the underline datum: draws once the hero settles (app.js adds .drawn). It
   sits clear *below* the descenders as a deliberate measurement rule — a datum,
   never a strikethrough. A hairline at small sizes, a precise thin bar at giant
   sizes; the leading-edge end-tick (::after) makes it read as a measured span. */
.u-word { position: relative; display: inline-block; padding-bottom: .14em; }
.u-rule {
  position: absolute;
  left: 0; right: 0; bottom: .01em;
  height: clamp(3px, .26vw + 1px, 6px);
  background: var(--accent);
  transform: scaleX(0); transform-origin: left center;
  transition: transform 1.1s var(--ease);
}
/* a fine end-tick rising off the rule's leading edge — the instrument signature */
.u-rule::after {
  content: ""; position: absolute; left: 0; bottom: 100%;
  width: clamp(3px, .26vw + 1px, 6px); height: clamp(7px, .7vw, 13px);
  background: inherit;
}
.u-word.drawn .u-rule { transform: scaleX(1); }

.hero .sub {
  font-family: var(--disp); font-weight: 600;
  font-size: clamp(1.1rem, 1.5vw, 1.5rem);
  letter-spacing: -.02em; line-height: 1.3;
  color: var(--accent);
  margin-bottom: clamp(22px, 2.6vw, 34px);
}

.hero .lede {
  font-size: clamp(1.1rem, 1.5vw, 1.42rem);
  line-height: 1.52;
  font-weight: 400;
  color: var(--fg-2);
  max-width: 48ch;
  margin-bottom: clamp(34px, 4vw, 52px);
}
.hero .lede strong { color: var(--fg); font-weight: 600; }

.hero-actions {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: clamp(1.1rem, 2.6vw, 2rem);
  margin-bottom: clamp(56px, 8vw, 104px);
}

/* the magnetic primary — a precision detent. JS feeds --mx/--my (cursor pull)
   and the spring curve gives it a mechanical snap; the label/arrow drift a hair
   less than the body for parallax depth. A hairline crosshair frames it. */
.btn {
  display: inline-flex; align-items: center; gap: .7rem;
  font-family: var(--mono); font-size: .76rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--on-fg); background: var(--accent);
  padding: .95rem 1.6rem; border-radius: 2px;
  position: relative; overflow: hidden;
  transform: translate(var(--mx, 0px), var(--my, 0px));
  transition: transform .45s var(--spring), box-shadow .3s var(--ease);
}
/* registration ticks at the button's corners — the labelled-instrument wink */
.btn::after, .btn::before { pointer-events: none; }
/* the wipe deepens to spruce-deep on hover (a forest, not a flash) */
.btn::before {
  content: ""; position: absolute; inset: 0;
  background: var(--accent-deep);
  transform: translateX(-101%);
  transition: transform .42s var(--mech);
}
.btn span, .btn .arr { position: relative; z-index: 1; transition: transform .45s var(--spring); }
.btn .arr { font-family: var(--mono); }
.btn:hover {
  box-shadow: 0 16px 34px -14px color-mix(in srgb, var(--accent) 55%, transparent);
}
.btn:hover::before { transform: translateX(0); }
.btn:hover .arr { transform: translateX(4px); }
/* inner content lags the magnetic body slightly → parallax depth */
.btn:hover span { transform: translateX(calc(var(--mx, 0px) * -0.12)); }
.btn:active { transition-duration: .08s; filter: brightness(.96); }

.quiet-link {
  font-family: var(--mono); font-size: .74rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--fg-2);
  display: inline-flex; align-items: center; gap: .5rem;
}
.quiet-link span { transition: transform .22s var(--ease); }
.quiet-link:hover { color: var(--accent); }
.quiet-link:hover span { transform: translateX(4px); }

.hero-meta {
  display: flex; flex-wrap: wrap;
  gap: clamp(1rem, 4vw, 2.6rem) clamp(1.6rem, 4vw, 3.4rem);
  font-size: .66rem; color: var(--fg-3);
  padding-top: clamp(28px, 3.4vw, 40px);
  border-top: 1px solid var(--line);
}
.hero-meta span { display: inline-flex; align-items: center; gap: .6rem; }
.hero-meta span::before {
  content: ""; width: 4px; height: 4px; background: var(--fg-3);
  display: inline-block; transform: rotate(45deg);
}

/* ============================================================================
   PHILOSOPHY / ABOUT — editorial asymmetric split, lots of air
   ========================================================================== */
.about-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: clamp(36px, 7vw, 112px);
  align-items: start;
}
.about-grid h2 {
  font-family: var(--disp); font-weight: 600;
  font-size: clamp(2.1rem, 4.8vw, 4.1rem);
  line-height: 1.0; letter-spacing: -.04em;
  max-width: 15ch;
}
.about-copy { padding-top: .35rem; }
.about-copy p { color: var(--fg-2); margin-bottom: 1.3rem; max-width: 50ch; }
.about-copy p strong { color: var(--fg); }
.about-copy p:last-child { margin-bottom: 0; }
.aphorism {
  font-family: var(--mono); font-size: .82rem; line-height: 1.5;
  letter-spacing: 0; text-transform: none;
  color: var(--fg-3) !important;
  margin-top: 2rem !important;
  padding-top: 1.2rem;
  border-top: 1px solid var(--line);
}
.aphorism::before { content: "// "; color: var(--fg-meta); }
@media (max-width: 860px) { .about-grid { grid-template-columns: 1fr; } }

/* ============================================================================
   PILLARS — Build & Secure. Two clean editorial panels, generous padding.
   ========================================================================== */
.pillars {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(20px, 2.6vw, 36px);
}
.pillar {
  background: var(--bg-1);
  border: 1px solid var(--line-2);   /* stronger hairline so cards read as seated parts (esp. on dark) */
  border-radius: var(--radius);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--fg) 4%, transparent);
  padding: clamp(30px, 3.6vw, 56px);
  display: flex; flex-direction: column;
  position: relative;
  overflow: hidden;                  /* clip the top register rule + corner tick */
  transition: border-color .3s var(--ease), transform .3s var(--ease), box-shadow .3s var(--ease);
}
/* the instrument register rule — a hairline seated along the card's top edge that
   ENERGISES to accent and draws across on hover/focus (the page's one motion idea,
   applied to the card). At rest it's a faint datum; on hover it locks. */
.pillar::before {
  content: ""; position: absolute; left: 0; top: 0; height: 2px; width: 100%;
  background: var(--accent);
  transform: scaleX(0); transform-origin: left;
  transition: transform .45s var(--mech);
}
.pillar:hover::before, .pillar:focus-within::before { transform: scaleX(1); }
/* a faint card index in the top-right corner — labelled-instrument numbering,
   tabular mono, matching the section-label/principle numeral system */
.pillar .ix {
  position: absolute; top: clamp(22px, 2.4vw, 30px); right: clamp(24px, 2.6vw, 34px);
  font-family: var(--mono); font-weight: 600; font-size: .62rem;
  letter-spacing: .14em; color: var(--fg-meta);
  font-variant-numeric: tabular-nums;
}
.pillar:hover, .pillar:focus-within {
  border-color: color-mix(in srgb, var(--accent) 38%, var(--line-2));
  transform: translateY(-3px);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--fg) 6%, transparent),
              0 22px 46px -26px color-mix(in srgb, var(--accent) 28%, transparent);
}
.pillar .ico {
  display: grid; place-items: center;
  width: 48px; height: 48px;
  border: 1px solid var(--line-2); border-radius: 3px;
  background: color-mix(in srgb, var(--accent) 5%, transparent);
  color: var(--accent);
  margin-bottom: clamp(22px, 2.6vw, 32px);
  transition: border-color .3s var(--ease), transform .35s var(--spring), background-color .3s var(--ease);
}
.pillar:hover .ico, .pillar:focus-within .ico {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 11%, transparent);
  transform: translateY(-2px);
}
.pillar .ico svg { width: 22px; height: 22px; }
.pillar .tag {
  display: inline-flex; align-items: center; gap: .5rem;
  font-size: .62rem; color: var(--fg-3);
  margin-bottom: .85rem;
}
/* a small diamond datum before the tag — the same mark the readouts use */
.pillar .tag::before {
  content: ""; width: 4px; height: 4px; background: var(--accent);
  transform: rotate(45deg);
}
.pillar h3 {
  font-family: var(--disp); font-weight: 600;
  font-size: clamp(1.7rem, 2.8vw, 2.4rem);
  line-height: 1.04; letter-spacing: -.035em;
  margin-bottom: 1rem;
}
.pillar > p { color: var(--fg-2); max-width: 38ch; margin-bottom: 1.8rem; }
.pillar ul { list-style: none; padding: 0; margin: 0 0 2rem; border-top: 1px solid var(--line); }
.pillar li {
  font-size: .96rem; color: var(--fg-2);
  padding: .95rem 0 .95rem 1.5rem;
  border-bottom: 1px solid var(--line);
  position: relative;
}
.pillar li b { color: var(--fg); font-weight: 600; }
.pillar li::before {
  content: ""; position: absolute; left: 0; top: 1.35rem;
  width: 6px; height: 6px;
  border: 1px solid var(--fg-3); background: transparent;
  transform: rotate(45deg);
}
.chips { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: auto; }
.chips span {
  font-size: .6rem; letter-spacing: .12em; color: var(--fg-3);
  padding: .42rem .6rem;
  border: 1px solid var(--line-2); border-radius: 2px;
}
@media (max-width: 860px) { .pillars { grid-template-columns: 1fr; } }

/* ============================================================================
   PRODUCT — Avtalon. Editorial split with a quiet typographic plate.
   (A's elaborate doc-mock is retired in favour of B's restraint — precision is
   rare here too: a single embossed § datum on a sunken panel.)
   ========================================================================== */
.product-card {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, .6fr);
  border: 1px solid var(--line-2);
  border-radius: var(--radius);
  background: var(--bg-1);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--fg) 4%, transparent),
              0 40px 80px -56px color-mix(in srgb, var(--accent-deep) 42%, transparent);
  overflow: hidden;
}
.product-body { padding: clamp(34px, 4.4vw, 72px); }
.product-card .stamp {
  display: inline-flex; align-items: center; gap: .6rem;
  font-size: .62rem; letter-spacing: .16em;
  color: var(--fg-3);
  margin-bottom: 1.4rem;
}
.product-card .stamp::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 0 var(--accent);
  animation: pulse 2.8s var(--ease) infinite;
}
@keyframes pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 52%, transparent); }
  70% { box-shadow: 0 0 0 7px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}
@media (prefers-reduced-motion: reduce) { .product-card .stamp::before { animation: none; } }
.product-card h3 {
  font-family: var(--disp); font-weight: 700;
  font-size: clamp(2.4rem, 5vw, 4rem);
  line-height: .98; letter-spacing: -.045em;
  margin-bottom: 1.2rem;
}
.product-card .desc {
  color: var(--fg-2);
  max-width: 52ch; margin-bottom: 1.9rem;
  font-size: clamp(1rem, 1.2vw, 1.14rem);
}
.product-meta {
  display: flex; flex-wrap: wrap; gap: .7rem 1.6rem;
  font-size: .62rem; letter-spacing: .1em;
  color: var(--fg-3);
  margin-bottom: 2rem;
}
.product-meta span { display: inline-flex; align-items: center; gap: .55rem; }
.product-meta span::before {
  content: ""; width: 4px; height: 4px; background: var(--fg-3); transform: rotate(45deg);
}
.product-link {
  font-family: var(--mono); font-size: .74rem; letter-spacing: .08em;
  text-transform: uppercase; font-weight: 600; color: var(--accent);
  display: inline-flex; align-items: center; gap: .5rem;
}
.product-link span { transition: transform .22s var(--ease); }
.product-link:hover span { transform: translateX(4px); }

/* the quiet typographic plate — a sunken panel with a faint ghost wordmark and a
   single embossed § registration datum. One precise detail, not a whole mock. */
.product-plate {
  position: relative;
  border-left: 1px solid var(--line);
  background:
    repeating-linear-gradient(90deg, transparent 0 calc(var(--grid) - 1px), var(--hair) calc(var(--grid) - 1px) var(--grid)),
    repeating-linear-gradient(0deg, transparent 0 calc(var(--grid) - 1px), var(--hair) calc(var(--grid) - 1px) var(--grid)),
    var(--bg-2);
  display: grid; place-items: center;
  overflow: hidden;
  min-height: 220px;
}
/* faint concentric registration rings centred on the seal — the plate reads as a
   measurement datum, not an empty panel (masked soft so it never competes) */
.product-plate::before {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 260px; height: 260px; transform: translate(-50%, -50%);
  border-radius: 50%;
  background:
    radial-gradient(circle, transparent 70px, var(--hair) 70px 71px, transparent 71px),
    radial-gradient(circle, transparent 108px, var(--hair) 108px 109px, transparent 109px);
  -webkit-mask-image: radial-gradient(circle, #000 40%, transparent 72%);
          mask-image: radial-gradient(circle, #000 40%, transparent 72%);
  opacity: .7; pointer-events: none;
}
.product-plate .plate-word {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  font-family: var(--disp); font-weight: 700;
  font-size: clamp(2.6rem, 8vw, 5.4rem);
  letter-spacing: -.05em;
  color: var(--fg); opacity: .045;
  white-space: nowrap;
}
.product-plate .plate-seal {
  position: relative; z-index: 1;
  width: 64px; height: 64px; border-radius: 50%;
  display: grid; place-items: center;
  color: var(--fg-2);
  background: radial-gradient(circle at 38% 32%, color-mix(in srgb, var(--fg) 9%, var(--bg-2)), var(--bg-2));
  border: 1px solid var(--line-2);
  box-shadow: 0 0 0 5px var(--bg-2), 0 0 0 6px var(--line),
              inset 0 1px 0 color-mix(in srgb, var(--fg) 12%, transparent);
}
.product-plate .plate-seal::before {
  content: ""; position: absolute; inset: 6px; border-radius: 50%;
  border: 1px dashed color-mix(in srgb, var(--fg-3) 55%, transparent);
}
.product-plate .plate-seal span {
  font-family: var(--disp); font-size: 1.7rem; font-weight: 600; line-height: 1;
}
.product-plate .plate-ref {
  position: absolute; bottom: clamp(16px, 2.4vw, 24px); left: 0; right: 0;
  text-align: center;
  font-family: var(--mono); font-size: .56rem; letter-spacing: .2em;
  text-transform: uppercase; color: var(--fg-meta);
}
@media (max-width: 860px) {
  .product-card { grid-template-columns: 1fr; }
  .product-plate { border-left: none; border-top: 1px solid var(--line); min-height: 170px; }
}

/* ---- the seal "compile-lock" — the hero's signature, recurring ONCE -----------
   When the Avtalon plate scrolls into view, the REF/BankID datum register-ticks
   out of a brief monospace scramble and LOCKS into its final form, while the §
   seal settles with the SAME spring detent + seafoam bloom the hero glyphs use.
   This is the only echo of the compile language below the hero. One-shot.
   0 CLS by construction: the final datum text is always the in-flow, layout-
   determining content of each .pg cell (it's already in the DOM for no-JS); the
   scrambling mono char rides an OUT-OF-FLOW .psc overlay (same technique as the
   hero's .scz), so its width can never re-wrap the line. */
.product-plate .plate-ref .pg { position: relative; display: inline-block; }
/* while a cell scrambles, hide its final glyph and show the overlay on top */
.plate-ref.compiling .pg[data-state="scramble"] { color: transparent; }
.product-plate .plate-ref .pg .psc {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  color: var(--accent); opacity: .85;
  pointer-events: none; white-space: pre;
}
/* each datum cell locks with the hero's spring detent + seafoam text-shadow
   (scaled to the small datum) — a register-tick snapping into place */
.plate-ref.compiling .pg[data-state="locked"] { animation: ref-lock .42s var(--spring) both; }
@keyframes ref-lock {
  0%   { opacity: .5;  filter: blur(2px) brightness(1.35);
         text-shadow: 0 0 9px color-mix(in srgb, var(--seafoam) 90%, transparent); }
  45%  { opacity: 1;   filter: blur(0) brightness(1.08);
         text-shadow: 0 0 7px color-mix(in srgb, var(--seafoam) 60%, transparent); }
  100% { opacity: 1;   filter: none; text-shadow: none; }
}
/* the § seal's one settle: a single spring detent + soft seafoam bloom pulse, the
   same warm "build complete" exhale the hero title gives — fired once on lock */
.product-plate .plate-seal { will-change: transform; }
.plate-seal.lock { animation: seal-detent .55s var(--spring) both; }
.plate-seal.lock::after {
  content: ""; position: absolute; inset: -7px; border-radius: 50%;
  pointer-events: none;
  background: radial-gradient(circle, color-mix(in srgb, var(--seafoam) 55%, transparent), transparent 70%);
  animation: seal-bloom 1.1s var(--ease) forwards;
}
@keyframes seal-detent {
  0%   { transform: scale(.9); }
  55%  { transform: scale(1.045); }
  100% { transform: scale(1); }
}
@keyframes seal-bloom { 0% { opacity: 0; } 28% { opacity: .8; } 100% { opacity: 0; } }
/* reduced motion: render the final locked datum + static seal immediately; no
   scramble overlay is ever created (JS-gated), and every animation is neutralised */
@media (prefers-reduced-motion: reduce) {
  .plate-ref.compiling .pg[data-state="scramble"] { color: inherit; }
  .product-plate .plate-ref .pg .psc { display: none; }
  .plate-ref.compiling .pg[data-state="locked"] { animation: none; filter: none; text-shadow: none; }
  .plate-seal.lock { animation: none; }
  .plate-seal.lock::after { animation: none; opacity: 0; }
}

/* ============================================================================
   PRINCIPLES — how we work. Numbered, on a ruled column (B's editorial frame).
   ========================================================================== */
.principles {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0;
  border-top: 1px solid var(--line-2);
}
.principle {
  padding: clamp(34px, 3.4vw, 52px) clamp(26px, 2.8vw, 40px) clamp(30px, 3.2vw, 48px) 0;
  border-bottom: 1px solid var(--line);
  border-right: 1px solid var(--line);
  position: relative;
  transition: background-color .35s var(--ease);
}
.principle:last-child { border-right: none; padding-right: 0; }
/* a register tick seated at each column's top-left on the rule — the instrument
   numbers its own divisions. Energises to accent on hover (the one motion idea). */
.principle::before {
  content: ""; position: absolute; left: 0; top: -1px;
  width: clamp(28px, 3vw, 44px); height: 2px;
  background: var(--fg-4);
  transition: background-color .35s var(--ease), width .4s var(--mech);
}
.principle:hover { background: color-mix(in srgb, var(--accent) 3.5%, transparent); }
.principle:hover::before { background: var(--accent); width: clamp(44px, 5vw, 72px); }
/* the numeral promoted to an instrument-scale ghost figure — big, outlined, sits
   as a measured datum the heading is registered against (echoes the hero's
   number-as-instrument language instead of a tiny mono label). */
.principle .no {
  font-family: var(--disp); font-weight: 700;
  font-size: clamp(2.4rem, 4vw, 3.4rem);
  line-height: .9; letter-spacing: -.04em;
  color: transparent;
  -webkit-text-stroke: 1px color-mix(in srgb, var(--accent) 42%, transparent);
  text-stroke: 1px color-mix(in srgb, var(--accent) 42%, transparent);
  font-variant-numeric: tabular-nums;
  margin-bottom: clamp(.8rem, 1.4vw, 1.1rem);
  transition: -webkit-text-stroke-color .35s var(--ease);
}
.principle:hover .no {
  -webkit-text-stroke-color: var(--accent);
  text-stroke-color: var(--accent);
}
.principle h3 {
  font-family: var(--disp); font-weight: 600;
  font-size: clamp(1.4rem, 2.1vw, 1.85rem);
  line-height: 1.08; letter-spacing: -.03em;
  margin-bottom: .9rem;
}
.principle p { color: var(--fg-2); font-size: .98rem; max-width: 34ch; }
@media (max-width: 860px) {
  .principles { grid-template-columns: 1fr; }
  .principle { border-right: none; padding-right: 0; }
  .principle:last-child { border-bottom: none; }
}

/* ============================================================================
   CONTACT — the big close. Giant type, the datum-line under the mail.
   ========================================================================== */
.contact {
  padding-block: clamp(96px, 14vw, 200px);
  background: var(--bg-1);
  position: relative;
  isolation: isolate;          /* contain the closing atmosphere whisper */
  overflow: hidden;
}
/* ---- the closing exhale — a single seafoam whisper that bookends the hero's
   opener. ONE soft bloom in the lower-right, masked to dissolve well before the
   copy, very low opacity → a faint recurrence of the forest light, not a busy
   field. GPU-only; drifts under motion, static and faint under reduced motion. */
.contact::before {
  content: ""; position: absolute; z-index: -1;
  right: -10%; bottom: -22%;
  width: clamp(420px, 52vw, 760px); aspect-ratio: 1;
  background: radial-gradient(circle at 50% 50%,
    color-mix(in srgb, var(--seafoam) 70%, transparent), transparent 64%);
  filter: blur(58px);
  opacity: .5;
  pointer-events: none;
}
:root[data-theme="dark"] .contact::before {
  background: radial-gradient(circle at 50% 50%, color-mix(in srgb, #3f7d5e 80%, transparent), transparent 64%);
  opacity: .34;
}
@media (prefers-reduced-motion: no-preference) {
  .contact::before { animation: drift-close 30s var(--ease) infinite alternate; }
  @keyframes drift-close {
    from { transform: translate3d(0,0,0) scale(1); }
    to   { transform: translate3d(-5%, -4%, 0) scale(1.12); }
  }
}
.contact h2 {
  font-family: var(--disp); font-weight: 700;
  font-size: clamp(2.6rem, 7vw, 5.8rem);
  line-height: .96; letter-spacing: -.045em;
  margin-bottom: 1.3rem; max-width: 13ch;
}
.contact > .container > p {
  color: var(--fg-2); max-width: 48ch;
  font-size: clamp(1.06rem, 1.4vw, 1.26rem);
  margin-bottom: clamp(40px, 5vw, 64px);
}
.contact-mail {
  display: inline-flex; align-items: center; gap: 1rem;
  font-family: var(--disp); font-weight: 600;
  font-size: clamp(1.6rem, 4.6vw, 3.3rem);
  letter-spacing: -.04em; color: var(--fg);
  position: relative;
}
.contact-mail::before {
  content: ""; position: absolute; left: 0; right: 0; bottom: -.06em;
  height: 2px; background: var(--accent);
  transform: scaleX(0); transform-origin: left;
  transition: transform .5s var(--ease);
}
.contact-mail::after {
  content: "→"; font-family: var(--mono); font-size: .5em;
  color: var(--fg-2);
  transition: transform .3s var(--ease);
}
.contact-mail:hover::before { transform: scaleX(1); }
.contact-mail:hover::after { transform: translate(6px, -2px); }

/* the closing readout datum — bookends the hero's instrument readout. Mono,
   tabular, AA-legible; the same diamond separators + live lamp as the header,
   signing the page's close like a build report. */
.contact-datum {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: .5rem clamp(.9rem, 2vw, 1.5rem);
  max-width: none; margin-bottom: 0;   /* override the intro-paragraph rule */
  margin-top: clamp(34px, 4.4vw, 56px);
  font-family: var(--mono); font-size: .64rem; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--fg-3); font-variant-numeric: tabular-nums;
}
.contact-datum .d { display: inline-flex; align-items: center; gap: .5rem; }
.contact-datum .k { color: var(--fg-meta); }
.contact-datum .v { color: var(--fg-2); letter-spacing: .1em; }
.contact-datum .dot { width: 4px; height: 4px; background: var(--accent); transform: rotate(45deg); }
.contact-datum .ready { color: var(--accent); }
.contact-datum .ready .v { color: var(--accent); }
.contact-datum .lamp {
  width: 6px; height: 6px; border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 55%, transparent);
  animation: lamp 2.6s var(--ease) infinite;
}
@media (prefers-reduced-motion: reduce) { .contact-datum .lamp { animation: none; } }

/* ============================================================================
   FOOTER — a quiet, well-spaced masthead: brand + tagline, contact, base line.
   ========================================================================== */
.site-foot {
  background: var(--bg);
  border-top: 1px solid var(--line);
  color: var(--fg-2);
}
.site-foot .container {
  padding-block: clamp(48px, 6vw, 84px);
  display: grid;
  grid-template-columns: 1fr auto;
  gap: clamp(36px, 4.4vw, 60px) 2rem;
  align-items: start;
}
.foot-brand { display: flex; flex-direction: column; gap: .9rem; align-items: flex-start; }
.foot-brand .row { display: flex; align-items: center; gap: .7rem; }
.foot-brand .mark { color: var(--accent); width: 24px; height: 24px; }
.foot-brand .name {
  font-family: var(--disp); font-size: 1.12rem; font-weight: 600;
  letter-spacing: -.04em; color: var(--fg);
}
/* a short positioning line under the wordmark — fills the left column so the
   footer reads as a balanced masthead, not a brand floating over dead space */
.foot-brand .tagline {
  font-family: var(--disp); font-size: .92rem; line-height: 1.5;
  color: var(--fg-2); max-width: 30ch; letter-spacing: -.01em;
}
.foot-cols {
  display: grid; grid-template-columns: auto;
  gap: 1.4rem 3rem;
  text-align: left;
}
.foot-col h4 {
  font-size: .58rem; font-weight: 600;
  color: var(--fg-3);
  margin-bottom: .8rem;
}
.foot-col a, .foot-col p {
  display: block; font-family: var(--mono); font-size: .8rem; line-height: 1.7;
  letter-spacing: .02em; text-transform: none;
  color: var(--fg-2);
  transition: color .2s var(--ease);
}
.foot-col a:hover { color: var(--accent); }
.foot-base {
  grid-column: 1 / -1;
  display: flex; flex-wrap: wrap; gap: .6rem 1.6rem;
  justify-content: space-between; align-items: center;
  margin-top: clamp(18px, 2.4vw, 30px);
  padding-top: 1.6rem;
  border-top: 1px solid var(--line);
  font-size: .62rem; letter-spacing: .08em;
  color: var(--fg-3);
}
.foot-base .sign { color: var(--fg-2); text-transform: none; letter-spacing: .04em; }
.foot-base .build { color: var(--fg-meta); }

/* the contact "ready" lamp keyframes (shared) — a soft expanding ring pulse */
@keyframes lamp {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 60%, transparent); }
  70%  { box-shadow: 0 0 0 6px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}
@media (max-width: 680px) {
  .site-foot .container { grid-template-columns: 1fr; }
  .foot-cols { text-align: left; grid-template-columns: repeat(2, 1fr); }
}

/* ============================================================================
   SCROLL REVEAL (progressive enhancement)
   The .js flag (set in <head>) hides observed blocks pre-paint; app.js adds .in.
   Hero uses staggered .reveal-N. Reduced motion → everything visible.
   ========================================================================== */
.js .observe {
  opacity: 0;
  transform: translateY(18px);
  /* crisp + mechanical: a measured in-out, not a soft drift */
  transition: opacity .66s var(--mech), transform .66s var(--mech), clip-path .66s var(--mech);
  /* each block carries its own conducted delay (--rd), set per-section below so a
     section's heading LEADS and its supporting copy FOLLOWS — a staged entrance
     that echoes the hero's load rather than one uniform fade. */
  transition-delay: var(--rd, 0s);
  will-change: opacity, transform;
}
.js .observe.in { opacity: 1; transform: none; will-change: auto; }
/* the product card is choreographed as a grid-child (rise animation) below, so it
   must not also carry the generic block transform — let the animation own it. */
.js .product-card.observe { transform: none; transition: none; }

/* ---- conducted section choreography -------------------------------------
   The section LABEL leads (it's the instrument's title bar), then the heading,
   then the supporting copy — a small staged cascade per section, not a block
   fade. Delays are tuned so the eye is led down through the section once. */
.js .section-label.observe,
.js .contact .section-label.observe { --rd: 0s; }
.js .about-grid h2.observe,
.js .contact h2.observe { --rd: .10s; }
.js .about-copy.observe,
.js .contact > .container > p.observe { --rd: .20s; }
.js .contact-mail.observe { --rd: .30s; }
.js .contact-datum.observe { --rd: .40s; }

/* grids reveal child-by-child — a precise engineered cascade, not one big fade.
   Each card rises into its detent in sequence so it reads as parts being seated
   onto the instrument, slightly behind the section label that introduces them. */
.js .pillars.in .pillar,
.js .principles.in .principle,
.js .product-card.in {
  opacity: 0; transform: translateY(22px);
  animation: rise .66s var(--mech) both;
  animation-delay: var(--cd, .14s);
}
.js .pillars.in .pillar:nth-child(1) { --cd: .14s; }
.js .pillars.in .pillar:nth-child(2) { --cd: .26s; }
.js .principles.in .principle:nth-child(1) { --cd: .14s; }
.js .principles.in .principle:nth-child(2) { --cd: .25s; }
.js .principles.in .principle:nth-child(3) { --cd: .36s; }
@keyframes rise { to { opacity: 1; transform: none; } }

.js .reveal {
  opacity: 0; transform: translateY(14px);
  transition: opacity .8s var(--ease), transform .8s var(--ease);
}
.js .reveal.in { opacity: 1; transform: none; }
.js .reveal-1 { transition-delay: .04s; }
.js .reveal-2 { transition-delay: .13s; }
.js .reveal-3 { transition-delay: .26s; }
.js .reveal-4 { transition-delay: .38s; }
.js .reveal-5 { transition-delay: .50s; }
.js .reveal-6 { transition-delay: .60s; }

@media (prefers-reduced-motion: reduce) {
  .js .observe, .js .reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
  .u-rule { transition: none; transform: scaleX(1); }
  .section-label::after { transition: none; transform: scaleX(1); }
}

/* ---- print: ink on paper (spruce flattens to near-black ink) ---- */
@media print {
  :root, :root[data-theme="dark"], :root[data-theme="light"] {
    --bg:#fff; --bg-1:#fff; --bg-2:#fff; --bg-3:#fff;
    --fg:#0c1a13; --fg-2:#26352c; --fg-3:#3a4a40; --fg-meta:#44544a; --fg-4:#9aab9f;
    --line:#bcc9bd; --line-2:#9aab9f;
    --accent:#1c3a2c; --accent-deep:#16291f;
  }
  .site-head, .site-nav, .theme-toggle, .neuralnet { display: none !important; }
  .hero::after { display: none !important; }
  * { background: transparent !important; box-shadow: none !important; text-shadow: none !important; }
  a[href^="http"]::after { content: " — " attr(href); font-family: var(--mono); font-size: .8em; color: #4a5a50; word-break: break-all; }
  .btn { border: 1px solid var(--accent); color: var(--accent) !important; background: #fff !important; }
  body { font-size: 11pt; }
}
