/* ============================================================
   INYUVATE — Predictive Adaptability Training
   Design system: "Quiet Signal"
   Geist (testo e display) + Geist Mono (voce d'interfaccia: label, indici,
   contatori, parentetiche). Mai nero.
   UN SOLO inchiostro #44413C: ogni grigio è una sua trasparenza
   (.89 titoli · .77 label e prosa · .52 display pallido) — si adatta
   da solo a ogni banda tonale, senza override.
   Clay = filo e accenti · petrol = science · dark = sezioni immersive
   ============================================================ */

:root {
  /* color — DARK scheme. Backgrounds are near-black; every text grey is an
     alpha of warm bone. Titles resolve to pure white; body sits on bone. */
  /* ---------- GRIGIO E TORTORA (ago 2026) ----------
     Niente colore, o quasi: il sito sta su una scala di grigi caldi, e
     l'unico accento è una TORTORA — la stessa temperatura delle immagini,
     che sono tutte calde. Il fondo è un "nero non nero": nero scaldato,
     non un grigio e non il nero pieno. Il colore chiaro entra solo come
     alone, in trasparenza, su un fondo che resta scuro (.atmos).
     Contrasti misurati sul fondo #0E0D0B — accento 7.73 · ink 16.15 ·
     ink-3 10.7 · fondo su accento (testo dei bottoni pieni) 7.73.
     Il tortora è stato SCALDATO il 13 ago 2026: era #A89A8C, che ha solo il
     14% di saturazione e su uno schermo tarato freddo — cioè quasi tutti i
     PC — si leggeva come un grigio e non come un accento. Ora #B5A08A: la
     stessa chiarezza, il colore che gli mancava (S 23%). Chiaro corrispon-
     dente #77624B (era #6E6155). Il 15 ago 2026 i due sono stati messi a
     confronto sulla stessa hero (confronto-tortora/): per un momento si era
     tornati al primo, poi la scelta è stata CONFERMATA su #B5A08A — è
     questo il colore buono, il ripensamento è durato mezza giornata e non
     va rifatto. Chi lo cerca altrove: ::selection qui sotto, il contorno
     del numero-fantasma e l'alone del punto degli assi in inner.css — sono
     gli stessi rgb scritti a mano.
     Le versioni precedenti: ottanio #2F9AB0 su #061719 · ruggine #D06B3C
     su #0B0B0A (con --bone-2 #151514, --bone-3 #131312, --dark #050505). */
  --bone: #0E0D0B;                   /* page background — nero non nero */
  --bone-2: #171613;                 /* tonal band / panel — warm lift */
  --ink: #ECEAE4;                    /* primary text — soft neutral off-white */
  --title: #FFFFFF;                  /* headings — white, for the larger/bolder voice */
  --ink-3: rgba(236, 234, 228, .80); /* labels, metadata, reading prose — AA */
  --ink-2: rgba(236, 234, 228, .58); /* pale display voice — large sizes only */
  --line: rgba(236, 234, 228, .13);
  --line-soft: rgba(236, 234, 228, .06);
  --clay: #B5A08A;                   /* tortora — l'unico accento, caldo come le immagini */
  /* the flowing line. It used to be deliberately earthier than the accent and
     read as a brown smudge on black next to the inner pages, which draw their
     line in --clay: brought up close to the accent so the home and the inner
     pages carry the same rust (feedback ago 2026). */
  --thread: #B5A08A;
  --petrol: #9E9A93;                 /* grigio freddo — il diagramma di Science, non un secondo colore */
  --dark: #080706;                   /* deepest immersive black — warm */
  --bone-on-dark: #ECEAE4;
  --line-on-dark: rgba(236, 234, 228, .18);
  --bone-3: #131210;                 /* footer surface — subtle warm lift */
  /* NIENTE color-mix() nelle variabili (rev. 12 ago 2026). Una custom property
     è sempre valida in fase di lettura: se il browser non conosce color-mix il
     valore diventa invalido solo al momento in cui viene sostituito, e lì la
     proprietà non torna indietro alla dichiarazione precedente — si azzera. Un
     `background: var(--glass)` diventava quindi TRASPARENTE, non "un po' meno
     vetro": i pannelli e la pillola della navigazione sparivano invece di
     degradare. Gli stessi valori scritti in rgba() li capiscono tutti, e sono
     esattamente il risultato del mix su questo fondo (#0E0D0B). */
  --glass: rgba(14, 13, 11, .52);
  --glass-strong: rgba(14, 13, 11, .70);

  /* type */
  --serif: 'Geist', 'Switzer', 'Helvetica Neue', sans-serif;
  --sans: 'Geist', 'Switzer', 'Helvetica Neue', sans-serif;
  --mono: 'Geist Mono', ui-monospace, 'SF Mono', monospace;  /* interface voice */

  --d1: clamp(1.3rem, 1.9vw, 1.7rem);       /* hero display */
  --d2: clamp(1.15rem, 1.55vw, 1.4rem);     /* statements / page titles */
  --d3: clamp(1.05rem, 1.3vw, 1.2rem);      /* section serif */
  --d4: clamp(1rem, 1.15vw, 1.1rem);        /* sub display */
  --body: .9375rem;
  --small: .8125rem;
  --micro: .68rem;   /* mono: più largo del sans, sta più comodo */

  /* rhythm */
  --gutter: clamp(1.25rem, 4vw, 3.5rem);
  --colgap: clamp(.8rem, 1.8vw, 1.6rem);
  --section: clamp(9rem, 26vh, 20rem);
  --measure: 34em;

  /* surface */
  --r-pill: 999px;
  --r-panel: 10px;
  --r-nav: 18px;

  /* weight — the reading voice and the display voice, kept far apart.
     Geist is a variable face (300..700): at 400 the prose already read as a
     semibold and the headings above it had nowhere left to go (feedback ago
     2026). The reading now sits BELOW regular and the display voice above
     medium, so the two are told apart at a glance, at any size. */
  --fw-read: 340;      /* body copy, leads, everything that is read */
  --fw-emph: 480;      /* an emphasis inside the reading */
  --fw-display: 580;   /* headings, statements, the phrases that land */

  /* motion */
  --ease: cubic-bezier(.25, .61, .36, 1);
  /* the reveal curve: easeOutCubic — a long soft landing, the same shape
     (power3.out) the reference site uses on its line reveals */
  --ease-soft: cubic-bezier(.215, .61, .355, 1);
  --dur: .8s;
}

/* ---------- reset ---------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* the browser's own furniture — the select's drop-down, the scrollbars, the
   caret, the autofill — has to belong to this page and not to the system's
   default light chrome. Without this the "Regarding" menu opened as a white
   sheet in the middle of a dark site, and nothing in CSS can restyle a native
   popup: only the colour scheme can (feedback ago 2026). */
html { color-scheme: dark; }
body.theme-light { color-scheme: light; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--sans);
  font-size: var(--body);
  line-height: 1.72;
  font-weight: var(--fw-read);
  color: var(--ink);
  background: var(--bone);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  letter-spacing: .002em;
  touch-action: manipulation;
  /* `clip` è il comportamento voluto (non crea un contenitore di scorrimento e
     non rompe position: sticky); `hidden` sotto è la rete per Safari < 16 e
     Firefox < 81, dove `clip` cade e la pagina resta scorrevole in orizzontale. */
  overflow-x: hidden;
  overflow-x: clip;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
ul, ol { list-style: none; }
::selection { background: rgba(181, 160, 138, .30); color: #fff; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--ink); color: var(--bone); padding: .6rem 1.2rem; border-radius: var(--r-pill);
}
.skip-link:focus { left: 1rem; top: 1rem; }

/* read by a screen reader, never seen: used where the design lifts a word out
   of a sentence and shows it as an image of type (the hero wordmark) */
.vh {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

:focus-visible { outline: 2px solid var(--clay); outline-offset: 3px; border-radius: 2px; }

/* ---------- grain ---------- */
body::after {
  content: ""; position: fixed; inset: 0; z-index: 90; pointer-events: none;
  opacity: .06; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- typography helpers ---------- */
em { font-family: var(--serif); font-style: italic; }

/* mono metadata — the interface voice */
.micro {
  font-family: var(--mono); font-size: var(--micro); font-weight: 400;
  letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3);
  font-feature-settings: "tnum";
}
.micro--center { display: block; text-align: center; }
.micro--paren::before { content: "( "; opacity: .55; }
.micro--paren::after { content: " )"; opacity: .55; }
.idx { font-family: var(--mono); font-size: var(--micro); letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); font-style: normal; }
.idx b { font-weight: var(--fw-read); color: var(--clay); }

/* ---------- layout ---------- */
.wrap { width: min(1280px, 100% - var(--gutter) * 2); margin-inline: auto; }
.wrap--narrow { width: min(760px, 100% - var(--gutter) * 2); margin-inline: auto; }

/* editorial 12-col grid */
.g12 { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--colgap); }


/* tonal bands — separation without borders; darker muted ink for AA */
.tone-2 { background: var(--bone-2); --line: rgba(237, 234, 225, .16); }


/* ============================================================
   NAV — floating pill
   ============================================================ */
.nav {
  position: fixed; top: clamp(.9rem, 2.5vh, 1.6rem); left: 50%;
  /* Le centrature STATICHE usano transform e non la proprietà `translate`:
     translate/rotate/scale singole non esistono prima di Safari 14.1 e
     Chrome 104, e lì la dichiarazione cade — la pillola finiva mezza fuori
     schermo a destra. Dove invece il movimento è solo decorativo (menu, punti,
     frecce) le proprietà singole restano: se cadono, non si perde nulla. */
  transform: translate(-50%, 0);
  width: min(600px, calc(100% - 2 * var(--gutter)));
  z-index: 100;
}
.nav-pill {
  display: flex; align-items: center; justify-content: space-between;
  height: 2.9rem; padding-inline: 1.15rem;
  background: rgba(14, 13, 11, .24);
  -webkit-backdrop-filter: blur(26px) saturate(1.4); backdrop-filter: blur(26px) saturate(1.4);
  border: 0; border-radius: var(--r-pill);
  transition: background var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.nav.is-open .nav-pill { background: var(--bone); }

/* over dark sections the nav flips to the light voice */
.nav--dark:not(.is-open) .nav-pill { background: rgba(20, 17, 14, .28); }
.nav--dark:not(.is-open) .nav-brand,
.nav--dark:not(.is-open) .nav-brand span,
.nav--dark:not(.is-open) .nav-toggle,
.nav--dark:not(.is-open) .theme-toggle { color: var(--bone-on-dark); }
.nav--dark:not(.is-open) .nav-mark circle { stroke: var(--bone-on-dark); }
.nav--dark:not(.is-open) .nav-toggle-dots i { background: var(--bone-on-dark); }
.nav-brand, .nav-toggle { transition: color .5s var(--ease); }
.nav-mark circle { transition: stroke .5s var(--ease); }
.nav-toggle-dots i { transition: translate .5s var(--ease), background .5s var(--ease); }
.nav-brand {
  font-family: var(--serif); font-weight: 500; font-size: .82rem;
  text-transform: uppercase; letter-spacing: .13em; color: var(--title);
}
.nav-brand span { color: var(--ink-3); }

.nav-mark { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: 24px; height: 24px; pointer-events: none; }
.nav-mark circle { fill: none; stroke: var(--title); stroke-width: 1; transform-origin: 50% 50%; }
.nav-mark .m2 { opacity: .45; animation: breathe 8s var(--ease) infinite; }
@keyframes breathe {
  0%, 100% { transform: scale(.78); opacity: .5; }
  50% { transform: scale(1.02); opacity: .18; }
}

/* the right-hand group: the background switch, then Menu. Keeping them in one
   box preserves the pill's space-between (brand | group) and leaves the
   centred mark untouched. */
.nav-right { display: flex; align-items: center; gap: 1.05rem; }
.theme-toggle {
  display: inline-flex; align-items: center; gap: .45rem;
  font-family: var(--mono); font-size: var(--micro); letter-spacing: .04em; text-transform: uppercase;
  color: var(--ink-3); padding: .5rem 0;
  transition: color .5s var(--ease);
}
.theme-toggle .tt-dot {
  width: 8px; height: 8px; border-radius: 50%;
  border: 1px solid currentColor; background: var(--clay);
  transition: background .5s var(--ease);
}
body.theme-light .theme-toggle .tt-dot { background: transparent; }
.theme-toggle:hover { color: var(--title); }
@media (max-width: 420px) { .theme-toggle .tt-t { display: none; } .nav-right { gap: .8rem; } }

.nav-toggle {
  display: flex; align-items: center; gap: .55rem;
  font-family: var(--mono); font-size: var(--micro); letter-spacing: .04em; text-transform: uppercase;
  color: var(--ink-3);
  padding: .5rem 0 .5rem .5rem;
}
.nav-toggle-dots { display: inline-flex; flex-direction: column; gap: 3px; }
.nav-toggle-dots i { width: 4px; height: 4px; border-radius: 50%; background: var(--title); transition: translate .5s var(--ease); }
.nav.is-open .nav-toggle-dots i:first-child { translate: 0 7px; }
.nav-toggle .label-close { display: none; }
.nav.is-open .label-menu { display: none; }
.nav.is-open .label-close { display: inline; }

.nav-menu {
  position: absolute; top: calc(100% + .55rem); left: 0; right: 0;
  background: rgba(14, 13, 11, .78);
  -webkit-backdrop-filter: blur(26px) saturate(1.2); backdrop-filter: blur(26px) saturate(1.2);
  border: 1px solid var(--line); border-radius: 22px;
  overflow: hidden;
  opacity: 0; translate: 0 -8px; visibility: hidden;
  transition: opacity .55s var(--ease), translate .55s var(--ease), visibility 0s linear .55s;
}
.nav.is-open .nav-menu { opacity: 1; translate: 0 0; visibility: visible; transition-delay: 0s; }
.nav-menu-group { padding: 1.05rem 1.35rem .45rem; }
.nav-menu-group .micro { font-size: .6rem; }
.nav-menu > a {
  display: flex; align-items: baseline; gap: 1.1rem;
  padding: .72rem 1.35rem; border-top: 1px solid var(--line-soft);
  font-family: var(--serif); font-weight: 500; font-size: 1.25rem; line-height: 1.25;
  color: var(--title);
  transition: background .4s var(--ease), translate .4s var(--ease);
}
.nav-menu > a:hover { background: rgba(23, 22, 19, .70); translate: .35rem 0; }
.nav-menu > a[aria-current="page"] { color: var(--ink-3); pointer-events: none; }
.nav-menu > a .n { font-family: var(--mono); font-size: .66rem; color: var(--ink-3); letter-spacing: .04em; }
.nav-menu > a[aria-current="page"] .n::after { content: " ·"; color: var(--clay); }
.nav-menu > a.sub { font-size: 1.08rem; padding-left: 2.4rem; }

.nav-menu-foot { display: flex; justify-content: flex-end; padding: .85rem 1.35rem 1.05rem; border-top: 1px solid var(--line-soft); }
.nav-menu-foot .micro { letter-spacing: .08em; }

/* ============================================================
   REVEAL
   ============================================================ */
/* FAIL-OPEN reveals — content is hidden ONLY under html.reveal-ready, which the
   script adds once it can guarantee the reveal. If the script never runs, is
   blocked, 404s from a stale cache, or a composited transition stalls, nothing
   is hidden — the page renders in full instead of going blank. */
/* The reveal grammar, taken from the reference site's line animations:
   a LONG travel on a soft out-curve (2s / power3.out there), a short stagger,
   and a composite of opacity + a little rise + a little blur — never a hard
   snap. Long and gentle reads as calm; short and linear reads as mechanical. */
[data-r] {
  transition: opacity 1.6s var(--ease-soft), translate 1.6s var(--ease-soft),
              filter 1.6s var(--ease-soft), scale 1.6s var(--ease-soft);
  transition-delay: calc(var(--i, 0) * .09s);
}
.reveal-ready [data-r] { opacity: 0; translate: 0 24px; filter: blur(9px); }
.reveal-ready [data-r="b"] { filter: blur(20px); translate: 0 30px; scale: .985; transition-duration: 1.9s; }
[data-r="b"].in { scale: 1; }
[data-r].in { opacity: 1; translate: 0 0; filter: blur(0); }

/* word-lit statements — blurred disclosure, resolves on scroll */
.lit .w {
  display: inline-block;
  transition: opacity 1.4s var(--ease-soft), filter 1.4s var(--ease-soft), translate 1.4s var(--ease-soft);
}
.reveal-ready .lit .w { opacity: .08; filter: blur(12px); translate: 0 .16em; }
.lit .w.on { opacity: 1; filter: blur(0); translate: 0 0; }

/* ============================================================
   BUTTONS
   ============================================================ */
.btn {
  display: inline-flex; align-items: center; gap: .9rem;
  padding: .6rem 1.5rem;
  border: 1px solid var(--line); border-radius: var(--r-pill);
  /* mono, uppercase and small: at the reading weight the label inside a solid
     pill read as a grey smudge instead of a word (feedback ago 2026) */
  font-family: var(--mono); font-size: .8rem; font-weight: 500;
  letter-spacing: .11em; text-transform: uppercase;
  position: relative; overflow: hidden; isolation: isolate;
  transition: color .6s var(--ease), border-color .6s var(--ease);
}
.btn::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: var(--ink); border-radius: inherit;
  scale: 0 1; transform-origin: left center;
  transition: scale .65s var(--ease);
}
.btn:hover { color: var(--bone); border-color: var(--ink); }
.btn:hover::before { scale: 1 1; }
.btn::after {
  content: ""; order: -1; width: 6px; height: 6px; border-radius: 50%;
  background: var(--clay); flex: none;
  transition: scale .5s var(--ease), background .5s var(--ease);
}
.btn:hover::after { scale: 1.6; }
.btn--solid:hover::after { background: var(--bone); }
.btn .arr { font-family: var(--sans); transition: translate .5s var(--ease); }
.btn:hover .arr { translate: 5px 0; }
.btn--solid { background: var(--ink); color: var(--bone); border-color: var(--ink); }
.btn--solid::before { background: var(--clay); }
.btn--solid:hover { border-color: var(--clay); }

/* ============================================================
   PAGE HERO (internal) — editorial masthead
   ============================================================ */
.phero { padding: calc(8rem + 6vh) 0 clamp(2.5rem, 6vh, 4.5rem); }
.phero-meta { display: flex; align-items: baseline; justify-content: space-between; gap: 2rem; margin-bottom: clamp(2.6rem, 6vh, 4.5rem); }
.phero h1 {
  font-family: var(--serif); font-weight: 400; font-size: var(--d2);
  line-height: 1.04; letter-spacing: 0; max-width: 13em;
}
.phero h1 .tail { display: block; padding-left: clamp(2rem, 14vw, 12rem); font-style: italic; font-weight: 400; color: var(--ink-2); }
.phero-foot { display: grid; grid-template-columns: repeat(12, minmax(0,1fr)); column-gap: var(--colgap); margin-top: clamp(2.6rem, 6vh, 4.5rem); }
.phero-foot .lede { grid-column: 6 / 13; max-width: var(--measure); color: var(--ink-2); font-size: 1.125rem; }
.phero-foot .idx { grid-column: 1 / 3; align-self: end; }
.phero-rule { border: 0; border-top: 1px solid var(--line); margin-top: clamp(2.5rem, 6vh, 4rem); }
@media (max-width: 720px) {
  .phero h1 .tail { padding-left: 1.5rem; }
  .phero-foot { display: block; }
  .phero-foot .lede { margin-top: 1.8rem; }
}

/* ============================================================
   PROSE
   ============================================================ */
.prose > * + * { margin-top: 1.4em; }
.prose p { color: var(--ink-2); max-width: var(--measure); }
.prose h3 { font-family: var(--serif); font-weight: 400; font-size: var(--d4); line-height: 1.25; color: var(--ink); max-width: 22em; }

.pull {
  font-family: var(--serif); font-weight: 400; font-size: var(--d3);
  line-height: 1.22; letter-spacing: -.005em; color: var(--ink); max-width: 21em;
}
.pull em { font-weight: 400; }

blockquote.q { max-width: 30em; position: relative; padding-left: clamp(1.6rem, 3vw, 2.6rem); }
blockquote.q::before { content: ""; position: absolute; left: 0; top: .35em; bottom: .35em; width: 1px; background: var(--line); }
blockquote.q p { font-family: var(--serif); font-style: italic; font-weight: 400; font-size: var(--d4); line-height: 1.4; color: var(--ink); }
blockquote.q footer { margin-top: 1.2rem; font-family: var(--mono); font-style: normal; font-size: var(--micro); letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); }
blockquote.q footer::before { content: "— "; color: var(--clay); }

/* ============================================================
   DEEPEN — expandable rows
   ============================================================ */
.deepen { border-top: 1px solid var(--line); }
.deepen-item { border-bottom: 1px solid var(--line); }
.deepen-head {
  display: flex; align-items: baseline; gap: 1.4rem;
  width: 100%; text-align: left; padding: 1.5rem .2rem;
  transition: translate .45s var(--ease);
}
.deepen-head:hover { translate: .5rem 0; }
.deepen-head .k { font-family: var(--mono); font-size: .66rem; letter-spacing: .06em; color: var(--ink-3); flex: none; }
.deepen-head .t { font-family: var(--serif); font-weight: 400; font-size: 1.15rem; line-height: 1.3; }
.deepen-x { position: relative; width: 14px; height: 14px; flex: none; margin-left: auto; align-self: center; }
.deepen-x::before, .deepen-x::after {
  content: ""; position: absolute; left: 50%; top: 50%; translate: -50% -50%;
  background: var(--ink); transition: rotate .5s var(--ease);
}
.deepen-x::before { width: 14px; height: 1px; }
.deepen-x::after { width: 1px; height: 14px; }
.deepen-item.open .deepen-x::after { rotate: 90deg; }
.deepen-item.open .deepen-x::before { rotate: 180deg; }
.deepen-body { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .7s var(--ease); }
.deepen-body > div { overflow: hidden; }
.deepen-item.open .deepen-body { grid-template-rows: 1fr; }
.deepen-inner { padding: .4rem .2rem 2.2rem; max-width: 40em; color: var(--ink-2); }
.deepen-inner ul { margin-top: .6rem; }
.deepen-inner li { padding: .55rem 0 .55rem 1.8rem; position: relative; border-top: 1px solid var(--line-soft); }
.deepen-inner li::before {
  counter-increment: dp;
  content: counter(dp, decimal-leading-zero);
  position: absolute; left: 0; top: .8em;
  font-family: var(--mono); font-size: .62rem; color: var(--clay); letter-spacing: .04em;
}
.deepen-inner ul { counter-reset: dp; }
.deepen-inner .outcome { margin-top: 1.6rem; padding-left: 1.8rem; }
.deepen-inner .outcome .micro { display: block; margin-bottom: .5rem; }

/* ============================================================
   PANEL — architectural
   ============================================================ */
/* Il riquadro risponde al passaggio schiarendo di una sola tacca: nessuna
   scala, nessuna ombra, nessun cambio di colore del testo. Deve notarsi che
   l'elemento risponde, non che cambia. Le due superfici sono dichiarate come
   variabili del componente, così la variante non è un valore sparso.
   Riguarda i riquadri di The Framework, Science e The Training — le uniche
   tre pagine che usano .panel. */
.panel {
  --panel-surface: var(--bone-2);        /* #151514 — bone + 6% */
  --panel-surface-hover: #1F1D1A;        /* +3%: la soglia del percepibile */
  border: 1px solid var(--line-soft); border-radius: var(--r-panel);
  padding: clamp(1.6rem, 3.5vw, 2.6rem); position: relative;
  background: var(--panel-surface);
  transition: background-color .3s var(--ease), border-color .3s var(--ease);
}
/* solo dove c'è un puntatore vero: su touch un :hover resterebbe appiccicato
   dopo il tocco */
@media (pointer: fine) {
  .panel:hover { background-color: var(--panel-surface-hover); border-color: var(--line); }
}
/* da tastiera lo stesso stato, a qualunque dispositivo di puntamento */
.panel:focus-visible { background-color: var(--panel-surface-hover); border-color: var(--line); }
/* regola SEPARATA, non in lista con quella sopra: un selettore sconosciuto
   invalida l'intero gruppo, e dove manca :has() si perdeva anche il focus
   diretto — cioè l'unico stato da tastiera del riquadro */
.panel:has(:focus-visible) { background-color: var(--panel-surface-hover); border-color: var(--line); }
.panel-head { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; margin-bottom: 1.6rem; padding-bottom: 1.1rem; border-bottom: 1px solid var(--line-soft); }
.panel-head .pin { align-self: center; width: 9px; height: 9px; border-radius: 50%; background: var(--clay); flex: none; }
.panel h3 { font-family: var(--serif); font-weight: 400; font-size: var(--d4); line-height: 1.25; max-width: 18em; }
.panel p { color: var(--ink-2); margin-top: 1.1rem; max-width: 36em; }
.panel h3 + p { margin-top: 1.3rem; }

/* ============================================================
   FIGURE
   ============================================================ */
.fig { border-radius: var(--r-panel); overflow: hidden; position: relative;
  transition: clip-path 1.6s var(--ease-soft);
}
.reveal-ready .fig { clip-path: inset(10% 8% round 14px); }
.fig.in { clip-path: inset(0 round var(--r-panel)); }
.fig img { width: 100%; height: 100%; object-fit: cover; scale: 1.08; transition: scale 1.8s var(--ease-soft); will-change: transform; }
.fig.in img { scale: 1.02; }
@media (pointer: fine) {
  .fig.in:hover img { scale: 1.055; }
}
/* L'immagine sborda del 7% sopra e sotto: e' lo spazio in cui il parallasse la
   fa scorrere. Il margine negativo funziona finche' il riquadro e' quadrato,
   perche' una percentuale di margine si misura sulla LARGHEZZA: su una banda
   larga e bassa il conto non torna piu' e sotto resta una striscia scoperta.
   La banda usa quindi top/height, che si misurano sull'altezza. Solo la banda:
   li' l'immagine puo' uscire dal flusso perche' il riquadro e' largo quanto la
   pagina, mentre le figure dei capitoli prendono la loro larghezza proprio
   dall'immagine e senza di essa collasserebbero a zero. */
.fig[data-plx] img { height: 114%; margin-top: -7%; }
.band .fig[data-plx] img { position: absolute; top: -7%; left: 0; right: 0; margin-top: 0; height: 114%; }

/* ============================================================
   FOOTER — one low line: the mark, four ways out, the notice.
   It used to be a five-column colophon; the site does its own signposting,
   so the footer only has to close the page (feedback ago 2026).
   ============================================================ */
.footer {
  background: var(--bone-3); color: var(--ink);
  --line: rgba(237, 234, 225, .16);
  margin-top: 0; position: relative;
}
.footer a { transition: opacity .4s var(--ease); }
.footer a:hover { opacity: .7; }
.footer li a, .nav-menu-foot a {
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 1px; background-position: 0 100%; background-repeat: no-repeat;
  transition: background-size .55s var(--ease), opacity .4s var(--ease);
  padding-bottom: .1em;
}
.footer li a:hover, .nav-menu-foot a:hover { background-size: 100% 1px; }
/* ALLINEAMENTO — perché è una griglia e non più un flex (feedback 12 ago 2026).
   Le quattro voci apparivano disordinate, e per due ragioni diverse:
   1. `justify-content: space-between` non le CENTRA: le posa fra il marchio e
      la nota, quindi il gruppo si sposta a ogni cambio di larghezza dei due
      vicini — e alla riga di copyright basta un anno più largo per muoverlo.
      Con `1fr auto 1fr` la fila sta in mezzo alla pagina, sempre, e le due
      colonne laterali si dividono l'avanzo.
   2. `align-items: baseline` allinea la prima riga di testo di ogni blocco:
      appena una delle voci andava a capo — o il marchio e la nota avevano
      corpi diversi, che è il caso — le tre parti si scalavano in verticale.
      `center` allinea i BLOCCHI, che è quello che si vede.
   Fra 721 e 900 px poi non ci stavano: la nota cadeva su una seconda riga e si
   incolonnava sotto il marchio. Il passaggio a due righe ora avviene lì, non a
   720 (dove era già tardi). */
.footer-inner {
  display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: center;
  column-gap: clamp(1.4rem, 3vw, 2.5rem); row-gap: .9rem;
  padding: clamp(1.6rem, 3.4vh, 2.3rem) 0;
}
.footer-mark {
  font-family: var(--serif); font-weight: 500; font-size: .95rem;
  letter-spacing: .04em; justify-self: start;
}
.footer-mark span { color: var(--clay); }
/* Lo spazio fra una voce e l'altra è PADDING, non `gap`: il gap sul flex non
   esiste prima di Safari 14.1 (iPhone fermi a iOS 14.0-14.4) e lì le quattro
   voci si toccavano — è esattamente il "disordine su alcuni dispositivi".
   Il margine negativo toglie il padding esterno, così i bordi del gruppo
   restano dove erano. */
.footer-links {
  justify-self: center;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  margin: -.2rem -.95rem;
}
.footer-links li { font-size: var(--small); line-height: 1.5; padding: .2rem .95rem; }
.footer-copy {
  font-family: var(--mono); font-size: var(--micro); letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-3);
  justify-self: end; text-align: right;
}
@media (max-width: 900px) {
  /* the four ways out keep their single row and take the top line; the mark
     and the notice close underneath — two low lines instead of a stack */
  .footer-inner { grid-template-columns: auto auto; row-gap: .85rem; padding: clamp(1.4rem, 3vh, 1.9rem) 0; }
  .footer-links { grid-column: 1 / -1; grid-row: 1; justify-self: start; justify-content: flex-start; margin-inline: -.62rem; }
  .footer-links li { padding-inline: .62rem; }
}
@media (max-width: 720px) {
  .footer-links li { font-size: .8125rem; }
  /* the notice has to share the closing line with the mark: at the full mono
     size the two together are a few pixels too wide for a phone and it drops
     to a third row, which is exactly the height we just took out */
  .footer-copy { font-size: .6rem; letter-spacing: .035em; }
}

/* ============================================================
   FORM (contact)
   ============================================================ */
/* the form used to be as tall as the page: two and a half rem between one
   field and the next, and a message box seven lines deep for a message that
   is optional. Closer, and the whole enquiry is one object again. */
.form {
  display: grid; gap: 1.55rem; max-width: 620px;
  /* I campi sono riquadri, non più righe trasparenti con una hairline sotto
     (13 ago 2026): su un fondo quasi nero non era evidente dove si dovesse
     scrivere. Stanno INCASSATI nel pannello del modulo — che ha la superficie
     dei .panel al passaggio del mouse, qui tenuta fissa (vedi contact.html) —
     quindi prendono la superficie di riposo dei .panel, una tacca sotto:
       pagina #0E0D0B  ·  pannello #1F1D1A  ·  campo #171613
     Il fuoco risale al livello del pannello: lo stato attivo deve restare
     distinguibile ora che il riposo non è più trasparente. */
  --field-surface: var(--bone-2);
  --field-surface-focus: #1F1D1A;
}
.field { display: grid; gap: .45rem; }
/* the labels are the only guide the form gives: they have to be read */
.field label {
  font-family: var(--mono); font-size: .74rem; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink);
}
.field input, .field textarea, .field select {
  font: inherit; color: var(--ink);
  background-color: var(--field-surface);
  border: 1px solid var(--line-soft); border-radius: var(--r-panel);
  padding: .78rem .95rem;
  transition: background-color .3s var(--ease), border-color .3s var(--ease);
  appearance: none; -webkit-appearance: none;
}
.field textarea { min-height: 5.2em; resize: vertical; }
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none; border-color: var(--ink); background-color: var(--field-surface-focus);
}
/* il riempimento automatico del browser dipinge di suo un fondo chiaro e un
   testo scuro: qui lo riporta alla superficie del campo (l'ombra interna è
   l'unico modo di sovrascriverlo su WebKit) */
.field input:-webkit-autofill,
.field input:-webkit-autofill:hover,
.field input:-webkit-autofill:focus,
.field textarea:-webkit-autofill {
  -webkit-text-fill-color: var(--ink);
  -webkit-box-shadow: 0 0 0 100px var(--field-surface) inset;
  caret-color: var(--ink);
}

/* the select: closed it carries our own chevron, open it is the page's dark
   (see color-scheme above), and the options are painted to match */
.field select {
  cursor: pointer; padding-right: 2.5rem;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.6 6 6.4 11 1.6' fill='none' stroke='%23ECEAE4' stroke-width='1.3' stroke-linecap='round'/%3E%3C/svg%3E");
  /* la freccia rientra dentro il riquadro ora che il campo ha un bordo e un
     riempimento: era a filo del testo quando il campo era una sola riga */
  background-repeat: no-repeat; background-position: right .95rem center; background-size: 11px 8px;
}
.field select option { background: #1F1D1A; color: #ECEAE4; }
/* sul fondo chiaro le stesse due superfici, ribaltate */
body.theme-light .form { --field-surface: #FFFFFF; --field-surface-focus: #FFFFFF; }
body.theme-light .field select {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.6 6 6.4 11 1.6' fill='none' stroke='%2326221D' stroke-width='1.3' stroke-linecap='round'/%3E%3C/svg%3E");
}
body.theme-light .field select option { background: #FBFAF6; color: #26221D; }
.form-note { font-size: .875rem; color: var(--ink-3); max-width: 32em; }

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 620px) {
  :root { --body: .9375rem; }
  .nav-brand span { display: none; }
  .nav-menu > a { font-size: 1.2rem; }
}
@media (pointer: coarse) {
  .deepen-head { padding-block: 1.7rem; }
  .nav-toggle { padding-block: .85rem; }
  .btn { padding: .7rem 1.6rem; }
}

/* ============================================================
   MODALITÀ LEGGERA — html.lite  (12 ago 2026)
   La mette site.js quando il dispositivo si dichiara debole (poca memoria,
   pochi core, risparmio dati, schermo lento a ridisegnare). Non è la
   riduzione del movimento chiesta dall'utente — quella è qui sotto e resta
   più severa: qui il sito si muove ancora, ma solo con ciò che la GPU compone
   da sola, cioè opacità e spostamento.

   Quello che si toglie, in ordine di costo:
   1. le SFOCATURE IN TRANSIZIONE. Un `filter: blur()` che va da 9 a 0 in 1,6s
      obbliga a ridisegnare l'elemento a ogni frame, e su una macchina lenta il
      reveal arriva a scatti — cioè si nota, che è il contrario di quello che
      deve fare;
   2. le sfocature FERME ma grandi (l'alone del fondo, il velo in basso, il
      vetro della navigazione): costano una volta sola, ma su schermi ad alta
      densità quella volta è cara e va rifatta a ogni ridimensionamento;
   3. le ANIMAZIONI INFINITE CHE SONO SOLO ATMOSFERA — gli aloni del fondo,
      l'anello della navigazione: non sono contenuto, e non valgono un frame
      perso ogni tre.

   Quello che NON si toglie mai (correzione 13 ago 2026): i due DIAGRAMMI —
   il punto che percorre i quattro assi del Framework e gli anelli di Science.
   Quelli non sono atmosfera: sono il disegno stesso, e fermi non dicono più
   quello che devono dire. Costano poco (una rotazione e uno spostamento, che
   la GPU compone) e restano accesi anche in modalità leggera. Se l'utente
   chiede davvero meno movimento, li ferma il blocco REDUCED MOTION qui sotto.
   ============================================================ */
.lite [data-r] { transition: opacity 1.1s var(--ease-soft), translate 1.1s var(--ease-soft); }
.lite .reveal-ready [data-r],
.lite .reveal-ready [data-r="b"] { filter: none; scale: 1; }
.lite .lit .w { transition: opacity 1s var(--ease-soft), translate 1s var(--ease-soft); }
.lite .reveal-ready .lit .w { filter: none; }
/* il ritaglio animato della figura è un'animazione di forma: resta il solo
   ingrandimento, che è composto */
.lite .fig { transition: none; clip-path: none; }
.lite .reveal-ready .fig { clip-path: none; }
/* niente vetro: al suo posto una superficie piena, che deve comunque reggere
   il testo che ci sta sopra */
.lite .nav-pill { -webkit-backdrop-filter: none; backdrop-filter: none; background: rgba(14, 13, 11, .92); }
.lite .nav-menu { -webkit-backdrop-filter: none; backdrop-filter: none; background: #100F0D; }
.lite .faq-list .deepen { -webkit-backdrop-filter: none; backdrop-filter: none; background: #131210; }
.lite .pblur { display: none; }
/* l'alone resta — è il colore del fondo — ma fermo e meno sfocato */
.lite .atmos i { animation: none; filter: blur(48px); will-change: auto; }
.lite .nav-mark .m2,
.lite .atmos .a-ring,
.lite .inner-thread-p { animation: none; }

/* ============================================================
   REDUCED MOTION
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
  [data-r] { opacity: 1; translate: none; filter: none; }
  .lit .w { opacity: 1; filter: none; translate: none; }
  .fig { clip-path: none; }
  .fig img { scale: 1; }
}

/* general style rules — quiet register */
.phero-rule, .essay-rule { display: none; }
.pn { border-top: 0; }
.atmos .a-ring { display: none; }

/* titles in a darker grey; leads and pulls stay pale */
.phero h1, .chapter-head h2, .marginalia .side h2, .panel h3, .prose h3,
.axis .name, .footer-mark, .deepen-head .t { color: var(--title); }
.essay .lead, .pull, .loop-center p { color: var(--ink-2); }
.prose p, .essay p, .panel p, .phero-foot .lede, .deepen-inner, .footer-tag { color: var(--ink-3); }
.essay .lead, .pull { line-height: 1.5; }
.phero h1 { font-size: clamp(1.6rem, 2.6vw, 2.3rem); line-height: 1.15; letter-spacing: -.016em; }

/* ============================================================
   RING ORGANIC — several hairline ellipses rotating together
   ============================================================ */
.ring-organic { display: block; width: 100%; height: 100%; overflow: visible; }
.ring-organic ellipse {
  fill: none; stroke: var(--ink); vector-effect: non-scaling-stroke;
  transform-box: view-box; transform-origin: center;
}
.ring-organic .e1 { stroke-width: .55; opacity: .5;  animation: ring-r 26s linear infinite,          ring-w 7s  ease-in-out infinite alternate; }
.ring-organic .e2 { stroke-width: .45; opacity: .42; animation: ring-r 38s linear infinite reverse,  ring-w 9s  ease-in-out infinite alternate-reverse; }
.ring-organic .e3 { stroke-width: .4;  opacity: .34; animation: ring-r 52s linear infinite,          ring-w 11s ease-in-out infinite alternate; }
.ring-organic .e4 { stroke-width: .4;  opacity: .3;  animation: ring-r 66s linear infinite reverse,  ring-w 8s  ease-in-out infinite alternate-reverse; }
.ring-organic .e5 { stroke-width: .35; opacity: .26; animation: ring-r 80s linear infinite,          ring-w 13s ease-in-out infinite alternate; }
.ring-organic .e6 { stroke-width: .3;  opacity: .2;  animation: ring-r 94s linear infinite reverse,  ring-w 10s ease-in-out infinite alternate-reverse; }
@keyframes ring-r { to { rotate: 360deg; } }
@keyframes ring-w {
  from { scale: 1 .955; }
  to   { scale: .96 1.04; }
}
.ring-breathe { animation: ring-b 9s var(--ease) infinite alternate; }
@keyframes ring-b { from { scale: .985; } to { scale: 1.015; } }
@media (prefers-reduced-motion: reduce) {
  .ring-organic ellipse, .ring-breathe { animation: none; }
}

/* ============================================================
   THREAD — the connective rust line, DRAWN down the page by the scroll.
   The same line on every page, homepage included (ago 2026): it is the one
   piece of motion that answers the wheel, so it has to read the same
   everywhere. Purely decorative — the content always sits above it, and if
   the scroll loop never runs the line simply stays partly drawn.
   ============================================================ */
#main.threaded { position: relative; }
#main.threaded > section,
#main.threaded > div,
#main.threaded > nav { position: relative; z-index: 1; }
.inner-thread {
  position: absolute; inset: 0; width: 100%; height: 100%;
  z-index: 0; pointer-events: none; overflow: visible;
}
.inner-thread-p { fill: none; stroke: var(--clay); vector-effect: non-scaling-stroke; }
/* weight and opacity per strand — here rather than in the script, so a page
   can dress the same line differently */
.inner-thread-p.s1 { stroke-width: .7; opacity: .5;  animation: thr-swc 21s ease-in-out infinite alternate; }
.inner-thread-p.s2 { stroke-width: .5; opacity: .32; animation: thr-swa 15s ease-in-out infinite alternate; }
.inner-thread-p.s3 { stroke-width: .4; opacity: .22; animation: thr-swb 26s ease-in-out infinite alternate; }
/* the drift: three different periods, none a multiple of another, so the
   braid never settles into a pose it has already held */
@keyframes thr-swa { from { transform: translate(6px, -2px); } to { transform: translate(-8px, 7px); } }
@keyframes thr-swb { from { transform: translate(-9px, 3px); } to { transform: translate(6px, -7px); } }
@keyframes thr-swc { from { transform: translate(-3px, 2px); } to { transform: translate(4px, -3px); } }
@media (prefers-reduced-motion: reduce) { .inner-thread { display: none; } }

/* ============================================================
   ATMOSPHERE — fixed organic background, gives glass its depth
   ============================================================ */
.atmos { position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; }
.atmos i {
  position: absolute; display: block; border-radius: 50% 42% 55% 45% / 48% 55% 45% 52%;
  filter: blur(70px); will-change: transform;
}
.atmos .a1 {
  width: 58vmax; height: 44vmax; left: -14vmax; top: -10vmax;
  background: radial-gradient(closest-side, rgba(194, 180, 166, .12), transparent 72%);
  animation: atmos-1 46s var(--ease) infinite alternate;
}
.atmos .a2 {
  width: 52vmax; height: 46vmax; right: -16vmax; top: 24vh;
  background: radial-gradient(closest-side, rgba(150, 148, 143, .09), transparent 72%);
  animation: atmos-2 58s var(--ease) infinite alternate;
}
.atmos .a3 {
  width: 46vmax; height: 40vmax; left: 18vw; bottom: -18vmax;
  background: radial-gradient(closest-side, rgba(237, 234, 225, .03), transparent 70%);
  animation: atmos-3 52s var(--ease) infinite alternate;
}
@keyframes atmos-1 { to { transform: translate(9vmax, 7vmax) scale(1.14) rotate(14deg); } }
@keyframes atmos-2 { to { transform: translate(-8vmax, -6vmax) scale(.9) rotate(-10deg); } }
@keyframes atmos-3 { to { transform: translate(-6vmax, -5vmax) scale(1.1) rotate(8deg); } }
.atmos .a-ring {
  position: absolute; right: 8vw; top: 16vh;
  width: clamp(200px, 26vw, 420px); aspect-ratio: 1;
  border: 1px solid var(--line-soft); border-radius: 50%;
  filter: none; opacity: .7;
  animation: atmos-ring 80s linear infinite;
}
/* on the home the background steps back: fewer things moving at once
   (feedback ago 2026, punto 8 — la richiesta riguarda la sola homepage) */
body[data-nothread] .atmos .a3,
body[data-nothread] .atmos .a-ring { animation: none; }
body[data-nothread] .atmos .a-ring { opacity: .55; }
.atmos .a-ring::before {
  content: ""; position: absolute; left: 50%; top: -2.5px; transform: translate(-50%, 0);
  width: 4px; height: 4px; border-radius: 50%; background: var(--ink-3);
}
@keyframes atmos-ring { to { rotate: 360deg; } }
@media (prefers-reduced-motion: reduce) { .atmos i, .atmos .a-ring { animation: none; } }

/* ============================================================
   PROGRESSIVE BLUR — gradient blur at the foot of the viewport,
   stronger toward the bottom (layered). No tint — blur only.
   ============================================================ */
.pblur { position: fixed; left: 0; right: 0; bottom: 0; height: 22vh; z-index: 80; pointer-events: none; transition: opacity .6s var(--ease); }
.pblur > span { position: absolute; inset: 0; display: block; }
.pblur > span:nth-child(1){ -webkit-backdrop-filter: blur(3px);  backdrop-filter: blur(3px);  -webkit-mask-image: linear-gradient(to top, #000 0%, #000 58%, transparent 100%); mask-image: linear-gradient(to top, #000 0%, #000 58%, transparent 100%); }
.pblur > span:nth-child(2){ -webkit-backdrop-filter: blur(9px);  backdrop-filter: blur(9px);  -webkit-mask-image: linear-gradient(to top, #000 0%, #000 32%, transparent 66%); mask-image: linear-gradient(to top, #000 0%, #000 32%, transparent 66%); }
.pblur > span:nth-child(3){ -webkit-backdrop-filter: blur(18px); backdrop-filter: blur(18px); -webkit-mask-image: linear-gradient(to top, #000 0%, transparent 40%); mask-image: linear-gradient(to top, #000 0%, transparent 40%); }
@media (prefers-reduced-motion: reduce) { .pblur { display: none; } }

/* ============================================================
   DISPLAY VOICE — single-family Switzer, medium weight
   ============================================================ */
.statement, .passage, .pull, .dark-head .title,
.phero h1, .chapter-head h2,
.marginalia .side h2, .panel h3, .prose h3, .essay .lead,
.circle-center p, .loop-center p, .journey-step .t, .journey-coda,
.deepen-head .t, .pn a .t, .nav-brand, .nav-menu > a, .axis .name,
blockquote.q p, .formats .fig-num, .chapter-ghost {
  font-weight: var(--fw-display); letter-spacing: -.005em;
}
em, .ital, blockquote.q p, .journey-coda { font-weight: var(--fw-emph); }
/* the one real bold in the prose: it has to be unmistakable next to a
   reading that now sits below regular */
strong, b { font-weight: 650; }
.dark-flow p { font-weight: var(--fw-emph); letter-spacing: -.01em; }

/* size-scaled kerning wins over the display-voice base */
.phero h1 { letter-spacing: -.016em; }

/* ============================================================
   THEME — LIGHT  (a full-page inversion back to warm paper).
   Token-driven: flipping the values on body.theme-light re-skins
   an entire page. Used to alternate light/dark pages across the
   site and break up the dark. Same alpha-of-ink model, dark ink.
   ============================================================ */
body.theme-light {
  --bone: #F1EFE8;                   /* warm paper background */
  --bone-2: #FBFAF6;                 /* panel / band lift */
  --bone-3: #E8E4DB;                 /* footer surface */
  --dark: #14110D;                   /* (immersive black — unused on inner pages) */
  --ink: #26221D;                    /* primary text — warm near-black */
  --title: #14110D;                  /* headings — darkest */
  --ink-3: rgba(28, 23, 18, .78);    /* labels, prose — AA on paper */
  --ink-2: rgba(28, 23, 18, .55);    /* pale display voice */
  --line: rgba(28, 23, 18, .14);
  --line-soft: rgba(28, 23, 18, .07);
  --clay: #77624B;                   /* tortora — darker for contrast on light */
  --petrol: #44606B;                 /* teal — darker for contrast on light */
  --glass: rgba(241, 239, 232, .60);
  --glass-strong: rgba(241, 239, 232, .78);
}
/* elements that hard-code a light-on-dark ink must flip on paper */
body.theme-light .footer { --line: rgba(28, 23, 18, .14); }
body.theme-light .tone-2 { --line: rgba(28, 23, 18, .14); }
body.theme-light .axes-frame { --ink-3: rgba(28, 23, 18, .78); }
