/* ==========================================================================
   Lab Medicinae — base.css
   --------------------------------------------------------------------------
   Reset minimale, layout di pagina, nav, footer, riflusso mobile.
   Canonici: dev/lab-medicinae-desktop-v2 (76:2020) · dev/lab-medicinae-mobile-v2 (167:624).
   Mobile-first: base = mobile (390), da --bp-desktop in su = desktop (1440).
   Richiede tokens.css.
   ========================================================================== */

/* --- Font (self-hosted, SIL OFL) ------------------------------------------
   Solo i pesi usati dai Text Styles (§3): Inter 400/600 · Geist 400/500 ·
   Geist Mono 400/700. Subset latin (copre æ, ò). woff2 in assets/fonts/.
   -------------------------------------------------------------------------- */

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../assets/fonts/inter-400.woff2") format("woff2");
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../assets/fonts/inter-600.woff2") format("woff2");
}

@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../assets/fonts/geist-400.woff2") format("woff2");
}

@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../assets/fonts/geist-500.woff2") format("woff2");
}

@font-face {
  font-family: "Geist Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../assets/fonts/geist-mono-400.woff2") format("woff2");
}

@font-face {
  font-family: "Geist Mono";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../assets/fonts/geist-mono-700.woff2") format("woff2");
}

/* --- Reset minimale ------------------------------------------------------ */

*, *::before, *::after { box-sizing: border-box; }

* { margin: 0; }

img, svg { display: block; max-width: 100%; }

button { font: inherit; color: inherit; background: none; border: none; padding: 0; cursor: pointer; }

a { color: inherit; text-decoration: none; }

/* [hidden] vince sempre sui display delle classi componente */
[hidden] { display: none !important; }

/* --- Documento ----------------------------------------------------------- */

html {
  -webkit-text-size-adjust: 100%;
  /* il radar hero sborda di proposito (canonico): clip orizzontale sulla
     radice, senza creare uno scroll container (niente scrollbar fantasma).
     `hidden` = fallback per browser senza `clip`. */
  overflow-x: hidden;
  overflow-x: clip;
  /* .page è centrata (max-width 1440 + margin auto): senza riservare sempre
     la barra di scorrimento, una pagina corta che non scrolla ha ~15px in
     più e il contenuto slitta a destra di ~7. Visto da Italo confrontando
     newsletter e strumenti (sessione 16). */
  scrollbar-gutter: stable;
}

/* Il pixel del contatore per chi non ha JS sta DOPO .page, che ha
   min-height 100vh: in flusso aggiunge il suo pixel e ogni pagina corta si
   ritrova una barra di scorrimento alta 1px. Fuori dal flusso conta uguale. */
noscript img {
  position: absolute;
  top: 0;
  left: 0;
}

body {
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-content);
  font-size: var(--size-20);
  line-height: var(--leading-24);
  overflow-x: hidden;
  overflow-x: clip;
}

/* A11y — focus sempre visibile (§4.9), radius 0 (§4.1) */
:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 2px;
}

/* Skip link */
.skip-link {
  position: absolute;
  left: -9999px;
  top: var(--space-8);
  z-index: 100;
  padding: var(--space-8) var(--space-16);
  background: var(--surface-white);
}
.skip-link:focus { left: var(--space-8); }

/* Solo screen reader (annunci aria-live del questionario, ecc.) */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --- Layout di pagina ----------------------------------------------------
   .page: colonna di sezioni, gap 80 (uguale mobile/desktop, §5).
   .container: margine orizzontale 24 mobile → 104 desktop (§5).
   -------------------------------------------------------------------------- */

.page {
  position: relative;
  display: flex;
  flex-direction: column;
  /* 80 è il respiro di tutte le pagine, canonico compreso (verificato
     sessione 13 su Privacy, Info, Colophon, intro ed esito). Il
     questionario è l'eccezione: vedi .page--quest. */
  gap: var(--space-80);
  min-height: 100vh;
  /* canvas canonico: sopra i 1440 il layout non si stira, si centra.
     Le card tornano ~400×418 (1232 = 3×400 + 2×16); il radar hero resta
     ancorato al canvas, non al viewport. */
  max-width: 1440px;
  margin-inline: auto;
}

/* main è un contenitore trasparente: stessa colonna, stesso gap */
.page main {
  display: flex;
  flex-direction: column;
  gap: var(--space-80);
}

.container {
  padding-inline: var(--space-24);
  width: 100%;
}

/* --- Nav ------------------------------------------------------------------
   Mobile: wordmark + link "Menu" (solo hook, drawer fuori scope 08).
   Desktop: wordmark + nav-main (Strumenti · Info · Contatti · Newsletter).
   -------------------------------------------------------------------------- */

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: var(--space-24);
  /* Sticky intelligente (deciso 2026-07-17): si nasconde scendendo, riappare
     scrollando verso l'alto. Classi gestite da main.js; senza JS resta una
     nav sticky sempre visibile (progressive enhancement). */
  position: sticky;
  top: 0;
  background: var(--surface);
  transition: transform var(--duration-base) var(--ease-out);
}

/* Questionario: nav ridotta e domanda alta nello schermo — i canonici del
   flusso e del form lungo chiedono 48, non 80 (misurato sessione 13:
   lab-quest-domanda/anagrafica-mobile-v1 e lab-quest-form-lungo-*). */
.page--quest { gap: var(--space-48); }

.nav--hidden { transform: translateY(-100%); }

/* staccata dal top: chiude la scatola con respiro e hairline (il cambio di
   padding avviene mentre è nascosta fuori viewport: nessun salto visibile) */
.nav--detached {
  padding-bottom: var(--space-16);
  border-bottom: 1px solid var(--line-2);
}

@media (prefers-reduced-motion: reduce) {
  .nav { transition: none; }
}

.brand {
  display: flex;
  align-items: center;
  gap: var(--space-8); /* glyph 16px + testo, ~8px nel canonico */
}
.brand__mark { width: 16px; height: 16px; }
.brand__text { width: 118px; height: 12px; }

.nav-main {
  display: none; /* mobile: nascosta */
  align-items: center;
  gap: var(--space-16);
}

.nav-menu-hook {
  display: inline-flex; /* mobile: visibile */
}

/* --- Menu mobile: drawer (handoff 09 §2 — canonico 246:376) -----------------
   Overlay full-screen su --surface, sotto la nav (il trigger "Menu"/"Chiudi"
   vive nello stesso slot). Voci title/36: inattive regular --text, attiva
   Semi Bold --accent-text (doppio canale peso+colore). Coda ancorata in fondo.
   Fade breve, rispetta prefers-reduced-motion. Solo mobile.
   -------------------------------------------------------------------------- */

.drawer {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  padding-top: 58px; /* slot nav (canonico: nav h58, menu-list pt64) */
  opacity: 0;
  transition: opacity var(--duration-fast) var(--ease-base);
}

.drawer.is-open { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .drawer { transition: none; }
}

.drawer__nav {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-32);
  padding: var(--space-64) var(--space-24) 0;
}

.drawer__link {
  font-family: var(--font-content);
  font-weight: var(--weight-regular); /* title/36-regular */
  font-size: var(--size-36);
  line-height: var(--leading-40);
  color: var(--text);
}

.drawer__link[aria-current="page"] {
  font-weight: var(--weight-semibold); /* title/36 + accent: doppio canale */
  color: var(--accent-text);
}

.drawer__tail {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
  margin-top: auto; /* coda ancorata in fondo */
  padding: 0 var(--space-24) var(--space-32);
  font-family: var(--font-ui);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text-muted);
}

/* scroll-lock quando il drawer è aperto: position fixed = lock vero anche su
   iOS (overflow hidden da solo non blocca il touch scroll). Il top negativo
   che conserva la posizione è inline, gestito da main.js. */
body.drawer-open {
  overflow: hidden;
  position: fixed;
  left: 0;
  right: 0;
  width: 100%;
}

@media (min-width: 768px) {
  .drawer { display: none; }
}

/* --- Footer ---------------------------------------------------------------
   Hairline = border-top (mai LINE/rect, §2). 4 voci su riga singola anche a
   ~342px; flex-wrap come paracadute (§5).
   -------------------------------------------------------------------------- */

.footer {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
  padding-bottom: var(--space-48);
}

/* hairline dentro il margine del container (canonico: 1232px a x=104) */
.footer::before {
  content: "";
  display: block;
  border-top: 1px solid var(--text);
}

.footer-links {
  display: flex;
  flex-wrap: wrap; /* paracadute: le 4 voci devono stare su una riga */
}

.footer .disclaimer,
.footer .colophon-line {
  font-family: var(--font-ui);
  font-weight: var(--weight-regular);
  font-size: var(--size-14);
  line-height: var(--leading-14);
  color: var(--text-muted);
}

/* --- Radar hero -----------------------------------------------------------
   Contenitore hook: il render è SEMPRE di radar.js (§6), mai SVG statici.
   Taratura (rotazione/opacità/misure) via config nel passo 4 — qui solo
   posizionamento da canonico. Mobile: versione ridotta, solo cornice incisa
   (poligono e dot hidden nel canonico — scelta intenzionale).
   -------------------------------------------------------------------------- */

.radar-hero {
  position: absolute;
  pointer-events: none; /* §6 */
  z-index: 0;
  display: flex;
  align-items: center;
  justify-content: center; /* l'SVG (430 mobile) centrato nel wrapper 513 */
  /* mobile (canonico 167:625): 513px, ruotato -75°, sborda alto-dx */
  width: 513px;
  height: 513px;
  top: -93px;
  left: 180px;
  transform: rotate(-75deg);
}

/* contenuto sopra il radar (che resta assoluto, z0). NB: la specificità del
   selettore è (0,1,0) per via di .page — NON zero: :where() azzera solo il
   proprio argomento. La nav va esclusa qui, altrimenti questo `relative`
   (più tardi nel file) batterebbe il suo `sticky` a pari specificità.
   Anche MAIN è escluso: niente z-index = niente stacking context, così le
   sue sezioni partecipano direttamente al contesto di .page e il segnale
   del radar (z2) si inserisce TRA l'hero (z1) e le card (z3). */
.page > :where(:not(.radar-hero, .drawer, .nav, main)) { position: relative; z-index: 1; }

.page main > * { position: relative; z-index: 1; }
.page main > .tools { z-index: 3; } /* le card sopra il segnale del radar (deciso 2026-07-17) */

/* layer segnale del radar (creato da radar.js, solo hero desktop): poligono
   e vertici SOPRA il contenuto (z1) — la profondità della spec radar.
   Stessa scatola di .radar-hero, che gli passa il posizionamento. */
.radar-hero--signal { z-index: 2; }

/* la nav resta sopra il drawer aperto (trigger sempre raggiungibile) */
.page > .nav { z-index: 50; }

/* --- Costruzione pagina ------------------------------------------------------
   Entrance una-tantum al load: fade + risalita 8px dei blocchi di main,
   stagger 60ms. Puro CSS (keyframes, fill backwards: durante il delay il
   blocco resta al frame iniziale). Nav, footer e radar-hero esclusi: la
   cornice appare subito, il contenuto si costruisce. Sui .textpage animano
   i figli (head → prose), non il contenitore: niente doppia animazione.
   prefers-reduced-motion: solo fade, nessun movimento.
   -------------------------------------------------------------------------- */

@keyframes rise-in {
  from { opacity: 0; transform: translateY(8px); }
}

@keyframes fade-in {
  from { opacity: 0; }
}

main > :not(.textpage),
.textpage > * {
  animation: rise-in var(--duration-slow) var(--ease-out) backwards;
}

main > :nth-child(2):not(.textpage),
.textpage > :nth-child(2) {
  animation-delay: 60ms;
}

main > :nth-child(3):not(.textpage) {
  animation-delay: 120ms;
}

@media (prefers-reduced-motion: reduce) {
  main > :not(.textpage),
  .textpage > * {
    animation-name: fade-in;
    animation-duration: var(--duration-base);
  }
}

/* ==========================================================================
   Desktop (canonico 1440) — breakpoint unico
   ========================================================================== */

@media (min-width: 768px) {

  .container { padding-inline: var(--space-104); }

  .nav { padding-top: 30px; } /* canonico 76:2048 */

  .nav-main { display: flex; }
  .nav .nav-menu-hook { display: none; } /* specificità > .link (components.css) */

  .footer { padding-bottom: 102px; } /* canonico 76:2103 */
  .footer .disclaimer { max-width: 608px; }

  .radar-hero {
    /* posizione B (spec radar 2026-07-17, da _radar-lab.html): più grande e
       centrale, sfiora la colonna testo, sborda a destra. Il canonico Figma
       (76:2021: 843/−72/right 24) è da riallineare a scelte confermate. */
    width: 960px;
    height: 960px;
    top: 20px; /* −40 + 60: con l'header pieno il taglio d'angolo era brutto */
    left: auto;
    right: -140px;
    transform: none;
  }
}
