/* ==========================================================================
   Zampe in Festa — stylesheet
   Ricostruito da uploads/Registrazione 2026-07-29 110403.mp4
   ========================================================================== */

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body,
h1, h2, h3, h4, p, figure, blockquote, dl, dd, ul, ol {
  margin: 0;
  padding: 0;
}

ul, ol { list-style: none; }
img { display: block; max-width: 100%; }
button, input { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }

/* ---------- Token ---------- */
:root {
  --orange: #ed3408;
  --orange-dark: #cf2c06;
  --orange-soft: #ffe7d9;
  --orange-pale: #ffcdb8;

  --ink: #111111;
  --ink-2: #1c1c1c;
  --muted: #6e6e6e;
  --muted-2: #8b8b8b;
  --ghost: #c9c9c9;

  --bg: #ffffff;
  --bg-soft: #f6f6f6;
  --line: #ececec;

  --r-card: 22px;
  --r-lg: 28px;
  --r-pill: 999px;

  --shell: 1160px;
  --nav-h: 66px;

  --ease: cubic-bezier(.22, .8, .28, 1);
}

/* ---------- Base ---------- */
body {
  font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont,
               'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  /* 16px identici a prima con le impostazioni predefinite del browser, ma
     espressi in rem: se l'utente alza il corpo del testo nelle preferenze
     di sistema, ora il sito lo segue invece di ignorarlo */
  font-size: 1rem;
  line-height: 1.55;
  color: var(--ink);
  background: var(--bg);
  /* overflow-x:hidden trasforma il documento in un contenitore di
     scorrimento, ed e' la causa classica della rottura di position:sticky,
     che qui serve a .process__aside. clip taglia e basta, senza creare
     nessun contenitore. La riga hidden resta come ripiego per Safari 15. */
  overflow-x: hidden;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
}

/* la gronda laterale arriva dal token --gutter (vedi fondamenta in fondo):
   vale 24px per lato da 684px in su, cioe' i 48px complessivi di sempre */
.shell {
  width: min(calc(100% - var(--gutter) * 2), var(--shell));
  margin-inline: auto;
}

.section { padding: var(--space-section) 0; position: relative; }
.section--soft { background: var(--bg-soft); }

/* ---------- Tipografia ---------- */
.h1, .h2, .h3 {
  font-weight: 800;
  letter-spacing: -.025em;
  line-height: 1.08;
  color: var(--ink);
}

/* i corpi arrivano dai token --fs-* (vedi fondamenta in fondo al file): i
   valori di arrivo sono gli stessi di prima, cambia il modo di arrivarci */
.h1 { font-size: var(--fs-h1); }
.h2 { font-size: var(--fs-h2); line-height: 1.14; }
.h3 { font-size: var(--fs-h3); line-height: 1.25; }

.lead {
  color: var(--muted);
  font-size: var(--fs-lead);
  line-height: 1.62;
}

.center { text-align: center; }
.section__head { max-width: 640px; margin-inline: auto; }
.section__head .lead { margin-top: 14px; }

/* ---------- Badge pill di sezione ---------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 16px 7px 12px;
  border-radius: var(--r-pill);
  background: var(--orange-soft);
  color: var(--orange);
  font-size: 14px;
  font-weight: 600;
  margin-bottom: 22px;
}
/* l'icona e' lo stesso ossicino verticale del logo (nel video, quando passa
   per la verticale, coincide con quello del marchio) e dondola avanti e
   indietro come un pendolo: misurato fra 32s e 36s, oscillazione di circa
   +/-22 gradi attorno al centro, un'andata e ritorno ogni ~2,2 s */
.badge svg {
  width: 10px;
  height: 21px;
  flex: none;
  transform-origin: 50% 50%;
  animation: bone-wag 2.2s ease-in-out infinite;
}
@keyframes bone-wag {
  0%, 100% { transform: rotate(-22deg); }
  50%      { transform: rotate(22deg); }
}

/* ---------- Bottone a osso ----------
   Geometria ricavata misurando pixel per pixel il profilo del bottone nel
   video: altezza 52, quattro cerchi di raggio 16 con i centri a 16px dai lati
   e a +/-10px dall'asse orizzontale. Le due coppie si sovrappongono ed e' la
   loro intersezione a creare la strozzatura laterale, profonda ~3.5px; la
   barra centrale e' alta 30 e rientra di 4px per lato.
   Tutto disegnato come background dell'elemento, cosi' resta dietro al testo. */
.bone-btn {
  --bone: var(--orange);
  --r: 16px;      /* raggio dei lobi */
  --d: 32px;      /* diametro dei lobi */
  --bar: 30px;    /* altezza della barra centrale */
  --inset: 4px;   /* rientro della barra = profondita' della strozzatura */

  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 52px;
  min-width: 126px;
  padding: 0 22px;
  border: 0;
  cursor: pointer;
  color: #fff;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -.01em;

  background:
    radial-gradient(circle var(--r) at var(--r) var(--r), var(--bone) 99%, transparent 100%) no-repeat left  0 top    0 / var(--d) var(--d),
    radial-gradient(circle var(--r) at var(--r) var(--r), var(--bone) 99%, transparent 100%) no-repeat left  0 bottom 0 / var(--d) var(--d),
    radial-gradient(circle var(--r) at var(--r) var(--r), var(--bone) 99%, transparent 100%) no-repeat right 0 top    0 / var(--d) var(--d),
    radial-gradient(circle var(--r) at var(--r) var(--r), var(--bone) 99%, transparent 100%) no-repeat right 0 bottom 0 / var(--d) var(--d),
    linear-gradient(var(--bone), var(--bone)) no-repeat var(--inset) center / calc(100% - var(--inset) * 2) var(--bar);

  transition: transform .3s var(--ease), filter .3s var(--ease);
}
/* All'ingresso del mouse l'osso fa un guizzo, una volta sola: misurato sul
   video fra 76,8s e 77,4s va a -9 gradi, poi a +9 e torna dritto in mezzo
   secondo. La dimensione non cambia.
   Il guizzo sta su una classe, non su :hover: cosi' se il mouse esce a meta'
   l'animazione arriva comunque in fondo (la classe la toglie animationend). */
.bone-btn:hover { filter: drop-shadow(0 9px 20px rgba(237, 52, 8, .30)); }
.bone-btn.is-wiggling { animation: bone-wiggle .55s var(--ease); }
@keyframes bone-wiggle {
  0%   { transform: rotate(0deg); }
  30%  { transform: rotate(-9deg); }
  65%  { transform: rotate(9deg); }
  100% { transform: rotate(0deg); }
}
.bone-btn:active { transform: scale(.98); }

/* ---------- Link con freccia ---------- */
.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--orange);
  font-weight: 600;
  font-size: 15px;
}
.arrow-link span { transition: transform .3s var(--ease); }
.arrow-link:hover span { transform: translate(2px, -2px); }

/* ==========================================================================
   Navbar
   ========================================================================== */
.nav {
  position: fixed;
  inset: 18px 0 auto;
  z-index: 90;
  pointer-events: none;
}
.nav__inner {
  pointer-events: auto;
  width: min(100% - 48px, 1030px);
  margin-inline: auto;
  height: var(--nav-h);
  padding: 0 14px 0 26px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: #fff;
  border-radius: var(--r-pill);
  box-shadow: 0 10px 34px rgba(20, 20, 20, .07), 0 2px 6px rgba(20, 20, 20, .04);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 21px;
  font-weight: 800;
  letter-spacing: -.03em;
  color: var(--orange);
  white-space: nowrap;
}
/* larghezza/altezza seguono il nuovo rapporto dell'osso (34:73); l'ossicino
   sta leggermente inclinato a destra invece che perfettamente verticale */
.brand svg {
  width: 11px;
  height: 23px;
  flex: none;
  transform: rotate(15deg);
  transform-origin: 50% 50%;
}

.nav__links {
  display: flex;
  gap: 34px;
  font-size: 15px;
  font-weight: 500;
}
.nav__links a { color: #2b2b2b; transition: color .25s var(--ease); }
.nav__links a:hover { color: var(--orange); }

.nav__right {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: none;
}

/* ---------- Selettore lingua ---------- */
.lang-switch { position: relative; flex: none; }

.lang-btn {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 8px 12px;
  border: 1px solid rgba(20, 20, 20, .13);
  border-radius: var(--r-pill);
  background: #fff;
  color: var(--ink);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .08em;
  cursor: pointer;
  transition: border-color .3s var(--ease), box-shadow .3s var(--ease);
}
.lang-btn:hover { border-color: var(--orange); box-shadow: 0 8px 18px rgba(20, 20, 20, .08); }
.lang-btn .caret { font-size: 9px; color: var(--orange); transition: transform .3s var(--ease); }
.lang-switch.open .lang-btn .caret { transform: rotate(180deg); }

.lang-switch .flag {
  display: inline-flex;
  width: 21px;
  height: 14px;
  flex: none;
  overflow: hidden;
  border-radius: 3px;
  box-shadow: 0 0 0 1px rgba(20, 20, 20, .12);
}
.lang-switch .flag svg { display: block; width: 100%; height: 100%; }

.lang-menu {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  min-width: 168px;
  padding: 6px;
  background: #fff;
  border: 1px solid rgba(20, 20, 20, .08);
  border-radius: 16px;
  box-shadow: 0 20px 44px rgba(20, 20, 20, .16);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: opacity .28s var(--ease), transform .28s var(--ease), visibility .28s;
  z-index: 120;
}
.lang-switch.open .lang-menu { opacity: 1; visibility: visible; transform: none; }

.lang-menu button {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 11px 13px;
  border: 0;
  border-radius: 11px;
  background: none;
  color: var(--ink);
  font-size: 14.5px;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
  transition: background .25s var(--ease), color .25s var(--ease);
}
.lang-menu button:hover { background: var(--bg-soft); }
.lang-menu button.active { background: var(--orange-soft); color: var(--orange); font-weight: 600; }

.nav__burger {
  display: none;
  width: 42px;
  height: 42px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--orange-soft);
  cursor: pointer;
  position: relative;
}
.nav__burger span {
  position: absolute;
  left: 12px;
  width: 18px;
  height: 2px;
  border-radius: 2px;
  background: var(--orange);
  transition: transform .3s var(--ease), opacity .2s var(--ease);
}
.nav__burger span:nth-child(1) { top: 15px; }
.nav__burger span:nth-child(2) { top: 20px; }
.nav__burger span:nth-child(3) { top: 25px; }
.nav.is-open .nav__burger span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.nav.is-open .nav__burger span:nth-child(2) { opacity: 0; }
.nav.is-open .nav__burger span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }

/* ==========================================================================
   Hero
   ========================================================================== */
.hero {
  background: var(--bg-soft);
  padding-top: calc(var(--nav-h) + 78px);
  overflow: hidden;
}

.trusted {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 28px;
}
.trusted__avs { display: inline-flex; }
.trusted__avs img {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  object-fit: cover;
  border: 2px solid var(--bg-soft);
}
.trusted__avs img + img { margin-left: -13px; }
.trusted__txt { text-align: left; line-height: 1.25; }
.trusted__txt small { display: block; font-size: 13px; color: var(--muted-2); }
.trusted__txt strong { font-size: 15px; font-weight: 700; }

.hero__sub {
  max-width: 470px;
  margin: 20px auto 0;
  font-size: 16px;
}
.hero__cta { margin-top: 34px; }

/* La fascia di foto sale di 70px con un padding-top trasparente che arriva
   sopra al bottone: senza questo z-index il blocco di testo resta sotto e
   l'osso non riceve ne' il click ne' l'hover. */
.hero .shell { position: relative; z-index: 2; }

/* --- marquee foto hero ---
   La striscia non e' orizzontale: nel video le card "dritte" scendono in modo
   costante da sinistra a destra (top a x=107 -> 243, x=457 -> 280, x=808 -> 318,
   x=1161 -> 352), cioe' una pendenza di 5.9 gradi. E' l'INTERA traccia a essere
   ruotata: le card in posizione dispari sono poi contro-ruotate per tornare
   dritte, ed e' questo che nel video fa sembrare le card alternativamente
   inclinate e diritte. */
.photo-strip {
  --tilt: 6deg;
  --lift: 92px;               /* di quanto sale la card sotto il mouse */
  position: relative;
  overflow: hidden;           /* il taglio finale, dritto, lo fa questo blocco */
  /* sopra: spazio per il sollevamento dell'hover + la risalita della fascia
     all'estremo sinistro; sotto: la discesa all'estremo destro */
  padding-top: calc(var(--lift) + 8vw);
  padding-bottom: 8vw;
  margin-top: -70px;          /* riavvicina la fascia al bottone */
}
.photo-strip .marquee {
  /* piu' larga del viewport e spostata a sinistra: cosi' gli spigoli della
     fascia inclinata cadono fuori dallo schermo */
  width: 132%;
  margin-left: -16%;
  overflow: visible;
  transform: rotate(var(--tilt));
}
.photo-strip .marquee__track { align-items: flex-start; }

/* Il JS avvolge le tracce in .marquee__inner, ne crea tante copie quante ne
   servono a coprire il viewport (altrimenti a fine ciclo resta uno spazio
   vuoto a destra sugli schermi larghi) e le fa scorrere con un ciclo rAF.
   Lo scorrimento non usa un'animazione CSS perche' cambiare la durata a meta'
   corsa farebbe saltare la striscia: con il JS la velocita' si interpola. */
.marquee {
  position: relative;
  display: flex;
  overflow: hidden;
  width: 100%;
}
.marquee__inner {
  display: flex;
  flex: none;
  will-change: transform;
}
.marquee__track {
  display: flex;
  flex: none;
  gap: 26px;
  padding-right: 26px;
}

/* spazio verticale per non tagliare le card ruotate e le loro ombre */
.ba-strip .marquee,
.team-strip .marquee { padding: 10px 0 14px; }

/* La card e' divisa in due livelli: il contenitore esterno fa il sollevamento
   e l'inclinazione 2D (in transizione, cosi' torna indietro da sola), quello
   interno fa il giro completo in 3D (che va per forza in animazione: una
   transizione da 0 a 360 gradi non produrrebbe alcun movimento). */
.photo-card {
  --card-rot: 0deg;           /* eredita l'inclinazione della traccia */
  position: relative;
  flex: none;
  width: 172px;
  height: 214px;
  perspective: 900px;         /* profondita' della rotazione 3D del figlio */
  transform: rotate(var(--card-rot));
  transition: transform .45s var(--ease);
}
.photo-card__in {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 14px;
  overflow: hidden;
  background: #ddd;
  box-shadow: 0 8px 26px rgba(0, 0, 0, .09);
  transform-style: preserve-3d;
  transition: box-shadow .45s var(--ease);
}
.photo-card img { width: 100%; height: 100%; object-fit: cover; }

/* le dispari tornano dritte annullando l'inclinazione della traccia */
.photo-card:nth-child(odd) { --card-rot: calc(var(--tilt, 0deg) * -1); }

/* hover: la card sale sopra le altre e si inclina ancora un po'.
   Misurato sul video: centro a y=341 invece dei 439 previsti dalla pendenza,
   quindi ~97px di sollevamento, piu' circa 16 gradi di inclinazione.
   Il marquee NON si ferma: continua a scorrere a 40 px/s.

   Lo stato NON e' legato a :hover ma alla classe .is-up messa dal JS: la
   striscia scorre, quindi la card esce da sotto il mouse dopo poche decine
   di millisecondi e con il solo :hover il giro si interrompeva a meta'.
   Il JS toglie .is-up solo a giro finito. Senza JS resta il vecchio :hover. */
.photo-card.is-up,
.photo-strip:not(.has-cardfx) .photo-card:hover {
  transform:
    translateY(calc(var(--lift, 92px) * -1))
    rotate(calc(var(--card-rot) + 16deg))
    scale(1.06);
  z-index: 5;
}
/* giro completo su se stessa, sull'asse verticale: a meta' corsa si vede il
   retro della card, ed e' questo a dare la profondita' 3D */
.photo-card.is-up .photo-card__in,
.photo-strip:not(.has-cardfx) .photo-card:hover .photo-card__in {
  box-shadow: 0 24px 50px rgba(0, 0, 0, .24);
  animation: card-spin 1s var(--ease);
}
@keyframes card-spin {
  from { transform: rotateY(0deg); }
  to   { transform: rotateY(360deg); }
}

/* ==========================================================================
   About
   ========================================================================== */
.about__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 60px;
  align-items: center;
}
.about__copy .lead { margin-top: 18px; max-width: 450px; }

.fan {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 260px;
}
.fan img {
  border-radius: 16px;
  object-fit: cover;
  box-shadow: 0 12px 34px rgba(0, 0, 0, .12);
  transition: transform .5s var(--ease);
}
.fan__side {
  width: 138px;
  height: 182px;
  position: relative;
  z-index: 1;
}
.fan__side--l { transform: rotate(-8deg) translateX(34px); }
.fan__side--r { transform: rotate(8deg)  translateX(-34px); }
.fan__main {
  width: 174px;
  height: 218px;
  position: relative;
  z-index: 2;
}
.fan:hover .fan__side--l { transform: rotate(-13deg) translateX(20px); }
.fan:hover .fan__side--r { transform: rotate(13deg)  translateX(-20px); }

/* --- stats --- */
.stats {
  margin-top: 62px;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 18px;
}
.stat {
  background: var(--bg-soft);
  border: 1px solid rgba(20, 20, 20, .07);
  border-radius: 16px;
  padding: 26px 24px 24px;
  /* due livelli molto tenui: uno stacco netto ravvicinato e un alone ampio,
     cosi' la card si stacca dal bianco senza sembrare "appiccicata" sopra */
  box-shadow:
    0 1px 2px rgba(20, 20, 20, .04),
    0 8px 22px rgba(20, 20, 20, .05);
  transition: transform .35s var(--ease), box-shadow .35s var(--ease),
              border-color .35s var(--ease);
}
.stat:hover {
  transform: translateY(-3px);
  border-color: rgba(237, 52, 8, .28);
  box-shadow:
    0 2px 4px rgba(20, 20, 20, .05),
    0 14px 30px rgba(20, 20, 20, .09);
}
.stat b {
  display: block;
  font-size: 34px;
  font-weight: 800;
  letter-spacing: -.03em;
  line-height: 1;
  /* cifre a larghezza fissa: durante il conteggio il numero non "balla" */
  font-variant-numeric: tabular-nums;
}
.stat span {
  display: block;
  margin-top: 12px;
  font-size: 14.5px;
  color: var(--muted);
}

/* ==========================================================================
   Services
   ========================================================================== */
/* Due colonne indipendenti, non una griglia a righe: nel video, quando una
   card si allunga in hover, scende solo quella sotto nella STESSA colonna
   (frame 20: Toelettatura arriva a y=467, la card sotto scende di 38px,
   mentre la colonna di destra resta ferma). */
.services__grid {
  margin-top: 56px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px;
  align-items: start;
}
.services__col { display: grid; gap: 24px; align-content: start; }

.svc {
  position: relative;
  display: block;
  background: #fff;
  border-radius: var(--r-card);
  border: 1.5px solid transparent;
  overflow: hidden;
  transition: border-color .35s var(--ease);
}
.svc:hover { border-color: var(--orange); }

/* la parte bianca ha altezza fissa: la card cresce solo per la barra */
.svc__inner {
  position: relative;
  min-height: 250px;
  padding: 26px 26px 30px;
}

/* --- prezzo: roll verticale ---
   Le due copie identiche del prezzo stanno una sopra l'altra dentro una
   finestra alta quanto una riga. Al passaggio del mouse scorrono entrambe
   di una riga: quella visibile esce in alto, la gemella sale al suo posto.
   Un solo movimento, in transizione, quindi torna indietro da sola se si
   esce a meta' corsa. */
.svc__price {
  position: relative;
  height: 32px;
  overflow: hidden;
}
.svc__price > span {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  display: flex;
  align-items: center;
  white-space: nowrap;
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -.03em;
  color: var(--orange);
  transition: transform .5s var(--ease);
}
/* la copia parte fuori quadro, appena sotto */
.svc__price > span + span { transform: translateY(100%); }

.svc:hover .svc__price > span { transform: translateY(-100%); }
.svc:hover .svc__price > span + span { transform: translateY(0); }

.svc__img {
  position: absolute;
  right: 20px;
  top: 20px;
  width: 172px;
  height: 206px;
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 10px 26px rgba(0, 0, 0, .1);
  transition: transform .45s var(--ease);
}
.svc__img img { width: 100%; height: 100%; object-fit: cover; }
.svc:hover .svc__img { transform: rotate(-4deg) scale(1.05); }

.svc__body {
  position: absolute;
  left: 26px;
  bottom: 30px;
  max-width: 250px;
}
.svc__body h3 { font-size: 23px; font-weight: 800; letter-spacing: -.03em; }
.svc__body p { margin-top: 8px; font-size: 14.5px; color: var(--muted); }

/* la barra sta nel flusso, sotto la parte bianca: aprendosi allunga la card */
.svc__bar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
  height: 0;
  overflow: hidden;
  padding-right: 22px;
  background: var(--orange);
  color: #fff;
  font-size: 14.5px;
  font-weight: 600;
  white-space: nowrap;
  transition: height .38s var(--ease);
}
.svc:hover .svc__bar { height: 44px; }

/* sui dispositivi senza mouse l'hover non esiste: barra sempre aperta */
@media (hover: none) {
  .svc__bar { height: 44px; }
}

/* ==========================================================================
   Transformations (before / after)
   ========================================================================== */
.ba-strip { margin-top: 56px; }
.ba-strip .marquee__track { gap: 26px; padding-right: 26px; }

.ba {
  position: relative;
  flex: none;
  width: 268px;
  height: 316px;
  border-radius: 18px;
  overflow: hidden;
  background: #eee;
  touch-action: pan-y;
  cursor: ew-resize;
  user-select: none;
}
.ba img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}
.ba__after { clip-path: inset(0 0 0 var(--pos, 50%)); }

.ba__tag {
  position: absolute;
  top: 14px;
  z-index: 3;
  padding: 4px 11px;
  border-radius: 8px;
  background: var(--orange);
  color: #fff;
  font-size: 12.5px;
  font-weight: 600;
  pointer-events: none;
}
.ba__tag--b { left: 12px; }
.ba__tag--a { right: 12px; }

.ba__line {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--pos, 50%);
  width: 3px;
  margin-left: -1.5px;
  background: #fff;
  /* un filo d'ombra: cosi' la riga si legge anche sulle foto chiare */
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .05), 0 0 12px rgba(0, 0, 0, .22);
  z-index: 2;
  pointer-events: none;
}
.ba__knob {
  position: absolute;
  top: 50%;
  left: var(--pos, 50%);
  z-index: 3;
  width: 40px;
  height: 40px;
  margin: -20px 0 0 -20px;
  border-radius: 50%;
  background: #fff;
  color: #33312f;
  box-shadow:
    0 2px 6px rgba(0, 0, 0, .16),
    0 10px 24px rgba(0, 0, 0, .18);
  display: grid;
  place-items: center;
  pointer-events: none;
  transition: transform .28s var(--ease), box-shadow .28s var(--ease);
}
.ba:hover .ba__knob {
  transform: scale(1.09);
  box-shadow:
    0 3px 8px rgba(0, 0, 0, .18),
    0 14px 32px rgba(0, 0, 0, .24);
}
.ba__knob svg { width: 21px; height: 21px; display: block; }

/* ==========================================================================
   Process
   ========================================================================== */
.process__grid {
  display: grid;
  grid-template-columns: minmax(0, .92fr) minmax(0, 1fr);
  gap: 70px;
  align-items: start;
}
.process__aside { position: sticky; top: 130px; }
.process__aside .lead { margin-top: 16px; max-width: 340px; }
.process__aside img {
  margin-top: 34px;
  width: 100%;
  max-width: 356px;
  aspect-ratio: 356 / 305;
  object-fit: cover;
  border-radius: 16px;
}

.steps { position: relative; padding-left: 68px; }
.steps__rail {
  position: absolute;
  left: 22px;
  top: 24px;
  bottom: 24px;
  width: 2px;
  background: #e4e2e0;
}
.steps__rail i {
  position: absolute;
  inset: 0 0 auto;
  height: var(--fill, 0%);
  background: var(--orange);
  display: block;
}

.step { position: relative; padding-bottom: 108px; }
.step:last-child { padding-bottom: 0; }

.step__dot {
  position: absolute;
  left: -68px;
  top: -8px;
  width: 45px;
  height: 45px;
  border-radius: 50%;
  border: 1.5px solid var(--orange);
  background: #fff;
  color: var(--ink);
  display: grid;
  place-items: center;
  font-size: 19px;
  font-weight: 800;
  transition: background .35s var(--ease), color .35s var(--ease);
}
.step.is-on .step__dot { background: var(--orange); color: #fff; border-color: var(--orange); }

.step h3 { font-size: 25px; font-weight: 800; letter-spacing: -.03em; }
.step p { margin-top: 8px; max-width: 340px; font-size: 15px; color: var(--muted); }

.step__txt {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity .5s var(--ease), transform .5s var(--ease);
}
.step.is-on .step__txt { opacity: 1; transform: none; }

/* ==========================================================================
   Testimonial
   ========================================================================== */
.quotes {
  margin-top: 56px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 22px;
  align-items: start;
}
.quotes__col { display: grid; gap: 22px; }
.quotes__col:nth-child(2) { margin-top: 14px; }

.quote {
  background: var(--bg-soft);
  border-radius: 16px;
  padding: 24px 22px 22px;
}
.quote p { font-size: 15px; color: var(--muted); }
.quote footer {
  margin-top: 18px;
  display: flex;
  align-items: center;
  gap: 11px;
  font-size: 15px;
  font-weight: 600;
}
.quote img { width: 30px; height: 30px; border-radius: 50%; object-fit: cover; flex: none; }

/* --- galleggiamento lento ---
   Le schede salgono e scendono di pochi pixel, con durate e ritardi diversi
   fra loro cosi' il movimento non e' mai all'unisono.
   Parte solo a reveal concluso: l'animazione vince sulla transizione, quindi
   se partisse subito taglierebbe l'entrata di .reveal (0,7s + stagger). */
@keyframes quote-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-8px); }
}
.quote.is-in {
  animation: quote-float var(--fdur, 7s) ease-in-out var(--fdel, 1.2s) infinite;
}
.quotes__col:nth-child(1) .quote:nth-child(1) { --fdur: 7s;   --fdel: 1.1s; }
.quotes__col:nth-child(1) .quote:nth-child(2) { --fdur: 8.4s; --fdel: 2s; }
.quotes__col:nth-child(2) .quote:nth-child(1) { --fdur: 7.8s; --fdel: 1.5s; }
.quotes__col:nth-child(2) .quote:nth-child(2) { --fdur: 6.6s; --fdel: 2.4s; }
.quotes__col:nth-child(3) .quote:nth-child(1) { --fdur: 8.8s; --fdel: 1.3s; }
.quotes__col:nth-child(3) .quote:nth-child(2) { --fdur: 7.2s; --fdel: 2.2s; }

/* ==========================================================================
   Team
   ========================================================================== */
.team-strip { margin-top: 52px; }
.team-strip .marquee__track { gap: 26px; padding-right: 26px; }

.member { flex: none; width: 250px; text-align: center; }
.member img {
  width: 100%;
  height: 268px;
  object-fit: cover;
  border-radius: 16px;
  transition: transform .5s var(--ease);
}
.member:hover img { transform: scale(1.035); }
.member b {
  display: block;
  margin-top: 20px;
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -.03em;
}
.member span { display: block; margin-top: 4px; font-size: 14px; color: var(--muted); }

/* ==========================================================================
   FAQ
   ========================================================================== */
.faq__grid {
  display: grid;
  grid-template-columns: minmax(0, .85fr) minmax(0, 1fr);
  gap: 70px;
  align-items: start;
}
.faq__aside .lead { margin-top: 16px; max-width: 400px; }

.faq__panel {
  background: var(--bg-soft);
  border-radius: var(--r-lg);
  padding: 18px;
  display: grid;
  gap: 12px;
}

.acc {
  background: #fff;
  border-radius: 14px;
  overflow: hidden;
}
.acc__q {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 17px 20px;
  border: 0;
  background: none;
  cursor: pointer;
  text-align: left;
  font-size: 15.5px;
  font-weight: 500;
  color: var(--ink);
}
.acc__ico {
  position: relative;
  flex: none;
  width: 16px;
  height: 16px;
  transition: transform .35s var(--ease);
}
.acc__ico::before,
.acc__ico::after {
  content: '';
  position: absolute;
  inset: 50% 0 auto;
  height: 1.6px;
  background: #333;
  transform: translateY(-50%);
}
.acc__ico::after { transform: translateY(-50%) rotate(90deg); }
.acc.is-open .acc__ico { transform: rotate(45deg); }

.acc__a {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .38s var(--ease);
}
.acc.is-open .acc__a { grid-template-rows: 1fr; }
.acc__a > div { overflow: hidden; }
.acc__a p {
  padding: 0 20px 18px;
  font-size: 15px;
  color: var(--muted);
  max-width: 420px;
}

/* ==========================================================================
   CTA finale
   ========================================================================== */
.cta {
  position: relative;
  padding: 200px 0 200px;
  overflow: hidden;
}
.cta .h2 { max-width: 620px; margin-inline: auto; }
.cta .lead { max-width: 380px; margin: 16px auto 0; }
.cta__btn { margin-top: 34px; }

/* Le foto stanno su un anello che gira lentamente attorno al testo.
   Tre livelli: .cta__ellipse schiaccia il cerchio in ellisse (cosi' abbraccia
   il blocco di testo, piu' largo che alto), .cta__orbit fa il giro, e dentro
   ogni foto contro-ruota della stessa quantita' per restare diritta mentre
   orbita. La contro-scala su .cta__pic annulla lo schiacciamento, quindi le
   foto restano proporzionate. */
.cta__float {
  --r: clamp(250px, 33vw, 450px);   /* raggio dell'anello */
  --flat: .56;                      /* quanto e' schiacciato in verticale */
  --orbit: 90s;                     /* durata di un giro completo */
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
.cta .shell { position: relative; z-index: 1; }

.cta__ellipse {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 0;
  height: 0;
  transform: scaleY(var(--flat));
}
.cta__orbit {
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  animation: cta-orbit var(--orbit) linear infinite;
}
.cta__float figure {
  position: absolute;
  left: 0;
  top: 0;
  width: clamp(96px, 11vw, 150px);
  aspect-ratio: 4 / 3;
  transform:
    translate(-50%, -50%)
    rotate(var(--a, 0deg))
    translateY(calc(var(--r) * -1))
    rotate(calc(var(--a, 0deg) * -1));
}
.cta__spin {
  display: block;
  width: 100%;
  height: 100%;
  animation: cta-orbit-rev var(--orbit) linear infinite;
}
.cta__pic {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 10px 26px rgba(0, 0, 0, .13);
  transform: scaleY(calc(1 / var(--flat))) rotate(var(--rot, 0deg));
}
.cta__pic img { width: 100%; height: 100%; object-fit: cover; }

@keyframes cta-orbit     { to { transform: rotate(360deg); } }
@keyframes cta-orbit-rev { to { transform: rotate(-360deg); } }

/* l'anello viene nascosto sotto i 980px, non piu' a 700: fra i 700 e i 980
   il semiasse verticale dell'ellisse e' piu' corto di meta' blocco di testo,
   quindi le foto passavano dietro al titolo rendendolo illeggibile.
   Vedi il blocco CTA nelle regole responsive in fondo al file. */

/* ==========================================================================
   Footer
   ========================================================================== */
.foot-band {
  background: var(--orange);
  border-radius: 42px 42px 0 0;
  padding: 60px 0 0;
  overflow: hidden;
}
.wordmark {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: clamp(10px, 2vw, 26px);
  padding: 0 clamp(16px, 4vw, 60px);
  -webkit-mask-image: linear-gradient(to bottom, #fff 52%, rgba(255, 255, 255, 0) 100%);
          mask-image: linear-gradient(to bottom, #fff 52%, rgba(255, 255, 255, 0) 100%);
}
.wordmark svg {
  width: clamp(20px, 3.4vw, 44px);
  aspect-ratio: 34 / 73;
  height: auto;
  flex: none;
  color: #fff;
  margin-bottom: clamp(4px, 1.1vw, 14px);
  transform: rotate(15deg);
  transform-origin: 50% 50%;
}
.wordmark span {
  /* "Zampe in Festa" e' il doppio di "Pawwell": corpo ridotto di conseguenza
     perche' la scritta continui a riempire la fascia senza andare a capo */
  font-size: clamp(34px, 10.2vw, 134px);
  font-weight: 800;
  letter-spacing: -.04em;
  line-height: .9;
  color: #fff;
  white-space: nowrap;
}

.foot { padding: 62px 0 0; }
.foot__grid {
  display: grid;
  /* la colonna dei link resta al centro, i recapiti chiudono a destra */
  grid-template-columns: minmax(0, 1.35fr) minmax(0, .75fr) minmax(0, 1.1fr);
  gap: 40px;
}
.foot__claim { font-size: 16px; font-weight: 500; max-width: 360px; line-height: 1.5; }

.socials { margin-top: 26px; display: flex; gap: 14px; }
.socials a {
  width: 20px;
  height: 20px;
  color: #2b2b2b;
  transition: color .25s var(--ease);
}
.socials a:hover { color: var(--orange); }
.socials svg { width: 100%; height: 100%; }

.foot__col h4 { font-size: 17px; font-weight: 700; letter-spacing: -.02em; }
.foot__col ul { margin-top: 18px; display: grid; gap: 12px; }
.foot__col a { font-size: 15px; color: var(--muted); transition: color .25s var(--ease); }
.foot__col a:hover { color: var(--orange); }

/* recapiti aziendali: righe di testo, non solo link, quindi servono colore e
   interlinea propri (gli indirizzi vanno a capo su due righe) */
.foot__col ul.foot__info {
  gap: 11px;
  font-size: 15px;
  color: var(--muted);
  line-height: 1.5;
}

.foot__bar {
  margin-top: 56px;
  padding: 20px 0 26px;
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  font-size: 14px;
  color: var(--muted);
}
.foot__bar a { color: inherit; transition: color .25s var(--ease); }
.foot__bar a:hover { color: var(--orange); }

/* ==========================================================================
   Animazioni di scroll
   ========================================================================== */
.reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
  transition-delay: var(--d, 0ms);
}
.reveal.is-in { opacity: 1; transform: none; }

/* reveal parola per parola dei titoli */
.words span {
  display: inline-block;
  color: var(--ghost);
  opacity: .45;
  transform: translateY(8px);
  transition: color .45s var(--ease), opacity .45s var(--ease), transform .45s var(--ease);
  transition-delay: var(--wd, 0ms);
  white-space: pre;
}
.words.is-in span { color: inherit; opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal, .words span { opacity: 1 !important; transform: none !important; }
  .marquee__inner,
  .badge svg,
  .quote.is-in,
  .bone-btn.is-wiggling,
  .photo-card__in { animation: none !important; }
  /* niente roll del prezzo: resta la sola copia, ferma */
  .svc__price > span { transform: none !important; }
  .svc__price > span + span { display: none; }
  html { scroll-behavior: auto; }
}

/* ==========================================================================
   Pagine interne (404 / policy)
   ========================================================================== */
.page-head {
  background: var(--bg-soft);
  padding: calc(var(--nav-h) + 54px) 0 48px;
  text-align: center;
}
.page-head .lead { max-width: 560px; margin: 14px auto 0; }

.doc { padding: 76px 0 96px; }
.doc__wrap { max-width: 760px; margin-inline: auto; }
.doc h2 {
  margin-top: 46px;
  font-size: 25px;
  font-weight: 800;
  letter-spacing: -.03em;
}
.doc h2:first-child { margin-top: 0; }
.doc p, .doc li { margin-top: 14px; font-size: 15.5px; color: var(--muted); line-height: 1.65; }
.doc ul { margin-top: 6px; padding-left: 22px; list-style: disc; }
.doc a { color: var(--orange); font-weight: 600; }
.doc__meta { font-size: 14px; color: var(--muted-2); margin-bottom: 34px; }

/* ==========================================================================
   Pagina contatti
   ========================================================================== */
.contact { padding: 48px 0 72px; }
.contact__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, .85fr);
  gap: 34px;
  /* niente "start": le due colonne devono avere la stessa altezza di riga,
     e' quello che permette alla colonna dei recapiti di allinearsi al modulo */
  align-items: stretch;
}

.contact__form-card {
  padding: 32px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: #fff;
  box-shadow: 0 14px 40px rgba(20, 20, 20, .06);
}
.contact__note { margin-top: 8px; font-size: 15px; color: var(--muted); }

.cform { margin-top: 22px; display: grid; gap: 16px; }
.cform__row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}

.field { display: grid; gap: 6px; }
.field__lab {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-2);
}
.field input,
.field select,
.field textarea {
  width: 100%;
  /* I controlli nativi hanno una larghezza intrinseca che width:100% NON
     annulla: la tendina vuole stare larga quanto la sua opzione piu' lunga
     ("Pomeriggio (14:00 - 19:00)", ~265px), la textarea quanto i suoi 20
     caratteri di default, il campo data quanto il calendario di sistema.
     Dentro una griglia quella misura diventa il minimo della colonna, e su
     un telefono da 320px (254px utili dentro la card) il modulo sfondava
     di una decina di pixel: pochi, ma bastano a far comparire lo
     scorrimento orizzontale su TUTTA la pagina — con la striscia bianca a
     destra e la navbar, che e' fissa, tirata larga quanto il documento
     invece che quanto lo schermo.
     min-width:0 toglie quel pavimento: i campi tornano a valere esattamente
     il 100% del loro contenitore, a qualsiasi larghezza. */
  min-width: 0;
  max-width: 100%;
  padding: 11px 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-soft);
  color: var(--ink);
  font: inherit;
  font-size: 15px;
  outline: none;
  transition: border-color .25s var(--ease), background .25s var(--ease),
              box-shadow .25s var(--ease);
}
.field textarea { resize: vertical; min-height: 88px; line-height: 1.5; }
.field input::placeholder,
.field textarea::placeholder { color: var(--muted-2); }
.field input:focus,
.field select:focus,
.field textarea:focus {
  background: #fff;
  border-color: var(--orange);
  box-shadow: 0 0 0 3px rgba(237, 52, 8, .12);
}
/* il campo segnalato dal controllo di validita' del JS */
.field.is-bad input,
.field.is-bad select,
.field.is-bad textarea { border-color: var(--orange); background: #fff5f1; }

/* scelta della visita: pillole radio, quella attiva prende l'arancio */
.choice { display: flex; flex-wrap: wrap; gap: 10px; }
/* la pillola e' il riferimento dei suoi stessi pezzi: senza questa riga il
   radio nascosto, che e' in assoluto, si aggancia al viewport */
.choice__opt { position: relative; }
/* I radio stanno dentro .field e quindi ereditavano width:100% dalla regola
   dei campi. Ma sono anche in position:absolute e, non avendo un antenato
   posizionato, quel 100% si misurava sul VIEWPORT: cinque caselle invisibili
   larghe quanto lo schermo, appoggiate al punto in cui sarebbero nate. Quella
   piu' a destra partiva a ~284px e finiva a ~674, cioe' 284px oltre il bordo:
   il documento diventava largo 674px su uno schermo da 390 e la navbar, che
   e' fissa, veniva disegnata larga quanto il documento e non quanto lo
   schermo (e' lo stesso guaio spiegato sopra per i campi di testo).
   Il radio torna a essere una casellina di 1px: invisibile come prima, ma
   senza portarsi dietro mezza pagina di larghezza. Resta raggiungibile da
   tastiera, quindi :checked e :focus-visible continuano a funzionare. */
.choice__opt input {
  position: absolute;
  top: 50%;
  left: 8px;
  width: 1px;
  height: 1px;
  min-width: 0;
  max-width: none;
  margin: 0;
  opacity: 0;
  pointer-events: none;
}
.choice__opt span {
  display: inline-block;
  padding: 9px 18px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--bg-soft);
  font-size: 14.5px;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  transition: background .25s var(--ease), color .25s var(--ease),
              border-color .25s var(--ease);
}
.choice__opt:hover span { border-color: var(--orange-pale); color: var(--ink); }
.choice__opt input:checked + span {
  background: var(--orange-soft);
  border-color: var(--orange-pale);
  color: var(--orange);
}
.choice__opt input:focus-visible + span { box-shadow: 0 0 0 3px rgba(237, 52, 8, .18); }

.check {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 14.5px;
  color: var(--muted);
}
.check input { margin-top: 3px; width: 16px; height: 16px; accent-color: var(--orange); flex: none; }
.check a { color: var(--orange); font-weight: 600; }

.cform__send {
  margin-top: 4px;
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
}
.cform__msg { font-size: 14.5px; font-weight: 600; color: var(--orange); }

/* --- colonna dei recapiti ---
   Le quattro card devono chiudersi alla stessa quota del modulo: sono tenute
   basse (icona in linea col titolo, testi di una riga) e lo spazio che avanza
   finisce fra una card e l'altra grazie a align-content: space-between, cosi'
   la base dell'ultima card e quella del modulo coincidono. */
.contact__side {
  display: grid;
  grid-auto-rows: min-content;
  align-content: space-between;
  gap: 16px;
}
.info-card {
  padding: 22px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--bg-soft);
}
.info-card__head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.info-card__ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex: none;
  border-radius: var(--r-pill);
  background: var(--orange-soft);
  color: var(--orange);
}
.info-card__ico svg { width: 18px; height: 18px; }
.info-card h3 { font-size: 18px; font-weight: 700; letter-spacing: -.02em; }
.info-card__big {
  font-size: 20px;
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.25;
}
.info-card__big--sm { font-size: 16.5px; font-weight: 700; }
.info-card__big a { color: var(--orange); }
.info-card__sub { margin-top: 7px; font-size: 14px; color: var(--muted); line-height: 1.5; }
.info-card .arrow-link { margin-top: 12px; font-size: 14px; }
/* nella colonna stretta l'osso occupa tutta la riga */
.bone-btn--call { margin-top: 14px; display: flex; width: 100%; height: 46px; }

.hours { margin-top: 2px; display: grid; gap: 7px; }
.hours li {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 14px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
  font-size: 15px;
  color: var(--muted);
}
.hours li:last-child { border-bottom: 0; padding-bottom: 0; }
.hours b { color: var(--ink); font-weight: 700; }

/* Giorno e orario non si spezzano MAI a meta': o stanno sulla stessa riga,
   o l'orario scende sotto al giorno tutto intero. Senza il nowrap il flex
   li comprime fino a mandare a capo dentro la parola ("Lunedi -" da una
   parte, "Venerdi" dall'altra), che e' il modo peggiore di stare stretti. */
.hours__day,
.hours b { white-space: nowrap; }
/* la forma breve del giorno esiste solo sul telefono (vedi blocco 640px) */
.hours__day--abbr { display: none; }

/* --- mappa --- */
/* la mappa resta dentro la shell come il resto della pagina e si chiude
   con un margine pieno prima della fascia arancione "Zampe in Festa" */
.map { padding-bottom: 96px; }
.map iframe {
  display: block;
  width: 100%;
  height: clamp(240px, 26vw, 340px);
  border: 1px solid var(--line);
  border-radius: 22px;
  background: var(--bg-soft);
}

@media (max-width: 900px) {
  .contact__grid { grid-template-columns: minmax(0, 1fr); }
  .contact__form-card { padding: 30px 24px; }
}
/* la soglia dei 560px e' stata portata a 640, che e' dove i due controlli
   nativi affiancati (la tendina della fascia oraria e il calendario) iniziano
   davvero a troncarsi: vedi il blocco pagine interne in fondo al file */

.err {
  min-height: 76vh;
  display: grid;
  place-items: center;
  text-align: center;
  padding: calc(var(--nav-h) + 80px) 0 90px;
  background: var(--bg-soft);
}
.err__code {
  font-size: clamp(96px, 22vw, 230px);
  font-weight: 800;
  letter-spacing: -.05em;
  line-height: .85;
  color: var(--orange);
}
.err .lead { max-width: 440px; margin: 18px auto 0; }
.err__actions {
  margin-top: 36px;
  display: flex;
  gap: 34px;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
}
.err__pets {
  margin-top: 52px;
  display: flex;
  justify-content: center;
  gap: 18px;
  flex-wrap: wrap;
}
.err__pets img {
  width: 112px;
  height: 140px;
  object-fit: cover;
  border-radius: 12px;
  box-shadow: 0 10px 26px rgba(0, 0, 0, .1);
}
.err__pets img:nth-child(odd)  { transform: rotate(-7deg); }
.err__pets img:nth-child(even) { transform: rotate(7deg); }

/* ==========================================================================
   Responsive
   ========================================================================== */
/* headbar: sotto i 900px i link passano nella tendina;
   il selettore lingua resta sempre raggiungibile */
@media (max-width: 900px) {
  .nav__links { display: none; }
  .nav__burger { display: block; }

  /* la tendina si allinea alla pillola della navbar, non al viewport */
  .nav__links.is-mobile {
    display: grid;
    position: absolute;
    top: calc(var(--nav-h) + 10px);
    left: 50%;
    transform: translateX(-50%);
    width: min(100% - 48px, 1030px);
    gap: 4px;
    padding: 14px 18px;
    background: #fff;
    border-radius: 20px;
    box-shadow: 0 16px 40px rgba(0, 0, 0, .1);
    z-index: 110;
  }
  .nav__links.is-mobile a { padding: 11px 6px; font-size: 16px; }
}

@media (max-width: 980px) {
  /* .section non ha piu' bisogno di uno scalino qui: il padding arriva dal
     token --space-section, che a 980px vale ancora 96px e poi scende con
     continuita' invece di saltare a 76 e restare li' fino a 320px */

  .about__grid,
  .process__grid,
  .faq__grid { grid-template-columns: minmax(0, 1fr); gap: 44px; }

  .process__aside { position: static; }
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .services__grid { grid-template-columns: minmax(0, 1fr); }
  .quotes { grid-template-columns: minmax(0, 1fr); }
  .quotes__col:nth-child(2) { margin-top: 0; }
  .foot__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  /* qui c'era .foot__claim { grid-column: 1 / -1 }, che non ha mai avuto
     effetto: .foot__claim e' il paragrafo DENTRO al primo div, non un figlio
     della griglia. Il claim va preso dal suo contenitore: la regola corretta
     sta nel blocco footer in fondo al file */
}

@media (max-width: 640px) {
  /* .shell non fa piu' lo scalino da 24 a 18px di gronda: se ne occupa il
     token --gutter, che scende con continuita' */
  .nav__inner { width: calc(100% - 28px); padding: 0 10px 0 18px; }
  .nav__links.is-mobile { width: calc(100% - 28px); }
  .brand { font-size: 18px; gap: 7px; }
  .brand svg { width: 13px; height: 20px; }
  .nav__right { gap: 7px; }
  /* sul telefono resta la sola bandiera: il codice lingua occuperebbe troppo */
  .lang-btn { padding: 7px 9px; gap: 5px; }
  .lang-btn .code { display: none; }
  .lang-menu { min-width: 150px; }
  .hero { padding-top: calc(var(--nav-h) + 54px); }
  /* le statistiche restano a due colonne fino in fondo (vedi blocco About):
     una colonna sola allungava la pagina di quasi 300px senza guadagnare
     nulla in leggibilita'.
     Le regole della card servizio sono state sostituite dal blocco Servizi
     in fondo al file, che introduce un regime intermedio invece di passare
     di colpo dal layout in assoluto a quello impilato. */
  /* la geometria della timeline (rientro, pallino, posizione della rail) non
     e' piu' un gruppo di numeri scollegati ripetuti qui: deriva da due sole
     misure fluide dichiarate nel blocco Process in fondo al file */
  /* la griglia del footer NON torna piu' a colonna unica: "Informazioni"
     resta accanto a "Link rapidi" fino in fondo (vedi blocco footer in
     fondo al file, dove le due colonne vengono strette a dovere) */
  .foot__bar { flex-direction: column; gap: 8px; }
}


/* ==========================================================================
   ==========================================================================
   LIVELLO RESPONSIVE
   Ricostruito sezione per sezione. Regola d'oro di tutto il blocco: sopra i
   1160px il sito deve restare identico al pixel, quindi ogni clamp() qui
   sotto e' tarata perche' il suo valore massimo sia gia' raggiunto entro
   quella larghezza.
   Ordine: fondamenta -> sezioni -> bersagli tattili (ultimi, perche'
   attraversano i territori di piu' sezioni e non devono farsi annullare).
   ==========================================================================
   ========================================================================== */

/* ==========================================================================
   1. FONDAMENTA
   ========================================================================== */

:root {
  /* La gronda laterale non e' piu' un numero ripetuto in due punti ma una
     misura sola, che chiunque puo' riusare per allinearsi al contenitore.
     Vale 24px per lato (i 48px complessivi di oggi) da 684px in su: sopra i
     1160px non cambia dunque assolutamente nulla. Sotto scende con
     continuita' fino ai 18px che il file applicava di colpo a 640px.
     Il max() con env() serve ai telefoni con la tacca: senza
     viewport-fit=cover env() vale 0, quindi la riga e' innocua. */
  --gutter: max(clamp(18px, calc(1.9vw + 11px), 24px),
                env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px));

  /* Respiro verticale fra le sezioni. Da 980px in su vale 96px, identico a
     oggi; sotto scende con continuita' fino a 56px a 360px. Prima c'era un
     solo scalino secco (96 -> 76 a 980px) e poi piu' niente: 76px di vuoto
     sopra e sotto ognuna delle sette sezioni, su uno schermo alto 640px,
     sono un quarto di schermata buttato via per sezione. */
  --space-section: clamp(56px, calc(6.45vw + 32.8px), 96px);

  /* Stessa curva, un gradino piu' in basso, per gli stacchi INTERNI alle
     sezioni: i vari margin-top da 52-62px di .stats, .services__grid,
     .ba-strip, .team-strip, .quotes. */
  --space-block: clamp(34px, calc(3.55vw + 21.2px), 56px);

  /* --- Scala tipografica fluida vera ---
     Interpolazione lineare fra 360px e 1160px di viewport (1160 = --shell:
     da li' in su il testo e' comunque fermo). I valori di arrivo sono gli
     stessi di prima - 66 / 46 / 26 / 15.5 - quindi il desktop non si muove.
     Cambia il modo di arrivarci: con clamp(40px, 6.2vw, 66px) il titolo
     restava incollato a 40px fino a 645px e poi correva da 40 a 66px in
     appena 420px di larghezza, cioe' tutta la variazione schiacciata
     proprio nella fascia dei tablet. Qui cresce di 0,0325px per ogni pixel
     di viewport, sempre, ed e' prevedibile a ogni larghezza. */
  --fs-h1: clamp(40px, calc(3.25vw + 28.3px), 66px);   /* 40 @360  ->  66 @1160 */
  --fs-h2: clamp(30px, calc(2vw + 22.8px), 46px);      /* 30 @360  ->  46 @1160 */

  /* .h3 resta la formula originale, non toccata di proposito: il suo tetto di
     26px viene raggiunto solo a 1182px, cioe' SOPRA i 1160 dello shell.
     Qualunque retta che chiuda a 1160 darebbe 26px dove oggi il sito ne
     mostra 25,5, e sarebbe una modifica al desktop travestita da responsive.
     Il pavimento di 20px va benissimo com'e' sui telefoni. */
  --fs-h3: clamp(20px, 2.2vw, 26px);

  /* Il testo di servizio va nella direzione opposta: sul desktop resta
     esattamente 15.5px, ma sul telefono sale a 16.5px, perche' 15.5px di
     grigio #6e6e6e su bianco, a 360px, sono al limite della leggibilita'. */
  --fs-lead: clamp(15.5px, calc(16.95px - .125vw), 16.5px); /* 16.5 @360 -> 15.5 @1160 */
}

html {
  /* La navbar e' fixed a 18px dall'alto ed e' alta --nav-h: senza questa
     riga i link ancora (#about, #services, #testimonial, #faq, #cta - usati
     da navbar, footer e dalle quattro card servizio) portavano il titolo di
     sezione a finire sotto la pillola bianca. Vale anche per il focus da
     tastiera, non solo per il click. */
  scroll-padding-top: calc(var(--nav-h) + 42px);
}

/* Rete anti-sforamento: nessun contenuto sostituito puo' superare il suo
   contenitore, qualunque cosa faccia il markup. height:auto e' innocuo qui
   perche' ogni immagine che deve riempire una box ha gia' una regola piu'
   specifica che le impone l'altezza. */
img, svg, video, iframe { max-width: 100%; }
img { height: auto; }

/* Le unita' vh sul telefono sono calcolate con la barra degli indirizzi
   APERTA: la pagina si allunga oltre lo schermo e sobbalza quando la barra
   si ritrae. dvh segue l'altezza reale; la riga vh piu' sopra nel file resta
   come ripiego per i browser anteriori al 2022. */
.err { min-height: 76dvh; }

/* --- Velocita' dei marquee ---
   Prima stava in un attributo style= inline su ogni .marquee: dal CSS non si
   poteva piu' toccare senza !important. Spostata qui, le media query che la
   rallentano sui telefoni sono regole normali. Il JS continua a leggerla con
   getComputedStyle, quindi per lui non cambia nulla. */
.photo-strip .marquee { --speed: 30s; }
.ba-strip .marquee    { --speed: 64s; }
.team-strip .marquee  { --speed: 46s; }

/* --- Rete di sicurezza del reveal ---
   .reveal parte da opacity:0 e solo main.js lo riporta a 1. Se lo script non
   arriva (rete, cache, CSP, un errore in un browser vecchio) sparisce il
   titolo dell'hero, il bottone di prenotazione, le quattro card servizio,
   tutte le FAQ e - sulla pagina contatti - l'intero modulo e tutti i
   recapiti. E' il rischio piu' grave del sito e va coperto due volte,
   perche' i due casi sono diversi:
   1. JavaScript disattivato -> ci pensa il <noscript> nelle 4 pagine;
   2. JavaScript attivo ma main.js non caricato o in errore -> il watchdog
      inline in <head> aggiunge .reveal-fallback dopo 2,5s se main.js non ha
      confermato di aver acceso l'observer. */
:root.reveal-fallback .reveal,
:root.reveal-fallback .words span {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
}
:root.reveal-fallback .words span { color: inherit !important; }

/* Terza cintura, gratis, per i browser recenti: se il motore dichiara di non
   poter eseguire script, il contenuto e' visibile fin dal primo frame, senza
   aspettare nessun timeout. */
@media (scripting: none) {
  .reveal { opacity: 1; transform: none; }
  .words span { color: inherit; opacity: 1; transform: none; }
}

/* --- Telefono ruotato ---
   Il breakpoint che mancava al set: non e' una questione di larghezza ma di
   altezza. Un telefono in orizzontale ha ~360px di viewport verticale. */
@media (max-height: 560px) and (orientation: landscape) {
  :root { --space-section: 48px; }
  .err {
    min-height: 0;
    padding-top: calc(var(--nav-h) + 40px);
    padding-bottom: 44px;
  }
}

/* --- Completamento di prefers-reduced-motion ---
   Il blocco piu' sopra nel file copre reveal, marquee, badge, quote-float,
   bone-wiggle e roll dei prezzi. Mancava tutto il resto. */
@media (prefers-reduced-motion: reduce) {
  /* Il buco piu' grosso: otto foto che ruotano all'infinito attorno al testo
     della CTA, un giro ogni 90 secondi, ininterrottamente. */
  .cta__orbit,
  .cta__spin { animation: none !important; }

  /* Con "riduci animazioni" attivo main.js non aggiunge .has-cardfx alla
     photo-strip, e questo RIACCENDE il vecchio ripiego :hover del CSS: la
     card torna a sollevarsi di 92px e a inclinarsi di 16 gradi. Il giro 3D
     era gia' spento, il sollevamento no. */
  .photo-strip .photo-card:hover { transform: rotate(var(--card-rot)) !important; }

  /* Gli hover che spostano o ingrandiscono: restano gli effetti di colore,
     bordo e ombra, che comunicano lo stesso senza muovere nulla. */
  .member:hover img,
  .fan:hover .fan__side--l,
  .fan:hover .fan__side--r,
  .svc:hover .svc__img,
  .stat:hover,
  .ba:hover .ba__knob,
  .arrow-link:hover span { transform: none !important; }

  /* Rete finale: azzera la durata di ogni transizione e animazione rimasta
     senza spegnerle (spegnerle congelerebbe alcune al fotogramma iniziale,
     per esempio l'ossicino del badge resterebbe storto di -22 gradi). */
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ==========================================================================
   2. SEZIONI
   ========================================================================== */
/* ==========================================================================
   Navbar — messa a punto responsive
   ========================================================================== */

/* il passo fra le voci era fisso a 34px fino al momento in cui sparivano nel
   burger: nell'ultimo tratto utile (poco sopra i 900px) le sei voci italiane
   arrivavano a sfiorare il selettore lingua. qui il passo si stringe insieme
   alla finestra. a 1180px il clamp vale ancora 34px, quindi la pillola del
   desktop resta identica al pixel */
@media (max-width: 1180px) {
  .nav__links { gap: clamp(20px, 2.9vw, 34px); }
}

/* la pillola alta 66px e' tarata sul desktop, dove dentro ci stanno testo e
   bottoni; sul telefono l'elemento piu' alto e' il burger (44px) e i 66px
   diventano una fascia bianca sproporzionata. l'altezza scende con la
   larghezza e a 760px vale ancora 66px esatti, cosi' il passaggio non si
   vede. nota: --nav-h e' usata anche dal padding di .hero e .err, che si
   riducono in proporzione — e' voluto */
@media (max-width: 760px) {
  :root { --nav-h: clamp(54px, 8.7vw, 66px); }
  /* meno stacco dal bordo alto: sul telefono ogni pixel verticale conta */
  .nav { inset: 12px 0 auto; }
}

@media (max-width: 900px) {
  /* la tendina parte a ~94px dal bordo e con sei voci ne occupa ~330: su un
     telefono in orizzontale (alto ~380) le ultime voci finivano sotto il
     bordo dello schermo, senza modo di raggiungerle. le si da' un tetto e uno
     scorrimento interno; overscroll contenuto perche' arrivati in fondo il
     dito non trascini la pagina sotto */
  .nav__links.is-mobile {
    max-height: calc(100vh - var(--nav-h) - 46px);
    max-height: calc(100dvh - var(--nav-h) - 46px);
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }

  /* con la tendina aperta la pagina sotto non deve scorrere: la classe la
     mette main.js sull'elemento <html>. sta dentro la media query cosi' se
     per qualsiasi motivo restasse appesa, sopra i 900px non blocca nulla */
  html.nav-locked,
  html.nav-locked body { overflow: hidden; }

  /* 42px non arrivano al bersaglio minimo di 44: si allarga il bottone e si
     ricentrano le tre barrette (la distanza fra loro resta 5px, quindi le
     rotazioni della X non cambiano) */
  .nav__burger { width: 44px; height: 44px; }
  .nav__burger span { left: 13px; }
  .nav__burger span:nth-child(1) { top: 16px; }
  .nav__burger span:nth-child(2) { top: 21px; }
  .nav__burger span:nth-child(3) { top: 26px; }

  /* il bottone lingua e' alto ~38px per via del solo padding: gli si impone
     il minimo tattile, che lo allinea anche al burger */
  .lang-btn { min-height: 44px; }

  /* rete di sicurezza: la tendina non deve mai debordare dal viewport nemmeno
     se un giorno si aggiungono lingue con nomi lunghi */
  .lang-menu { max-width: calc(100vw - 28px); }
}

@media (max-width: 640px) {
  /* il brand ha white-space:nowrap e non puo' accorciarsi: a 320px lo scarto
     fra brand+bandiera+burger e la larghezza della pillola e' di una manciata
     di pixel, e basta il font di sistema al posto di quello di Google per
     mandarlo in overflow. il corpo diventa fluido invece di essere fissato a
     18px: a 640px vale ancora ~18, a 340 scende a 15.5 */
  .brand {
    font-size: clamp(15.5px, 13.4px + .72vw, 18px);
    min-width: 0;
  }
  /* l'osso ha viewBox 34:73: dichiarato 13x20 veniva comunque disegnato
     9.3x20 e i 3.7px avanzati erano box vuoto. qui la casella combacia con
     il disegno e restituisce quei pixel al testo (sovrascrive la riga 1491) */
  .brand svg { width: 9.5px; height: 20px; }
}

@media (max-width: 380px) {
  /* ultimi millimetri recuperati dove il conto e' piu' stretto: si stringono
     i respiri laterali della pillola, non i bersagli tattili */
  .nav__inner { padding: 0 7px 0 13px; }
  .nav__right { gap: 5px; }
  .brand { gap: 5px; overflow: hidden; }
  .lang-btn { padding: 6px 8px; gap: 4px; }
  .lang-menu { min-width: 142px; }
}

/* telefono in orizzontale: lo schermo e' alto ~350-420px e la tendina in
   colonna non ci sta comunque. la larghezza pero' abbonda, quindi le voci si
   dispongono su due colonne: tre righe invece di sei, tutto visibile senza
   scorrere e senza ridurre l'area toccabile delle voci */
@media (max-height: 480px) and (orientation: landscape) {
  :root { --nav-h: 52px; }
  .nav { inset: 10px 0 auto; }
  .nav__links.is-mobile {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 12px;
    padding: 10px 16px;
    max-height: calc(100vh - var(--nav-h) - 32px);
    max-height: calc(100dvh - var(--nav-h) - 32px);
  }
}
/* ==========================================================================
   Responsive — Hero, bottone a osso e fascia di foto
   L'ordine dei blocchi qui sotto conta: le media query vanno dalla piu'
   larga alla piu' stretta, poi (hover:none), poi il landscape. Sopra i
   1160px ogni valore calcolato coincide con quello originale.
   ========================================================================== */

/* ---------- Bottone a osso: una sola manopola, --bh ----------
   La sagoma nasce da quattro cerchi agli angoli: i centri stanno a --r dai
   lati e quindi a (H - --d)/2 dall'asse orizzontale. La strozzatura vale
   r - radice(r^2 - ((H-d)/2)^2) = 3,51px sui 52px originali, ed e' per
   questo che la barra rientra di 4px: appena piu' della strozzatura, cosi'
   resta dentro la sagoma. Tutte queste relazioni sono proporzionali, quindi
   basta scalare ogni misura di k = --bh/52 e l'osso resta un osso a
   qualunque altezza. Con --bh:52px i calcoli ridanno esattamente 16/32/30/4.
   L'altezza scende da 52 a 44px (minimo tocco-friendly) fra ~754px e
   ~638px di viewport: sopra resta piena, sotto si ferma. */
.bone-btn {
  --bh: clamp(44px, 6.9vw, 52px);

  --r:     calc(var(--bh) * 16 / 52);   /* raggio dei lobi */
  --d:     calc(var(--bh) * 32 / 52);   /* diametro dei lobi */
  --bar:   calc(var(--bh) * 30 / 52);   /* altezza della barra centrale */
  --inset: calc(var(--bh) *  4 / 52);   /* rientro = profondita' strozzatura */

  height: var(--bh);
  min-width: calc(var(--bh) * 126 / 52);
  padding: 0 calc(var(--bh) * 22 / 52);
  /* il testo non deve mai andare a capo: con l'altezza fissa una seconda
     riga uscirebbe dalla sagoma. Il corpo scala con il bottone ma non
     scende sotto i 14px, sotto i quali un'etichetta lunga diventa illeggibile */
  font-size: clamp(14px, calc(var(--bh) * 15 / 52), 15px);
  white-space: nowrap;
  max-width: 100%;
}
/* l'osso "Chiama ora" della colonna contatti resta ai suoi 46px, ma ora con
   i lobi ricalcolati su quell'altezza invece che su 52 */
.bone-btn--call { --bh: 46px; }

/* ---------- Fascia foto: card, passo e sollevamento fluidi ----------
   --cw e' l'unica misura da cui dipendono card e altezza (rapporto
   172:214 del video). Sopra i 573px vale 172px pieni, quindi da li' in su
   non cambia nulla; sotto le card diventano il 30% della larghezza dello
   schermo, cosi' se ne vedono sempre tre e mezza come sul desktop.
   --pull sostituisce il margin-top:-70px fisso: la risalita della fascia
   deve accompagnare il sollevamento, altrimenti azzerando --lift le card
   finiscono sopra il bottone. Sopra i ~1150px valgono ancora 92 e 70. */
.photo-strip {
  --cw:   clamp(104px, 30vw, 172px);
  --lift: clamp(46px, 8vw, 92px);
  --pull: clamp(18px, 6.1vw, 70px);
  margin-top: calc(var(--pull) * -1);
}
/* il passo del loop e' la larghezza della traccia, che comprende il
   padding-right finale: se non fosse identico al gap, alla giunzione fra
   una copia e l'altra si vedrebbe una spaziatura diversa dalle altre */
.photo-strip .marquee__track {
  gap: clamp(12px, 4.5vw, 26px);
  padding-right: clamp(12px, 4.5vw, 26px);
}
.photo-strip .photo-card {
  width: var(--cw);
  height: calc(var(--cw) * 214 / 172);
}
.photo-strip .photo-card__in { border-radius: calc(var(--cw) * 14 / 172); }

/* ---------- Hero: si accorcia lo spazio sopra e fra i blocchi ---------- */
@media (max-width: 980px) {
  .hero { padding-top: calc(var(--nav-h) + 66px); }
  .trusted { margin-bottom: 22px; }
  .hero__cta { margin-top: 28px; }
}

@media (max-width: 640px) {
  /* ripete il valore gia' scritto nella media query storica a 640px: questo
     blocco arriva dopo nel file, quindi senza la ripetizione vincerebbe la
     regola dei 980px qui sopra */
  .hero { padding-top: calc(var(--nav-h) + 54px); }
  /* solo il margine: il corpo lo governa --fs-lead, che sul telefono ALZA
     il testo a 16.5px invece di abbassarlo (15,5px di grigio su bianco a
     360px sono al limite della leggibilita') */
  .hero__sub { margin-top: 16px; }
  .hero__cta { margin-top: 24px; }
  .trusted { margin-bottom: 18px; gap: 10px; max-width: 100%; }
}

@media (max-width: 480px) {
  .hero { padding-top: calc(var(--nav-h) + 44px); }
  /* il clamp di base si blocca a 40px sotto i 645px: su uno schermo da 375px
     un titolo di 40px va su tre righe pesantissime. Qui riprende a scendere
     fino a 33px, che e' il punto in cui "sentono." sta ancora in una riga */
  .h1 { font-size: clamp(33px, 8.6vw, 40px); }
}

@media (max-width: 380px) {
  .hero { padding-top: calc(var(--nav-h) + 38px); }
  /* avatar e testo devono restare affiancati su una riga sola: a 320px la
     shell offre 284px e la coppia ne chiede circa 190, ma con l'inglese
     ("500+ Pet Parents") il margine si assottiglia troppo */
  .trusted { gap: 9px; }
  .trusted__avs img { width: 30px; height: 30px; }
  .trusted__avs img + img { margin-left: -11px; }
  .trusted__txt small { font-size: 12px; }
  .trusted__txt strong { font-size: 14px; }
}

/* ---------- Senza mouse non c'e' hover: niente sollevamento ----------
   Sul touch il sollevamento non si vede mai, ma il suo spazio veniva
   riservato lo stesso (92px di padding-top morto). Qui --lift va a zero e
   con lui --pull, perche' le due misure si compensano: restano gli 8vw che
   servono davvero, cioe' la risalita della banda inclinata (6.9vw), piu'
   18px di respiro sotto il bottone.
   Servono anche gli annullamenti espliciti: il tap su iOS emette un
   mouseover sintetico che fa scattare .is-up, e senza JS resterebbe attivo
   il fallback su :hover, che sul touch resta appiccicato alla card. */
@media (hover: none) {
  .photo-strip {
    --lift: 0px;
    --pull: 0px;
    padding-top: calc(8vw + 18px);
  }
  .photo-card.is-up,
  .photo-strip:not(.has-cardfx) .photo-card:hover {
    transform: rotate(var(--card-rot));
    z-index: auto;
  }
  .photo-card.is-up .photo-card__in,
  .photo-strip:not(.has-cardfx) .photo-card:hover .photo-card__in {
    animation: none;
    box-shadow: 0 8px 26px rgba(0, 0, 0, .09);
  }
  .bone-btn:hover { filter: none; }
}

/* ---------- Telefono coricato: 380px di altezza in tutto ----------
   Con l'hero a misura piena il solo blocco di testo riempirebbe due
   schermate. Qui si taglia tutto lo spazio verticale e si dimezza
   l'inclinazione: l'escursione di una banda larga 132% ruotata vale
   0.66 * Vw * sin(tilt), cioe' 6.9vw a 6 gradi e 3.45vw a 3 gradi, per
   questo il padding puo' scendere da 8vw a 4vw restando abbondante.
   Le card si misurano sull'altezza disponibile, non piu' sulla larghezza. */
@media (max-height: 480px) and (orientation: landscape) {
  .hero { padding-top: calc(var(--nav-h) + 24px); }
  .h1 { font-size: clamp(28px, 4.4vw, 40px); }
  .trusted { margin-bottom: 12px; }
  .hero__sub { margin-top: 12px; }
  .hero__cta { margin-top: 18px; }
  .photo-strip {
    --tilt: 3deg;
    --cw: clamp(92px, 26vh, 132px);
    --lift: 0px;            /* niente spazio per sollevare, in nessun caso */
    --pull: 0px;
    padding-top: calc(4vw + 12px);
    padding-bottom: 4vw;
  }
}
/* ==========================================================================
   Responsive — About / ventaglio / statistiche
   Nulla qui cambia il rendering sopra i 1160px: ogni clamp() e' calibrato
   perche' a quella larghezza il valore massimo sia gia' raggiunto.
   ========================================================================== */

/* --- il ventaglio ---------------------------------------------------------
   Le tre foto erano flex-item con larghezza fissa ma senza flex:none: appena
   la colonna scende sotto i 450px (somma delle tre) il flex-shrink le
   restringeva lasciando l'altezza a 182/218px, e object-fit:cover tagliava
   il soggetto. Ora la larghezza e' fluida, l'altezza segue da aspect-ratio
   (gli stessi rapporti originali 138/182 e 174/218) e flex:none impedisce
   qualunque compressione residua. */
.fan__side {
  flex: none;
  width: clamp(112px, 11.9vw, 138px);   /* 11.9vw = 138px esatti a 1160px */
  height: auto;
  aspect-ratio: 138 / 182;
}
.fan__main {
  flex: none;
  width: clamp(140px, 15vw, 174px);     /* 15vw = 174px esatti a 1160px */
  height: auto;
  aspect-ratio: 174 / 218;
}

/* lo scostamento laterale diventa percentuale: 34/138 = 24.64% e 20/138 =
   14.49%, cioe' esattamente i valori di oggi a piena dimensione, ma se le
   foto rimpiccioliscono il ventaglio si chiude nella stessa proporzione
   invece di far sparire le laterali sotto quella centrale. */
.fan__side--l { transform: rotate(-8deg) translateX(24.64%); }
.fan__side--r { transform: rotate(8deg)  translateX(-24.64%); }
.fan:hover .fan__side--l { transform: rotate(-13deg) translateX(14.49%); }
.fan:hover .fan__side--r { transform: rotate(13deg)  translateX(-14.49%); }

/* l'altezza minima serviva a dare aria attorno alle foto: se le foto si
   rimpiccioliscono deve rimpicciolirsi anche lei, altrimenti sul telefono
   resta un buco di oltre 100px sotto al ventaglio. 23vw tocca il tetto di
   260px gia' a 1131px, quindi il desktop non si accorge di nulla. */
.fan { min-height: clamp(150px, 23vw, 260px); }

/* sotto i 980px la griglia About passa a una colonna sola: c'e' tutta la
   larghezza dello shell, quindi le foto tornano alla misura piena e
   ricominciano a scalare solo quando lo shell non le contiene piu'
   (450px + il debordo delle rotazioni ~ 474px, cioe' sotto i 640px). */
@media (max-width: 980px) {
  .fan__side { width: clamp(84px, 16.88vw + 30px, 138px); }
  .fan__main { width: clamp(106px, 21.25vw + 38px, 174px); }
}

/* su touch il :hover non arriva mai, quindi il ventaglio resterebbe per
   sempre nella posa piu' chiusa: gli diamo di riposo una posa intermedia,
   piu' aperta, che e' anche quella che si legge meglio in piccolo. Le due
   regole sono identiche cosi' un tap non lascia lo stato hover "incollato". */
@media (hover: none) {
  .fan__side--l,
  .fan:hover .fan__side--l { transform: rotate(-11deg) translateX(19%); }
  .fan__side--r,
  .fan:hover .fan__side--r { transform: rotate(11deg)  translateX(-19%); }
}

/* --- griglia About --------------------------------------------------------
   Il gap fluido serve soprattutto fra 980 e 1160px: sono i 9px che mancavano
   alla colonna del ventaglio per non schiacciare le foto. 5.2vw arriva a
   60px a 1154px, quindi sopra i 1160 il valore e' identico a oggi.
   Le due regole sono ridichiarate qui perche' questo blocco sta in fondo al
   file: senza la @media a 980px sovrascriverebbe il gap:44px piu' sopra. */
.about__grid { gap: clamp(40px, 5.2vw, 60px); }
@media (max-width: 980px) {
  .about__grid { gap: clamp(30px, 6vw, 46px); }
  /* a colonna singola il testo aveva un tetto di 450px dentro una colonna da
     900: lo allarghiamo quel tanto che basta a non sembrare una nota a
     margine, restando sotto la lunghezza di riga leggibile. */
  .about__copy .lead { max-width: 640px; }
}

/* --- statistiche ----------------------------------------------------------
   Le quattro card restano a due colonne fino in fondo: una colonna sola sotto
   i 640px allungava la pagina di quasi 300px senza guadagnare leggibilita'.
   auto-fit qui non aiuta (con 4 item e una soglia bassa tornerebbe a quattro
   colonne gia' a 640px), quindi la coppia e' dichiarata esplicitamente. */
.stats { margin-top: clamp(34px, 5.4vw, 62px); }

@media (max-width: 640px) {
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
}
@media (max-width: 380px) {
  /* con 135px di colonna il padding di 24px lasciava 85px utili, meno della
     larghezza di "1259L+": stringendo il padding si arriva a 105px. */
  .stats { gap: 12px; }
  .stat { padding: 18px 14px 16px; }
  .stat span { margin-top: 8px; font-size: 13.5px; }
}

/* il numero era a 34px fissi: in colonna stretta "1259L+" (tabular-nums,
   circa 3,6em) sarebbe uscito dalla card. La retta e' ancorata a 24px su
   380px e a 34px su 1160px, dove il clamp si chiude: sopra quella soglia il
   valore e' esattamente quello di oggi. */
.stat b { font-size: clamp(24px, 1.282vw + 19.13px, 34px); }

@media (max-width: 480px) {
  .stat { padding: 20px 16px 18px; }
}

/* --- badge di sezione -----------------------------------------------------
   Non rompe nulla, ma 22px di margine sotto una pillola alta 35px sono
   tanti quando l'altezza dello schermo e' la risorsa scarsa. */
@media (max-width: 480px) {
  .badge {
    margin-bottom: 16px;
    padding: 6px 13px 6px 10px;
    font-size: 13.5px;
  }
  .badge svg { width: 9px; height: 19px; }
}

/* OPZIONALE (vedi note coordinatore): abbassare SOLO il pavimento di .h2.
   Il massimo 46px e' raggiunto a 1095px e la parte fluida 4.2vw resta
   invariata, quindi sopra i 619px non cambia assolutamente nulla.
   .h3 NON va toccata: il suo massimo cade a 1182px, cioe' sopra i 1160.
.h2 { font-size: clamp(27px, 4.2vw, 46px); }
*/
/* ==========================================================================
   Servizi — adattamento responsive (griglia + card a due regimi)
   ==========================================================================
   NOTA PER L'INTEGRAZIONE: questo blocco SOSTITUISCE le righe 1499-1502
   dentro @media (max-width: 640px) (.svc__inner, .svc__img, .svc__body,
   .svc__bar): vanno cancellate da li'. Restano invece invariate la riga 1479
   (.services__grid a una colonna sotto i 980px) e il blocco @media (hover:none)
   delle righe 686-688.
   Sopra i 1160px non cambia nulla: tutti i min()/clamp() qui sotto scelgono
   esattamente i valori originali finche' la card e' larga. */

/* --- Guardie fluide, senza media query ---------------------------------- */

/* Il respiro sopra la griglia si accorcia da solo sugli schermi bassi.
   Sopra i 1120px di viewport 5vw supera 56px, quindi il valore desktop
   resta identico al pixel. */
.services__grid { margin-top: clamp(32px, 5vw, 56px); }

/* Il testo della card e' posizionato in assoluto e non "sa" dove finisce la
   foto: senza guardia, sotto i ~1008px di viewport i 250px del paragrafo
   scavalcano i 172px dell'immagine (e ci passano sopra, perche' il body viene
   dopo nel DOM). Il min() gli impone di fermarsi sempre 24px prima della foto:
   242px = 172 di foto + 20 di distacco destro + 26 di padding sinistro + 24 di
   respiro. Con la card desktop (568px) il calcolo da' 326px, quindi vince il
   valore originale di 250px e il desktop non si muove. */
.svc__body { max-width: min(250px, calc(100% - 242px)); }

/* --- Da 980px in giu': la card diventa una riga ------------------------- */
/* Qui la griglia passa a una colonna (riga 1479) e la card puo' arrivare a
   ~930px di larghezza: col vecchio layout in assoluto il testo restava
   incollato a sinistra e la fotina a destra, con mezzo metro di bianco in
   mezzo. Passiamo quindi a una griglia interna vera - prezzo e testo a
   sinistra, foto a destra che occupa entrambe le righe - cosi' la card si
   riempie qualunque sia la sua larghezza. Il testo resta allineato in basso
   con la foto, esattamente come nel layout desktop. */
@media (max-width: 980px) {
  .services__grid,
  .services__col { gap: clamp(16px, 2.4vw, 24px); }

  .svc__inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) clamp(160px, 26%, 240px);
    grid-template-areas:
      "price img"
      "body  img";
    gap: 14px 26px;
    align-content: start;
    min-height: 0;              /* l'altezza la decide il contenuto */
    padding: 24px;
  }

  .svc__price { grid-area: price; }

  /* la foto rientra nel flusso: niente piu' coordinate assolute */
  .svc__img {
    grid-area: img;
    position: static;
    align-self: start;          /* altezza esplicita, non stirata */
    width: 100%;
    height: clamp(170px, 20vw, 220px);
    margin-top: 0;              /* annulla il margine della vecchia riga 1500 */
  }

  .svc__body {
    grid-area: body;
    position: static;
    align-self: end;            /* resta appoggiato in basso come sul desktop */
    max-width: 52ch;            /* righe leggibili anche su card larghissime */
    margin-top: 0;              /* annulla il margine della vecchia riga 1501 */
  }
  .svc__body h3 { font-size: clamp(20px, 2.2vw, 23px); }
}

/* --- Da 760px in giu': stessa riga, proporzioni piu' strette ------------ */
/* La card ora e' larga quanto lo schermo meno i margini: la foto puo'
   prendersi una fetta maggiore in percentuale senza sbilanciare il testo. */
@media (max-width: 760px) {
  .svc__inner {
    grid-template-columns: minmax(0, 1fr) clamp(140px, 30%, 200px);
    gap: 12px 20px;
    padding: 22px;
  }
  .svc__img { height: clamp(150px, 22vw, 190px); }
  .svc__body p { font-size: 14px; }
}

/* --- Da 640px in giu': riga compatta ------------------------------------ */
/* Prima qui si passava di colpo alla foto a tutta larghezza: il salto era
   netto. Teniamo ancora la riga affiancata, solo piu' stretta, e rimandiamo
   l'impilamento a 480px. Prezzo e finestra del roll scalano INSIEME: il roll
   usa translateY(100%), cioe' l'altezza della finestra, quindi finche' le due
   misure restano proporzionate l'animazione resta perfettamente registrata. */
@media (max-width: 640px) {
  .svc__inner {
    grid-template-columns: minmax(0, 1fr) clamp(118px, 34%, 190px);
    gap: 10px 16px;
    padding: 20px;
  }
  .svc__img { height: clamp(130px, 26vw, 175px); }
  .svc__body h3 { font-size: clamp(18px, 4.6vw, 21px); }
  .svc__body p { margin-top: 6px; font-size: 13.5px; }

  .svc__price { height: clamp(28px, 6.4vw, 32px); }
  .svc__price > span { font-size: clamp(22px, 5.2vw, 26px); }
}

/* --- Da 480px in giu': la card si impila -------------------------------- */
/* Sotto i 480px una foto affiancata scenderebbe sotto i 130px e non
   racconterebbe piu' nulla: qui ha senso il classico prezzo / foto / testo,
   nell'ordine in cui gli elementi stanno gia' nell'HTML. */
@media (max-width: 480px) {
  .svc__inner {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "price"
      "img"
      "body";
    gap: 14px;
    padding: 20px 20px 22px;
  }
  .svc__img { height: clamp(150px, 44vw, 190px); }
  .svc__body { align-self: auto; max-width: none; }

  /* con la foto a tutta larghezza la rotazione in hover sporgerebbe di lato e
     verrebbe tranciata dal contenitore: lasciamo il solo ingrandimento */
  .svc:hover .svc__img { transform: scale(1.03); }

  .svc__bar { padding-right: 18px; }
}

/* --- Schermi molto stretti ---------------------------------------------- */
@media (max-width: 380px) {
  .svc__inner { padding: 17px 17px 19px; gap: 12px; }
  .svc__bar { padding-right: 15px; font-size: 13.5px; }
}
/* ==========================================================================
   Trasformazioni (before/after) — adattamento fluido e usabilita' touch
   Tutte le formule qui sotto saturano gia' a 640px: da li' in su il
   comparatore resta identico a prima, desktop compreso.
   ========================================================================== */

/* La card era 268x316 fissi: su un telefono a 320px si mangiava l'84% dello
   schermo, e cosi' non si capiva nemmeno di essere dentro una striscia che
   scorre. Qui la larghezza scende in modo continuo da 268px (a 640px in su)
   a 196px (a 320px), lasciando sempre intravedere la card successiva: e' il
   segnale che invita a scorrere. L'altezza non e' piu' scritta a mano ma
   ricavata dal rapporto originale 268/316, cosi' la proporzione delle foto
   non cambia mai e a 268px si ottiene esattamente 316px come prima. */
.ba {
  width: clamp(196px, 22.8vw + 122px, 268px);
  height: auto;
  aspect-ratio: 268 / 316;

  /* pan-y da solo impediva anche di zoomare con due dita: si continua a
     catturare lo swipe orizzontale (che qui serve al comparatore e non
     toglie niente, la pagina non scorre in orizzontale) ma si restituisce
     il pinch-zoom all'utente. */
  touch-action: pan-y pinch-zoom;

  /* iOS vuole ancora il prefisso per la selezione, e senza touch-callout il
     dito tenuto premuto fa comparire il menu "Salva immagine" proprio mentre
     si sta trascinando la maniglia. */
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

/* browser senza aspect-ratio: le foto sono in posizione assoluta, quindi
   senza un'altezza esplicita la card collasserebbe a zero */
@supports not (aspect-ratio: 1 / 1) {
  .ba { height: clamp(231px, 26.9vw + 144px, 316px); }
}

/* le immagini sono gia' pointer-events:none, ma Safari e Chrome permettono
   comunque di "staccarle" col drag nativo e questo interrompe il trascinamento */
.ba img { -webkit-user-drag: none; user-drag: none; }

/* Le etichette Prima/Dopo scalano con la card: a 320px restano leggibili
   (11px) e, verificato anche in inglese con "Before"/"After", le due
   etichette insieme stanno larghe dentro la card piu' stretta. */
.ba__tag {
  top: clamp(10px, 1.25vw + 6px, 14px);
  padding: clamp(3px, .31vw + 2px, 4px) clamp(8px, .94vw + 5px, 11px);
  font-size: clamp(11px, .47vw + 9.5px, 12.5px);
}
.ba__tag--b { left: clamp(9px, .94vw + 6px, 12px); }
.ba__tag--a { right: clamp(9px, .94vw + 6px, 12px); }

/* Il vuoto fra un comparatore e l'altro era fisso a 26px, cioe' quasi un
   decimo dello schermo a 320px: scende a 14px sui telefoni. */
.ba-strip .marquee__track {
  gap: clamp(14px, 3.75vw + 2px, 26px);
  padding-right: clamp(14px, 3.75vw + 2px, 26px);
}

/* stacco dal titolo proporzionato allo schermo */
.ba-strip { margin-top: clamp(32px, 7.5vw + 8px, 56px); }

/* Dove non esiste il mouse, .ba:hover .ba__knob non scatta mai e la maniglia
   resta piatta: nessuno capisce che si trascina. Le si da' da ferma lo stesso
   rilievo che sul desktop compare al passaggio del mouse — nessun colore o
   forma nuova, solo l'ombra gia' prevista. Riscrivere anche il selettore
   :hover serve a spegnere l'hover "appiccicoso" che i browser mobili
   lasciano attaccato alla card dopo il tap. */
@media (hover: none) {
  .ba .ba__knob,
  .ba:hover .ba__knob {
    transform: scale(1.06);
    box-shadow:
      0 3px 8px rgba(0, 0, 0, .18),
      0 14px 32px rgba(0, 0, 0, .24);
  }
}
/* ==========================================================================
   Responsive — Process (#process) e FAQ (#faq)
   Tutto quello che segue e' calibrato per restituire i valori originali
   sopra i 1160px: i clamp() raggiungono il loro massimo ben prima, quindi
   il desktop non si muove di un pixel.
   ========================================================================== */

/* --- Process: colonna di sinistra appiccicata ---
   130px non era un numero arbitrario: e' l'inset di 18px della navbar fissa,
   piu' i 66px di --nav-h, piu' 46px d'aria. Scritto come somma resta 130px
   oggi ed e' gia' giusto domani, se la navbar si rimpicciolisce sui telefoni.
   Sotto i 980px l'aside torna statico (regola gia' presente), quindi qui
   si tocca solo il valore, non il posizionamento. */
.process__aside { top: calc(var(--nav-h) + 64px); }

/* Su finestre basse (portatili 768px, telefoni in orizzontale) l'aside e'
   piu' alto del viewport disponibile e l'immagine resterebbe tagliata fuori
   mentre e' appiccicata: meglio lasciarlo scorrere via normalmente. */
@media (max-height: 700px) {
  .process__aside { position: static; }
}

/* L'aria sopra la foto e' generosa sul desktop ma ruba mezzo schermo al
   telefono, dove l'immagine e' gia' l'ultimo elemento della colonna. */
.process__aside img { margin-top: clamp(22px, 4vw, 34px); }

/* --- Process: geometria della timeline ---
   Prima il rientro (68px), la posizione del pallino (-68px), il suo diametro
   (45px) e la x della rail (22px) erano quattro numeri scollegati, ripetuti
   una seconda volta nella media query a 640px: bastava cambiarne uno per
   sfasare tutto. Ora derivano da due sole misure fluide, cosi' restano
   sempre allineati a qualsiasi larghezza.
   Il pallino resta 45px fino a 500px di viewport e si stringe solo sotto,
   dove ogni pixel tolto alla colonna sinistra e' un pixel dato al testo:
   a 320px la riga utile passa da 228px a 238px. */
.steps {
  --dot: clamp(34px, 9vw, 45px);
  --gap-dot: clamp(12px, 3vw, 23px);
  /* lo stacco fra un passo e l'altro serve anche al tratto di linea che
     sul telefono collega i pallini: sta qui una volta sola */
  --step-gap: clamp(46px, 9.5vw, 108px);
  padding-left: calc(var(--dot) + var(--gap-dot));
}
.steps__rail { left: calc(var(--dot) / 2 - .5px); }
.step__dot {
  left: calc(-1 * (var(--dot) + var(--gap-dot)));
  width: var(--dot);
  height: var(--dot);
  font-size: clamp(15px, 4.2vw, 19px);
}

/* 108px fra un passo e l'altro danno respiro quando accanto scorre la
   colonna di sinistra; in colonna unica su un telefono diventano un vuoto
   che allunga la sezione senza motivo. Il massimo e' gia' raggiunto a
   1137px, quindi il desktop resta identico. */
.step { padding-bottom: var(--step-gap); }
.step:last-child { padding-bottom: 0; }

/* Il titolo del passo torna a 25px pieni gia' da 463px in su. */
.step h3 { font-size: clamp(20px, 5.4vw, 25px); }

/* --- Process: rete di sicurezza sul testo dei passi ---
   PROBLEMA: i .step__txt nascono a opacity:0 e li riaccende solo il JS.
   Se main.js non arriva alla timeline (script bloccato, errore in una
   sezione precedente, rete che si interrompe) l'intera sezione mostra
   quattro pallini numerati e nessun testo.
   SOLUZIONE: il testo ora e' visibile di default; a nasconderlo e' la
   classe .steps--live, che il JS mette sul contenitore solo quando la
   timeline e' effettivamente inizializzata. Nessun JS, nessun nascondiglio. */
.step__txt { opacity: 1; transform: none; }
.steps--live .step__txt { opacity: 0; transform: translateY(10px); }
.steps--live .step.is-on .step__txt { opacity: 1; transform: none; }

/* Sul telefono la comparsa a scorrimento vale poco (i passi entrano quasi
   tutti insieme) e costa molto se qualcosa va storto: sotto i 760px il
   testo e' sempre in chiaro e resta animata solo la linea coi pallini. */
@media (max-width: 760px) {
  .steps--live .step__txt { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .steps--live .step__txt { opacity: 1; transform: none; }
}

/* --- Process: impaginazione centrata sul telefono ---
   In colonna unica il blocco restava incollato a sinistra e la timeline
   spostava tutto il testo di 57-68px verso destra, con la colonna di
   lettura sbilanciata. Sotto i 760px la sezione si allinea al centro:
   il pallino numerato sale sopra il suo testo (invece di stargli a
   fianco) e il testo si centra sotto di lui.
   La linea che unisce i pallini resta, ma non puo' piu' essere l'unica
   rail continua del desktop: al centro passerebbe dietro alle parole.
   Diventa quindi un tratto per ogni passo, che vive nello stacco fra la
   fine di un testo e il pallino successivo — la linea c'e', ed e'
   interrotta dove c'e' il testo. Sopra i 760px non cambia nulla. */
@media (max-width: 760px) {
  .process__aside { text-align: center; }
  .process__aside .lead { margin-inline: auto; }
  /* l'immagine e' inline: senza display:block il margine automatico non
     la centrerebbe */
  .process__aside img { display: block; margin-inline: auto; }

  .steps { padding-left: 0; width: 100%; text-align: center; }

  /* la rail continua sparisce: al suo posto i tratti fra un passo e l'altro */
  .steps__rail { display: none; }

  /* il pallino esce dal posizionamento assoluto e torna nel flusso,
     centrato sopra al testo del passo */
  .step__dot {
    position: relative;
    left: auto;
    top: auto;
    margin: 0 auto clamp(12px, 3vw, 16px);
  }
  .step p { margin-inline: auto; }

  /* Il tratto di collegamento. bottom:0 e' esattamente dove comincia il
     passo successivo, cioe' il suo pallino: partendo da 12px piu' su e
     alto quanto lo stacco meno i due margini, il segmento resta staccato
     sia dal testo sopra sia dal pallino sotto. L'ultimo passo non ne ha
     bisogno, non c'e' niente da collegare. */
  .step:not(:last-child)::after {
    content: '';
    position: absolute;
    left: calc(50% - 1px);
    bottom: 12px;
    width: 2px;
    height: calc(var(--step-gap) - 24px);
    background: #e4e2e0;
    transition: background .35s var(--ease);
  }
  /* stessa progressione dei pallini: quando il passo si accende, si
     accende anche il tratto che porta al successivo */
  .step.is-on:not(:last-child)::after { background: var(--orange); }
}

/* --- Process e FAQ: il solco fra le due colonne ---
   70px sono giusti quando lo shell e' al massimo; appena le colonne si
   stringono quel solco si mangia lo spazio del testo. Il valore pieno e'
   mantenuto fino a 1148px, quindi sopra i 1160px non cambia nulla. */
@media (max-width: 1180px) {
  .process__grid,
  .faq__grid { gap: clamp(38px, 6.1vw, 70px); }
}

/* --- FAQ: respiro del pannello ---
   Il pannello grigio ha 18px di bordo e le schede bianche altri 20px:
   a 320px sono 76px di margini prima ancora di iniziare a scrivere, e
   alla domanda restano 174px. Rendendoli fluidi si recuperano quasi 40px
   di riga utile senza toccare il desktop (i massimi sono gia' attivi
   sopra i 563px). */
.faq__panel {
  padding: clamp(10px, 3.2vw, 18px);
  gap: clamp(8px, 2.2vw, 12px);
}

/* Un'unica variabile per il padding orizzontale, cosi' domanda e risposta
   non possono andare fuori registro quando si stringono. */
.acc { --acc-pad-x: clamp(13px, 4vw, 20px); }
.acc__q {
  padding: clamp(13px, 3.4vw, 17px) var(--acc-pad-x);
  gap: clamp(10px, 3vw, 18px);
  font-size: clamp(14.5px, 3.6vw, 15.5px);
}
.acc__a p { padding: 0 var(--acc-pad-x) clamp(13px, 3.4vw, 18px); }
/* ==========================================================================
   Responsive — Recensioni (#testimonial) e Team (#team)
   ========================================================================== */

/* --- Team: misure fluide ---
   Le card erano 250px fissi con l'immagine a 268px: riducendo la sola
   larghezza il ritaglio di object-fit diventava un ritratto sempre piu'
   stretto, percio' l'altezza e' legata al rapporto originale (250:268)
   invece che a un valore assoluto.
   Tutti i clamp() qui sotto sono gia' al loro massimo ben prima dei 1160px:
   sopra quella soglia il layout non cambia di un pixel. */
.member { width: clamp(150px, 44vw, 250px); }

@supports (aspect-ratio: 1) {
  .member img { height: auto; aspect-ratio: 250 / 268; }
}

.member b {
  margin-top: clamp(12px, 3.5vw, 20px);
  font-size: clamp(17px, 3.9vw, 22px);
}
.member span { font-size: clamp(12.5px, 2.5vw, 14px); }

/* gap e padding-right devono restare IDENTICI: il padding chiude la
   giuntura fra una copia della traccia e la successiva, se i due valori
   divergono a ogni ciclo compare uno scalino. Un'unica variabile evita
   che si disallineino. */
.team-strip .marquee__track {
  --team-gap: clamp(14px, 3vw, 26px);
  gap: var(--team-gap);
  padding-right: var(--team-gap);
}

@media (max-width: 980px) {
  /* Recensioni: in colonna unica la riga di testo superava i 110 caratteri.
     Le tre .quotes__col vengono sciolte con display:contents cosi' gli item
     della griglia sono le sei citazioni e non le colonne: senza questo, con
     due colonne resterebbe una colonna orfana sotto.
     Il JS dello stagger legge group.children, che display:contents non tocca. */
  .quotes { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
  .quotes__col { display: contents; }

  /* il marquee del team scorre un giro intero in --speed secondi: piu' il
     viewport e' stretto, piu' quel movimento pesa in proporzione allo
     schermo. Rallentando si tiene la velocita' percepita intorno al 4%
     della larghezza al secondo, come su desktop.
     --speed non e piu inline nell HTML ma sta nelle fondamenta, quindi
     qui basta una regola normale, senza !important.
     */
  .team-strip .marquee { --speed: 56s; }
}

/* Il galleggiamento delle schede e' un'animazione infinita su sei elementi:
   sul telefono e su qualsiasi schermo tattile costa batteria e disturba la
   lettura mentre si scorre. Stessa logica del blocco prefers-reduced-motion. */
@media (max-width: 760px), (hover: none) {
  .quote.is-in { animation: none; }
}

@media (hover: none) {
  /* niente zoom "appiccicato": su touch :hover resta attivo dopo il tap */
  .member:hover img { transform: none; }
}

@media (max-width: 640px) {
  /* Recensioni a due colonne anche sul telefono. Le card diventano strette,
     quindi tutto quello che le riempie (padding, corpo del testo, firma,
     avatar) scende in proporzione: senza, a 320px il padding pieno si
     mangiava meta' della riga. I massimi sono quelli originali, cosi'
     sopra i 640px non cambia niente. */
  .quotes { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(10px, 2.6vw, 16px); }
  .quote { padding: clamp(15px, 3.9vw, 24px) clamp(13px, 3.5vw, 22px) clamp(13px, 3.5vw, 22px); }
  /* colonne strettissime: meglio spezzare che sfondare la card */
  .quote p { overflow-wrap: break-word; font-size: clamp(13px, 3.3vw, 15px); }
  .quote footer {
    margin-top: clamp(12px, 3vw, 18px);
    gap: clamp(7px, 2vw, 11px);
    font-size: clamp(12.5px, 3.2vw, 15px);
    /* nomi lunghi ("Michele, proprietario di Charlie") non devono
       spingere fuori l'avatar */
    flex-wrap: wrap;
  }
  .quote footer span { min-width: 0; overflow-wrap: break-word; }
  .quote img {
    width: clamp(24px, 6vw, 30px);
    height: clamp(24px, 6vw, 30px);
  }

  /* con card strette i ruoli piu' lunghi ("Responsabile toelettatura",
     "Pet Behavior Specialist") vanno a capo: balance divide le due righe
     in modo uniforme invece di lasciare una parola isolata. */
  .member span { text-wrap: balance; }

  .team-strip { margin-top: 40px; }
  .team-strip .marquee { --speed: 68s; }
}

@media (max-width: 480px) {
  .quotes { margin-top: 40px; }
}
/* ==========================================================================
   Responsive — CTA orbitale, fascia arancione e footer
   Nota di lettura: sopra i 1160px non cambia nulla. Tutte le clamp() qui sotto
   sono tarate perche' il valore massimo sia gia' raggiunto a 1160px, cosi' il
   desktop resta identico al pixel e la riduzione parte solo scendendo.

   COORDINATORE — regole esistenti da toccare:
   - righe 1062-1065  @media (max-width:700px){.cta__float{display:none}}
                      -> ELIMINARE (breakpoint fuori standard e troppo basso)
   - riga 1483        .foot__claim { grid-column: 1 / -1; }
                      -> codice morto, sostituito qui sotto
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. CTA — la fascia dove l'anello di foto puo' davvero stare
   L'anello e' un'ellisse schiacciata (--flat .56): in verticale e' molto piu'
   stretto che in orizzontale, ed e' li' che entra in conflitto col testo.
   Facendo i conti: a 900px il semiasse verticale vale 166px mentre il blocco
   di testo e' alto 166px a partire dal centro; servirebbero 203px per far
   passare le foto sopra il titolo. A 768px va anche peggio, e allargare il
   raggio non aiuta perche' l'anello uscirebbe dal viewport e verrebbe tagliato
   a meta' foto dall'overflow:hidden. L'anello torna respirabile solo da circa
   1080px in su: sotto i 980px si nasconde e basta.
   -------------------------------------------------------------------------- */
@media (max-width: 980px) {
  /* niente anello: le foto passerebbero dietro al titolo rendendolo illeggibile */
  .cta__float { display: none; }

  /* i 200px di padding servivano solo a contenere l'anello: senza anello
     restavano 400px di bianco. Qui il respiro torna in scala con la sezione */
  .cta { padding: clamp(64px, 9vw, 88px) 0; }

  /* cintura di sicurezza: se un giorno l'anello venisse rimostrato qui,
     le nove animazioni infinite non devono comunque girare a vuoto */
  .cta__orbit,
  .cta__spin { animation: none; }
}

/* il bottone segue la scala del resto della sezione (34px gia' a 1160px) */
.cta__btn { margin-top: clamp(24px, 2.95vw, 34px); }

/* nove animazioni infinite (un giro + otto contro-rotazioni) sono esattamente
   il tipo di movimento che chi attiva "riduci animazioni" vuole spegnere:
   le foto restano dove sono, l'anello si ferma */
@media (prefers-reduced-motion: reduce) {
  .cta__orbit,
  .cta__spin { animation: none !important; }
}

/* --------------------------------------------------------------------------
   2. Fascia arancione e wordmark
   Due difetti veri, entrambi dovuti ai *minimi* delle clamp che smettono di
   scalare troppo presto e vanno fuori proporzione fra loro.
   -------------------------------------------------------------------------- */

/* una sola misura guida tutta la fascia, cosi' ossicino e scritta restano
   agganciati fra loro invece di scalare ognuno per conto suo */
.wordmark { --wm: clamp(22px, 10.2vw, 134px); }

/* il minimo di 34px era troppo alto: "Zampe in Festa" su una riga sola, in
   peso 800, misura circa 6,7-7,4 volte il corpo, cioe' 228-253px a 34px; con
   ossicino, gap e padding si arriva a 290-315px su 320 disponibili, e con il
   font di sistema (durante il caricamento del webfont) si sfora e la fascia,
   che ha overflow:hidden, taglia via la Z e l'ossicino. Lasciando scendere il
   corpo insieme al viewport la scritta resta sempre dentro, e la differenza
   a 320px e' di un solo pixel e mezzo: invisibile */
.wordmark span { font-size: var(--wm); }

/* l'ossicino si fermava a 20px di larghezza gia' a 588px, quindi diventava
   alto 47px mentre il box del testo scendeva a 31px: siccome la mask sfuma a
   partire dal 52% dell'altezza dell'INTERO blocco, sotto i ~510px la
   sfumatura mangiava tre quarti della scritta invece della meta'. Legando la
   larghezza massima dell'ossicino al corpo del testo l'altezza del blocco
   torna a essere sempre dettata dalla scritta e la sfumatura e' identica a
   ogni larghezza. Sopra i 1160px il tetto non morde mai (134 x .34 = 45,6px,
   piu' dei 44px gia' previsti), quindi il desktop non cambia */
.wordmark svg { width: min(clamp(20px, 3.4vw, 44px), calc(var(--wm) * .34)); }

/* 42px di raggio su una fascia larga 320px sono il 13% della larghezza contro
   il 3,6% del desktop: la curva si mangiava gli angoli */
.foot-band {
  border-radius: clamp(24px, 3.7vw, 42px) clamp(24px, 3.7vw, 42px) 0 0;
  padding: clamp(32px, 5.3vw, 60px) 0 0;
}

/* --------------------------------------------------------------------------
   3. Footer — griglia
   -------------------------------------------------------------------------- */
.foot { padding: clamp(40px, 5.5vw, 62px) 0 0; }
.foot__grid { gap: clamp(30px, 3.5vw, 40px); }
.foot__bar { margin-top: clamp(34px, 5vw, 56px); }

@media (max-width: 980px) {
  /* la regola esistente mette grid-column su .foot__claim, che pero' e' il
     paragrafo DENTRO al primo div e non un figlio della griglia: non aveva
     nessun effetto e a due colonne restava un buco in basso a destra
     (claim + Link rapidi sulla prima riga, Informazioni da sola sulla
     seconda). Il claim va preso dal suo contenitore, che e' il grid item */
  .foot__grid > div:first-child { grid-column: 1 / -1; }
}

/* Sotto i 640px la griglia restava a colonna unica e "Informazioni" finiva
   sotto a "Link rapidi", allungando il footer di un paio di schermate. Le
   due colonne restano invece affiancate a qualsiasi larghezza: il claim
   occupa la riga intera (regola qui sopra) e sotto stanno i due elenchi.
   A 320px ogni colonna e' larga ~146px, quindi mail e telefono devono poter
   spezzarsi invece di sfondare la gronda. */
@media (max-width: 640px) {
  .foot__grid { column-gap: clamp(16px, 5vw, 30px); }
  .foot__col h4 { font-size: clamp(15.5px, 4.2vw, 17px); }
  .foot__col a,
  .foot__col ul.foot__info {
    font-size: clamp(13.5px, 3.6vw, 15px);
    overflow-wrap: anywhere;
  }
}

/* --------------------------------------------------------------------------
   4. Footer — aree di tocco
   Tutte le icone e i link del footer sono sotto il minimo di 44px. Le aree si
   allargano con uno ::after assoluto: non ha sfondo, non occupa spazio nel
   flusso e quindi NON sposta di un pixel il layout desktop, ma il dito ci
   arriva lo stesso. Le estensioni sono calcolate per riempire esattamente il
   gap esistente, cosi' due target vicini si toccano senza mai sovrapporsi.
   -------------------------------------------------------------------------- */

/* icone social: 20x20 visivi, 44x34 toccabili (34 = 20 + i 14px di gap) */
.socials a { position: relative; }
.socials a::after {
  content: '';
  position: absolute;
  inset: -12px -7px;
}

/* link delle colonne: il box di riga e' alto 23px (15px x 1.55), il gap 12px;
   estendendo di 6px sopra e sotto si arriva a 35px senza toccare il vicino */
.foot__col ul { --tap: 6px; }
.foot__col ul.foot__info { --tap: 5.5px; }
.foot__col a {
  position: relative;
  display: inline-block;
}
.foot__col a::after {
  content: '';
  position: absolute;
  inset: calc(var(--tap) * -1) -6px;
}

/* "Privacy Policy" non ha vicini cliccabili: puo' arrivare a 44px pieni ovunque */
.foot__bar a {
  position: relative;
  display: inline-block;
}
.foot__bar a::after {
  content: '';
  position: absolute;
  inset: -11px -8px;
}

@media (max-width: 760px) {
  /* sul telefono il footer e' gia' impilato e un po' di aria in piu' non
     disturba: allargando i gap le aree di tocco arrivano ai 44px pieni
     (23px di riga + 22px di gap = 45px) restando comunque separate */
  .socials { gap: 24px; }
  .foot__col ul { gap: 22px; --tap: 11px; }
  .foot__col ul.foot__info { gap: 20px; --tap: 10px; }
}
/* ==========================================================================
   Super responsive — pagine interne (contatti / policy / 404)
   Tutto quello che segue vive sotto i 1160px: le clamp sono tarate perche'
   raggiungano il valore desktop entro i 1160px, cosi' la resa sopra la soglia
   resta identica al pixel.

   COORDINATORE — prerequisito: ELIMINARE le righe 1396-1400
   (@media (max-width: 560px) { .cform__row / .map / .map iframe })

   RICONCILIATO CON AG2: la correzione di .bone-btn--call e' espressa con la
   manopola --bh introdotta dal blocco hero, non con --r/--d/--bar a mano.
   --bh:46px produce --r 14.15 / --d 28.3 / --bar 26.5 / --inset 3.54, cioe'
   gli stessi valori che AG9 aveva calcolato a mano (14/28/26/3.3).
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Ritmo verticale fluido: niente breakpoint, solo clamp.
   Sui telefoni i respiri da 76/96px pesano quanto un blocco di testo; le
   clamp li accorciano man mano che lo schermo si stringe e tornano al valore
   originale ben prima dei 1160px (indicato a fianco di ogni regola).
   -------------------------------------------------------------------------- */
.page-head {
  /* la navbar e' fissa a 18px dall'alto ed e' alta --nav-h (66px): finisce a
     84px. Anche col minimo di 34px restano 16px d'aria sotto la pillola. */
  padding: calc(var(--nav-h) + clamp(34px, 5vw, 54px)) 0 clamp(32px, 4.5vw, 48px);
}                                    /* max a 1080px e 1067px */

.doc { padding: clamp(44px, 8vw, 76px) 0 clamp(56px, 10vw, 96px); }  /* max a 950/960px */
.doc h2 { margin-top: clamp(34px, 5vw, 46px); font-size: clamp(22px, 2.4vw, 25px); }
.contact { padding: clamp(32px, 4.5vw, 48px) 0 clamp(48px, 6.5vw, 72px); }
.map { padding-bottom: clamp(56px, 8.3vw, 96px); }                   /* max a 1157px */

/* la mappa: 240px su un telefono sono una finestrella. Alziamo il minimo a
   280px senza sfiorare il desktop, perche' a 1160px 26vw fa gia' 301px e il
   minimo non entra mai in gioco sopra i 1077px. */
.map iframe { height: clamp(280px, 26vw, 340px); }

/* 404: su mobile 76vh usa il viewport "grande" e la sezione salta ogni volta
   che la barra degli indirizzi entra o esce. dvh segue il viewport reale; i
   browser che non lo conoscono ignorano la riga e tengono il 76vh di sopra. */
.err {
  min-height: 76dvh;
  padding: calc(var(--nav-h) + clamp(46px, 7vw, 80px)) 0 clamp(56px, 8vw, 90px);
}
/* le foto scendono con lo schermo: sopra i 431px sono gia' i 112x140 originali */
.err__pets img { width: clamp(84px, 26vw, 112px); height: clamp(105px, 32.5vw, 140px); }

/* --------------------------------------------------------------------------
   2. Correzioni funzionali
   -------------------------------------------------------------------------- */

/* Il bottone-osso "Chiama ora" era alto 46px ma teneva --r:16 tarato su 52:
   la strozzatura crollava da 3,5px a 1,6px e l'osso diventava un rettangolo
   stondato. Con la manopola --bh del blocco hero i quattro lobi si
   ricalcolano da soli sull'altezza giusta. */
.bone-btn--call { --bh: 46px; }

/* la checkbox della privacy e' obbligatoria: quando manca dev'essere visibile
   quanto un campo in errore, altrimenti il messaggio "controlla i campi
   evidenziati" manda l'utente a sbattere (il JS ora aggiunge is-bad qui). */
.check.is-bad { color: var(--orange); }
.check.is-bad input { outline: 2px solid var(--orange); outline-offset: 3px; }
.check input:focus-visible { outline: 2px solid var(--orange); outline-offset: 3px; }

/* la mappa in iframe cattura lo scorrimento a un dito e blocca la pagina:
   sui dispositivi touch resta inerte finche' non la si tocca (la classe
   is-touch la mette il JS, quindi senza JS la mappa resta usabile). */
.map.is-touch iframe { pointer-events: none; }
.map.is-touch.is-live iframe { pointer-events: auto; }

/* --------------------------------------------------------------------------
   3. Dita, non puntatori. Vale per ogni larghezza (anche un iPad in
   orizzontale a 1366px e' un dispositivo touch) e non tocca il desktop,
   perche' la query guarda il tipo di puntatore, non i pixel.
   -------------------------------------------------------------------------- */
@media (hover: none), (pointer: coarse) {

  /* IL BUG PIU' GRAVE DELLA PAGINA: su iOS un campo sotto i 16px fa zoomare
     la pagina al focus e la pagina RESTA zoomata. 16px esatti lo disinnescano. */
  .field input,
  .field select,
  .field textarea { font-size: 16px; }

  /* pillole della visita: 9px di padding + interlinea 14,5px danno 42,5px,
     sotto la soglia dei 44. Con 11px si arriva a 46,5px. */
  .choice__opt span { padding: 11px 16px; }

  /* il quadratino del consenso: 16px sono meno di un polpastrello */
  .check { padding: 2px 0; }
  .check input { width: 22px; height: 22px; margin-top: 1px; }

  /* telefono, email e i link con la freccia sono i tap che valgono di piu':
     portiamoli all'altezza minima raccomandata */
  .info-card__big a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  .info-card .arrow-link,
  .err__actions .arrow-link { min-height: 44px; }
}

/* --------------------------------------------------------------------------
   4. Tablet e sotto
   -------------------------------------------------------------------------- */
@media (max-width: 900px) {
  /* a una colonna lo spazio libero e' zero e space-between degenera comunque
     in start: lo scriviamo per non lasciare in giro una regola che, se un
     domani la riga prendesse altezza, spalancherebbe buchi fra le card */
  .contact__side {
    align-content: start;
    /* la colonna e' larga quanto la pagina: due card per riga invece di
       quattro incolonnate accorciano molto lo scroll */
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .contact__grid { gap: 24px; }

  /* ---- Disposizione delle quattro card sul telefono ----
     I due recapiti "secchi" (un numero, un indirizzo email) stanno
     affiancati in cima, perche' sono corti e sono quelli che si cercano di
     corsa. Indirizzo e orari hanno piu' testo dentro — due righe di via, tre
     righe di giorni — e si prendono tutta la larghezza, uno sotto l'altro.

        [ Chiama ora ] [ Scrivici ]
        [        Dove siamo       ]
        [      Orari d'ufficio    ]

     Nel documento le card restano nell'ordine del desktop (telefono, orari,
     email, indirizzo): qui si sposta solo il disegno, con order. Sopra i
     900px non cambia nulla. */
  .info-card:nth-child(1) { order: 1; }   /* Chiama ora */
  .info-card:nth-child(3) { order: 2; }   /* Scrivici */
  .info-card:nth-child(4) { order: 3; grid-column: 1 / -1; }   /* Dove siamo */
  .info-card:nth-child(2) { order: 4; grid-column: 1 / -1; }   /* Orari d'ufficio */

  /* ---- Una riga sola per numero, email e link della mappa ----
     Da qui in giu' le card stanno in due colonne: un testo che va a capo
     alza la card e sfalsa quella accanto, e il numero di telefono spezzato
     a meta' e' anche il piu' difficile da leggere a colpo d'occhio.
     Il corpo che li fa entrare senza andare a capo arriva dal blocco 640px.
     overflow:hidden e' solo la rete di sicurezza: se un domani il testo
     cambiasse o il font di sistema fosse molto piu' largo del previsto, la
     riga viene troncata dentro la card invece di sfondarne il bordo e
     riportare tutta la pagina in scorrimento orizzontale — che e'
     esattamente il difetto da cui nasceva la navbar lunga. */
  .info-card__big a,
  .info-card .arrow-link {
    white-space: nowrap;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /* colonna piena: l'osso torna alla sua altezza naturale, e con essa alla
     geometria di serie (ricalcolata da --bh) */
  .bone-btn--call { --bh: 52px; }
}

/* --------------------------------------------------------------------------
   5. Telefoni
   -------------------------------------------------------------------------- */
@media (max-width: 640px) {
  /* Due campi affiancati reggono fino a ~265px di colonna: e' quanto chiede
     la tendina "Pomeriggio (14:00 - 19:00)" a 16px (215px di testo + 28 di
     padding + la freccia) e quanto vuole il calendario nativo di iOS/Android.
     A 640px la colonna misura 269px: e' l'ultimo gradino buono, a 480px
     scenderebbe a 189px e i due controlli nativi si troncherebbero.
     (sostituisce la vecchia soglia a 560px) */
  .cform__row { grid-template-columns: minmax(0, 1fr); }

  .contact__form-card { padding: 26px 20px; }

  /* ---- Recapiti: due colonne anche sul telefono ----
     Le quattro card (Chiama ora / Orari / Scrivici / Dove siamo) restavano
     affiancate solo fino a 640px e poi si incolonnavano, allungando la
     pagina di quasi tre schermate. Ora le due colonne arrivano fino in
     fondo: a 320px ogni card e' larga 134px, quindi tutto quello che sta
     dentro deve rimpicciolirsi con lei, altrimenti sfonda il bordo e
     trascina l'intera pagina in scorrimento orizzontale.
     Tutti i massimi sono i valori originali. */
  .contact__side { gap: clamp(12px, 3vw, 16px); }
  .info-card { padding: clamp(14px, 4vw, 22px); }

  /* testata della card: l'icona non puo' restare un blocco fisso da 36px
     quando la riga utile e' 100px */
  .info-card__head { gap: clamp(8px, 2.4vw, 12px); margin-bottom: clamp(9px, 2.6vw, 12px); }
  .info-card__ico { width: clamp(28px, 8vw, 36px); height: clamp(28px, 8vw, 36px); }
  .info-card__ico svg { width: clamp(15px, 4vw, 18px); height: clamp(15px, 4vw, 18px); }
  /* stesso ragionamento dei campi: "d'ufficio" e' una parola sola da ~68px
     e accanto ha l'icona, in una riga utile di 106px. Ci passa, ma per un
     pelo: se il testo o la lingua cambiano deve spezzarsi lui, non allargare
     la card oltre la colonna. */
  .info-card h3 {
    font-size: clamp(14.5px, 3.9vw, 18px);
    min-width: 0;
    overflow-wrap: anywhere;
  }

  /* ---- Numero e email: il corpo si calcola, non si indovina ----
     I due testi non sono lunghi uguali e non possono avere la stessa
     pendenza. Misurati nel font del sito, per ogni pixel di corpo servono
     8,1px di riga al numero (+39 06 4512 3387, 16 caratteri) e 10,2px
     all'email (info@zampeinfesta.it, 20 caratteri: e' l'800% in piu' di
     larghezza per la stessa altezza).
     Il caso peggiore e' lo schermo da 320px, dove dentro la card restano
     106px utili, cioe' il 33,1% della finestra — sopra i 320 la card cresce
     piu' in fretta della finestra, quindi chi entra li' entra ovunque.
     106/8,1 = 13,0px per il numero e 106/10,2 = 10,4px per l'email: tolto
     l'8% di margine per il font di sistema (se quello di Google non arriva)
     restano le due pendenze qui sotto.
     I massimi sono i 20px originali di sempre: il numero li riprende a
     533px di finestra, l'email a 667. */
  .info-card__big {
    font-size: clamp(11px, 3.75vw, 20px);
    overflow-wrap: anywhere;
  }
  .info-card__big a[href^="mailto:"] { font-size: clamp(9px, 3vw, 20px); }
  .info-card__big--sm { font-size: clamp(14px, 4vw, 16.5px); }
  .info-card__big a { max-width: 100%; }
  .info-card__sub { font-size: clamp(12.5px, 3.4vw, 14px); }
  /* "Apri in Google Maps": la card "Dove siamo" e' su tutta la larghezza,
     quindi di spazio ce n'e' d'avanzo e il link resta al corpo di sempre.
     Il nowrap del blocco 900px gli garantisce comunque una riga sola. */
  .info-card .arrow-link { font-size: clamp(12.5px, 3.4vw, 14px); }
  /* Orari d'ufficio. La card sta su tutta la larghezza (vedi il blocco 900px),
     quindi il giorno resta nella forma lunga: "Lunedi - Venerdi" per intero,
     che e' come si legge sul desktop. La forma breve serviva quando la card
     era una delle due strette e il giorno non ci stava.
     La riga puo' comunque andare a capo, ma solo FRA giorno e orario: mai
     dentro la parola. */
  .hours li {
    font-size: clamp(12.5px, 3.4vw, 15px);
    gap: clamp(2px, 2.2vw, 14px);
    flex-wrap: wrap;
    row-gap: 2px;
  }

  /* il bottone-osso ha una larghezza minima di 111px, piu' della card:
     senza toglierla sarebbe lui da solo a sfondare la colonna */
  .bone-btn--call {
    --bh: clamp(40px, 11vw, 46px);
    min-width: 0;
    padding: 0 clamp(8px, 2.5vw, 19px);
    font-size: clamp(13px, 3.5vw, 15px);
  }

  /* invio: il bottone prende tutta la riga, e l'esito gli sta subito sotto
     invece di finire a 20px di distanza dopo essere andato a capo */
  .cform__send { flex-direction: column; align-items: stretch; gap: 12px; }
  .cform__send .bone-btn { width: 100%; }

  /* il documento della privacy si legge tutto d'un fiato: sul telefono
     16px con interlinea piu' generosa affaticano meno */
  .doc p, .doc li { font-size: 16px; line-height: 1.7; }

  .map iframe { border-radius: 16px; }   /* era nel blocco 560px */

  /* 404: bottone e link uno sotto l'altro, senza i 34px di stacco pensati
     per l'affiancamento */
  .err__actions { flex-direction: column; gap: 16px; margin-top: 30px; }
  .err__pets { margin-top: 36px; gap: 14px; }
}

@media (max-width: 480px) {
  .contact__form-card { padding: 24px 18px; }
  .err__pets { gap: 12px; }
}

/* --------------------------------------------------------------------------
   6. Schermi molto stretti (320-380px)
   -------------------------------------------------------------------------- */
@media (max-width: 380px) {
  /* recuperiamo larghezza dai bordi della card: a 320px si passa da 234 a
     254px utili, ed e' quello che permette alle pillole di stare in due */
  .contact__form-card { padding: 22px 14px; }
  /* il padding della .info-card non e' piu' uno scalino secco qui: con le
     due colonne fino in fondo scende con continuita' dal blocco 640px */

  /* in fila le pillole ci stavano una per riga (126+10+120 = 256 > 234):
     in griglia a due colonne sono tutte larghe uguali e il gruppo scende da
     cinque righe a tre, restando alto 45px per riga */
  .choice { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .choice__opt span {
    display: block;
    padding: 11px 6px;
    font-size: 13.5px;
    text-align: center;
  }

  /* gli orari sono gia' impilati e con corpo fluido dai blocchi 640/520px */
  .doc ul { padding-left: 20px; }
}

/* --------------------------------------------------------------------------
   7. Telefono coricato: l'altezza e' la risorsa scarsa, i respiri verticali
   vanno compressi e la cifra del 404 non puo' occupare mezzo schermo.
   -------------------------------------------------------------------------- */
@media (max-height: 480px) and (orientation: landscape) {
  .page-head { padding: calc(var(--nav-h) + 26px) 0 28px; }
  .doc { padding: 40px 0 56px; }

  .err {
    min-height: auto;                /* il contenuto e' gia' piu' alto: il 76% imporrebbe solo vuoto */
    padding: calc(var(--nav-h) + 34px) 0 48px;
  }
  .err__code { font-size: clamp(70px, 11vw, 110px); }
  .err__actions { flex-direction: row; gap: 20px; margin-top: 22px; }
  .err__pets { margin-top: 24px; gap: 10px; }
  .err__pets img { width: 84px; height: 104px; }

  .contact { padding: 28px 0 40px; }
  .map iframe { height: 240px; }
}

/* ==========================================================================
   3. BERSAGLI TATTILI — ultimo blocco del file
   Solo (pointer: coarse): il desktop col mouse non viene toccato in nessun
   modo. La soglia e' 44x44 CSS px, il minimo sotto il quale il dito comincia
   a sbagliare bersaglio.
   Sta in fondo di proposito: tocca selettori che appartengono ai territori
   della navbar, del footer e della pagina contatti, e se stesse piu' in alto
   quei blocchi lo annullerebbero per semplice ordine di sorgente.
   Le icone social e i link del footer NON sono qui: li' l'area si allarga
   con uno ::after assoluto (vedi blocco footer), che non sposta il layout.
   ========================================================================== */
@media (pointer: coarse) {
  /* il burger era 42x42, mancavano due pixel; le tre barrette vanno
     ricentrate nel bottone piu' grande (la distanza fra loro resta 5px,
     quindi le rotazioni della X non cambiano) */
  .nav__burger { width: 44px; height: 44px; }
  .nav__burger span { left: 13px; }
  .nav__burger span:nth-child(1) { top: 16px; }
  .nav__burger span:nth-child(2) { top: 21px; }
  .nav__burger span:nth-child(3) { top: 26px; }

  /* il selettore lingua era alto ~36px, ~34 sotto i 640px */
  .lang-btn,
  .lang-menu button { min-height: 44px; }

  /* la riga estesa dei link vale sui tablet sopra i 900px, dove il burger
     non c'e': le voci erano alte quanto il testo */
  .nav__links a { display: flex; align-items: center; min-height: 44px; }
  .brand { min-height: 44px; }

  /* i campi del modulo: l'altezza calcolata sta gia' sopra la soglia, ma la
     dichiarazione la mette al riparo da qualsiasi riduzione di padding */
  .field input,
  .field select,
  .field textarea { min-height: 44px; }

  /* eccezione: i radio nascosti delle pillole non sono bersagli — il bersaglio
     e' la pillola, che i suoi 44px ce li ha gia'. Senza questa riga si
     riprenderebbero l'altezza qui sopra e tornerebbero a essere caselle vere */
  .choice__opt input { min-height: 0; }
}
