/* SolaryxDev site: the design system. Tokens, fonts, the shared chrome (the lockup at the top left,
   the island in the middle and its panels, the actions at the top right, the Search panel,
   the footer), shared components, the contact form, and the home: an Astra article over the star
   field.
   The particle field's own layers are field/field.css and are not restyled here.

   Layers (z): field backdrop 0 · the home and the footer 10 (the hero's and the cues' drag
   surfaces inside) · section index 60 · scrim 90 · island 100 · lockup and actions 102 · skip link 110 ·
   dialog (top layer).
   Shapes: crisp rounded rectangles, never a pill. Every radius stays under half its element's
   height: tags 4px, controls 8px, buttons 10px, fields 12px, cards 12 to 14px, the island 12px
   closed and 14px open. Markers and dots are small squares. */

/* ── fonts (self-hosted, SIL OFL; licence texts beside the files) ───────────────────────────── */
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/geist-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: "Geist";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/geist-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: "Geist Mono";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/geist-mono-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: "Geist Mono";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/geist-mono-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;
}
/* the name: Unbounded, subset to the ten letters of "SolaryxDev", wght 700 to 900 */
@font-face {
  font-family: "SX Name";
  font-style: normal;
  font-weight: 700 900;
  font-display: block;
  src: url("/fonts/unbounded-wordmark.woff2") format("woff2");
}
/* Inter stays available for the one-line switch below; it only downloads if it is used */
@font-face {
  font-family: "SX Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/inter-var.woff2") format("woff2");
}

/* ── tokens ─────────────────────────────────────────────────────────────────────────────────── */
:root {
  color-scheme: dark;

  /* THE NAME'S FACE, one line: `unbounded` (heavy, tight) or `inter` (the approved Inter 600 set).
     Read by the @container style() rule under "the lockup" below. */
  --name: unbounded;

  --font-ui: "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --font-name: "SX Name", "Arial Black", sans-serif;
  --font-name-inter: "SX Inter", system-ui, sans-serif;

  /* colour: monochrome; the field is the only colour on the page */
  --bg: #000;
  --ink: #f5f5f2;
  --ink-2: rgba(245, 245, 242, 0.62);        /* 7.3:1 on black */
  --ink-3: rgba(245, 245, 242, 0.5);         /* 5.0:1 on black */
  --line: rgba(255, 255, 255, 0.09);
  --line-2: rgba(255, 255, 255, 0.16);
  --fill: rgba(255, 255, 255, 0.035);
  --nav-pad: 16px;                           /* the fixed navs' soft backing: its inset around the links */
  --fill-2: rgba(255, 255, 255, 0.07);
  --fill-3: rgba(255, 255, 255, 0.1);
  --glass: rgba(12, 12, 14, 0.78);
  --alert: #ff6b6b;                          /* the one sanctioned red, errors only */

  /* type ramp (Astra's, fluid from 375 to 1440 px) */
  --fs-display: clamp(28px, 22.4px + 1.78vw, 48px);
  --lh-display: 1.1;
  --tr-display: -0.032em;
  --fs-body: clamp(15px, 14.3px + 0.19vw, 17px);
  --lh-body: 1.55;
  --fs-small: 14px;
  --fs-meta: 13px;
  --fs-xs: 12px;

  /* space */
  --gutter: 32px;
  --col-gap: 24px;
  --pg-top: 92px;                            /* under the header band: 14 + 46 + 32 */

  /* the page's grid: 1376 px up to 1496 px wide, then 92% of the screen (4% either side), up to
     2400 px, so a wide screen is used edge to edge instead of leaving the page in the middle */
  --grid: min(2400px, max(1376px, 92vw));
  /* wide screens step the type and the reading column up with the width (1 up to 1599 px):
     --z for running text and cards, --zd for headings and figures (set below) */
  --z: 1;
  --zd: 1;

  /* the header band. The lockup sits at the top left, the island in the middle and the actions at
     the top right (below 1200 px the island is Menu and Book a call at the right), in one band
     that spans the page's 12-column grid plus 14 px either side; the lockup's left edge is the
     grid's left edge, so it lines up with every page's copy. */
  --hdr-t: 14px;
  --hdr-x: max(18px, calc((100vw - var(--grid)) / 2 - 14px));
  --hdr-in: 14px;
  --row: 44px;

  /* radius (see the header: never a pill) */
  --r-tag: 4px;
  --r-ctl: 8px;
  --r-btn: 10px;
  --r-field: 12px;
  --r-card: 14px;
  --r-isl: 12px;
  --r-isl-open: 14px;

  /* motion */
  --spring: linear(0, 0.042, 0.144, 0.274, 0.413, 0.547, 0.666, 0.767, 0.849, 0.912, 0.958, 0.991, 1.012, 1.024, 1.03, 1.032, 1.03, 1.027, 1.022, 1.018, 1.014, 1.01, 1.007, 1.004, 1);
  --settle: cubic-bezier(0.32, 0.72, 0, 1);
  --out: cubic-bezier(0.22, 1, 0.36, 1);
}
@media (max-width: 719px) {
  :root { --gutter: 20px; --col-gap: 12px; --pg-top: 72px; --hdr-t: 10px; --hdr-x: 8px; --hdr-in: 12px; }
}
@media (min-width: 1600px) { :root { --z: 1.05; --zd: 1.1; --col-gap: 28px; } }
@media (min-width: 1800px) { :root { --z: 1.1; --zd: 1.2; --col-gap: 32px; } }
@media (min-width: 2000px) { :root { --z: 1.15; --zd: 1.3; } }
@media (min-width: 2240px) { :root { --z: 1.2; --zd: 1.4; --col-gap: 40px; } }
@media (min-width: 2480px) { :root { --z: 1.25; --zd: 1.5; } }

/* ── base ───────────────────────────────────────────────────────────────────────────────────── */
html, body { background: var(--bg); }
body {
  margin: 0;
  color: var(--ink);
  font: 400 16px/1.5 var(--font-ui);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  caret-color: var(--ink);
}
html.isl-locked { overflow: hidden; }
::selection { background: rgba(245, 245, 242, 0.88); color: #000; }
.sr {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; margin: 0; padding: 0; }
h1, h2, h3, p { margin: 0; }
:focus-visible { outline: 2px solid rgba(255, 255, 255, 0.92); outline-offset: 2px; }
.skip {
  position: fixed; left: var(--hdr-x); top: var(--hdr-t); z-index: 110;
  display: inline-flex; align-items: center; height: 46px; padding: 0 16px; border-radius: var(--r-isl);
  background: var(--ink); color: #000; font: 500 13px/1 var(--font-ui);
  transform: translateY(-140px); transition: transform 0.2s var(--settle);
}
.skip:focus-visible { transform: none; }
.icon { width: 14px; height: 14px; flex: none; }
.sprite { position: absolute; }   /* an <svg> that only holds <symbol>s (the home's): takes no room */

/* ── the lockup, top left, on every page ───────────────────────────────────────────────────────
   The X of the favicon, "SolaryxDev" in Unbounded and the line under the name, in the header band
   beside the island. Everything scales from the name's size (--bn): 24 px up to 1200 px, then
   growing with the screen to 30 px, where the name is as wide as the line under it; the lockup
   always clears the centred island (chrome.js checks). The line leaves once the page moves or a
   panel opens. Phones: the X and the name.
   On the home it arrives once the stars have formed the X; everywhere else it is simply there. */
.brand {
  --bn: 24px;
  position: fixed;
  z-index: 102;
  top: var(--hdr-t);
  /* never under a phone's rounded corner or notch in landscape (viewport-fit=cover): the lockup
     keeps at least 12 px beside the safe area, so the X is never cut at the left edge */
  left: max(calc(var(--hdr-x) + var(--hdr-in)), calc(env(safe-area-inset-left, 0px) + 12px));
  box-sizing: border-box;
  display: flex;
  align-items: flex-start;
  gap: calc(var(--bn) * 0.46);
  padding-top: calc((var(--row) + 2px - var(--bn) * 1.3) / 2);
  color: var(--ink);
  border-radius: 6px;
  -webkit-tap-highlight-color: transparent;
}
@media (min-width: 1200px) {
  .brand { --bn: clamp(24px, calc(24px + (100vw - 1200px) * 0.0136), calc(30px * var(--z))); }
}
.brand:focus-visible { outline-offset: 6px; }
.brand-mark {
  flex: none;
  width: calc(var(--bn) * 1.3);
  height: calc(var(--bn) * 1.3);
  filter: drop-shadow(0 1px 10px rgba(0, 0, 0, 0.7));
}
.brand-text { display: flex; flex-direction: column; min-width: 0; }
.brand-name {
  font-family: var(--font-name);
  font-weight: 900;
  font-size: var(--bn);
  line-height: 1.3;
  letter-spacing: -0.035em;
  white-space: nowrap;
  text-shadow: 0 1px 14px rgba(0, 0, 0, 0.75);
}
.brand-dev { color: #8f8f99; }          /* as in the hero: 6.5:1 on black */
.brand-line {
  max-width: 17.5em;
  margin-top: 1px;
  font: 400 12.5px/1.36 var(--font-ui);
  letter-spacing: -0.004em;
  color: var(--ink-2);
  text-wrap: balance;
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.85);
  transition: color 0.2s, opacity 0.3s var(--settle), visibility 0s;
}
.brand:hover .brand-line { color: var(--ink); }
html[data-scrolled] .brand-line, body:has(.island[data-state="open"]) .brand-line {
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s, visibility 0s linear 0.2s;
}
/* the intro starts at 1% opacity, not 0: invisible, but Chrome counts a first paint at 0 as no
   paint and never reports it, which would leave the home with no Largest Contentful Paint */
html[data-intro] .brand > * {
  opacity: 0.01;
  transform: translateY(8px);
  filter: blur(6px);
  animation: brand-in 1.1s var(--out) 3.3s forwards;
}
html[data-intro] .brand-text { animation-delay: 3.45s; }
@keyframes brand-in { to { opacity: 1; transform: none; filter: blur(0); } }
html[data-intro] .island, html[data-intro] .hdr-acts { opacity: 0.01; transform: translateY(-8px); animation: isl-in 0.9s var(--out) 0.35s forwards; }
@keyframes isl-in { to { opacity: 1; transform: none; } }

/* a page that scrolls: its copy passes under the header through a band of black,
   shown once the page has moved (chrome.js sets data-scrolled from a sentinel) */
body::before {
  content: "";
  position: fixed;
  z-index: 95;
  top: 0;
  left: 0;
  right: 0;
  height: calc(var(--hdr-t) + var(--row) + 44px);
  background: linear-gradient(to bottom, #000 0, #000 calc(var(--hdr-t) + var(--row) + 4px), rgba(0, 0, 0, 0.72) calc(var(--hdr-t) + var(--row) + 18px), rgba(0, 0, 0, 0));
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.35s var(--settle);
}
html[data-scrolled] body::before { opacity: 1; }
/* below 720 px: the X and the name, so they never meet the island */
@media (max-width: 719px) {
  .brand { --bn: 19px; }
  .brand-line { display: none; }
}
@media (max-width: 599px) {
  .brand { --bn: 17px; }
}
/* under 360 px the X gives way, so the name still clears Menu and Book a call */
@media (max-width: 359px) {
  .brand { --bn: 15px; }
  .brand-mark { display: none; }
}
/* the switch: --name: inter restores the approved Inter 600 set */
@container style(--name: inter) {
  .brand-name { font-family: var(--font-name-inter); font-weight: 600; letter-spacing: -0.03em; }
}

/* ── buttons and tags (shared by the island, the footer and the pages) ─────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  box-sizing: border-box; height: 44px; padding: 0 20px; border: 0; border-radius: var(--r-btn);
  font: 500 14px/1 var(--font-ui); letter-spacing: -0.005em; white-space: nowrap; cursor: pointer;
  transition: background-color 0.2s, color 0.2s, box-shadow 0.2s, transform 0.2s var(--settle), opacity 0.2s;
}
.btn:active { transform: scale(0.97); }
.btn-sm { height: 32px; padding: 0 12px; border-radius: var(--r-ctl); font-size: 13px; }
.btn-solid { background: var(--ink); color: #0a0a0b; font-weight: 600; }
.btn-solid:hover { background: #fff; }
.btn-ghost { background: var(--fill-3); color: var(--ink); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.06); }
.btn-ghost:hover { background: rgba(255, 255, 255, 0.16); }
.btn[disabled] { cursor: progress; opacity: 0.6; }
.btn .icon { width: 13px; height: 13px; }

/* status tags are text first; the square before "Live" is the one mark of real state */
.tag {
  display: inline-flex; align-items: center; gap: 6px; flex: none;
  box-sizing: border-box; height: 20px; padding: 0 7px;
  border: 1px solid rgba(255, 255, 255, 0.16); border-radius: var(--r-tag);
  font: 500 11px/1 var(--font-ui); letter-spacing: 0.01em; color: var(--ink-2); white-space: nowrap;
}
.tag-live { color: var(--ink); border-color: rgba(255, 255, 255, 0.32); }
.tag-live::before { content: ""; width: 5px; height: 5px; border-radius: 1px; background: #fff; box-shadow: 0 0 6px rgba(255, 255, 255, 0.7); }

/* ── the island ────────────────────────────────────────────────────────────────────────────────
   Closed, a crisp dark-glass bar in the middle of the header band: the seven items, with Search,
   Client login and Book a call beside it at the top right (.hdr-acts). Open, it grows out to
   both sides and down into the full-width panel, its row staying where it was, and the lockup and
   the actions end up inside it. Below 1200 px it is Menu and Book a call at the right, and opens
   into a drawer (a full sheet on phones) that holds the actions too. chrome.js measures, the CSS
   owns the easing. */
.isl-scrim {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: rgba(0, 0, 0, 0.42);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.35s var(--settle);
}
.isl-scrim[data-on="true"] { opacity: 1; pointer-events: auto; }

.island {
  position: fixed;
  top: var(--hdr-t);
  right: max(var(--hdr-x), env(safe-area-inset-right, 0px));
  z-index: 100;
  box-sizing: border-box;
  width: var(--isl-w, auto);
  height: var(--isl-h, calc(var(--row) + 2px));
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  grid-template-rows: var(--row) minmax(0, 1fr);
  align-items: center;
  padding: 0 5px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--r-isl);
  background: var(--glass);
  -webkit-backdrop-filter: blur(20px) saturate(1.5);
  backdrop-filter: blur(20px) saturate(1.5);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 2px 6px rgba(0, 0, 0, 0.35), 0 18px 48px rgba(0, 0, 0, 0.55);
  overflow: hidden;
  font-family: var(--font-ui);
}
.island.is-ready { transition: width 0.3s var(--settle), height 0.3s var(--settle), border-radius 0.3s var(--settle); }
.island.is-ready[data-state="open"] { transition: width 0.46s var(--spring), height 0.46s var(--spring), border-radius 0.46s var(--spring); }
.island[data-state="open"] { border-radius: var(--r-isl-open); }

/* the row (wide screens): in the middle, between two equal spaces, so it stays put as it opens */
@media (min-width: 1200px) {
  .island { left: var(--hdr-x); margin-inline: auto; width: var(--isl-w, fit-content); grid-template-columns: minmax(0, 1fr) auto auto minmax(0, 1fr); }
  .island .isl-utils, .island .isl-book { display: none; }
}
.isl-menu { display: none; }
.isl-nav { grid-column: 2; grid-row: 1; display: flex; align-items: center; min-width: 0; }
.isl-book { grid-column: 3; grid-row: 1; margin-left: 4px; }
.isl-top { display: flex; align-items: center; gap: 1px; }
.isl-item {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  box-sizing: border-box;
  height: 32px;
  margin: 0;
  padding: 0 9px;
  border: 0;
  border-radius: var(--r-ctl);
  background: transparent;
  color: var(--ink-2);
  font: 500 13.5px/1 var(--font-ui);
  letter-spacing: -0.005em;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.2s, color 0.2s;
}
.isl-item:hover { color: var(--ink); background: rgba(255, 255, 255, 0.06); }
.isl-item[aria-expanded="true"] { color: var(--ink); background: rgba(255, 255, 255, 0.09); }
/* the section this page belongs to: full ink and a 1 px rule under the label */
.isl-item[data-current], .isl-item[aria-current="page"] { position: relative; color: var(--ink); }
.isl-item[data-current]::after, .isl-item[aria-current="page"]::after {
  content: ""; position: absolute; left: 9px; right: 9px; bottom: 3px; height: 1px; background: rgba(255, 255, 255, 0.55);
}
.isl-utils { display: flex; align-items: center; gap: 1px; }
.isl-utils::before { content: ""; flex: none; width: 1px; height: 18px; margin: 0 7px 0 6px; background: rgba(255, 255, 255, 0.12); }
.isl-util {
  display: inline-flex; align-items: center; gap: 6px; box-sizing: border-box;
  height: 32px; padding: 0 9px; border-radius: var(--r-ctl);
  color: var(--ink-2); font: 500 13.5px/1 var(--font-ui); letter-spacing: -0.005em; white-space: nowrap;
  transition: background-color 0.2s, color 0.2s;
}
.isl-util:hover { color: var(--ink); background: rgba(255, 255, 255, 0.06); }
.isl-util .icon { width: 15px; height: 15px; }
.isl-login { margin-left: 5px; }
.isl-legal { display: none; }
/* 1200 to 1339 px: the items tighten, so the row still clears the lockup (chrome.js adds the same
   squeeze wherever a measurement says it must) */
@media (min-width: 1200px) and (max-width: 1339px) {
  .isl-util > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .isl-util { width: 32px; padding: 0; justify-content: center; }
}
.island[data-tight] .isl-util > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.island[data-tight] .isl-util { width: 32px; padding: 0; justify-content: center; }
@media (min-width: 1200px) and (max-width: 1339px) { .isl-item { padding: 0 7px; font-size: 13px; } }
.island[data-tight] .isl-item { padding: 0 7px; }
.isl-link[aria-current="page"] .isl-lbl::after { content: ""; flex: none; width: 5px; height: 5px; margin-left: auto; border-radius: 1px; background: var(--ink); }

/* the actions at the top right (wide screens): Search, Client login and Book a call; below
   1280 px Search keeps its icon and gives up its word. Below 1200 px they live in the
   drawer instead. */
.hdr-acts { display: none; }
@media (min-width: 1200px) {
  .hdr-acts {
    position: fixed;
    z-index: 102;
    top: var(--hdr-t);
    right: calc(var(--hdr-x) + var(--hdr-in));
    height: calc(var(--row) + 2px);
    display: flex;
    align-items: center;
    gap: 4px;
  }
}
.hdr-util {
  display: inline-flex; align-items: center; gap: 6px; box-sizing: border-box;
  height: 32px; padding: 0 9px; border-radius: var(--r-ctl);
  color: var(--ink-2); font: 500 13.5px/1 var(--font-ui); letter-spacing: -0.005em; white-space: nowrap;
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.85);
  transition: background-color 0.2s, color 0.2s;
}
.hdr-util:hover { color: var(--ink); background: rgba(255, 255, 255, 0.08); }
/* Client login sits on the island's dark glass with a hairline, so over the stars it reads as a
   solid control, not a see-through one (review 8) */
.hdr-acts .btn-ghost {
  background: var(--glass);
  -webkit-backdrop-filter: blur(20px) saturate(1.5);
  backdrop-filter: blur(20px) saturate(1.5);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.14), 0 2px 8px rgba(0, 0, 0, 0.4);
}
.hdr-acts .btn-ghost:hover { background: rgba(40, 40, 44, 0.9); }
.hdr-util .icon { width: 15px; height: 15px; }
@media (max-width: 1279px) {
  .hdr-util > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .hdr-util { width: 32px; padding: 0; justify-content: center; }
}

/* a panel: intro column (title, line, overview, featured card), the groups, the foot line */
.isl-panel {
  position: absolute;
  top: var(--row);
  right: 0;
  z-index: 1;
  box-sizing: border-box;
  width: var(--isl-pw, calc(100vw - 2 * var(--hdr-x) - 2px));
  height: var(--isl-ph, auto);
  display: flex;
  flex-direction: column;
  visibility: hidden;
  opacity: 0;
  transform: translate(var(--isl-dx, 0px), -4px);
  filter: blur(4px);
  pointer-events: none;
  transition: opacity 0.14s, transform 0.22s var(--settle), filter 0.14s, visibility 0s linear 0.22s;
}
.island[data-state="open"] .isl-panel[data-active] {
  visibility: visible;
  opacity: 1;
  transform: none;
  filter: blur(0);
  pointer-events: auto;
  transition: opacity 0.26s 0.1s, transform 0.44s 0.06s var(--settle), filter 0.26s 0.1s, visibility 0s;
}
.isl-pscroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-template-rows: auto 1fr;
  column-gap: var(--col-gap);
  padding: 24px calc(var(--hdr-in) - 1px) 10px;
  border-top: 1px solid var(--line);
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}
.isl-pintro { grid-column: 1 / span 3; grid-row: 1; padding-right: 8px; }
.isl-ptitle { font: 500 22px/1.15 var(--font-ui); letter-spacing: -0.025em; color: var(--ink); }
.isl-pline { margin-top: 10px; max-width: 26em; font-size: 14px; line-height: 1.5; color: var(--ink-2); text-wrap: pretty; }
.isl-over {
  display: inline-flex; align-items: center; gap: 7px; margin-top: 16px;
  font: 500 13.5px/1.2 var(--font-ui); color: var(--ink);
  text-decoration: underline; text-decoration-color: rgba(255, 255, 255, 0.3); text-underline-offset: 5px;
  transition: text-decoration-color 0.2s;
}
.isl-over:hover { text-decoration-color: #fff; }
.isl-feat {
  grid-column: 1 / span 3;
  grid-row: 2;
  align-self: end;
  display: block;
  box-sizing: border-box;
  margin: 26px 8px 14px 0;
  padding: 14px 16px 15px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.02));
  transition: border-color 0.2s, background-color 0.2s;
}
.isl-feat:hover { border-color: rgba(255, 255, 255, 0.2); }
.isl-feat-title { display: block; font: 600 14px/1.3 var(--font-ui); letter-spacing: -0.01em; color: var(--ink); }
.isl-feat-line { display: block; margin-top: 6px; font-size: 13px; line-height: 1.45; color: var(--ink-2); text-wrap: pretty; }
.isl-feat-line b { font: 500 13px/1 var(--font-mono); color: var(--ink); font-variant-numeric: tabular-nums; }
.isl-feat-cta {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 12px; font: 500 13px/1.2 var(--font-ui); color: var(--ink);
  text-decoration: underline; text-decoration-color: rgba(255, 255, 255, 0.3); text-underline-offset: 5px; transition: text-decoration-color 0.2s;
}
.isl-feat:hover .isl-feat-cta { text-decoration-color: #fff; }
.isl-groups {
  grid-column: 4 / -1;
  grid-row: 1 / span 2;
  display: grid;
  grid-template-columns: repeat(var(--g, 4), minmax(0, 1fr));
  gap: 0 var(--col-gap);
  align-content: start;
  padding-bottom: 12px;
}
.isl-groups[data-groups="2"], .isl-groups[data-groups="single"] { --g: 2; }
.isl-groups[data-groups="3"] { --g: 3; }
.isl-groups[data-groups="2"] ul { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--col-gap); }
.isl-groups[data-groups="single"] > .isl-group { grid-column: 1 / -1; }
.isl-groups[data-groups="single"] ul { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px var(--col-gap); }
.isl-gtitle { margin: 0 0 6px; font: 500 12px/1.3 var(--font-ui); letter-spacing: 0; color: var(--ink-3); }
.isl-link { display: block; margin: 0 -10px; padding: 8px 10px 9px; border-radius: var(--r-ctl); transition: background-color 0.18s; }
.isl-link:hover { background: rgba(255, 255, 255, 0.05); }
.isl-lbl { display: flex; align-items: center; justify-content: space-between; gap: 10px; font: 500 14px/1.3 var(--font-ui); letter-spacing: -0.01em; color: var(--ink); }
.isl-blurb { display: block; margin-top: 3px; font-size: 12.5px; line-height: 1.45; color: var(--ink-3); text-wrap: pretty; transition: color 0.18s; }
.isl-link:hover .isl-blurb { color: var(--ink-2); }
.isl-pfoot {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px 24px;
  margin: 0 calc(var(--hdr-in) - 1px);
  padding: 13px 0 15px;
  border-top: 1px solid var(--line);
}
.isl-pfoot p { font-size: 12.5px; line-height: 1.4; color: var(--ink-3); }
.isl-plegal { display: flex; gap: 18px; }
.isl-plegal a { font-size: 12.5px; color: var(--ink-2); transition: color 0.2s; }
.isl-plegal a:hover { color: var(--ink); }

/* below 1200 px: Menu and Book a call; open, a drawer from the right (a full sheet on phones)
   with every panel as an accordion, then Search, Client login and the legal links */
@media (max-width: 1199px) {
  .isl-menu {
    grid-column: 2; grid-row: 1; display: inline-grid; align-items: center; justify-items: start;
    box-sizing: border-box; height: 32px; padding: 0 12px; border: 0; border-radius: var(--r-ctl);
    background: transparent; color: var(--ink); font: 500 14px/1 var(--font-ui); cursor: pointer;
    transition: background-color 0.2s;
  }
  .isl-menu:hover { background: rgba(255, 255, 255, 0.06); }
  .isl-menu > span { grid-area: 1 / 1; transition: opacity 0.2s, transform 0.3s var(--settle); }
  .isl-menu-b { opacity: 0; transform: translateY(6px); }
  .island[data-state="open"] .isl-menu-a { opacity: 0; transform: translateY(-6px); }
  .island[data-state="open"] .isl-menu-b { opacity: 1; transform: none; }
  html:not(.js) .isl-menu, html:not(.js) .isl-nav { display: none; }   /* without script the footer's map is the menu */

  .isl-nav {
    grid-column: 1 / -1;
    grid-row: 2;
    align-self: stretch;
    display: block;
    contain: inline-size;             /* the closed bar is Menu and Book a call, even before chrome.js has measured it */
    min-height: 0;
    margin: 0 -5px;
    padding: 4px calc(var(--hdr-in) - 1px) 28px;
    overflow-y: auto;
    overscroll-behavior: contain;
    border-top: 1px solid var(--line);
    visibility: hidden;
    opacity: 0;
    transform: translateY(-6px);
    transition: opacity 0.14s, transform 0.2s var(--settle), visibility 0s linear 0.2s;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
  }
  .island[data-state="open"] .isl-nav { visibility: visible; opacity: 1; transform: none; transition: opacity 0.26s 0.1s, transform 0.4s 0.08s var(--settle), visibility 0s; }
  .isl-top { display: block; }
  .isl-li { border-bottom: 1px solid var(--line); }
  .isl-item {
    display: flex; justify-content: space-between; width: 100%; height: 54px; padding: 0 2px;
    border-radius: 0; background: none; color: var(--ink); font-size: 17px; letter-spacing: -0.015em;
  }
  .isl-item:hover, .isl-item[aria-expanded="true"] { background: none; }
  /* a section that opens shows a plus, which becomes a minus while it is open (no chevrons) */
  .isl-item[aria-expanded]::before {
    content: ""; order: 2; flex: none; width: 12px; height: 12px; opacity: 0.7;
    background: linear-gradient(currentColor, currentColor) center / 12px 1.5px no-repeat, linear-gradient(currentColor, currentColor) center / 1.5px 12px no-repeat;
    transition: background-size 0.3s var(--settle), opacity 0.2s;
  }
  .isl-item[aria-expanded="true"]::before { background-size: 12px 1.5px, 1.5px 0; opacity: 1; }
  .isl-panel {
    position: static; display: none; width: auto; height: auto;
    visibility: visible; opacity: 1; transform: none; filter: none; pointer-events: auto; transition: none;
  }
  .isl-item[aria-expanded="true"] + .isl-panel { display: block; animation: acc-in 0.34s var(--out); }
  .isl-item[data-current]::after, .isl-item[aria-current="page"]::after { left: 2px; right: auto; bottom: 12px; width: 16px; }
  .isl-pscroll { display: block; overflow: visible; padding: 0 0 20px; border: 0; }
  .isl-pintro { padding: 0; }
  .isl-ptitle { display: none; }
  .isl-pline { margin-top: 0; }
  .isl-over { margin-top: 10px; }
  .isl-groups { display: block; margin-top: 12px; padding: 0; }
  .isl-groups ul, .isl-groups[data-groups] ul { display: block; }
  .isl-group { margin-top: 12px; }
  .isl-link { margin: 0; padding: 9px 0 10px; border-radius: 0; }
  .isl-link:hover { background: none; }
  .isl-lbl { justify-content: flex-start; font-size: 15.5px; }
  .isl-blurb { font-size: 13px; }
  .isl-feat { margin: 14px 0 0; }
  .isl-pfoot { display: none; }
  .isl-utils { display: block; margin-top: 16px; }
  .isl-utils::before { display: none; }
  .isl-util { display: flex; width: 100%; height: 50px; padding: 0 2px; gap: 12px; border-radius: 0; border-bottom: 1px solid var(--line); color: var(--ink); font-size: 16px; }
  .isl-util:hover { background: none; }
  .isl-util .icon { width: 17px; height: 17px; color: var(--ink-2); }
  .isl-login { display: flex; width: 100%; height: 46px; margin: 20px 0 0; border-radius: var(--r-btn); font-size: 15px; }
  .isl-legal { display: flex; flex-wrap: wrap; gap: 6px 20px; margin-top: 22px; }
  .isl-legal a { font-size: 13px; color: var(--ink-2); }
}
@media (max-width: 599px) {
  .isl-book { padding: 0 11px; }
}
@keyframes acc-in { from { opacity: 0; transform: translateY(-6px); } }

/* ── Search: one panel for pages and answers, both from this site's own files ───────────────────── */
.find {
  position: fixed;
  inset: 0;
  box-sizing: border-box;
  width: min(680px, calc(100vw - 32px));
  max-width: none;
  height: fit-content;
  max-height: min(640px, 76dvh);
  margin: 12vh auto auto;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 14px;
  background: rgba(15, 15, 18, 0.92);
  -webkit-backdrop-filter: blur(28px) saturate(1.4);
  backdrop-filter: blur(28px) saturate(1.4);
  color: var(--ink);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 24px 80px rgba(0, 0, 0, 0.6);
  overflow: hidden;
  font-family: var(--font-ui);
}
.find[open] { display: flex; flex-direction: column; animation: find-in 0.24s var(--out); }
.find::backdrop { background: rgba(0, 0, 0, 0.52); }
@keyframes find-in { from { opacity: 0; transform: translateY(-8px) scale(0.985); } }
/* the field and Esc in one row */
.find-top { display: flex; align-items: center; gap: 10px; padding: 12px 12px 0; }
.find-x {
  flex: none; height: 26px; padding: 0 8px; border: 1px solid rgba(255, 255, 255, 0.14); border-radius: 6px;
  background: none; color: var(--ink-2); font: 500 11.5px/1 var(--font-mono); cursor: pointer; transition: color 0.2s, border-color 0.2s;
}
.find-x:hover { color: var(--ink); border-color: rgba(255, 255, 255, 0.3); }
.find-x-tap { display: none; }
@media (hover: none), (max-width: 719px) {
  .find-x { height: 34px; padding: 0 12px; font: 500 13px/1 var(--font-ui); }
  .find-x-esc { display: none; }
  .find-x-tap { display: inline; }
}
.find-field { position: relative; flex: 1 1 auto; min-width: 0; display: flex; align-items: center; margin: 0; }
.find-field > .icon { position: absolute; left: 15px; width: 17px; height: 17px; color: var(--ink-3); pointer-events: none; }
.find-input {
  box-sizing: border-box; width: 100%; height: 50px; margin: 0; padding: 0 14px 0 43px;
  border: 1px solid var(--line-2); border-radius: var(--r-btn); background: rgba(255, 255, 255, 0.04);
  color: var(--ink); font: 400 16.5px/1.2 var(--font-ui); letter-spacing: -0.01em; outline: none;
  transition: border-color 0.2s, box-shadow 0.2s;
}
.find-input:focus { border-color: rgba(255, 255, 255, 0.55); box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.08); }
.find-input::placeholder { color: var(--ink-3); opacity: 1; }
.find-input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.find-body {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 8px 8px 10px;
  scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}
.find-cap { padding: 10px 8px 6px; font: 500 12px/1.3 var(--font-ui); color: var(--ink-3); }
.find-hit, .find-ans-src {
  display: block; box-sizing: border-box; padding: 10px 10px 11px; border-radius: var(--r-ctl); transition: background-color 0.15s;
}
.find-opt[aria-selected="true"] > .find-hit { background: rgba(255, 255, 255, 0.075); }
.find-hit-top { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; }
.find-hit-title { font: 500 14.5px/1.3 var(--font-ui); letter-spacing: -0.01em; color: var(--ink); }
.find-hit-path { flex: none; font: 400 11.5px/1 var(--font-mono); color: var(--ink-3); white-space: nowrap; }
.find-hit-text {
  display: -webkit-box; margin-top: 4px; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  font-size: 13px; line-height: 1.5; color: var(--ink-2);
}
.find mark { padding: 0 1px; border-radius: 2px; background: rgba(255, 255, 255, 0.15); color: var(--ink); }
/* the direct answer to a question: one card above the pages, quoted from an FAQ with its page */
.find-opt--ans { margin: 4px 0 6px; }
.find-ans { padding: 14px 14px 10px; border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 10px; background: rgba(255, 255, 255, 0.035); transition: border-color 0.15s, background-color 0.15s; }
.find-opt--ans[aria-selected="true"] > .find-ans { border-color: rgba(255, 255, 255, 0.24); background: rgba(255, 255, 255, 0.06); }
.find-ans-k { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; font: 500 11px/1 var(--font-mono); letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); }
.find-ans-k::before { content: ""; width: 6px; height: 6px; border-radius: 1.5px; background: var(--ink); }
.find-ans-q { font: 500 15px/1.35 var(--font-ui); letter-spacing: -0.01em; color: var(--ink); }
.find-ans-a { margin: 8px 0 0; padding-left: 13px; border-left: 1px solid rgba(255, 255, 255, 0.24); font-size: 13.5px; line-height: 1.6; color: var(--ink-2); }
.find-ans-a a { color: var(--ink); text-decoration: underline; text-decoration-color: rgba(255, 255, 255, 0.3); text-underline-offset: 3px; }
.find-ans-src { display: inline-flex; align-items: center; gap: 6px; margin: 8px 0 0 -10px; padding: 7px 10px; font: 500 12.5px/1.2 var(--font-ui); color: var(--ink); }
.find-ans-src:hover { background: rgba(255, 255, 255, 0.07); }
.find-ans-src { text-decoration: underline; text-decoration-color: rgba(255, 255, 255, 0.3); text-underline-offset: 4px; }
.find-opt--ans[aria-selected="true"] .find-ans-src, .find-ans-src:hover { text-decoration-color: #fff; }
.find-q { display: flex; align-items: center; gap: 10px; width: 100%; box-sizing: border-box; padding: 9px 10px; border: 0; border-radius: var(--r-ctl); background: none; color: var(--ink-2); font: 400 14px/1.4 var(--font-ui); text-align: left; cursor: pointer; }
.find-q .icon { width: 14px; height: 14px; color: var(--ink-3); }
.find-q:hover, .find-opt[aria-selected="true"] > .find-q { background: rgba(255, 255, 255, 0.07); color: var(--ink); }
.find-empty { padding: 14px 10px 10px; font-size: 14px; line-height: 1.55; color: var(--ink-2); }
.find-empty--q { padding-top: 8px; font-size: 13px; color: var(--ink-3); }
.find-empty a, .find-link { color: var(--ink); text-decoration: underline; text-decoration-color: rgba(255, 255, 255, 0.3); text-underline-offset: 3px; }
.find-link { padding: 0; border: 0; background: none; font: inherit; cursor: pointer; }
.find-empty a:hover, .find-link:hover { text-decoration-color: #fff; }
.find-body [data-find-list][hidden] { display: none; }
.find-hit, .find-q { scroll-margin: 8px; }
.find-ans-a p { margin: 0; }
.find-foot p { margin: 0; }
.find-keys span { display: inline-flex; align-items: center; }
.find-sk { height: 50px; margin: 4px 0; border-radius: var(--r-ctl); background: linear-gradient(90deg, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0.03)); background-size: 200% 100%; animation: find-sk 1.2s linear infinite; }
@keyframes find-sk { to { background-position: -200% 0; } }
.find-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 8px 16px; flex-wrap: wrap;
  padding: 10px 14px 11px; border-top: 1px solid var(--line); font-size: 12px; line-height: 1.4; color: var(--ink-3);
}
.find-keys { display: flex; gap: 14px; }
.find kbd {
  display: inline-grid; place-items: center; box-sizing: border-box; min-width: 18px; height: 18px; margin-right: 5px; padding: 0 4px;
  border: 1px solid rgba(255, 255, 255, 0.16); border-radius: var(--r-tag); font: 500 10.5px/1 var(--font-mono); color: var(--ink-2);
}
@media (max-width: 719px) {
  .find { width: calc(100vw - 16px); max-height: calc(100dvh - 16px); margin-top: 8px; }
  .find-keys { display: none; }
  /* the path goes under the title, so the title keeps the full width and a long path is cut */
  .find-hit-top { flex-direction: column; align-items: flex-start; gap: 3px; }
  .find-hit-path { max-width: 100%; overflow: hidden; text-overflow: ellipsis; font-size: 11px; }
}

/* ── shared components: text links, link cards, step lists, the contact form ────────────────── */
/* text links: the one link style on the pages, the words and their underline (no arrows anywhere,
   changed by the operator on 2026-09-25) */
.more {
  display: inline-flex; align-items: center; gap: 8px;
  font: 500 var(--fs-small)/1.2 var(--font-ui); color: var(--ink);
  text-decoration: underline; text-decoration-color: rgba(255, 255, 255, 0.3); text-underline-offset: 5px;
  transition: text-decoration-color 0.2s, color 0.2s;
}
.more:hover { text-decoration-color: #fff; }

/* cards (14 px): a whole card is one link */
.card {
  display: block; box-sizing: border-box; padding: 14px 16px 15px;
  border: 1px solid rgba(255, 255, 255, 0.07); border-radius: var(--r-card); background: var(--fill);
  transition: background-color 0.2s, border-color 0.2s, transform 0.2s var(--settle);
}
.card:hover { background: var(--fill-2); border-color: rgba(255, 255, 255, 0.14); }
.card:active { transform: scale(0.99); }
.card-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.card-title { font-size: 15px; font-weight: 600; letter-spacing: -0.012em; }
.card-text { display: block; margin-top: 4px; font-size: 13.5px; line-height: 1.45; color: var(--ink-2); }
.card-title { text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 4px; transition: text-decoration-color 0.2s; }
a.card:hover .card-title { text-decoration-color: rgba(255, 255, 255, 0.5); }

/* step lists: the generated pages' .steps build on these (page.css) */
.steps { position: relative; display: grid; gap: 14px; padding-left: 22px; }
.steps::before {
  content: ""; position: absolute; left: 3px; top: 8px; bottom: 8px; width: 1px;
  background: linear-gradient(to bottom, rgba(255, 255, 255, 0.55), rgba(255, 255, 255, 0.12));
}
.steps li { position: relative; display: grid; grid-template-columns: 7.5em minmax(0, 1fr); gap: 2px 16px; align-items: baseline; }
.steps li::before {
  content: ""; position: absolute; left: -22px; top: 0.5em; width: 7px; height: 7px; border-radius: 1.5px; box-sizing: border-box;
  background: var(--bg); border: 1px solid rgba(255, 255, 255, 0.7);
}
.steps li:first-child::before { background: var(--ink); border-color: var(--ink); }
.step-name { font-size: 16px; font-weight: 500; letter-spacing: -0.012em; }
.step-text { font-size: 14px; line-height: 1.45; color: var(--ink-2); }

/* the contact form: one form on the home, on /contact and in the message window (site.js). The
   problem first, then the work email and the name, then Send with its note, which keeps to the foot
   of a form taller than its fields (the home's card, beside the column at its left) */
.cform { --cf-gap: 22px; display: grid; grid-template-rows: auto auto 1fr; gap: var(--cf-gap); }
.cform[hidden] { display: none; }   /* sent: only the confirmation stays (grid would outrank [hidden]) */
.cf-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 22px 14px; }
.cf-field { position: relative; display: grid; gap: 7px; min-width: 0; }
.cf-field label { font: 500 var(--fs-meta)/1.25 var(--font-ui); color: var(--ink-2); }
.cf-opt { color: var(--ink-3); font-weight: 400; }
.cf-field input, .cf-field textarea {
  box-sizing: border-box; width: 100%; margin: 0; padding: 0 14px; height: 46px;
  border: 1px solid var(--line-2); border-radius: var(--r-field); background: rgba(255, 255, 255, 0.04);
  color: var(--ink); font: 400 15px/1.4 var(--font-ui); letter-spacing: -0.005em;
  transition: border-color 0.2s, background-color 0.2s, box-shadow 0.2s;
}
.cf-field textarea { height: 112px; padding: 12px 14px; resize: none; display: block; }
.cf-field :is(input, textarea)::placeholder { color: var(--ink-3); opacity: 1; }
.cf-field :is(input, textarea):hover { border-color: rgba(255, 255, 255, 0.26); }
.cf-field :is(input, textarea):focus { outline: none; border-color: rgba(255, 255, 255, 0.8); background: rgba(255, 255, 255, 0.06); box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.1); }
.cf-field [aria-invalid="true"] { border-color: var(--alert); }
.cf-err {
  position: absolute; left: 2px; right: 0; top: 100%; margin-top: 4px;
  font-size: var(--fs-xs); line-height: 1.2; color: var(--alert);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cf-actions { align-self: end; display: flex; align-items: center; gap: 14px 18px; flex-wrap: wrap; }
.cf-note { flex: 1 1 16em; font-size: var(--fs-xs); line-height: 1.5; color: var(--ink-3); }
.cf-note a, .cf-done a, .cf-noscript a { color: var(--ink-2); text-decoration: underline; text-decoration-color: rgba(255, 255, 255, 0.3); text-underline-offset: 3px; }
.cf-note a:hover, .cf-done a:hover { color: var(--ink); }
.cf-status { flex: 1 1 16em; font-size: 13px; line-height: 1.4; color: var(--ink); }
.cf-status:empty { display: none; }
.cf-actions:has(.cf-status:not(:empty)) .cf-note { display: none; }   /* the answer takes the note's place */
.cf-status[data-kind="error"] { color: var(--alert); }
.cf-hp { position: absolute !important; left: -9999px !important; width: 1px; height: 1px; overflow: hidden; }
.cf-done {
  padding: 26px 24px; border: 1px solid rgba(255, 255, 255, 0.1); border-radius: var(--r-card); background: var(--fill);
  outline: none;
}
.cf-done h3 { font-size: 22px; font-weight: 500; letter-spacing: -0.02em; }
.cf-done p { margin-top: 10px; font-size: var(--fs-small); line-height: 1.55; color: var(--ink-2); }
.cf-noscript { font-size: var(--fs-small); color: var(--ink-2); margin-bottom: 16px; }
/* the message window (site.js): every "Contact" opens it on the page it is on, with the home's form
   (the problem and Send first; typing opens the work email and the name). The Search panel's
   glass; a sheet from the bottom on phones. The page behind does not scroll while it is open. */
html.cdlg-open { overflow: hidden; }
.cdlg {
  position: fixed;
  inset: 0;
  box-sizing: border-box;
  width: min(560px, calc(100vw - 32px));
  max-width: none;
  height: fit-content;
  max-height: min(720px, calc(100dvh - 32px));
  margin: auto;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 14px;
  background: rgba(15, 15, 18, 0.94);
  -webkit-backdrop-filter: blur(28px) saturate(1.4);
  backdrop-filter: blur(28px) saturate(1.4);
  color: var(--ink);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 24px 80px rgba(0, 0, 0, 0.6);
  overflow: hidden;
  font-family: var(--font-ui);
}
.cdlg[open] { display: flex; flex-direction: column; animation: find-in 0.24s var(--out); }
.cdlg::backdrop { background: rgba(0, 0, 0, 0.56); }
.cdlg-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 18px 18px 0 24px; }
.cdlg-h { font: 500 20px/1.25 var(--font-ui); letter-spacing: -0.02em; color: var(--ink); }
.cdlg-x {
  flex: none; height: 34px; padding: 0 12px; border: 1px solid rgba(255, 255, 255, 0.14); border-radius: 6px;
  background: none; color: var(--ink-2); font: 500 13px/1 var(--font-ui); cursor: pointer; transition: color 0.2s, border-color 0.2s;
}
.cdlg-x:hover { color: var(--ink); border-color: rgba(255, 255, 255, 0.3); }
.cdlg-x:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.cdlg-body { min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 18px 24px 24px; }
.cdlg .cf-done { padding: 6px 0 4px; border: 0; background: none; }
@media (max-width: 559px) {
  .cform .cf-row { grid-template-columns: 1fr; }
}
@media (max-width: 719px) {
  .cdlg { width: 100vw; max-height: calc(100dvh - 24px); margin: auto 0 0; border-width: 1px 0 0; border-radius: 14px 14px 0 0; padding-bottom: env(safe-area-inset-bottom); }
  .cdlg[open] { animation: cdlg-up 0.32s var(--out); }
  .cdlg-top { padding: 14px 14px 0 18px; }
  .cdlg-body { padding: 16px 18px 20px; }
}
@keyframes cdlg-up { from { opacity: 0; transform: translateY(28px); } }
@media (prefers-reduced-motion: reduce) { .cdlg[open] { animation: none; } }
/* the home's form and the window's ask one question first (site.js, data-step "ask"), with Send and
   its note already there: the email and the name open smoothly as soon as the first character is
   typed ("open"), and stay open. They wait in a clip of no height, each row carrying its own gap
   above it, so a closed row adds nothing; the clip keeps 4 px of room at its sides and foot, so a
   focused field's ring is never cut. Without script, and on /contact, every field shows. */
.cf-field--lead label { font: 500 15px/1.3 var(--font-ui); letter-spacing: -0.01em; color: var(--ink); }
.cf-field--lead textarea { height: 108px; font-size: 16px; line-height: 1.5; }
.cf-more { display: grid; grid-template-rows: 1fr; min-width: 0; }
.cf-more-in { min-width: 0; min-height: 0; }
.cform[data-step] { row-gap: 0; }
.cform[data-step] :is(.cf-row, .cf-actions) { margin-top: var(--cf-gap); }
.cform[data-step] .cf-more { transition: grid-template-rows 0.62s var(--settle), opacity 0.45s var(--out) 0.08s; }
.cform[data-step] .cf-more-in { overflow: hidden; margin: 0 -4px -4px; padding: 0 4px 4px; }
.cform[data-step="ask"] .cf-more { grid-template-rows: 0fr; opacity: 0; }
.cform[data-step="open"] .cf-row > * { animation: cf-in 0.7s var(--out) backwards; }
.cform[data-step="open"] .cf-row > :nth-child(2) { animation-delay: 0.07s; }
@keyframes cf-in { from { opacity: 0; translate: 0 10px; } }
@media (prefers-reduced-motion: reduce) {
  .cform[data-step] .cf-more { transition: none; }
  .cform[data-step="open"] .cf-row > * { animation: none; }
}
.spin { width: 13px; height: 13px; box-sizing: border-box; border-radius: 3px; border: 1.5px solid rgba(0, 0, 0, 0.25); border-top-color: #000; animation: spin 0.8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ── the home: an Astra article ─────────────────────────────────────────────────────────────────
   One natively scrolling page. The star field is fixed behind it and runs in the engine's scroll
   mode (field/boot.js): the hero forms the mark; as the title block arrives the field tilts back
   and disperses to rails either side of the text column ([data-astra-column]), dimmed and masked
   behind the text; it re-forms on each cue's picture as that cue crosses the screen, and fades
   out once the last cue has passed. The layout is the reference article's (spec layout.md): text
   in a 676 px column, figures in a 909 px one, 120 px between the article's blocks (80 on
   phones), 64 px between the blocks of a section (48), 24 px from a heading to its first block
   (20). Every rule here is scoped to the home, so none of it reaches the generated pages. */
.home {
  --prose: calc(676px * var(--z));
  --wide: 909px;
  --art-gap: calc(120px * var(--z));
  --blk-gap: calc(64px * var(--z));
  --head-gap: 24px;
  --t-title: calc(clamp(32px, 26.68px + 1.481vw, 48px) * var(--zd));   /* 32 at 375 px to 48 at 1440 px, then up */
  --t-h2: calc(clamp(24px, 22px + 0.556vw, 30px) * var(--zd));
  --t-h3: calc(clamp(16px, 15.3px + 0.19vw, 18px) * var(--z));
  --prose-ink: rgba(245, 245, 242, 0.84);
  --surface: rgba(10, 10, 11, 0.86);               /* cards sit over the dimmed field */
  --rule: rgba(255, 255, 255, 0.2);
  position: relative;
  z-index: 10;
  display: block;
}
@media (max-width: 767px) {
  .home { --art-gap: 80px; --blk-gap: 48px; --head-gap: 20px; }
}
/* the wide column grows with the screen from 1280 px: 909 px there, 1047 at 1440, 1459 at 1920 and
   76% of any wider screen, so the stars keep a rail of 12% on either side */
@media (min-width: 1280px) {
  .home { --wide: min(76vw, max(909px, calc(909px + (100vw - 1280px) * 0.86))); }
}
@media (prefers-reduced-motion: no-preference) {
  html:has(main.home) { scroll-behavior: smooth; }
}
.home [id] { scroll-margin-top: calc(var(--pg-top) + 12px); }

/* the hero: the field forms the mark behind it; its one line of copy fades with the engine's
   copy opacity over the first 200 px of scroll */
.scroll-cue {
  position: absolute;
  z-index: 2;
  left: 50%;
  bottom: max(18px, env(safe-area-inset-bottom));
  transform: translateX(-50%);
  padding: 8px 12px;
  border-radius: var(--r-ctl);
  color: var(--ink-2);
  font: 500 12px/1 var(--font-ui);
  letter-spacing: 0.02em;
  opacity: var(--astra-copy-opacity, 1);
  transition: color 0.2s;
}
.scroll-cue:hover { color: var(--ink); }
.scroll-cue-in { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.scroll-cue-line { position: relative; width: 1px; height: 34px; overflow: hidden; background: rgba(255, 255, 255, 0.16); }
.scroll-cue-line::after {
  content: ""; position: absolute; top: 0; left: 0; width: 1px; height: 12px; background: var(--ink);
  animation: cue-drop 2.2s var(--settle) infinite;
}
@keyframes cue-drop { 0% { transform: translateY(-12px); } 72%, 100% { transform: translateY(34px); } }
html[data-intro] .scroll-cue-in { opacity: 0.01; animation: cue-in 0.9s var(--out) 4.1s forwards; }
@keyframes cue-in { to { opacity: 1; } }

/* the hero lockup. The stars form the X in the middle of the hero, in the square the engine fits the
   glyph into ([data-astra-mark], --xs a side: 76% of the height, never wider than 64% of the width).
   "SolaryxDev" sits on the X's horizontal axis at the left, "Dev" in a cool grey; the X's four arms
   leave a clear cross through its middle and a wide notch opening to the left, so the name can run
   into that notch without meeting an arm: it ends at least 0.26 --xs left of the centre (inside the
   inner corners, where the gap between the arms is twice the name's height) and stays clear of the
   core. The line sits under it, in the notch's lower half, clear of the lower-left arm. The name is
   30% larger than the first lockup (156 px at most, where the notch allows it). Both run from the
   hero's own edge (2.5vw, the header's inset on smaller screens). The line fades with the engine's
   copy opacity over the first 200 px of scroll; the name does not fade: over the first 70% of the
   hero it shrinks and travels into the header's name while the stars carry the X into the header's
   mark (field/page.js, data-astra-dock), so the header lockup is where the hero ends. Narrow or
   portrait screens stack: the name and the line at the top, the X below, as wide as the screen
   allows.
   Changed by the operator on 2026-09-25: the lockup sits 20% higher (its top at 80% of where it
   was: top 40% less 0.4 of the name, instead of 50% less 0.5), so the name now runs above the
   X's axis, under the upper-left arm. That arm's lower edge falls at 45 degrees towards the left,
   so the higher the name sits, the sooner it has to end: the last term of --nf keeps the name's
   right end clear of it (checked on the stars at 1280 to 2560 px). */
.home-hero {
  --hx: max(calc(min(var(--hdr-x), 18px) + var(--hdr-in)), 2.5vw);
  --hw: calc(100vw - 2 * var(--hx));
  --xs: min(76svh, 64vw);
  --hh: var(--astra-viewport-height, 100svh);
  --nf: min(156px, calc((var(--hw) * 0.56 - 16px) / 8.15), calc((50vw - var(--xs) * 0.105 - var(--hx) - 8px) / 7.06), calc(var(--xs) * 0.156),
    calc((50vw - var(--hx) - var(--hh) * 0.1 - var(--xs) * var(--hk, 0.149) - var(--hg, 24px)) / 7.46));
  --lf: clamp(16px, 10px + 0.6vw, 26px);
}
.hero-lock {
  position: absolute;
  z-index: 2;
  left: var(--hx);
  top: 40%;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: calc(var(--nf) * 0.24);
  transform: translateY(calc(var(--nf) * -0.4));      /* 20% higher than the name's line on the X's axis */
  pointer-events: none;
}
/* the engine writes translate and scale on the name while it docks, and --astra-dock (0 to 1) on
   <html>: the tracking eases from the hero's to the header's, so the two names match where they meet */
.hero-name {
  position: relative;
  align-self: flex-start;
  transform-origin: 0 0;
  font-family: var(--font-name);
  font-weight: 900;
  font-size: var(--nf);                /* the name is 7.05em wide */
  line-height: 1;
  letter-spacing: calc(-0.045em + 0.01em * var(--astra-dock, 0));
  white-space: nowrap;
  color: var(--ink);
  text-shadow: 0 2px 28px rgba(0, 0, 0, 0.6);
}
html[data-astra-docked] .hero-name { visibility: hidden; }
.hero-dev { color: #8f8f99; }          /* 6.5:1 on black */
/* one sweep of light across the name once the X has formed (the same word drawn again on top,
   clipped to the letters; empty for assistive technology) */
.hero-name::after {
  content: "SolaryxDev" / "";
  position: absolute;
  inset: 0;
  color: transparent;
  text-shadow: none;
  background: linear-gradient(100deg, rgba(255, 255, 255, 0) 40%, rgba(255, 255, 255, 0.92) 50%, rgba(255, 255, 255, 0) 60%) 100% 0 / 250% 100% no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  pointer-events: none;
  animation: hero-shine 2.4s var(--settle) 4.3s both;
}
@keyframes hero-shine { from { background-position: 100% 0; } to { background-position: 0 0; } }
.hero-line {
  max-width: min(16.5em, calc(50vw - var(--xs) * 0.475 - var(--hx) - 4px));   /* left of the X */
  font: 400 var(--lf)/1.38 var(--font-ui);
  letter-spacing: -0.014em;
  color: rgba(245, 245, 242, 0.8);
  text-wrap: balance;
  text-shadow: 0 1px 16px rgba(0, 0, 0, 0.85);
  opacity: var(--astra-copy-opacity, 1);
}
.hero-mark {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--xs);
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  pointer-events: none;
}
@media (max-width: 1023px), (max-aspect-ratio: 1/1) {
  .home-hero { --nf: min(calc((var(--hw) - 4px) / 8.15), 12svh); --lf: clamp(16px, 13px + 0.8vw, 22px); }
  .hero-lock { top: calc((var(--pg-top) + 4svh) * 0.8); transform: none; }
  .hero-line { max-width: 16.5em; }
  .hero-mark { top: calc(var(--pg-top) + 4svh + var(--nf) * 1.24 + var(--lf) * 2.76 + 5svh); bottom: 9svh; left: 2vw; right: 2vw; width: auto; aspect-ratio: auto; transform: none; }
}
/* the name arrives while the stars gather (1% opacity, not 0: see the lockup above). The first
   keyframe holds through the delay and the animation leaves nothing behind, so the line's own
   scroll fade and the name's dock apply the moment it ends. With motion.js running, the name is
   split into its letters (.hn-split, 2026-09-25): "Solaryx" rises out of a blur letter by letter
   from 0.9 s, as the stars start to gather (the reference's labels start at 0.85 s), "Dev" follows
   a beat later, then the line; each letter keeps the advance it had in the shaped word, so the
   name's box does not move. Without script the whole word arrives at once, as before. */
html[data-intro] :is(.hero-name, .hero-line) { animation: hero-in 1.4s var(--out) 1s backwards; }
html[data-intro] .hero-line { animation-delay: 1.95s; }
@keyframes hero-in { from { opacity: 0.01; transform: translateY(14px); filter: blur(10px); } }
html[data-intro] .hero-name.hn-split { animation: none; }
.hn-w, .hn-ch { display: inline-block; }
.hero-name.hn-split .hn-ch { animation: hn-in 1.25s var(--out) var(--d, 0ms) backwards; }
@keyframes hn-in {
  from { opacity: 0.01; transform: translate3d(0, 0.34em, 0) scale(0.96); filter: blur(0.16em); }
  45% { filter: blur(0.02em); }
}
@media (prefers-reduced-motion: reduce) {
  html[data-intro] :is(.hero-name, .hero-line) { animation: none; }
  .hero-name.hn-split .hn-ch { animation: none; }
  .hero-name::after { animation: none; opacity: 0; }
}
/* on the home the header's lockup is the hero's end state: it shows once the stars have carried
   the X to its place, the X fading in over them as they hand over (--astra-dock 0.86 to 1), and the
   name takes over from the hero's where the two meet (data-astra-docked). The line stays with the
   hero. Until the stars have left the mark for the rails the band behind the header stays away, so
   nothing covers the mark while it lands. */
html[data-intro]:has(main.home) .brand > * { opacity: 1; transform: none; filter: none; animation: none; }
html:has(main.home):not([data-astra-landing]) .brand { visibility: hidden; }
html:has(main.home) .brand .brand-mark { opacity: clamp(0, (var(--astra-dock, 1) - 0.86) / 0.14, 1); }
html:has(main.home):not([data-astra-docked]) .brand-name { visibility: hidden; }
html:has(main.home) .brand-line { visibility: hidden; }
html:has(main.home):not([data-astra-released]) body::before { opacity: 0; }

/* the section index: a rail at the left on wide screens, its entries the article's sections
   (home.js builds it), shown once the hero has gone and until the footer arrives, wherever the text
   beside it leaves it room; the section in view is marked. Its rail starts on the header lockup's
   left edge; home.js moves it left where the text comes closer. It is as wide as its labels, and a
   label wraps past 8.25em, so from 1280 to 2560 px it keeps that edge with 24 px to the text; a box
   narrower than its labels hid them under the backing's mask and left the rail alone across the
   text (review n14). It sits on a soft dark backing (the stars behind it blurred and dimmed, the
   edge feathered), so it reads over the side stars (review 8: 1.0-3.9:1 without it) */
.art-index { display: none; }
@media (min-width: 1280px) {
  .art-index {
    display: block;
    position: fixed;
    z-index: 60;
    left: calc(var(--hdr-x) + var(--hdr-in) - var(--nav-pad));
    top: 50%;
    padding: var(--nav-pad);
    transform: translateY(-50%);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.3s var(--settle), visibility 0s linear 0.3s;
  }
  html[data-index-on] .art-index { opacity: 1; visibility: visible; transition: opacity 0.3s var(--settle); }
}
.art-index ol { border-left: 1px solid var(--line-2); }
.art-index a {
  display: block;
  margin-left: -1px;
  padding: 5px 0 5px 14px;
  border-left: 1px solid transparent;
  max-width: 8.25em;
  font: 400 13px/1.4 var(--font-ui);
  color: var(--ink-2);
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.9);
  text-wrap: balance;
  transition: color 0.18s, border-color 0.18s;
}
.art-index a:hover { color: var(--ink); }
.art-index a[aria-current="true"] { color: var(--ink); border-left-color: var(--ink); }
.art-index a:focus-visible { outline-offset: -2px; border-radius: 4px; }
/* the backing of the home's section index and a content page's "On this page" (page.css): dark
   glass whose edge fades out over the padding, so it reads as shade, not as a card */
@media (min-width: 1280px) {
  .art-index, .cp-toc {
    background: rgba(3, 4, 6, 0.66);
    -webkit-backdrop-filter: blur(16px);
    backdrop-filter: blur(16px);
    border-radius: var(--r-card);
    -webkit-mask: linear-gradient(90deg, transparent, #000 var(--nav-pad), #000 calc(100% - var(--nav-pad)), transparent),
      linear-gradient(transparent, #000 var(--nav-pad), #000 calc(100% - var(--nav-pad)), transparent);
    -webkit-mask-composite: source-in;
    mask: linear-gradient(90deg, transparent, #000 var(--nav-pad), #000 calc(100% - var(--nav-pad)), transparent),
      linear-gradient(transparent, #000 var(--nav-pad), #000 calc(100% - var(--nav-pad)), transparent);
    mask-composite: intersect;
  }
}
@media (min-width: 1280px) and (prefers-reduced-transparency: reduce) {
  .art-index, .cp-toc { background: #060708; -webkit-backdrop-filter: none; backdrop-filter: none; }
}

/* the article: blocks in one column; each takes the text width unless it is a figure (.w) */
.art {
  box-sizing: border-box;
  max-width: calc(var(--grid) + 2 * var(--gutter));
  margin: 0 auto;
  padding: var(--art-gap) var(--gutter) 48px;
  display: flex;
  flex-direction: column;
  gap: var(--art-gap);
}
.art > :not([data-astra-cue]), .art .sec > * { box-sizing: border-box; width: 100%; max-width: var(--prose); margin-inline: auto; }
.art > .sec { max-width: none; }
.art > .art-lead, .art .w { max-width: var(--wide); }
.art .sec { display: flex; flex-direction: column; gap: var(--blk-gap); }
.art .sec > .sec-head + * { margin-top: calc(var(--head-gap) - var(--blk-gap)); }
.art [data-astra-column] { --grid-gap: var(--col-gap); }   /* the rails keep this far from the column */

/* a cue: the frame the stars form the picture in (field.css sizes it); its outline shows only where
   the stars cannot draw it, one screen pixel wide at any size */
.art-cue > svg path { vector-effect: non-scaling-stroke; }
/* without script there is no engine: the still of the mark stays with the hero, and each cue shows
   its outline, as it does on the still poster */
html:not(.js):has(main.home) .astra-backdrop { position: absolute; height: 100svh; }
html:not(.js) .art-cue > svg { color: #fafafa4d; opacity: 1; }

/* scenes: the stars take a form of their own for a section (field/boot.js, data-astra-scene). The
   engine writes --astra-scene (0 to 1) on each as it forms and lets go. */
/* the system: while the practice passes, the stars gather to the right of its words into a star
   with its planets' orbits, turning as a real one does (field/shaders.js systemAt), and the words
   move to the left of it (wide screens: from 1200 px, where it still has a third of the width; below
   that the section stays centred and the stars stay on the rails) */
.art .sec--river { position: relative; --river-w: max(760px, calc(var(--wide) * 0.6)); }   /* the words' width, beside the river */
.art .sec > .art-river { display: none; }
@media (min-width: 1200px) {
  .art .sec--river > :not(.art-river) { margin-inline: calc(50% - var(--wide) / 2) auto; }
  .art .sec--river > .w { max-width: var(--river-w); }
  .art .sec > .art-river {
    display: block;
    position: absolute;
    top: 0;
    bottom: 0;
    left: calc(50% - var(--wide) / 2 + var(--river-w) + 44px);
    right: calc(50% - 50vw);
    width: auto;
    max-width: none;
    margin: 0;
    pointer-events: none;
  }
}
/* the horizon: a line of light under the One record heading, and under it, barely there, the upper
   limb of a planet. page.js writes the radius the stars bow their line to (--astra-limb), so the limb
   meets the line along its length: a dark body just lighter than the sky, a thin rim of atmosphere
   with a soft glow above it, and a few warm city lights inside the edge. It comes and goes with the
   scene (--astra-scene), fades out toward the sides and downward, and sits behind the words. */
.art .sec > .art-horizon {
  --limb: var(--astra-limb, 5560px);
  --limb-k: var(--astra-limb-k, 9e-5);
  position: relative;
  z-index: -1;
  max-width: var(--wide);
  height: clamp(104px, 13vh, 136px);           /* the line, its glow and its bow, clear of the words */
  margin-bottom: calc(var(--blk-gap) * -0.5);
  pointer-events: none;
}
.art .sec > .art-horizon::before {
  content: "";
  position: absolute;
  left: calc(50% - 50vw);
  width: 100vw;
  top: calc(50% - 40px);
  height: min(56vh, 480px);
  background:
    radial-gradient(2.3px circle at calc(50% + -352px) calc(62px + 123904px * var(--limb-k)), rgba(255, 206, 142, 0.55), rgba(255, 206, 142, 0)),
    radial-gradient(1.6px circle at calc(50% + -338px) calc(66px + 114244px * var(--limb-k)), rgba(255, 206, 142, 0.4), rgba(255, 206, 142, 0)),
    radial-gradient(2.0px circle at calc(50% + -214px) calc(88px + 45796px * var(--limb-k)), rgba(255, 206, 142, 0.45), rgba(255, 206, 142, 0)),
    radial-gradient(2.5px circle at calc(50% + -96px) calc(59px + 9216px * var(--limb-k)), rgba(255, 206, 142, 0.6), rgba(255, 206, 142, 0)),
    radial-gradient(1.6px circle at calc(50% + -84px) calc(64px + 7056px * var(--limb-k)), rgba(255, 206, 142, 0.4), rgba(255, 206, 142, 0)),
    radial-gradient(1.8px circle at calc(50% + -71px) calc(61px + 5041px * var(--limb-k)), rgba(255, 206, 142, 0.45), rgba(255, 206, 142, 0)),
    radial-gradient(2.2px circle at calc(50% + 58px) calc(76px + 3364px * var(--limb-k)), rgba(255, 206, 142, 0.5), rgba(255, 206, 142, 0)),
    radial-gradient(2.3px circle at calc(50% + 176px) calc(57px + 30976px * var(--limb-k)), rgba(255, 206, 142, 0.55), rgba(255, 206, 142, 0)),
    radial-gradient(1.6px circle at calc(50% + 189px) calc(62px + 35721px * var(--limb-k)), rgba(255, 206, 142, 0.35), rgba(255, 206, 142, 0)),
    radial-gradient(1.8px circle at calc(50% + 298px) calc(84px + 88804px * var(--limb-k)), rgba(255, 206, 142, 0.4), rgba(255, 206, 142, 0)),
    radial-gradient(2.2px circle at calc(50% + 412px) calc(68px + 169744px * var(--limb-k)), rgba(255, 206, 142, 0.45), rgba(255, 206, 142, 0)),
    radial-gradient(circle var(--limb) at 50% calc(var(--limb) + 40px),
      rgba(6, 9, 14, 0.94) calc(var(--limb) - 120px),
      rgba(10, 18, 31, 0.86) calc(var(--limb) - 30px),
      rgba(44, 82, 138, 0.5) calc(var(--limb) - 4px),
      rgba(150, 192, 255, 0.5) calc(var(--limb) - 0.5px),
      rgba(110, 160, 235, 0.16) calc(var(--limb) + 5px),
      rgba(90, 140, 220, 0.06) calc(var(--limb) + 18px),
      rgba(90, 140, 220, 0) calc(var(--limb) + 36px));
  -webkit-mask-image: linear-gradient(to right, transparent 4%, #000 30%, #000 70%, transparent 96%), linear-gradient(#000 12%, rgba(0, 0, 0, 0.55) 45%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(to right, transparent 4%, #000 30%, #000 70%, transparent 96%), linear-gradient(#000 12%, rgba(0, 0, 0, 0.55) 45%, transparent 100%);
  mask-composite: intersect;
  opacity: calc(var(--astra-scene, 0) * 0.92);
}
@media (max-width: 767px) {
  .art .sec > .art-horizon::before { height: min(40vh, 300px); }
}
/* the stack: the names from the paragraph above it, running past in one line, faded at both ends;
   it pauses under the cursor, and stands still (wrapping) with reduced motion. A plain label above
   it says what the names are (tools we build with) and that none of them is a partner, so the row
   never reads as a wall of partner logos (review 17) */
.art .marq-k { margin: 0 auto calc(12px - var(--blk-gap)); font: 500 12.5px/1.5 var(--font-mono, var(--font-ui)); letter-spacing: 0.02em; color: var(--ink-3); text-wrap: pretty; }
.art .marq {
  display: flex;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 9%, #000 91%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 9%, #000 91%, transparent);
}
.art .marq-list {
  display: flex;
  flex: none;
  align-items: center;
  gap: 44px;
  padding: 6px 44px 6px 0;
  animation: marq 38s linear infinite;
}
.art .marq:hover .marq-list { animation-play-state: paused; }
.art .marq-list li {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  font: 500 15px/1.4 var(--font-ui);
  letter-spacing: -0.01em;
  white-space: nowrap;
  color: var(--ink-2);
}
.art .marq-list li::before { content: ""; width: 5px; height: 5px; border-radius: 1px; background: rgba(245, 245, 242, 0.45); }
@keyframes marq { to { transform: translateX(-100%); } }
@media (prefers-reduced-motion: reduce) {
  .art .marq { -webkit-mask-image: none; mask-image: none; }
  .art .marq-list { flex-wrap: wrap; flex: 1 1 auto; row-gap: 10px; padding-right: 0; animation: none; }
  .art .marq-list[aria-hidden="true"] { display: none; }
}

/* the fly-through: the white section (field/boot.js [data-astra-flythrough]). Above it the stars rush
   at the viewer and the camera homes in on one star whose core fills the view: that light is this
   ground. Below it the light ebbs back into the middle of the view and the stars return to the
   rails. That light is the section's white ground, full width, one colour from the runway above to
   the runway below, so its words read in dark ink on white at any scroll position, and the runways
   either side hold no text while the light changes. Its own paper is only for when no light is drawn.
   Three parts, one after the other, each opened by a numbered kicker and a large close-set heading
   with its lead beside it on wide screens: Solutions (the menu's four groups, numbered, on
   hairlines), By industry (two columns of rows) and Intelligence (seven charts from published data,
   js/charts.js). One accent, a deep steel blue, used only for marks. On the white, a soft light that
   follows the cursor (motion.js writes --sx, --sy); the stars seen on white are the field's own
   (field/ink.js). Every colour holds 4.5:1 on the paper (the light's own colour) or better. */
.art > .sec--white {
  --ink: #0b0b0c;
  --ink-2: #3a3a3e;                   /* 10.9:1 on the paper */
  --ink-3: #5f5f66;                   /* 6.1:1 */
  --prose-ink: #2b2b2f;
  --line-2: rgba(11, 11, 12, 0.14);
  --rule: rgba(11, 11, 12, 0.13);
  --surface: #ffffff;
  --paper: #f7f7f4;
  --accent: #2c5a86;                  /* 6.6:1 */
  --wh-max: 1180px;
  /* one gutter for every part of the page: the heads, Solutions, By industry and the charts share
     their column lines (four columns of the Solutions list, two of everything else) */
  --wh-gap: clamp(24px, 2.5vw, 48px);
  position: relative;
  isolation: isolate;
  /* the same runway above and below (field/page.js, the fly-through): above, the rush and the star
     that fills the view just before this block's first line comes up; below, the exact reverse, run
     in the open once its last line has left the top, while the next section comes up under it
     (operator 2026-09-25, 09:00: "do exactly the reverse when the white part finishes"; it replaces
     the shorter runway below, which ran the way out behind the paper) */
  margin-block: calc(50lvh + clamp(460px, 62lvh, 600px) - var(--art-gap));
  /* a short breath of paper above "01 Solutions" (operator 2026-09-25, 09:00: "this gap before the
     white space opens should be less"; it was 15svh): the light fills the view just before the
     first line comes up (the engine times it on the content, not on this padding) */
  padding-block: clamp(40px, 6svh, 72px) clamp(56px, 8svh, 96px);
  padding-inline: max(0px, calc((100% - var(--wh-max)) / 2));
  gap: clamp(112px, 17svh, 200px);
  color: var(--ink);
}
.art > .sec--white > .wh { max-width: none; margin-inline: 0; display: flex; flex-direction: column; gap: clamp(40px, 6svh, 64px); }
/* each part's head: the numbered kicker, the heading, and its lead (beside it from 1024 px) */
.art > .sec--white .wh-head { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--wh-gap); row-gap: 22px; align-items: end; }
.art > .sec--white .wh-head > * { grid-column: 1 / -1; }
.art > .sec--white .wh-head > .sec-h { grid-column: 1; }
.art > .sec--white .wh-head > .wh-lead { grid-column: 2; justify-self: start; max-width: 34em; margin-bottom: 6px; }
@media (max-width: 1023px) {
  .art > .sec--white .wh-head > :is(.sec-h, .wh-lead) { grid-column: 1 / -1; justify-self: start; max-width: 640px; }
  .art > .sec--white .wh-head { row-gap: 20px; }
}
.art > .sec--white .kicker { display: inline-flex; align-items: center; gap: 12px; font: 500 13px/1.3 var(--font-mono, var(--font-ui)); letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); }
.art > .sec--white .wh-n { color: var(--accent); }
.art > .sec--white .wh-n::after { content: ""; display: inline-block; width: 22px; height: 1px; margin-left: 12px; vertical-align: middle; background: rgba(11, 11, 12, 0.28); }
.art > .sec--white .sec-h {
  font: 500 clamp(38px, 1.5vw + 30px, 64px)/1.04 var(--font-ui);
  letter-spacing: -0.038em;
  color: var(--ink);
  text-wrap: balance;
}
.art > .sec--white .sec-h-2 { color: #6b6b74; }   /* 4.9:1 */
@media (min-width: 1024px) { .art > .sec--white .sec-h-2 { display: block; } }
.art > .sec--white .wh-lead { font-size: 18px; line-height: 29px; letter-spacing: -0.012em; color: var(--ink-2); text-wrap: pretty; }
.art > .sec--white :is(.sec-h, .kicker, .wh-lead) { text-shadow: none; }
.art > .sec--white .wh-foot { display: flex; flex-wrap: wrap; gap: 12px 28px; }
.art > .sec--white .more { color: var(--ink); text-decoration-color: rgba(11, 11, 12, 0.3); }
.art > .sec--white .more:hover { text-decoration-color: var(--ink); }
.art > .sec--white a:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }
/* the ground where no light is drawn: the paper, a fine grain and a soft light at the cursor (the
   dark stars drifting on it are the field's own: field/ink.js) */
.art > .sec--white::before {
  content: "";
  position: absolute;
  z-index: -2;
  inset: 0 calc(50% - 50vw);
  background:
    radial-gradient(720px circle at var(--sx, 50%) var(--sy, -900px), rgba(44, 90, 134, 0.07), rgba(44, 90, 134, 0) 65%),
    var(--paper);
}
.art > .sec--white::after {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0 calc(50% - 50vw);
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .07 0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23g)'/%3E%3C/svg%3E") 0 0 / 200px 200px;
  /* from nothing at the top edge (the light above it is plain) to nothing at the foot */
  -webkit-mask-image: linear-gradient(transparent, #000 min(12%, 360px), #000 88%, transparent);
  mask-image: linear-gradient(transparent, #000 min(12%, 360px), #000 88%, transparent);
  pointer-events: none;
}
/* over the engine's light (field/page.js marks the block data-astra-lit while it draws it) the block
   drops its own ground: the light is its white, #f7f7f4 as the paper, so no line or band shows where
   the block begins or ends (operator 2026-09-25: "there is this line and a gap before and after we go
   in the white area"). The grain goes with the paper (it read as a darker white than the light); the
   cursor's light stays, faded out toward the block's top and foot so it is never cut there. */
.art > .sec--white[data-astra-lit]::before {
  background: radial-gradient(720px circle at var(--sx, 50%) var(--sy, -900px), rgba(44, 90, 134, 0.07), rgba(44, 90, 134, 0) 65%);
  -webkit-mask-image: linear-gradient(transparent, #000 min(12%, 360px), #000 88%, transparent);
  mask-image: linear-gradient(transparent, #000 min(12%, 360px), #000 88%, transparent);
}
.art > .sec--white[data-astra-lit]::after { display: none; }
html:not(.js) .art > .sec--white { margin-block: 0; }

/* Solutions: the menu's four groups (sx:solutions, from js/menu.js and each solution's own page), a
   column each from 1600 px, two columns of two groups from 720 px. Every solution is a card and a link. At rest: its number, its name and
   its line. Under the cursor and on keyboard focus the card lifts, a light follows the cursor
   (motion.js initCards), the name takes the accent and its underline, and the line gives way to
   what the solution's page says you get. The line and the list share one cell, so nothing below a
   card moves. No arrows anywhere (changed by the operator on 2026-09-25). */
.art > .sec--white .sol-grid { display: grid; max-width: none; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 48px var(--wh-gap); }
/* two columns of two groups each (partials/build.mjs wraps them in .sol-col): the first two groups
   and the last two, 8 and 7 cards, so both columns end level; the shorter column's cards share out
   the difference. Four columns from 1600 px, where each group has its own */
.art > .sec--white .sol-col { display: contents; }
@media (min-width: 720px) and (max-width: 1599px) {
  .art > .sec--white .sol-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .art > .sec--white .sol-col { display: flex; flex-direction: column; gap: 48px; }
  .art > .sec--white .sol-col > .sol-group { display: flex; flex: 1 1 auto; flex-direction: column; }
  .art > .sec--white .sol-col .sol-list { flex: 1 1 auto; grid-auto-rows: 1fr; }
  .art > .sec--white .sol-col .sol-list > li { display: grid; }
  .art > .sec--white .sol-card { align-content: start; }
}
.art > .sec--white .sol-h {
  position: relative;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 16px;
  padding: 16px 0 0;
  border-top: 1px solid var(--rule);
  font: 600 15px/1.3 var(--font-ui);
  letter-spacing: -0.012em;
  color: var(--ink);
}
.art > .sec--white .sol-h::after { content: ""; position: absolute; top: -1px; left: 0; width: 32px; height: 2px; background: var(--accent); }
.art > .sec--white .sol-h-n { flex: none; font: 500 11.5px/1 var(--font-mono); letter-spacing: 0.02em; color: var(--ink-3); }
.art > .sec--white .sol-list { display: grid; gap: 10px; }
.art > .sec--white .sol-card {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "l i" "b b";
  gap: 8px 12px;
  box-sizing: border-box;
  padding: 16px 18px 18px;
  border: 1px solid rgba(11, 11, 12, 0.08);
  border-radius: 12px;
  background: #fff;
  box-shadow: 0 1px 2px rgba(11, 11, 12, 0.04);
  transition: translate 0.4s var(--settle), box-shadow 0.4s var(--settle), border-color 0.25s;
}
.art > .sec--white .sol-i { grid-area: i; padding-top: 3px; font: 500 11px/1.2 var(--font-mono); letter-spacing: 0.02em; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.art > .sec--white .sol-l {
  grid-area: l;
  font: 500 16px/1.32 var(--font-ui);
  letter-spacing: -0.014em;
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: transparent;
  text-underline-offset: 4px;
  transition: color 0.25s, text-decoration-color 0.25s;
}
.art > .sec--white .sol-body { grid-area: b; display: grid; }
.art > .sec--white :is(.sol-b, .sol-get) { grid-area: 1 / 1; }
.art > .sec--white .sol-b { font-size: 14px; line-height: 1.5; color: var(--ink-2); text-wrap: pretty; transition: opacity 0.3s var(--settle), translate 0.45s var(--settle); }
.art > .sec--white .sol-get { display: flex; flex-direction: column; gap: 4px; visibility: hidden; opacity: 0; translate: 0 10px; transition: opacity 0.25s, translate 0.45s var(--settle), visibility 0s linear 0.3s; }
.art > .sec--white .sol-get-k { margin-bottom: 2px; font: 500 10.5px/1.4 var(--font-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--accent); }
.art > .sec--white .sol-get-i { position: relative; padding-left: 14px; font-size: 13.5px; line-height: 1.42; color: var(--ink); text-wrap: pretty; }
.art > .sec--white .sol-get-i::before { content: ""; position: absolute; left: 1px; top: 0.56em; width: 5px; height: 5px; border-radius: 1px; background: var(--accent); }
.art > .sec--white .sol-card:is(:hover, :focus-visible) { translate: 0 -3px; border-color: rgba(44, 90, 134, 0.34); box-shadow: 0 1px 2px rgba(11, 11, 12, 0.04), 0 24px 46px -28px rgba(20, 50, 90, 0.42); }
.art > .sec--white .sol-card:is(:hover, :focus-visible) .sol-l { color: var(--accent); text-decoration-color: rgba(44, 90, 134, 0.5); }
.art > .sec--white .sol-card:is(:hover, :focus-visible) .sol-b { opacity: 0; translate: 0 -10px; }
.art > .sec--white .sol-card:is(:hover, :focus-visible) .sol-get { visibility: visible; opacity: 1; translate: 0 0; transition: opacity 0.35s 0.06s, translate 0.5s var(--settle) 0.04s, visibility 0s; }
.art > .sec--white .sol-card:is(:hover, :focus-visible) .sol-get-i { animation: wh-pop 0.55s var(--out) backwards; }
.art > .sec--white .sol-card:is(:hover, :focus-visible) .sol-get-i:nth-child(3) { animation-delay: 0.06s; }
.art > .sec--white .sol-card:is(:hover, :focus-visible) .sol-get-i:nth-child(4) { animation-delay: 0.12s; }
.art > .sec--white :is(.sol-card, .ind-card):focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
@keyframes wh-pop { from { opacity: 0; translate: 0 6px; } }
@media (max-width: 719px) { .art > .sec--white .sol-grid { grid-template-columns: 1fr; gap: 36px; } }
/* touch screens have no hover to turn a card: the card is its line and its link */
@media (hover: none) { .art > .sec--white .sol-get { display: none; } }

/* By industry (sx:industries, from js/menu.js and each industry's own page): a search over the
   trades, a switch between the two groups and a count, then one card per trade: its name, the
   problem in its page's own words and three things its page says we build. The search matches the
   words of each page's headings, lists, questions and search terms, so a problem finds the trades
   that have it (home.js). The cards that match close up in order and the rest fold away; the list
   keeps its height meanwhile, so nothing below it moves. Without script there is no search, and
   every card shows. */
.art > .sec--white .ind { display: flex; flex-direction: column; gap: 20px; max-width: none; }
.art > .sec--white .ind-bar { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px var(--wh-gap); align-items: center; }
html:not(.js) .art > .sec--white .ind-bar { display: none; }
.art > .sec--white .ind-field { position: relative; }
.art > .sec--white .ind-field > .icon { position: absolute; left: 16px; top: 50%; width: 17px; height: 17px; margin-top: -8.5px; color: var(--ink-3); pointer-events: none; }
.art > .sec--white .ind-q {
  box-sizing: border-box;
  width: 100%;
  height: 52px;
  margin: 0;
  padding: 0 16px 0 44px;
  border: 1px solid rgba(11, 11, 12, 0.14);
  border-radius: var(--r-field);
  background: #fff;
  color: var(--ink);
  caret-color: var(--accent);
  font: 400 16px/1.2 var(--font-ui);
  letter-spacing: -0.01em;
  box-shadow: 0 1px 2px rgba(11, 11, 12, 0.04);
  transition: border-color 0.2s, box-shadow 0.2s;
}
.art > .sec--white .ind-q::placeholder { color: #6e6e76; opacity: 1; }   /* 4.9:1 on white */
.art > .sec--white .ind-q:hover { border-color: rgba(11, 11, 12, 0.26); }
.art > .sec--white .ind-q:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 4px rgba(44, 90, 134, 0.14); }
.art > .sec--white .ind-tools { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 16px; min-width: 0; }
.art > .sec--white .seg { display: inline-flex; flex-wrap: wrap; gap: 2px; padding: 3px; border: 1px solid rgba(11, 11, 12, 0.1); border-radius: 11px; background: rgba(11, 11, 12, 0.035); }
.art > .sec--white .seg > button {
  box-sizing: border-box;
  height: 36px;
  padding: 0 13px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--ink-2);
  font: 500 13px/1 var(--font-ui);
  letter-spacing: -0.005em;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.2s, color 0.2s, box-shadow 0.2s;
}
.art > .sec--white .seg > button:hover { color: var(--ink); }
.art > .sec--white .seg > button[aria-pressed="true"] { background: #fff; color: var(--ink); box-shadow: 0 1px 2px rgba(11, 11, 12, 0.12), 0 0 0 1px rgba(11, 11, 12, 0.06); }
.art > .sec--white .seg > button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.art > .sec--white .ind-n { font: 500 12px/1.3 var(--font-mono); letter-spacing: 0.02em; color: var(--ink-3); white-space: nowrap; }
.art > .sec--white .ind-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px var(--wh-gap); align-content: start; }
.art > .sec--white .ind-item[hidden] { display: none; }
.art > .sec--white .ind-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 10px;
  box-sizing: border-box;
  height: 100%;
  padding: 20px 22px;
  border: 1px solid rgba(11, 11, 12, 0.08);
  border-radius: var(--r-card);
  background: #fff;
  box-shadow: 0 1px 2px rgba(11, 11, 12, 0.04);
  transition: translate 0.4s var(--settle), box-shadow 0.4s var(--settle), border-color 0.25s;
}
.art > .sec--white .ind-top { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.art > .sec--white .ind-l {
  font: 500 18px/1.3 var(--font-ui);
  letter-spacing: -0.018em;
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: transparent;
  text-underline-offset: 5px;
  transition: color 0.25s, text-decoration-color 0.25s;
}
.art > .sec--white .ind-g { flex: none; font: 500 10.5px/1.3 var(--font-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-3); }
.art > .sec--white .ind-p { font-size: 14.5px; line-height: 1.55; color: var(--ink-2); text-wrap: pretty; }
.art > .sec--white .ind-we { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: auto; padding-top: 14px; border-top: 1px solid rgba(11, 11, 12, 0.07); }
.art > .sec--white .ind-we-k { flex: 0 0 100%; margin-bottom: 2px; font: 500 10.5px/1.4 var(--font-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--accent); }
.art > .sec--white .ind-we-i {
  display: inline-flex;
  align-items: center;
  box-sizing: border-box;
  min-height: 28px;
  padding: 4px 10px;
  border: 1px solid rgba(44, 90, 134, 0.18);
  border-radius: 6px;
  background: rgba(44, 90, 134, 0.045);
  font: 500 13px/1.25 var(--font-ui);
  color: #1f4a78;                      /* 8.7:1 on white */
  transition: background-color 0.25s, border-color 0.25s;
}
.art > .sec--white .ind-card:is(:hover, :focus-visible) { translate: 0 -3px; border-color: rgba(44, 90, 134, 0.34); box-shadow: 0 1px 2px rgba(11, 11, 12, 0.04), 0 24px 46px -28px rgba(20, 50, 90, 0.42); }
.art > .sec--white .ind-card:is(:hover, :focus-visible) .ind-l { color: var(--accent); text-decoration-color: rgba(44, 90, 134, 0.5); }
.art > .sec--white .ind-card:is(:hover, :focus-visible) .ind-we-i { background: rgba(44, 90, 134, 0.1); border-color: rgba(44, 90, 134, 0.32); }
.art > .sec--white .ind-none { padding: 22px 24px; border: 1px dashed rgba(11, 11, 12, 0.22); border-radius: var(--r-card); font-size: 15px; line-height: 1.55; color: var(--ink-2); }
.art > .sec--white .ind-none[hidden] { display: none; }
.art > .sec--white .ind-none a { color: var(--accent); text-decoration: underline; text-decoration-color: rgba(44, 90, 134, 0.45); text-underline-offset: 3px; }
@media (max-width: 899px) { .art > .sec--white .ind-bar { grid-template-columns: 1fr; } }
@media (max-width: 719px) {
  .art > .sec--white .ind-list { grid-template-columns: 1fr; }
  .art > .sec--white .ind-card { padding: 18px; }
  .art > .sec--white .ind-g { display: none; }
}

/* Intelligence: seven charts from published data, set like a research report (js/charts.js draws
   them). Each figure: its number and theme, one headline figure, a title that says what the chart
   shows, a line on what is plotted, the chart, one linked source line and its data table. Three
   to a row from 1024 px, the capability chart and the studies taking two places each, so the seven
   fill three rows; four to a row from 3000 px, where they fill two; two on tablets, one on phones
   (operator 2026-09-26: "graphs are too big make them more compact (put more data in a row and
   eventually less white part)"). A card two places wide sets its words in two columns (the
   container query below). The cards in a row share one height, and each chart takes the height its
   card leaves it, so no card carries an empty band and the source lines end level. The palette is
   four hues checked with the dataviz validator on white (lightness band, chroma floor, colour-blind
   separation for every pair, 3:1 against the paper), used in one fixed order: blue, orange, teal,
   violet; grey for context. Text never wears a series colour. */
.art > .sec--white .dash { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(16px, 1.2vw, 28px); max-width: none; }
.art > .sec--white .dash > :is(.viz--wide, [data-fig="trials"]) { grid-column: span 2; }
@media (min-width: 3000px) {
  .art > .sec--white .dash { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .art > .sec--white .dash > [data-fig="trials"] { grid-column: auto; }
}
@media (max-width: 1023px) {
  .art > .sec--white .dash { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .art > .sec--white .dash > [data-fig="trials"] { grid-column: auto; }
}
@media (max-width: 719px) {
  .art > .sec--white .dash { grid-template-columns: minmax(0, 1fr); }
  .art > .sec--white .dash > .viz--wide { grid-column: auto; }
}

.viz {
  --c1: #2b62a6;
  --c2: #d65a26;
  --c3: #138f73;
  --c4: #9a6fc4;
  --cg: #a3a3ab;
  --viz-rule: rgba(11, 11, 12, 0.08);
  position: relative;
  container-type: inline-size;
  display: flex;
  flex-direction: column;
  gap: 14px;
  box-sizing: border-box;
  min-width: 0;
  margin: 0;
  padding: clamp(16px, 1.1vw, 24px);
  border: 1px solid rgba(11, 11, 12, 0.08);
  border-radius: var(--r-card);
  background: #fff;
  box-shadow: 0 1px 2px rgba(11, 11, 12, 0.04), 0 18px 40px -30px rgba(11, 11, 12, 0.2);
  color: var(--ink);
}
.fig-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; min-width: 0; }
.fig-head > * { flex: 1 1 100%; order: 2; }
.fig-body { flex: 1 1 auto; display: flex; flex-direction: column; justify-content: flex-end; gap: 10px; min-width: 0; }
.fig-k { display: flex; gap: 10px; margin: 0; font: 500 11.5px/1.3 var(--font-mono); letter-spacing: 0.07em; text-transform: uppercase; color: var(--ink-3); }
.fig-kn { color: var(--accent); }
.fig-hl { display: flex; align-items: flex-start; gap: 12px; margin: 2px 0 0; }
/* the headline figure: the chart's own point, in the text face with proportional figures */
.fig-v { flex: none; display: flex; align-items: baseline; gap: 4px; font: 500 clamp(30px, 22px + 0.8vw, 40px)/1 var(--font-ui); letter-spacing: -0.045em; color: var(--ink); white-space: nowrap; }
.fig-u { font-size: 0.4em; letter-spacing: -0.01em; color: var(--ink-3); }
.fig-vl { min-width: 0; max-width: 44ch; font-size: 13px; line-height: 1.4; color: var(--ink-2); text-wrap: pretty; }
.viz-t { margin: 0; font: 500 clamp(15.5px, 14px + 0.22vw, 18px)/1.25 var(--font-ui); letter-spacing: -0.015em; color: var(--ink); text-wrap: balance; }
.viz-s { margin: 0; max-width: 76ch; font-size: 12px; line-height: 1.45; color: var(--ink-3); text-wrap: pretty; }
/* the switch shares the line of the figure's number and theme while both fit, else takes the next */
.fig-head > .fig-k { flex: 1 0 auto; order: 0; }
.fig-head > .seg { flex: none; order: 1; }
.art > .sec--white .fig-head .seg > button { height: 28px; padding: 0 10px; font-size: 12px; }
/* a card two places wide: its number and theme at the left, its title and what is plotted at the
   right, so the words take two short columns instead of one long one */
@container (min-width: 600px) {
  .fig-head { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 8px clamp(20px, 4cqi, 40px); align-items: start; }
  .fig-k { grid-area: 1 / 1; }
  .fig-hl { grid-area: 2 / 1 / 5 / 2; flex-direction: column; gap: 4px; }
  .viz-t { grid-area: 1 / 2 / 3 / 3; }
  .viz-s { grid-area: 3 / 2; }
  .fig-head > .seg { grid-area: 4 / 2; justify-self: start; }
}

/* the key: one mark per series, the mark it wears in the chart */
.ch-key { display: flex; flex-wrap: wrap; gap: 2px 14px; margin: 0; padding: 0; list-style: none; font-size: 12px; line-height: 1.4; color: var(--ink-2); }
.ch-key li { display: inline-flex; align-items: center; gap: 7px; }
.ch-sw { flex: none; display: inline-block; background: var(--c); }
.ch-sw--dot { width: 9px; height: 9px; border-radius: 50%; }
.ch-sw--line { width: 16px; height: 2px; border-radius: 1px; }
.ch-sw--rect { width: 10px; height: 10px; border-radius: 2px; }
.ch-sw--ref { width: 16px; height: 0; border-top: 1.5px dashed var(--ink-3); background: none; }
.s-1 { --c: var(--c1); }
.s-2 { --c: var(--c2); }
.s-3 { --c: var(--c3); }
.s-4 { --c: var(--c4); }
.s-g { --c: var(--cg); }
.s-t { --c: rgba(43, 98, 166, 0.5); }

/* the chart: inline SVG, drawn to its box; hairline grid, mono ticks, 2 px lines, ringed points */
.ch { position: relative; min-height: 150px; border-radius: 8px; outline: none; -webkit-tap-highlight-color: transparent; }
.ch:focus-visible { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--accent); }
/* the chart takes the height its row leaves it: js/charts.js sets the box's least height (the height
   the chart is drawn at on its own) and draws to the box, and the drawing sits out of flow, so it
   never holds the card open. Without script the table stands open in its place */
.fig-body > .ch { flex: 1 1 auto; }
html:not(.js) .dash .ch { display: none; }
.ch-svg { position: absolute; top: 0; left: 0; display: block; overflow: visible; }
.ch-grid { stroke: #ececef; stroke-width: 1; shape-rendering: crispEdges; }
.ch-base { stroke: #b4b4bb; stroke-width: 1; shape-rendering: crispEdges; }
.ch-zero { stroke: #8e8e96; stroke-width: 1; shape-rendering: crispEdges; }
.ch-tick { font: 500 11px var(--font-mono); fill: var(--ink-3); font-variant-numeric: tabular-nums; }
.ch-tick--minor { fill: #8b8b93; }
.ch-lab { font: 500 12.5px var(--font-ui); fill: var(--ink-2); }
.ch-lab--val { fill: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
.ch-lab--na { fill: var(--ink-3); font-weight: 400; }
.ch-lab--note { font-size: 11.5px; fill: var(--ink-3); }
/* a point's name and the trend's label carry a halo of the card's white, so an interval or the
   trend line passing under them never runs through a letter */
.ch-lab--note, .ch-lab--trend { paint-order: stroke; stroke: #fff; stroke-width: 3px; stroke-linejoin: round; }
.ch-lab--ref { font-size: 11.5px; fill: var(--ink-2); }
.ch-lab--trend { font-size: 11.5px; fill: #24548f; }
.ch-lab--row { fill: var(--ink); font-weight: 400; }
.ch-lab--grp { font-size: 13px; font-weight: 600; fill: var(--ink); }
.ch-sub { font: 400 11.5px var(--font-ui); fill: var(--ink-3); }
.ch-line { fill: none; stroke: var(--c); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.ch-area { fill: var(--c); opacity: 0.1; }
.ch-dot { fill: var(--c); stroke: #fff; stroke-width: 2; }
.ch-dot.is-open { fill: #fff; stroke: var(--c); }
.ch-ci { stroke: var(--c); stroke-width: 2; stroke-linecap: round; opacity: 0.22; }
.ch-trend { fill: none; stroke: var(--c1); stroke-width: 1.5; stroke-linecap: round; opacity: 0.5; }
.ch-ref { stroke: var(--ink-3); stroke-width: 1; stroke-dasharray: 4 4; }
.ch-col, .ch-bar { fill: var(--c); }
.ch-link { stroke: #d4d4da; stroke-width: 2; stroke-linecap: round; }
.ch-cross { stroke: rgba(11, 11, 12, 0.32); stroke-width: 1; shape-rendering: crispEdges; }
.ch-hot { fill: none; stroke: var(--c); stroke-width: 2; }
.ch-band { fill: rgba(44, 90, 134, 0.07); }
.ch-dot, .ch-col, .ch-bar { transform-box: fill-box; transform-origin: 50% 50%; }
.ch-col { transform-origin: 50% 100%; }
.ch-bar { transform-origin: 0 50%; }
.ch-bar.is-neg { transform-origin: 100% 50%; }

/* the reading: every value at the point, the value first, keyed with the series' short line */
.viz-tip {
  position: absolute;
  z-index: 3;
  top: 0;
  left: 0;
  box-sizing: border-box;
  min-width: 150px;
  max-width: min(290px, 86%);
  padding: 10px 12px 11px;
  border-radius: 10px;
  background: #0b0b0c;
  color: #f5f5f2;
  font: 400 12.5px/1.45 var(--font-ui);
  box-shadow: 0 12px 32px -12px rgba(0, 0, 0, 0.45);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s;
}
.viz-tip.is-on { opacity: 1; }
.viz-tip-h { margin: 0 0 5px; font: 500 11px/1.35 var(--font-mono); letter-spacing: 0.02em; color: rgba(245, 245, 242, 0.66); }
.viz-tip-r { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0 7px; margin: 0; }
.viz-tip-r + .viz-tip-r { margin-top: 3px; }
.viz-tip-k { flex: none; align-self: center; width: 12px; height: 2px; border-radius: 1px; background: var(--c); }
.viz-tip-k.s-1 { --c: #6f9fe0; }   /* the blue one step lighter, so the key reads on the dark tip */
.viz-tip b { font-weight: 600; color: #fff; font-variant-numeric: tabular-nums; }
.viz-tip-n { color: rgba(245, 245, 242, 0.74); }

/* the foot: one source line, and the data table behind a disclosure (open without script) */
.viz-foot { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 16px; padding-top: 10px; border-top: 1px solid var(--viz-rule); }
.viz-src { flex: 1 1 15em; margin: 0; font-size: 12px; line-height: 1.45; color: var(--ink-3); text-wrap: pretty; }
.viz-src a { color: var(--ink-2); text-decoration: underline; text-decoration-color: rgba(11, 11, 12, 0.3); text-underline-offset: 3px; transition: color 0.2s, text-decoration-color 0.2s; }
.viz-src a:hover { color: var(--accent); text-decoration-color: currentColor; }
.viz-data { font-size: 12px; color: var(--ink-2); }
.viz-data summary { cursor: pointer; list-style: none; text-decoration: underline; text-decoration-color: rgba(11, 11, 12, 0.3); text-underline-offset: 3px; white-space: nowrap; }
.viz-data summary::-webkit-details-marker { display: none; }
.viz-data summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }
.viz-data[open] { flex-basis: 100%; }
.viz-data table { width: 100%; margin-top: 12px; border-collapse: collapse; font: 400 12.5px/1.4 var(--font-ui); font-variant-numeric: tabular-nums; }
.viz-data caption { margin-bottom: 8px; text-align: left; font-size: 12px; line-height: 1.45; color: var(--ink-3); caption-side: top; }
.viz-data :is(th, td) { padding: 7px 10px 7px 0; border-bottom: 1px solid var(--viz-rule); text-align: right; vertical-align: top; }
.viz-data :is(th[scope="row"], thead th:first-child) { text-align: left; font-weight: 400; color: var(--ink-2); }
.viz-data thead th { font-weight: 500; color: var(--ink-3); }
.viz-data td:last-child:not([data-v]) { text-align: left; }
/* an open table wider than its card scrolls inside it: its width is kept from the figure (contain),
   which otherwise grew to fit it and ran out of the card on phones */
.viz-data[open] .viz-data-scroll, .viz-data[open] table { display: block; max-width: 100%; overflow-x: auto; contain: inline-size; }
@media (max-width: 559px) { .viz-data table { font-size: 12px; } }

/* arrivals: each figure rises into focus (js/motion.js initWhite, css/motion.css), then its chart
   plays once its plot is in view (js/charts.js marks it armed, then in): lines draw, points pop in
   left to right, columns and bars grow from their baseline, labels follow. Everything is in place
   without script, and with reduced motion nothing moves. */
@media (prefers-reduced-motion: no-preference) {
  .viz[data-play="armed"] .ch-draw { stroke-dasharray: 1; stroke-dashoffset: 1; }
  .viz[data-play="armed"] :is(.ch-dot, .ch-bar) { transform: scale(0); }
  .viz[data-play="armed"] .ch-col { transform: scaleY(0); }
  .viz[data-play="armed"] .ch-bar { transform: scaleX(0); }
  .viz[data-play="armed"] :is(.ch-in, .ch-area, .ch-ci) { opacity: 0; }
  .viz[data-play="in"] .ch-draw { stroke-dasharray: 1; transition: stroke-dashoffset 1.9s var(--out) 0.2s; }
  .viz[data-play="in"] .ch-dot { transition: transform 0.55s var(--out) calc(0.25s + var(--k, 0) * 55ms); }
  .viz[data-play="in"] :is(.ch-col, .ch-bar) { transition: transform 0.9s var(--out) calc(0.2s + var(--k, 0) * 60ms); }
  .viz[data-play="in"] :is(.ch-in, .ch-area) { transition: opacity 0.6s ease 1.1s; }
  .viz[data-play="in"] .ch-ci { transition: opacity 0.8s ease 0.9s; }
}
@media (prefers-reduced-motion: reduce) {
  .art > .sec--white :is(.sol-card, .sol-l, .sol-b, .sol-get, .ind-card, .ind-l, .ind-we-i, .ind-q, .seg > button),
  .art > .sec--white .viz-tip { transition: none; }
  .art > .sec--white .sol-card:is(:hover, :focus-visible) .sol-get-i { animation: none; }
}

/* the header over the light: while it floods or ebbs, the lockup and the section index step aside
   and the quiet actions take a dark ground, so nothing light sits on a light middle; once the view
   is white they return in dark ink, over a white band */
html[data-astra-flood]:has(main.home) .brand { opacity: 0 !important; transition: opacity 0.18s; }
html[data-astra-flood]:not([data-astra-white]) .art-index { opacity: 0 !important; visibility: hidden; transition: opacity 0.18s, visibility 0s linear 0.18s; }
html[data-astra-flood] .hdr-acts :is(.hdr-util, .btn-ghost) { background: rgba(12, 12, 14, 0.86); color: #f5f5f2; box-shadow: none; }
html[data-astra-flood] body::before { opacity: 0; transition: opacity 0.18s; }
html[data-astra-white]:has(main.home) .brand { opacity: 1 !important; color: #0b0b0c; }
html[data-astra-white] :is(.brand-name, .brand-line) { text-shadow: none; }
html[data-astra-white] .brand-dev { color: #6b6b74; }   /* 4.9:1 on the white ground */
html[data-astra-white] .brand-mark { filter: none; }
/* on the white the section index turns to ink on a paper backing (where the white page reaches
   into its gutter, home.js has it step aside instead) */
html[data-astra-white] .art-index { background: rgba(247, 247, 244, 0.78); }
html[data-astra-white] .art-index ol { border-left-color: rgba(11, 11, 12, 0.16); }
html[data-astra-white] .art-index a { color: #3a3a3e; text-shadow: none; }   /* 10.9:1 on the paper */
html[data-astra-white] .art-index a:is(:hover, [aria-current="true"]) { color: #0b0b0c; }
html[data-astra-white] .art-index a[aria-current="true"] { border-left-color: #0b0b0c; }
@media (prefers-reduced-transparency: reduce) { html[data-astra-white] .art-index { background: #f7f7f4; } }
html[data-astra-white] .hdr-acts .btn-solid { background: #0b0b0c; color: #f5f5f2; }
html[data-astra-white] body::before {
  opacity: 1;
  background: linear-gradient(to bottom, #f7f7f4 0, #f7f7f4 calc(var(--hdr-t) + var(--row) + 4px), rgba(247, 247, 244, 0.72) calc(var(--hdr-t) + var(--row) + 18px), rgba(247, 247, 244, 0));
}

/* the title block */
.art-lead { padding-bottom: 7svh; text-align: center; }
.art .art-lead .kicker { margin-bottom: 18px; }
.art-title {
  margin: 0 auto;
  max-width: calc(62.5rem * var(--zd));
  font: 500 var(--t-title)/1.16 var(--font-ui);
  letter-spacing: -0.03em;
  color: var(--ink);
  text-wrap: balance;
}

/* headings, text, links */
.art .kicker { font: 500 13px/1.3 var(--font-ui); letter-spacing: 0.01em; color: var(--ink-3); }
.art .sec-head { display: flex; flex-direction: column; gap: 12px; }
.art .sec-h { font: 500 var(--t-h2)/1.32 var(--font-ui); letter-spacing: -0.01em; color: var(--ink); text-wrap: pretty; }
.art .prose > * + * { margin-top: 24px; }
.art .prose p { font-size: 17px; line-height: 28px; letter-spacing: -0.01em; color: var(--prose-ink); text-wrap: pretty; }
.art .prose strong { font-weight: 600; color: var(--ink); }
.art :is(.prose, .boxed, .sub-l) a:not([class]) {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: rgba(255, 255, 255, 0.44);
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
  transition: color 0.2s, text-decoration-color 0.2s;
}
.art :is(.prose, .boxed, .sub-l) a:not([class]):hover { color: rgba(245, 245, 242, 0.6); text-decoration-color: #fff; }
/* a figure's source line links the source itself, in the line's own quiet colour */
.art :is(.stat-n, .counter-n) a { text-decoration: underline; text-decoration-color: color-mix(in srgb, currentColor 45%, transparent); text-underline-offset: 3px; transition: color 0.2s, text-decoration-color 0.2s; }
.art :is(.stat-n, .counter-n) a:hover { color: var(--ink-2); text-decoration-color: currentColor; }
.art .prose .note, .art .note { font-size: 14px; line-height: 23px; color: var(--ink-3); }
.art .prose .tbl + .note { margin-top: 14px; }
.art .small { margin-top: 14px; font-size: 13px; line-height: 1.5; color: var(--ink-3); }
.art .prose .links, .art .links { display: flex; flex-wrap: wrap; gap: 12px 28px; }
.art .w > .links { margin-top: 24px; }
.art .acts { display: flex; flex-wrap: wrap; gap: 10px; }

/* the title block's group: the calls to action and the trust row under them */
.art-cta { display: flex; flex-direction: column; gap: 22px; }
.art .trust { display: flex; flex-wrap: wrap; gap: 8px 22px; }
.art .trust li { display: inline-flex; align-items: center; gap: 9px; font: 400 14px/1.45 var(--font-ui); color: var(--ink-2); }
.art .trust li::before { content: ""; flex: none; width: 5px; height: 5px; border-radius: 1px; background: rgba(245, 245, 242, 0.7); }

/* surfaces: stat cards, counters, cards, the boxed note, the form */
.art :is(.stat, .counter, .panel, .boxed, .reach-main, .reach-card) {
  box-sizing: border-box;
  border: 1px solid var(--line-2);
  border-radius: var(--r-card);
  background: var(--surface);
}

/* the proof strip */
.art .stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.art .stat { display: flex; flex-direction: column; gap: 8px; padding: 24px 24px 22px; }
.art :is(.stat-fig, .stat-count b) {
  display: block;
  font: 500 clamp(30px, 25px + 1.2vw, 40px)/1.08 var(--font-ui);
  letter-spacing: -0.03em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.art .stat-count b { margin-bottom: 8px; }
.art .stat-l { font-size: 15px; line-height: 1.5; color: var(--ink-2); text-wrap: pretty; }
.art .stat-n { margin-top: auto; padding-top: 6px; font-size: 13px; line-height: 1.45; color: var(--ink-3); }

/* a sub-block under a section: a small heading, a line, then its list */
.art .sub > * + * { margin-top: 12px; }
.art .sub-h { font: 500 var(--t-h3)/1.35 var(--font-ui); letter-spacing: -0.012em; color: var(--ink); text-wrap: balance; }
.art .sub-l { max-width: var(--prose); font-size: 15px; line-height: 1.6; color: var(--ink-2); text-wrap: pretty; }

/* cards */
.art .cards { display: grid; gap: 16px; }
.art .cards--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.art .cards--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.art .panel { display: flex; flex-direction: column; gap: 12px; height: 100%; padding: 24px 24px 22px; }
.art .panel-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.art .panel-h { font: 500 var(--t-h3)/1.3 var(--font-ui); letter-spacing: -0.015em; color: var(--ink); text-wrap: balance; }
.art .panel-t { display: block; font-size: 15px; line-height: 1.6; color: var(--ink-2); text-wrap: pretty; }
.art .panel-links { display: flex; flex-wrap: wrap; gap: 10px 24px; margin-top: auto; padding-top: 6px; }
.art .panel--link { transition: border-color 0.2s, background-color 0.2s; }
.art .panel--link:hover { border-color: rgba(255, 255, 255, 0.3); background: rgba(20, 20, 22, 0.9); }
.art .panel--link .panel-h { text-decoration: underline; text-decoration-thickness: 1px; text-decoration-color: transparent; text-underline-offset: 5px; transition: text-decoration-color 0.2s; }
.art .panel--link:hover .panel-h { text-decoration-color: rgba(255, 255, 255, 0.55); }
.art .ticks { display: grid; gap: 8px; }
.art .ticks li { position: relative; padding-left: 18px; font-size: 14.5px; line-height: 1.55; color: var(--ink-2); text-wrap: pretty; }
.art .ticks li::before { content: ""; position: absolute; left: 1px; top: 0.62em; width: 5px; height: 5px; border-radius: 1px; background: rgba(245, 245, 242, 0.62); }
.art .ticks--prose { gap: 12px; }
.art .ticks--prose li { padding-left: 22px; font-size: 17px; line-height: 28px; letter-spacing: -0.01em; color: var(--prose-ink); }
.art .ticks--prose li::before { top: 11px; }
.art .prose .sub-h + .ticks { margin-top: 16px; }

/* worked examples inside the Intelligence cards: illustrations, labelled as such */
.art .ex {
  display: grid;
  gap: 7px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.025);
  font: 400 12.5px/1.45 var(--font-mono);
  color: var(--ink-2);
}
.art .ex-row { display: flex; align-items: center; gap: 10px; min-width: 0; }
.art .ex-ic { width: 14px; height: 14px; flex: none; color: var(--ink); }
.art .ex-row--wait { color: var(--ink); }
.art .ex-row--kv { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, auto); gap: 16px; }
.art .ex-row--kv > :last-child { text-align: right; }
.art .ex-row--kv.ex-row--wait { margin: 0 -8px; padding: 5px 7px; border: 1px dashed rgba(255, 255, 255, 0.3); border-radius: 6px; }
.art .ex-num { color: var(--ink); font-variant-numeric: tabular-nums; }
.art .ex-row--q { align-items: baseline; }
.art .ex-k { flex: none; width: 14px; color: var(--ink-3); }
.art .ex-src { justify-self: start; margin-top: 3px; padding: 3px 8px; border: 1px solid var(--line-2); border-radius: 4px; font-size: 12px; color: var(--ink); }

/* e-invoicing: the two counters, the phases, the boxed note */
.art .counters { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.art .counter { display: flex; flex-direction: column; gap: 10px; padding: 24px 24px 22px; }
.art .counter-l { font-size: 15px; line-height: 1.5; color: var(--ink-2); text-wrap: pretty; }
.art .counter-l b {
  display: block;
  margin-bottom: 10px;
  font: 500 clamp(36px, 28px + 2vw, 56px)/1.02 var(--font-ui);
  letter-spacing: -0.035em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.art .counter-n { margin-top: auto; font-size: 13px; line-height: 1.45; color: var(--ink-3); }
.art .boxed { padding: 24px 26px 26px; border-color: rgba(255, 255, 255, 0.24); }
.art .boxed-h { font: 500 var(--t-h3)/1.35 var(--font-ui); letter-spacing: -0.012em; color: var(--ink); }
.art .boxed p { margin-top: 10px; font-size: 16px; line-height: 1.65; color: var(--prose-ink); text-wrap: pretty; }

/* tables: row rules only, the reference's */
.art .tbl { width: 100%; border-collapse: collapse; font-size: 14px; line-height: 23px; }
.art .tbl caption { caption-side: top; padding-bottom: 14px; text-align: left; font: 500 var(--t-h3)/1.35 var(--font-ui); letter-spacing: -0.012em; color: var(--ink); }
.art .tbl :is(th, td) { padding: 12px 16px 12px 0; text-align: left; vertical-align: top; border-bottom: 1px solid var(--rule); }
.art .tbl tr > :last-child { padding-right: 0; }
.art .tbl thead th { padding-top: 0; font-size: 13px; font-weight: 500; color: var(--ink-3); }
.art .tbl tbody th { font-weight: 500; color: var(--ink); }
.art .tbl td { color: var(--prose-ink); }
.art .tbl--2 tbody th { width: 32%; }

/* a line of steps: one record, and how an engagement runs */
.art .chain { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 16px; counter-reset: chn; }
.art .chain > li { position: relative; padding-top: 36px; counter-increment: chn; }
.art .chain > li::before {
  content: counter(chn, decimal-leading-zero);
  position: absolute; top: 0; left: 0;
  display: grid; place-items: center; box-sizing: border-box;
  width: 30px; height: 22px;
  border: 1px solid var(--line-2); border-radius: 6px; background: #000;
  font: 500 11px/1 var(--font-mono); color: var(--ink); font-variant-numeric: tabular-nums;
}
.art .chain > li::after {
  content: ""; position: absolute; top: 11px; left: 38px; right: -8px; height: 1px;
  background: linear-gradient(to right, rgba(255, 255, 255, 0.36), rgba(255, 255, 255, 0.08));
}
.art .chain > li:last-child::after { display: none; }
.art .chain-t { font: 500 16px/1.35 var(--font-ui); letter-spacing: -0.012em; color: var(--ink); }
.art .chain-x { margin-top: 6px; font-size: 14px; line-height: 1.55; color: var(--ink-2); text-wrap: pretty; }

/* Proof: six items under row rules */
.art .rows { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 32px; }
.art .rows li { padding: 18px 0 24px; border-top: 1px solid var(--rule); }
.art .rows-h { font: 500 var(--t-h3)/1.35 var(--font-ui); letter-spacing: -0.012em; color: var(--ink); }
.art .rows p { margin-top: 8px; font-size: 15px; line-height: 1.6; color: var(--ink-2); text-wrap: pretty; }

/* the four questions */
.art .qa { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px 32px; margin-top: 22px; }
.art .qa > div { padding-top: 16px; border-top: 1px solid var(--rule); }
.art .qa dt { font: 500 16px/1.4 var(--font-ui); letter-spacing: -0.01em; color: var(--ink); }
.art .qa dd { margin: 8px 0 0; font-size: 15px; line-height: 1.6; color: var(--ink-2); text-wrap: pretty; }

/* Contact: the heading, its one line and the two ways in at the left (five columns), the form at the
   right, from the column every section's lead starts on (from 1024 px; stacked below, the form
   under the heading). It is as tall as what it holds: the article's gap above it and nothing more
   (operator 2026-09-26: a screen-high box left a band of empty sky above it), and room below for
   the footer to rise into. The left column never moves: the form's card is as tall as the column
   until the email and the name open past it. */
.art .reach-lead { max-width: 30em; font-size: 15px; line-height: 1.5; color: var(--ink-2); text-wrap: pretty; }
.art .reach-main { min-width: 0; padding: 24px 24px 22px; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05); }
.art .reach-main .cf-done { padding: 0; border: 0; background: none; }
.art .reach-side { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 10px; }
/* a way in: its name and line at the left, what it does at the top right (read last) */
.art .reach-card {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "top go" "text text";
  align-items: baseline; gap: 4px 12px; padding: 14px 16px 15px; transition: border-color 0.2s, background-color 0.2s;
}
.art a.reach-card:hover { border-color: rgba(255, 255, 255, 0.3); background: rgba(20, 20, 22, 0.9); }
.art .reach-top { grid-area: top; display: flex; align-items: center; gap: 12px; min-width: 0; }
.art .reach-title { font: 600 15px/1.3 var(--font-ui); letter-spacing: -0.012em; color: var(--ink); }
.art .reach-text { grid-area: text; font-size: 13.5px; line-height: 1.5; color: var(--ink-2); text-wrap: pretty; }
.art .reach-go {
  grid-area: go; font: 500 13px/1.2 var(--font-ui); color: var(--ink-2);
  text-decoration: underline; text-decoration-color: rgba(255, 255, 255, 0.25); text-underline-offset: 4px;
  transition: color 0.2s, text-decoration-color 0.2s;
}
.art a.reach-card:hover .reach-go { color: var(--ink); text-decoration-color: #fff; }
/* the contact closes the article: its own foot is the article's, with room for the footer to rise into
   (none when a scene follows it) */
.art:has(> #contact:last-child) { padding-bottom: 0; }
.art #contact { padding-bottom: 72px; }
.art #contact > .reach-side { margin-top: calc(28px - var(--blk-gap)); }
.art > #contact:not(:last-child) { padding-bottom: 0; }
@media (min-width: 1024px) {
  .art #contact {
    box-sizing: border-box;
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    grid-template-rows: auto 1fr;
    align-items: start;
    column-gap: var(--col-gap);
    row-gap: 0;
    max-width: var(--wide);
    margin-inline: auto;
    padding-top: 0;
  }
  .art > #contact:last-child { padding-bottom: clamp(96px, 16svh, 176px); }
  .art #contact > * { grid-column: 1 / span 5; width: auto; max-width: none; margin: 0; }
  .art #contact > :not(.reach-main) { padding-right: calc(20px * var(--zd)); }
  .art #contact > .sec-head { grid-row: 1; }
  .art #contact > .reach-side { grid-row: 2; grid-template-columns: 1fr; max-width: calc(480px * var(--z)); margin-top: calc(28px * var(--z)); }
  .art #contact > .reach-main { grid-column: 6 / -1; grid-row: 1 / span 2; align-self: stretch; display: flex; flex-direction: column; max-width: calc(720px * var(--z)); }
  .art #contact .cform { flex: 1 1 auto; }
  .art #contact .cf-done { margin-block: auto; }
}

/* narrower screens: figures fold to fewer columns */
@media (max-width: 899px) {
  .art .cards--3 { grid-template-columns: 1fr; }
  .art .chain { grid-template-columns: 1fr; gap: 0; }
  .art .chain > li { padding: 0 0 22px 46px; }
  .art .chain > li:last-child { padding-bottom: 0; }
  .art .chain > li::after {
    top: 28px; bottom: 4px; left: 15px; right: auto; width: 1px; height: auto;
    background: linear-gradient(to bottom, rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.06));
  }
  .art .chain-x { margin-top: 4px; }
}
@media (max-width: 719px) {
  .art .stats, .art .counters, .art .cards--2, .art .sol-grid, .art .links2, .art .rows, .art .qa { grid-template-columns: 1fr; }
  .art .sol-grid { gap: 32px; }
  .art .qa { gap: 22px; }
  .art .stat, .art .counter, .art .panel { padding: 20px 18px 18px; }
  .art .boxed { padding: 20px 18px 22px; }
  .art .reach-main { padding: 20px 16px 18px; }
  .art .reach-side { grid-template-columns: 1fr; }
  .art #contact { padding-bottom: 56px; }
  .art .tbl :is(th, td) { padding-right: 12px; }
  .art .trust { gap: 8px 18px; }
}

/* ── the home on wide screens: the article uses the width ─────────────────────────────────────────
   From 1440 px each section is a 12-column grid as wide as the wide column (1047 px at 1440, 1459
   at 1920, 76% of anything wider, so the stars keep a rail of 12% either side): the heading takes
   five columns and its lead the other seven beside it, figures, cards and lists take all twelve,
   and the text after a figure stays in the lead's seven. A sub-block splits the same way, its
   heading at the left and its list at the right. The opening text runs as three columns, one
   paragraph each, and is the text column the engine keeps the stars off; every block of a section
   widens that clearing while it is on screen (index.html data-astra-wide). From 1600 px the type
   steps up with --z and --zd. Below 1440 nothing here applies. */
@media (min-width: 1440px) {
  .art .sec:not(.sec--white, .sec--river) {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--col-gap);
    row-gap: var(--blk-gap);
    align-items: start;
    max-width: var(--wide);
    margin-inline: auto;
  }
  .art .sec:not(.sec--white, .sec--river) > * { grid-column: 1 / -1; max-width: none; margin-inline: 0; }
  .art .sec:not(.sec--white, .sec--river) > :is(.prose, .acts) { grid-column: 6 / -1; }
  .art .sec:not(.sec--white, .sec--river) > .sec-head { grid-column: 1 / span 5; padding-right: calc(16px * var(--zd)); }
  .art .sec:not(.sec--white, .sec--river) > .sec-head + * { margin-top: 0; }
  .art .sec > .art-horizon + .prose { grid-row: 1; }   /* the lead beside its heading, the line of light under both */
  .art .sec > .sec-head + .prose { padding-top: calc(38px * var(--zd)); }   /* the lead starts level with the heading, under the kicker */
  .art .sec:not(.sec--white, .sec--river) > .acts { margin-top: calc(var(--blk-gap) * -0.5); }

  /* the opening: three statements side by side, then the calls to action and the trust row in one line */
  .art .sec > .prose[data-astra-column] { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: calc(var(--col-gap) * 1.5); }
  .art .prose[data-astra-column] > * + * { margin-top: 0; }
  .art .prose[data-astra-column] > p:first-child { color: var(--ink); }
  .art-cta { flex-direction: row; align-items: center; justify-content: space-between; gap: 24px 40px; }
  .art-cta > .acts { flex: none; }
  .art-cta .trust { justify-content: flex-end; }
  .art .stats { grid-template-columns: minmax(0, 1.5fr) repeat(3, minmax(0, 1fr)); }   /* the first figure is the longest */
  /* each figure fits its card on one line: capped by the card's own width */
  .art .stats > .stat { container-type: inline-size; }
  .art .stats :is(.stat-fig, .stat-count b) { font-size: min(clamp(30px, 25px + 1.2vw, 40px) * var(--zd), 15.5cqi); }
  .art .stats > .stat:first-child .stat-fig { font-size: min(clamp(30px, 25px + 1.2vw, 40px) * var(--zd), 11.5cqi); }

  /* Solutions: the four groups side by side */
  .art .sol-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 40px var(--col-gap); }
  /* a sub-block: its heading and line at the left, its list at the right */
  .art .sub.w { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--col-gap); align-items: start; }
  .art .sub.w > * { grid-column: 1 / span 5; }
  .art .sub.w > .sub-h { padding-right: calc(16px * var(--zd)); }
  .art .sub.w > :is(.links2, .qa) { grid-column: 6 / -1; grid-row: 1 / span 3; margin-top: 0; }

  /* cards, rows and steps: wider rows */
  .art .rows { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .art #availability .cards--2 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

  /* e-invoicing: the phases beside the note on what we are, the deliverables beside the actions */
  .art #einvoicing > .counters + .prose, .art #einvoicing > .boxed + .prose, .art #einvoicing > .acts + .prose { grid-column: 1 / span 7; }
  .art #einvoicing > .boxed { grid-column: 8 / -1; }
  .art #einvoicing > .acts { grid-column: 8 / -1; align-self: end; margin-top: 0; }
  .art #einvoicing > .boxed + .prose { margin-top: 0; }

  /* the white page takes the wide column too */
  .art > .sec--white { --wh-max: max(1180px, var(--wide)); }
}
/* from 1280 to 1599 px the section index sits beside the text (home.js needs its labels' end plus
   24 px clear of the text): the white block's column narrows to start 192 px in (the block's own 32 px gutter plus 160), so the index shows
   over all three parts instead of stepping aside (review 17: at 1440 the column started at 130 px,
   inside the index's 170). After the 1440 px block above, which it overrides up to 1599 px */
@media (min-width: 1280px) and (max-width: 1599px) { .art > .sec--white { --wh-max: calc(100% - 320px); } }
/* the type steps up with the screen (--z for text, --zd for headings and figures: 1 below 1600 px) */
@media (min-width: 1600px) {
  .art .kicker { font-size: calc(13px * var(--z)); }
  .art .prose p, .art .ticks--prose li { font-size: calc(17px * var(--z)); line-height: calc(28px * var(--z)); }
  .art .ticks--prose li::before { top: calc(11px * var(--z)); }
  .art .prose .note, .art .note { font-size: calc(14px * var(--z)); line-height: calc(23px * var(--z)); }
  .art .small, .art :is(.stat-n, .counter-n) { font-size: calc(13px * var(--z)); }
  .art .trust li { font-size: calc(14px * var(--z)); }
  .art :is(.stat-l, .counter-l, .panel-t, .rows p, .qa dd, .sub-l, .links2-l) { font-size: calc(15px * var(--z)); }
  .art :is(.sol-b, .links2-b, .reach-text) { font-size: calc(13.5px * var(--z)); }
  .art .sol-l { font-size: calc(15.5px * var(--z)); }
  .art .sol-h { font-size: calc(13px * var(--z)); }
  .art :is(.chain-t, .qa dt) { font-size: calc(16px * var(--z)); }
  .art .chain-x, .art .tbl { font-size: calc(14px * var(--z)); }
  .art .tbl { line-height: calc(23px * var(--z)); }
  .art .tbl thead th { font-size: calc(13px * var(--z)); }
  .art .ticks li { font-size: calc(14.5px * var(--z)); }
  .art .boxed p { font-size: calc(16px * var(--z)); }
  .art .ex { font-size: calc(12.5px * var(--z)); }
  .art .counter-l b { font-size: calc(56px * var(--zd)); }
  .art .reach-title { font-size: calc(15px * var(--z)); }
  .art .marq-list li { font-size: calc(15px * var(--z)); }
  .art .more { font-size: calc(14px * var(--z)); }
  .art :is(.stat, .counter, .panel) { padding: calc(24px * var(--z)) calc(24px * var(--z)) calc(22px * var(--z)); }
  .art .reach-main { padding: calc(24px * var(--z)) calc(24px * var(--z)) calc(22px * var(--z)); }
  .art .reach-lead { font-size: calc(15px * var(--z)); }
  .art .reach-go { font-size: calc(13px * var(--z)); }
  .art .cf-field label { font-size: calc(13px * var(--z)); }
  .art .cf-field--lead label { font-size: calc(15px * var(--z)); }
  .art .cf-note { font-size: calc(12px * var(--z)); }
  .art .btn:not(.btn-sm) { height: calc(44px * var(--z)); padding: 0 calc(20px * var(--z)); font-size: calc(14px * var(--z)); }
  .art .cf-field :is(input, textarea) { font-size: calc(15px * var(--z)); }
  .art .cf-field input { height: calc(46px * var(--z)); }
  .art .cf-field--lead textarea { height: calc(108px * var(--z)); font-size: calc(16px * var(--z)); }
  .art > .sec--white .wh-lead { font-size: calc(18px * var(--z)); line-height: calc(29px * var(--z)); }
  .art > .sec--white .sol-l { font-size: calc(16px * var(--z)); }
  .art > .sec--white .ind-l { font-size: calc(18px * var(--z)); }
  .art > .sec--white .sol-b { font-size: calc(14px * var(--z)); }
  .art > .sec--white .fig-vl { font-size: calc(13px * var(--z)); }
  .art > .sec--white .viz-s { font-size: calc(12px * var(--z)); }
  .art > .sec--white .ind-p { font-size: calc(14px * var(--z)); }
  .art > .sec--white :is(.sol-get-i, .ind-we-i, .seg > button) { font-size: calc(13px * var(--z)); }
  .art > .sec--white :is(.viz-src, .viz-data, .ch-key) { font-size: calc(12px * var(--z)); }
  .art > .sec--white .ind-q { font-size: calc(16px * var(--z)); height: calc(52px * var(--z)); }
}

/* ── the footer: every page's close, its link map and legal line ───────────────────────────── */
/* It opens on the night sky: a band across its top (.foot-horizon, --sky tall) where the stars lay one
   line of light as the footer comes up the view, the engine's horizon (field/boot.js,
   data-astra-scene="horizon"; the band lies past <main>, so the field stays until it has gone,
   field/page.js). The operator's third picture, 2026-09-26: the particles' horizon, in the footer. No
   buttons: the header carries them on every page. Under the band, the ground: the header's own black,
   a very dark grey at its top (#111113) deepening to #060607 at the foot, neutral, with no colour in
   it (operator, 2026-09-25, 09:00: "make the footer dark grey again, or black like the top part"). It
   rises out of the sky over the band's last 40 px, so no edge shows where the band ends, and it is
   opaque below: the field is still drawn behind it. It comes over the page (moveuras.com's footer):
   motion.js holds the page still at its end while the footer slides up over it (a content page's
   call to action, page.css .cp-band, rising with it right above it), and cuts the held page at the
   top edge of whichever comes first, so the band shows the sky, never the page. Square corners; its
   content keeps the page's grid (--grid). Without script, or with reduced motion, the page is not
   held and the band is plain night sky. */
.site-foot {
  --sky: clamp(112px, 15svh, 168px);
  position: relative;
  z-index: 10;
  box-sizing: border-box;
  padding: calc(var(--sky) + 44px) max(var(--gutter), calc((100% - var(--grid)) / 2)) 28px;
  color: var(--ink);
  --line: rgba(255, 255, 255, 0.09);
}
.site-foot::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: calc(var(--sky) - 40px) 0 0;
  background: linear-gradient(180deg, rgba(17, 17, 19, 0) 0, #111113 40px, #0b0b0c 360px, #060607 100%);
  pointer-events: none;
}
.foot-horizon { position: absolute; top: 0; left: 0; width: 100%; height: var(--sky); pointer-events: none; }
.foot-map { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 30px var(--col-gap); padding: 0 0 32px; }
.foot-col { grid-column: span 2; min-width: 0; }
.foot-col--wide { grid-column: span 4; }
.foot-col--wide ul { columns: 2; column-gap: var(--col-gap); }
.foot-col li { break-inside: avoid; }
.foot-h { margin-bottom: 8px; font: 500 13px/1.3 var(--font-ui); letter-spacing: -0.005em; }
.foot-h a { color: var(--ink); transition: color 0.2s; }
.foot-col ul + .foot-h { margin-top: 22px; }
.foot-col li a { display: inline-block; padding: 3.5px 0; font-size: 13px; line-height: 1.35; color: var(--ink-2); transition: color 0.18s; }
.foot-col a:hover { color: #fff; }
.foot-legal { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 6px 32px; padding-top: 18px; border-top: 1px solid var(--line); font-size: var(--fs-xs); line-height: 1.55; color: var(--ink-3); }
.foot-links { display: flex; flex-wrap: wrap; gap: 4px 20px; }
.foot-links a { color: var(--ink-2); text-decoration: underline; text-decoration-color: rgba(255, 255, 255, 0.22); text-underline-offset: 4px; transition: color 0.2s, text-decoration-color 0.2s; }
.foot-links a:hover { color: var(--ink); text-decoration-color: #fff; }
@media (max-width: 959px) {
  .foot-map { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .foot-col { grid-column: span 1; }
  .foot-col--wide { grid-column: span 2; }
}
@media (max-width: 719px) {
  .site-foot { padding: calc(var(--sky) + 32px) var(--gutter) 24px; }
  .foot-map { grid-template-columns: 1fr 1fr; row-gap: 26px; }
  .foot-col { grid-column: auto; }
  .foot-col--wide { grid-column: 1 / -1; }
  .foot-legal { display: block; }
  .foot-links { margin-top: 6px; }
}

/* ── phones ────────────────────────────────────────────────────────────────────────────────── */
@media (max-width: 719px) {
  .steps { gap: 9px; }
  .steps li { display: block; font-size: 13.5px; line-height: 1.45; }
  .steps li::before { top: 0.45em; }
  .cform { --cf-gap: 20px; }
  .cf-row { gap: 20px 10px; }
  .cf-field input { height: 42px; font-size: 16px; }
  .cf-field textarea { height: 84px; font-size: 16px; }
  .cf-field--lead textarea { height: 100px; }
  .cf-actions { flex-wrap: nowrap; }
  .cf-actions .btn { height: 42px; flex: none; }
  .cf-note, .cf-status { flex: 1 1 auto; font-size: 12px; line-height: 1.38; }
  .card { padding: 4px 0; border: 0; border-radius: 0; background: none; }
  .card:hover { background: none; }
  .card-top { justify-content: flex-start; gap: 8px; }
  .card-title { font-size: 14px; font-weight: 500; }
  .card-text { display: none; }
}
/* short landscape screens (1280x720, 1366x768): the header band sits a little higher */
@media (min-aspect-ratio: 1/1) and (max-height: 800px) {
  :root { --pg-top: 84px; }
}

/* ── from one page to the next ──────────────────────────────────────────────────────────────────
   site.js: on a click to another page of the site the stars stream out to the right (astra:leave)
   and the content slides out with them (data-leave); the next page's content comes in from the
   left (data-enter, set by its head script) while its stars stream in from the left. No
   cross-document view transition (x10, 2026-09-25: Chrome 153 held the next page's first frame
   about 330 ms for it, on these pages and on two plain ones alike); without it the browser keeps
   the page being left on screen until the next one paints, so there is still no blank frame
   between them. Nothing moves under reduced motion. The fixed
   section index is left out of the slide (a moved parent would carry it off its place). Starts
   at 1% opacity, not 0, so the first paint still counts (see the lockup's intro). */
.brand { view-transition-name: sx-brand; }
.island { view-transition-name: sx-island; }
.hdr-acts { view-transition-name: sx-acts; }
::view-transition-group(*) { animation-duration: 0.3s; }
html[data-swap] [data-astra-canvas] { visibility: hidden; }   /* site.js: the last picture of a page is taken without the field */
@media (prefers-reduced-motion: no-preference) {
  html[data-leave] :is(main > :not(.art-index), .cp-band, .site-foot) {
    translate: 9vw 0;
    opacity: 0.01;
    transition: translate 0.6s cubic-bezier(0.45, 0, 0.75, 0.4), opacity 0.5s cubic-bezier(0.4, 0, 0.9, 0.6) 0.06s;
  }
  html[data-leave] .art-index { opacity: 0 !important; transition: opacity 0.25s; }
  html[data-enter] :is(main > :not(.art-index), .cp-band, .site-foot) { animation: sx-enter 0.8s var(--out) 0.08s both; }
}
@keyframes sx-enter { from { translate: -9vw 0; opacity: 0.01; } }

/* ── reduced motion and transparency ───────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  html[data-intro] .brand > * { opacity: 1; transform: none; filter: none; animation: none; }
  html[data-intro] .scroll-cue-in { opacity: 1; animation: none; }
  html[data-intro] .island, html[data-intro] .hdr-acts { opacity: 1; transform: none; animation: none; }
  .brand-line, html[data-scrolled] .brand-line, body:has(.island[data-state="open"]) .brand-line { transition: none; }
  .isl-item[aria-expanded="true"] + .isl-panel { animation: none; }
  body::before { transition: none; }
  .island.is-ready, .island.is-ready[data-state="open"], .isl-scrim, .isl-panel, .island[data-state="open"] .isl-panel[data-active],
  .isl-nav, .island[data-state="open"] .isl-nav, .isl-menu > span { transition: none !important; }
  .isl-panel { filter: none; transform: none; }
  .scroll-cue-line::after { animation: none; transform: translateY(11px); }
  .find[open] { animation: none; }
  .find-sk { animation: none; }
  .btn, .card, .card-title, .isl-feat-cta { transition: none; }
  .art :is(.panel--link, .panel--link .panel-h, .reach-card, .reach-go), .art-index, .art-index a { transition: none; }
}
@media (prefers-reduced-transparency: reduce) {
  .island, .find, .hdr-acts .btn-ghost { background: #0c0c0e; -webkit-backdrop-filter: none; backdrop-filter: none; }
}

/* Charts draw with a viewBox, so on the smallest phones they scale down instead of spilling out
   (iOS pans a page sideways even with overflow-x: hidden on the body). */
figure[data-fig] svg { max-width: 100%; height: auto; }
