/* components.css — componenti di sezione e chrome del verticale clinical_center.
   Tesi: struttura accreditata, l'INFORMAZIONE è il servizio. Il carattere lo danno i PANNELLI e i
   BLOCCHI PIENI (petrolio/ciano), NON la fotografia: questi clienti non hanno foto proprie (il
   materiale è il dump del sito vecchio, in buona parte stock) → tutto regge anche a foto zero.
   I colori arrivano da tokens.css: qui non si dichiarano valori. */

/* ============================ Chrome: header ============================ */
/* Header fisso "a vetro". ⚠ backdrop-filter crea un containing-block per il position:fixed → l'overlay
   del menu mobile va forzato a 100vh (vedi .is-menu-open in fondo), altrimenti si confina all'header. */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: var(--border);
}
/* Il wrapper WP del template-part limiterebbe lo sticky: display:contents lo toglie di mezzo. */
.wp-block-template-part { display: contents; }

/* Riga header CENTRATA verticalmente: align-items:center + azzeramento dei margini di blocco WP,
   che spingerebbero nav e CTA sotto il centro. */
.site-header__row {
  display: flex; align-items: center; gap: var(--space-5);
  min-height: 76px; padding-block: var(--space-3);
}
.site-header__row > * { align-self: center; margin-block: 0; }

/* Wordmark: il marchio di questi clienti è tipografico (il nome in ciano + la riga descrittrice sopra).
   ⚠ `.wordmark small` è CONDIVISO header/footer: sul footer scuro --ink-muted sarebbe illeggibile
   (vedi la correzione in fondo, sezione footer). */
.wordmark { font-family: var(--font-display); font-weight: 700; font-size: 1.4rem; line-height: 1; display: flex; align-items: center; gap: var(--space-3); color: var(--accent-deco); }
.wordmark small { display: block; font-family: var(--font-body); font-weight: 500; font-size: var(--text-sm); letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--ink-muted); margin-top: .25rem; }
.wordmark--logo .wordmark__mark { flex: none; }
.wordmark__txt { display: block; }
/* Il marchio di questi clienti è un WORDMARK LARGO: sostituisce mark+testo invece di affiancarli.
   ⚠ Nel file del cliente i quattro elementi (badge ISO, numero di certificato, riga descrittrice, nome)
   sono IMPILATI in 245px: portati all'altezza di un header, il nome scende a ~9px e la riga a ~3px — è
   fisica, nessuna resa la salva. Il marchio è quindi ricomposto in ORIZZONTALE (badge | nome): stessa
   identità, ma il nome sta a 29px e il badge resta leggibile, senza alzare di un pixel l'header.
   Altezza fissa, larghezza intrinseca; su mobile scende, non si comprime. */
.wordmark--logo { gap: 0; }
.wordmark__logo { height: 46px; width: auto; flex: 0 0 auto; display: block; align-self: center; }
/* Il marchio ricomposto è largo (ratio ~6.9): sotto i 900px scende, o mangia la riga della nav. */
@media (max-width: 900px) { .wordmark__logo { height: 38px; } }
@media (max-width: 560px) { .wordmark__logo { height: 32px; } }

.site-nav { margin-left: auto; }
.site-nav a { font-size: .95rem; white-space: nowrap; }   /* le voci non vanno a capo: una voce spezzata legge male */
.site-nav a:hover { color: var(--accent-text); }

/* Sotto-menu DESKTOP: il default WP è una card bianca squadrata, estranea al resto. Qui è un pannello
   petrolio col filo ciano in testa — lo stesso segno dei pannelli dell'hero.
   ⚠ SPECIFICITÀ: WP dichiara `.wp-block-navigation .wp-block-navigation__submenu-container{background-color:#fff;border:1px solid rgba(0,0,0,.15)}` — stesso peso (0,2,0) del selettore `.site-nav …`, ma il CSS dei
   blocchi è iniettato DOPO il tema, quindi a parità vince WP e il pannello resta BIANCO. Serve un livello
   in più (`.site-header .site-nav …`). Stessa trappola del bottone header e dell'overlay del menu. */
.site-header .site-nav .wp-block-navigation__submenu-container {
  background: var(--brand);
  border: none; border-top: 2px solid var(--accent-lt);   /* sul petrolio il filo è --accent-lt: il ciano del marchio fa 2.4:1 */
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding-block: var(--space-3);
  min-width: 16rem;
}
.site-header .site-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
  color: var(--on-dark); padding: var(--space-3) var(--space-5); width: 100%;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.site-header .site-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover {
  background: color-mix(in srgb, var(--on-dark) 10%, transparent); color: var(--accent-lt);
}
.site-header__tel { font-weight: 600; white-space: nowrap; }
.site-header__cta { white-space: nowrap; }
/* Su mobile telefono e CTA escono dall'header (che ha già logo + hamburger) e lo fanno sbordare in
   orizzontale: li porta la .cta-bar fissa in basso, quindi qui sono ridondanti.
   ⚠ Selettore discendente NON per vezzo: `.site-header__cta` e `.btn` hanno la stessa specificità e
   `.btn{display:inline-flex}` è dichiarato DOPO — la media query non aggiunge specificità, quindi una
   regola piatta qui verrebbe sovrascritta e il bottone resterebbe visibile (sbordando). */
@media (max-width: 900px) {
  .site-header .site-header__tel, .site-header .site-header__cta { display: none; }
}

/* ============================ Bottoni ============================ */
/* ⚠ CONTRATTO a11y: il CTA pieno sta su --accent-text (ciano SCURITO, bianco 6.6:1).
   MAI bianco sul ciano del marchio --accent-deco (4.3:1 = solo large/UI). */
.btn {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: var(--space-3) var(--space-5);
  font-family: var(--font-body); font-weight: 600; font-size: .95rem;
  border-radius: var(--radius-pill); border: 1px solid transparent;
  padding-inline: var(--space-6);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease), border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.btn--accent { background: var(--accent-text); color: var(--on-dark); box-shadow: var(--shadow-sm); }
.btn--accent:hover { background: var(--night); box-shadow: var(--shadow-md); }
.btn--ghost { border-color: var(--accent-text); color: var(--accent-text); background: transparent; }
.btn--ghost:hover { background: var(--accent-text); color: var(--on-dark); }
/* Ghost su banda scura: il bordo eredita --on-dark, l'hover inverte. */
.btn--on-dark { border-color: var(--on-dark); color: var(--on-dark); background: transparent; }
.btn--on-dark:hover { background: var(--on-dark); color: var(--brand); }

/* ============================ Hero: foto velata + pannelli ============================ */
/* Il riferimento (BeClinic2) è una foto full-bleed col velo blu e il display grosso; da BeClinic arriva
   il dispositivo dei PANNELLI che scavalcano la foto. Insieme risolvono il problema di questi clienti:
   la foto (stock, senza volti) arretra a SFONDO e l'informazione comanda.
   ⚠ overflow:visible + z-index: i pannelli devono poter uscire dal bordo inferiore della banda. */
/* La foto TIENE il campo: è alta quanto quasi tutta la finestra e contiene tutto — testo e pannelli — con
   ancora immagine sotto di loro. È il dispositivo del riferimento (BeClinic2 apre a piena viewport) e la
   ragione per cui il cliente chiede «le foto in prima pagina»: qui la fotografia non fa da sfondo, apre. */
.hero { position: relative; isolation: isolate; background: var(--brand); color: var(--on-dark);
  overflow: visible; min-height: clamp(620px, 86vh, 880px); display: flex; align-items: center; }
.hero__media { position: absolute; inset: 0; z-index: -2; overflow: hidden; }
.hero__media img { width: 100%; height: 100%; object-fit: cover; }
/* Velo petrolio: unifica la banda e stacca i pannelli. ⚠ Resta LEGGERO e non arriva mai a coprire: il
   testo NON dipende da lui (sta in un pannello pieno), quindi il velo deve solo dare unità — un velo che
   chiude a tinta piena cancella la foto, ed era ciò che rendeva questa banda un rettangolo colorato. */
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--brand) calc(var(--hero-scrim) * 34%), transparent) 0%,
    color-mix(in srgb, var(--brand) calc(var(--hero-scrim) * 52%), transparent) 55%,
    color-mix(in srgb, var(--brand) calc(var(--hero-scrim) * 72%), transparent) 100%);
}
/* Senza foto (variante design-only) la banda resta petrolio pieno: l'hero regge PER COSTRUZIONE. */
/* Il padding sotto è quello che lascia vedere la foto OLTRE i pannelli: senza, le tessere finirebbero sul
   bordo dell'immagine e sembrerebbero appese. */
.hero__inner { width: 100%; padding-block: clamp(3rem, 2rem + 5vw, 5rem); }
/* ⚠⚠ Il testo dell'hero sta in un PANNELLO PIENO, non sulla foto. MISURATO sui pixel veri: con il solo
   velo il bianco faceva 2.9:1 sull'eyebrow e 2.9:1 sull'h1 (sotto la soglia large-text) — la foto di
   questi clienti è stock e chiara, e il contrasto finirebbe per dipendere dal fotogramma. Sul petrolio
   pieno il bianco fa 10.3:1 sempre. È anche il dispositivo dei due riferimenti (il box dell'hero nel sito
   attuale del cliente; i pannelli sopra la foto di BeClinic). */
/* ⚠ Larghezza MISURATA sulla copy reale: il titolo di questi clienti è lungo (58 caratteri: "Laboratorio
   analisi cliniche e poliambulatorio convenzionato") e a 52rem andava a 4 righe. A 62rem sta in 3 righe
   ANCHE col display cresciuto a 4rem. La misura si prende sul testo vero, mai sulla copy corta del demo. */
.hero__text { position: relative; z-index: 2; max-width: 62rem; }
/* Il pannello serve SOLO quando c'è la foto sotto: nella variante design-only la banda è già petrolio
   pieno e un riquadro dello stesso colore sarebbe un bordo senza ragione. */
.hero:has(.hero__media) .hero__text {
  background: var(--brand); color: var(--on-dark);
  padding: clamp(1.75rem, 1.1rem + 2.6vw, 3rem);
  border-radius: var(--radius-lg); border-top: 3px solid var(--accent-lt);
  box-shadow: var(--shadow-md);
}
/* ⚠ NIENTE max-width di lettura sul DISPLAY: la misura (~46ch) vale per la LEAD — uno strozzamento sul
   contenitore del titolo lo manda a righe in più (lezione ripetuta 5 volte: statement DeMartini, titolo
   del form, titoli di sezione, hero Le Parisien, e questo). È la larghezza del PANNELLO a governare l'h1. */
.hero .lead { color: var(--on-dark); max-width: 46ch; margin-top: var(--space-4); }
/* L'eyebrow è una riga di orientamento: non deve andare a capo strappando il nome delle località. */
.hero .eyebrow { flex-wrap: wrap; }
.hero__cta { margin-top: var(--space-6); display: flex; gap: var(--space-4); flex-wrap: wrap; }

/* I 3 pannelli stanno DENTRO la foto, non sul suo bordo: sono la prima informazione utile del sito
   (accreditamento, come si prenota, dove si ritira il referto) e la foto continua sotto di loro — è ciò
   che li fa leggere come parte dell'immagine invece che come una riga di tessere appoggiate al limite. */
/* ⚠ Il BFC serve comunque: senza, i margini dei pannelli collasserebbero attraverso .hero__inner (e
   `.wp-block-post-content > *{margin-block:0}` li azzererebbe del tutto). */
.hero__inner { display: flow-root; }
.hero__panels {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--tile-gap);
  margin-top: clamp(2.5rem, 1.5rem + 4vw, 4rem);
  position: relative; z-index: 2;
}
.panel { padding: var(--space-6); border-radius: var(--radius-lg); box-shadow: var(--shadow-md); }
.panel h3 { font-size: 1.05rem; }
.panel p, .panel li { font-size: .92rem; line-height: 1.5; margin-top: var(--space-2); }
.panel--brand { background: var(--night); color: var(--on-dark); border-top: 3px solid var(--accent-lt); }
.panel--brand .panel__meta { color: var(--muted-on-dark); }
/* ⚠ Campitura ciano CHIARA, non il ciano di marca: #0083AC non regge NESSUN testo normale (ink 3.7:1,
   bianco 4.3:1 — solo l'accostamento col nero puro passerebbe, ed è fuori palette). Su --accent-lt il
   testo --ink fa 8.1:1. Il ciano di marca resta dov'è lecito: filetti, bordi, bollini (non-testo, 3:1). */
.panel--accent { background: var(--accent-lt); color: var(--ink); }
.panel--accent a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
/* Sul ciano chiaro il secondario --ink-muted scende a 3.1:1: qui il testo minore resta --ink. */
.panel--accent .panel__meta { color: var(--ink); }
.panel--paper { background: var(--paper); color: var(--ink); border-top: 3px solid var(--accent-deco); }
.panel--paper a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 3px; }
.panel__meta { font-size: var(--text-sm); color: var(--ink-muted); }
@media (max-width: 900px) { .hero__panels { grid-template-columns: 1fr; margin-bottom: calc(var(--space-7) * -1); } }
/* La sezione dopo l'hero deve lasciare spazio ai pannelli che sporgono. */
/* I pannelli stanno dentro la banda dell'hero, quindi la sezione che segue non deve più far loro spazio:
   il ritmo verticale del sito è quello di --section-y, e un'eccezione qui si legge come uno strappo. */

/* ============================ Esami in evidenza (services) ============================ */
/* Mosaico di tessere CON GUTTER (mai a contatto). Due tessere sono PIENE di colore: è il carattere che
   non chiede nulla alle foto — se il cliente non ne manda mai, la sezione regge lo stesso.
   Sfalsato per colonna: la griglia piatta è il segno "templatoso" (lo dice la nota di categoria). */
.exams { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--tile-gap); }
@media (max-width: 900px) { .exams { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .exams { grid-template-columns: 1fr; } }
/* Griglia ALLINEATA: la sfalsatura per colonna dava un ritmo inquieto su una pagina che deve essere
   ordinata e clinica — qui il carattere lo portano le campiture, non lo scarto verticale. */
.exam {
  position: relative; display: flex; flex-direction: column;
  background: var(--paper); border: 1px solid transparent; border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden; min-height: 15rem;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.exam:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.exam__body { padding: var(--space-6) var(--space-5); display: flex; flex-direction: column; gap: var(--space-3); flex: 1; }
/* L'icona è una MASCHERA, non un <img>: così eredita `currentColor` e cambia da sé sulle tessere piene
   (bianca sul petrolio, inchiostro sul ciano chiaro). Con un <img> il colore sarebbe cotto nel file.
   Il disegno arriva dallo slug `icon` dichiarato PER-ITEM nell'IR → l'icona segue il contenuto, non la
   posizione: un secondo centro clinico con esami diversi dichiara i suoi slug e le icone restano giuste.
   ⚠ aria-hidden: il nome dell'esame è nell'h3 accanto, l'icona non aggiunge informazione. */
/* ⚠ La `mask-image` sta nello STYLE INLINE del pattern, non in una custom property: un url() dentro una
   custom property si risolve rispetto al FOGLIO DI STILE che la usa (qui `css/`), non al documento —
   le icone venivano cercate in css/img/icons/ e la maschera restava vuota. Qui restano forma e colore. */
.exam__ico {
  width: 44px; height: 44px; flex: none;
  background: currentColor; color: var(--accent-deco);
  -webkit-mask-size: contain; -webkit-mask-position: center; -webkit-mask-repeat: no-repeat;
  mask-size: contain; mask-position: center; mask-repeat: no-repeat;
  transition: transform var(--dur) var(--ease);
}
/* ⚠⚠ La maschera sta QUI, non in uno style inline sul pattern. Queste tessere vivono nel post_content del
   DB, dove `../assets/…` NON viene riscritto (l'emitter inietta get_theme_file_uri solo nei .php del tema:
   nel DB il PHP non gira) e resta un path relativo al DOCUMENTO, che non esiste → icone invisibili, e
   nessun gate se ne accorge perché il FILE c'è: manca solo l'URL che lo raggiunge.
   Dal foglio di stile invece l'url() si risolve rispetto al FOGLIO (theme/css/) → ../assets/… è esatto.
   Il nome dell'icona arriva dall'IR via data-icon, quindi l'icona segue sempre il CONTENUTO dell'esame. */
.exam__ico[data-icon="petri"] { -webkit-mask-image: url("../assets/img/icons/petri.svg"); mask-image: url("../assets/img/icons/petri.svg"); }
.exam__ico[data-icon="antibody"] { -webkit-mask-image: url("../assets/img/icons/antibody.svg"); mask-image: url("../assets/img/icons/antibody.svg"); }
.exam__ico[data-icon="breath"] { -webkit-mask-image: url("../assets/img/icons/breath.svg"); mask-image: url("../assets/img/icons/breath.svg"); }
.exam__ico[data-icon="sleep"] { -webkit-mask-image: url("../assets/img/icons/sleep.svg"); mask-image: url("../assets/img/icons/sleep.svg"); }
.exam__ico[data-icon="sperm"] { -webkit-mask-image: url("../assets/img/icons/sperm.svg"); mask-image: url("../assets/img/icons/sperm.svg"); }
.exam__ico[data-icon="shield-cell"] { -webkit-mask-image: url("../assets/img/icons/shield-cell.svg"); mask-image: url("../assets/img/icons/shield-cell.svg"); }
.exam:hover .exam__ico { transform: translateY(-2px) scale(1.06); }
/* Sulle tessere piene l'icona prende il colore del testo della tessera (contratto palette). */
.exam--filled-ink .exam__ico { color: var(--accent-lt); }
.exam--filled-accent .exam__ico, .exam--filled-tint .exam__ico { color: var(--accent-text); }
.exam__body p { font-size: .92rem; line-height: 1.5; color: var(--ink-muted); }
/* Il link copre la tessera: si va DIRITTO alla pagina dell'esame, mai a un hub intermedio (regola 12). */
.exam__link { position: absolute; inset: 0; z-index: 1; }
.exam__link span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
/* Tessere piene: 2ª petrolio SCURA, 5ª ciano CHIARA. La coppia scuro/chiaro (5.25:1 fra loro) è ciò che
   fa leggere il mosaico; due campiture scure si appiattirebbero l'una sull'altra (1.6:1).
   ⚠ La tessera chiara NON è il ciano di marca: #0083AC col testo --ink fa 3.7:1 (axe lo boccia). Su
   --accent-lt fa 8.1:1. E niente opacity sul testo: abbasserebbe il contrasto appena verificato. */
.exam--filled-ink { background: var(--brand); border-color: var(--brand); color: var(--on-dark); }
.exam--filled-ink .exam__body p { color: var(--muted-on-dark); }
.exam--filled-accent { background: var(--accent-lt); border-color: var(--accent-lt); color: var(--ink); }
.exam--filled-accent .exam__body p { color: var(--ink); }
/* Terza campitura, chiara: prende il posto di una tessera senza foto utilizzabile (es. una grafica del
   cliente col testo cotto dentro il pixel, che ripeterebbe il titolo e non sarebbe leggibile da nessuno). */
.exam--filled-tint { background: var(--surface); border-color: var(--surface); color: var(--ink); }
.exam--filled-tint .exam__body p { color: var(--ink-muted); }
/* Senza foto le tessere piene resterebbero mozze accanto alle card: il min-height le tiene in griglia. */


/* ============================ Concorsi (featured) ============================ */
/* Banda piena: è l'informazione che il cliente-tipo vuole gridare (un pubblico che la cerca per nome). */
/* Gradiente diagonale invece della campitura piatta: dà profondità alla banda senza aggiungere nulla da
   leggere. Il contrasto del testo resta calcolato sul capo PIÙ CHIARO del gradiente (--brand, 10.3:1). */
.callout { background: linear-gradient(135deg, var(--brand) 0%, var(--night) 62%); color: var(--on-dark);
  position: relative; overflow: visible; }
.callout__inner { display: grid; grid-template-columns: 1fr auto; gap: var(--space-6); align-items: center; }
@media (max-width: 900px) { .callout__inner { grid-template-columns: 1fr; } }
.callout h2 { max-width: 24ch; }
.callout p { color: var(--muted-on-dark); margin-top: var(--space-3); max-width: 52ch; }
/* La foto SCAVALCA la banda: entra nel colore e ne esce sopra e sotto. È la sovrapposizione a dare
   profondità — la foto qui è stock e da sola non direbbe nulla, ma rompere il bordo di una campitura sì.
   ⚠ Serve `overflow: visible` sulla banda, e la sporgenza deve stare dentro il padding delle sezioni
   confinanti: il grid non fa collassare i margini, quindi lo sbordo è esattamente quello dichiarato. */
/* ⚠ SPECIFICITÀ: WP dichiara `:root :where(.is-layout-flow) > * { margin-block: 24px 0 }` — pesa (0,1,0)
   come una classe piatta, ma è iniettato DOPO il tema, quindi a parità vince lui e lo sbordo inferiore
   spariva (la foto scavalcava solo di sopra). Serve un selettore discendente. */
/* ⚠ MISURATO, non stimato: perché la foto ESCA dalla banda servono DUE cose insieme, e mancava entrambe.
   (1) Il margine negativo deve superare il PADDING della banda (72px): a -64 la foto restava dentro di 8.
   (2) La foto deve essere più ALTA della banda, ma senza determinarne l'altezza — altrimenti la banda
   cresce con lei e lo sbordo resta zero per sempre. Il margine sottrae 2×128 all'altezza di layout, così
   la riga la decide il testo e i 600px della foto le escono davvero sopra e sotto. */
/* ⚠ Altezza DEFINITA, non un minimo: un'immagine in `height:100%` dentro un padre con solo `min-height`
   non ha una percentuale cui riferirsi e resta alta quanto vuole — la tessera si allungava e la foto
   restava una fascia in cima, col vuoto sotto. */
.callout .callout__media { width: clamp(12rem, 26vw, 20rem); height: 37.5rem;
  border-radius: var(--radius-lg); overflow: hidden;
  border: 2px solid var(--accent-lt); position: relative; z-index: 2;
  margin-block: calc(var(--space-8) * -2);
  box-shadow: 0 26px 52px rgba(0, 26, 45, .38); }
.callout .callout__media img { height: 100%; width: 100%; object-fit: cover; display: block; }
/* A una colonna la foto tornerebbe sotto il testo: lì lo sbordo non ha una banda da scavalcare. */
@media (max-width: 900px) {
  .callout .callout__media { margin-block: 0; width: 100%; height: auto; aspect-ratio: 16 / 9; }
  .callout__media img { aspect-ratio: 16 / 9; }
}

/* ============================ Come funziona (method) ============================ */
/* Il percorso del paziente: prenota → preparati → vieni → scarica il referto. È la sezione che rompe la
   colonna di rettangoli, ed è la prima domanda di chi arriva («come faccio?»).
   ⚠ Dispositivo DELIBERATAMENTE diverso dagli altri verticali della flotta: qui il numero è una
   FILIGRANA dietro il testo (non i bolli in cerchio di Pafundi né i numerali serif di Le Parisien) —
   stessa famiglia di idee, segno riconoscibile. */
.steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--tile-gap); counter-reset: step; }
@media (max-width: 1000px) { .steps { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .steps { grid-template-columns: 1fr; } }
.step {
  position: relative; overflow: hidden; isolation: isolate;
  padding: var(--space-6) var(--space-5) var(--space-6);
  background: var(--paper); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.step:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
/* Il numerale sta INTERO dentro la scheda: tagliarlo col bordo sembrava un incidente, non una scelta.
   È decoro, non testo — infatti è aria-hidden (l'ordine lo dà già la lista <ol>). */
.step__n {
  position: absolute; top: var(--space-4); right: var(--space-5); z-index: -1;
  font-family: var(--font-display); font-weight: 700; font-size: var(--text-num);
  line-height: .82; letter-spacing: -0.04em;
  color: var(--surface);
}
.step h3 { color: var(--accent-text); margin-bottom: var(--space-2); }
.step p { font-size: .95rem; color: var(--ink-muted); }
/* Filo che collega i passaggi: si spegne quando la griglia va a capo (a una colonna è una bugia). */
@media (min-width: 1001px) {
  .steps { position: relative; }
  .step::after {
    content: ""; position: absolute; top: var(--space-6); right: calc(var(--tile-gap) * -1 - 1px);
    width: var(--tile-gap); height: 2px; background: var(--accent-lt);
  }
  .step:last-child::after { display: none; }
}

/* ============================ Fiducia (trust) ============================ */
/* Intro sopra, numeri in FILA sotto: a 2x2 dentro una colonna stretta i numeri lunghi ("ISO 9001") si
   spezzavano e la fila perdeva forza. Su tutta la larghezza è la striscia di contatori del riferimento. */
.trust__grid { display: block; }
.trust__text { max-width: 48rem; margin-bottom: var(--space-8); }
/* I punti di fiducia sono NUMERI: è il dispositivo dei contatori di BeClinic, e qui i numeri esistono
   davvero (le sedi, le specializzazioni, gli esami, la certificazione). Un dato secco convince più di una
   frase, e non chiede nulla alla fotografia.
   ⚠ Il "numero" è il TITOLO dell'item nell'IR: niente campo nuovo nello schema chiuso. */
.trust__points { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--tile-gap); }
@media (max-width: 1000px) { .trust__points { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .trust__points { grid-template-columns: 1fr; } }
.trust__point {
  padding: var(--space-6) var(--space-5); background: var(--paper);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.trust__point:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }
.trust__point h3 {
  font-size: var(--text-stat); font-weight: 700; line-height: 1; white-space: nowrap;
  letter-spacing: var(--tracking-display); color: var(--accent-text);
  margin-bottom: var(--space-3);
}
.trust__point p { color: var(--ink-muted); font-size: .92rem; line-height: 1.45; }

/* ============================ Sedi (contact_details) ============================ */
/* Le due sedi affiancate, con gli ORARI in tabella VERA: nel materiale di questi clienti gli orari
   arrivano come immagini di tabelle Word — inaccessibili e invisibili a Google. Qui sono HTML. */
.sedi { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.5rem, 1rem + 3vw, 3rem); }
@media (max-width: 900px) { .sedi { grid-template-columns: 1fr; } }
.sede { background: var(--paper); border-top: 3px solid var(--accent-deco); border-radius: var(--radius-lg); padding: var(--space-6); box-shadow: var(--shadow-md); }
.sede h3 { color: var(--accent-text); }
.sede__addr { margin-top: var(--space-3); color: var(--ink-muted); font-size: .95rem; font-style: normal; }
.sede__addr a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 3px; }
.sede__badge { display: inline-block; margin-top: var(--space-3); padding: var(--space-1) var(--space-3); background: var(--surface); color: var(--accent-text); font-size: var(--text-sm); font-weight: 600; border-radius: var(--radius); }
/* Tabella orari: sobria, leggibile, e soprattutto TESTO (mai uno screenshot). */
.hours { width: 100%; border-collapse: collapse; margin-top: var(--space-5); font-size: .92rem; }
.hours caption { text-align: left; font-weight: 600; color: var(--ink); margin-bottom: var(--space-3); }
.hours th, .hours td { padding: var(--space-2) var(--space-3); text-align: left; border-bottom: 1px solid var(--line); }
.hours th { font-weight: 600; color: var(--ink); width: 38%; }
.hours td { color: var(--ink-muted); }
.hours tr:last-child th, .hours tr:last-child td { border-bottom: none; }
.hours .is-closed { color: var(--ink-muted); font-style: italic; }
/* Link mappa: zero-cookie sancito → niente embed Google (la CSP lo bloccherebbe), si apre Maps. */
.map-link { display: inline-flex; align-items: center; gap: var(--space-2); margin-top: var(--space-4); font-weight: 600; color: var(--accent-text); }
.map-link:hover { text-decoration: underline; text-underline-offset: 3px; }

/* ============================ Pagina contatti (modulo) ============================ */
/* Modulo a sinistra, sedi a destra. Le stesse classi le rende il form live [fp_contact_form] del mu-plugin:
   questo stile vale sia per il placeholder statico sia per il modulo vero. Senza queste regole gli input
   restano ai default del browser (label e campo in linea): il reset globale azzera i margini e non tocca
   input/textarea. ⚠ .sedi è a due colonne nella home: qui dentro .contact-info sta in colonna stretta → una sola. */
.contact-cols { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: clamp(var(--space-6), 5vw, var(--space-8)); align-items: start; }
@media (max-width: 900px) { .contact-cols { grid-template-columns: 1fr; gap: var(--space-7); } }
.contact-form-col > h2, .contact-info > h2 { margin-bottom: var(--space-5); }
.contact-info .sedi { grid-template-columns: 1fr; }

.contact-form { display: grid; gap: var(--space-5); }
.contact-form .row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }
@media (max-width: 520px) { .contact-form .row { grid-template-columns: 1fr; } }
.field { display: grid; gap: var(--space-2); }
.field label { font-size: var(--text-sm); font-weight: 600; letter-spacing: .04em; color: var(--ink); }
.field input, .field textarea { font: inherit; width: 100%; padding: var(--space-3) var(--space-4); color: var(--ink); background: var(--paper); border: var(--border); border-radius: var(--radius); }
.field textarea { resize: vertical; min-height: 8rem; }
.field input:focus, .field textarea:focus { outline: 2px solid var(--focus); outline-offset: 1px; border-color: var(--accent-text); }
.consent { display: flex; gap: var(--space-3); align-items: flex-start; font-size: .92rem; color: var(--ink-muted); }
.consent input { margin-top: .25em; flex: 0 0 auto; }
.consent a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 3px; }
.form-note { margin-top: var(--space-2); font-size: .92rem; color: var(--ink-muted); }
.form-note a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 3px; }

/* ============================ Banda contatti (contact_band) ============================ */
.contact-band { background: linear-gradient(135deg, var(--brand) 0%, var(--night) 100%); color: var(--on-dark); }
.contact-band__inner { display: grid; grid-template-columns: 1fr auto; gap: var(--space-6); align-items: center; }
@media (max-width: 900px) { .contact-band__inner { grid-template-columns: 1fr; } }
.contact-band .lead { color: var(--muted-on-dark); max-width: 52ch; margin-top: var(--space-3); }

/* ============================ Pagine interne ============================ */
/* ⚠ La page-head NON riusa la size dell'hero: è una testata, non un hero (occuperebbe mezza schermata).
   È CONDIVISA da tutte le pagine interne: si sistema una volta sola. Fondo = tint di marca, mai grigio. */
.page-head { background: var(--surface); padding-block: clamp(2.5rem, 1.5rem + 3vw, 4rem); }
/* ⚠ Il renderer dei download (condiviso) usa `container--narrow` nella testata: essendo centrato, il titolo
   finiva a 444px mentre il contenuto sotto parte da 176 — l'unica pagina sfalsata del sito. Qui il
   contenitore torna pieno e la misura di LETTURA passa al testo, dove deve stare (lezione ripetuta). */
.page-head .container--narrow { max-width: var(--container); }
.page-head .container--narrow > p { max-width: 60ch; }
.page-head h1 { font-size: var(--text-2xl); }
.page-head .lead { margin-top: var(--space-3); max-width: 60ch; color: var(--ink-muted); }
.prose { max-width: var(--container-narrow); }
.prose > * + * { margin-top: var(--space-4); }

/* Testo e fotografia sulla stessa riga: la foto sta ACCANTO a ciò che descrive, mai relegata in fondo —
   in fondo, con testi corti, apre un vuoto e non spiega più nulla. La colonna del testo tiene la sua
   misura di lettura, la foto prende quel che resta. Su schermo stretto la foto passa sopra il testo:
   apre la pagina invece di allontanare la risposta. */
.page-split { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, .7fr);
  gap: clamp(1.75rem, 1rem + 3vw, 3.5rem); align-items: start; }
.page-split > .prose { max-width: none; }
.page-figure { margin: 0; border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-sm);
  aspect-ratio: 4 / 3; background: var(--surface); }
.page-figure img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* ============================ Istruzioni al paziente (griglia) ============================ */
/* Una pagina di istruzioni è un ELENCO di casi, non un discorso: incolonnarli in una lista lunga costringe
   a scorrere per trovare il proprio, e una foto sola accanto a duemila pixel di prosa lascia mezza pagina
   vuota. Qui ogni caso è una scheda in due colonne, e le tessere fotografiche stanno DENTRO la griglia,
   accanto al caso che mostrano — la fotografia entra nel ritmo invece di stare a guardare da un lato.
   ⚠ Le schede si allungano alla riga (stretch di default): testi da 100 e da 700 battute convivono, e
   lasciarle ad altezza libera le farebbe leggere come sbagliate — è la lezione del mosaico. */
.info-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--tile-gap); }
/* ⚠ Contenuto CENTRATO nella scheda: le schede si allungano alla riga, ma i casi non hanno tutti la stessa
   lunghezza — un testo di due righe appoggiato in cima a una scheda alta lascia un vuoto sotto e la fa
   sembrare incompiuta. Centrato, la scheda corta respira e quella lunga riempie comunque (è la stessa
   ragione per cui i pannelli dell'hero centrano il loro testo). */
.info-card { display: flex; flex-direction: column; justify-content: center; padding: var(--space-6);
  background: var(--paper); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  border-top: 3px solid var(--accent-lt); }
.info-card h2 { font-size: 1.25rem; margin-bottom: var(--space-3); }
.info-card p { color: var(--ink-muted); font-size: .95rem; }
.info-card ul { margin-top: var(--space-3); }
/* La tessera fotografica: nella griglia come le schede, ma senza cornice — è l'immagine a parlare, e il
   filo ciano la lega alle schede accanto. */
.info-shot { margin: 0; overflow: hidden; border-radius: var(--radius-lg); box-shadow: var(--shadow-md);
  border: 2px solid var(--accent-lt); background: var(--surface); min-height: 15rem; }
.info-shot img { width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform var(--dur) var(--ease); }
.info-shot:hover img { transform: scale(1.04); }
@media (max-width: 860px) { .info-grid { grid-template-columns: 1fr; } .info-shot { min-height: 12rem; } }

/* Fascia sotto la testata: per le pagine che sono ELENCHI (niente prosa da affiancare), dove una tessera
   accanto al testo non avrebbe testo cui stare accanto. Bassa e larga: apre la pagina e non la ritarda. */
.page-band { margin: 0; overflow: hidden; aspect-ratio: 21 / 6; background: var(--surface); }
.page-band img { width: 100%; height: 100%; object-fit: cover; display: block; }
@media (max-width: 700px) { .page-band { aspect-ratio: 16 / 9; } }

/* Le due sedi si mostrano prima di dirsi: il laboratorio e il poliambulatorio sono due mestieri diversi
   sotto lo stesso nome, e questi clienti lo scrivono in maiuscolo perché nessuno se ne accorge. */
.sedi-shots { display: grid; grid-template-columns: 1fr 1fr; gap: var(--tile-gap); margin-bottom: var(--space-6); }
.sedi-shots figure { margin: 0; overflow: hidden; border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  aspect-ratio: 16 / 9; background: var(--surface); }
.sedi-shots img { width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform var(--dur) var(--ease); }
.sedi-shots figure:hover img { transform: scale(1.04); }
@media (max-width: 700px) { .sedi-shots { grid-template-columns: 1fr; } }

/* Fascia a tutta larghezza in chiusura di sezione: dà respiro tra due blocchi di testo e fa entrare la
   fotografia dove il racconto si ferma. Bassa: è una pausa, non un secondo hero.
   ⚠ 24/5 tagliava la foto a una feritoia (il 28% di un fotogramma alto 1067px): il soggetto spariva e
   restava una striscia illeggibile. A 21/6 se ne vede il 40% e la fascia si capisce ancora a colpo d'occhio. */
.strip { margin: var(--space-8) 0 0; overflow: hidden; aspect-ratio: 21 / 6; background: var(--surface); }
.strip img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* ⚠ La fascia CHIUDE la sezione: il padding inferiore le lascerebbe sotto una striscia di fondo pagina
   (120px di bianco), che si legge come uno stacco sbagliato e non come aria. */
.section:has(> .strip) { padding-bottom: 0; }
@media (max-width: 700px) { .strip { aspect-ratio: 16 / 9; margin-top: var(--space-6); } }

/* Il laboratorio in tre scatti. Righe a passo fisso e tessere che occupano più celle: l'asimmetria sta
   nella GRIGLIA, non in un disallineamento — tre riquadri uguali direbbero "provini", e tessere lasciate
   ad altezza libera con un offset addosso si leggono come sbaglio, non come ritmo.
   Le campate chiudono la griglia esatta (2+2 sopra, 2+2 sotto = 8 celle = 4 colonne x 2 righe): nessun buco. */
.lab-shots { display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: 11rem;
  gap: var(--tile-gap); margin-top: var(--space-6); }
.lab-shots figure { margin: 0; overflow: hidden; border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); background: var(--surface); }
.lab-shots img { width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform var(--dur) var(--ease); }
.lab-shots figure:hover img { transform: scale(1.04); }
.lab-shots figure:nth-child(1) { grid-column: span 2; grid-row: span 2; }
.lab-shots figure:nth-child(2) { grid-column: span 2; }
.lab-shots figure:nth-child(3) { grid-column: span 2; }
@media (max-width: 860px) {
  .lab-shots { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 10rem; }
  .lab-shots figure:nth-child(1) { grid-column: span 2; grid-row: span 1; }
}
@media (max-width: 520px) { .lab-shots { grid-template-columns: 1fr; grid-auto-rows: 13rem; }
  .lab-shots figure:nth-child(n) { grid-column: span 1; } }
@media (max-width: 860px) {
  .page-split { grid-template-columns: 1fr; }
  .page-split > .page-figure { order: -1; aspect-ratio: 16 / 9; }
}
.prose h2 { margin-top: var(--space-7); }
.prose h3 { margin-top: var(--space-6); }
.prose ul { display: grid; gap: var(--space-2); }
.prose li { position: relative; padding-left: var(--space-5); }
.prose li::before { content: ""; position: absolute; left: 0; top: .62em; width: .5rem; height: .5rem; background: var(--accent-deco); border-radius: 50%; }
.prose a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 3px; }
.section-intro { max-width: 48rem; margin-bottom: var(--space-8); }
.section-intro h2 { margin-top: var(--space-3); }
.section-intro .lead { margin-top: var(--space-3); color: var(--ink-muted); }

/* Elenco esami: è IL contenuto di questi clienti (liste lunghissime). A colonne, denso ma arioso. */
.exam-list { columns: 3 16rem; column-gap: var(--space-6); }
.exam-list li { break-inside: avoid; padding: var(--space-2) 0 var(--space-2) var(--space-5); position: relative; border-bottom: 1px solid var(--line); }
.exam-list li::before { content: ""; position: absolute; left: 0; top: 1em; width: .45rem; height: .45rem; background: var(--accent-deco); border-radius: 50%; }

/* ============================ Pagina download (linee guida / cataloghi) ============================ */
/* Il renderer dei download (apply/build-downloads.mjs) emette `.cat-row` > `.cat` > `.cat__name` +
   `.cat__dl`, con `.cat__media` SOLO se l'item dichiara una copertina. Un verticale che non stila queste
   classi ottiene un elenco nudo: qui sono schede coerenti col resto (raggio ampio, ombra morbida).
   ⚠ Per questi clienti sono DOCUMENTI clinici, non cataloghi da sfogliare: niente copertina, quindi la
   scheda è tipografica — il titolo comanda e il download è l'azione. */
.cat-row { display: grid; grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); gap: var(--tile-gap); margin-bottom: var(--space-8); }
.cat {
  display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-5); background: var(--paper);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  border-left: 3px solid var(--accent-deco);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.cat:hover { transform: translateY(-3px); box-shadow: var(--shadow-md);
  border-left-color: var(--accent-text); }
/* Il titolo della specialità siede su una banda al tint di marca, con la sua targa numerata: una pagina di
   sole schede bianche non dice a quale area appartiene ciò che si sta guardando, e queste sono dieci aree
   con novanta documenti. Il colore qui non decora: separa. */
.section h2 { position: relative; }
.cat-row + h2 { margin-top: var(--space-9); }
.section h2:has(+ .cat-row) {
  background: var(--surface); border-left: 4px solid var(--accent-deco);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: var(--space-4) var(--space-5); font-size: 1.35rem; color: var(--brand);
}
.cat__media { border-radius: var(--radius); overflow: hidden; background: var(--surface); }
.cat__media img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; }
.cat__name { font-family: var(--font-display); font-weight: 600; font-size: 1rem; line-height: 1.35; color: var(--ink); }
/* Il link di download è l'azione della scheda: accento, mai testo grigio da nota a piè di pagina. */
.cat__dl { margin-top: auto; font-weight: 600; font-size: .92rem; color: var(--accent-text); white-space: nowrap; }
.cat:hover .cat__dl { text-decoration: underline; text-underline-offset: 3px; }
/* Il titolo della collezione (h2) stacca le famiglie di documenti. */
.section h2 + .cat-row { margin-top: var(--space-5); }

/* ============================ Chrome: footer ============================ */
.site-footer { background: linear-gradient(180deg, var(--night) 0%, #00263E 100%); color: var(--on-dark); padding-block: var(--space-8) var(--space-6); }
/* 3 colonne nel demo, 4 sui progetti (la colonna "Prestazioni" è fenced fp:real): auto-fit invece di un
   conteggio fisso, così il footer non si rompe in nessuno dei due casi. */
/* Quattro blocchi sui progetti (marchio, prestazioni, sedi, contatti), tre sul demo (senza prestazioni).
   ⚠⚠ `1.5fr repeat(auto-fit, …)` era una regola INVALIDA — auto-fit non ammette una traccia flessibile
   davanti a sé — e il browser la SCARTAVA in blocco: il footer restava a UNA colonna, alto oltre 1000px,
   con tutto incolonnato. Una griglia che "non si applica" non lascia tracce: va letta nel DOM calcolato.
   auto-fit da solo è valido e collassa le tracce vuote, quindi regge tre blocchi come quattro. */
.site-footer__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: var(--space-7) var(--space-6); }
/* Il marchio tiene due campate: porta ragione sociale e P.IVA, che su una colonna sola andrebbero a capo. */
.site-footer__grid > :first-child { grid-column: span 2; }
@media (max-width: 900px) {
  .site-footer__grid { grid-template-columns: 1fr 1fr; gap: var(--space-6); }
  .site-footer__grid > :first-child { grid-column: span 2; }
}
@media (max-width: 560px) {
  .site-footer__grid { grid-template-columns: 1fr; }
  .site-footer__grid > :first-child { grid-column: span 1; }
}
.site-footer h3 { font-size: var(--text-sm); letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--accent-lt); margin-bottom: var(--space-4); font-family: var(--font-body); }
.site-footer a:hover { color: var(--accent-lt); }
.site-footer__links { display: grid; gap: var(--space-2); font-size: .92rem; }
/* ⚠ `justify-content:space-between` con 3 elementi NON centra il mediano: lo centra solo se i due esterni
   hanno la stessa larghezza (qui la ragione sociale è lunga e "Privacy" corta → il badge Dgitaly finiva
   scentrato di ~100px). Griglia 1fr auto 1fr: il centro è il centro. */
.site-footer__legal { margin-top: var(--space-7); padding-top: var(--space-5); border-top: 1px solid color-mix(in srgb, var(--on-dark) 18%, transparent); display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: var(--space-4); font-size: var(--text-sm); color: var(--muted-on-dark); }
.site-footer__legal > :last-child { justify-self: end; }
@media (max-width: 780px) { .site-footer__legal { grid-template-columns: 1fr; justify-items: center; text-align: center; } .site-footer__legal > :last-child { justify-self: center; } }
/* ⚠ `.wordmark small` è condiviso header/footer e porta --ink-muted (tarato sul fondo CHIARO): sul
   petrolio profondo fa 2.3:1. Un componente condiviso chiaro/scuro va SEMPRE ri-verificato sul dark. */
.site-footer .wordmark { color: var(--on-dark); }
.site-footer .wordmark small { color: var(--muted-on-dark); }
.site-footer__meta { font-size: .92rem; color: var(--muted-on-dark); margin-top: var(--space-4); display: grid; gap: var(--space-1); }
/* Powered by Dgitaly (regola 1): sta nella fence fp:real, quindi solo sui progetti. */
.dgitaly { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--muted-on-dark); white-space: nowrap; }
.dgitaly img { width: 20px; height: 20px; }

/* ============================ CTA bar mobile ============================ */
.cta-bar { display: none; }
@media (max-width: 900px) {
  .cta-bar {
    position: fixed; inset: auto 0 0 0; z-index: 40;
    display: grid; grid-template-columns: 1fr 1fr;
    background: var(--night); border-top: 1px solid color-mix(in srgb, var(--on-dark) 18%, transparent);
  }
  .cta-bar a { padding: var(--space-4); text-align: center; color: var(--on-dark); font-weight: 600; font-size: .95rem; }
  /* ⚠ SPECIFICITÀ: `.cta-bar a` pesa (0,1,1) e batte `.cta-bar__call` (0,1,0) QUALUNQUE sia l'ordine →
     il testo resterebbe bianco sul ciano chiaro (1.97:1). Serve un selettore di pari peso: `a.cta-bar__call`. */
  .cta-bar a.cta-bar__call { background: var(--accent-lt); color: var(--ink); }   /* ciano CHIARO: sul marchio #0083AC il testo farebbe 3.7:1 */
  body { padding-bottom: 56px; }
}

/* ============================ Menu mobile (overlay wp:navigation) ============================ */
/* ⚠ L'header ha backdrop-filter → containing-block per il fixed: senza questo, l'overlay si confina
   all'altezza dell'header (~76px) e il menu risulta "rotto". */
/* ⚠ SPECIFICITÀ: WP dichiara `.wp-block-navigation:not(.has-background) .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay){background-color:#fff}` (0,4,0). Una regola
   piatta sul container (0,2,0) NON vince e l'overlay resta BIANCO. Va ripreso lo stesso schema. */
.site-nav:not(.has-background) .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay),
.wp-block-navigation__responsive-container.is-menu-open {
  height: 100vh; max-height: 100vh; overflow-y: auto; -webkit-overflow-scrolling: touch;
  background: var(--brand); color: var(--on-dark);
}
/* Le voci vanno a SINISTRA: `justifyContent:right` (desktop) in colonna diventa align-items:flex-end.
   ⚠ Va messo su TUTTA la catena, non solo sul `__container`: è il PADRE
   `__responsive-container-content` (largo quanto il viewport) che, restando flex-end, spinge a destra
   il blocco delle voci — correggere il solo figlio non sposta nulla. */
.site-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content,
.site-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container,
.site-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item,
.site-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container {
  align-items: flex-start; justify-content: flex-start;
}
/* Aria a sinistra: le voci non devono toccare il bordo dello schermo. */
.site-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content { padding-left: var(--gutter); }
/* La X di chiusura: il default è sottile e incollata all'angolo. Più marcata (stroke sul path, che WP
   disegna in solo fill) e con aria sopra e di lato — l'area di tocco cresce con lei. */
.site-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-close {
  top: var(--space-4); right: var(--space-4);
  padding: var(--space-3); color: var(--on-dark);
  border-radius: var(--radius);
}
.site-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-close:hover { background: color-mix(in srgb, var(--on-dark) 12%, transparent); }
.site-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-close svg {
  width: 28px; height: 28px;
  stroke: currentColor; stroke-width: 1.4;   /* l'icona WP è solo `fill`: lo stroke la ingrossa */
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container { align-items: flex-start; }
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item { width: 100%; }
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content { width: 100%; text-align: left; }
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container .wp-block-navigation-item { width: 100%; }
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-icon { margin-left: auto; }
/* L'ultima voce non deve finire sotto la cta-bar fissa. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content { padding-bottom: 96px; }
/* I sotto-menu su mobile stanno INLINE, non come card-dropdown desktop. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container {
  position: static !important; border: none !important; box-shadow: none !important; background: none !important; padding-left: var(--space-5);
}

/* ============================ Scroll-reveal (micro-JS IntersectionObserver) ============================ */
/* Fail-visible: senza JS (.js assente) il contenuto è già visibile. reduced-motion rivela tutto.
   ⚠ MAI mettere `.reveal` su un contenitore di IMMAGINI (es. la griglia `.exams`): con `opacity:0` il browser
   NON scarica le img che contiene — né lazy né eager — finché l'osservatore non lo rivela. Risultato: gallerie
   che restano vuote finché non si scrolla fin lì. Il reveal sta sui blocchi di TESTO (intro, punti, sedi). */
/* ⚠⚠ Il reveal MUOVE, non sfuma. Un'opacità intermedia COMPONE il testo col fondo, e i testi --ink-muted
   stanno a 4.6 sul chiaro: appena sopra la soglia AA. Durante la dissolvenza scendono sotto (misurato
   4.31 su un .trust__point) per tutti i 620ms — un testo non deve MAI attraversare la soglia, nemmeno
   per mezzo secondo. Col solo transform il problema non esiste, e nemmeno l'altro: un elemento a
   opacity:0 non fa scaricare le immagini che contiene, e qui dentro ci sono mosaici e fasce. */
.js .reveal { opacity: 1; transform: translateY(24px); }
/* Rete di sicurezza: una griglia foto non deve mai restare invisibile, nemmeno se qualcuno le rimette .reveal. */
.js .exams, .js .exams.reveal { opacity: 1; transform: none; }
.js .reveal.is-visible { transform: none; transition: transform 620ms var(--ease); transition-delay: calc(var(--reveal-i, 0) * 90ms); }
@media (prefers-reduced-motion: reduce) { .js .reveal { transform: none; } }
