:root {
  --brand-blue: #145ba6;
  --navy: #0d3f74;
  --navy-2: #145ba6;
  --ink: #13243a;
  --muted: #5b6978;
  --teal: #5dbfc1;
  --teal-dark: #267676;
  --green-teal: #00b09e;
  --teal-pale: #e2f5f4;
  --blue-pale: #edf7fa;
  --sand: #f1f9fc;
  --paper: #f8fafb;
  --white: #fff;
  --line: #dbe4e9;
  --danger-pale: #fff3de;
  --shadow: 0 24px 80px rgb(7 25 45 / .12);
  --shadow-soft: 0 12px 36px rgb(7 25 45 / .08);
  --radius-sm: .75rem;
  --radius: 1.25rem;
  --radius-lg: 2rem;
  --shell: 74rem;
  --font: "Avenir Next", "Segoe UI", Helvetica, Arial, sans-serif;
  /* A1 — R3. `--ease` è la curva unica del sito (entrata decisa, uscita lunga);
     `--navy-deep` e `--darkroom` riducono cinque blu scuri a due e quattro neri a uno;
     `--hero-sky` è il cielo unico dei cinque hero. `interpolate-size` abilita
     l'interpolazione di `auto` (F1, apertura morbida delle FAQ): dove non è supportata
     l'apertura resta istantanea come oggi. */
  --ease: cubic-bezier(.22,.61,.36,1);
  --navy-deep: #092b4d;
  --darkroom: #071925;
  --hero-sky: linear-gradient(145deg, #f8fafb, #eef4fa);
  interpolate-size: allow-keywords;
}

*, *::before, *::after { box-sizing: border-box; }
/* 2026-08-06, rilievo owner sull'ancora #come-si-paga: 7rem (112px) lasciavano 21px di banda
   della sezione precedente sotto l'header sticky (91px). Atterraggio a filo: 91px esatti,
   per TUTTE le ancore del sito. */
/* 2026-08-06, difetto owner sul Pixel: senza dichiarazione, l'auto-dark di Chromium/Brave
   Android scurisce un sito progettato solo chiaro. `only light` e' l'opt-out standard. */
html { scroll-behavior: smooth; scroll-padding-top: 91px; color-scheme: only light; }
body { margin: 0; color: var(--ink); background: var(--paper); font-family: var(--font); font-size: 1.075rem; line-height: 1.67; -webkit-font-smoothing: antialiased; }
body[data-nav-open] { overflow: hidden; }
img { display: block; width: 100%; height: auto; }
a { color: inherit; }
button, summary { font: inherit; }
h1, h2, h3, p { margin-top: 0; }
/* C1 — l'interlinea 1.08 è del titolone: applicata anche agli H3 (corpo ~1.2rem) li stringeva
   fino a far toccare le righe. Ora H1/H2 tengono 1.08 e H3 va a 1.3; colore e tracking
   restano nel gruppo, che è la ragione per cui il gruppo esiste.
   C3 — `balance` sui titoli e `pretty` sui paragrafi: nessuna parola orfana in ultima riga.
   Dove non è supportato la resa resta quella di oggi: è un miglioramento, non un requisito. */
h1, h2, h3 { color: var(--navy); letter-spacing: -.015em; text-wrap: balance; }
h1, h2 { line-height: 1.08; }
h3 { line-height: 1.3; }
/* C2 — a corpo 3.6rem il tracking di gruppo resta largo: l'H1 chiude a -.022em. */
h1 { max-width: 26ch; margin-bottom: 1.5rem; font-size: clamp(2.2rem, 4.6vw, 3.6rem); font-weight: 640; letter-spacing: -.022em; }
h2 { max-width: 20ch; margin-bottom: 1.25rem; font-size: clamp(1.9rem, 3.6vw, 2.8rem); font-weight: 620; }
h3 { margin-bottom: .65rem; font-size: clamp(1.18rem, 2vw, 1.5rem); font-weight: 650; }
p { margin-bottom: 1rem; text-wrap: pretty; }
/* C4 — cifre tabellari dove i numeri sono dati e non prosa: telefoni, P.IVA, numeri di
   autorizzazione, indici e contatori. Le cifre prendono tutte la stessa larghezza, quindi le
   colonne di numeri smettono di ballare fra una riga e l'altra. */
.hero-actions .button, .mobile-contact-bar a, .footer-legal-details dd, .footer-list a, .identity-facts li, .anatomy-index, .path-number, .steps-grid li > span, .implant-part-number, .price-checklist li > span, .result-title > span { font-variant-numeric: tabular-nums lining-nums; }
address { font-style: normal; }
svg { width: 1.15em; height: 1.15em; fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.8; }
:focus-visible { outline: 3px solid var(--navy); outline-offset: 4px; border-radius: .2rem; }
.trust-strip :focus-visible, .answer-block :focus-visible, .boundaries :focus-visible, .no-amounts :focus-visible, .contact-panel :focus-visible, .procedure-video :focus-visible, .site-footer :focus-visible, .mobile-contact-bar :focus-visible, .stock-lightbox :focus-visible { outline-color: var(--teal); }
/* D1 — la selezione di testo era quella di sistema, l'unico stato del sito senza voce.
   Il teal ad alpha .4 regge sia sul chiaro sia sulle bande navy con una regola sola: non
   serve un override di colore per superficie. */
::selection { background: rgb(93 191 193 / .4); }
.shell { width: min(calc(100% - 2rem), var(--shell)); margin-inline: auto; }
.section { padding-block: clamp(4.5rem, 9vw, 8.5rem); }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.skip-link { position: fixed; z-index: 2000; top: .75rem; left: .75rem; transform: translateY(-160%); padding: .75rem 1rem; background: var(--white); color: var(--navy); border-radius: var(--radius-sm); box-shadow: var(--shadow); }
.skip-link:focus { transform: none; }
.eyebrow { margin-bottom: .85rem; color: var(--teal-dark); font-size: .82rem; font-weight: 750; letter-spacing: .14em; text-transform: uppercase; }
/* A2 — la tacca, rango 1 della grammatica del segno teal: piccola, inline, mai a piena
   larghezza. Precede ogni eyebrow ed è il segno della voce, non dell'azione (rango 2, il filo
   full-width, resta su banda stagionale, contact-panel e barra mobile). */
.eyebrow::before { content: ''; display: inline-block; width: 1.35rem; height: 3px; margin-right: .6rem; vertical-align: .18em; background: var(--teal); border-radius: 999px; }
.eyebrow-light { color: #9fe1df; }
.hero-lead { max-width: 44rem; color: #31465a; font-size: clamp(1.1rem, 2vw, 1.35rem); line-height: 1.55; }
.microcopy { margin: 1rem 0 0; color: var(--muted); font-size: .92rem; }

.site-header { position: sticky; z-index: 1000; top: 0; background: rgb(248 250 251 / .93); border-bottom: 1px solid rgb(219 228 233 / .8); backdrop-filter: blur(18px); }
/* 2026-08-07, rilievo owner (mobile e desktop): a fondo pagina lo sticky header tagliava una
   riga del footer — su desktop il pannello-logo, mozzato e raddoppiato col logo dell'header.
   Auto-hide: scendendo l'header si ritira, salendo riappare (attributo posato da app.js).
   La transizione e' gated; il comportamento vale anche con reduced-motion (scatto secco).
   Oracolo: HEADER_COVERS_PAGE_BOTTOM. */
/* 2026-08-07, secondo rilievo owner sullo stesso meccanismo: su DESKTOP l'auto-hide costava
   la CTA proprio nella direzione di lettura ordinaria (scroll-down), che conta piu' dello
   scroll-up. Da qui in poi desktop e mobile divergono, e ciascuno risolve il proprio problema:
   - MOBILE: l'header si ritira per intero. Il difetto del footer tagliato resta risolto, e la
     funzione CTA e' gia' coperta dalla barra fissa Chiama/WhatsApp.
   - DESKTOP: l'header NON si ritira, si CONDENSA — escono logo e menu, resta la sola riga di
     contatto. La CTA e' quindi sempre presente mentre si legge, e il doppio logo a fondo pagina
     non puo' piu' esistere: nella striscia condensata il logo non c'e'.
   Le due regole vivono in media query esplicite e disgiunte, non in una base piu' un override:
   e' la lezione dei Blocchi 43 e 46 (un fix di cascata rimasto morto per tre giorni, e un
   selettore di gruppo che declassava il payoff). Nessuna delle due puo' colare sull'altra.
   Oracoli: HEADER_COVERS_PAGE_BOTTOM (mobile), DESKTOP_CTA_PERSISTENT e SINGLE_LOGO_VISIBLE. */
/* Riga di contatto dell'header. NIENTE margin-left auto qui: ce l'ha gia' .site-nav, e due
   margini auto nello stesso flex si SPARTISCONO lo spazio libero — il menu si staccava dalla
   CTA e galleggiava verso il centro (98px misurati a 1440, peggio sugli schermi larghi:
   rilievo owner). Il gruppo sta subito dopo il menu, come nel layout ratificato.
   Su mobile il gruppo e' vuoto: CTA e numero li porta la barra fissa in basso. */
.header-contact { display: flex; flex: 0 0 auto; align-items: center; gap: 0; }
/* Il numero e' TESTO, non un link tel: — su desktop un tel: apre Skype o niente, e un
   pulsante che non fa nulla irrita chi lo clicca (decisione owner). Il clic sul testo
   traccia comunque contact_intent via .track-contact, senza navigare da nessuna parte. */
.header-phone { display: none; align-items: center; gap: .4rem; font-weight: 650; color: var(--navy); white-space: nowrap; font-variant-numeric: tabular-nums lining-nums; cursor: default; user-select: text; }
.header-cta-long { display: none; white-space: nowrap; }
@media (max-width: 78rem) {
  .site-header[data-header-hidden] { translate: 0 -102%; }
}
@media (min-width: 78.0625rem) {
  /* Durante la transizione menu e riga di contatto coesistono per ~200ms: il clip evita che
     lo sbordo transitorio apra una scrollbar orizzontale. Nessun contenuto legittimo
     dell'header desktop sporge in orizzontale. */
  .site-header { overflow-x: clip; }
  .brand { max-width: 12rem; }
  .site-nav { max-width: 64rem; }
  /* LA STRISCIA. Il BOX dell'header resta 91px — cambiarne l'altezza muoveva la geometria del
     documento, lo scroll rimbalzava e l'header ri-appariva: anello di retroazione misurato.
     A ridursi e' la parte DIPINTA: l'header scivola su di 37px (visibile: striscia da 54px)
     e la riga di contatto compensa di +18px per centrarsi nella fascia. Solo trasformazioni,
     dissolvenze e max-width: il layout del documento non si muove mai. */
  .site-header[data-header-hidden] { translate: 0 -37px; }
  .site-header[data-header-hidden] .brand,
  .site-header[data-header-hidden] .site-nav { max-width: 0; opacity: 0; visibility: hidden; overflow: hidden; }
  .site-header[data-header-hidden] .header-contact { translate: 0 18px; gap: .9rem; }
  .header-phone { display: inline-flex; max-width: 0; opacity: 0; visibility: hidden; overflow: hidden; }
  .site-header[data-header-hidden] .header-phone { max-width: 16rem; opacity: 1; visibility: visible; }
  .header-cta-long { display: inline-block; max-width: 0; opacity: 0; visibility: hidden; overflow: hidden; }
  .site-header[data-header-hidden] .header-cta-long { max-width: 9rem; opacity: 1; visibility: visible; }
}
@media (prefers-reduced-motion: no-preference) {
  .site-header { transition: translate .18s var(--ease); }
  .header-contact { transition: translate .18s var(--ease), gap .2s var(--ease); }
  /* Direzionale: sparendo, visibility scatta a dissolvenza conclusa (delay nel ramo di
     destinazione); ricomparendo, subito. Cosi' niente scatti e niente elementi focusabili
     invisibili. Tutto dentro no-preference: con reduced-motion ogni cambio e' istantaneo. */
  .site-header .brand, .site-header .site-nav { transition: opacity .13s var(--ease), max-width .2s var(--ease), visibility 0s linear; }
  .site-header[data-header-hidden] .brand, .site-header[data-header-hidden] .site-nav { transition: opacity .13s var(--ease), max-width .2s var(--ease), visibility 0s linear .2s; }
  .header-phone, .header-cta-long { transition: opacity .16s var(--ease) .05s, max-width .2s var(--ease), visibility 0s linear .2s; }
  .site-header[data-header-hidden] .header-phone, .site-header[data-header-hidden] .header-cta-long { transition: opacity .16s var(--ease) .05s, max-width .2s var(--ease), visibility 0s linear; }
}
.header-inner { display: flex; min-height: 5.6rem; align-items: center; gap: 1rem; }
.brand { display: inline-flex; flex: 0 0 auto; align-items: center; text-decoration: none; }
.brand-logo { width: 10.8rem; height: auto; }
.site-nav { display: flex; margin-left: auto; align-items: center; gap: .72rem; }
.site-nav a { position: relative; padding: .9rem 0; color: #2b435a; font-size: .86rem; font-weight: 650; line-height: 1.2; text-decoration: none; white-space: nowrap; }
.site-nav a::after { position: absolute; right: 0; bottom: -.45rem; left: 0; height: 2px; content: ''; background: var(--teal-dark); transform: scaleX(0); transition: transform .2s ease; }
.site-nav a[aria-current="page"]::after { transform: scaleX(1); }
@media (hover: hover) { .site-nav a:hover::after { transform: scaleX(1); } }
@media (hover: none) { .site-nav a:active::after { transform: scaleX(1); } }
/* D12 — nel pannello mobile l'underline è spenta (`.site-nav a::after { display: none }`),
   quindi la pagina corrente non aveva alcun segno. Il colore lo dà anche lì. */
.site-nav a[aria-current="page"] { color: var(--navy); }
/* B5 — cinque radius orfani (.65, .5, .75, 1.1, .8rem) riportati ai token: --radius-sm/--radius. */
.nav-toggle { display: none; width: 2.75rem; height: 2.75rem; margin-left: auto; padding: .7rem; background: transparent; border: 1px solid var(--line); border-radius: var(--radius-sm); }
.nav-toggle > span:not(.sr-only) { display: block; height: 2px; margin: .23rem 0; background: var(--navy); }

.button { display: inline-flex; min-height: 3.2rem; padding: .85rem 1.15rem; align-items: center; justify-content: center; gap: .55rem; color: var(--white); background: var(--navy); border: 1px solid var(--navy); border-radius: 999px; font-weight: 680; text-decoration: none; transition: transform .2s ease, background .2s ease, box-shadow .2s ease; }
@media (hover: hover) { .button:hover { background: var(--navy-2); box-shadow: var(--shadow-soft); transform: translateY(-2px); } }
@media (hover: none) { .button:active { background: var(--navy-2); box-shadow: var(--shadow-soft); transform: translateY(-2px); } }
/* D6 — il bottone si alzava all'hover e restava alzato al clic: mancava il rientro, cioè
   l'unico momento in cui l'interfaccia conferma di aver ricevuto il gesto. */
.button:active { transform: translateY(0); box-shadow: none; }
.button-small { min-height: 2.65rem; padding: .62rem 1rem; font-size: .82rem; }
.button-ghost { color: var(--navy); background: transparent; border-color: #aab8c4; }
/* 2026-08-07 — LA PILLOLA INFORMATIVA. Stessa geometria di un bottone (l'hero non si sposta di
   un pixel), linguaggio visivo opposto. La regola R3 del rango del teal la governa: la tacca
   dell'eyebrow e' il segno della VOCE, il filo quello dell'AZIONE. Un numero da leggere sta
   nella voce, quindi porta il teal sull'icona e mai il contorno d'azione.
   Superficie piena e tenue invece del contorno: un bordo che perimetra e' la promessa di un
   bersaglio: toglierlo e riempire dice «dato», non «premi». Niente transizione, niente ombra,
   niente sollevamento: le tre cose che nel sistema significano «questo risponde».
   Il testo resta selezionabile — su desktop l'unico gesto utile su un numero e' copiarlo. */
.button-static { color: var(--navy); background: var(--blue-pale); border-color: transparent; font-weight: 650; letter-spacing: .01em; cursor: default; transition: none; user-select: text; }
.button-static svg { color: var(--teal-dark); stroke: var(--teal-dark); }
@media (hover: hover) { .button-static:hover { background: var(--blue-pale); box-shadow: none; transform: none; } }
@media (hover: none) { .button-static:active { background: var(--blue-pale); box-shadow: none; transform: none; } }
/* Le due varianti del numero: una sola vive per dispositivo. Il discrimine e' la capacita' di
   input, non la larghezza — un portatile con la finestra stretta resta un dispositivo a mouse,
   e li' `tel:` non porta a nulla. `display: none` toglie l'altra anche dall'albero di
   accessibilita', quindi nessuna lettura doppia e nessun JavaScript.
   REGOLA DI COMPETENZA: il `display` di queste due classi lo governano SOLO le regole
   qui sotto, tutte a specificita' identica (0,1,0), piu' la variante negli hero introdotta
   il 2026-08-08. Nessun'altra regola del foglio deve
   impostare `display` su .phone-touch/.phone-pointer — chi ci prova vince per specificita' e
   fa ricomparire il link telefonico su desktop, che e' esattamente il difetto misurato al
   primo giro (`.footer-list a` a (0,1,1) batteva `.phone-touch` a (0,1,0)).
   2026-08-08 — questo commento era ROTTO: una chiusura di troppo dopo «nessun JavaScript»
   lo terminava qui sopra, e le righe seguenti finivano come testo grezzo nel foglio. Il
   parser CSS le assorbiva insieme al selettore successivo e SCARTAVA `.phone-touch`, che
   percio' non e' mai esistita nel CSSOM del sito pubblicato. Negli hero il danno non si
   vedeva perche' li' il numero e' anche `.button`; nel footer, dove `.phone-touch` e' sola,
   la riga rendeva `inline` con gap 0 invece di `inline-flex` con 6,4px — su 13 pagine.
   La regola che questo commento DICHIARA era quindi disattivata dal commento stesso.
   Ora e' un oracolo: vedi CSS_COMMENTI_INTEGRI e CSS_REGOLE_PERSE in qa.cjs. */
.phone-touch { display: inline-flex; }
/* 2026-08-08 — QUI C'ERA una regola che nascondeva «Chiama» negli hero sotto 78rem,
   scritta per il difetto del bottone tagliato dalla barra fissa. La sua motivazione
   era testuale: «dove la barra fissa esiste, Chiama e' gia' permanentemente a
   schermo, quindi ripeterlo nell'hero non aggiunge nulla». Ragionamento corretto
   FINCHE' la barra era sempre presente.
   Lo stesso giorno la barra e' stata resa assente sulla prima schermata (vedi il
   blocco `html.js .mobile-contact-bar` piu' avanti), perche' il difetto non era il
   bottone di troppo ma la striscia coperta: colpiva 18 combinazioni di pagina e
   viewport, e su quelle larghe il taglio passava dentro le lettere della CTA
   PRINCIPALE, non del telefono. Tolta la causa, quella premessa e' diventata
   falsa: a scroll zero «Chiama» non e' piu' un duplicato, e' l'unico modo di
   telefonare visibile.
   Regola quindi rimossa su decisione owner. Misurato prima di rimuoverla: sulla
   home i recapiti sulla prima schermata tornano da 1 a 2, e i bottoni bisecati
   restano ZERO su tutti i viewport provati. Non ripristinarla senza rimettere
   prima la barra sulla prima schermata: le due cose stanno o cadono insieme. */
.phone-pointer { display: none; }
@media (hover: hover) and (pointer: fine) {
  .phone-touch { display: none; }
  .phone-pointer { display: inline-flex; }
}
@media (hover: hover) { .button-ghost:hover { color: var(--white); background: var(--navy); } }
@media (hover: none) { .button-ghost:active { color: var(--white); background: var(--navy); } }
.button-dark { color: var(--white); background: var(--navy); }
.hero-actions { display: flex; margin-top: 1.8rem; flex-wrap: wrap; gap: .75rem; }
.hero-actions .button { min-height: 3.85rem; padding: 1rem 1.45rem; font-size: 1.06rem; }
.hero-actions .button svg { flex: 0 0 auto; font-size: 1.12em; }
.decision-zone-action { margin-top: 2.4rem; }
.text-link { display: inline-flex; align-items: center; gap: .4rem; color: var(--navy); font-weight: 700; text-decoration: none; }
@media (hover: hover) { .text-link:hover { color: var(--teal-dark); } }
@media (hover: none) { .text-link:active { color: var(--teal-dark); } }
/* D11 — il gesto della freccia: ogni freccia del sito scorre verso la destinazione all'hover.
   Un solo linguaggio per hub Home, text-link e card correlate, coordinato con l'underline
   della nav. È il terzo elemento di firma, il più economico. */
.text-link svg { transition: transform .2s var(--ease); }
@media (hover: hover) { .text-link:hover svg { transform: translateX(3px); } }
@media (hover: none) { .text-link:active svg { transform: translateX(3px); } }

/* B1 — un solo cielo. I cinque hero avevano cinque gradienti quasi-uguali (145deg/135deg,
   fondi diversi di pochi punti): differenze invisibili al lettore ma cinque cose da mantenere.
   Ora sono un token solo, `--hero-sky`. `overflow: hidden` resta dov'era. */
.home-hero { overflow: hidden; padding-block: clamp(3.5rem, 7vw, 7.2rem); background: var(--hero-sky); }
.home-hero-grid { display: grid; gap: clamp(2.5rem, 5vw, 4.5rem); grid-template-columns: 1fr; }
.hero-copy { position: relative; z-index: 2; max-width: 62rem; }
.hero-visual { position: relative; }
.hero-image-wrap { overflow: hidden; background: var(--white); border-radius: var(--radius-lg); box-shadow: var(--shadow); }
.hero-image { aspect-ratio: 16 / 9; object-fit: cover; }
.hero-location { position: absolute; right: -1rem; bottom: 1.75rem; display: flex; min-width: 14rem; padding: .95rem 1.1rem; align-items: center; gap: .7rem; background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-sm); box-shadow: var(--shadow-soft); }
.hero-location svg { color: var(--teal-dark); font-size: 1.3rem; }
.hero-location span { display: grid; line-height: 1.25; }
.hero-location small { margin-top: .15rem; color: var(--muted); }
/* 2026-08-05, rilievo owner: box dritto (il ruotato leggeva come storto). 2026-08-06: torna la
   riga sotto il logo, stavolta con un fatto («Odontoiatria per adulti e bambini»); senza testo
   il box restava troppo vuoto, sempre su indicazione owner. */
.home-brand-sticker { position: absolute; top: 1.25rem; left: 1.25rem; display: grid; width: min(15rem, calc(100% - 2.5rem)); padding: .95rem 1.1rem .75rem; gap: .3rem; background: rgb(255 255 255 / .96); border: 1px solid rgb(219 228 233 / .9); border-radius: var(--radius); box-shadow: 0 16px 44px rgb(7 25 45 / .2); }
.home-brand-sticker .brand-logo { width: 10rem; }
.home-brand-sticker span { color: var(--teal-dark); font-size: .7rem; font-weight: 780; letter-spacing: .11em; line-height: 1.2; text-transform: uppercase; }

.trust-strip { color: var(--white); background: var(--navy); }
.trust-grid { display: grid; grid-template-columns: repeat(4, 1fr); }
.trust-grid > div { display: flex; min-height: 5.8rem; padding: 1rem 1.2rem; align-items: center; gap: .65rem; border-left: 1px solid rgb(255 255 255 / .13); font-size: .94rem; line-height: 1.45; }
.trust-grid > div:last-child { border-right: 1px solid rgb(255 255 255 / .13); }
.trust-grid svg { flex: 0 0 auto; color: #91d8d6; }

.section-heading { max-width: 46rem; margin-bottom: 3rem; }
.section-heading > p:not(.eyebrow) { color: var(--muted); font-size: 1.08rem; }
.split-heading { display: grid; max-width: none; align-items: end; gap: 2rem; grid-template-columns: 1fr .78fr; }
.split-heading > p { margin-bottom: 1.25rem; }
.service-hub { background: var(--white); }
.service-hub-layout { display: grid; align-items: start; gap: 1.35rem; grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr); }
.service-hub-visuals { display: grid; align-content: space-between; align-self: stretch; gap: 1.35rem; }
.service-hub-visual { margin: 0; overflow: hidden; background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-soft); }
.service-hub-image { aspect-ratio: 4 / 3; object-fit: cover; background: #e8edef; }
.service-hub-visual figcaption { padding: .9rem 1rem; color: var(--muted); font-size: .9rem; }
.service-card-grid { display: grid; gap: 0; grid-template-columns: 1fr; border-top: 1px solid var(--line); }
.service-card { display: flex; padding: 1.35rem .25rem; flex-direction: column; color: var(--navy); background: transparent; border: 0; border-bottom: 1px solid var(--line); border-radius: 0; text-decoration: none; transition: background-color .2s ease; }
/* A7 — scheda unica del cluster service-card. La freccia lascia il flusso e si allinea al
   titolo (era una riga vuota sopra ogni card); l'hover passa da paper a blue-pale, perché
   Δ7 su bianco era subliminale; la freccia scorre di 4px verso la destinazione — lo stesso
   gesto di ogni link testuale del sito. Il selettore `a.service-card` esclude la card statica
   con `.service-card-status`, che non è cliccabile e resta in flusso. */
a.service-card { position: relative; transition: background-color .2s ease; }
a.service-card .service-card-top { position: absolute; top: 1.3rem; right: .25rem; min-height: 0; margin: 0; }
a.service-card h3 { padding-right: 2.4rem; }
.service-card-top svg { transition: transform .2s var(--ease); }
@media (hover: hover) { a.service-card:hover { background: var(--blue-pale); } }
@media (hover: none) { a.service-card:active { background: var(--blue-pale); } }
@media (hover: hover) { a.service-card:hover .service-card-top svg { transform: translateX(4px); } }
@media (hover: none) { a.service-card:active .service-card-top svg { transform: translateX(4px); } }
.service-card-link { transition: opacity .2s ease, color .2s ease; }
@media (hover: hover) { a.service-card:hover .service-card-link { opacity: 1; color: var(--teal-dark); } }
@media (hover: none) { a.service-card:active .service-card-link { opacity: 1; color: var(--teal-dark); } }
.service-card-top { display: flex; min-height: 1.35rem; margin-bottom: .55rem; align-items: center; justify-content: flex-end; color: var(--teal-dark); }
.service-card-top svg { font-size: 1.2rem; }
.service-card h3 { max-width: none; margin-bottom: .7rem; font-size: clamp(1.08rem, 1.8vw, 1.34rem); }
.service-card-description { margin-bottom: 1.1rem; color: var(--muted); font-size: .93rem; line-height: 1.48; }
.service-card-link { margin-top: auto; color: inherit; font-size: .82rem; font-weight: 720; line-height: 1.35; opacity: .78; }
.service-card-static { color: #405367; background: #f5f7f8; }
.service-card-status { margin-right: auto; color: var(--muted); font-size: .69rem; font-weight: 760; letter-spacing: .07em; text-transform: uppercase; }

.studio-preview { background: var(--sand); }
.studio-preview-grid { display: grid; margin-bottom: 1.5rem; align-items: start; gap: 1.25rem; grid-template-columns: .878fr 1.122fr; }
.studio-preview-column { display: grid; align-items: start; gap: 1.25rem; }
.studio-preview-grid figure { margin: 0; overflow: hidden; background: var(--white); border-radius: var(--radius); box-shadow: var(--shadow-soft); }
.studio-preview-grid img { aspect-ratio: auto; object-fit: contain; background: #e8edef; }
.studio-preview-grid figcaption { padding: .9rem 1rem; color: var(--muted); font-size: .94rem; }

.tech-proof { background: var(--white); }
.image-duo { display: grid; margin-bottom: 1.5rem; gap: 1.25rem; grid-template-columns: 1fr 1fr; }
.image-duo figure { margin: 0; overflow: hidden; background: var(--blue-pale); border-radius: var(--radius); }
.image-duo img { aspect-ratio: 3 / 4; object-fit: contain; background: #e8edef; }
.image-duo figcaption { padding: .9rem 1rem; color: var(--muted); font-size: .94rem; }
.director-card { padding: clamp(.65rem, 2vw, 1.25rem); }
/* C6 — cerniera della Home: tech-proof (bianco) → contact-process (sand) → access (bianco).
   Prima erano bianco-bianco-sand e le due sezioni si fondevano in un unico blocco lungo. */
.contact-process { background: var(--sand); }
.steps-grid { display: grid; margin: 0; padding: 0; gap: 1rem; grid-template-columns: repeat(3, 1fr); list-style: none; }
.steps-grid li { padding: 1.8rem; background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); }
/* B4 — un solo contatore. I tre cerchietti numerati misuravano 2.2, 2.55 e 2.1rem con corpi
   .8, .78 e .75rem: tre volte lo stesso oggetto, mai uguale a se stesso. Ora 2.25rem/.78rem. */
.steps-grid li > span { display: grid; width: 2.25rem; height: 2.25rem; margin-bottom: 1.5rem; color: var(--navy); background: var(--teal-pale); place-items: center; border-radius: 50%; font-size: .95rem; font-weight: 800; }
.steps-grid p { color: var(--muted); }
.access { background: var(--white); }
.access-grid { display: grid; align-items: center; gap: 4rem; grid-template-columns: 1fr 1fr; }
.access-grid img { aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--radius-lg); box-shadow: var(--shadow-soft); }
.access-ramp { object-position: 50% 68%; }

.studio-hero { overflow: hidden; padding-block: clamp(3.5rem, 7vw, 7rem); background: var(--hero-sky); }
.studio-hero-grid { display: grid; align-items: center; gap: clamp(2.5rem, 6vw, 6rem); grid-template-columns: 1fr .92fr; }
.studio-hero-media { margin: 0; overflow: hidden; background: var(--white); border-radius: var(--radius-lg); box-shadow: var(--shadow); }
.studio-hero-media img { aspect-ratio: 4 / 3; object-fit: cover; }
.studio-hero-media figcaption { padding: .9rem 1.1rem; color: var(--muted); font-size: .94rem; }
.studio-arrival { background: var(--white); }
.studio-spaces { background: var(--paper); }
/* 2026-08-04: da due colonne a proporzioni diverse a una riga di tre. Le tre fotografie sono
   ritagliate allo stesso 3:4, quindi le altezze coincidono e non resta il «buco di bianco». */
.studio-gallery { display: grid; align-items: start; gap: 1.2rem; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.studio-gallery figure, .access-gallery figure { margin: 0; overflow: hidden; background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-soft); }
.studio-gallery img { aspect-ratio: auto; object-fit: contain; background: #e8edef; }
.studio-gallery figcaption, .access-gallery figcaption { padding: .9rem 1rem; color: var(--muted); font-size: .94rem; }
.studio-access { background: var(--sand); }
.studio-access-grid { display: grid; align-items: center; gap: 4rem; grid-template-columns: .8fr 1.2fr; }
.access-gallery { display: grid; gap: 1rem; grid-template-columns: 1fr 1fr; }
/* 2026-08-06, rilievo owner: nelle finestre 4:3 a ritaglio alcuni soggetti (schemi esplosi su
   fondo bianco, still-life su fondo uniforme) perdevano pezzi. `media-fit-contain` mantiene la
   finestra 4:3 della riga (allineamento intatto) ma mostra l'immagine INTERA; il fondo bianco
   della card assorbe le bande sulle illustrazioni. */
.choice-card .media-card.media-fit-contain img { object-fit: contain; background: var(--white); }
.choice-card .media-fit-contain a { background: var(--white); }
/* 2026-08-06: la galleria accesso ha una sola fotografia (bagno accessibile, decisione owner):
   niente cella orfana a meta' larghezza. */
.access-gallery:has(> figure:only-child) { grid-template-columns: minmax(0, 26rem); justify-content: start; }
.access-gallery img { aspect-ratio: 3 / 4; object-fit: cover; }
.studio-identity { background: var(--blue-pale); }
.studio-identity-grid { display: grid; align-items: center; gap: clamp(2.5rem, 7vw, 7rem); grid-template-columns: 1.1fr .9fr; }
.studio-equipment { background: var(--white); }
.studio-equipment-grid { display: grid; align-items: start; gap: 1.35rem; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.studio-equipment-card { margin: 0; overflow: hidden; background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-soft); }
.studio-equipment-card img { aspect-ratio: 3 / 4; object-fit: cover; background: #e8edef; }
.studio-equipment-card figcaption { padding: .9rem 1.1rem; color: var(--muted); font-size: .9rem; line-height: 1.45; }
.identity-facts { margin: 0 0 1.5rem; padding: 0; list-style: none; }
.identity-facts li { display: flex; padding: .7rem 0; align-items: flex-start; gap: .7rem; border-bottom: 1px solid rgb(20 91 166 / .16); }
.identity-facts svg { flex: 0 0 auto; margin-top: .25rem; color: var(--teal-dark); }
.studio-director-card { background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-soft); }
.studio-director-card img { aspect-ratio: 1; object-fit: contain; }

.breadcrumbs { display: flex; padding-block: 1.2rem; align-items: center; gap: .5rem; color: var(--muted); font-size: .92rem; }
/* D5 — il breadcrumb non si distingueva dal testo attorno: nessun underline, nessun hover,
   nessuna differenza fra il link «Home» e la pagina corrente. Underline tenue a riposo,
   pieno all'hover, e la pagina corrente in navy 650 — tre stati distinti. */
.breadcrumbs a { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: .24em; text-decoration-color: rgb(20 91 166 / .3); transition: color .2s ease; }
@media (hover: hover) { .breadcrumbs a:hover { color: var(--brand-blue); text-decoration-color: currentColor; } }
@media (hover: none) { .breadcrumbs a:active { color: var(--brand-blue); text-decoration-color: currentColor; } }
.breadcrumbs [aria-current="page"] { color: var(--navy); font-weight: 650; }
/* A4 — la quinta d'onda. Il vuoto destro degli hero di servizio (380x700 px di gradiente
   piatto) era il punto incompiuto del sito. Tre anelli concentrici ancorati oltre il bordo
   destro — eco delle onde delle vetrofanie e delle curve del logo — costruiti con un solo
   pseudo-elemento e box-shadow: nessun asset, nessun markup, nessun elemento attrattivo
   (L.145/2018): è geometria di sfondo. `overflow: hidden` sulla sezione (già presente) è ciò
   che tiene il cerchio a -20rem dentro la pagina: non va rimosso. */
.service-hero { position: relative; overflow: hidden; padding-block: clamp(4rem, 9vw, 8rem); background: var(--hero-sky); }
.service-hero::after { content: ''; position: absolute; top: 50%; right: -20rem; width: 46rem; height: 46rem; transform: translateY(-50%); border-radius: 50%; background: rgb(226 245 244 / .55); box-shadow: 0 0 0 4rem rgb(237 247 250 / .6), 0 0 0 calc(4rem + 1px) rgb(93 191 193 / .28), 0 0 0 9rem rgb(237 247 250 / .35), 0 0 0 calc(9rem + 1px) rgb(93 191 193 / .18); pointer-events: none; }
.service-hero-grid { position: relative; z-index: 1; display: grid; align-items: center; gap: 4rem; grid-template-columns: minmax(0, 1fr); }
.answer-block { background: var(--navy); }
.answer-block h2, .answer-block p { color: var(--white); }
/* C5 — la colonna «In breve» correva a ~95 caratteri su bianco-su-navy, la combinazione più
   faticosa del sito. Misura riportata a 60ch. */
.answer-block .narrow-grid > div:last-child { max-width: 60ch; padding-left: 2rem; border-left: 1px solid rgb(255 255 255 / .2); }
.narrow-grid { display: grid; gap: 4rem; grid-template-columns: .75fr 1.25fr; }
.choices-section { background: var(--white); }
.choice-grid { display: grid; gap: 1.2rem; grid-template-columns: repeat(3, 1fr); }
.choice-card { overflow: hidden; background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); }
.choice-copy { padding: 1.4rem; }
.choice-copy p { color: var(--muted); }
.media-card { margin: 0; background: #e8edef; }
.media-card img { aspect-ratio: 3 / 2; object-fit: cover; }
.media-card figcaption { min-height: 7.2rem; padding: .8rem 1rem; color: var(--ink); background: #edf1f3; font-size: .9rem; line-height: 1.45; }
.stock-preview { position: relative; }
/* 2026-08-05, decisione owner: l'affordance di ingrandimento diventa visibile.
   Il testo del chip e' identico all'aria-label gia' esistente: nessun copy nuovo.
   aria-hidden: l'anchor ha gia' l'aria-label, il chip non deve essere letto due volte.
   Alpha .68 su #061F2F: sul caso peggiore (area d'immagine bianca) il fondo efficace
   resta abbastanza scuro da tenere il bianco sopra 4.5:1. */
.stock-preview a { position: relative; }
/* D8 — affordance di ingrandimento sobria: il cursore dichiara l'azione e l'immagine risponde
   di 1,5%. Nessuna etichetta nuova — il chip «Ingrandisci» esiste già, ripete l'aria-label. */
a[data-stock-preview] { cursor: zoom-in; }
a[data-stock-preview] img { transition: transform .3s var(--ease); }
@media (hover: hover) { a[data-stock-preview]:hover img { transform: scale(1.015); } }
@media (hover: none) { a[data-stock-preview]:active img { transform: scale(1.015); } }
.zoom-hint { position: absolute; right: .6rem; bottom: .6rem; z-index: 1; padding: .28rem .68rem; color: #fff; background: rgb(6 18 31 / .68); border-radius: 999px; font-size: .72rem; font-weight: 700; letter-spacing: .04em; opacity: 0; transition: opacity .2s ease; pointer-events: none; }
.stock-preview a:focus-visible .zoom-hint { opacity: 1; }
@media (hover: hover) { .stock-preview a:hover .zoom-hint { opacity: 1; } }
@media (hover: none) { .stock-preview a:active .zoom-hint { opacity: 1; } }
@media (hover: none) { .zoom-hint { opacity: 1; } }
/* 2026-08-06, secondo rilievo owner («immagini ingrandite»): via lo zoom 1.42 del giro
   precedente. La radiografia torna INTERA; le bande — che sono la pellicola dentro l'opera —
   smettono di leggersi come difetto perche' la finestra ha lo stesso nero della pellicola:
   un negativoscopio, non un'immagine rotta. */
/* 2026-08-06: il caso speciale della radiografia 1305928481 (negativoscopio + contain) e'
   ritirato — il file e' ora un 4:3 esatto e riempie la scheda come le vicine. */
/* B3 — un solo nero di camera oscura (`--darkroom`) per i quattro toni che convivevano:
   #071925, #101820 (grafite), #061421, #020a10. Quattro neri diversi non sono una scelta:
   sono quattro momenti in cui nessuno ha guardato il valore accanto. */
.stock-complete a { display: grid; background: var(--darkroom); place-items: center; }
.stock-complete img { aspect-ratio: auto; object-fit: contain; }
.choice-card .media-card a { display: grid; background: #f4f6f6; place-items: center; }
/* 2026-08-04, due rilievi owner con la stessa causa: su Prevenzione le tre immagini finivano a
   323, 285 e 304 px — tre bordi diversi — e su Diagnostica lo scanner verticale dentro una
   finestra orizzontale lasciava bande laterali. Entrambi nascono da finestre a rapporto libero.
   Le schede di confronto hanno ora una finestra fissa che l'immagine riempie: bordi allineati,
   nessuna banda. */
.choice-card .media-card img { aspect-ratio: 4 / 3; object-fit: cover; }
/* Eccezione dichiarata: i confronti clinici vanno mostrati per intero, decisione owner.
   Restano a rapporto naturale anche a costo di bordi non allineati. */
.choice-card .stock-complete img { aspect-ratio: auto; object-fit: contain; }
.choice-card .local-choice-media img { aspect-ratio: 4 / 3; object-fit: cover; }
.materials-section { background: var(--sand); }
/* C6 — regola nuova: `.components-section` (Implantologia) era l'unica sezione senza fondo
   dichiarato, quindi ereditava il `--paper` del body e cadeva fra sand e blue-pale come un
   buco. Ora è bianca per scelta, non per omissione. */
.components-section { background: var(--white); }
.materials-grid { display: grid; align-items: stretch; gap: 1.2rem; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.implant-diagram-layout { display: grid; align-items: start; gap: clamp(1.2rem, 3vw, 2rem); grid-template-columns: minmax(0, 1.25fr) minmax(19rem, .75fr); }
.implant-diagram-visual { overflow: hidden; background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-soft); }
.implant-diagram-visual .media-card, .implant-diagram-visual .media-card a { display: block; background: var(--white); }
.implant-diagram-visual .media-card img { aspect-ratio: auto; object-fit: contain; }
.implant-parts-list { display: grid; margin: 0; padding: 0; gap: 1rem; list-style: none; }
.implant-part-card { display: grid; padding: 1.2rem; background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-soft); grid-template-columns: auto 1fr; gap: 1rem; }
.implant-part-number { display: grid; width: 2.25rem; height: 2.25rem; color: var(--navy); background: var(--teal-pale); border-radius: 50%; place-items: center; font-size: .95rem; font-weight: 800; }
.implant-part-copy h3 { max-width: none; margin-bottom: .55rem; font-size: clamp(1.08rem, 1.7vw, 1.32rem); }
.implant-part-copy p { margin: 0; color: var(--muted); font-size: .96rem; line-height: 1.55; }
.implant-diagram-placeholder { display: grid; min-height: 28rem; padding: 2rem; align-content: center; justify-items: center; gap: .8rem; background: linear-gradient(145deg, #fff, #edf7fa); }
.implant-diagram-placeholder span { display: grid; width: min(18rem, 80%); min-height: 4rem; place-items: center; color: var(--navy); background: var(--white); border: 1px solid #a9c5cf; box-shadow: var(--shadow-soft); font-weight: 750; }
.implant-placeholder-crown { border-radius: 2rem 2rem .8rem .8rem; }
.implant-diagram-placeholder .implant-placeholder-abutment { width: min(10rem, 48%); border-radius: .8rem; }
.implant-diagram-placeholder .implant-placeholder-fixture { width: min(7rem, 34%); min-height: 8rem; border-radius: .7rem .7rem 2rem 2rem; }
.material-card { display: flex; overflow: hidden; min-width: 0; flex-direction: column; background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-soft); }
.material-card .media-card a { display: grid; background: var(--darkroom); place-items: center; }
.material-card .media-card img { aspect-ratio: 3 / 2; object-fit: contain; }
.material-card .media-card figcaption { min-height: 6.6rem; background: #f5f7f7; }
.material-copy { padding: 1.45rem; }
.material-copy h3 { max-width: none; }
.material-copy p { margin: 0; color: var(--muted); }
.results-gallery-section { background: linear-gradient(180deg, var(--blue-pale), #f7fbfc); }
.results-gallery { display: grid; align-items: start; gap: 1.35rem; grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* C7 — l'orfana di griglia. Con 7 confronti la settima scheda restava sola a metà riga,
   incollata a sinistra come un residuo. Ora prende la riga intera ma tiene la larghezza di
   una colonna (50% meno metà del gap 1.35rem) e sta al centro: chiude la sequenza. */
.results-gallery > .result-card:nth-child(odd):last-child { grid-column: 1 / -1; width: calc(50% - .675rem); justify-self: center; }
.result-card { overflow: hidden; background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-soft); }
.result-card .media-card figcaption { min-height: auto; padding: 1rem 1.1rem; font-size: .78rem; }
.result-title { display: flex; padding: 1.1rem; align-items: baseline; gap: .8rem; border-top: 1px solid var(--line); }
.result-title > span { color: var(--teal-dark); font-size: .85rem; font-weight: 800; letter-spacing: .1em; }
.result-title h3 { max-width: none; margin: 0; font-size: 1.18rem; }
/* Blocco video MAXI — decisione owner 2026-08-04. Il video non e' piu' un riquadro accanto al
   testo: e' una banda che occupa la larghezza utile e vale come immagine anche da fermo, perche'
   il poster e' l'anteprima statica a 1000 px. Il testo sta sopra, il quadro sotto e da solo.
   La banda segue il fondo del video (`tone`): un'animazione su bianco dentro una banda navy
   abbaglia, un filmato nero dentro una banda chiara si stacca. */
.procedure-video { padding-block: clamp(3.5rem, 7vw, 6rem); }
.procedure-video-head { display: grid; align-items: end; margin-bottom: clamp(1.75rem, 3.5vw, 2.75rem); gap: .5rem clamp(2rem, 5vw, 4rem); grid-template-columns: minmax(0, .95fr) minmax(0, 1.05fr); }
.procedure-video-head h2 { margin-bottom: 0; }
.procedure-video-head p { margin-bottom: 0; }
/* 2026-08-04, rilievo owner: il quadro era dimensionato sulla larghezza e con l'header sticky
   non entrava nella finestra, quindi si vedeva tagliato. Ora il terzo termine del `min()` lega
   la larghezza all'altezza disponibile: `(100vh - 12rem) * 16 / 9` e' la larghezza massima
   compatibile con un'altezza che lascia spazio all'header e un margine di respiro sotto.
   Cosi' il video entra intero in qualunque finestra, senza scrollare. */
.video-maxi { width: min(calc(100% - 2rem), 88rem, calc((100vh - 12rem) * 16 / 9)); margin: 0 auto; overflow: hidden; border-radius: var(--radius-lg); box-shadow: var(--shadow); }
/* `height: auto` e' necessario: senza, l'attributo HTML height="1080" vince sull'aspect-ratio
   e il quadro rende 1408x1082 su desktop e 370x1080 su mobile. Misurato, non supposto. */
/* `contain` e non `cover`: se un domani un filmato non fosse 16:9, il letterbox e' onesto
   mentre il crop toglierebbe silenziosamente contenuto clinico dal quadro. */
.video-maxi video { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; background: #06121f; object-fit: contain; }
.procedure-video-light .video-maxi video { background: var(--white); }

/* B2 — da cinque blu scuri a due: `--navy` per le bande informative, `--navy-deep` per i
   fondi profondi. #0a2947 era la quinta variante, distinguibile solo affiancandola. */
.procedure-video-dark { color: var(--white); background: var(--navy-deep); }
.procedure-video-dark h2, .procedure-video-dark p { color: var(--white); }
.procedure-video-dark .video-maxi { border: 1px solid rgb(255 255 255 / .18); }

.procedure-video-light { background: linear-gradient(180deg, var(--blue-pale), var(--sand)); }
.procedure-video-light h2 { color: var(--navy); }
.procedure-video-light p { color: #31465a; }
.procedure-video-light .eyebrow { color: var(--teal-dark); }
.procedure-video-light .video-maxi { background: var(--white); border: 1px solid var(--line); }
.procedure-video-light .video-maxi video { background: var(--white); }

.local-choice-media { margin: 0; overflow: hidden; background: var(--white); border-bottom: 1px solid var(--line); }
.choice-local-image { aspect-ratio: 4 / 3; object-fit: cover; background: #e8edef; }
.video-transcript { margin: 1.5rem 0; padding: 1rem 1.1rem; background: rgb(255 255 255 / .08); border: 1px solid rgb(255 255 255 / .14); border-radius: var(--radius-sm); }
.video-transcript p { margin: .35rem 0 0; color: #d6e4ed; font-size: .94rem; }
.stock-lightbox { width: min(72rem, calc(100% - 2rem)); max-height: calc(100vh - 2rem); padding: 0; overflow: hidden; background: var(--darkroom); border: 1px solid rgb(255 255 255 / .18); border-radius: var(--radius); box-shadow: 0 30px 100px rgb(0 0 0 / .45); }
.stock-lightbox::backdrop { background: rgb(1 10 18 / .84); backdrop-filter: blur(8px); }
/* F2 — il lightbox appariva e spariva di scatto, e su un ingrandimento a schermo intero lo
   scatto è il momento in cui si perde il riferimento a che cosa si stava guardando.
   `@starting-style` + `allow-discrete` su `display`/`overlay` danno entrata e uscita a un
   dialog nel top layer senza una riga di JS. Dove non è supportato, resta il comportamento
   di oggi. */
.stock-lightbox { opacity: 1; translate: 0 0; transition: opacity .2s var(--ease), translate .2s var(--ease), display .2s allow-discrete, overlay .2s allow-discrete; }
@starting-style { .stock-lightbox[open] { opacity: 0; translate: 0 .6rem; } }
.stock-lightbox::backdrop { transition: background-color .2s var(--ease), display .2s allow-discrete, overlay .2s allow-discrete; }
@starting-style { .stock-lightbox[open]::backdrop { background: rgb(1 10 18 / 0); } }
.stock-lightbox-inner { display: grid; max-height: calc(100vh - 2rem); grid-template-rows: auto minmax(0, 1fr) auto; }
.stock-lightbox-toolbar { display: flex; padding: .7rem; align-items: center; justify-content: space-between; gap: .7rem; color: var(--white); }
.stock-lightbox-toolbar button { min-width: 3rem; min-height: 3rem; color: var(--white); background: rgb(255 255 255 / .09); border: 1px solid rgb(255 255 255 / .2); border-radius: 999px; cursor: pointer; }
.stock-lightbox-image { width: 100%; height: 100%; min-height: 0; object-fit: contain; background: var(--darkroom); }
.stock-lightbox-caption { margin: 0; padding: 1rem 1.2rem 1.2rem; color: #d8e5ed; font-size: .9rem; }
.demo-toast { position: fixed; z-index: 2200; right: 1rem; bottom: calc(5.4rem + env(safe-area-inset-bottom)); width: min(28rem, calc(100% - 2rem)); padding: 1rem 1.15rem; color: var(--white); background: var(--navy-deep); border: 1px solid rgb(255 255 255 / .2); border-radius: var(--radius-sm); box-shadow: var(--shadow); }
.evaluation { background: var(--blue-pale); }
.evaluation-grid { display: grid; gap: 1rem; grid-template-columns: repeat(4, 1fr); }
/* C7 — con due sole schede la griglia a quattro colonne lasciava mezza riga vuota. `:has()`
   le porta a due colonne piene; dove `:has()` non è supportato resta la resa di oggi. */
.evaluation-grid:has(> :nth-child(2):last-child) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.evaluation-grid article { padding: 1.5rem; background: rgb(255 255 255 / .8); border: 1px solid rgb(255 255 255 / .9); border-radius: var(--radius-sm); }
.evaluation-grid article img { margin: -1.5rem -1.5rem 1.3rem; width: calc(100% + 3rem); aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--radius-sm) var(--radius-sm) 0 0; }
.evaluation-grid p { color: var(--muted); }
.evaluation-dot { display: block; width: .75rem; height: .75rem; margin-bottom: 1.4rem; background: var(--teal); border-radius: 50%; box-shadow: 0 0 0 .55rem rgb(88 185 183 / .15); }
.pathway { background: var(--white); }
.path-list { margin: 0; padding: 0; border-top: 1px solid var(--line); list-style: none; }
.path-list li { display: grid; padding: 1.4rem 0; gap: 2rem; border-bottom: 1px solid var(--line); grid-template-columns: 3.5rem 1fr; }
/* B4 — un solo indice testuale: .78rem/.1em per anatomy-index e result-title, che salgono
   (erano .74 e .76rem). `.path-number` NON scende a .78rem: il contratto di leggibilità del
   progetto (qa.cjs, ramo READABILITY) impone a questo elemento un corpo ≥ 13,5px e .78rem
   vale 12,48px — misurato, non supposto: la passata del 2026-08-05 ha fatto fallire sette
   pagine su questo solo valore. Resta .9rem; il letter-spacing .1em della scheda B4 era già
   in vigore. L'armonizzazione è quindi parziale per vincolo, e il vincolo è dichiarato qui. */
/* 2026-08-05, aggiudicazione B4: un solo indice testuale a .85rem — il .78rem della scheda
   scendeva a 12,48px, sotto il pavimento 13,5px che l'oracolo READABILITY impone a .path-number.
   .85rem = 13,6px: passa l'oracolo e unifica davvero i tre indici. */
.path-number { color: var(--teal-dark); font-size: .85rem; font-weight: 800; letter-spacing: .1em; }
.path-list h3, .path-list p { margin-bottom: .3rem; }
.path-list p { color: var(--muted); }
.boundaries { color: var(--white); background: var(--navy); }
.boundaries-inner { display: grid; gap: 4rem; grid-template-columns: 1fr 1fr; }
.boundaries h2, .boundaries p { color: var(--white); }
.boundaries ul { margin: 0; padding: 0; list-style: none; }
.boundaries li { display: flex; padding: .75rem 0; gap: .7rem; border-bottom: 1px solid rgb(255 255 255 / .14); }
.boundaries li svg { flex: 0 0 auto; margin-top: .25rem; color: #91d8d6; }
/* C6 — le FAQ su sand spengono i ~2000 px di bianco continuo in coda alle cinque pagine servizio. */
.faq { background: var(--sand); }
.faq-grid { display: grid; align-items: start; gap: 4rem; grid-template-columns: .75fr 1.25fr; }
.faq-heading { position: sticky; top: 8rem; }
.faq-heading p:not(.eyebrow) { color: var(--muted); }
.accordion { border-top: 1px solid var(--line); }
.accordion details { border-bottom: 1px solid var(--line); }
.accordion summary { display: flex; padding: 1.35rem .2rem; align-items: center; justify-content: space-between; gap: 1rem; color: var(--navy); font-size: 1.05rem; font-weight: 680; cursor: pointer; transition: color .2s ease; list-style: none; }
/* D2 — l'accordion era l'unico comando del sito senza stato di hover: il cursore diventava
   una manina su una riga che non rispondeva. Il glifo +/− passa da 1px a 2px, il peso della
   famiglia di icone, e segue `currentColor` così l'hover lo tinge insieme al titolo. */
@media (hover: hover) { .accordion summary:hover { color: var(--brand-blue); } }
@media (hover: none) { .accordion summary:active { color: var(--brand-blue); } }
.accordion summary::-webkit-details-marker { display: none; }
.accordion summary span { position: relative; width: 1.3rem; height: 1.3rem; flex: 0 0 auto; }
.accordion summary span::before, .accordion summary span::after { position: absolute; top: 50%; left: 50%; width: .9rem; height: 2px; content: ''; background: currentColor; border-radius: 1px; transform: translate(-50%, -50%); }
.accordion summary span::after { transform: translate(-50%, -50%) rotate(90deg); transition: transform .2s ease; }
.accordion details[open] summary span::after { transform: translate(-50%, -50%); }
.accordion details p { padding: 0 2.5rem 1.25rem .2rem; color: var(--muted); }
/* F1 — apertura morbida delle FAQ. `::details-content` + `interpolate-size: allow-keywords`
   (A1) permettono di animare verso `auto` senza misurare l'altezza in JS. Progressive
   enhancement puro: dove lo pseudo-elemento non esiste, la regola è ignorata e l'apertura
   resta istantanea come oggi. Il kill-switch `reduce` azzera comunque la durata. */
.accordion details::details-content { block-size: 0; overflow: clip; transition: block-size .26s var(--ease), content-visibility .26s allow-discrete; }
.accordion details[open]::details-content { block-size: auto; }
.related { background: var(--white); }
.related-grid { display: grid; gap: .8rem; grid-template-columns: repeat(4, 1fr); }
.related-grid a { display: grid; min-height: 9rem; padding: 1.2rem; color: var(--navy); background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-sm); text-decoration: none; transition: border-color .2s ease, transform .2s ease, box-shadow .2s ease; }
/* D3 — la card correlata si alzava di 3px senza ombra: il sollevamento senza ombra è un
   movimento, non un rilievo. Riceve la stessa grammatica lift+ombra dei bottoni.
   D11 — e la freccia scorre verso la destinazione, come ogni altro link del sito. */
@media (hover: hover) { .related-grid a:hover { border-color: var(--teal); transform: translateY(-3px); box-shadow: var(--shadow-soft); } }
@media (hover: none) { .related-grid a:active { border-color: var(--teal); transform: translateY(-3px); box-shadow: var(--shadow-soft); } }
@media (hover: hover) { .related-grid a:hover svg { transform: translateX(3px); } }
@media (hover: none) { .related-grid a:active svg { transform: translateX(3px); } }
.related-grid span { color: var(--muted); font-size: .84rem; }
.related-grid strong { margin-top: auto; }
.related-grid svg { margin-top: .5rem; transition: transform .2s var(--ease); }

.prices-hero { background: var(--hero-sky); }
/* A4, esclusione dichiarata. L'hero Prezzi porta anche la classe `.service-hero` (markup:
   `<section class="service-hero prices-hero">`), quindi ereditava la quinta d'onda — ma la
   quinta esiste per riempire il VUOTO destro dei sette hero di servizio, e qui il lato destro
   non è vuoto: c'è una fotografia. Peggio: la griglia di Prezzi si chiama `.prices-hero-grid`,
   non `.service-hero-grid`, quindi non riceveva lo `z-index: 1` della scheda A4 e il cerchio
   finiva SOPRA la foto — misurato a 1440px: 288px di sovrapposizione orizzontale (cerchio
   1024→1440 dopo il clip, figura 836→1312), con la foto velata di menta.
   La direzione R3 lo dichiara essa stessa: §2 assegna la quinta ai «7 service heroes» e §3
   elenca l'hero Prezzi fra quelli da non toccare. L'esclusione ripristina quella portata.
   Per revocarla basta togliere questa riga. */
.prices-hero::after { content: none; }
.prices-hero-grid { display: grid; align-items: center; gap: clamp(2rem, 5vw, 4rem); grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); }
.prices-hero-media { margin: 0; overflow: hidden; background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-soft); }
.prices-hero-media img { aspect-ratio: 3 / 4; object-fit: cover; background: #e8edef; }
.prices-hero-media figcaption { padding: .9rem 1.1rem; color: var(--muted); font-size: .92rem; }

/* Anatomia di un preventivo — l'elemento grafico persuasivo della pagina, nativo.
   Sei segmenti che mostrano quante voci si nascondono dietro una sola parola. Nessun importo:
   sono componenti, non prezzi, e la barra non e' una proporzione economica. */
.price-anatomy { background: var(--white); }
.anatomy-track { display: grid; margin: 0; padding: 0; gap: 1rem; grid-template-columns: repeat(6, minmax(0, 1fr)); list-style: none; counter-reset: anatomy; }
.anatomy-step { display: flex; flex-direction: column; }
.anatomy-index { color: var(--teal-dark); font-size: .85rem; font-weight: 800; letter-spacing: .1em; }
.anatomy-bar { display: block; height: .55rem; margin: .55rem 0 .9rem; background: var(--teal-pale); border-radius: 999px; }
.anatomy-step:nth-child(2) .anatomy-bar { background: var(--navy); }
.anatomy-step h3 { margin-bottom: .35rem; font-size: 1.02rem; }
.anatomy-step p { margin: 0; color: var(--muted); font-size: .92rem; line-height: 1.5; }
.anatomy-note { max-width: 52rem; margin: clamp(2rem, 4vw, 3rem) 0 0; padding-left: 1.1rem; border-left: 3px solid var(--teal); color: var(--ink); font-size: 1.08rem; }

/* Due preventivi, la stessa cifra: il confronto che rende visibile il perimetro. */
/* C6 — Prezzi, passaggio unico coordinato con la riduzione dei blu: compare→blue-pale,
   example→sand. Le tre bande scure della pagina non annegano più in due paper identici. */
.price-compare { background: var(--blue-pale); }
/* 2026-08-06, sesta review owner: align-items start lasciava le card ad altezze diverse
   (513px vs 482px misurati a 1440px) — stretch le pareggia sulla riga. */
.compare-grid { display: grid; align-items: stretch; gap: 1.25rem; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.compare-card { padding: clamp(1.5rem, 3vw, 2.25rem); background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-soft); }
/* A6 — l'anello di fiducia. Il bordo teal a 1px non si distingueva dal bordo neutro della
   scheda accanto: il preventivo completo va riconosciuto prima di essere letto. */
.compare-card:first-child { border: 2px solid var(--teal); box-shadow: var(--shadow-soft), 0 0 0 4px var(--teal-pale); }
.compare-label { margin-bottom: .3rem; color: var(--teal-dark); font-size: .76rem; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; }
.compare-card h3 { margin-bottom: 1rem; font-size: 1.3rem; }
.compare-in, .compare-out { margin: 0; padding: 0; list-style: none; }
.compare-in li, .compare-out li { display: grid; padding: .42rem 0; align-items: start; gap: .6rem; grid-template-columns: 1.35rem 1fr; }
.compare-in li { color: var(--ink); }
/* D9 — il check era allineato al bordo alto della riga invece che al centro ottico della
   prima riga di testo: +.3rem, esattamente come già fanno le identity-facts. */
.compare-in svg { margin-top: .3rem; color: var(--teal-dark); }
.compare-out-title { margin: 1.15rem 0 .35rem; color: var(--muted); font-size: .78rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; }
.compare-out li { color: var(--muted); }
/* D9 — i trattini «resta fuori» erano su `--line` (#dbe4e9): ~1,35:1 sul bianco, cioè
   invisibili. #8FA2B0 li rende leggibili restando bullet decorativi: l'informazione
   è nel testo accanto, non nel segno. */
.compare-out li > span:first-child { color: #8FA2B0; font-weight: 800; text-align: center; }
/* 2026-08-06 — «Come si paga»: tre card, le due leve (rate interne, finanziamento anche a
   tasso zero) portano il segno teal delle superfici d'azione; la prassi resta neutra.
   Atterraggio dell'ancora: il target e' l'INTESTAZIONE (id sull'heading, non sulla section,
   perche' il padding della section scala col viewport e sui monitor grandi diventava un
   vuoto da 200px con le card sotto la piega). scroll-margin 28px + scroll-padding globale
   91px = eyebrow a 119px dal top, cioe' 28px di respiro sotto l'header, a OGNI larghezza. */
#come-si-paga { scroll-margin-top: 28px; }
.payment-grid { display: grid; margin-top: 1rem; align-items: stretch; gap: 1.25rem; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.payment-card { padding: clamp(1.4rem, 2.6vw, 2rem); background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-soft); }
.payment-card-lever { border: 2px solid var(--teal); box-shadow: var(--shadow-soft), 0 0 0 4px var(--teal-pale); }
.payment-label { margin-bottom: .5rem; color: var(--teal-dark); font-size: .78rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; }
.payment-card > h3 { margin-bottom: .6rem; font-size: 1.2rem; }
.payment-card > p:last-child { color: var(--muted); font-size: .95rem; }

.checklist-section { background: var(--white); }
.price-checklist { margin: 0; padding: 0; list-style: none; counter-reset: price; }
.price-checklist li { display: grid; padding: 1rem 0; align-items: center; gap: 1rem; border-bottom: 1px solid var(--line); grid-template-columns: 2.25rem 1fr; }
.price-checklist li > span { display: grid; width: 2.25rem; height: 2.25rem; color: var(--navy); background: var(--teal-pale); place-items: center; border-radius: 50%; font-size: .95rem; font-weight: 800; }
.price-checklist p { margin: 0; }
.example-section { background: var(--sand); }
.example-grid { display: grid; gap: 1rem; grid-template-columns: repeat(2, 1fr); }
.example-grid article { padding: 1.5rem; background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-sm); }
.example-grid article > span { color: var(--teal-dark); font-size: .72rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; }
.example-grid p { color: var(--muted); }
.no-amounts { color: var(--white); background: var(--navy); }
.no-amounts-inner { max-width: 54rem; }
.no-amounts h2, .no-amounts p { color: var(--white); }

/* A3 — il filo, rango 2: appartiene solo alle superfici che contengono un'azione primaria di
   contatto. Le bande navy informative (trust-strip, answer-block, boundaries, no-amounts,
   footer) non lo ricevono mai, così il segnale di conversione non si diluisce. */
.contact-panel { color: var(--white); background: linear-gradient(135deg, var(--navy-deep), var(--navy)); border-top: 3px solid var(--teal); }
.contact-panel-inner { display: grid; align-items: center; gap: 4rem; grid-template-columns: 1.15fr .85fr; }
.contact-panel h2, .contact-panel p { color: var(--white); }
.contact-panel .button { color: var(--navy); background: var(--teal); border-color: var(--teal); }
.contact-panel .button-ghost { color: var(--white); background: transparent; border-color: rgb(255 255 255 / .5); }
/* 2026-08-08, rilievo owner: qui la pillola informativa rendeva IDENTICA al bottone d'azione —
   stesso fondo teal, stesso testo navy, indistinguibili. Causa: `.contact-panel .button` sta a
   (0,2,0) e batteva `.button-static` a (0,1,0), quindi dentro il pannello l'informazione veniva
   ridipinta come azione. E' lo stesso errore del footer: una classe nuova non tradotta nei
   contesti che riscrivono i bottoni.
   La traduzione segue la regola gia' usata sul chiaro — l'informazione ha una superficie tenue
   e NESSUN bordo, perche' nel sistema il bordo perimetra un bersaglio e chi non lo ha non e' un
   bersaglio. Sul fondo scuro la superficie tenue diventa un velo di bianco, e l'icona porta il
   teal pieno (non `--teal-dark`, che qui sparirebbe). Restano cosi' tre stati distinguibili nel
   pannello: teal pieno = azione primaria, trasparente col bordo bianco = azione secondaria,
   velo senza bordo = informazione. Oracolo: CTA_ROLE_COLLISION. */
.contact-panel .button-static { color: var(--white); background: rgb(255 255 255 / .1); border-color: transparent; }
.contact-panel .button-static svg { color: var(--teal); stroke: var(--teal); }
/* D7 — sul pannello scuro il ghost ereditava l'hover chiaro (testo bianco su fondo navy su
   fondo navy: invisibile). Si inverte in bianco pieno con testo navy: AA garantito. */
@media (hover: hover) { .contact-panel .button-ghost:hover { color: var(--navy); background: var(--white); border-color: var(--white); } }
@media (hover: none) { .contact-panel .button-ghost:active { color: var(--navy); background: var(--white); border-color: var(--white); } }
.contact-panel .hero-actions { margin-top: 0; }
.email-link { display: inline-block; margin-top: 1rem; color: #c5e5e4; font-size: .95rem; }

.utility-hero { min-height: 60vh; padding-block: 6rem; background: var(--hero-sky); }
.utility-copy { max-width: 52rem; }
.draft-gate { margin-top: 2rem; padding: 1.5rem; background: var(--danger-pale); border: 1px solid #ead4ab; border-radius: var(--radius-sm); }
.site-footer { padding: 4rem 0 1.5rem; color: #e8f0f6; background: var(--navy-deep); }
.footer-grid { display: grid; gap: 2.5rem; grid-template-columns: 1.3fr .9fr 1fr 1.1fr; }
.site-footer h2 { margin-bottom: 1rem; color: var(--white); font-size: 1rem; letter-spacing: .09em; text-transform: uppercase; }
.site-footer p, .site-footer address { color: #c2d2df; font-size: .95rem; }
/* 2026-08-06, direttiva owner: il testo sotto il logo e' il punto che cattura l'occhio —
   diventa il payoff del sito, e la riga sotto lo mette al lavoro. */
.footer-payoff { margin: 1rem 0 .45rem; color: var(--white); font-size: 1.25rem; font-weight: 750; letter-spacing: -.01em; text-wrap: balance; }
.brand-footer { margin-bottom: 1.2rem; }
.footer-logo-panel { display: inline-flex; padding: .65rem .8rem; background: var(--white); border-radius: var(--radius-sm); }
.brand-footer .brand-logo { width: 11.5rem; }
.footer-list, .footer-links { margin: 0; padding: 0; list-style: none; }
.footer-list li, .footer-links li { margin-bottom: .65rem; }
/* Le due varianti del numero sono ESCLUSE da questa riga: impostava `display` a specificita'
   (0,1,1) e faceva ricomparire il link telefonico su desktop. Qui si dichiara solo l'aspetto;
   la visibilita' resta competenza esclusiva di .phone-touch/.phone-pointer. */
.footer-list a:not(.phone-touch), .footer-links a { display: inline-flex; align-items: center; gap: .4rem; color: #e8f0f6; font-size: .95rem; line-height: 1.4; text-decoration: none; }
/* Entrambe le varianti copiano l'aspetto dei recapiti — il numero deve restare
   indistinguibile dagli altri. Sulla variante inerte cambia solo cio' che prometteva un
   gesto: niente manina, testo selezionabile per copiarlo. */
.footer-list .phone-touch, .footer-list .phone-pointer { align-items: center; gap: .4rem; color: #e8f0f6; font-size: .95rem; line-height: 1.4; text-decoration: none; }
.footer-list .phone-pointer { cursor: default; user-select: text; }
/* D4 — nel footer l'hover ereditava `--teal-dark`, che su navy scende sotto la soglia AA:
   un hover che rende il link meno leggibile di quando è a riposo. Ora i link testuali vanno
   verso il chiaro (teal-pale) e le voci di colonna verso il bianco con underline teal. */
.site-footer .text-link { color: #bcebea; font-size: .95rem; }
@media (hover: hover) { .site-footer .text-link:hover { color: var(--teal-pale); } }
@media (hover: none) { .site-footer .text-link:active { color: var(--teal-pale); } }
@media (hover: hover) { .footer-list a:hover, .footer-links a:hover, .email-link:hover { color: var(--white); text-decoration: underline; text-decoration-color: var(--teal); text-underline-offset: .28em; } }
@media (hover: none) { .footer-list a:active, .footer-links a:active, .email-link:active { color: var(--white); text-decoration: underline; text-decoration-color: var(--teal); text-underline-offset: .28em; } }
.map-profile-link { margin-top: .6rem; }
.footer-docs { margin-top: 1.25rem; padding-top: 1rem; border-top: 1px solid rgb(255 255 255 / .12); }
/* 2026-08-06, direttiva owner: le modalità di pagamento sono una leva — la fascia le ripete
   in ogni pagina, come i metodi di pagamento nel footer di un e-commerce. */
.footer-payments { display: flex; margin-top: 3rem; padding-top: 1.25rem; align-items: flex-start; gap: .6rem; border-top: 1px solid rgb(255 255 255 / .14); }
.footer-payments svg { margin-top: .2rem; flex: none; color: var(--teal-pale); }
.footer-payments p { color: #e8f0f6; font-size: .95rem; }
.footer-payments strong { color: var(--white); }
.footer-payments a { color: #bcebea; }
@media (hover: hover) { .footer-payments a:hover { color: var(--teal-pale); } }
@media (hover: none) { .footer-payments a:active { color: var(--teal-pale); } }
/* Il pulsante di revoca del consenso vive fra i link documento e ne veste l'aspetto. */
.footer-consent { padding: 0; border: 0; background: none; color: #e8f0f6; font: inherit; font-size: .95rem; line-height: 1.4; text-decoration: underline; text-decoration-color: rgb(255 255 255 / .35); text-underline-offset: .28em; cursor: pointer; }
@media (hover: hover) { .footer-consent:hover { color: var(--white); text-decoration-color: var(--teal); } }
@media (hover: none) { .footer-consent:active { color: var(--white); text-decoration-color: var(--teal); } }
.footer-legal { display: grid; margin-top: 1.5rem; padding-top: 1.5rem; align-items: end; gap: 1.5rem 2rem; border-top: 1px solid rgb(255 255 255 / .14); grid-template-columns: minmax(0, 1fr) auto; }
.footer-legal-details { display: grid; min-width: 0; margin: 0; gap: 1rem 1.5rem; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.footer-legal-details > div { min-width: 0; padding-left: 1rem; border-left: 2px solid rgb(159 225 223 / .38); }
.footer-legal-details dt { margin-bottom: .35rem; color: #9fe1df; font-size: .7rem; font-weight: 780; letter-spacing: .09em; line-height: 1.3; text-transform: uppercase; }
.footer-legal-details dd { display: grid; margin: 0; gap: .08rem; color: #d8e5ed; font-size: .84rem; line-height: 1.45; }
.footer-legal-details dd span { white-space: nowrap; }
.footer-copyright { margin: 0; color: #d8e5ed; font-size: .84rem; line-height: 1.45; white-space: nowrap; }
/* A3 — filo rango 2 anche qui: è la seconda superficie d'azione, e il filo le dà il contorno
   che le mancava quando la barra atterra su una sezione scura. */
/* 2026-08-08, due review owner sulla stessa fascia. Qui c'era un filo da 3px, il segno R3 di
   rango 2 che marca le superfici d'azione. E' stato tolto, non ricolorato, e la ragione e'
   strutturale: una fascia UNICA non puo' servire due meta' di colore diverso. Teal si fonde col
   verde (e il verde sembra salire sopra il blu: primo rilievo); navy si fonde col blu, difetto
   speculare; qualunque altro tono — provato `--teal-dark` — e' un terzo colore su una superficie
   che deve leggersi a due (secondo rilievo). Nessun colore risolve: finche' la fascia c'e', il
   problema si sposta soltanto.
   Il filo era comunque ridondante qui: marca le superfici d'azione, ma questa barra e'
   INTERAMENTE azione — entrambe le meta' sono bottoni — e un segno che dice «questa e' azione»
   non aggiunge nulla dove tutto lo e' gia'. Lo stacco dal contenuto sopra resta garantito
   dall'ombra `0 -10px 30px` gia' presente sulla barra.
   ATTENZIONE: quell'ombra e' ora l'UNICO meccanismo di separazione — da ridondanza e' diventata
   punto singolo. La protegge l'oracolo MOBILE_BAR_NO_SEPARATION; la fascia non puo' tornare per
   via di MOBILE_BAR_BAND, che e' geometrico e quindi indifferente al colore che le si darebbe. */
.mobile-contact-bar { display: none; }

@media (max-width: 78rem) {
  /* G4 — fra 1025 e 1248px il sito restava senza alcuna CTA persistente: il pulsante header
     spariva a 78rem ma la barra contatti mobile non compariva prima di 64rem. Su un portatile
     da 13" l'unico invito a scrivere era in fondo alla pagina. Il CTA resta ora visibile fino
     a 64rem, e logo e nav si comprimono per fargli spazio: l'altezza dell'header (min-height
     5.6rem) non cambia. */
  .brand-logo { width: 9.6rem; }
  .site-nav { gap: .5rem; }
  /* 2026-08-05, aggiudicazione G4: 13px, il pavimento che il QA impone alla nav altrove;
     .78rem (12,48px) restava sotto soglia nella fascia 1025-1248 non coperta dall'oracolo. */
  .site-nav a { font-size: .8125rem; }
  .trust-grid { grid-template-columns: repeat(2, 1fr); }
  .trust-grid > div:nth-child(3) { border-top: 1px solid rgb(255 255 255 / .13); }
  .trust-grid > div:nth-child(4) { border-top: 1px solid rgb(255 255 255 / .13); border-right: 1px solid rgb(255 255 255 / .13); }
  .evaluation-grid { grid-template-columns: repeat(2, 1fr); }
  .related-grid { grid-template-columns: repeat(2, 1fr); }
  .footer-grid { grid-template-columns: 1.5fr 1fr 1fr; }
  .footer-grid > div:last-child { grid-column: 2 / -1; }
  .footer-legal { align-items: start; grid-template-columns: 1fr; }
}

@media (max-width: 64rem) {
  /* A3, conseguenza misurata: il filo teal rango 2 ha reso la barra contatti 75px invece di 72
     (4.5rem di min-height + 3px di bordo). Lo spazio riservato in fondo al body deve crescere
     con lei, altrimenti il footer finisce sotto la barra: l'oracolo QA
     MOBILE_COLLISION_OR_SAFE_AREA lo ha rilevato (bodyPaddingBottom 72 < barHeight 75,
     footerClearOfBar false) e la causa è qui, non nell'oracolo. */
  body { padding-bottom: calc(4.5rem + 3px + env(safe-area-inset-bottom)); }
  /* E1 — a 11vw l'H1 occupava cinque righe su 390px e spingeva la CTA sotto la piega.
     8.6vw lo riporta a tre o quattro righe: la prima azione torna visibile senza scorrere. */
  h1 { font-size: clamp(2.1rem, 8.6vw, 3.1rem); }
  h2 { font-size: clamp(1.85rem, 9vw, 2.8rem); }
  .site-header { top: 0; }
  .brand-logo { width: 9.4rem; }
  /* G4 — «header CTA visibile FINO a 64rem»: la regola non sparisce, si sposta qui. Sotto i
     64rem la barra contatti fissa è già la CTA persistente (è esattamente la ragione per cui
     la fascia 1025–1248 ne era priva) e nell'header non c'è spazio: a 320px, senza questa
     riga, il burger si comprime a 25px — sotto il minimo di 44 per un bersaglio tattile — e il
     pulsante sborda di 8px oltre lo shell. Misurato, non supposto. */
  .header-cta { display: none; }
  .nav-toggle { display: block; }
  /* 2026-08-07, bug owner dal Pixel: il menu APERTO finiva sotto la barra contatti (z 1200)
     — con la scala tipografica spinta o la scala font di sistema alzata la lista si allunga
     e l'ultima voce (Prezzi) diventava intoccabile: il tap colpiva la barra (riprodotto a
     360x640, elementFromPoint). Alzare lo z del solo nav NON basta: l'header sticky (z 1000)
     crea uno stacking context che intrappola il figlio a quota 1000. Quando il menu e'
     aperto e' l'HEADER a salire sopra la barra. Oracolo: MENU_LAST_LINK_COVERED. */
  .site-header:has(.site-nav[data-open]) { z-index: 1350; }
  .site-nav { position: fixed; z-index: 1300; inset: calc(5.6rem + 1px) 0 auto; display: none; max-height: calc(100vh - 5.6rem); padding: 1rem; overflow: auto; background: var(--paper); border-bottom: 1px solid var(--line); box-shadow: var(--shadow-soft); }
  .site-nav[data-open] { display: grid; }
  /* E4 — il menu compariva di scatto sopra una pagina che restava a piena luce: non si capiva
     che cosa fosse pannello e che cosa fosse pagina. Il velo è una sola box-shadow con spread
     100vh (zero markup, zero overlay da chiudere) e l'entrata dura 180ms. L'uscita resta
     immediata: `display` torna a `none` senza transizione, e va bene — chiudere un menu non
     ha bisogno di essere raccontato. */
  .site-nav[data-open] { opacity: 1; translate: 0 0; box-shadow: var(--shadow-soft), 0 100vh 0 100vh rgb(7 25 45 / .32); transition: opacity .18s var(--ease), translate .18s var(--ease), display .18s allow-discrete; }
  @starting-style { .site-nav[data-open] { opacity: 0; translate: 0 -.4rem; } }
  .site-nav a { padding: .85rem .4rem; border-bottom: 1px solid var(--line); font-size: 1rem; }
  .site-nav a::after { display: none; }
  .home-hero-grid, .service-hero-grid, .studio-hero-grid, .split-heading, .service-hub-layout, .access-grid, .studio-access-grid, .studio-identity-grid, .studio-equipment-grid, .narrow-grid, .boundaries-inner, .faq-grid, .contact-panel-inner, .procedure-video-head, .implant-diagram-layout { grid-template-columns: 1fr; }
  .home-hero { padding-top: 3rem; }
  /* A4 — sotto i 64rem la quinta si stringe e arretra: resta un'eco ai margini, non un disco. */
  .service-hero::after { width: 30rem; height: 30rem; right: -22rem; }
  .hero-visual { margin-top: 1rem; }
  .hero-image-wrap { border-radius: var(--radius); }
  .hero-location { right: .5rem; bottom: .75rem; min-width: 13rem; }
  .hero-actions { display: grid; }
  .hero-actions .button { width: 100%; }
  .trust-grid { grid-template-columns: 1fr; }
  .trust-grid > div { min-height: auto; padding: .85rem 0; border: 0; border-bottom: 1px solid rgb(255 255 255 / .13); }
  .trust-grid > div:nth-child(3), .trust-grid > div:nth-child(4) { border-top: 0; border-right: 0; }
  .image-duo, .steps-grid, .choice-grid, .materials-grid, .evaluation-grid, .example-grid, .compare-grid, .payment-grid { grid-template-columns: 1fr; }
  /* C7, correzione di portata. La regola `:has()` della scheda pesa (0,3,0) e le media query
     non aggiungono specificità: batteva quindi il collasso a una colonna qui sopra, e su
     Diagnostica le due schede restavano affiancate a 177px l'una su un viewport da 390px
     (misurato). La scheda risolve un vuoto di griglia da desktop — sopra i 78rem la base è a
     quattro colonne — non un layout mobile. Stessa specificità, più avanti nel file: vince
     questa, e il collasso torna a valere. */
  .evaluation-grid:has(> :nth-child(2):last-child) { grid-template-columns: 1fr; }
  .prices-hero-grid { grid-template-columns: 1fr; }
  .anatomy-track { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.4rem 1rem; }
  /* E2 — il rail del percorso teneva 3.5rem di colonna più 2rem di gap su 390px: 88px di
     margine sinistro per un indice di due cifre, e il testo strozzato a destra. */
  .path-list li { grid-template-columns: 2.1rem 1fr; gap: 1rem; }
  .studio-gallery { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .75rem; }
  .service-hub-visuals { order: 2; align-content: start; }
  .service-card-grid { order: 1; }
  .answer-block .narrow-grid > div:last-child { padding: 1.5rem 0 0; border-top: 1px solid rgb(255 255 255 / .2); border-left: 0; }
  .media-card figcaption { min-height: auto; }
  .faq-heading { position: static; }
  .related-grid { grid-template-columns: 1fr 1fr; }
  .footer-grid { grid-template-columns: 1fr; }
  .footer-grid > div:last-child { grid-column: auto; }
  .footer-legal { margin-bottom: 1rem; }
  .footer-legal-details { gap: 1rem; grid-template-columns: 1fr; }
  .footer-legal-details > div { padding: .8rem 0 0; border-top: 1px solid rgb(255 255 255 / .12); border-left: 0; }
  .footer-legal-details > div:first-child { padding-top: 0; border-top: 0; }
  .mobile-contact-bar { position: fixed; z-index: 1200; right: 0; bottom: 0; left: 0; display: grid; padding-bottom: env(safe-area-inset-bottom); grid-template-columns: 1fr 1fr; background: var(--navy); box-shadow: 0 -10px 30px rgb(7 25 45 / .2); }
  .mobile-contact-bar a { display: flex; min-height: 4.5rem; align-items: center; justify-content: center; gap: .45rem; color: var(--white); border-right: 1px solid rgb(255 255 255 / .18); font-weight: 700; text-decoration: none; }
  .mobile-contact-bar a:last-child { color: var(--navy); background: var(--teal); border: 0; }
  /* 2026-08-08 — LA BARRA NON COPRE PIU' LA PRIMA SCHERMATA.
     Una barra fissa in basso copre SEMPRE l'ultima striscia del viewport, a
     qualunque scroll. Di norma li' passa testo e non si nota; quando ci finisce
     un BOTTONE, questo si legge come rotto. Misurato sul sito pubblicato: 18
     combinazioni viewport/pagina con un bottone dell'hero tagliato a meta',
     fino a 72px nascosti su 97, e sui telefoni larghi il taglio passava dentro
     le lettere della CTA principale.
     Nessuna correzione statica puo' garantire che un bottone non finisca in
     quella striscia: la posizione dipende da quanto testo c'e' sopra e
     dall'altezza dello schermo. Si toglie invece la causa — la striscia non
     esiste finche' si sta guardando la prima schermata. La barra entra dopo un
     minimo di scorrimento, quando l'hero non e' piu' il soggetto.
     DEFAULT VISIBILE, di proposito: senza JavaScript la barra resta esattamente
     com'e' oggi. E' la classe `js` ad attivare il nascondimento, mai il
     contrario, cosi' il guasto cade sempre dal lato sicuro — il recapito non
     sparisce mai per un errore di script.
     `visibility` accompagna la trasformazione: una barra solo traslata fuori
     schermo resterebbe raggiungibile da tastiera, cioe' un bersaglio invisibile.
     `barra-animata` viene messa dopo il primo frame: il nascondimento iniziale
     e' istantaneo (niente scivolata all'apertura), la comparsa successiva no.
     Scelto JavaScript e non `animation-timeline: scroll()`, che avrebbe fatto
     tutto in CSS: quella proprieta' e' all'85,43% di supporto globale (caniuse,
     2026-08) e su iOS arriva solo con Safari 26. Circa un visitatore su sette
     resterebbe col difetto, e in particolare ogni iPhone non ancora aggiornato
     — cioe' proprio la classe di dispositivi su cui il difetto e' stato visto. */
  html.js .mobile-contact-bar { transform: translateY(110%); visibility: hidden; }
  html.js.barra-animata .mobile-contact-bar { transition: transform .24s var(--ease), visibility 0s .24s; }
  html.js.barra-in .mobile-contact-bar { transform: none; visibility: visible; }
  html.js.barra-animata.barra-in .mobile-contact-bar { transition: transform .24s var(--ease), visibility 0s; }
  /* A8: la quota mobile del pannello consenso NON vive piu' qui — le regole base del
     pannello stanno piu' in basso nel file e la sovrascrivevano per ordine di cascata
     (il fix era morto dalla nascita: scoperto dall'owner sul Pixel reale, 2026-08-06).
     La quota vive ora in coda al blocco del consenso, DOPO le regole base. */
}

@media (max-width: 32rem) {
  .shell { width: min(calc(100% - 1.25rem), var(--shell)); }
  .section { padding-block: 4rem; }
  .home-brand-sticker { top: .65rem; left: .65rem; width: 10rem; padding: .65rem .75rem .55rem; border-radius: var(--radius-sm); }
  .home-brand-sticker .brand-logo { width: 7.5rem; }
  /* 2026-08-06: l'override .58rem (9,3px!) e' ritirato — era il testo piu' piccolo
     dell'intero sito, trovato dall'oracolo MOBILE_TYPE_FLOOR sul rilievo owner. La taglia
     mobile dello sticker vive nel Piano tipografico mobile in fondo al foglio. */
  .hero-location { position: static; width: 100%; margin-top: .75rem; }
  .results-gallery { grid-template-columns: 1fr; }
  /* C7, correzione di portata. «Larghezza di una colonna» significa metà griglia solo dove le
     colonne sono due. Qui la galleria è a colonna singola, e la regola della scheda rendeva la
     settima scheda larga 174px dentro una griglia da 370 (misurato a 390px), accanto a sei
     sorelle a piena larghezza. L'orfana non esiste su una colonna sola: non c'è niente da
     centrare. `justify-self` torna a `stretch` perché con `center` l'elemento si stringerebbe
     comunque al contenuto. */
  .results-gallery > .result-card:nth-child(odd):last-child { width: auto; justify-self: stretch; }
  .service-card:last-child { grid-column: auto; }
  .related-grid, .access-gallery { grid-template-columns: 1fr; }
  .studio-preview-grid { display: flex; flex-direction: column; }
  .studio-preview-column { display: contents; }
  .studio-preview-card-primary-1 { order: 1; }
  .studio-preview-card-secondary-1 { order: 2; }
  .studio-preview-card-primary-2 { order: 3; }
  .studio-preview-card-secondary-2 { order: 4; }
  .studio-gallery { grid-template-columns: 1fr; }
  .video-maxi { width: calc(100% - 1.25rem); border-radius: var(--radius); }
  .anatomy-track { grid-template-columns: 1fr; }
  /* E3 — a 390px l'anatomia del preventivo perdeva la sua metafora: sei barre orizzontali
     impilate una sotto l'altra non sono più una barra scomposta, sono sei righe. Qui la barra
     diventa verticale a sinistra di ogni passo: i segmenti separati da .8rem tornano a
     leggersi come UNA barra, e il 02 navy resta l'accento. L'ordine DOM non cambia. */
  .anatomy-track { gap: .8rem; }
  .anatomy-step { display: grid; grid-template-columns: .6rem minmax(0, 1fr); column-gap: 1rem; }
  .anatomy-bar { grid-column: 1; grid-row: 1 / span 3; width: .6rem; height: auto; margin: 0; align-self: stretch; }
  .anatomy-index, .anatomy-step h3, .anatomy-step p { grid-column: 2; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { scroll-behavior: auto !important; transition-duration: .01ms !important; animation-duration: .01ms !important; animation-iteration-count: 1 !important; }
}

/* ── Movimento, tutto dietro un solo cancello ─────────────────────────────────
   2026-08-05, R3. Un gate unico: `prefers-reduced-motion: no-preference`. Chi chiede
   meno movimento vede la pagina di oggi, identica — e gli oracoli QA, che emulano
   `reduce`, misurano quella. Il coordinamento è dichiarato: lo stagger dell'hero
   parte a .04s e chiude sotto .9s, il crossfade di navigazione dura .22s: la somma
   non si percepisce doppia. */
@media (prefers-reduced-motion: no-preference) {
  /* A5 — ingresso scaglionato dell'hero, una sola volta per caricamento di pagina
     (`animation` senza iterazioni, non un observer): non si ripete allo scroll. */
  @keyframes hero-rise { from { opacity: 0; transform: translateY(10px); } }
  .hero-copy > * { animation: hero-rise .5s var(--ease) backwards; }
  .hero-copy > :nth-child(2) { animation-delay: .07s; }
  .hero-copy > :nth-child(3) { animation-delay: .14s; }
  .hero-copy > :nth-child(4) { animation-delay: .21s; }
  .hero-copy > :nth-child(5) { animation-delay: .28s; }
  .hero-visual, .studio-hero-media, .prices-hero-media { animation: hero-rise .55s var(--ease) .18s backwards; }
}

/* F4 — reveals allo scroll, una tantum. Le classi le mette app.js, e SOLO dietro
   `matchMedia('(prefers-reduced-motion: no-preference)')`: con `reduce` nessun elemento
   riceve `.reveal`, quindi niente resta a opacità 0 e gli oracoli QA misurano il DOM di oggi
   esattamente. Questa è la ragione tecnica del gate in JS, non solo quella etica. */
.reveal { opacity: 0; translate: 0 14px; transition: opacity .45s var(--ease), translate .45s var(--ease); }
.reveal.in { opacity: 1; translate: 0 0; }

/* F3 — transizioni di navigazione cross-document. Header e barra contatti sono «pinnati» con
   `view-transition-name`: gli unici due elementi identici fra una pagina e l'altra smettono di
   morire e rinascere a ogni clic. Il crossfade della root sta a .22s per non sommarsi allo
   stagger dell'hero. Dove le view transitions non esistono, la navigazione è quella di oggi. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  .site-header { view-transition-name: site-header; }
  .mobile-contact-bar { view-transition-name: contact-bar; }
  ::view-transition-old(root), ::view-transition-new(root) { animation-duration: .22s; }
}

@media print {
  .site-header, .mobile-contact-bar, .hero-actions, .contact-panel { display: none !important; }
  body { color: #000; background: #fff; }
  .section { padding-block: 2rem; }
}

/* ── Avviso stagionale ────────────────────────────────────────────────────────
   2026-08-05. Il banner v1 era invisibile per una ragione misurabile: non aveva
   colore di fondo, solo testo scuro su pagina chiara. Qui il fondo e' pieno, ed
   e' quello — non la dimensione del testo — a farlo leggere come avviso.
   Bianco su #145BA6 = contrasto 6,8:1, oltre la soglia AA. Il teal #5DBFC1 NON
   e' usato come fondo con testo bianco: non reggerebbe il contrasto.
   Non sticky: l'header sticky e' gia' 91 px e la geometria del video maxi ci si
   aggancia. Tono informativo, nessun elemento attrattivo (L.145/2018 c.525). */
.seasonal-band { background: #145BA6; border-bottom: 3px solid #5DBFC1; color: #fff; }
.seasonal-inner { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .7rem 1.5rem; padding: .95rem 0 1rem; }
.seasonal-text { display: flex; flex-wrap: wrap; align-items: baseline; gap: .35rem .85rem; margin: 0; flex: 1 1 20rem; }
.seasonal-lead { font-size: 1.1rem; font-weight: 700; letter-spacing: .01em; }
.seasonal-exception { font-size: 1rem; font-weight: 600; color: #cfe6f7; }
/* D10 — i due separatori «·» avevano stacchi diversi a destra e sinistra (gap .85rem del
   flex contro margin-right .6rem): equalizzati a .85rem. */
.seasonal-exception::before { content: "·"; margin-right: .85rem; color: #7fb4dd; }
.seasonal-note { font-size: .95rem; color: #dbe9f6; }
.seasonal-note::before { content: "·"; margin-right: .85rem; color: #7fb4dd; }
/* D10 — il pill della banda era l'unico comando del sito che cambiava fondo di scatto. */
.seasonal-cta { display: inline-flex; align-items: center; gap: .45rem; flex: 0 0 auto; padding: .6rem 1.1rem; border-radius: 999px; background: #fff; color: #0F4A88; font-size: .95rem; font-weight: 700; text-decoration: none; transition: background .2s ease; }
.seasonal-cta svg { width: 1.05em; height: 1.05em; }
@media (hover: hover) { .seasonal-cta:hover { background: #e6f1fb; } }
@media (hover: none) { .seasonal-cta:active { background: #e6f1fb; } }
.seasonal-cta:focus-visible { outline: 3px solid #5DBFC1; outline-offset: 3px; }
@media (max-width: 720px) {
  .seasonal-inner { align-items: flex-start; gap: .6rem; padding: .85rem 0 .95rem; }
  .seasonal-text { flex-direction: column; gap: .2rem; }
  .seasonal-exception::before, .seasonal-note::before { content: none; margin-right: 0; }
  .seasonal-lead { font-size: 1.05rem; }
  .seasonal-cta { width: 100%; justify-content: center; }
}

/* ── Consenso analytics ───────────────────────────────────────────────────────
   2026-08-05. Rifiuto e accettazione hanno lo stesso peso visivo: nessun bottone
   scolorito per spingere all'accettazione. Il pannello e' in fondo, non modale:
   non blocca la lettura, che e' il contenuto sanitario e non deve essere
   ostaggio di una scelta di misurazione. */
.analytics-consent[hidden] { display: none; }
.analytics-consent { position: fixed; right: 1rem; bottom: 1rem; left: 1rem; z-index: 60; margin: 0 auto; max-width: 46rem; background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: 0 18px 48px rgb(7 25 45 / .22); }
.analytics-consent-inner { position: relative; display: grid; gap: 1rem; padding: 1.15rem 1.35rem 1.25rem; }
.analytics-consent-kicker { margin: 0 0 .25rem; font-size: .78rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: #5A6879; }
.analytics-consent h2 { margin: 0 0 .4rem; font-size: 1.1rem; }
.analytics-consent p { margin: 0 0 .5rem; font-size: .93rem; line-height: 1.5; }
.analytics-consent-actions { display: flex; flex-wrap: wrap; gap: .6rem; }
.analytics-consent-choice { flex: 0 1 auto; padding: .65rem 1.1rem; border: 1px solid var(--line); border-radius: 999px; background: var(--white); color: var(--ink); font: inherit; font-weight: 700; font-size: .95rem; cursor: pointer; }
@media (hover: hover) { .analytics-consent-choice:hover { background: #eef3f6; } }
@media (hover: none) { .analytics-consent-choice:active { background: #eef3f6; } }
.analytics-consent-primary { background: #145BA6; border-color: #145BA6; color: #fff; }
@media (hover: hover) { .analytics-consent-primary:hover { background: #0F4A88; } }
@media (hover: none) { .analytics-consent-primary:active { background: #0F4A88; } }
.analytics-consent-choice:focus-visible { outline: 3px solid #5DBFC1; outline-offset: 2px; }
.analytics-consent-close { position: absolute; top: .5rem; right: .6rem; width: 2rem; height: 2rem; border: 0; border-radius: 50%; background: transparent; color: #5A6879; font-size: 1.3rem; line-height: 1; cursor: pointer; }
@media (hover: hover) { .analytics-consent-close:hover { background: #eef3f6; } }
@media (hover: none) { .analytics-consent-close:active { background: #eef3f6; } }
/* Quota mobile del pannello: sopra la barra contatti fissa (z 1200 vs 60). DEVE stare qui,
   DOPO le regole base del pannello: messa prima (blocco <=64rem), la base `bottom: 1rem`
   la sovrascriveva per ordine di cascata e la barra copriva il pannello — difetto trovato
   dall'owner sul Pixel reale il 2026-08-06, ora pinnato dall'oracolo CONSENT_BAR_OVERLAP. */
@media (max-width: 64rem) {
  .analytics-consent { bottom: calc(5.4rem + env(safe-area-inset-bottom)); }
}
@media (min-width: 780px) {
  .analytics-consent-inner { grid-template-columns: 1fr auto; align-items: center; gap: 1.5rem; }
  .analytics-consent-actions { flex-direction: column; min-width: 13rem; align-self: center; }
}

/* ── Documenti di servizio (privacy, cookie, Carta) ──────────────────────────
   2026-08-05: prima erano segnaposto di poche righe, ora sono testi lunghi e
   vanno letti davvero. Misura di riga contenuta, gerarchia chiara, tabelle che
   scorrono da sole invece di far scorrere la pagina in orizzontale. */
.utility-copy { max-width: 46rem; }
/* 2026-08-05: la regola globale h2{max-width:20ch} serve ai titoloni brevi delle pagine
   commerciali, ma sui documenti legali — titoli lunghi e numerati — li strozzava a 220 px
   dentro un contenitore da 736, spezzandoli su due o tre righe senza ragione. Annullata qui. */
.utility-copy h1, .utility-copy h2, .utility-copy h3, .utility-copy h4 { max-width: none; }
.utility-copy h2 { margin: 2.1rem 0 .7rem; font-size: 1.24rem; line-height: 1.3; }
.utility-copy h3 { margin: 1.5rem 0 .5rem; font-size: 1.05rem; }
.utility-copy h4 { margin: 1.2rem 0 .4rem; font-size: .97rem; }
.utility-copy p { margin: 0 0 .85rem; line-height: 1.65; }
.utility-copy ul, .utility-copy ol { margin: 0 0 1rem; padding-left: 1.3rem; }
.utility-copy li { margin-bottom: .45rem; line-height: 1.6; }
.utility-copy hr { margin: 2rem 0; border: 0; border-top: 1px solid var(--line); }
.utility-copy code { padding: .1em .35em; border-radius: .25rem; background: #eef2f5; font-size: .9em; }
.utility-copy .table-scroll { overflow-x: auto; margin: 0 0 1.2rem; }
.utility-copy table { width: 100%; border-collapse: collapse; font-size: .92rem; }
.utility-copy th, .utility-copy td { padding: .55rem .7rem; border: 1px solid var(--line); text-align: left; vertical-align: top; }
.utility-copy th { background: #eef3f6; font-weight: 700; }
.draft-gate { margin: 0 0 1.6rem; padding: .95rem 1.1rem; border-left: 4px solid #c8811a; border-radius: .4rem; background: #fdf5e8; }
.draft-gate strong { display: block; margin-bottom: .3rem; color: #7a4d07; }
.draft-gate p { margin: 0; font-size: .92rem; line-height: 1.55; color: #5c4a2a; }

/* ── Allineamento delle scatole nelle righe di card ───────────────────────────
   2026-08-07, rilievo owner (screenshot): card della stessa riga ad altezze
   diverse. Cause misurate: la galleria risultati ha FILE con rapporti diversi
   (Implantologia 0,867/0,985/0,998 → delta 68px; Estetica delta 161px, la
   peggiore, scoperta dall'oracolo) e le didascalie delle dotazioni corrono su
   2-3 righe (delta 23px). Il crop dei casi clinici e' VIETATO (legge owner):
   le scatole si pareggiano con lo stretch, l'immagine si centra nel suo campo
   e il titolo si ancora al fondo — l'aria resta DENTRO la card bianca, dove
   non si legge come banda. Oracolo: CARD_ROWS_RAGGED (delta > 2px). */
.results-gallery { align-items: stretch; }
.result-card { display: flex; flex-direction: column; }
.result-card .media-card { display: grid; flex: 1; align-items: center; }
.result-card .result-title { margin-top: auto; }
.studio-equipment-grid { align-items: stretch; }

/* ── Lo sticker della cover, su mobile ────────────────────────────────────────
   2026-08-07, rilievo owner (il piu' grave del giro): su mobile il box con
   logo copriva l'ingresso e buona parte della fotografia, col logo GIA'
   presente nello sticky header un palmo sopra — doppione e immagine rovinata.
   Su mobile lo sticker esce dalla fotografia e diventa una striscia sotto di
   essa, senza logo (lo porta l'header): resta il fatto, «Odontoiatria per
   adulti e bambini». Su desktop il box resta come ratificato (Blocco 36). */
@media (max-width: 48rem) {
  .home-brand-sticker { position: static; display: flex; width: auto; margin: .8rem 0 0; padding: .85rem 1rem; justify-content: center; border-radius: var(--radius-sm); }
  .home-brand-sticker .brand-logo { display: none; }
  .home-brand-sticker span { text-align: center; }
}

/* ── Piano tipografico desktop ────────────────────────────────────────────────
   2026-08-07, ratifica owner: «mi piacciono i testi grandi e leggibili, la roba
   piccola non la reggo» — il gusto diventa legge di design anche su desktop.
   Body 17,2 → 18px; didascalie e prosa secondaria a 16; testo di servizio a 17;
   etichette maiuscole >= 13,6; chip >= 12,8; ogni titolo minore sopra il body.
   NON toccata la nav dell'header: la fascia 1025-1248 fu aggiudicata in R3 al
   pixel per evitare il wrap (header 91px) e non si riapre per tipografia.
   Blocco PRIMA del piano mobile: sotto i 48rem vince il mobile per cascata.
   Oracoli: DESKTOP_TYPE_FLOOR >= 12,5px, DESKTOP_BODY_SIZE >= 17,5px. */
body { font-size: 1.125rem; }
.service-card-status, .example-grid article > span, .zoom-hint, .footer-legal-details dt, .home-brand-sticker span { font-size: .8rem; }
.eyebrow { font-size: .875rem; }
.compare-label, .compare-out-title, .payment-label, .analytics-consent-kicker { font-size: .85rem; }
.service-card-link, .button-small, .result-card .media-card figcaption { font-size: .875rem; }
/* 2026-08-08 — I numeri dentro il cerchietto (l'1-2-3 della home, le parti
   dell'impianto, la checklist dei prezzi) stavano nella regola delle ETICHETTE,
   insieme a `.eyebrow` e `.compare-label`, e risultavano quindi uno scalino
   sotto gli altri numeri d'elenco: 15,2px contro 16px su mobile, a ogni
   breakpoint. Ma un numero in un disco non e' un'etichetta, e' un INDICE —
   numera i passi di un percorso, esattamente come `.path-number`. Rilievo del
   titolare, che li vedeva piu' piccoli: aveva ragione, e la differenza era
   sistematica, non percettiva. Spostati nella famiglia giusta; il disco resta
   2,25rem, quindi nessuna geometria si muove. Il restyling R3 aveva gia' fra i
   suoi obiettivi «indici unificati»: questo lo completa, non lo contraddice. */
.path-number, .anatomy-index, .result-title > span, .related-grid span, .footer-legal-details dd, .footer-copyright { font-size: .9rem; }
/* COMPENSAZIONE OTTICA, deliberata: i numeri nel cerchietto stanno UNO SCALINO
   SOPRA gli indici liberi, non alla pari. Misurato: alla pari (14,4px desktop,
   16px mobile) il glifo occupa 20px in un disco di 36, cioe' il 30% — un badge
   tipografico calibrato sta sul 45-50%, e una cifra racchiusa legge sempre piu'
   piccola della stessa cifra libera perche' il disco le fa da metro di paragone.
   Si somma il contrasto: navy su teal chiaro pesa meno di teal scuro su bianco.
   Rilievo del titolare, che li vedeva piu' piccoli anche dopo il pareggio: la
   misura era identica, la percezione fondata. Il disco resta 2,25rem, quindi
   nessuna geometria si muove. NON «correggere» questa disparita' riportandoli
   alla parita': e' il punto. */
.steps-grid li > span, .implant-part-number, .price-checklist li > span { font-size: 1rem; }
.microcopy, .breadcrumbs, .anatomy-step p, .draft-gate p, .utility-copy table { font-size: .95rem; }
figcaption, .service-hub-visual figcaption, .studio-preview-grid figcaption, .image-duo figcaption, .studio-hero-media figcaption, .studio-gallery figcaption, .access-gallery figcaption, .studio-equipment-card figcaption, .media-card figcaption, .prices-hero-media figcaption, .service-card-description, .analytics-consent p, .trust-grid > div, .video-transcript p, .stock-lightbox-caption { font-size: 1rem; }
.site-footer p, .site-footer address, .footer-list a, .footer-links a, .site-footer .text-link, .footer-payments p, .footer-consent, .email-link, .payment-card > p:last-child, .seasonal-note, .seasonal-cta, .analytics-consent-choice, .implant-part-copy p, .site-footer h2 { font-size: 1.0625rem; }
/* il payoff NON e' testo di servizio: .site-footer p (0,1,1) lo declassava — specificita'
   (0,2,0) per tenerlo da display text (regressione trovata dalla sonda, non dall'occhio) */
.site-footer .footer-payoff { font-size: 1.3rem; }
.section-heading > p:not(.eyebrow), .accordion summary { font-size: 1.15rem; }
.hero-actions .button { font-size: 1.125rem; }
.hero-lead { font-size: clamp(1.2rem, 2vw, 1.4rem); }
h3 { font-size: clamp(1.3rem, 2vw, 1.55rem); }
.service-card h3 { font-size: clamp(1.2rem, 1.8vw, 1.4rem); }
.implant-part-copy h3 { font-size: clamp(1.2rem, 1.7vw, 1.38rem); }
.result-title h3 { font-size: 1.25rem; }
.anatomy-step h3 { font-size: 1.15rem; }
.analytics-consent h2 { font-size: 1.2rem; }
.payment-card > h3 { font-size: 1.3rem; }
.compare-card h3 { font-size: 1.35rem; }
.utility-copy h2 { font-size: 1.35rem; }
.utility-copy h3 { font-size: 1.2rem; }

/* ── Piano tipografico mobile ─────────────────────────────────────────────────
   2026-08-06, rilievo owner dal Pixel reale, in DUE giri. Primo giro: taglie
   fino a 9,3px, pavimento portato a 12,8. Secondo giro, direttiva owner:
   «ancora troppo piccoli — il sito non è concepito mobile-first, si recupera
   spingendo i caratteri al massimo senza distruggere la gerarchia».
   Regola: la scala si COMPRIME — TUTTO sale, il rapporto fra i gradini si
   stringe, e la gerarchia la tengono peso, colore e maiuscoletto (grammatica
   R3). Il BODY mobile sale a 18,4px (pubblico che include molti over-50);
   ogni titolo minore sale sopra il body, che altrimenti lo supererebbe.
   Scala mobile: 13,6 chip / 14,4 etichette / 15,2 meta / 16 didascalie /
   17 servizio / 18 intro-FAQ-bottoni / 18,4 BODY / 19,2-20 h3 piccoli /
   20,8-22,4 h3 principali / H2-H1 clamp invariati (30-38px).
   Blocco in FONDO al foglio per vincere la cascata a parita' di specificita'.
   Oracoli: MOBILE_TYPE_FLOOR >= 13,5px + MOBILE_BODY_SIZE >= 18px, misurati
   sul DOM visibile. */
@media (max-width: 48rem) {
  /* il body: 19,2px — il limite estremo chiesto dall'owner (terzo giro) */
  body { font-size: 1.2rem; }
  /* chip e legende maiuscole: 14,4px */
  .service-card-status, .example-grid article > span, .zoom-hint, .footer-legal-details dt, .home-brand-sticker span { font-size: .9rem; }
  /* etichette maiuscole e indici numerati: 15,2px */
  .eyebrow, .compare-label, .compare-out-title, .payment-label, .analytics-consent-kicker { font-size: .95rem; }
  /* micro-meta, link-card, numeratori, didascalie dei casi: 16px */
  .service-card-link, .button-small, .result-card .media-card figcaption, .path-number, .anatomy-index, .result-title > span, .related-grid span, .footer-legal-details dd, .footer-copyright { font-size: 1rem; }
  /* uno scalino sopra gli indici anche qui: vedi la nota sulla compensazione ottica */
  .steps-grid li > span, .implant-part-number, .price-checklist li > span { font-size: 1.125rem; }
  /* didascalie e prosa secondaria: 17px — i selettori specifici replicano quelli desktop
     (0,1,1) che altrimenti batterebbero il generico figcaption per specificita' */
  figcaption, .service-hub-visual figcaption, .studio-preview-grid figcaption, .image-duo figcaption, .studio-hero-media figcaption, .studio-gallery figcaption, .access-gallery figcaption, .studio-equipment-card figcaption, .media-card figcaption, .prices-hero-media figcaption, .microcopy, .breadcrumbs, .service-card-description, .anatomy-step p, .analytics-consent p, .utility-copy table, .draft-gate p, .trust-grid > div, .video-transcript p, .stock-lightbox-caption { font-size: 1.0625rem; }
  /* testo di servizio e navigazione: 18px */
  .site-footer p, .site-footer address, .footer-list a, .footer-links a, .site-footer .text-link, .footer-payments p, .footer-consent, .email-link, .payment-card > p:last-child, .seasonal-note, .seasonal-cta, .analytics-consent-choice, .implant-part-copy p, .site-nav a, .site-footer h2 { font-size: 1.125rem; }
  /* intro di sezione, domande FAQ, bottoni, titoletti dei passi: 19px */
  .section-heading > p:not(.eyebrow), .accordion summary, .hero-actions .button, .anatomy-step h3 { font-size: 1.1875rem; }
  /* il lead dell'hero sta SOPRA il body: 20,8px */
  .hero-lead { font-size: 1.3rem; }
  .site-footer .footer-payoff { font-size: 1.35rem; }
  /* titoli minori: sopra il body, gradini netti */
  .analytics-consent h2 { font-size: 1.25rem; }
  .service-card h3, .implant-part-copy h3, .result-title h3, .utility-copy h3 { font-size: 1.3rem; }
  h3, .payment-card > h3, .utility-copy h2 { font-size: 1.45rem; }
  .compare-card h3 { font-size: 1.5rem; }
}
