/* components.css — pharmacy. Farmacia con reparti merceologici e servizi sanitari.
   Consuma i token di tokens.css: qui NON si dichiarano colori letterali.

   L'impianto viene da PharmaCare (riferimento di categoria per la farmacia medicale, distinto
   dall'apothecary botanico di herbal_boutique): testata a TRE PIANI — barra di servizio con gli orari,
   riga del marchio, fascia piena con le voci — e ritmo a bande alternate carta/verde.
   Il quarto che si MIGLIORA: niente carrello né apparato negozio (ForgePress non è e-commerce), niente
   sezioni-riempitivo, contrasti misurati, e la tipografia non è il Roboto di sistema del template. */

/* ============================ primitive di impaginazione ============================ */
.container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: var(--gutter); }
.container--narrow { max-width: var(--container-narrow); }

.section { padding-block: var(--section-y); background: var(--paper); }
.section--alt { background: var(--surface); }
.section--tight { padding-block: calc(var(--section-y) * .6); }

.section-intro { margin-bottom: var(--space-7); }
.section-intro h2 { margin-bottom: var(--space-3); }

/* Filetto di chiusura: separa senza disegnare una riga piena da modulo burocratico. */
.rule { height: 3px; width: 56px; background: var(--brand-mark); border-radius: var(--radius-pill); }

/* ============================ bottoni ============================ */
.btn {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-family: var(--font-display); font-weight: 600; font-size: var(--text-base);
  padding: .8em 1.5em; border-radius: var(--radius-pill);
  background: var(--brand); color: var(--on-dark);
  transition: background var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.btn:hover { background: var(--brand-mid); }
.btn:active { transform: translateY(1px); }
/* ⚠ Il fantasma vive su fondo CHIARO: il bordo è il filetto, il testo il verde che porta testo (6,17). */
.btn--ghost { background: transparent; color: var(--brand); box-shadow: inset 0 0 0 2px var(--brand); }
.btn--ghost:hover { background: var(--surface); }
/* Su banda piena il bottone si inverte: carta con testo verde. Mai il verde di marca, che col bianco fa 2,62. */
.btn--on-dark { background: var(--paper); color: var(--brand); }
.btn--on-dark:hover { background: var(--accent-lt); }
/* Variante secondaria su fondo chiaro: campitura tenue di marca con l'inchiostro sopra.
   ⚠ Il fondo è --surface-2, non --brand-mark: sul verde del marchio l'inchiostro passa (6,02) ma la
   campitura piena a quella saturazione grida, e in una farmacia il richiamo secondario non deve gridare. */
.btn--accent { background: var(--surface-2); color: var(--ink); }
.btn--accent:hover { background: var(--accent-lt); }
@media (prefers-reduced-motion: reduce) { .btn { transition: none; } }

/* ============================ testata, piano 1: barra di servizio ============================ */
/* Gli orari sono l'informazione più cercata di una farmacia e il cliente li ha già scritti come riga di
   servizio. Sta in cima, scorre via col contenuto: non merita spazio permanente. */
.topbar { background: var(--brand-dark); color: var(--on-dark); font-size: var(--text-sm); }
.topbar__row {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-5);
  padding-block: var(--space-3); justify-content: space-between;
}
.topbar__item { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--on-dark-muted); }
.topbar__item strong { color: var(--on-dark); font-weight: 600; }
.topbar__item a:hover { color: var(--on-dark); text-decoration: underline; }
.topbar__item svg { width: 1em; height: 1em; flex: none; }
@media (max-width: 599.98px) { .topbar__row { justify-content: center; } }

/* ============================ testata, piano 2: marchio e recapiti ============================ */
/* ⚠⚠ UNA SOLA RIGA: marchio, voci e richiamo stanno sulla stessa linea. La fascia verde separata sotto
   l'intestazione — che nasceva dal template di categoria — spingeva le voci a capo e apriva sopra la
   testata una banda di colore vuota alta quanto lei. Un menu che va a capo sotto il logo si legge come
   un errore di impaginazione, non come una scelta. */
.site-header {
  background: var(--paper); border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 50;
  transition: box-shadow var(--dur) var(--ease), padding var(--dur) var(--ease);
}
/* L'intestazione si assottiglia allo scorrimento (aggancio .fp-shrink letto da reveal.js). */
.site-header.is-scrolled { box-shadow: var(--shadow-md); }
.site-header.is-scrolled .site-header__row { padding-block: var(--space-3); }
.site-header__row {
  display: flex; align-items: center; gap: var(--space-5);
  padding-block: var(--space-4);
  transition: padding var(--dur) var(--ease);
}
@media (prefers-reduced-motion: reduce) { .site-header, .site-header__row { transition: none; } }
/* Marchio a fianco del titolo (regola 7): l'SVG resta compatto e non si deforma mai. */
.wordmark { display: inline-flex; align-items: center; gap: var(--space-3); }
.wordmark__mark { width: 48px; height: 48px; flex: none; }
.wordmark__name {
  font-family: var(--font-display); font-weight: 600; font-size: var(--text-lg);
  line-height: 1.1; color: var(--ink); letter-spacing: -0.01em;
}
.wordmark__tag { display: block; font-family: var(--font-body); font-size: var(--text-sm);
  font-weight: 400; color: var(--ink-muted); letter-spacing: var(--tracking-label); text-transform: uppercase; }

/* ⚠ L'auto-margine sta SOLO sulle voci: metterlo anche qui creerebbe due spinte concorrenti e il gruppo
   voci+richiamo si spaccherebbe ai due estremi. Regola 4: il richiamo non si attacca al bordo. */
.site-header__cta { margin-left: var(--space-5); align-self: center; }
@media (max-width: 1023.98px) { .site-header__cta { display: none; } }

/* ============================ le voci, in linea col marchio ============================ */
/* `margin-left:auto` spinge il gruppo voci+richiamo a destra: il marchio resta ancorato a sinistra e la
   riga non si spezza mai. ⚠ Su mobile l'hamburger eredita questa posizione, quindi resta a DESTRA e
   allineato al logo invece di finire sotto. */
/* ⚠⚠ Il blocco nav di WP porta `width:100%` su QUATTRO livelli annidati (nav, responsive-container,
   container-content, ul). Con `margin-left:auto` sulla sola nav quel 100% si misura sullo spazio
   residuo e il richiamo finisce FUORI dal viewport: misurato 238px di sfondamento, e 441px dopo un
   `flex-shrink:0` che sembrava la cura. La larghezza va riportata al CONTENUTO su tutti e quattro i
   livelli — correggerne uno solo sposta il problema, non lo chiude.
   ⚠ L'ancoraggio lo dà `margin-right:auto` sul MARCHIO, non un auto-margine sulla nav: così la riga ha
   una sola spinta e i due gruppi non si contendono lo spazio. */
/* ⚠⚠ NIENTE `margin-right: auto` sul marchio: un margine automatico ASSORBE tutto lo spazio libero
   PRIMA che flex-grow lo distribuisca, quindi la nav con base 0 riceveva zero e la prima voce usciva
   dal bordo sinistro. La riga è già `space-between` dal blocco: la spinta ce l'ha di suo. */
/* ⚠⚠ I gusci dell'overlay (container, close, dialog, container-content) esistono per il menu MOBILE, ma
   a desktop restano nel flusso e continuano a MISURARE largo: ridimensionarli non basta, perché la
   larghezza naturale della nav è la loro. Misurato in fila: 1360px → 1130 con `fit-content`, mai sotto.
   La cura è toglierli dal layout con `display: contents`, così la lista delle voci diventa figlia
   diretta della nav e la riga si misura sulle voci.
   ⚠ Vale SOLO sopra la soglia mobile: sotto, quei gusci SONO l'overlay e vanno lasciati intatti —
   `display:contents` lì spegnerebbe l'apertura del menu. */
@media (min-width: 600px) {
  .site-header__row .site-nav .wp-block-navigation__responsive-container,
  .site-header__row .site-nav .wp-block-navigation__responsive-close,
  .site-header__row .site-nav .wp-block-navigation__responsive-dialog,
  .site-header__row .site-nav .wp-block-navigation__responsive-container-content {
    display: contents;
  }
  /* ⚠ Selettori di ELEMENTO+classe (nav.site-nav / ul.wp-…): il CSS dei blocchi è iniettato dopo il
     tema, quindi a pari specificità vince lui. Qui il livello in più lo dà il nome del tag, non un
     !important — misurato: con la sola classe la lista resta a 1360px dentro una riga da 1200. */
  /* ⚠⚠ La nav SI RESTRINGE sullo spazio disponibile invece di misurarsi sul contenuto: `flex: 1 1 auto`
     + `min-width: 0` è ciò che permette a un figlio flex di scendere sotto la propria larghezza
     naturale. Chiedere alla nav di misurarsi sul contenuto (`fit-content`, `max-content`, `flex:0 0
     auto`) la lasciava a 1360px dentro una riga da 1200 — e nessuna regola dichiarava quella misura:
     veniva dal LAYOUT, non da una proprietà, per questo alzare la specificità non serviva a niente.
     ⚠ La classe `site-nav` WP la mette anche sulla UL, non solo sulla nav: i selettori vanno qualificati
     col tag, sennò una regola pensata per il contenitore colpisce pure la lista. */
  /* ⚠ `min-width: 0` NON va rimesso: azzerando la dimensione minima automatica la nav scende sotto il
     proprio contenuto e la prima voce esce dal bordo SINISTRO (misurato: «Home» a x=-29). Senza
     l'override, la minima automatica di un figlio flex è il suo min-content, che è esattamente il
     vincolo giusto: si restringe fin dove le voci ci stanno, e non oltre. */
  /* ⚠⚠ `flex: 1 1 0` — base ZERO, non `auto`. È il punto che ha richiesto sei tentativi: con base `auto`
     la nav parte dalla propria larghezza naturale (1360px, che nessuna regola dichiara — viene dal
     layout del blocco WP) e ogni tentativo di farla misurare sul contenuto la lasciava lì. Con base 0
     prende ESATTAMENTE lo spazio che avanza fra marchio e richiamo, e la lista si allinea a destra
     dentro quello spazio. `min-width: 0` qui è necessario e innocuo: la larghezza non la decide più il
     contenuto. */
  .site-header__row nav.site-nav { flex: 1 1 0; min-width: 0; width: auto; }
  .site-header__row nav.site-nav ul.wp-block-navigation__container {
    width: 100%; max-width: 100%; flex-wrap: nowrap; justify-content: flex-end;
  }
}

.site-nav .wp-block-navigation-item__content {
  font-family: var(--font-display); font-weight: 500; color: var(--ink);
  padding-block: var(--space-2); display: inline-block;
  position: relative;
}
/* Sottolineatura che cresce dal centro: il richiamo è il movimento, non un cambio di colore secco. */
.site-nav .wp-block-navigation-item__content::after {
  content: ""; position: absolute; left: 50%; right: 50%; bottom: 0; height: 2px;
  background: var(--brand-mark); border-radius: var(--radius-pill);
  transition: left var(--dur) var(--ease), right var(--dur) var(--ease);
}
.site-nav .wp-block-navigation-item__content:hover { color: var(--brand); }
.site-nav .wp-block-navigation-item__content:hover::after { left: 0; right: 0; }
.site-nav .current-menu-item > .wp-block-navigation-item__content { color: var(--brand); font-weight: 600; }
.site-nav .current-menu-item > .wp-block-navigation-item__content::after { left: 0; right: 0; }
@media (prefers-reduced-motion: reduce) { .site-nav .wp-block-navigation-item__content::after { transition: none; } }
/* ⚠ Una ul di wp:navigation nasce flex-wrap:wrap: con una voce in più una va orfana su due righe.
   Con NOVE voci (il menu di questa farmacia è lungo) il rischio è concreto: sopra i 900px si impone nowrap. */
@media (min-width: 900px) { .site-nav .wp-block-navigation__container { flex-wrap: nowrap; } }
/* ⚠ La fascia è appiccicata in alto: `overflow-x: clip` sulle sezioni (base.css) non la rompe, `hidden` sì. */

/* --- Menu mobile: overlay di wp:navigation (regola 15).
   ⚠ WP tiene l'overlay bianco con un selettore a specificità (0,4,0): si vince solo RICOPIANDONE lo
   schema, non aggiungendo una classe.
   ⚠⚠ E NON BASTA allineare le voci: il contenitore `__responsive-container-content` è largo quanto il
   viewport e nasce `justify-content: flex-end`, quindi le voci restano schiacciate a DESTRA e vanno
   fuori schermo anche con `text-align: left` sul figlio. Il colpevole è il PRIMO ANTENATO largo quanto
   lo schermo con l'allineamento contrario: si corregge lì, risalendo la catena.
   ⚠ L'overlay è CARTA con inchiostro scuro, non verde: su fondo verde le voci figlie (Telemedicina,
   Esami, i quattro reparti) perderebbero la gerarchia, e il verde di marca non porta il bianco. --- */
.wp-block-navigation__responsive-container.is-menu-open {
  height: 100vh; max-height: 100vh; overflow-y: auto; -webkit-overflow-scrolling: touch;
}
.wp-block-navigation__responsive-container.is-menu-open:not(.has-background):not(.disable-default-overlay) { background: var(--paper); }
/* ⚠ Il padding orizzontale va sul CONTENUTO, non sull'overlay: sull'overlay WP lo azzera e la regola
   sparisce senza lasciare traccia. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
  width: 100%; align-items: stretch; justify-content: flex-start;
  padding-inline: var(--gutter); padding-bottom: 96px;
}
/* ⚠ Il contenitore delle voci nasce `align-items: flex-end` e il nostro `stretch` a pari specificità
   perde contro il CSS dei blocchi, che è iniettato DOPO il tema: serve un livello in più. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__container {
  width: 100%; align-items: stretch; gap: 0;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item { width: 100%; }
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content {
  width: 100%; text-align: left; font-family: var(--font-display); font-weight: 600;
  font-size: 1.28rem; color: var(--ink);
  padding-block: var(--space-4); border-bottom: 1px solid var(--line);
}
/* Le voci figlie rientrano e si alleggeriscono: nove voci su due livelli senza gerarchia sono un muro. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
  font-size: 1.05rem; font-weight: 400; color: var(--ink-muted); padding-left: var(--space-5);
}
/* ⚠ Il bottone di chiusura di WP nasce minuscolo e SENZA area di tocco: sotto i 44px non rispetta il
   bersaglio minimo, e appiccicato al bordo sembra un refuso. */
.wp-block-navigation__responsive-container-close,
.wp-block-navigation__responsive-container .wp-block-navigation__responsive-container-close {
  top: var(--space-5); right: var(--gutter);
  width: 48px; height: 48px; padding: 10px;
  color: var(--ink); background: var(--surface); border-radius: var(--radius-pill);
}
.wp-block-navigation__responsive-container-close svg { width: 28px; height: 28px; }
.wp-block-navigation__responsive-container-close:hover { background: var(--surface-2); }
/* ⚠ L'hamburger vive ORA su carta bianca, non piu' sulla fascia verde: porta l'inchiostro. Con il
   bianco sarebbe invisibile — e' lo stesso colore che aveva quando il fondo era verde. */
.wp-block-navigation__responsive-container-open { width: 48px; height: 48px; padding: 10px; color: var(--ink); }
.wp-block-navigation__responsive-container-open svg { width: 28px; height: 28px; }

/* ============================ testata di pagina (il segno del verticale) ============================ */
/* Campitura piena e fotografia AFFIANCATE, non sovrapposte: il contrasto del titolo è STRUTTURALE e non
   dipende dal fotogramma. ⚠ È la ragione per cui la palette non deve coprire «testo sopra foto»: qui non
   accade mai. Le foto reali di questa farmacia arrivano da un upscale 2x e non reggerebbero un velo. */
/* ⚠⚠ `display: flex` sulla testata: da blocco, il nodo di testo che il wrapper `wp:html` lascia prima
   della griglia genera una LINE BOX di 16px e spinge giù entrambe le colonne — la striscia di colore
   sopra la fotografia era quella. Un contenitore flex ignora il testo di soli spazi bianchi.
   ⚠ Diagnosticato misurando: colonne ad altezza GIUSTA (660) e posizione sbagliata (+16), quindi né
   ancorare l'immagine né azzerare margini e gap potevano bastare. */
.hero { background: var(--paper); display: flex; flex-direction: column; }
.hero > .hero__split { flex: 1 1 auto; }
.hero__split {
  display: grid; grid-template-columns: 1fr calc(100% * var(--hero-media-share));
  grid-template-rows: 1fr;
  min-height: clamp(420px, 52vw, 660px);
  align-items: stretch;
  /* ⚠⚠ `gap: 0` e UNA riga esplicita: il block-gap che WP applica ai gruppi vale anche sulla griglia, e
     con una riga implicita in più spingeva ENTRAMBE le colonne 16px più in basso lasciando scoperta una
     striscia di colore sopra la fotografia. Le colonne avevano altezza giusta e posizione sbagliata —
     per questo ancorare l'immagine non bastava. */
  gap: 0;
}
/* ⚠⚠ `align-items: stretch` + `height:100%` sulla figura: senza, la fotografia si allinea in alto dentro
   una cella più alta di lei e sopra resta una banda di colore vuota. Era il difetto visibile in testata. */
.hero__panel {
  background: linear-gradient(155deg, var(--brand-mid) 0%, var(--brand) 45%, var(--brand-dark) 100%);
  color: var(--on-dark);
  display: flex; flex-direction: column; justify-content: center;
  padding: var(--space-8) var(--gutter);
  position: relative; overflow: hidden;
}
/* Croce di farmacia in filigrana: profondità senza rumore, e non è una foto finta. */
.hero__panel::after {
  content: ""; position: absolute; right: -6%; top: -12%; width: 46%; aspect-ratio: 1;
  background: var(--on-dark); opacity: .05;
  -webkit-mask: url("../assets/img/icons/cross.svg") center / contain no-repeat;
  mask: url("../assets/img/icons/cross.svg") center / contain no-repeat;
  pointer-events: none;
}
.hero__panel > * { max-width: 34rem; }
.hero__panel .eyebrow { color: var(--accent-lt); }
.hero__panel h1 { color: var(--on-dark); margin-bottom: var(--space-4); }
.hero__panel p { color: var(--on-dark-muted); font-size: var(--text-md); }
.hero__cta { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-6); }
/* La figura riempie la cella per intero: nessuna banda di colore residua sopra o sotto la fotografia. */
/* ⚠⚠ La fotografia è ANCORATA ai quattro lati (`position:absolute; inset:0`), non semplicemente alta
   il 100%: dentro un `wp:html` il blocco lascia comunque 16px sopra l'immagine — misurati — e quello
   scarto si legge come una striscia di colore sopra la testata. Con l'ancoraggio il riquadro è pieno
   per costruzione, qualunque margine il blocco introduca. */
/* ⚠ I due lati della testata non devono portare margini: il block-gap che WP mette sui figli sposta
   la colonna della fotografia di 15px verso il basso, e riappare la striscia di colore in alto. */
/* ⚠⚠ Colonne inchiodate alla PRIMA riga e alla propria colonna: senza il posizionamento esplicito una
   riga implicita generata dal wrapper del blocco le faceva scivolare in riga 2, 15px più in basso —
   con l'altezza giusta, quindi il difetto si vedeva solo come striscia di colore in cima. */
.hero__split > * { margin: 0; grid-row: 1; align-self: stretch; }
.hero__split > .hero__panel { grid-column: 1; }
.hero__split > .hero__media { grid-column: 2; }
/* ⚠ Niente `height:100%` né `min-height:inherit` qui: una dimensione ESPLICITA su un elemento di griglia
   disattiva lo stiramento di `align-self:stretch`, e la colonna si ritrova alta quanto la riga ma
   posizionata come se fosse più corta — misurato: box alto 660 dentro una riga da 660, ma a +16.
   Lasciando decidere allo stiramento, posizione e altezza vengono dalla stessa regola. */
/* ⚠⚠ La fotografia esce dalla GRIGLIA e si ancora alla SEZIONE. Dentro la griglia la colonna restava
   ostinatamente a +16px — con altezza corretta — qualunque combinazione di margini, gap, righe
   esplicite, stretch o dimensioni si provasse (sei tentativi, tutti misurati): l'offset nasce dal
   wrapper che il blocco `wp:html` interpone e non è raggiungibile dalle proprietà della cella.
   Ancorandola alla sezione, che È a filo, il riquadro è pieno per costruzione.
   ⚠ La larghezza deriva dallo STESSO token delle colonne: una sola dichiarazione, due consumatori. */
.hero { position: relative; }
/* ⚠⚠ NIENTE `.reveal` sulla testata: la rivelazione parte da `translateY(16px)`, e una trasformazione
   non solo SPOSTA — crea anche un blocco contenitore per i discendenti posizionati. Il risultato era
   una striscia di colore di 16px sopra la fotografia che nessuna proprietà della griglia poteva
   chiudere, perché non veniva dalla griglia. In più la testata è sopra la piega: rivelarla significa
   animare ciò che l'utente sta già guardando. */
.hero .reveal { transform: none; }
.hero__media {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: calc(100% * var(--hero-media-share)); overflow: hidden;
}
.hero__media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
/* Sfumatura di raccordo: la fotografia entra nella campitura invece di tagliarsi di netto. */
.hero__media::before {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(90deg, var(--brand-dark) 0%, transparent 14%);
  opacity: .55;
}
/* Ken Burns lentissimo: la testata respira invece di stare ferma. Si spegne con reduced-motion. */
@media (prefers-reduced-motion: no-preference) {
  /* � Il movimento sposta object-position, NON scala l'immagine: una `transform: scale` allarga il
     rettangolo dell'elemento e i misuratori la contano come sfondamento orizzontale (6px, misurati),
     anche quando il genitore la ritaglia e a occhio non si vede nulla. */
  .hero__media img { animation: heroPan 30s var(--ease) infinite alternate; }
  @keyframes heroPan { from { object-position: 46% 50%; } to { object-position: 60% 50%; } }
}
/* Variante design: nessuna foto all'altezza. La campitura prende tutta la banda e porta un motivo di
   croci, mai una foto finta (regola: la variante design esiste apposta). */
.hero--design .hero__split { grid-template-columns: 1fr; }
.hero--design .hero__panel { align-items: center; text-align: center; background: var(--brand); }
.hero--design .hero__panel > * { max-width: 46rem; }
@media (max-width: 899.98px) {
  .hero__split { grid-template-columns: 1fr; }
  .hero__media { min-height: 260px; order: -1; }
}

/* Testata delle pagine interne: NON riusa la size della testata di home (regola 6). */
.page-head { background: var(--surface); padding-block: var(--space-8) var(--space-7); }
.page-head h1 { font-size: var(--text-2xl); margin-bottom: var(--space-3); }
.page-head p { color: var(--ink-muted); font-size: var(--text-md); }

/* --- Testata di pagina FOTOGRAFICA: la fotografia sta sotto, il testo su una velatura verde.
   ⚠ Qui il testo È sopra la foto, quindi i rapporti della palette non bastano: la velatura è un
   gradiente che dal basso arriva quasi opaco, e il titolo vive nella parte più densa. Sopra c'è il
   colore pieno, non il fotogramma. --- */
.page-head--photo { position: relative; background: var(--brand-dark); padding-block: var(--space-9) var(--space-8); overflow: hidden; }
.page-head__media { position: absolute; inset: 0; }
.page-head__media img { width: 100%; height: 100%; object-fit: cover; }
.page-head--photo::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(47,85,22,.62) 0%, rgba(47,85,22,.80) 55%, rgba(47,85,22,.94) 100%);
}
.page-head__inner { position: relative; z-index: 1; }
.page-head--photo h1, .page-head--photo .page-head__lead { color: var(--on-dark); }
.page-head--photo .eyebrow { color: var(--accent-lt); }
.page-head__lead { font-size: var(--text-md); max-width: 60ch; }
/* Briciole: dicono DOVE si è, e su un sito a tre livelli non sono decoro. */
.crumbs { font-size: var(--text-sm); color: var(--on-dark-muted); margin-bottom: var(--space-4); }
.crumbs a { text-decoration: underline; text-underline-offset: 3px; }
.crumbs a:hover { color: var(--on-dark); }

/* ============================ servizi sanitari (3 schede) ============================ */
.servizi__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-5); }
.servizio {
  display: flex; flex-direction: column;
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-lg);
  overflow: hidden; transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.servizio:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.servizio__fig { aspect-ratio: 4 / 3; background: var(--surface-2); }
.servizio__fig img { width: 100%; height: 100%; object-fit: cover; }
.servizio__body { padding: var(--space-5); display: flex; flex-direction: column; flex: 1; }
.servizio h3 { margin-bottom: var(--space-3); }
.servizio p { color: var(--ink-muted); flex: 1; }
/* Regola 12: la scheda linka DIRITTO alla pagina, non a un indice intermedio. */
.servizio__more { margin-top: var(--space-4); color: var(--brand); font-weight: 600; font-family: var(--font-display); }
.servizio__more::after { content: " →"; }
@media (max-width: 899.98px) { .servizi__grid { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) { .servizio { transition: none; } .servizio:hover { transform: none; } }

/* ============================ chi siamo (banda piena + foto) ============================ */
/* La fascia editoriale di PharmaCare: metà colore che parla, metà fotografia dei farmacisti. */
.chisiamo { background: var(--brand); color: var(--on-dark); }
.chisiamo__split { display: grid; grid-template-columns: 1fr 1fr; align-items: stretch; }
.chisiamo__body { padding: var(--section-y) var(--gutter); display: flex; flex-direction: column; justify-content: center; }
.chisiamo__body > * { max-width: 36rem; }
.chisiamo__body .eyebrow { color: var(--accent-lt); }
.chisiamo__body h2 { color: var(--on-dark); margin-bottom: var(--space-4); }
.chisiamo__body p { color: var(--on-dark-muted); }
.chisiamo__fig img { width: 100%; height: 100%; object-fit: cover; min-height: 320px; }
/* Le tre prove di fiducia sotto il testo: elenco, non contatori inventati. */
.checks { display: grid; gap: var(--space-3); margin-top: var(--space-6); }
.checks li { display: flex; align-items: flex-start; gap: var(--space-3); color: var(--on-dark); }
.checks li::before {
  content: ""; flex: none; width: 1.35em; height: 1.35em; margin-top: .1em;
  background: var(--accent-lt); border-radius: var(--radius-pill);
  /* La spunta è disegnata dalla maschera, non da un glifo: resta nitida a ogni scala.
     ⚠ L'url() della maschera si risolve rispetto al FOGLIO, mai da uno style inline nel post_content. */
  -webkit-mask: url("../assets/img/icons/check.svg") center / 62% no-repeat;
  mask: url("../assets/img/icons/check.svg") center / 62% no-repeat;
}
@media (max-width: 899.98px) {
  .chisiamo__split { grid-template-columns: 1fr; }
  .chisiamo__fig { order: -1; }
}

/* ============================ reparti (4 schede merceologiche) ============================ */
.reparti__grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-5); }
.reparto {
  display: flex; flex-direction: column;
  border-radius: var(--radius-lg); overflow: hidden; background: var(--paper);
  border: 1px solid var(--line);
}
.reparto__fig { aspect-ratio: 3 / 2; background: var(--surface-2); }
.reparto__fig img { width: 100%; height: 100%; object-fit: cover; }
.reparto__body { padding: var(--space-5); display: flex; flex-direction: column; flex: 1; }
/* L'icona è ancorata al SIGNIFICATO della voce, non alla sua posizione: `data-icon` viene dall'IR e la
   maschera vive qui nel foglio. ⚠ Un'icona copiata per SLOT finisce sulla voce sbagliata appena il
   progetto elenca i reparti nel proprio ordine. */
.reparto__icon {
  width: 42px; height: 42px; margin-bottom: var(--space-3);
  background: var(--brand-mark); border-radius: var(--radius);
  -webkit-mask: var(--icon-src) center / 60% no-repeat; mask: var(--icon-src) center / 60% no-repeat;
}
.reparto[data-icon="infanzia"]      { --icon-src: url("../assets/img/icons/infanzia.svg"); }
.reparto[data-icon="dermocosmesi"]  { --icon-src: url("../assets/img/icons/dermocosmesi.svg"); }
.reparto[data-icon="integratori"]   { --icon-src: url("../assets/img/icons/integratori.svg"); }
.reparto[data-icon="veterinaria"]   { --icon-src: url("../assets/img/icons/veterinaria.svg"); }
.reparto h3 { margin-bottom: var(--space-2); }
.reparto p { color: var(--ink-muted); font-size: var(--text-base); flex: 1; }
.reparto__more { margin-top: var(--space-4); color: var(--brand); font-weight: 600; font-family: var(--font-display); }
.reparto__more::after { content: " →"; }
@media (max-width: 1023.98px) { .reparti__grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 599.98px) { .reparti__grid { grid-template-columns: 1fr; } }

/* ============================ marchi trattati ============================ */
/* Per un rivenditore multi-marca il muro dei marchi è sostanza, non decoro: qui i nomi sono TESTO, non
   loghi di terzi, perché i marchi di questo cliente non ci sono stati forniti come file. */
.marchi__list { display: flex; flex-wrap: wrap; gap: var(--space-3); justify-content: center; }
.marchi__list li {
  font-family: var(--font-display); font-weight: 500; color: var(--ink-muted);
  border: 1px solid var(--line); border-radius: var(--radius-pill);
  padding: .45em 1.1em; background: var(--paper);
}

/* ============================ galleria ============================ */
/* Le foto reali della farmacia. ⚠ Vengono da un upscale 2x di scatti 900x675: reggono la tessera, non
   il velo né il testo sopra. Mosaico a tessere, mai una banda a piena pagina con scritte. */
/* ⚠⚠ Il mosaico a tessere di misura diversa lasciava un BUCO in basso a destra: con cinque foto e una
   tessera doppia, l'ultima riga non si chiude mai. Qui le righe sono ESPLICITE e la somma torna sempre:
   riga 1 = una foto larga due colonne + una alta due righe; riga 2 = due foto. Nessuna cella vuota. */
.gallery__grid {
  /* ⚠ DUE colonne, non tre: a tre, una tessera su una colonna da 1200 misura 366px e copre il 10% del
     viewport — sotto la soglia oltre la quale una fotografia «pesa» in pagina. A due colonne la tessera
     raddoppia (588px, ~27%) e sei foto fanno comunque tre righe PIENE: l'allineamento non si perde. */
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: var(--space-4);
}
.gallery__grid li { min-width: 0; }
.gallery__grid img {
  width: 100%; height: 100%; object-fit: cover; border-radius: var(--radius-lg); display: block;
  transition: transform var(--dur) var(--ease), filter var(--dur) var(--ease);
}
.gallery__grid li:hover img { transform: scale(1.035); filter: saturate(1.08); }
/* insegna: due colonne per una riga · interno alto: una colonna per due righe · le altre tre a modulo */
/* ⚠⚠ Tessere TUTTE UGUALI. Il mosaico a misure diverse (una larga due colonne, una alta due righe) non
   chiude mai l'ultima riga: con sei foto restano due celle vuote in basso a destra, ed è esattamente lo
   spazio bianco che si vedeva. Sei tessere uniformi su tre colonne fanno due righe piene, sempre. */
/* ⚠⚠ Una tessera LARGA due colonne in testa, poi quattro quadrate: cinque foto in tre righe PIENE.
   L'aritmetica è il vincolo, non il gusto — su due colonne la tessera larga occupa due celle, quindi il
   totale deve restare PARI: 2 + 4 = 6 celle = 3 righe esatte. Con sei foto (2 + 5 = 7 celle) il buco in
   fondo tornerebbe, ed è il difetto da cui siamo partiti.
   La prima è panoramica (16/7): larga il doppio senza diventare alta il doppio. */
.gallery__grid li:first-child { grid-column: 1 / -1; }
.gallery__grid li:first-child img { aspect-ratio: 16 / 7; }
.gallery__grid img { aspect-ratio: 1 / 1; }
@media (max-width: 899.98px) {
  .gallery__grid { grid-template-columns: 1fr; }
  .gallery__grid li:first-child img { aspect-ratio: 4 / 3; }
  .gallery__grid li:nth-child(1) { grid-column: span 2; }
  .gallery__grid li:nth-child(2) { grid-row: auto; }
  /* ⚠⚠ Una tessera LARGA due colonne in testa, poi quattro quadrate: cinque foto in tre righe PIENE.
   L'aritmetica è il vincolo, non il gusto — su due colonne la tessera larga occupa due celle, quindi il
   totale deve restare PARI: 2 + 4 = 6 celle = 3 righe esatte. Con sei foto (2 + 5 = 7 celle) il buco in
   fondo tornerebbe, ed è il difetto da cui siamo partiti.
   La prima è panoramica (16/7): larga il doppio senza diventare alta il doppio. */
.gallery__grid li:first-child { grid-column: 1 / -1; }
.gallery__grid li:first-child img { aspect-ratio: 16 / 7; }
.gallery__grid img { aspect-ratio: 1 / 1; }
}
@media (prefers-reduced-motion: reduce) { .gallery__grid img { transition: none; } .gallery__grid li:hover img { transform: none; } }

/* ============================ fidelity (bersaglio dell'ancora di menu) ============================ */
/* ⚠ «Fidelity Card» in menu è un'ANCORA verso questa sezione in home: l'id è parte del contratto con la
   navigazione, non un dettaglio. `scroll-margin-top` sta in base.css su :target. */
.fidelity { background: var(--brand-dark); color: var(--on-dark); }
.fidelity__split { display: grid; grid-template-columns: 1.05fr .95fr; gap: var(--space-7); align-items: center; }
.fidelity__body { padding-block: var(--section-y); }
.fidelity .eyebrow { color: var(--accent-lt); }
.fidelity h2 { color: var(--on-dark); margin-bottom: var(--space-4); }
.fidelity p { color: var(--on-dark-muted); }
.fidelity__cta { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-6); }
/* La copertina del catalogo è un'ANTEPRIMA rasterizzata (regola 10), non un'icona di file. */
.fidelity__fig img { width: 100%; border-radius: var(--radius-lg); box-shadow: var(--shadow-md); }
@media (max-width: 899.98px) {
  .fidelity__split { grid-template-columns: 1fr; gap: var(--space-5); }
  .fidelity__fig { max-width: 320px; }
}

/* ============================ listino (prezzi dei servizi in telemedicina) ============================ */
/* ForgePress non è e-commerce: questi sono prezzi INFORMATIVI di un servizio, senza carrello.
   Pubblicati per decisione esplicita dell'owner — sono già pubblici sul sito del cliente. */
.listino { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-5); }
.listino__voce {
  background: var(--surface); border-radius: var(--radius-lg); padding: var(--space-6);
  border-top: 4px solid var(--brand-mark);
}
.listino__voce h3 { margin-bottom: var(--space-2); }
.listino__prezzo {
  font-family: var(--font-display); font-weight: 600; font-size: var(--text-xl);
  color: var(--brand); display: block; margin-bottom: var(--space-3);
}
.listino__voce p { color: var(--ink-muted); font-size: var(--text-base); }
@media (max-width: 899.98px) { .listino { grid-template-columns: 1fr; } }

/* ============================ domande frequenti ============================ */
/* 28 coppie su sette pagine: `<details>` NATIVO, zero JavaScript. ⚠ La CSP è nonce-based e vieta gli
   script inline sui progetti reali (regola 22): una fisarmonica scriptata qui sarebbe irricevibile. */
.faq { display: grid; gap: var(--space-3); }
.faq details {
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius);
  padding: var(--space-4) var(--space-5);
}
.faq summary {
  font-family: var(--font-display); font-weight: 600; font-size: var(--text-base);
  cursor: pointer; list-style: none; display: flex; gap: var(--space-4); align-items: flex-start;
  color: var(--ink);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+"; margin-left: auto; flex: none;
  font-weight: 400; font-size: 1.5em; line-height: 1; color: var(--brand);
}
.faq details[open] summary::after { content: "−"; }
.faq details[open] summary { margin-bottom: var(--space-3); }
.faq details > p { color: var(--ink-muted); max-width: 68ch; }

/* ============================ prosa delle pagine interne ============================ */
/* I testi di questo cliente sono LUNGHI (paragrafi di reparto oltre i 400 caratteri): il ritmo verticale
   conta più che altrove. La misura di lettura sta sul paragrafo (base.css), non sul contenitore. */
.prose > * + * { margin-top: var(--space-4); }
.prose h2 { margin-top: var(--space-7); }
.prose h3 { margin-top: var(--space-6); }
.prose ul { display: grid; gap: var(--space-2); }
.prose ul li { position: relative; padding-left: var(--space-5); color: var(--ink-muted); }
.prose ul li::before {
  content: ""; position: absolute; left: 0; top: .62em;
  width: .5em; height: .5em; border-radius: var(--radius-pill); background: var(--brand-mark);
}
.prose strong { color: var(--ink); font-weight: 600; }
/* Regola 13: la foto sta SOTTO o DI FIANCO al testo che descrive, mai orfana in fondo alla pagina.
   Regola 21: il margine sopra e sotto una figura è lo stesso. */
.fig { margin-block: var(--space-6); }
.fig img { width: 100%; border-radius: var(--radius-lg); }
.fig figcaption { margin-top: var(--space-3); font-size: var(--text-sm); color: var(--ink-muted); }

/* ============================ le due sedi ============================ */
/* business.locations[]: ogni sede porta indirizzo, telefono, email, orari e il PROPRIO map_url.
   ⚠ La mappa è un LINK, mai un iframe: l'invariante zero-live vieta ogni richiesta esterna. Due sedi
   ⇒ DUE link, uno per riquadro: un solo link non può mostrare due segnaposti. */
.sedi { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-5); }
.sede {
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: var(--space-6); display: flex; flex-direction: column;
}
/* ⚠⚠ Il markup della scheda sede NON è nostro: lo emette `sedeCards()` in contract-helpers.mjs, che è
   CONGELATO. Le classi e i tag qui sotto sono quelli che l'helper produce davvero — article.sede > h3 +
   address.sede__addr + table.hours + a.map-link — non quelli che farebbe comodo avere. Chi stila un
   `.sede__row` con dt/dd stila un elemento che a terra non esiste. */
.sede h3 { margin-bottom: var(--space-2); }
.sede__addr { color: var(--ink-muted); margin-bottom: var(--space-4); font-style: normal; line-height: 1.9; }
.sede__addr a:hover { color: var(--brand); text-decoration: underline; }

/* Gli orari sono una TABELLA vera (th di riga + td), non una lista: è la resa giusta per un dato
   tabellare e la didascalia dà il contesto a chi legge con lo screen reader.
   ⚠ Un giorno di chiusura si SCRIVE — «Domenica chiuso» è un'informazione, la sua assenza è un dubbio:
   l'helper aggiunge da sé la riga dei giorni scoperti. */
.hours { width: 100%; border-collapse: collapse; margin-bottom: var(--space-4); }
.hours caption {
  text-align: left; font-family: var(--font-display); font-weight: 600; color: var(--ink);
  padding-bottom: var(--space-2);
}
.hours th, .hours td { text-align: left; padding-block: var(--space-2); border-top: 1px solid var(--line); font-weight: 400; }
.hours th { color: var(--ink); font-weight: 600; }
.hours td { color: var(--ink-muted); text-align: right; }
.hours .is-closed { color: var(--ink-muted); font-style: italic; }

/* Il link alla mappa chiude la scheda e si spinge in fondo, così due sedi con orari diversi restano
   allineate. ⚠ È un LINK esterno, mai un iframe: l'invariante zero-live vieta ogni richiesta di rete,
   e con due sedi servono DUE link — uno per scheda, come li emette l'helper. */
.map-link {
  margin-top: auto; padding-top: var(--space-4);
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-family: var(--font-display); font-weight: 600; color: var(--brand);
}
.map-link::after { content: " ↗"; }
.map-link:hover { text-decoration: underline; text-underline-offset: 3px; }
@media (max-width: 767.98px) { .sedi { grid-template-columns: 1fr; } }

/* ============================ bande di chiamata ============================ */
.cta-band { background: var(--brand); color: var(--on-dark); padding-block: var(--section-y); }
.cta-band__row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-5); justify-content: space-between; }
.cta-band h2 { color: var(--on-dark); }
.cta-band p { color: var(--on-dark-muted); margin-top: var(--space-2); }
.cta-band__cta { display: flex; flex-wrap: wrap; gap: var(--space-3); }

.contact-band { background: var(--surface); padding-block: var(--section-y); }
.contact-band__row { display: grid; grid-template-columns: 1.2fr .8fr; gap: var(--space-7); align-items: start; }
@media (max-width: 899.98px) { .contact-band__row { grid-template-columns: 1fr; } }

/* ============================ piè ============================ */
.site-footer { background: var(--brand-dark); color: var(--on-dark-muted); padding-block: var(--space-8) var(--space-6); }
.site-footer__grid { display: grid; grid-template-columns: 1.3fr 1fr 1fr 1fr; gap: var(--space-6); }
.site-footer__col h4 { color: var(--on-dark); margin-bottom: var(--space-4); font-family: var(--font-display); }
.site-footer__col li + li { margin-top: var(--space-2); }
.site-footer a:hover { color: var(--on-dark); text-decoration: underline; }
/* Colonna orari del piè: una riga per insieme di giorni, giorno a sinistra e fasce a destra.
   ⚠ Il markup lo emette il contratto di resa (hoursFooter), non un pattern: le classi sono quelle. */
.hours-list li { display: flex; justify-content: space-between; gap: var(--space-4); }
.hours-list li span:first-child { color: var(--on-dark); font-weight: 600; }
.hours-list li span:last-child { text-align: right; }
.site-footer__col .sede__addr,
.site-footer__col > span { display: block; margin-bottom: var(--space-3); }
.site-footer .wordmark__name { color: var(--on-dark); }
.site-footer .wordmark__tag { color: var(--on-dark-muted); }
.site-footer__legal {
  margin-top: var(--space-7); padding-top: var(--space-5);
  border-top: 1px solid var(--hairline-on-dark);
  display: flex; flex-wrap: wrap; gap: var(--space-4); justify-content: space-between; align-items: center;
  font-size: var(--text-sm);
}
/* Regola 1: «Powered by Dgitaly» su ogni sito reale. ⚠ Il marchio è QUADRATO e senza scritta: il testo è
   nostro e il logo non si deforma mai. */
.powered { display: inline-flex; align-items: center; gap: var(--space-2); }
.powered img { width: 20px; height: 20px; }
@media (max-width: 899.98px) { .site-footer__grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 599.98px) { .site-footer__grid { grid-template-columns: 1fr; } }

/* ============================ barra di chiamata su mobile ============================ */
/* Su telefono la chiamata è il gesto che una farmacia riceve di più: la barra si fissa in basso e resta
   raggiungibile col pollice. Su desktop non esiste — lì il numero è già nella barra di servizio. */
.cta-bar { display: none; }
@media (max-width: 767.98px) {
  .cta-bar {
    display: block; position: fixed; left: 0; right: 0; bottom: 0; z-index: 55;
    background: var(--brand); box-shadow: var(--shadow-bar);
    padding: var(--space-3) var(--gutter);
    padding-bottom: calc(var(--space-3) + env(safe-area-inset-bottom));
  }
  .cta-bar__call {
    display: block; text-align: center;
    font-family: var(--font-display); font-weight: 600; font-size: var(--text-base);
    color: var(--on-dark); padding-block: var(--space-2);
  }
  /* Il piè deve poter respirare sotto la barra fissa, sennò l'ultima riga resta coperta. */
  .site-footer { padding-bottom: calc(var(--space-6) + 4.5rem); }
}

/* ============================ WhatsApp flottante ============================ */
/* Contenitore inerte: senza `display:contents` il gruppo di blocco creerebbe una scatola vuota nel flusso
   anche quando il cliente non dichiara alcun WhatsApp e lo slot rende stringa vuota. */
.wa-slot { display: contents; }

/* Richiesto dal cliente. È un LINK a wa.me: nessuna richiesta di rete, nessun cookie, zero-live salvo.
   ⚠ Non copre la CTA del piè: si ferma sopra il bordo e lascia respiro al bersaglio di tocco. */
.wa-float {
  position: fixed; right: var(--gutter); bottom: var(--space-5); z-index: 60;
  width: 56px; height: 56px; border-radius: var(--radius-pill);
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--brand); color: var(--on-dark); box-shadow: var(--shadow-md);
  transition: transform var(--dur) var(--ease);
}
.wa-float:hover { transform: scale(1.06); }
.wa-float svg { width: 30px; height: 30px; }
/* ⚠ Su telefono la barra di chiamata occupa lo stesso angolo: senza questo scarto i due bersagli si
   sovrappongono e il pollice ne colpisce uno a caso. Il pulsante sale SOPRA la barra. */
@media (max-width: 767.98px) { .wa-float { bottom: calc(var(--space-5) + 4rem); } }
@media (prefers-reduced-motion: reduce) { .wa-float { transition: none; } .wa-float:hover { transform: none; } }
@media print { .wa-float { display: none; } }

/* ============================ pagina Parafarmacia: la seconda identità ============================ */
/* ⭐ Una sola famiglia di componenti, due vestiti: la classe di pagina RIMAPPA i token di marca sulla
   scala turchese, e ogni componente si riveste da sé senza una riga di CSS duplicata.
   ⚠⚠ La rimappatura è possibile SOLO perché ogni componente qui sopra consuma --brand/--brand-dark e
   mai un colore letterale. Chi scrive un esadecimale in un componente rompe questa proprietà.
   ⚠ Il RAL 6034 (--para-mark) resta marchio e campitura: non entra mai in --brand, che porta il bianco. */
.page-para {
  --brand: var(--para);
  --brand-mid: var(--para);
  --brand-dark: var(--para-deep);
  --brand-mark: var(--para-mark);
  --surface: var(--para-tint);
  --surface-2: var(--para-surface);
  --accent-lt: var(--para-lt);
  --on-dark-muted: var(--para-lt);
  --focus: var(--para);
}

/* ============================ 404 ============================ */
.notfound { padding-block: var(--space-9); text-align: center; background: var(--surface); }
.notfound h1 { margin-bottom: var(--space-4); }
.notfound p { color: var(--ink-muted); margin-inline: auto; }
.notfound .btn { margin-top: var(--space-6); }

/* ============================ profondità: gradienti di banda ============================ */
/* ⚠ I gradienti stanno sugli ELEMENTI, non su pseudo-elementi: una sfumatura messa su ::after non
   partecipa al fondo dell'elemento e non si legge come profondità della banda — vale come decoro.
   Qui ogni superficie piena ha una sua direzione di luce, così le bande non sembrano campiture piatte
   accostate. Le coppie di contrasto restano quelle misurate: il gradiente lavora fra --brand e
   --brand-dark, che portano entrambi il bianco (6,17 e 8,64). */
.section--alt { background: linear-gradient(170deg, var(--surface) 0%, var(--surface-2) 100%); }
.chisiamo { background: linear-gradient(135deg, var(--brand-mid) 0%, var(--brand) 52%, var(--brand-dark) 100%); }
.fidelity { background: linear-gradient(200deg, var(--brand-dark) 0%, var(--brand) 60%, var(--brand-mid) 100%); }
.cta-band { background: linear-gradient(100deg, var(--brand) 0%, var(--brand-dark) 100%); }
.topbar { background: linear-gradient(90deg, var(--brand-dark) 0%, var(--brand) 100%); }
.site-footer { background: linear-gradient(185deg, var(--brand-dark) 0%, var(--footer-deep) 100%); }
/* Le schede prendono luce dall'alto: separa la scheda dal fondo senza disegnarci un bordo attorno. */
.servizio, .reparto, .sede, .listino__voce {
  background: linear-gradient(180deg, var(--paper) 0%, var(--surface) 100%);
}
.page-head { background: linear-gradient(160deg, var(--surface) 0%, var(--surface-2) 100%); }
/* Velo di chiusura sulle fotografie di scheda: le immagini si legano al fondo della scheda. */
.servizio__fig, .reparto__fig { position: relative; }
.servizio__fig::after, .reparto__fig::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 62%, rgba(31,36,32,.16) 100%);
}

/* ============================ movimento: micro-reazioni al puntatore ============================ */
/* Regola 2: le micro-animazioni sono percepibili ma sobrie, e si spengono TUTTE con reduced-motion.
   ⚠ Nessuna tocca l'opacità di un testo vicino alla soglia AA: si muovono ombre, scale e posizioni,
   mai il colore di un corpo di testo. Un sito che non reagisce al puntatore si legge come una bozza. */
.servizio, .reparto, .sede, .listino__voce, .faq details, .marchi__list li {
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.sede:hover, .listino__voce:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.faq details:hover { border-color: var(--brand-mark); }
.marchi__list li:hover { transform: translateY(-2px); border-color: var(--brand-mark); color: var(--ink); }
.reparto:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }
/* La fotografia di scheda si avvicina appena: il movimento è dell'immagine, la scheda resta ferma. */
.servizio__fig img, .reparto__fig img { transition: transform 420ms var(--ease); }
.servizio:hover .servizio__fig img, .reparto:hover .reparto__fig img { transform: scale(1.05); }
/* L'icona di reparto pulsa piano quando la scheda è sotto il puntatore. */
.reparto__icon { transition: transform var(--dur) var(--ease), background-color var(--dur) var(--ease); }
.reparto:hover .reparto__icon { transform: scale(1.12) rotate(-4deg); }
/* Le frecce «Approfondisci» / «Leggi di più» si allungano: dice che portano da qualche parte. */
.servizio__more, .reparto__more, .map-link { transition: gap var(--dur) var(--ease), color var(--dur) var(--ease); display: inline-flex; gap: var(--space-2); }
.servizio:hover .servizio__more, .reparto:hover .reparto__more { gap: var(--space-4); }
/* Il filetto di sezione si allunga entrando in scena. */
.rule { transition: width 600ms var(--ease); }
.section-intro:hover .rule { width: 88px; }
/* Righe di elenco e recapiti: reazione minima, ma c'è. */
.prose ul li, .hours th, .hours td, .site-footer a, .topbar__item a {
  transition: color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.site-footer a:hover, .topbar__item a:hover { transform: translateX(2px); }
.prose ul li::before { transition: transform var(--dur) var(--ease), background-color var(--dur) var(--ease); }
.prose ul li:hover::before { transform: scale(1.5); }
/* I bottoni prendono un'ombra crescente oltre al colore. */
.btn { transition: background var(--dur) var(--ease), transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease); }
.btn:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
/* Le tessere della galleria: già animate, qui si aggiunge l'ombra. */
.gallery__grid li { transition: box-shadow var(--dur) var(--ease); border-radius: var(--radius-lg); overflow: hidden; }
.gallery__grid li:hover { box-shadow: var(--shadow-md); }
/* Le figure della prosa reagiscono anch'esse: sono contenuto, non ornamento. */
.fig img { transition: transform 420ms var(--ease), box-shadow var(--dur) var(--ease); }
.fig:hover img { transform: scale(1.02); box-shadow: var(--shadow-md); }

@media (prefers-reduced-motion: reduce) {
  .servizio, .reparto, .sede, .listino__voce, .faq details, .marchi__list li,
  .servizio__fig img, .reparto__fig img, .reparto__icon, .servizio__more, .reparto__more,
  .map-link, .rule, .prose ul li, .site-footer a, .topbar__item a, .btn,
  .gallery__grid li, .fig img, .prose ul li::before { transition: none; }
  .sede:hover, .listino__voce:hover, .reparto:hover, .marchi__list li:hover, .btn:hover,
  .servizio:hover .servizio__fig img, .reparto:hover .reparto__fig img,
  .reparto:hover .reparto__icon, .fig:hover img, .site-footer a:hover, .topbar__item a:hover,
  .prose ul li:hover::before { transform: none; }
}

/* ============================ nastro dei marchi trattati ============================ */
/* Per una farmacia i marchi che tiene sono sostanza, non decoro: il cliente li elenca per nome nei suoi
   testi. Sono TESTO e non loghi — i file dei marchi non fanno parte del materiale, e riprodurli sarebbe
   inventare un asset di terzi.
   ⚠ Il nastro scorre con `data-marquee` (reveal.js): si ferma con reduced-motion, e il contenuto resta
   leggibile fermo. `role="presentation"` sul contenitore: è una fascia decorativa, non una lista di
   navigazione da annunciare voce per voce. */
.ribbon {
  background: linear-gradient(90deg, var(--brand-dark) 0%, var(--brand) 50%, var(--brand-dark) 100%);
  color: var(--on-dark); padding-block: var(--space-4); overflow: hidden;
}
.ribbon__viewport { overflow: hidden; }
.ribbon__track {
  display: flex; align-items: center; gap: var(--space-5);
  white-space: nowrap; width: max-content;
  font-family: var(--font-display); font-weight: 500; font-size: var(--text-md);
  animation: ribbonRun 46s linear infinite;
}
.ribbon__track li { color: var(--on-dark); }
.ribbon__track li[aria-hidden] { color: var(--accent-lt); }
@keyframes ribbonRun { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .ribbon__track { animation: none; width: 100%; flex-wrap: wrap; white-space: normal; justify-content: center; }
}
