
/* ==================================================
   SCENA 00 — COVER / PRIMA SCHEDA iOS
   Evita una prima schermata "vuota": prima della conversazione esiste
   una vera scheda autonoma, speculare al linguaggio delle altre card.
   ================================================== */
.intro-cover {
  position: relative;
  padding-top: calc(var(--brand-bar-height) + var(--safe-top) + 10px);
}

/* V1.8 — la scheda iOS 1 e' alta 155% della iOS 2 (155dvh = 1.55 * 100dvh,
   era 165% in V1.7): all'apertura pagina si vede solo la prima "fetta" a
   tinta unita, quasi uno sfondo pieno; le stondature basse e la barca si
   scoprono solo scorrendo fino in fondo alla scheda. */
.intro-cover__card {
  min-height: 155svh;
  min-height: 155dvh;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: clamp(30px, calc(8 * var(--vw)), 58px);
  padding-bottom: clamp(140px, 36vh, 320px);
}

.intro-cover__content {
  width: min(100%, 31rem);
  text-align: left;
}

.intro-cover__title {
  margin: 0;
  max-width: 10ch;
  font-family: var(--font-display);
  font-size: clamp(3.6rem, calc(17 * var(--vw)), 7.6rem);
  font-weight: 480;
  line-height: 0.82;
  letter-spacing: -0.055em;
  color: #ffffff;
  /* V1.8 — la barca e' molto piu' grande da questa versione: un'ombra
     leggera garantisce contrasto anche se il suo riflesso luminoso dovesse
     risalire fin qui su schermi molto larghi. */
  text-shadow: 0 2px 14px rgba(0, 0, 0, 0.25);
}

.intro-cover__subtitle {
  margin: clamp(24px, calc(7 * var(--vw)), 40px) 0 0;
  max-width: 24ch;
  font-family: var(--font-body);
  font-size: clamp(1rem, calc(4.1 * var(--vw)), 1.22rem);
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.86);
  text-shadow: 0 2px 14px rgba(0, 0, 0, 0.25);
}

/* V1.7 — frase centrale editoriale: scoperta scorrendo, non nel primo
   schermo, per scandire la lunga scheda iOS 1 in due momenti. */
.intro-cover__quote {
  position: relative;
  /* V1.8 — sopra la barca (ora molto piu' grande): resta leggibile anche
     se la barca risale fin qui, e l'ombra tiene il contrasto anche sopra
     il riflesso piu' chiaro della foto. */
  z-index: 2;
  margin: clamp(18vh, 24vh, 30vh) auto 0;
  max-width: 26ch;
  text-align: center;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 420;
  font-size: clamp(1.35rem, calc(5.2 * var(--vw)), 2rem);
  line-height: 1.32;
  color: #ffffff;
  text-shadow: 0 2px 14px rgba(0, 0, 0, 0.35);
}

/* V1.8 — barca a vela notturna, in basso a sinistra verso la fine della
   scheda: asset fotografico gia' ripulito (mare/orizzonte/barca visibili,
   trasparente sopra l'orizzonte), nessun filtro/ombra aggiunto. Dimensione
   raddoppiata rispetto alla V1.7 (78vw/460px -> 156vw/920px). Ancoraggio
   in basso a sinistra invariato, nessuna deformazione.
   V2.0 — .intro-cover__boat e' ora il CONTENITORE (prima era l'<img>
   stesso): height:auto non basta piu' perche' object-fit:cover richiede
   una scatola di dimensioni proprie, indipendenti dall'immagine sorgente
   (e' proprio questo che permette framing/zoom diversi dalla vista
   "intera" di prima). aspect-ratio mantiene invariata la FORMA del
   riquadro (stessa proporzione 941:1672 di prima, stesso ingombro
   visivo), overflow:hidden clippa lo zoom interno. */
.intro-cover__boat {
  position: absolute;
  left: 0;
  bottom: 0;
  width: min(calc(156 * var(--vw)), 920px);
  aspect-ratio: 941 / 1672;
  overflow: hidden;
  z-index: 1;
  pointer-events: none;
  /* V2.0 — il transform:translateX(50%) della V1.9 (spostamento "a
     occhio" verso destra) e' rimosso: il posizionamento preciso arriva
     ora per intero dai valori del calibratore su object-position/zoom
     dell'<img> qui sotto, che sostituiscono quel tentativo precedente
     invece di sommarcisi. */
}

/* V2.0 — framing/zoom dal calibratore HTML: valori presi cosi' come sono
   (incluso l'asse Y negativo, intenzionale), nessuna normalizzazione.
   object-fit:cover riempie il riquadro senza deformare; transform:scale
   riproduce lo zoom aggiuntivo del calibratore in modo robusto e
   cross-browser (nessuna proprieta' sperimentale). */
.intro-cover__boat img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 86.59% -53.59%;
  /* V2.1 — sul cellulare vogliamo vedere piu' la parte DESTRA della foto:
     per ottenere questo risultato spostiamo l'immagine verso sinistra del
     35% della propria larghezza complessiva, mantenendo il framing del
     calibratore come base e lo stesso zoom 124%. */
  transform: translateX(-35%) scale(1.24);
  transform-origin: center;
}

.intro-cover__scroll-hint {
  position: absolute;
  left: clamp(30px, calc(8 * var(--vw)), 58px);
  bottom: clamp(24px, calc(6 * var(--vw)), 42px);
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-body);
  font-size: 0.7rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.intro-cover__arrow {
  font-size: 1rem;
  line-height: 1;
}

/* V2.3 — testo in calce alla iOS 1, sopra l'area del mare della barca:
   centrato, con margine sufficiente a non toccare mai lo scroll-hint
   (che resta ancorato al bottom, sotto). z-index sopra la barca (1) ma
   sotto/allo stesso livello di quote/content, stessa logica di
   leggibilita' gia' usata li'. */
.intro-cover__closing {
  position: absolute;
  left: 50%;
  bottom: clamp(92px, 19vh, 168px);
  transform: translateX(-50%);
  z-index: 2;
  width: min(88%, 30rem);
  text-align: center;
}

/* V2.6 — richiesto il ritorno al bianco (era stato portato a "terra
   rossa" in V2.5). Dimensioni (leggermente aumentate in V2.5) e ombra
   doppia invariate: e' proprio l'ombra doppia (una scura stretta + una
   piu' ampia e sfumata) a fornire "la leggera enfasi tipografica" e il
   "contrasto controllato" richiesti, che restano necessari col bianco
   tanto quanto lo erano col terra rossa per restare leggibili sopra la
   zona piu' luminosa del riflesso del sole in foto. */
.intro-cover__closing-lead {
  margin: 0;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 480;
  font-size: clamp(1.18rem, calc(4.7 * var(--vw)), 1.62rem);
  line-height: 1.32;
  color: #ffffff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.55), 0 3px 14px rgba(0, 0, 0, 0.45);
}

.intro-cover__closing-kicker {
  margin: clamp(14px, calc(3.4 * var(--vw)), 20px) 0 0;
  font-family: var(--font-body);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #ffffff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5), 0 2px 10px rgba(0, 0, 0, 0.4);
}

.intro-cover__closing-body {
  margin: 0.5rem 0 0;
  font-family: var(--font-body);
  font-size: clamp(0.98rem, calc(3.9 * var(--vw)), 1.14rem);
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.92);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5), 0 2px 12px rgba(0, 0, 0, 0.45);
}

/* ==================================================
   HERO — Scena 01, conversazione scroll-driven stile WhatsApp
   Tutta la progressione e' guidata dallo scroll reale (vedi js/hero.js):
   qui il CSS legge solo variabili custom (--bubble-progress,
   --giorgia-progress, --exit-progress...) impostate frame per frame da
   JS in funzione della posizione di scroll — nessuna transition/animation
   temporizzata sul contenuto, cosi' la sequenza e' scrubbabile avanti e
   indietro in modo coerente con il dito dell'utente.
   ================================================== */

.hero-pin {
  position: relative;
  /* V3.8 — l'avanzamento della sequenza non e' piu' guidato dalla
     quantita' di scroll (vedi IOS2_TIMELINE in js/hero.js, ora una
     timeline a tempo fisso): questa altezza resta comunque necessaria
     come area di sicurezza del pin, per assorbire l'eventuale overshoot
     del gesto di scroll che fa da trigger, senza mai lasciar intravedere
     iOS 2.1 prima che la timeline sia conclusa (js/hero.js collassa
     questa altezza al solo viewport non appena la sequenza termina). */
  height: var(--hero-scroll-span, 184vh);
  /* V1.8 — nessuna sovrapposizione con la scheda precedente (era un
     margine negativo in V1.7: risultava compressa e dava l'impressione
     di una composizione "smontata"). Lo spazio vuoto intenzionale tra le
     due schede e' il padding-bottom di .intro-cover qui sotto, non un
     margine su questo elemento: cosi' il "vuoto" resta dipinto dello
     stesso sfondo della iOS 1, senza un seam di colore estraneo. */
}

.hero-sticky {
  position: sticky;
  top: 0;
  height: 100dvh;
  height: 100svh;
  display: flex;
}

.hero-card {
  position: relative;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  padding-top: calc(var(--brand-bar-height) + var(--safe-top) + var(--space-lg));
  padding-bottom: calc(var(--space-xl) + var(--safe-bottom));
}

@media (min-width: 1024px) {
  .hero-card {
    max-width: 40rem;
    margin-inline: auto;
  }
}

.hero-pattern {
  position: absolute;
  inset: 0;
  background-color: #263a3a;
  background-image: none;
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center center;
  z-index: 0;
  transform: scale(1.20); /* V1.2: doodle circa 20% più grandi, meno elementi percepiti */
  transform-origin: center center;
  /* Una sola immagine continua: niente repeat, niente giunzioni/tile orizzontali. */
}

/* ---------- bolle messaggio ---------- */
.hero-chat {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: 28rem;
  padding-inline: var(--space-md);
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.chat-bubble {
  --bubble-progress: 0;
  max-width: 80%;
  width: fit-content;
  padding: 0.8rem 1.15rem;
  border-radius: 20px;
  font-family: var(--font-body);
  font-size: clamp(0.95rem, calc(2.2 * var(--vw)) + 0.5rem, 1.08rem);
  line-height: 1.45;
  box-shadow: 0 6px 18px rgba(41, 36, 31, 0.075);
  opacity: 1;
  visibility: hidden;
  will-change: transform;
}

.chat-bubble[data-stage-visible="true"] {
  visibility: visible;
}

/* FIX scheda iOS 2 — la bolla del typing (elemento in-flow nel flex column
   .hero-chat) restava sempre "visibility:hidden" ma continuava a occupare
   il proprio spazio, creando un vuoto fisso fra la domanda e la risposta
   anche a sequenza conclusa. display:none la toglie del tutto dal flusso
   quando non e' nella sua finestra, cosi' domanda e risposta restano vicine
   come nella reference approvata. */
.chat-bubble--typing[data-stage-visible="false"] {
  display: none;
}

.chat-bubble--in {
  align-self: flex-start;
  background: #ffffff;
  color: var(--text);
  border-bottom-left-radius: 6px;
  transform: translateX(calc((1 - var(--bubble-progress)) * 76px)); /* entra muovendosi verso sinistra */
}

.chat-bubble--out {
  align-self: flex-end;
  background: var(--accent);
  color: #fff8f2;
  border-bottom-right-radius: 6px;
  transform: translateX(calc((1 - var(--bubble-progress)) * -76px)); /* entra muovendosi verso destra */
}

.brand-mark {
  font-family: var(--font-display);
  font-style: italic;
}

.chat-bubble--typing {
  display: flex;
  align-items: center;
  gap: 5px;
  padding-block: 0.85rem;
  min-width: 3.4rem;
  justify-content: center;
}

.typing-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.55;
  animation: typing-bounce 1.15s ease-in-out infinite;
  animation-play-state: paused;
}

.chat-bubble--typing[data-typing-active="true"] .typing-dot {
  animation-play-state: running;
}

.typing-dot:nth-child(2) { animation-delay: 0.15s; }
.typing-dot:nth-child(3) { animation-delay: 0.3s; }

@keyframes typing-bounce {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.55; }
  30% { transform: translateY(-4px); opacity: 1; }
}

/* ---------- Giorgia, risposta visiva ---------- */
.hero-giorgia {
  position: relative;
  z-index: 1;
  margin-top: auto;
  width: min(calc(118 * var(--vw)), 760px);
  max-width: none;
  height: auto;
  object-fit: contain;
  --giorgia-progress: 0;
  opacity: 1;
  visibility: hidden;
  transform: translateX(calc((1 - var(--giorgia-progress)) * 92px));
  will-change: transform;
  /* niente filtro/ombra/glow: l'asset va usato cosi' com'e', vedi
     01_PROMPT_CODEX punto 6 */
}

/* V3.6 — DISATTIVATO: ridimensionava Giorgia in modo diverso dal mobile
   su schermi larghi, una vera differenza di composizione. Con la nuova
   modalita' "mobile shell centrata" (Parte 8-17) il desktop deve
   mostrare la STESSA proporzione del mobile: la larghezza resta sempre
   quella definita sopra (ora calc(N * var(--vw)), shell-aware — vedi
   variables.css). Codice storico:
@media (min-width: 1024px) {
  .hero-giorgia {
    width: min(66vw, 690px);
  }
}
*/

.hero-giorgia[data-stage-visible="true"] {
  visibility: visible;
}

@media (prefers-reduced-motion: reduce) {
  .hero-pin {
    height: auto;
  }

  .hero-sticky {
    position: relative;
    height: auto;
    min-height: 100svh;
  }

  .chat-bubble,
  .hero-giorgia {
    opacity: 1 !important;
    visibility: visible !important;
    transform: none !important;
  }

  /* FIX scheda iOS 2 — il typing e' uno stato transitorio ("sta scrivendo"),
     non contenuto finale: con reduced-motion (setupHero() non parte, quindi
     data-stage-visible resta non impostato) andrebbe altrimenti reso
     visibile insieme a domanda e risposta dalla regola sopra, riaprendo lo
     stesso vuoto fra i due messaggi che questa correzione elimina. */
  .chat-bubble--typing {
    display: none !important;
  }

  .typing-dot {
    animation: none !important;
  }
}

/* ---------- introduzione scheda 02 ---------- */
.hero-next {
  padding-block: var(--space-2xl);
}


/* V1.3 — Giorgia entra fisicamente da sinistra, mai in dissolvenza e mai dal basso */
[data-hero-stage="giorgia"] {
  opacity: 1 !important;
  transform: translate3d(calc((1 - var(--giorgia-progress, 0)) * -42 * var(--vw)), 0, 0) !important;
  will-change: transform;
}
[data-hero-stage="giorgia"][data-stage-visible="false"] {
  visibility: hidden;
}
[data-hero-stage="giorgia"][data-stage-visible="true"] {
  visibility: visible;
}


/* V1.3 — fondo WhatsApp più adulto: petrolio profondo, doodle vivi sopra */
.hero-pattern {
  background-color: #263a3a;
}
.hero-pattern img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.20);
  transform-origin: center;
  mix-blend-mode: screen;
  opacity: 0.92;
}


/* ==================================================
   V1.4 — affinamento visivo verso il mockup approvato
   ================================================== */
.intro-cover {
  /* V1.9 — lo sfondo dietro/intorno alla scheda iOS 1 e' lo stesso usato
     dietro tutte le altre schede del sito (var(--background), lo sfondo
     del <body>): prima qui c'era un gradiente scuro dedicato che creava
     uno stacco di colore incoerente con il resto delle sezioni. Il
     contenuto interno della card (tinta terra rossa) resta invariato. */
  background: var(--background);
  padding-top: calc(var(--brand-bar-height) + var(--safe-top) + 12px);
  /* V1.8 — margine vuoto intenzionale tra la fine della iOS 1 e l'inizio
     della iOS 2 (era una sovrapposizione anticipata in V1.7): dipinto
     dallo sfondo di questa sezione, cosi' non introduce un seam di colore
     estraneo tra le due schede. */
  padding-bottom: var(--scene-gap);
}

.intro-cover__card {
  overflow: hidden;
  position: relative;
}

.intro-cover__content {
  position: relative;
  /* V1.8 — resta sopra la barca (ora molto piu' grande) anche se il suo
     bordo superiore dovesse risalire fin qui: i testi devono restare
     sempre leggibili. */
  z-index: 2;
}

.intro-cover__subtitle {
  max-width: 18ch;
  font-family: var(--font-display);
  font-size: clamp(1.55rem, calc(5 * var(--vw)), 2.1rem);
  line-height: 1.18;
}

/* V1.8 — iOS 1 e iOS 2 sono separate da uno spazio netto (--scene-gap):
   niente piu' sovrapposizione anticipata. La iOS 1 si mostra per intero,
   col suo stondato inferiore ben visibile contro lo sfondo di questa
   sezione, poi un piccolo margine, poi la iOS 2 comincia pulita. */

.intro-cover__scroll-hint {
  z-index: 3;
  left: 50%;
  transform: translateX(-50%);
  bottom: clamp(10px, calc(2.5 * var(--vw)), 18px);
  color: rgba(255, 255, 255, 0.78);
}

.hero-card {
  overflow: hidden;
}

.hero-pattern {
  background-image: url('../assets/images/hero/pattern_whatsapp_multicolore_transparent.png') !important;
  background-repeat: no-repeat;
  background-position: center center;
  background-size: 126% auto;
  background-color: transparent;
  transform: none;
}

.hero-chat {
  padding-top: clamp(10px, calc(4 * var(--vw)), 20px);
}

.chat-bubble {
  display: grid;
  gap: 0.22rem;
  min-width: min(calc(68 * var(--vw)), 290px);
  padding: 0.95rem 1rem 0.7rem;
  border-radius: 18px;
  box-shadow: 0 9px 28px rgba(3, 21, 22, 0.16);
}

.chat-bubble__text {
  display: block;
}

.chat-bubble__meta {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.78rem;
  line-height: 1;
  opacity: 0.7;
}

.chat-bubble__ticks {
  letter-spacing: -0.12em;
  color: #3b8ef3;
  font-weight: 700;
}

.chat-bubble--in {
  background: #fffdfa;
  color: #152a2c;
  border-bottom-left-radius: 6px;
}

.chat-bubble--out {
  background: #dff0d2;
  color: #14282a;
  border-bottom-right-radius: 6px;
}

.chat-bubble--typing {
  min-width: 3.7rem;
  padding-block: 0.9rem;
  background: #dff0d2;
}

.hero-giorgia {
  width: min(calc(124 * var(--vw)), 800px);
  align-self: flex-start;
  margin-left: clamp(-38px, -calc(6 * var(--vw)), -12px);
}

/* V3.6 — DISATTIVATO, stesso motivo del blocco gemello sopra. Codice
   storico:
@media (min-width: 1024px) {
  .hero-giorgia {
    width: min(68vw, 740px);
    margin-left: -1.5rem;
  }
}
*/


/* ==================================================
   V1.5 — slide iOS 2 allineata al mockup approvato
   - sfondo approvato separato
   - Giorgia posizionata come nella reference
   - messaggi in stile WhatsApp conservati
   ================================================== */
.hero-card {
  overflow: hidden;
  justify-content: flex-start;
}

.hero-pattern {
  inset: 0;
  background-image: url('../assets/images/hero/slide2_background_approved.png') !important;
  background-repeat: no-repeat;
  background-position: center center;
  background-size: cover;
  background-color: transparent;
  transform: none !important;
}

.hero-chat {
  position: relative;
  z-index: 4;
  width: 100%;
  max-width: none;
  padding-inline: clamp(22px, calc(6 * var(--vw)), 34px);
  padding-top: clamp(28px, calc(7 * var(--vw)), 46px);
  gap: clamp(12px, calc(2.2 * var(--vw)), 18px);
}

.chat-bubble {
  display: grid;
  gap: 0.22rem;
  min-width: 0;
  width: auto;
  max-width: min(calc(76 * var(--vw)), 330px);
  padding: 0.95rem 1.05rem 0.72rem;
  border-radius: 20px;
  box-shadow: 0 10px 30px rgba(3, 21, 22, 0.14);
}

.chat-bubble__text {
  display: block;
  font-size: clamp(1.02rem, calc(2.9 * var(--vw)), 1.12rem);
  line-height: 1.28;
}

.chat-bubble__meta {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 0.34rem;
  margin-top: 0.15rem;
  font-size: 0.77rem;
  line-height: 1;
  color: rgba(26, 35, 34, 0.55);
}

.chat-bubble--in {
  align-self: flex-start;
  margin-left: clamp(4px, calc(1.4 * var(--vw)), 10px);
  background: #fffdf9;
  color: #132528;
  border-bottom-left-radius: 7px;
  transform: translateX(calc((1 - var(--bubble-progress)) * 76px));
}

.chat-bubble--out {
  align-self: flex-end;
  margin-right: clamp(6px, calc(2 * var(--vw)), 14px);
  background: #e6f3d8;
  color: #132528;
  border-bottom-right-radius: 7px;
  transform: translateX(calc((1 - var(--bubble-progress)) * -76px));
}

.chat-bubble--typing {
  min-width: 3.8rem;
  padding: 0.86rem 1rem;
  background: #e6f3d8;
}

.chat-bubble__ticks {
  color: #2098ff;
  letter-spacing: -0.11em;
  font-weight: 700;
}

/* FIX scheda iOS 2 — crop di Giorgia calibrato per pixel sulla reference
   approvata (slide2_composite_reference.png vs foto sorgente originale
   1351x1164): prima si vedeva l'intera foto (object-fit:contain), quindi
   troppa faccia. Ora si usa un ritaglio "cover" con una finestra della
   stessa proporzione della reference (941:1115), cosi' il bordo sinistro
   della scheda taglia la foto proprio dove inizia la bocca (misurato in
   originale a x=270 su 1351 -> object-position-x 73%), lasciando occhio,
   naso e bocca intera visibili ma non piu' guancia/mascella a sinistra.
   Larghezza piena della scheda: nessuna necessita' di offset negativi.
   V1.8 — object-position-x 73% -> 76%: con object-fit:cover, aumentare
   la X sposta la finestra di ritaglio verso destra sulla foto sorgente,
   il che fa apparire il soggetto spostato di conseguenza verso SINISTRA
   nella scheda (~3 punti percentuali), senza toccare scala/proporzioni
   ne' il resto del crop calibrato sopra.
   V1.9 — 76% -> 81%: stesso principio, altri ~5 punti verso sinistra. */
.hero-giorgia {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  width: 100%;
  aspect-ratio: 941 / 1115;
  max-width: none;
  height: auto;
  margin: 0;
  object-fit: cover;
  object-position: 81% 100%;
  opacity: 1;
  visibility: hidden;
  transform: translate3d(calc((1 - var(--giorgia-progress, 0)) * -42 * var(--vw)), 0, 0) !important;
  will-change: transform;
}

.hero-note {
  --bubble-progress: 0;
  position: absolute;
  right: clamp(22px, calc(6 * var(--vw)), 42px);
  top: 57%;
  z-index: 3;
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.25rem, calc(4 * var(--vw)), 2rem);
  line-height: 0.95;
  color: #edf3d9;
  text-align: left;
  transform: translateX(calc((1 - var(--giorgia-progress, 0)) * 48px)) rotate(-4deg);
  opacity: 1;
  visibility: hidden;
  text-shadow: 0 1px 0 rgba(0,0,0,0.04);
}

.hero-note::after {
  content: '';
  display: block;
  width: 6.2rem;
  height: 0.22rem;
  margin-top: 0.35rem;
  border-radius: 999px;
  background: #89a548;
  transform: rotate(-4deg);
}

.hero-note[data-stage-visible="true"] {
  visibility: visible;
}

[data-hero-stage="giorgia"][data-stage-visible="true"] {
  visibility: visible;
}

@media (prefers-reduced-motion: reduce) {
  .hero-note {
    opacity: 1 !important;
    visibility: visible !important;
    transform: rotate(-4deg) !important;
  }
}

/* ==================================================
   SCENA 02 — SCHEDA iOS 3: "Viaggi trasformativi"
   Terza scheda del sistema: verticale nel flusso della pagina (scrolla
   normalmente con il resto del sito) ma con una sequenza ORIZZONTALE di
   slide al suo interno. Riusa la primitiva .horizontal-story gia'
   presente sul sito (scroll-snap nativo + drag mouse su desktop, vedi
   js/main.js): nessun nuovo JS per lo scorrimento orizzontale. Partecipa
   al sistema generico --exit-progress via [data-ios-card] (vedi
   js/hero.js, setupCardExit) senza bisogno di codice dedicato.
   ================================================== */
.ios3 {
  /* V2.0 — stessa spaziatura "di sistema" usata tra iOS 1 e iOS 2, per
     coerenza: prima era --space-lg, un valore ad-hoc solo per questa
     scena. */
  padding-block: var(--scene-gap);
}

.ios-card--ios3 {
  /* V2.0 — 67dvh -> 72dvh */
  min-height: 72svh;
  min-height: 72dvh;
  display: flex;
  flex-direction: column;
}

.ios3-story {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  margin-block: 0;
}

.ios3-track {
  flex: 1;
  min-height: 0;
  gap: 0;
  padding-inline: 0;
  padding-block: 0;
}

.ios3-panel {
  position: relative;
  flex: 0 0 100%;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  overflow: hidden;
}

/* V2.0 — immagini reali al posto del placeholder a righe. Contenitore
   sempre presente (necessario per object-fit:cover, che richiede una
   scatola di dimensioni proprie indipendenti dall'immagine sorgente).
   Il "fallback" a fondo pagina resta come rete di sicurezza: se un asset
   dovesse mancare o non caricare, mostra un pannello neutro invece di
   un'icona di immagine rotta. */
/* V2.5 — sfondo unico bianco per tutte le slide fotografiche (era un
   pacato colore dedicato per slide, V2.1): vedi anche il nuovo scrim
   chiaro qui sotto, che sostituisce quello scuro. */
.ios3-panel__media {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: #ffffff;
}

/* V2.5 — slide D "Coming Soon": nessuna foto, tono caldo chiaro coerente
   con la palette (invece del bianco pieno, per un minimo di carattere). */
.ios3-panel__media--comingsoon {
  background: var(--background-secondary);
}

.ios3-panel__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* object-fit:cover da solo basta per riempire il riquadro senza
     deformare l'immagine; la combinazione object-position + transform:scale
     replica fedelmente framing e zoom del calibratore (vedi i valori per
     ogni slide qui sotto — object-position puo' avere legittimamente
     percentuali negative o >100%, e' cosi' che il calibratore sposta il
     punto di riferimento quando l'immagine e' ingrandita oltre il cover
     naturale). transform-origin center = default browser, stesso comportamento
     assunto dal calibratore. */
  object-fit: cover;
  transform-origin: center;
}

/* Slide A — 10A, esperienza camper
   V2.2 — FIX: translateY(-50%) (V2.1) spostava l'intero <img> fuori dal
   riquadro invece di cambiare cosa viene ritagliato: con l'elemento gia'
   a inset:0/100%x100%, spostarlo in alto del 50% della sua altezza
   lasciava vuota (colore di sfondo puro) tutta la meta' inferiore del
   pannello. La stessa intenzione — inquadrare piu' in basso, mostrare
   davvero i camper e le persone invece del cielo — si ottiene
   correttamente aumentando la Y di object-position (X e zoom invariati,
   come richiesto): niente viene mai spostato fuori dal riquadro, e'
   sempre e solo la finestra di ritaglio a cambiare. */
.ios3-panel__media--camper img {
  object-position: 56.41% 40%;
  transform: scale(1.08);
}

/* Slide B — 10B, esperienza vela — stessa correzione del punto sopra. */
.ios3-panel__media--vela img {
  object-position: 44.48% 0%;
  transform: scale(1.05);
}

/* Slide C — 10C, esperienza terme */
.ios3-panel__media--terme img {
  object-position: 52.62% -6.41%;
  transform: scale(1.12); /* invariata: il posizionamento e' gia' corretto */
}

/* V2.6 — il velo chiaro introdotto in V2.5 (che sbiadiva/opacizzava le
   foto delle prime tre slide) e' stato rimosso: niente piu' overlay,
   scrim, pseudo-elemento o filtro sopra l'immagine. Lo sfondo bianco
   della slide (.ios3-panel__media, sopra, invariato) resta com'era; e'
   solo il velo AGGIUNTIVO sopra la foto ad essere sparito, cosi' la foto
   risulta nitida, chiara nel dettaglio e viva nei colori, non piu'
   "slavata". L'elemento .ios3-panel__scrim resta nel markup (per non
   toccare l'HTML) ma e' reso inerte: nessuno sfondo, nessun effetto
   visivo residuo. */
.ios3-panel__scrim {
  position: absolute;
  inset: 0;
  background: none;
  pointer-events: none;
}

.ios3-panel__content {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 26rem;
  padding: clamp(28px, calc(7 * var(--vw)), 48px) clamp(20px, calc(6 * var(--vw)), 36px) clamp(20px, calc(5 * var(--vw)), 32px);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

/* V2.6 — senza il velo chiaro, il testo torna sopra la foto viva (non
   piu' sopra uno sfondo quasi bianco): tornano quindi bianco + ombra
   doppia (stessa tecnica gia' validata per il testo in calce della iOS 1,
   vedi .intro-cover__closing-* sopra), che regge la leggibilita' sia
   sulle zone chiare che scure della foto — a differenza del testo scuro
   di V2.5, pensato apposta per il velo chiaro ora rimosso. Scoperta SOLO
   sulle tre slide fotografiche (camper/vela/terme) tramite selettore di
   fratelli generico — la slide "Coming Soon" (sfondo pieno chiaro, senza
   foto) non viene toccata e resta con testo scuro come V2.5. */
.ios3-panel__media--camper ~ .ios3-panel__content .ios3-panel__title,
.ios3-panel__media--vela ~ .ios3-panel__content .ios3-panel__title,
.ios3-panel__media--terme ~ .ios3-panel__content .ios3-panel__title {
  color: #ffffff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.55), 0 3px 14px rgba(0, 0, 0, 0.45);
}

.ios3-panel__media--camper ~ .ios3-panel__content .ios3-panel__subtitle,
.ios3-panel__media--vela ~ .ios3-panel__content .ios3-panel__subtitle,
.ios3-panel__media--terme ~ .ios3-panel__content .ios3-panel__subtitle {
  color: rgba(255, 255, 255, 0.92);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5), 0 2px 12px rgba(0, 0, 0, 0.45);
}

.ios3-panel__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.35rem, calc(4.6 * var(--vw)), 1.9rem);
  font-weight: 560;
  color: var(--text);
}

.ios3-panel__subtitle {
  margin: 0.6rem 0 0;
  max-width: 30ch;
  font-family: var(--font-body);
  font-size: clamp(0.92rem, calc(3.4 * var(--vw)), 1.05rem);
  line-height: 1.5;
  color: var(--text-muted);
}

.ios3-panel__cta {
  margin-top: clamp(18px, calc(4 * var(--vw)), 28px);
  display: flex;
  gap: 0.7rem;
  flex-wrap: wrap;
  justify-content: center;
}

/* V2.6 — .button-primary resta invariato: e' un riquadro pieno
   (background:var(--text)/color:var(--background)), quindi gia'
   perfettamente leggibile su qualunque foto sotto, velo o non velo.
   .button-secondary invece e' un semplice contorno trasparente: sulle
   tre slide fotografiche (dove il testo torna bianco, sopra) va
   ricalibrato allo stesso modo per restare leggibile sulla foto viva,
   sempre scoperto SOLO li' con lo stesso selettore di fratelli — sulla
   slide "Coming Soon" .button-secondary non e' nemmeno presente (un
   solo CTA, "Proponi"), quindi non c'e' nulla da preservare la'. */
.ios3-panel__media--camper ~ .ios3-panel__content .button-secondary,
.ios3-panel__media--vela ~ .ios3-panel__content .button-secondary,
.ios3-panel__media--terme ~ .ios3-panel__content .button-secondary {
  border-color: rgba(255, 255, 255, 0.85);
  color: #ffffff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5), 0 2px 10px rgba(0, 0, 0, 0.4);
}

.ios3-panel__media--camper ~ .ios3-panel__content .button-secondary:hover,
.ios3-panel__media--vela ~ .ios3-panel__content .button-secondary:hover,
.ios3-panel__media--terme ~ .ios3-panel__content .button-secondary:hover {
  border-color: #ffffff;
}
