/* ==========================================================================
   EV House Management - design minimale nero / oro
   Doppio tema (chiaro / scuro) tramite token CSS.
   Mobile-first. Serif per i titoli, sans per il testo.

   Stati del tema:
     - nessun data-theme  -> segue prefers-color-scheme del sistema
     - data-theme="light" -> chiaro forzato dall'utente
     - data-theme="dark"  -> scuro forzato dall'utente
   ========================================================================== */


/* ==========================================================================
   Caratteri — ospitati qui, non su Google Fonts

   Due ragioni. La prima e' di conformita': chiamare fonts.gstatic.com manda
   l'indirizzo IP del visitatore a Google prima ancora che abbia visto il
   banner cookie, ed e' proprio il genere di trasferimento che la privacy
   policy di questo sito dichiara di non fare. La seconda e' di prestazione:
   spariscono due connessioni verso un terzo dominio e un foglio di stile che
   bloccava il rendering.

   Fraunces e Archivo sono entrambi in licenza SIL Open Font, quindi
   ridistribuibili con il sito.

   I file `latin-ext` si scaricano solo se in pagina compare un carattere che
   li richiede: l'italiano sta quasi tutto in `latin`, quindi in pratica non
   vengono mai chiesti. Per questo `unicode-range` non e' un dettaglio.
   ========================================================================== */

/* Fraunces variabile: un solo file copre i pesi 300-700 e tutte le dimensioni
   ottiche. Costa piu' di un peso statico ma meno di tre, e in cambio da'
   `font-optical-sizing`, che a corpo grande assottiglia le grazie e a corpo
   piccolo le ispessisce. E' il motivo per cui un titolo da 4rem e uno da
   1.3rem non sembrano lo stesso disegno rimpicciolito. */
@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("../fonts/fraunces-var-latin.5d2835174326.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("../fonts/fraunces-var-latin-ext.3592119408ee.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Il corsivo serve solo per le parole in risalto dentro i titoli grandi:
   quindi un peso solo, dimensione ottica fissa sul massimo. 21 KB invece dei
   79 della versione variabile. */
@font-face {
  font-family: "Fraunces";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/fraunces-italic-latin.123767c0fe21.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Archivo variabile: pesi 300-700 in un file solo. */
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("../fonts/archivo-var-latin.92895abae7c5.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("../fonts/archivo-var-latin-ext.288d2a1c9f04.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}


/* ---------- Tema chiaro (base) ---------- */
:root {
  color-scheme: light;

  --bg:            #faf8f4;
  --bg-0:          rgba(250, 248, 244, 0);   /* --bg con alpha 0 */
  --bg-soft:       #f2eee6;
  --surface:       #ffffff;
  --surface-alt:   #f5f1ea;
  --field-bg:      #ffffff;
  --border:        #e0d9cc;

  --text:          #17150f;
  --text-muted:    #6b6459;
  --placeholder:   #9a9184;

  --accent:              #8a6d10;
  --accent-hover:        #6b530a;
  --accent-solid:        #8a6d10;
  --accent-solid-hover:  #6b530a;
  --on-accent:           #ffffff;
  --accent-dim:          rgba(138, 109, 16, 0.10);

  --header-bg:     rgba(250, 248, 244, 0.92);
  --band-veil:     rgba(242, 238, 230, 0.75);
  --band-glow:     rgba(138, 109, 16, 0.20);

  --card-shadow:   0 1px 3px rgba(23, 21, 15, 0.06);

  --danger:        #a63d21;
  --success:       #3f6b2b;

  /* ---- Caratteri ----
     Fraunces per i titoli: serif contemporaneo, alto contrasto, con asse di
     dimensione ottica. Archivo per tutto il resto: grottesco stretto, molto
     leggibile ai corpi piccoli, con una personalita' che Inter non ha.
     I due alias storici restano per non riscrivere ogni regola del foglio. */
  --font-display: "Fraunces", "Iowan Old Style", "Palatino Linotype", Georgia, serif;
  --font-testo:   "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-serif: var(--font-display);
  --font-sans:  var(--font-testo);

  /* ---- Scala dei corpi ----
     Una scala sola per tutto il sito. Prima c'erano sessantasei dichiarazioni
     di `font-size` decise una per una, e infatti i salti fra un livello e
     l'altro non erano regolari. */
  --t-2xs: 0.68rem;
  --t-xs:  0.76rem;
  --t-sm:  0.875rem;
  --t-md:  1rem;
  --t-lg:  1.0625rem;
  --t-xl:  clamp(1.15rem, 1.06rem + 0.45vw, 1.4rem);
  --t-2xl: clamp(1.45rem, 1.15rem + 1.5vw, 2.05rem);
  --t-3xl: clamp(2rem, 1.3rem + 3.2vw, 3.15rem);
  --t-4xl: clamp(2.6rem, 1.35rem + 5.6vw, 4.6rem);

  /* ---- Spaziatura fra le lettere ----
     Cinque valori al posto dei sette a occhio di prima. Negativa sui titoli
     grandi, dove le lettere hanno gia' abbastanza aria; larga sulle etichette
     maiuscole, dove serve per non farle sembrare una parola sola. */
  --tr-display:   -0.03em;
  --tr-titolo:    -0.012em;
  --tr-corpo:      0em;
  --tr-etichetta:  0.14em;
  --tr-occhiello:  0.26em;

  /* ---- Interlinee ---- */
  --lh-display: 0.98;
  --lh-titolo:  1.16;
  --lh-corpo:   1.72;
  --lh-stretto: 1.4;

  --header-h: 78px;
  --container: 1200px;
  --radius: 2px;
  --transition: 260ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* ---------- Tema scuro: preferenza di sistema (se non forzato chiaro) ---------- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --bg:          #0a0a0a;
    --bg-0:        rgba(10, 10, 10, 0);
    --bg-soft:     #121212;
    --surface:     #171717;
    --surface-alt: #1e1e1e;
    --field-bg:    #121212;
    --border:      #2a2a2a;

    --text:        #f2efe9;
    --text-muted:  #a9a49b;
    --placeholder: #6b6760;

    --accent:              #c9a227;
    --accent-hover:        #e3c667;
    --accent-solid:        #c9a227;
    --accent-solid-hover:  #e3c667;
    --on-accent:           #0a0a0a;
    --accent-dim:          rgba(201, 162, 39, 0.14);

    --header-bg:   rgba(10, 10, 10, 0.92);
    --band-veil:   rgba(10, 10, 10, 0.90);
    --band-glow:   rgba(201, 162, 39, 0.20);

    --card-shadow: none;

    --danger:      #e07a5f;
    --success:     #7fb069;
  }
}

/* ---------- Tema scuro: scelta esplicita dell'utente ---------- */
:root[data-theme="dark"] {
  color-scheme: dark;

  --bg:          #0a0a0a;
  --bg-0:        rgba(10, 10, 10, 0);
  --bg-soft:     #121212;
  --surface:     #171717;
  --surface-alt: #1e1e1e;
  --field-bg:    #121212;
  --border:      #2a2a2a;

  --text:        #f2efe9;
  --text-muted:  #a9a49b;
  --placeholder: #6b6760;

  --accent:              #c9a227;
  --accent-hover:        #e3c667;
  --accent-solid:        #c9a227;
  --accent-solid-hover:  #e3c667;
  --on-accent:           #0a0a0a;
  --accent-dim:          rgba(201, 162, 39, 0.14);

  --header-bg:   rgba(10, 10, 10, 0.92);
  --band-veil:   rgba(10, 10, 10, 0.90);
  --band-glow:   rgba(201, 162, 39, 0.20);

  --card-shadow: none;

  --danger:      #e07a5f;
  --success:     #7fb069;
}

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-testo);
  font-size: var(--t-md);      /* la misura vera la detta :root */
  /* 400 e non 300: Archivo e' piu' asciutta di Inter e a peso 300 il testo
     corrente si sfilaccia. Il peso leggero resta, ma dove ha un ruolo — sui
     sottotitoli. */
  font-weight: 400;
  line-height: var(--lh-corpo);
  letter-spacing: var(--tr-corpo);
  /* Fa muovere l'asse `opsz` di Fraunces in funzione del corpo: le grazie si
     assottigliano nei titoli grandi e si ispessiscono in quelli piccoli. E'
     il motivo per cui un H1 e un H3 non sembrano lo stesso disegno scalato. */
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  transition: background-color var(--transition), color var(--transition);
}

/* I titoli grandi sono voce editoriale: Fraunces, interlinea sotto l'unita',
   spaziatura negativa. Devono sembrare composti, non impaginati. */
h1, h2 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: var(--lh-display);
  letter-spacing: var(--tr-display);
  margin: 0 0 0.5em;
  text-wrap: balance;
}

/* I titoli piccoli restano nella stessa famiglia ma cambiano registro: un
   filo piu' pesanti, interlinea normale, spaziatura quasi neutra. */
h3, h4 {
  font-family: var(--font-display);
  font-weight: 500;
  line-height: var(--lh-titolo);
  letter-spacing: var(--tr-titolo);
  margin: 0 0 0.5em;
}

h1 { font-size: var(--t-4xl); }
h2 { font-size: var(--t-3xl); }
h3 { font-size: var(--t-xl); }
h4 { font-size: var(--t-lg); }

/* Il corsivo di Fraunces e' l'accento del sistema: una sola parola per
   titolo, mai frasi intere. */
h1 em, h2 em { font-style: italic; font-weight: 400; }

p { margin: 0 0 1.35em; }
p:last-child { margin-bottom: 0; }

a { color: var(--accent); text-decoration: none; transition: color var(--transition); }
a:hover { color: var(--accent-hover); }

img { max-width: 100%; height: auto; display: block; }

ul { margin: 0; padding: 0; list-style: none; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.container {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 1.25rem;
}

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--accent-solid); color: var(--on-accent); padding: 0.75rem 1.25rem;
}
.skip-link:focus { left: 0; }

/* ---------- Tipografia di supporto ---------- */
/* Occhiello: la voce piu' piccola del sistema e insieme la piu' spaziata.
   E' quel contrasto — corpo minimo, spaziatura massima — a farla leggere come
   etichetta e non come testo. */
.eyebrow {
  font-family: var(--font-testo);
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: var(--tr-occhiello);
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 1.1rem;
  display: block;
}

/* Sottotitolo: corpo piu' grande del testo corrente ma peso piu' leggero.
   Prima era la stessa cosa del paragrafo, appena piu' grande. */
.lead {
  font-family: var(--font-testo);
  font-size: var(--t-xl);
  font-weight: 300;
  line-height: 1.62;
  letter-spacing: -0.002em;
  color: var(--text-muted);
  max-width: 56ch;
}

/* Piu' respiro fra le sezioni e sotto le intestazioni: la gerarchia si legge
   anche nel vuoto, non solo nei corpi. */
.section { padding: 5.5rem 0; }
.section-dark { background: var(--bg-soft); transition: background-color var(--transition); }

.section-head { margin-bottom: 3.25rem; max-width: 62ch; }

.gold-rule {
  width: 56px; height: 1px; background: var(--accent);
  margin: 1.5rem 0; border: 0;
}

/* ---------- Micro-titolo ----------
   Dove il titolo di un elemento e' un'etichetta e non un nome proprio, cambia
   famiglia: Archivo maiuscolo al posto di Fraunces. Non e' un vezzo — e' la
   distinzione che il sistema fa fra "questa cosa ha un nome" (una casa: resta
   in Fraunces) e "questa cosa e' una categoria" (un servizio, un passo: va in
   maiuscolo spaziato). E' il salto di trama che evita che tutta la pagina
   sembri lo stesso testo a corpi diversi. */
.service-card h3,
.servizio h3,
.percorso-testo h3 {
  font-family: var(--font-testo);
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  line-height: 1.35;
  color: var(--text);
  margin-bottom: 0.75rem;
}

/* ---------- Link nel testo ----------
   Sottolineatura che non tocca le discendenti e si ispessisce al passaggio.
   `text-decoration` invece di uno pseudo-elemento perche' cosi' segue
   l'andamento della riga anche quando il link va a capo. */
.prose a,
.footer-col a,
.cookie-copy a,
.list-meta a {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: color-mix(in srgb, var(--accent) 40%, transparent);
  text-underline-offset: 0.22em;
  transition: text-decoration-color var(--transition), color var(--transition),
              text-decoration-thickness var(--transition);
}
.prose a:hover,
.footer-col a:hover,
.cookie-copy a:hover,
.list-meta a:hover {
  text-decoration-color: var(--accent);
  text-decoration-thickness: 2px;
}

/* ---------- Bottoni ---------- */
.btn {
  display: inline-block;
  font-family: var(--font-testo);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: var(--tr-etichetta);
  text-transform: uppercase;
  padding: 1rem 2rem;
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  cursor: pointer;
  transition: all var(--transition);
  text-align: center;
}

.btn-primary { background: var(--accent-solid); border-color: var(--accent-solid); color: var(--on-accent); }
.btn-primary:hover {
  background: var(--accent-solid-hover); border-color: var(--accent-solid-hover); color: var(--on-accent);
}

.btn-outline { background: transparent; color: var(--accent); }
.btn-outline:hover { background: var(--accent-dim); color: var(--accent-hover); }

.btn-block { display: block; width: 100%; }
.btn-external { display: flex; align-items: center; justify-content: center; gap: 0.6rem; }

.btn-group { display: flex; flex-wrap: wrap; gap: 1rem; }

/* ---------- Header ---------- */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: var(--header-bg);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
  transition: background-color var(--transition), border-color var(--transition);
}

.header-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem;
  min-height: var(--header-h);
}

.brand { display: flex; align-items: center; gap: 0.7rem; color: var(--text); }
.brand:hover { color: var(--text); }

/* Il logo esiste in due varianti: la sigla "EV" e' bianca nell'originale,
   quindi su fondo chiaro sparirebbe. La variante "su-chiaro" la ricolora,
   lasciando intatto l'oro dei tetti. Lo scambio e' in CSS, cosi' funziona
   anche quando il tema segue le preferenze di sistema. */
/* Il marchio e' impilato — tetti e «EV» sopra, «HOUSE MANAGEMENT» sotto — e
   sta in una proporzione di 1,8:1. Con la scritta su una riga sola bastavano
   46px per farla leggere; qui la parte bassa e' un dodicesimo dell'altezza,
   quindi il logo cresce, e in larghezza occupa comunque meno di prima. */
.brand-logo { display: block; height: 54px; width: auto; }
.brand-logo-scuro { display: none; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .brand-logo-chiaro { display: none; }
  :root:not([data-theme="light"]) .brand-logo-scuro  { display: block; }
}
:root[data-theme="dark"] .brand-logo-chiaro { display: none; }
:root[data-theme="dark"] .brand-logo-scuro  { display: block; }

.brand-footer .brand-logo { height: 66px; }

.header-actions { display: flex; align-items: center; gap: 0.5rem; }

/* Toggle tema */
.theme-toggle {
  width: 40px; height: 40px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text-muted);
  cursor: pointer;
  transition: color var(--transition), border-color var(--transition), background-color var(--transition);
}
.theme-toggle:hover {
  color: var(--accent); border-color: var(--accent); background: var(--accent-dim);
}
.theme-toggle svg { width: 18px; height: 18px; display: block; }

/* L'icona mostrata rappresenta il tema verso cui si passa. */
.theme-toggle .icon-to-dark  { display: block; }
.theme-toggle .icon-to-light { display: none; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .icon-to-dark  { display: none; }
  :root:not([data-theme="light"]) .theme-toggle .icon-to-light { display: block; }
}
:root[data-theme="dark"] .theme-toggle .icon-to-dark  { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-to-light { display: block; }

.nav-toggle {
  display: flex; flex-direction: column; justify-content: center; gap: 5px;
  width: 44px; height: 44px;
  background: none; border: 0; cursor: pointer; padding: 0;
}
.nav-toggle span {
  display: block; height: 1px; width: 24px; background: var(--text);
  transition: transform var(--transition), opacity var(--transition), background-color var(--transition);
  margin: 0 auto;
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* La marca non si comprime: se lo spazio manca e' il menu a doversi
   ripensare. Senza questo il flex la assottigliava in silenzio, e il difetto
   si vedeva solo guardando l'header a una misura precisa. */
.brand { flex: none; }

.primary-nav {
  position: absolute; top: 100%; left: 0; right: 0;
  background: var(--bg-soft);
  border-bottom: 1px solid var(--border);
  max-height: 0; overflow: hidden;
  transition: max-height var(--transition);
}
.primary-nav.is-open {
  /* Con la tendina delle localita' aperta 420px non bastavano piu': il fondo
     dell'elenco finiva tagliato. */
  max-height: min(80vh, 820px);
  overflow-y: auto;
}

.primary-nav ul { display: flex; flex-direction: column; padding: 0.5rem 1.25rem 1.5rem; }
.primary-nav a {
  display: block; padding: 0.85rem 0;
  color: var(--text);
  font-size: var(--t-xs); font-weight: 500;
  letter-spacing: var(--tr-etichetta); text-transform: uppercase;
  border-bottom: 1px solid var(--border);
}
.primary-nav a:hover { color: var(--accent); }
.primary-nav .nav-cta { color: var(--accent); }

/* Voce che porta fuori dal sito. La freccina lo dice prima del clic: chi la
   vede sa che sta per cambiare pagina — e scheda — invece di scoprirlo dopo.
   `display: flex` e non `inline-flex` perche' sul telefono la voce deve
   riempire la riga, altrimenti il filetto sotto sarebbe piu' corto delle
   altre voci e sembrerebbe un errore di impaginazione. */
.nav-portale {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  /* Maiuscoletto spaziato: «Portale proprietari» e' lungo e andava a capo in
     mezzo alla barra, con la freccina orfana sulla seconda riga. Le voci di
     un menu stanno su una riga sola. */
  white-space: nowrap;
}
.nav-portale svg {
  width: 0.85em; height: 0.85em;
  flex: none;
  opacity: 0.65;
  transition: opacity var(--transition);
}
.nav-portale:hover svg,
.nav-portale:focus-visible svg { opacity: 1; }

/* ---------- Voce «Immobili» con tendina delle localita' ----------
   Il link alla pagina completa e il pulsante che apre la tendina sono due
   bersagli distinti: «Immobili» porta all'elenco intero con un colpo solo,
   il triangolino apre la scelta per localita'. Accorpare i due gesti in un
   elemento solo costringerebbe a rinunciare a uno dei due. */
.nav-riga {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}
.nav-riga > a { flex: 1; }

.nav-freccia {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 36px; height: 36px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-muted);
  cursor: pointer;
  /* `rotate` e non `transform`: proprieta' indipendente, non litiga con le
     animazioni che nel sito occupano gia' `transform`. */
  transition: color var(--transition), rotate var(--transition);
}
.nav-freccia svg { width: 16px; height: 16px; }
.nav-freccia:hover { color: var(--accent); }
.ha-tendina.e-aperta > .nav-riga .nav-freccia { rotate: 180deg; color: var(--accent); }

/* Sotto i 900px la tendina e' un sotto-elenco che si apre dentro al menu.
   Chiuse dentro la loro media query, e non lasciate come regole di base: la
   riga `.ha-tendina.e-aperta > .tendina` ha specificita' 0,3,0 e batteva la
   `.tendina { max-height: none }` del blocco desktop (0,1,0). Il risultato era
   che sul desktop la tendina, se aperta *col click*, si ritrovava alta al
   massimo 60vh con uno scorrimento interno: su una finestra da 760px il
   pannello veniva tagliato a 456px contro 478 di contenuto, e le ultime
   localita' sparivano. Aprendola col passaggio del mouse invece no, perche'
   li' la classe `e-aperta` non c'e'. */
@media (max-width: 899.98px) {
  .tendina {
    max-height: 0;
    overflow: hidden;
    transition: max-height var(--transition);
  }
  .ha-tendina.e-aperta > .tendina { max-height: 60vh; overflow-y: auto; }
}

.tendina-titolo {
  margin: 0.75rem 0 0.25rem;
  font-family: var(--font-testo);
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: var(--tr-occhiello);
  text-transform: uppercase;
  color: var(--accent);
}

/* Qualificate con `.primary-nav`: senza, `.primary-nav ul` e `.primary-nav a`
   hanno specificita' piu' alta e vincono loro — l'elenco tornava una fila
   orizzontale larga duemila pixel. */
.primary-nav .tendina-elenco {
  display: block;
  padding: 0;
  gap: 0;
}
.primary-nav .tendina a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.55rem 0 0.55rem 0.9rem;
  border-bottom: 0;
  border-left: 1px solid var(--border);
  font-size: var(--t-2xs);
  font-weight: 500;
  color: var(--text-muted);
  text-transform: none;
  letter-spacing: 0.04em;
  transition: color var(--transition), border-color var(--transition);
}
.primary-nav .tendina a:hover { color: var(--accent); border-left-color: var(--accent); }
.primary-nav .tendina a.e-corrente { color: var(--accent); border-left-color: var(--accent); }

/* Il conteggio e' informazione di servizio: resta in secondo piano. */
.tendina-conta {
  font-size: 0.9em;
  font-weight: 400;
  color: var(--placeholder);
  font-variant-numeric: tabular-nums;
}

.primary-nav .tendina .tendina-tutte {
  margin-top: 0.5rem;
  border-left: 0;
  padding-left: 0;
  font-weight: 600;
  letter-spacing: var(--tr-etichetta);
  text-transform: uppercase;
  color: var(--text);
}
.primary-nav .tendina .tendina-tutte:hover { color: var(--accent); }


/* ---------- Hero ---------- */
/* L'hero e' sempre chiaro-su-scuro: la fotografia impone la propria palette,
   indipendentemente dal tema attivo. Da qui i token dedicati. */
.hero {
  --hero-text:   #f7f4ee;
  --hero-muted:  rgba(247, 244, 238, 0.78);
  --hero-accent: #dcbb4e;
  --hero-line:   rgba(247, 244, 238, 0.26);
  --hero-fade:   140px;          /* altezza della dissolvenza inferiore */

  position: relative;
  display: flex;
  align-items: center;
  min-height: min(94vh, 880px);
  padding: calc(var(--header-h) + 3.5rem) 0 calc(var(--hero-fade) + 1.5rem);
  overflow: hidden;
  color: var(--hero-text);
  background: var(--bg);
}
body.has-hero .hero { margin-top: calc(var(--header-h) * -1); }

.hero-media { position: absolute; inset: 0; z-index: 0; }
.hero-media img,
.hero-media video {
  width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 45%;
}

/* Il video sta sopra la fotografia e sfuma in campo quando ha davvero
   qualcosa da mostrare. Finche' non arriva a quel punto — rete lenta, formato
   rifiutato, autoplay negato — resta invisibile e sotto si vede la fotografia,
   che e' un fotogramma dello stesso video: non c'e' nessun salto. */
.hero-video {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 900ms ease;
}
.hero-video.e-pronto { opacity: 1; }

/* Comando di pausa. Nascosto finche' il video non parte: se lo sfondo e' una
   fotografia ferma non c'e' niente da mettere in pausa. */
.hero-video-toggle {
  position: absolute;
  /* Allineato al bordo del contenitore. In percentuale e non in `vw`:
     `100vw` include la barra di scorrimento e su Windows finirebbe sotto. */
  right: max(1.5rem, calc((100% - var(--container)) / 2));
  bottom: calc(var(--hero-fade) + 0.75rem);
  z-index: 3;
  display: grid;
  place-items: center;
  width: 38px; height: 38px;
  padding: 0;
  border: 1px solid rgba(247, 244, 238, 0.34);
  border-radius: 50%;
  background: rgba(6, 8, 10, 0.42);
  backdrop-filter: blur(6px);
  color: var(--hero-text);
  cursor: pointer;
  transition: background var(--transition), border-color var(--transition),
              opacity var(--transition);
  opacity: 0.62;
}
.hero-video-toggle:hover,
.hero-video-toggle:focus-visible {
  opacity: 1;
  border-color: var(--hero-accent);
  background: rgba(6, 8, 10, 0.66);
}
.hero-video-toggle[hidden] { display: none; }
.hero-video-toggle svg { width: 15px; height: 15px; }

/* Si mostra l'icona dell'azione, non quella dello stato: mentre il video va,
   il bottone offre la pausa. */
.hero-video-toggle .icona-play  { display: none; }
.hero-video-toggle.in-pausa .icona-pausa { display: none; }
.hero-video-toggle.in-pausa .icona-play  { display: block; }

/* Doppio gradiente: scurisce il lato del testo e sfuma in basso
   verso lo sfondo della pagina, cosi' l'hero si fonde in entrambi i temi. */
.hero-scrim {
  position: absolute; inset: 0; z-index: 1;
  background:
    /* 1. dissolvenza verso lo sfondo della pagina (usa --bg-0 per evitare
          il viraggio grigio dell'interpolazione da `transparent`) */
    linear-gradient(to bottom, var(--bg-0) 58%, var(--bg) 99%),
    /* 2. scurimento laterale, per la leggibilita del testo */
    linear-gradient(100deg,
      rgba(6, 8, 10, 0.90) 0%,
      rgba(6, 8, 10, 0.72) 34%,
      rgba(6, 8, 10, 0.38) 66%,
      rgba(6, 8, 10, 0.24) 100%),
    /* 2. velo superiore, per staccare l'header dalla foto */
    linear-gradient(to bottom, rgba(6, 8, 10, 0.55) 0%, rgba(6, 8, 10, 0) 24%);
}

/* Dissolvenza verso lo sfondo della pagina: usa --bg-0 (lo sfondo con alpha 0)
   invece di `transparent`, che interpolando da nero darebbe una banda grigia. */
.hero-scrim::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: 0;
  height: var(--hero-fade);
  background: linear-gradient(to bottom, var(--bg-0), var(--bg));
}

.hero > .container { position: relative; z-index: 2; }
.hero-inner { max-width: 44rem; }

.hero-eyebrow {
  display: flex; align-items: center; gap: 0.9rem;
  font-size: var(--t-2xs); font-weight: 600;
  letter-spacing: var(--tr-occhiello); text-transform: uppercase;
  color: var(--hero-accent);
  margin-bottom: 1.75rem;
}
.hero-eyebrow::before {
  content: ""; width: 40px; height: 1px; flex-shrink: 0;
  background: var(--hero-accent);
}

.hero h1 {
  font-size: clamp(2.7rem, 1.4rem + 6vw, 5.1rem);
  line-height: var(--lh-display);
  letter-spacing: var(--tr-display);
  margin-bottom: 1.75rem;
  text-wrap: balance;
}
.hero h1 em { font-style: italic; color: var(--hero-accent); }

.hero-lead {
  font-size: var(--t-xl);
  font-weight: 300;
  line-height: 1.62;
  letter-spacing: -0.002em;
  color: var(--hero-muted);
  max-width: 46ch;
  margin-bottom: 2.75rem;
}

/* Sull'hero i bottoni usano l'oro chiaro, leggibile sopra la foto. */
.hero .btn-primary {
  background: var(--hero-accent); border-color: var(--hero-accent); color: #0d0b06;
}
.hero .btn-primary:hover { background: #ecd06a; border-color: #ecd06a; color: #0d0b06; }

.btn-ghost {
  background: rgba(247, 244, 238, 0.06);
  border-color: rgba(247, 244, 238, 0.42);
  color: var(--hero-text);
  backdrop-filter: blur(4px);
}
.btn-ghost:hover {
  background: rgba(247, 244, 238, 0.14);
  border-color: var(--hero-text);
  color: var(--hero-text);
}

/* ---------- Fascia statistiche (sotto l'hero) ---------- */
.stagione {
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  padding: 4.5rem 0;
  transition: background-color var(--transition), border-color var(--transition);
}

/* Occhiello con il trattino davanti, come quello dell'hero. */
.eyebrow-riga { display: flex; align-items: center; gap: 0.9rem; }
.eyebrow-riga::before {
  content: "";
  width: 40px; height: 1px;
  flex-shrink: 0;
  background: var(--accent);
}

/* La cifra d'apertura e' l'elemento piu' grande della pagina dopo il titolo
   dell'hero: e' il numero che il visitatore deve portarsi via. */
.stagione-cifra {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(3.4rem, 1.4rem + 8.4vw, 6.4rem);
  font-weight: 400;
  line-height: 0.92;
  letter-spacing: var(--tr-display);
  color: var(--accent);
  font-variant-numeric: lining-nums;
}

.stagione-frase {
  margin: 1rem 0 0;
  font-family: var(--font-display);
  font-size: var(--t-3xl);
  font-weight: 400;
  line-height: var(--lh-titolo);
  letter-spacing: var(--tr-display);
  color: var(--text);
  max-width: 22ch;
}

/* I numeri di supporto. Il filetto sopra ciascuno li separa senza bisogno di
   riquadri. Quante siano non e' deciso qui: le caselle senza dato non vengono
   stampate, quindi la griglia si conta da sola con auto-fit invece di avere
   un numero di colonne fisso che lascerebbe buchi in fondo alla riga. */
.stagione-dati {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2rem 1.5rem;
  margin: 3.5rem 0 0;
  padding: 0;
  list-style: none;
}
.stagione-dati li {
  padding-top: 1rem;
  border-top: 1px solid var(--accent);
}
.stagione-dati .num {
  display: block;
  font-family: var(--font-display);
  font-size: var(--t-2xl);
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: var(--tr-titolo);
  color: var(--accent);
  margin-bottom: 0.5rem;
}
/* La cifra delle prenotazioni e' quattro volte piu' lunga di «+100», ma alla
   dimensione delle altre ci sta in tutte le colonne — 123px su 148 alla
   larghezza piu' stretta che il sito serve. Quindi resta grande come le
   altre: rimpicciolirla la farebbe sembrare un dato di serie B accanto a
   «3.406». Le si vieta solo di andare a capo, perche' un numero spezzato fra
   le migliaia si legge come due numeri. */
.stagione-dati .num-lungo { white-space: nowrap; }

.stagione-dati .label {
  display: block;
  font-size: var(--t-xs);
  line-height: 1.5;
  color: var(--text-muted);
}

.stagione-nota {
  margin: 3rem 0 0;
  max-width: 52ch;
  font-size: var(--t-sm);
  line-height: 1.75;
  color: var(--text-muted);
}

/* Sul telefono le colonne sono due: se le caselle sono in numero dispari,
   l'ultima resta sola con un filetto lungo meta' riga e sembra un pezzo
   mancante. Le si fa occupare la riga intera. */
@media (max-width: 699.98px) {
  .stagione-dati li:last-child:nth-child(odd) { grid-column: 1 / -1; }
}

@media (min-width: 700px) {
  .stagione-dati { grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); gap: 2rem; }
}

@media (min-width: 900px) {
  .stagione { padding: 6rem 0; }
  .stagione-dati { margin-top: 4.5rem; }
}

/* ---------- Header trasparente sopra l'hero ---------- */
body.has-hero .site-header:not(.is-solid) {
  background: transparent;
  border-bottom-color: transparent;
  backdrop-filter: none;
}
/* Le voci si scelgono per classe e non per posizione nell'albero. La regola
   diceva `li > a`, e appena il link di «Immobili» e' finito dentro `.nav-riga`
   ha smesso di applicarsi: sopra l'hero la voce restava quasi nera su una
   fotografia scura, cioe' invisibile. Una classe non si rompe se il markup si
   annida. */
body.has-hero .site-header:not(.is-solid) .brand,
body.has-hero .site-header:not(.is-solid) .primary-nav .nav-voce,
body.has-hero .site-header:not(.is-solid) .nav-freccia {
  color: #f7f4ee;
}
body.has-hero .site-header:not(.is-solid) .primary-nav .nav-cta {
  color: #dcbb4e; border-color: #dcbb4e;
}
body.has-hero .site-header:not(.is-solid) .brand-logo-chiaro { display: none; }
body.has-hero .site-header:not(.is-solid) .brand-logo-scuro  { display: block; }
body.has-hero .site-header:not(.is-solid) .primary-nav .nav-voce:hover,
body.has-hero .site-header:not(.is-solid) .nav-freccia:hover { color: #dcbb4e; }
body.has-hero .site-header:not(.is-solid) .theme-toggle {
  color: rgba(247, 244, 238, 0.85); border-color: rgba(247, 244, 238, 0.32);
}
body.has-hero .site-header:not(.is-solid) .theme-toggle:hover {
  color: #dcbb4e; border-color: #dcbb4e; background: rgba(247, 244, 238, 0.10);
}
body.has-hero .site-header:not(.is-solid) .nav-toggle span { background: #f7f4ee; }

/* ---------- Griglia card immobili ---------- */
.property-grid {
  display: grid; grid-template-columns: 1fr; gap: 2rem;
}

.property-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--card-shadow);
  overflow: hidden;
  display: flex; flex-direction: column;
  transition: border-color var(--transition), translate var(--transition),
              background-color var(--transition);
}
/* Il sollevamento usa `translate`, non `transform`: l'animazione di rivelazione
   occupa `transform` e, avendo un'animazione la precedenza sulle dichiarazioni
   normali, il sollevamento verrebbe ignorato. `translate` e' una proprieta'
   indipendente e si compone con l'altra invece di scontrarsi. */
.property-card:hover { border-color: var(--accent); translate: 0 -4px; }

.property-card-media {
  position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: var(--surface-alt);
}
.property-card-media img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 600ms cubic-bezier(0.4, 0, 0.2, 1);
}
.property-card:hover .property-card-media img { transform: scale(1.05); }

.media-placeholder {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-muted); opacity: 0.35;
  font-family: var(--font-display); font-size: var(--t-3xl);
  background: var(--surface-alt);
}

.badge-featured {
  position: absolute; top: 1rem; left: 1rem;
  background: var(--accent-solid); color: var(--on-accent);
  font-size: var(--t-2xs); font-weight: 600;
  letter-spacing: var(--tr-etichetta); text-transform: uppercase;
  padding: 0.35rem 0.75rem;
}

.property-card-body { padding: 1.5rem; flex: 1; display: flex; flex-direction: column; }
.property-card-body h3 { margin-bottom: 0.35rem; }
.property-card-body h3 a { color: var(--text); }
.property-card-body h3 a:hover { color: var(--accent); }

.property-location {
  font-size: var(--t-2xs); font-weight: 600;
  letter-spacing: var(--tr-etichetta); text-transform: uppercase;
  color: var(--accent); margin-bottom: 1rem;
}

.property-excerpt { color: var(--text-muted); font-size: var(--t-sm); flex: 1; }

.property-specs {
  display: flex; flex-wrap: wrap; gap: 1.25rem;
  margin-top: 1.5rem; padding-top: 1.25rem;
  border-top: 1px solid var(--border);
  font-size: var(--t-xs); color: var(--text-muted);
}
.property-specs span strong { color: var(--text); font-weight: 500; }

/* ---------- Filtri ---------- */
.filter-bar {
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--card-shadow);
  padding: 1.5rem;
  margin-bottom: 2.5rem;
  display: grid; gap: 1rem;
  transition: background-color var(--transition), border-color var(--transition);
}
.filter-bar label {
  display: block; font-size: var(--t-2xs); font-weight: 600;
  letter-spacing: var(--tr-etichetta);
  text-transform: uppercase; color: var(--text-muted); margin-bottom: 0.4rem;
}

/* ---------- Form ---------- */
input[type="text"], input[type="email"], input[type="tel"],
input[type="number"], select, textarea {
  width: 100%;
  background: var(--field-bg);
  border: 1px solid var(--border);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--t-md);
  padding: 0.85rem 1rem;
  border-radius: var(--radius);
  transition: border-color var(--transition), background-color var(--transition);
}
input:focus, select:focus, textarea:focus { border-color: var(--accent); outline: none; }
textarea { resize: vertical; min-height: 140px; }
::placeholder { color: var(--placeholder); }

.form-field { margin-bottom: 1.5rem; }
.form-field > label {
  display: block; font-size: var(--t-2xs); font-weight: 600;
  letter-spacing: var(--tr-etichetta);
  text-transform: uppercase; color: var(--text-muted); margin-bottom: 0.5rem;
}
.form-field.required > label::after { content: " *"; color: var(--accent); }

.form-check { display: flex; align-items: flex-start; gap: 0.75rem; margin-bottom: 1.75rem; }
.form-check input[type="checkbox"] {
  width: 18px; height: 18px; margin-top: 3px; accent-color: var(--accent-solid); flex-shrink: 0;
}
.form-check label { font-size: var(--t-sm); color: var(--text-muted); text-transform: none; letter-spacing: 0; }

.errorlist { list-style: none; margin: 0.5rem 0 0; padding: 0; }
.errorlist li { color: var(--danger); font-size: var(--t-xs); }

.helptext { display: block; font-size: var(--t-xs); color: var(--text-muted); margin-top: 0.4rem; }

.alert {
  padding: 1rem 1.25rem;
  border-left: 2px solid var(--accent);
  background: var(--surface);
  box-shadow: var(--card-shadow);
  font-size: var(--t-sm);
  margin-bottom: 1rem;
}
.alert-success { border-left-color: var(--success); }
.alert-error { border-left-color: var(--danger); }
.messages-wrap { padding-top: 1.5rem; }

/* ---------- Dettaglio immobile ---------- */
.detail-hero { padding: 3rem 0 0; }
.breadcrumb {
  font-size: var(--t-2xs); font-weight: 600;
  letter-spacing: var(--tr-etichetta); text-transform: uppercase;
  color: var(--text-muted); margin-bottom: 1.5rem;
}
.breadcrumb a { color: var(--text-muted); }
.breadcrumb a:hover { color: var(--accent); }

.gallery-main {
  aspect-ratio: 16 / 10; overflow: hidden;
  background: var(--surface-alt); margin-bottom: 0.75rem;
  border: 1px solid var(--border);
}
.gallery-main img { width: 100%; height: 100%; object-fit: cover; }

.gallery-thumbs {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.75rem;
}
.gallery-thumb {
  aspect-ratio: 1; overflow: hidden; border: 1px solid var(--border);
  background: none; padding: 0; cursor: pointer;
  transition: border-color var(--transition), opacity var(--transition);
  opacity: 0.6;
}
.gallery-thumb img { width: 100%; height: 100%; object-fit: cover; }
.gallery-thumb:hover, .gallery-thumb.is-active { border-color: var(--accent); opacity: 1; }

.detail-layout { display: grid; gap: 3rem; margin-top: 3rem; }

.spec-grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem; margin: 2rem 0;
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
  padding: 1.75rem 0;
}
.spec-item { text-align: center; }
.spec-item .num {
  font-family: var(--font-display); font-size: var(--t-2xl); font-weight: 500;
  letter-spacing: var(--tr-titolo);
  color: var(--accent); display: block;
}
.spec-item .label {
  font-size: var(--t-2xs); font-weight: 600;
  letter-spacing: var(--tr-etichetta); text-transform: uppercase; color: var(--text-muted);
}

.booking-box {
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--card-shadow);
  padding: 2rem;
  position: sticky; top: 96px;
  transition: background-color var(--transition), border-color var(--transition);
}
.booking-box h3 { color: var(--text); }
.booking-box .price-note { font-size: var(--t-xs); color: var(--text-muted); margin-bottom: 1.5rem; }

/* ---------- Servizi ---------- */
.passi-griglia { display: grid; grid-template-columns: 1fr; gap: 1.5rem; }
.service-card {
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--card-shadow);
  padding: 2rem;
  transition: border-color var(--transition), background-color var(--transition);
}
.service-card:hover { border-color: var(--accent); }
.service-card .idx {
  font-family: var(--font-display); font-size: var(--t-lg); font-weight: 500;
  color: var(--accent); display: block; margin-bottom: 1.1rem;
  letter-spacing: var(--tr-titolo);
}
.service-card p { color: var(--text-muted); font-size: var(--t-sm); margin: 0; }

/* La quarta tessera: il rimando alla pagina Servizi. Si distingue dalle tre
   che la precedono — fondo d'accento invece che chiaro — perche' non e' un
   passo da leggere ma una cosa da premere, e deve dirlo prima di essere
   letta. */
.service-card-invito { background: var(--accent-dim); border-color: var(--accent); padding: 0; }
.service-card-invito > a {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 2rem;
  color: inherit;
}
.service-card-invito .idx { line-height: 0; }
.service-card-invito .idx svg {
  width: 28px; height: 28px;
  transition: translate var(--transition);
}
.service-card-invito:hover { background: var(--surface); }
.service-card-invito:hover .idx svg { translate: 6px 0; }
/* Il contorno del fuoco non serve scriverlo: il collegamento riempie la
   tessera, quindi la regola generale `:focus-visible` gli disegna gia' attorno
   un anello che coincide con il bordo della casella. */


/* ---------- «Come funziona» che si blocca ----------
   La sezione arriva a schermo pieno e resta ferma: si vede solo la prima
   tessera, e le altre si scoprono una per volta continuando a scorrere. Finite
   le tessere il blocco si stacca e la pagina riprende da sola.

   Nessuno intercetta la rotella. La pagina scorre come su qualunque altra
   sezione — rotella, trackpad, frecce, barra laterale, ricerca nel testo
   funzionano tutti — e' solo che per un tratto la sezione sta incollata in
   cima mentre le si scorre attraverso, e quanto si e' scorso decide quante
   tessere sono comparse.

   La classe `e-bloccata` la mette main.js: senza JavaScript, su schermi che
   non ci stanno o con `prefers-reduced-motion`, questo blocco non esiste e
   resta la griglia normale con la rivelazione a cascata. */

.passi {
  /* Quanto si scorre in piu' perche' le tessere si scoprano tutte. La prima
     e' gia' li' quando il blocco si attacca, quindi la corsa la spartiscono le
     altre tre: cinquanta centesimi di schermo a testa. E' l'unico numero da
     toccare per rendere la sezione piu' svelta o piu' lenta. */
  --passo: 50svh;
  --corsa: calc(3 * var(--passo));

  /* Quanto dura la comparsa di una tessera, in frazione della corsa. Le tre
     fette occupano il 78%: il rimanente e' la coda in cui tutte e quattro
     restano in campo prima che il blocco si stacchi — senza, l'ultima
     comparirebbe nell'istante stesso in cui la sezione riparte e non la si
     vedrebbe mai ferma. */
  --fetta: 0.26;
}

.passi.e-bloccata {
  /* Altezza = quanto resta incollata + il tratto da scorrere. Il primo addendo
     e' l'altezza del blocco, non lo schermo intero: solo cosi' l'intervallo
     `contain` torna esattamente pari alla corsa.
     `svh` e non `vh` ne' `dvh`: su iOS `vh` e' l'altezza a barra ritirata e la
     sezione sborderebbe, mentre `dvh` cambia *mentre* la barra si ritira e
     cambierebbe il rapporto fra scorrimento e comparse a meta' corsa. */
  height: calc(100vh - var(--header-h) + var(--corsa));
  height: calc(100svh - var(--header-h) + var(--corsa));
  padding: 0;

  view-timeline-name: --passi;
  /* L'intestazione del sito e' appiccicata in alto: la timeline deve partire
     da sotto, altrimenti va fuori passo di quei pixel. */
  view-timeline-inset: var(--header-h) 0px;
}

.passi.e-bloccata .passi-pin {
  position: sticky;
  top: var(--header-h);
  height: calc(100vh - var(--header-h));
  height: calc(100svh - var(--header-h));
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 1rem 0;
  /* `clip` e non `hidden`: `hidden` creerebbe un contenitore di scorrimento, e
     portando a fuoco una tessera il browser lo farebbe scorrere di nascosto,
     sfasando il blocco rispetto alla pagina. */
  overflow: clip;
}

/* Bloccata, l'altezza non e' piu' una conseguenza del contenuto: e' un tetto.
   Quello che sfora viene tagliato, e a essere tagliata sarebbe l'ultima
   tessera — proprio quella che il blocco esiste per scoprire. Percio' qui si
   spende meno in spaziature, e sotto gli 860px di finestra cade anche la frase
   introduttiva: il titolo dice gia' di cosa si tratta, le tessere no. */
@media (max-height: 860px) {
  .passi.e-bloccata .section-head .lead { display: none; }
}

/* Bloccata, la griglia non puo' crescere: quello che sfora viene tagliato.
   Le tessere prendono quindi l'altezza che avanza invece di quella del proprio
   testo, e i quattro riquadri restano alti uguali qualunque cosa ci sia
   dentro. */
.passi.e-bloccata .passi-griglia {
  flex: 0 1 auto;
  min-height: 0;
  margin-top: 2rem;
}
.passi.e-bloccata .section-head { margin-bottom: 0; }

/* --- La comparsa, versione senza timeline di scorrimento ---
   `--avanzamento` (da 0 a 1) lo scrive main.js dove il browser non sa animare
   sulla posizione dello scorrimento. `--q` e' la quota di comparsa della
   singola tessera: la prima e' gia' a 1 quando l'avanzamento e' 0, le altre
   partono ognuna dove finisce la precedente.

   Chi ha le timeline ignora tutto questo: il blocco @supports piu' sotto mette
   un'animazione sulle stesse proprieta', e un'animazione in corso ha la
   precedenza sulle dichiarazioni normali. Cosi' i browser capaci lo fanno sul
   compositor e gli altri con un ascoltatore di scroll, senza duplicare una
   riga di layout. */
.passi.e-bloccata .passi-griglia > [data-reveal] {
  --q: clamp(0, calc((var(--avanzamento, 0) - (var(--i, 0) - 1) * var(--fetta)) / var(--fetta)), 1);
  transition: none;
  opacity: var(--q);
  transform: none;
  translate: 0 calc((1 - var(--q)) * 40px);
}

.passi-avanzamento { display: none; }
.passi.e-bloccata .passi-avanzamento {
  display: block;
  position: relative;
  flex: 0 0 auto;
  height: 2px;
  margin: 2rem auto 0;
  width: min(100% - 2.5rem, var(--container));
  background: var(--border);
}
.passi.e-bloccata .passi-avanzamento span {
  position: absolute;
  inset: 0;
  background: var(--accent);
  transform-origin: left center;
  transform: scaleX(var(--avanzamento, 0));
}

@keyframes ev-passo-appare {
  from { opacity: 0; translate: 0 40px; }
  to   { opacity: 1; translate: 0 0; }
}

@keyframes ev-passi-avanza {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* Dove il browser sa animare sulla posizione dello scorrimento se ne occupa
   lui: gira sul compositor, non tocca il main thread e non perde un fotogramma
   nemmeno scorrendo di scatto. */
@supports (animation-timeline: view()) {
  .passi.e-bloccata .passi-griglia > [data-reveal] {
    animation: ev-passo-appare linear both;
    animation-timeline: --passi;
    /* `contain` e' esattamente il tratto in cui la sezione copre lo schermo,
       cioe' quello in cui resta incollata: 0% quando si attacca, 100% quando
       si stacca.

       L'intervallo della prima tessera finisce a 0%, quindi comincia *prima*
       che il blocco si attacchi: la prima compare mentre la sezione sale, ed
       e' gia' li' — sola — nell'istante in cui la pagina si ferma. Le altre
       tre si spartiscono il tratto bloccato, una fetta a testa. Le percentuali
       fuori dallo 0-100 sono legittime: la timeline si estrapola. */
    animation-range:
      contain calc((var(--i, 0) - 1) * var(--fetta) * 100%)
      contain calc(var(--i, 0) * var(--fetta) * 100%);
  }

  .passi.e-bloccata .passi-avanzamento span {
    animation: ev-passi-avanza linear both;
    animation-timeline: --passi;
    animation-range: contain 0% contain 100%;
  }
}

/* ==========================================================================
   Pagina Servizi
   ========================================================================== */

/* ---------- Testata di pagina ----------
   Apre le pagine interne con il titolo di primo livello. Stessa fascia della
   `cta-band` ma allineata a sinistra: e' un'apertura, non un invito. */
.page-head {
  padding: 4rem 0 3.25rem;
  background:
    linear-gradient(var(--band-veil), var(--band-veil)),
    radial-gradient(ellipse at 82% 40%, var(--band-glow), transparent 62%),
    var(--bg-soft);
  border-bottom: 1px solid var(--border);
  transition: background-color var(--transition), border-color var(--transition);
}
.page-head h1 { max-width: 18ch; margin-bottom: 0; }
.page-head h1 em { font-style: italic; color: var(--accent); }
.page-head .lead { max-width: 56ch; margin-bottom: 0; }


/* ---------- Elenco dei servizi ----------
   Sei voci con un'icona. L'icona non e' decorazione: e' quello che rende
   l'elenco scorribile con lo sguardo invece che da leggere riga per riga. */
.servizi-lista {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1px;                       /* le voci si toccano: il fondo fa da griglia */
  background: var(--border);
  border: 1px solid var(--border);
}

.servizio {
  background: var(--surface);
  padding: 2.25rem 2rem;
  transition: background-color var(--transition);
}
.servizio h3 { margin-bottom: 0.5rem; }
.servizio p {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--t-sm);
  line-height: var(--lh-stretto);
}

.servizio-icona {
  display: block;
  width: 30px; height: 30px;
  color: var(--accent);
  margin-bottom: 1.4rem;
  /* `translate` e non `transform`: la rivelazione allo scroll occupa gia'
     `transform` sull'antenato e le due proprieta' si compongono invece di
     scontrarsi. */
  transition: translate var(--transition), color var(--transition);
}
.servizio:hover { background: var(--surface-alt); }
.servizio:hover .servizio-icona { translate: 0 -3px; }


/* ---------- Chi fa cosa ----------
   Due colonne affiancate. Il messaggio e' la differenza di lunghezza fra le
   due liste, quindi le colonne restano allineate in cima e crescono verso il
   basso: il confronto si vede a colpo d'occhio. */
.riparto {
  display: grid;
  gap: 1.5rem;
  align-items: start;
}

.riparto-col {
  background: var(--surface);
  border: 1px solid var(--border);
  padding: 2rem;
}
.riparto-nostro { border-color: var(--accent); }

.riparto-etichetta {
  display: block;
  font-family: var(--font-display);
  font-size: var(--t-2xl);
  font-weight: 500;
  letter-spacing: var(--tr-titolo);
  line-height: 1;
  color: var(--accent);
}
.riparto-conteggio {
  margin: 0.35rem 0 1.5rem;
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: var(--tr-etichetta);
  text-transform: uppercase;
  color: var(--text-muted);
}
.riparto-conteggio strong { color: var(--text); font-size: var(--t-sm); }

.riparto-col ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.9rem;
}
.riparto-col li {
  position: relative;
  padding-left: 1.6rem;
  font-size: var(--t-sm);
  line-height: 1.6;
  color: var(--text-muted);
}
/* Trattino invece di una spunta: non c'e' niente da confermare, e' un elenco. */
.riparto-col li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.7em;
  width: 12px; height: 1px;
  background: var(--accent);
}


/* ---------- Percorso in quattro passi ----------
   E' una sequenza, e va vista come tale: una linea che unisce i passi e si
   traccia man mano che si scorre, con i numeri che si riempiono al passaggio.
   Prima erano quattro schede uguali a quelle dei servizi e niente diceva che
   fossero consecutive. */
.percorso {
  --percorso-nodo: 52px;
  --percorso-gap: 2.5rem;

  position: relative;
  z-index: 1;
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--percorso-gap);
}

.percorso-passo {
  position: relative;
  display: grid;
  grid-template-columns: var(--percorso-nodo) 1fr;
  column-gap: 1.25rem;
  align-items: start;
  /* Le tessere sono alte quanto la piu' alta, e senza questo lo spazio che
     avanza verrebbe distribuito fra le righe interne: il passo col testo piu'
     lungo ne avrebbe meno da distribuire e il suo titolo si troverebbe piu' in
     alto degli altri. Con `start` l'eccedenza resta in fondo e i titoli si
     allineano. */
  align-content: start;
}

/* Il collegamento al passo successivo e' un tratto per passo, non una linea
   sola tirata da un capo all'altro. Cosi' non c'e' niente da calcolare: ogni
   tratto va dal proprio nodo a quello dopo, e resta esatto qualunque sia
   l'altezza delle righe o il numero dei passi. Sull'ultimo non c'e'. */
.percorso-passo::before {
  content: "";
  position: absolute;
  z-index: 0;
  left: calc(var(--percorso-nodo) / 2);
  top: var(--percorso-nodo);
  bottom: calc(-1 * var(--percorso-gap));
  width: 1px;
  background: var(--accent);
  transform-origin: top center;
}
.percorso-passo:last-child::before { content: none; }

.percorso-nodo {
  display: grid;
  place-items: center;
  width: var(--percorso-nodo); height: var(--percorso-nodo);
  border-radius: 50%;
  border: 1px solid var(--border);
  /* Opaco: la linea passa dietro e non deve attraversare il numero. */
  background: var(--bg);
  color: var(--accent);
  font-family: var(--font-display);
  font-size: var(--t-md);
  font-weight: 500;
  transition: background-color 600ms ease, color 600ms ease, border-color 600ms ease;
}

.percorso-testo h3 { margin-bottom: 0.4rem; }
.percorso-testo p {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--t-sm);
  line-height: 1.65;
}

@media (min-width: 900px) {
  .percorso {
    --percorso-gap: 2rem;
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
  .percorso-passo { grid-template-columns: 1fr; column-gap: 0; }
  .percorso-nodo { margin-bottom: 1.5rem; }

  /* Da qui in su i passi sono in riga: il tratto diventa orizzontale. */
  .percorso-passo::before {
    left: var(--percorso-nodo);
    right: calc(-1 * var(--percorso-gap));
    top: calc(var(--percorso-nodo) / 2);
    bottom: auto;
    width: auto;
    height: 1px;
    transform-origin: left center;
  }
}

@media (min-width: 600px) {
  .servizi-lista { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .riparto { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 900px) {
  .servizi-lista { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .page-head { padding: 5.5rem 0 4.5rem; }
  .riparto { gap: 2rem; }
}

/* ==========================================================================
   Home: esperienza dell'ospite, recensioni, zone coperte
   ========================================================================== */

/* Sottoetichetta dentro una casella dei numeri. */
.label-sotto {
  display: block;
  margin-top: 0.35rem;
  font-size: 0.92em;
  color: var(--placeholder);
}

.passi-griglia { list-style: none; padding: 0; margin: 0; }

/* ---------- Esperienza dell'ospite ---------- */
.ospite-layout { display: grid; gap: 3rem; }

.ospite-punti {
  display: grid;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}
.ospite-punti li {
  display: grid;
  grid-template-columns: 3rem 1fr;
  column-gap: 1.25rem;
  padding: 1.5rem 0;
  border-top: 1px solid var(--border);
}
.ospite-punti li:last-child { border-bottom: 1px solid var(--border); }

.ospite-num {
  /* Occupa entrambe le righe: senza, il titolo prende la seconda colonna e il
     paragrafo scivola nella prima — larga tre rem — andando a capo una parola
     per riga. */
  grid-row: span 2;
  font-family: var(--font-display);
  font-size: var(--t-lg);
  font-weight: 500;
  color: var(--accent);
  line-height: 1.4;
}
.ospite-punti h3 { margin-bottom: 0.3rem; }
.ospite-punti p {
  margin: 0;
  font-size: var(--t-sm);
  line-height: 1.65;
  color: var(--text-muted);
}

/* ---------- Recensioni ---------- */
.recensioni {
  display: grid;
  gap: 1.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.recensione {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 2rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

/* Chi parla si dichiara subito: da un proprietario e da un ospite ci si
   aspettano cose diverse, e saperlo prima di leggere cambia la lettura. */
.recensione-voce {
  align-self: flex-start;
  font-family: var(--font-testo);
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: var(--tr-etichetta);
  text-transform: uppercase;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 100px;
  padding: 0.35rem 0.85rem;
}

.recensione blockquote {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--t-xl);
  font-weight: 400;
  line-height: 1.45;
  letter-spacing: var(--tr-titolo);
  color: var(--text);
  flex: 1;
}
.recensione blockquote::before { content: "«"; color: var(--accent); }
.recensione blockquote::after  { content: "»"; color: var(--accent); }

.recensione-firma {
  display: grid;
  gap: 0.2rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
}
.recensione-autore {
  font-family: var(--font-testo);
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--text);
}
/* Canale e data non sono un dettaglio tipografico: sono cio' che rende
   verificabile la citazione. Piccoli, ma sempre presenti. */
.recensione-fonte {
  font-size: var(--t-2xs);
  letter-spacing: 0.04em;
  color: var(--text-muted);
}
.recensione-fonte a { color: var(--accent); }

/* ---------- Zone coperte ---------- */
.zone-layout { display: grid; gap: 2.5rem; align-items: start; }

.zone-mappa svg {
  display: block;
  width: 100%;
  max-width: 320px;
  height: auto;
  margin: 0 auto;
  /* Niente `overflow: visible`: annullerebbe il ritaglio del viewBox e l'isola
     verrebbe disegnata tutta, fuori scala e fuori riquadro. */
  overflow: hidden;
}
.zone-costa {
  /* `--surface` e non `--surface-alt`: su fondo tenue quest'ultimo dista tre
     valori dallo sfondo e la terraferma non si distingue dal mare. */
  fill: var(--surface);
  stroke: var(--accent);
  stroke-width: 2.5;
  stroke-opacity: 0.45;
  transition: fill var(--transition), stroke var(--transition);
}
.zone-punto circle { fill: var(--accent); transition: fill var(--transition); }

/* ---------- I punti che si accendono scorrendo ----------
   Ogni punto vive un tratto del passaggio della sezione: compare, resta, si
   spegne. Gli intervalli sono sfalsati da `--i`, che la vista assegna da nord
   a sud, cioe' nell'ordine in cui la costa scorre sotto gli occhi: ne esce
   un'onda che scende lungo il litorale invece di un lampeggio collettivo.

   L'informazione non se ne va con i punti: l'elenco accanto elenca sempre
   tutte e diciannove le localita'. La mappa e' il gemello decorativo di quel
   testo, e un effetto non deve mai essere l'unico posto in cui un dato esiste.

   Fuori da `.js-anim` — niente JavaScript, oppure "riduci movimento" — questo
   blocco non esiste e i punti stanno fermi, tutti visibili. */
@keyframes ev-zona {
  0%   { opacity: 0; scale: 0.35; }
  20%  { opacity: 1; scale: 1; }
  72%  { opacity: 1; scale: 1; }
  100% { opacity: 0; scale: 0.35; }
}

@supports (animation-timeline: view()) {
  .js-anim .zone-mappa { view-timeline-name: --zone; }

  .js-anim .zone-punto {
    /* Senza `fill-box` la scala partirebbe dall'origine del disegno e i punti
       schizzerebbero verso l'angolo invece di gonfiarsi sul posto. */
    transform-box: fill-box;
    transform-origin: center;
    animation: ev-zona linear both;
    animation-timeline: --zone;
    /* Quanto vive ogni punto e quanto sono sfalsati fra loro decidono due
       cose: quanti se ne vedono insieme al culmine (vita diviso sfalsamento,
       qui circa diciotto su diciannove) e quando l'ultimo si spegne — che
       deve cadere in fondo al `cover`, non prima, altrimenti la mappa resta
       vuota mentre la sezione e' ancora sullo schermo. */
    animation-range:
      cover calc(1% + var(--i, 0) * 2.7%)
      cover calc(49% + var(--i, 0) * 2.7%);
  }
}
.zone-alone {
  opacity: 0.16;
  transition: opacity var(--transition), r var(--transition);
}
.zone-punto.e-accesa .zone-alone { opacity: 0.42; }

.zone-fonte {
  margin: 0.75rem 0 0;
  text-align: center;
  font-size: var(--t-2xs);
  letter-spacing: 0.04em;
  color: var(--placeholder);
}

.zone-elenco {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 1.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.zone-elenco a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  transition: color var(--transition), border-color var(--transition);
}
.zone-elenco a:hover,
.zone-elenco a:focus-visible { color: var(--accent); border-color: var(--accent); }
.zone-nome { font-size: var(--t-sm); }
.zone-conta {
  font-family: var(--font-display);
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

@media (min-width: 700px) {
  .recensioni { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .zone-elenco { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 900px) {
  .ospite-layout { grid-template-columns: 0.9fr 1.1fr; gap: 4rem; }
  .zone-layout { grid-template-columns: 0.8fr 1.2fr; gap: 4rem; align-items: center; }
  /* Larghezza contenuta anche qui: l'isola e' alta e stretta, e a piena
     colonna diventerebbe il doppio dell'elenco che le sta accanto. */
  .zone-mappa svg { max-width: 300px; }
  .recensioni { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.75rem; }
}

/* ==========================================================================
   Galleria
   ========================================================================== */

/* Titolo che serve solo a chi legge con uno screen reader: la sezione ha
   bisogno di un'intestazione, la pagina no di due titoli visibili. */
.solo-lettori {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- Filtri per localita' ---------- */
.filtri-luogo {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1.25rem;
}
.filtri-luogo[hidden] { display: none; }

.chip {
  display: inline-flex;
  align-items: baseline;
  gap: 0.55rem;
  font-family: var(--font-testo);
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: var(--tr-etichetta);
  text-transform: uppercase;
  color: var(--text-muted);
  background: none;
  border: 1px solid var(--border);
  border-radius: 100px;
  padding: 0.6rem 1.1rem;
  cursor: pointer;
  transition: color var(--transition), border-color var(--transition),
              background-color var(--transition);
}
.chip:hover { color: var(--text); border-color: var(--accent); }
.chip.is-attiva {
  color: var(--on-accent);
  background: var(--accent-solid);
  border-color: var(--accent-solid);
}
/* Il conteggio e' un'informazione di servizio: resta in secondo piano. */
.chip-conta {
  font-size: 0.85em;
  font-weight: 400;
  letter-spacing: 0.06em;
  opacity: 0.7;
}

.filtri-esito {
  margin: 0 0 2rem;
  min-height: 1.2em;
  font-size: var(--t-xs);
  color: var(--text-muted);
}

/* ---------- Mosaico ----------
   Le tessere non hanno tutte la stessa forma. Con fotografie tutte in 3:2 una
   griglia regolare finisce per somigliare a un foglio di calcolo: il ritmo
   `grande / alta / larga / normale` la rende una pagina. Il taglio lo fa
   `object-fit: cover`, quindi nessuna foto viene deformata. */
.mosaico {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: clamp(96px, 28vw, 150px);
  grid-auto-flow: dense;      /* riempie i buchi lasciati dalle tessere grandi */
  gap: 0.5rem;
}

.tessera {
  position: relative;
  display: block;
  overflow: hidden;
  /* Contenitore, non piu' link: dentro ci stanno due destinazioni diverse. */
  background: var(--surface-alt);
  border-radius: var(--radius);
  grid-column: span 1;
  grid-row: span 1;
}
/* `hidden` da solo non basterebbe: la regola d'autore `display: block` qui
   sopra vince su quella del browser, e la tessera resterebbe in pagina. */
.tessera[hidden] { display: none; }

/* Mentre il visore e' aperto la pagina sotto non deve scorrere. */
html.visore-aperto { overflow: hidden; }

.tessera img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 900ms cubic-bezier(0.16, 1, 0.3, 1);
}
/* Il collegamento sulla fotografia riempie la tessera. */
.tessera-foto { display: block; width: 100%; height: 100%; }

.tessera:hover img,
.tessera-foto:focus-visible img { transform: scale(1.06); }

/* ---------- Pulsante «Vedi l'annuncio» ----------
   Compare al passaggio del mouse e quando il fuoco entra nella tessera. Sotto
   i 700px non esiste affatto: su schermo tattile il passaggio del mouse non
   c'e', e chi tocca la fotografia apre il visore, dove il collegamento
   all'immobile c'e' gia'. Un pulsante sempre acceso su centoventisei tessere
   sarebbe rumore. */
.tessera-annuncio {
  position: absolute;
  top: 0.7rem;
  right: 0.7rem;
  z-index: 2;
  display: none;
  align-items: center;
  gap: 0.45rem;
  padding: 0.55rem 0.85rem;
  font-family: var(--font-testo);
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: var(--tr-etichetta);
  text-transform: uppercase;
  color: #0d0b06;
  background: var(--hero-accent, #dcbb4e);
  border-radius: var(--radius);
  opacity: 0;
  translate: 0 -6px;
  transition: opacity var(--transition), translate var(--transition),
              background-color var(--transition);
}
.tessera-annuncio svg { width: 13px; height: 13px; flex-shrink: 0; }
.tessera-annuncio:hover { background: #ecd06a; color: #0d0b06; }

/* Il velo col titolo compare al passaggio, ma il testo c'e' comunque nel
   markup: `aria-hidden` perche' il link ha gia' il proprio testo alternativo,
   e su schermo tattile non esiste il passaggio del mouse — infatti sotto i
   700px il velo resta sempre visibile. */
.tessera-velo {
  position: absolute;
  inset: auto 0 0 0;
  display: grid;
  gap: 0.15rem;
  padding: 2.5rem 1rem 0.9rem;
  background: linear-gradient(to top, rgba(6, 8, 10, 0.88), rgba(6, 8, 10, 0));
  color: #f7f4ee;
  opacity: 1;
  transition: opacity var(--transition);
}
.tessera-titolo {
  font-family: var(--font-testo);
  font-size: var(--t-xs);
  font-weight: 600;
  line-height: 1.25;
  /* Una riga sola: i nomi lunghi non devono allagare la tessera. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tessera-luogo {
  font-family: var(--font-testo);
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: var(--tr-etichetta);
  text-transform: uppercase;
  color: var(--hero-accent, #dcbb4e);
}

/* ---------- Visore a schermo intero ---------- */
.visore {
  width: 100vw;
  max-width: 100vw;
  height: 100dvh;
  max-height: 100dvh;
  margin: 0;
  padding: 0;
  border: 0;
  background: #07090b;
  color: #f7f4ee;
  overflow: hidden;
}
.visore::backdrop { background: rgba(4, 6, 8, 0.92); }
.visore:not([open]) { display: none; }

.visore-scena {
  position: absolute;
  /* Il margine inferiore deve superare l'altezza del piede, che su schermo
     stretto va a capo e arriva a sfiorare i 180px: sotto quella soglia la
     fotografia finirebbe dietro alla didascalia. */
  inset: 4.5rem 0.75rem 11.5rem;
  display: grid;
  /* La riga esplicita non e' pignoleria: con `auto` la riga si dimensiona sul
     contenuto, quindi il `max-height: 100%` della fotografia non ha una base
     su cui risolversi e viene ignorato — la foto sfonda sotto il piede. */
  grid-template-rows: minmax(0, 1fr);
  place-items: center;
}
.visore-foto {
  max-width: 100%;
  max-height: 100%;
  width: auto; height: auto;
  object-fit: contain;
}

.visore-freccia,
.visore-chiudi {
  position: absolute;
  display: grid;
  place-items: center;
  border: 1px solid rgba(247, 244, 238, 0.28);
  border-radius: 50%;
  background: rgba(7, 9, 11, 0.55);
  backdrop-filter: blur(6px);
  color: #f7f4ee;
  cursor: pointer;
  transition: background-color var(--transition), border-color var(--transition),
              opacity var(--transition);
}
.visore-freccia:hover,
.visore-chiudi:hover {
  border-color: var(--hero-accent, #dcbb4e);
  background: rgba(7, 9, 11, 0.8);
}
.visore-freccia[disabled] { opacity: 0.25; cursor: default; }

.visore-freccia { width: 52px; height: 52px; top: 50%; margin-top: -26px; }
.visore-prec { left: 1rem; }
.visore-succ { right: 1rem; }
.visore-freccia svg { width: 22px; height: 22px; }

.visore-chiudi { width: 44px; height: 44px; top: 1rem; right: 1rem; }
.visore-chiudi svg { width: 18px; height: 18px; }

.visore-piede {
  position: absolute;
  inset: auto 0 0 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 1.5rem;
  padding: 1.25rem 1.5rem 1.5rem;
  background: linear-gradient(to top, rgba(7, 9, 11, 0.95), rgba(7, 9, 11, 0));
}
.visore-conta {
  font-family: var(--font-display);
  font-size: var(--t-lg);
  font-weight: 500;
  color: var(--hero-accent, #dcbb4e);
  font-variant-numeric: tabular-nums;   /* il contatore non deve ballare */
}
.visore-didascalia { display: grid; gap: 0.1rem; margin-right: auto; }
.visore-titolo {
  font-family: var(--font-testo);
  font-size: var(--t-sm);
  font-weight: 600;
}
.visore-luogo {
  font-family: var(--font-testo);
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: var(--tr-etichetta);
  text-transform: uppercase;
  color: rgba(247, 244, 238, 0.65);
}
.visore-scheda {
  font-family: var(--font-testo);
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: var(--tr-etichetta);
  text-transform: uppercase;
  color: #f7f4ee;
  border: 1px solid rgba(247, 244, 238, 0.42);
  padding: 0.7rem 1.3rem;
  transition: background-color var(--transition), border-color var(--transition);
}
.visore-scheda:hover {
  color: #0d0b06;
  background: var(--hero-accent, #dcbb4e);
  border-color: var(--hero-accent, #dcbb4e);
}

@media (min-width: 700px) {
  .visore-scena { inset: 5rem 1.25rem 7.5rem; }
  .mosaico { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.6rem; }
  /* Da qui in su il puntatore c'e': il velo si scopre al passaggio. */
  .tessera-velo { opacity: 0; }
  .tessera:hover .tessera-velo,
  .tessera:focus-within .tessera-velo { opacity: 1; }

  .tessera-annuncio { display: inline-flex; }
  /* `focus-within` e non `focus-visible` sulla tessera: il pulsante deve
     comparire anche quando a prendere il fuoco col tabulatore e' lui stesso,
     non solo la fotografia. */
  .tessera:hover .tessera-annuncio,
  .tessera:focus-within .tessera-annuncio { opacity: 1; translate: 0 0; }
}

@media (min-width: 1000px) {
  .mosaico {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    grid-auto-rows: clamp(120px, 12.5vw, 190px);
    gap: 0.75rem;
  }

  /* Ritmo di ripiego, per quando JavaScript non riassegna le forme.
     Sei tessere: una grande, due normali, una alta, una normale, una larga. */
  .mosaico > .tessera:nth-child(6n + 1) { grid-column: span 2; grid-row: span 2; }
  .mosaico > .tessera:nth-child(6n + 4) { grid-row: span 2; }
  .mosaico > .tessera:nth-child(6n + 6) { grid-column: span 2; }

  /* Quando c'e' JavaScript comanda `data-forma`, che viene riassegnata dopo
     ogni filtro: cosi' il ritmo resta regolare anche a tessere nascoste. */
  .mosaico > .tessera[data-forma] { grid-column: span 1; grid-row: span 1; }
  .mosaico > .tessera[data-forma="grande"] { grid-column: span 2; grid-row: span 2; }
  .mosaico > .tessera[data-forma="alta"]   { grid-row: span 2; }
  .mosaico > .tessera[data-forma="larga"]  { grid-column: span 2; }

  .visore-scena { inset: 5.5rem 5.5rem 7rem; }   /* qui il piede sta su una riga */
  .visore-prec { left: 1.75rem; }
  .visore-succ { right: 1.75rem; }
  .visore-piede { padding: 1.5rem 2rem 1.75rem; }
}



/* ---------- CTA ---------- */
.cta-band {
  background:
    linear-gradient(var(--band-veil), var(--band-veil)),
    radial-gradient(ellipse at 70% 50%, var(--band-glow), transparent 60%),
    var(--bg-soft);
  padding: 5rem 0;
  text-align: center;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  transition: background-color var(--transition), border-color var(--transition);
}
.cta-band .lead { margin: 0 auto 2.5rem; }
.cta-band .btn-group { justify-content: center; }

/* ---------- Contenuto legale / prosa ---------- */
.prose { max-width: 72ch; }
.prose h2 { margin-top: 3rem; font-size: var(--t-2xl); }
.prose h3 { margin-top: 2rem; }
.prose ul { list-style: disc; padding-left: 1.4rem; margin-bottom: 1.2em; color: var(--text-muted); }
.prose li { margin-bottom: 0.5rem; }
.prose p { color: var(--text-muted); }
.prose code {
  font-size: 0.9em; background: var(--surface-alt); padding: 0.1rem 0.35rem;
  border-radius: var(--radius); color: var(--text);
}
.prose .placeholder,
.footer-legal-data .placeholder {
  color: var(--accent); background: var(--accent-dim); padding: 0 0.35rem; font-size: 0.9em;
}

/* Dati societari: l'etichetta sopra e il valore sotto. Sono cinque righe di
   coppie voce/valore, e messe in linea diventano un muro in cui bisogna
   cercare la partita IVA; l'etichetta piccola in maiuscoletto la si salta con
   l'occhio quando non serve. */
.footer-legal-data li { margin-bottom: 0.9rem; line-height: 1.5; }
.footer-legal-data .dato-voce {
  display: block;
  font-size: var(--t-2xs);
  letter-spacing: var(--tr-etichetta);
  text-transform: uppercase;
  color: var(--text-muted);
  opacity: 0.75;
  margin-bottom: 0.1rem;
}
/* Cifre in tabulare: partita IVA e REA si leggono a cifra a cifra, e le cifre
   a larghezza variabile fanno ballare i gruppi. */
.footer-legal-data .dato-cifra { font-variant-numeric: tabular-nums; }

/* ---------- Paginazione ---------- */
.pagination {
  display: flex; gap: 0.5rem; justify-content: center; align-items: center;
  margin-top: 3.5rem; flex-wrap: wrap;
}
.pagination a, .pagination span {
  padding: 0.6rem 1rem; border: 1px solid var(--border);
  font-size: var(--t-xs); color: var(--text-muted);
}
.pagination a:hover { border-color: var(--accent); color: var(--accent); }
.pagination .current { border-color: var(--accent); color: var(--accent); }

/* ---------- Footer ---------- */
.site-footer {
  background: var(--bg-soft);
  border-top: 1px solid var(--border);
  padding: 4rem 0 2rem;
  margin-top: 0;
  transition: background-color var(--transition), border-color var(--transition);
}
.footer-grid { display: grid; grid-template-columns: 1fr; gap: 2.5rem; }
.footer-col h3 {
  font-family: var(--font-testo);
  font-size: var(--t-2xs); font-weight: 600;
  letter-spacing: var(--tr-etichetta); text-transform: uppercase;
  color: var(--accent); margin-bottom: 1.25rem;
}
.footer-col li { margin-bottom: 0.6rem; font-size: var(--t-sm); color: var(--text-muted); }
.footer-col a { color: var(--text-muted); }
.footer-col a:hover { color: var(--accent); }
.brand-footer { margin-bottom: 1.25rem; }
.footer-tagline { font-size: var(--t-sm); color: var(--text-muted); max-width: 32ch; }

.footer-bottom {
  margin-top: 3rem; padding-top: 1.75rem;
  border-top: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 1rem;
  font-size: var(--t-xs); color: var(--text-muted);
}
.footer-bottom p { margin: 0; }
.footer-legal-links { display: flex; gap: 1.5rem; }



/* ---------- Dotazioni, badge e meta ---------- */
.amenities-title { font-size: var(--t-2xl); margin: 3rem 0 1.5rem; color: var(--text); }
.amenities-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.75rem 1.5rem;
}
.amenities-grid li {
  display: flex; align-items: center; gap: 0.7rem;
  font-size: var(--t-sm); color: var(--text-muted);
}
.amenities-grid svg { color: var(--accent); flex-shrink: 0; }

.license-note {
  margin-top: 2.5rem; padding: 1rem 1.25rem;
  border-left: 2px solid var(--accent); background: var(--surface);
  font-size: var(--t-xs); color: var(--text-muted);
}
.license-note strong { color: var(--text); font-weight: 500; }

.badge-cat {
  position: absolute; top: 1rem; left: 1rem;
  background: var(--accent-solid); color: var(--on-accent);
  font-size: var(--t-2xs); font-weight: 600;
  letter-spacing: var(--tr-etichetta); text-transform: uppercase;
  padding: 0.35rem 0.75rem;
}

.list-meta {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-bottom: 1.5rem; font-size: var(--t-xs); color: var(--text-muted);
}

.booking-host { margin-top: 0.75rem; text-align: center; font-size: var(--t-xs); }
.booking-address {
  margin-top: 1.5rem; padding-top: 1.25rem; border-top: 1px solid var(--border);
  font-size: var(--t-xs); color: var(--text-muted);
}

@media (min-width: 900px) {
  .amenities-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ==========================================================================
   Banner consenso cookie
   Rifiuta e Accetta hanno lo stesso rilievo visivo: il GDPR non ammette che
   negare il consenso costi piu' fatica che concederlo.
   ========================================================================== */
.cookie-banner {
  position: fixed; z-index: 200;
  left: 1rem; right: 1rem; bottom: 1rem;
  max-width: 1100px; margin: 0 auto;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: 0 6px 32px rgba(0, 0, 0, 0.28);
  padding: 1.5rem 1.6rem;
}
.cookie-banner[hidden] { display: none; }

.cookie-inner { display: flex; flex-direction: column; gap: 1.25rem; }
.cookie-copy h2 {
  font-size: var(--t-xl); color: var(--text); margin: 0 0 0.6rem;
}
.cookie-copy p {
  margin: 0; font-size: var(--t-sm); line-height: 1.65; color: var(--text-muted);
}
.cookie-actions { display: flex; flex-wrap: wrap; gap: 0.7rem; }
.cookie-actions .btn { padding: 0.85rem 1.5rem; font-size: var(--t-2xs); }

.btn-quiet {
  background: transparent; border-color: var(--border); color: var(--text);
}
.btn-quiet:hover { border-color: var(--accent); color: var(--accent); }

.cookie-prefs {
  margin-top: 1.5rem; padding-top: 1.25rem; border-top: 1px solid var(--border);
}
.cookie-prefs[hidden] { display: none; }
.cookie-prefs h3 { font-size: var(--t-lg); color: var(--text); margin-bottom: 1rem; }

.cookie-row {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 1.5rem;
  padding: 1rem 0; border-top: 1px solid var(--border);
}
.cookie-row-name {
  display: block; font-size: var(--t-sm); color: var(--text); margin-bottom: 0.25rem;
}
.cookie-row-text {
  display: block; font-size: var(--t-xs); line-height: 1.6; color: var(--text-muted);
}
.cookie-check {
  width: 20px; height: 20px; flex-shrink: 0; margin-top: 0.2rem;
  accent-color: var(--accent-solid);
}
/* I cookie tecnici non sono disattivabili: interruttore fisso, non un campo. */
.cookie-switch {
  flex-shrink: 0; width: 44px; height: 24px; border-radius: 12px;
  background: var(--accent-solid); border: 1px solid var(--accent-solid);
  display: flex; align-items: center; justify-content: flex-end;
  padding: 2px; box-sizing: border-box; margin-top: 0.15rem;
}
.cookie-switch span {
  width: 18px; height: 18px; border-radius: 9px; background: var(--on-accent); display: block;
}
.cookie-prefs-actions { margin-top: 1.25rem; }

@media (min-width: 800px) {
  .cookie-inner { flex-direction: row; align-items: center; gap: 2.5rem; }
  .cookie-copy { flex: 1; }
  .cookie-actions { flex-shrink: 0; }
}


/* ==========================================================================
   Micro-interazioni
   Tutte in CSS, nessuna libreria. Animano solo `transform` e `opacity`, che il
   browser compone sulla GPU senza ricalcolare il layout.

   Ogni effetto vale anche per `:focus-visible`, non solo per `:hover`: chi
   naviga da tastiera deve ricevere lo stesso segnale di chi usa il mouse.
   Sono decorazioni: nessun contenuto compare solo al passaggio del mouse,
   perche' sui dispositivi tattili quel passaggio non esiste.
   Il blocco `prefers-reduced-motion` in fondo al file le azzera tutte.
   ========================================================================== */

/* ---------- Sottolineatura che si disegna ---------- */
.primary-nav .nav-voce,
.footer-col a,
.prose p a,
.breadcrumb a {
  position: relative;
}
.primary-nav .nav-voce::after,
.footer-col a::after,
.prose p a::after,
.breadcrumb a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -3px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform var(--transition);
}
.primary-nav .nav-voce:hover::after,
.primary-nav .nav-voce:focus-visible::after,
.footer-col a:hover::after,
.footer-col a:focus-visible::after,
.prose p a:hover::after,
.prose p a:focus-visible::after,
.breadcrumb a:hover::after,
.breadcrumb a:focus-visible::after {
  transform: scaleX(1);
  transform-origin: left;
}

/* ---------- Bottoni ---------- */
/* Il bordato si riempie da sinistra: il colore entra, non si accende di colpo. */
.btn-outline,
.btn-quiet,
.nav-cta {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
.btn-outline::before,
.btn-quiet::before,
.nav-cta::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--accent-dim);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--transition);
}
.btn-outline:hover::before,
.btn-outline:focus-visible::before,
.btn-quiet:hover::before,
.btn-quiet:focus-visible::before,
.nav-cta:hover::before,
.nav-cta:focus-visible::before {
  transform: scaleX(1);
}

/* Il pieno non puo' riempirsi ancora: si solleva. */
.btn-primary {
  transition: transform var(--transition), background-color var(--transition),
              border-color var(--transition), box-shadow var(--transition);
}
.btn-primary:hover,
.btn-primary:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 6px 18px var(--accent-dim);
}
.btn:active { transform: translateY(1px); }

/* ---------- Card immobile ---------- */
/* Il titolo si sottolinea quando il mouse e' sulla card, non solo sul titolo:
   il bersaglio percepito e' la card intera. */
.property-card-body h3 a { position: relative; }
.property-card-body h3 a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -4px;
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform var(--transition);
}
.property-card:hover .property-card-body h3 a::after,
.property-card-body h3 a:focus-visible::after {
  transform: scaleX(1);
  transform-origin: left;
}
/* La targhetta della tipologia rientra di un soffio. */
.badge-cat { transition: transform var(--transition); }
.property-card:hover .badge-cat { transform: translateX(4px); }

/* ---------- Campi del modulo ---------- */
/* Una riga dorata si apre sotto al campo attivo, oltre al bordo. */
.form-field, .filter-bar > div { position: relative; }
.form-field::after, .filter-bar > div::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transition: transform var(--transition);
}
.form-field:focus-within::after,
.filter-bar > div:focus-within::after { transform: scaleX(1); }

/* ---------- Selettore del tema ---------- */
.theme-toggle svg { transition: transform 420ms cubic-bezier(0.34, 1.56, 0.64, 1); }
.theme-toggle:hover svg,
.theme-toggle:focus-visible svg { transform: rotate(-18deg) scale(1.1); }
.theme-toggle:active svg { transform: rotate(-18deg) scale(0.92); }

/* ---------- Miniature della galleria ---------- */
.gallery-thumb img { transition: transform var(--transition); }
.gallery-thumb:hover img { transform: scale(1.08); }

/* ==========================================================================
   Il Giornale
   Nessun colore e nessun carattere nuovo: tutto viene dai token gia' in uso.
   La scheda articolo e' la scheda immobile con altri contenuti dentro — stesso
   fondo, stesso bordo, stesso sollevamento — perche' scorrere una griglia di
   articoli e scorrere una griglia di case e' lo stesso gesto, e cambiare
   impaginazione fra le due pagine avrebbe reso il sito due siti.
   ========================================================================== */

/* ---------- Barra dei filtri ---------- */
.giornale-filtri {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem 2.5rem;
  margin-bottom: 3.25rem;
}
/* Le voci stanno su una guida: e' la guida a rendere leggibile il cursore che
   scorre. Riquadrate una per una erano cinque pulsanti in fila — l'impaginato
   di qualunque blog — e il cursore non si vedeva nemmeno, coperto dal fondo
   pieno della voce attiva. */
.giornale-categorie {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.75rem;
  border-bottom: 1px solid var(--border);
}

/* Cursore d'oro che scivola sulla guida fino alla voce scelta. Lo posiziona
   main.js misurando il pulsante attivo. Senza JavaScript resta invisibile, e a
   marcare la voce ci pensa il bordo inferiore di `.e-attiva` qui sotto: due
   modi diversi per lo stesso stato, ma uno solo dei due e' attivo per volta. */
.filtro-cursore {
  position: absolute;
  left: 0; bottom: -1px;
  height: 2px;
  width: 0;
  background: var(--accent);
  opacity: 0;
  transition: transform var(--transition), width var(--transition),
              opacity var(--transition);
  pointer-events: none;
}

/* Bottoni di invio, non finti bottoni: la barra e' un <form> e senza
   JavaScript filtra lo stesso. */
.filtro-voce {
  display: inline-flex;
  align-items: baseline;
  gap: 0.45rem;
  font-family: var(--font-testo);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: var(--tr-etichetta);
  text-transform: uppercase;
  color: var(--text-muted);
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  padding: 0.55rem 0 0.7rem;
  cursor: pointer;
  transition: color var(--transition);
}
.filtro-voce:hover { color: var(--text); }
.filtro-voce.e-attiva { color: var(--accent); }
/* Ripiego senza JavaScript: il cursore non si muove, quindi il bordo lo
   disegna la voce stessa. Con JavaScript il cursore c'e' e questo bordo
   sparisce, altrimenti si vedrebbero due filetti sovrapposti. */
.filtro-voce.e-attiva { border-bottom-color: var(--accent); }
.js-cursore .filtro-voce.e-attiva { border-bottom-color: transparent; }

.filtro-conta {
  font-size: 0.8em;
  color: var(--placeholder);
  font-variant-numeric: tabular-nums;
  transition: color var(--transition);
}
.filtro-voce.e-attiva .filtro-conta { color: var(--accent); }

.giornale-esito {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 1.25rem;
  margin: 1.75rem 0 0;
  font-size: var(--t-sm);
  color: var(--text-muted);
}
.giornale-esito[hidden] { display: none; }

.giornale-cerca { position: relative; flex: 0 1 20rem; min-width: 14rem; }

/* La scorciatoia da tastiera si annuncia solo dove esiste una tastiera: la
   scopre main.js, e solo su puntatore fine. Mostrarla su un telefono sarebbe
   un'istruzione ineseguibile. */
.cerca-scorciatoia {
  position: absolute;
  right: 2.6rem; top: 50%;
  translate: 0 -50%;
  font-family: var(--font-testo);
  font-size: var(--t-2xs);
  font-weight: 600;
  color: var(--placeholder);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.1rem 0.4rem;
  pointer-events: none;
  transition: opacity var(--transition);
}
.cerca-scorciatoia[hidden] { display: none; }
.giornale-cerca input:focus ~ .cerca-scorciatoia { opacity: 0; }
.giornale-cerca input {
  width: 100%;
  padding: 0.78rem 2.6rem 0.78rem 1rem;
  font-family: var(--font-testo);
  font-size: var(--t-sm);
  color: var(--text);
  background: var(--field-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  transition: border-color var(--transition), background-color var(--transition);
}
.giornale-cerca input:focus { border-color: var(--accent); outline: none; }
.giornale-cerca input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.giornale-cerca-invio {
  position: absolute;
  right: 0.35rem; top: 50%;
  translate: 0 -50%;
  display: flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem;
  background: none; border: 0; cursor: pointer;
  color: var(--text-muted);
  transition: color var(--transition);
}
.giornale-cerca-invio:hover { color: var(--accent); }
.giornale-cerca-invio svg { width: 17px; height: 17px; }

/* ---------- Righe di servizio dell'articolo ---------- */
.art-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.9rem;
  margin: 0 0 0.7rem;
  font-size: var(--t-2xs);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.art-categoria {
  font-weight: 600;
  letter-spacing: var(--tr-etichetta);
  text-transform: uppercase;
  color: var(--accent);
}
a.art-categoria:hover { color: var(--accent-hover); }
.art-minuti { color: var(--placeholder); }

/* ---------- Articolo in evidenza ---------- */
/* `display` esplicito batte il `display: none` che il browser da' a
   `[hidden]`: senza questa riga l'apertura resterebbe in pagina anche
   filtrando, ed e' proprio quello che era successo. Vale per ogni elemento a
   cui si assegna un display e che poi si nasconde con l'attributo. */
.art-evidenza[hidden] { display: none; }

.art-evidenza {
  display: grid;
  gap: 2rem;
  align-items: center;
  margin-bottom: 3.5rem;
  padding-bottom: 3.5rem;
}
.art-evidenza-testo h3 {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 1.3rem + 2.2vw, 2.9rem);
  font-weight: 400;
  line-height: var(--lh-titolo);
  letter-spacing: var(--tr-display);
  margin: 0 0 1rem;
  max-width: 18ch;
}
.art-evidenza-testo h3 a { color: var(--text); }
.art-evidenza-testo h3 a:hover { color: var(--accent); }
.art-evidenza .art-estratto { max-width: 52ch; margin-bottom: 1.75rem; }

.art-vai { margin: 0; }
.art-vai a {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: var(--tr-etichetta);
  text-transform: uppercase;
  color: var(--accent);
}
.art-freccia { transition: translate var(--transition); }
.art-vai a:hover .art-freccia { translate: 6px 0; }

.art-evidenza-media {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--surface-alt);
}
.art-evidenza-media img {
  display: block;
  width: 100%; height: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
}

/* ---------- L'indice datato ----------
   Non e' una griglia di schede. Otto riquadri identici in tre colonne
   lasciavano una riga spaiata in fondo e non dicevano niente di cosa fosse
   questa pagina: sarebbe stato lo stesso impaginato di un blog qualsiasi.
   Qui c'e' una riga per uscita, con la data nel margine in cifre allineate —
   la forma di un giornale di bordo, che e' quello che questa pagina e'.
   Si scorre con gli occhi, si legge in ordine di data, e righe spaiate non ne
   ha per costruzione. */
.registro-articoli {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--border);
}

.voce-articolo {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  padding: 1.75rem 0;
  border-bottom: 1px solid var(--border);
  transition: background-color var(--transition);
}

/* Il velo del passaggio del mouse sborda oltre il testo, fin sotto la data e
   la freccia: una riga che si accende solo dove c'e' scritto qualcosa
   sembrerebbe rotta. Sta su `::before` per non toccare lo sfondo della riga,
   che serve intatto al filetto. */
.voce-articolo::before {
  content: "";
  position: absolute;
  inset: 0 -1.25rem;
  background: var(--accent-dim);
  opacity: 0;
  transition: opacity var(--transition);
  pointer-events: none;
}
.voce-articolo:hover::before,
.voce-articolo:has(a:focus-visible)::before { opacity: 1; }

/* La data. `tabular-nums` perche' incolonnata: con le cifre proporzionali un
   «11» e un «20» partono da due punti diversi e la colonna balla. */
.voce-data {
  margin: 0;
  font-variant-numeric: tabular-nums lining-nums;
  color: var(--text-muted);
}
.voce-giorno {
  font-family: var(--font-display);
  font-size: var(--t-2xl);
  font-weight: 400;
  line-height: 1;
  color: var(--accent);
  display: inline-block;
  transition: color var(--transition);
}
.voce-mese {
  display: inline-block;
  margin-left: 0.5rem;
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: var(--tr-etichetta);
  text-transform: uppercase;
}

.voce-media {
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--surface-alt);
  aspect-ratio: 4 / 3;
}
.voce-media img,
.voce-media .media-placeholder {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 600ms cubic-bezier(0.4, 0, 0.2, 1);
}
.voce-articolo:hover .voce-media img { transform: scale(1.06); }

.voce-alto {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.9rem;
  margin: 0 0 0.5rem;
}

.voce-testo .art-estratto { max-width: 62ch; }
.voce-testo h3 {
  font-family: var(--font-display);
  font-size: var(--t-xl);
  font-weight: 500;
  line-height: var(--lh-titolo);
  letter-spacing: var(--tr-titolo);
  margin: 0 0 0.55rem;
  max-width: 34ch;
}
.voce-testo h3 a { color: var(--text); transition: color var(--transition); }
.voce-articolo:hover h3 a { color: var(--accent); }

/* Il bersaglio si allarga a tutta la riga, ma nell'ordine di lettura resta un
   collegamento solo, col titolo per nome. */
.voce-testo h3 a::after { content: ""; position: absolute; inset: 0; }
.voce-articolo:has(a:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.voce-testo h3 a:focus-visible { outline: none; }

.voce-freccia {
  display: none;
  align-self: center;
  color: var(--accent);
  opacity: 0;
  translate: -8px 0;
  transition: opacity var(--transition), translate var(--transition);
}
.voce-freccia svg { width: 24px; height: 24px; display: block; }
.voce-articolo:hover .voce-freccia,
.voce-articolo:has(a:focus-visible) .voce-freccia { opacity: 1; translate: 0 0; }

/* Riga nascosta dal filtro dal vivo. `display: none` e non `visibility`: deve
   uscire dal flusso, altrimenti resta il suo filetto e l'elenco sembra pieno
   di buchi. */
.voce-articolo[hidden] { display: none; }

.registro-vuoto {
  margin: 3rem 0 0;
  font-size: var(--t-lg);
  color: var(--text-muted);
}

/* Un pulsante che deve leggersi come un collegamento: e' un comando (azzera
   dei filtri applicati qui) e non una destinazione, quindi <button>. */
.collegamento-finto {
  font: inherit;
  color: var(--accent);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.collegamento-finto:hover { color: var(--accent-hover); }

.art-apertura {
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: var(--tr-etichetta);
  text-transform: uppercase;
  color: var(--on-accent);
  background: var(--accent-solid);
  padding: 0.25rem 0.6rem;
  border-radius: var(--radius);
}

.art-estratto {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--t-sm);
  line-height: 1.7;
}

.art-piede {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.75rem;
  margin: 1.5rem 0 0;
  padding-top: 1.25rem;
  border-top: 1px solid var(--border);
  font-size: var(--t-xs);
  color: var(--text-muted);
}

/* ---------- Chiusura dell'elenco ---------- */
.giornale-chiusura { display: grid; gap: 1.75rem; }

.riquadro-lettera, .riquadro-invito {
  padding: 2.25rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.riquadro-invito { background: var(--accent-dim); border-color: var(--accent); }
.riquadro-lettera h3, .riquadro-invito h3 {
  font-family: var(--font-display);
  font-size: var(--t-2xl);
  font-weight: 400;
  line-height: var(--lh-titolo);
  letter-spacing: var(--tr-titolo);
  margin: 0 0 0.9rem;
  max-width: 20ch;
}
.riquadro-lettera p, .riquadro-invito p {
  color: var(--text-muted);
  font-size: var(--t-sm);
  line-height: 1.7;
  max-width: 46ch;
  margin: 0 0 1.75rem;
}

.lettera-modulo { display: flex; flex-wrap: wrap; gap: 0.75rem; }
.lettera-modulo input {
  flex: 1 1 12rem;
  padding: 0.9rem 1rem;
  font-family: var(--font-testo);
  font-size: var(--t-sm);
  color: var(--text);
  background: var(--field-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
/* Disattivato finche' non c'e' un servizio d'invio collegato: si vede che non
   funziona, invece di raccogliere indirizzi che nessuno riceve. */
.lettera-modulo input:disabled, .lettera-modulo button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.lettera-nota {
  margin: 1rem 0 0 !important;
  font-size: var(--t-xs);
  color: var(--placeholder);
}

/* ---------- Barra di avanzamento della lettura ---------- */
.lettura-barra {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 2px;
  z-index: 200;
  pointer-events: none;
  background: transparent;
}
.lettura-barra span {
  display: block;
  height: 100%;
  background: var(--accent);
  transform-origin: left center;
  transform: scaleX(var(--letto, 0));
}


/* ---------- Testata dell'articolo ---------- */
.articolo-testa {
  padding: 3.5rem 0 2.5rem;
  background:
    linear-gradient(var(--band-veil), var(--band-veil)),
    radial-gradient(ellipse at 82% 40%, var(--band-glow), transparent 62%),
    var(--bg-soft);
  border-bottom: 1px solid var(--border);
  transition: background-color var(--transition), border-color var(--transition);
}
.articolo-briciole { margin: 0 0 1.75rem; font-size: var(--t-xs); }
.articolo-briciole a {
  color: var(--text-muted);
  letter-spacing: var(--tr-etichetta);
  text-transform: uppercase;
  font-weight: 600;
}
.articolo-briciole a:hover { color: var(--accent); }

.articolo-testa h1 { max-width: 20ch; margin: 0 0 1.25rem; }
.articolo-testa .lead { max-width: 54ch; margin-bottom: 2rem; }
.articolo-meta { margin-bottom: 1.1rem; }

.articolo-firma {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin: 0;
  font-size: var(--t-xs);
  color: var(--text-muted);
}
.firma-chi { display: flex; align-items: center; gap: 0.8rem; margin: 0; }

.copia-link {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-testo);
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: var(--tr-etichetta);
  text-transform: uppercase;
  color: var(--text-muted);
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.6rem 1rem;
  cursor: pointer;
  transition: color var(--transition), border-color var(--transition),
              background-color var(--transition);
}
.copia-link:hover { color: var(--accent); border-color: var(--accent); }
.copia-link svg { width: 15px; height: 15px; }
.copia-link[hidden] { display: none; }
/* A cosa fatta il pulsante lo dice da se': senza conferma non si sa se il
   click e' andato a segno, e si preme una seconda volta. */
.copia-link.e-fatto { color: var(--accent); border-color: var(--accent); background: var(--accent-dim); }
.firma-bollo {
  display: grid;
  place-items: center;
  width: 2.4rem; height: 2.4rem;
  border: 1px solid var(--accent);
  border-radius: 50%;
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--accent);
}

/* ---------- Corpo ---------- */
.articolo-copertina {
  margin: 3rem 0 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  /* `clip` e non `hidden`, e non e' un dettaglio: `hidden` fa di questo
     elemento un contenitore di scorrimento, e `view()` misura sempre rispetto
     al contenitore di scorrimento piu' vicino. La fotografia dentro avrebbe
     quindi agganciato la timeline di un riquadro che non scorre mai, restando
     ferma sul primo fotogramma. E' la stessa trappola gia' documentata per il
     blocco della vetrina. */
  overflow: clip;
  background: var(--surface-alt);
}
.copertina-scena { display: block; overflow: clip; }
.articolo-copertina img {
  display: block;
  width: 100%;
  aspect-ratio: 21 / 9;
  object-fit: cover;
}

/* La fotografia scorre piu' lenta della pagina. Vive dentro `.js-anim`, quindi
   con «riduci movimento» non esiste: e' esattamente il genere di movimento che
   quella preferenza vuole evitare. Il fotogramma sorgente e' piu' alto del
   riquadro, altrimenti a fondo corsa si scoprirebbe una striscia vuota. */
@supports (animation-timeline: view()) {
  .js-anim .copertina-scena img {
    height: 118%;
    animation: ev-copertina linear both;
    animation-timeline: view();
    /* `cover` e non `entry`: il movimento deve durare quanto la fotografia
       resta in campo, non solo mentre entra. */
    animation-range: cover 0% cover 100%;
  }
}
@keyframes ev-copertina {
  from { transform: translateY(-13%); }
  to   { transform: translateY(0); }
}

/* Colonna di lettura e indice. Sotto i 1100px sono impilati; sopra, l'indice
   va nel margine destro — che altrimenti resterebbe vuoto per tutta la
   lunghezza dell'articolo — e ci resta appiccicato mentre si scorre.

   Nel markup l'indice viene dopo il testo, perche' e' li' che serve nell'ordine
   di lettura di uno screen reader — prima il contenuto, poi lo strumento per
   saltarci dentro. Impilato pero' finirebbe in fondo all'articolo, dove non
   serve a nessuno: `order` lo riporta in cima senza toccare l'ordine del
   documento. */
.articolo-lettura { display: grid; margin: 3.25rem 0 0; }

.articolo-corpo { max-width: 680px; }

/* L'incipit e' composto un filo piu' grande del resto: da' un attacco al
   testo senza bisogno di un capolettera, che con Fraunces a questi corpi
   diventerebbe un ornamento e basta. */
.articolo-corpo .incipit {
  font-size: 1.16rem;
  line-height: 1.66;
  color: var(--text);
}

/* Ancora accanto al titolo di sezione: compare al passaggio del mouse e
   quando prende il fuoco. Resta nel flusso — `margin-left` negativo lo
   toglierebbe dall'allineamento del testo su schermi stretti. */
/* Arrivando da `#sezione`, il titolo si ferma sotto l'intestazione
   appiccicata invece che dietro. */
.articolo-corpo h2 {
  position: relative;
  scroll-margin-top: calc(var(--header-h) + 1.5rem);
}
.ancora {
  display: inline-block;
  margin-left: 0.5rem;
  font-family: var(--font-testo);
  font-size: 0.62em;
  font-weight: 600;
  color: var(--accent);
  opacity: 0;
  translate: -4px 0;
  transition: opacity var(--transition), translate var(--transition);
}
.articolo-corpo h2:hover .ancora,
.ancora:focus-visible { opacity: 1; translate: 0 0; }
/* Su schermi a tocco il passaggio del mouse non esiste: li' l'ancora si vede
   sempre, in secondo piano, invece di essere irraggiungibile. */
@media (hover: none) {
  .ancora { opacity: 0.45; translate: 0 0; }
}
/* Conferma della copia: l'ancora diventa un segno di spunta per un attimo.
   Il carattere sta nel CSS e non nel markup perche' e' un ritorno visivo, non
   contenuto: chi legge con uno screen reader ha gia' sentito il nome del
   collegamento. */
.ancora.e-copiata { opacity: 1; translate: 0 0; }
.ancora.e-copiata span::after { content: " ✓"; }

.articolo-indice { order: -1; margin: 0 0 2.5rem; }
.indice-titolo {
  margin: 0 0 1rem;
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: var(--tr-occhiello);
  text-transform: uppercase;
  color: var(--accent);
}
.articolo-indice ol {
  list-style: none;
  margin: 0;
  padding: 0;
  border-left: 1px solid var(--border);
}
.articolo-indice li { margin: 0; }
.articolo-indice a {
  display: block;
  padding: 0.5rem 0 0.5rem 1rem;
  margin-left: -1px;
  border-left: 1px solid transparent;
  font-size: var(--t-sm);
  line-height: 1.45;
  color: var(--text-muted);
  transition: color var(--transition), border-color var(--transition);
}
.articolo-indice a:hover { color: var(--text); }
/* La sezione in cui ci si trova: il filetto si accende e il testo passa in
   primo piano. Lo stato lo scrive main.js leggendo la posizione dei titoli. */
.articolo-indice a.e-corrente {
  color: var(--accent);
  border-left-color: var(--accent);
  font-weight: 500;
}
.articolo-corpo p {
  font-size: 1.0625rem;
  line-height: 1.72;
  color: var(--text);
  margin: 0 0 1.5rem;
}
.articolo-corpo h2 {
  font-family: var(--font-display);
  font-size: var(--t-2xl);
  font-weight: 400;
  line-height: var(--lh-titolo);
  letter-spacing: var(--tr-titolo);
  margin: 2.75rem 0 1.1rem;
}
.articolo-corpo h2:first-child { margin-top: 0; }
.articolo-corpo p:last-child { margin-bottom: 0; }

/* ---------- Fascia dei numeri ---------- */
.articolo-numeri {
  margin: 4rem 0 0;
  padding: 3.5rem 0;
  background: var(--bg-soft);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  transition: background-color var(--transition), border-color var(--transition);
}
.articolo-numeri .stagione-dati { margin: 0; }
.articolo-numeri-nota {
  margin: 2.25rem 0 0;
  font-size: var(--t-xs);
  color: var(--placeholder);
}

/* ---------- Citazione ---------- */
.articolo-citazione { max-width: 680px; margin: 3.5rem 0 0; }
.articolo-citazione .gold-rule { margin: 0 0 1.5rem; }
.articolo-citazione blockquote {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--t-xl);
  font-style: italic;
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: var(--tr-titolo);
  color: var(--text);
}
.articolo-citazione figcaption {
  margin-top: 1rem;
  font-size: var(--t-xs);
  letter-spacing: var(--tr-etichetta);
  text-transform: uppercase;
  color: var(--text-muted);
}

/* ---------- Tag ---------- */
.articolo-tag {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
  list-style: none;
  max-width: 680px;
  margin: 3.5rem 0 0;
  padding: 0;
}
.articolo-tag li {
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: var(--tr-etichetta);
  text-transform: uppercase;
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.45rem 0.85rem;
}

.articolo + .cta-band { margin-top: 4.5rem; }

/* ---------- Da leggere dopo ---------- */
.art-dopo { display: grid; grid-template-columns: 1fr; gap: 2rem; list-style: none; padding: 0; margin: 0; }
.art-dopo li { padding-top: 1.25rem; border-top: 1px solid var(--accent); }
.dopo-media {
  aspect-ratio: 3 / 2;
  margin-bottom: 1.1rem;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--surface-alt);
}
.dopo-media img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 600ms cubic-bezier(0.4, 0, 0.2, 1);
}
.art-dopo li:hover .dopo-media img { transform: scale(1.05); }
.art-dopo h3 {
  font-family: var(--font-display);
  font-size: var(--t-lg);
  font-weight: 500;
  line-height: var(--lh-titolo);
  letter-spacing: var(--tr-titolo);
  margin: 0 0 0.6rem;
}
.art-dopo h3 a { color: var(--text); }
.art-dopo li:hover h3 a { color: var(--accent); }

/* ---------- Torna su ---------- */
.torna-su {
  position: fixed;
  right: 1.5rem; bottom: 1.5rem;
  z-index: 90;
  display: grid;
  place-items: center;
  width: 2.9rem; height: 2.9rem;
  color: var(--accent);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 50%;
  box-shadow: var(--card-shadow);
  transition: border-color var(--transition), background-color var(--transition),
              opacity var(--transition), translate var(--transition);
}
.torna-su svg { width: 18px; height: 18px; }
.torna-su:hover { border-color: var(--accent); background: var(--accent-dim); }
/* Nasconde con `hidden`, che main.js commuta: cosi' l'elemento esce anche
   dall'ordine del tabulatore invece di restare un bersaglio invisibile. */
.torna-su[hidden] { display: none; }

/* La comparsa e' un'animazione, quindi vive dentro `.js-anim`: senza, il
   pulsante appare e basta. */
.js-anim .torna-su { animation: ev-torna-su 320ms ease-out both; }
@keyframes ev-torna-su {
  from { opacity: 0; translate: 0 12px; }
  to   { opacity: 1; translate: 0 0; }
}

/* ---------- Il trattino dell'occhiello che si traccia ----------
   Il filetto oro davanti a «Il Giornale · EV House» non c'e' e poi c'e': si
   disegna da sinistra quando la testata entra in campo. E' lo stesso gesto dei
   tratti che uniscono i passi nella pagina Servizi. */
.js-anim .page-head .eyebrow-riga::before,
.js-anim .articolo-testa .eyebrow-riga::before {
  transform-origin: left center;
  transform: scaleX(0);
  transition: transform 900ms cubic-bezier(0.22, 1, 0.36, 1) 120ms;
}
.js-anim [data-reveal].is-visible .eyebrow-riga::before { transform: scaleX(1); }

@supports (animation-timeline: view()) {
  .js-anim .page-head .eyebrow-riga::before {
    transition: none;
    animation: ev-linea-orizzontale linear both;
    animation-timeline: view();
    animation-range: entry 18% entry 62%;
  }
}

@media (min-width: 600px) {
  .art-dopo { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .giornale-chiusura { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Da qui l'indice sta nel margine destro e ci resta appiccicato. Sotto questa
   soglia il margine non c'e': la colonna di lettura occupa quasi tutta la
   larghezza, e l'indice torna un riquadro sopra il testo. */
@media (min-width: 1100px) {
  .articolo-lettura {
    grid-template-columns: 680px minmax(0, 1fr);
    gap: 4rem;
    align-items: start;
  }
  /* Posizione esplicita: senza, `order: -1` metterebbe l'indice nella prima
     casella libera, cioe' nella colonna del testo. */
  .articolo-corpo  { grid-column: 1; grid-row: 1; }
  .articolo-indice {
    grid-column: 2;
    grid-row: 1;
    position: sticky;
    /* Sotto l'intestazione appiccicata del sito, con un po' d'aria. */
    top: calc(var(--header-h) + 2rem);
    margin: 0.5rem 0 0;
    max-height: calc(100vh - var(--header-h) - 4rem);
    overflow-y: auto;
  }
}

@media (min-width: 900px) {
  /* Da qui la riga si dispone in orizzontale: data nel margine, miniatura,
     testo, freccia. Sotto, gli stessi pezzi restano impilati. */
  .voce-articolo {
    grid-template-columns: 4.5rem 190px 1fr 2.5rem;
    gap: 2rem;
    align-items: start;
    padding: 2rem 0;
  }
  .voce-data { padding-top: 0.15rem; }
  .voce-giorno { display: block; font-size: 2rem; }
  .voce-mese { display: block; margin: 0.35rem 0 0; }
  .voce-freccia { display: block; }
  .art-dopo { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* Cinque parti al testo, sei all'immagine: la fotografia pesa appena piu'
     della colonna scritta, che e' quello che la fa leggere come apertura e non
     come una scheda larga. */
  .art-evidenza { grid-template-columns: 5fr 6fr; gap: 3.5rem; }
  .giornale-chiusura { grid-template-columns: 1.15fr 1fr; gap: 2rem; }
  .articolo-testa { padding: 4.5rem 0 3rem; }
  .torna-su { right: 2.5rem; bottom: 2.5rem; }
}


/* ==========================================================================
   Breakpoints
   ========================================================================== */

@media (min-width: 600px) {
  .property-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .passi-griglia { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .filter-bar    { grid-template-columns: 1fr 1fr; align-items: end; }
  .footer-grid   { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .footer-bottom { flex-direction: row; justify-content: space-between; align-items: center; }
}

@media (min-width: 900px) {
  /* L'ingrandimento va sulla radice, non sul body: le misure della scala sono
     in `rem`, che si riferiscono alla radice. Alzando solo il body il testo
     corrente cresceva e tutto il resto restava fermo, e i rapporti fra i
     livelli si sfasavano del 6%. */
  :root { font-size: 17px; }
  .section { padding: 7rem 0; }


  .header-actions { margin-left: 1.75rem; order: 3; }

  /* Da qui in su c'e' spazio per il logo alla misura piena, e l'header
     cresce di conseguenza: il token governa anche lo scostamento dell'hero. */
  :root { --header-h: 104px; }
  .brand-logo { height: 72px; }

  /* localita, tipologia, ospiti e pulsante su una riga sola */
  .filter-bar { grid-template-columns: 1.4fr 1.1fr 0.7fr auto; }

  .hero { --hero-fade: 190px; }

  .property-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .passi-griglia { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1.25rem; }
  .footer-grid   { grid-template-columns: 1.5fr 1fr 1fr 1fr; }

  .detail-layout { grid-template-columns: 1.7fr 1fr; align-items: start; }
  .contact-layout { display: grid; grid-template-columns: 1.2fr 1fr; gap: 4rem; align-items: start; }
}

/* ---------- La barra orizzontale del menu parte da 1150px ----------
   Sotto, resta il pannello a scomparsa col pulsante. Non e' una scelta di
   gusto: sette voci — «Portale proprietari» e' lunga — piu' il logo a 246px
   piu' il cambio tema non stanno negli 860px di riga utile di uno schermo da
   900. Fino a 1100 il logo veniva schiacciato a una scheggia di nove pixel e
   la pagina scorreva di lato. Col pannello il menu si apre intero e il logo
   resta leggibile. Da 900 a 1150 il resto della pagina e' gia' in versione
   larga: qui cambia solo il menu. */
@media (min-width: 1150px) {
  .nav-toggle { display: none; }

  .primary-nav {
    position: static; max-height: none; overflow: visible;
    background: none; border: 0;
    margin-left: auto;
    order: 2;              /* dopo il brand, prima del toggle tema */
  }
  /* Il respiro fra le voci: stretto dove la riga e' contata, pieno piu' in la
     (vedi il blocco a 1400). Con sette voci la differenza fra 1,4rem e
     2,25rem sono novanta pixel, cioe' se il logo resta intero o no. */
  .primary-nav ul { flex-direction: row; gap: 1.4rem; padding: 0; align-items: center; }
  .primary-nav a { padding: 0; border: 0; font-size: var(--t-2xs); }
  .primary-nav .nav-cta {
    border: 1px solid var(--accent); padding: 0.65rem 1.4rem;
  }
  .primary-nav .nav-cta:hover { background: var(--accent-dim); }

  /* ---------- Tendina delle localita', da 900px in su ----------
     Qui non e' piu' un sotto-elenco ma un pannello sospeso sotto la voce. */
  .ha-tendina { position: relative; }
  .nav-riga { gap: 0.3rem; }
  .nav-freccia { width: 18px; height: 18px; }
  .nav-freccia svg { width: 13px; height: 13px; }

  .tendina {
    position: absolute;
    top: calc(100% + 1.1rem);
    left: 50%;
    z-index: 120;
    width: max-content;
    max-width: min(92vw, 30rem);
    max-height: none;
    overflow: visible;
    padding: 1.35rem 1.6rem 1.1rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: 0 20px 48px rgba(10, 10, 10, 0.16);

    /* Stato chiuso. `visibility` e non solo `opacity`: un pannello a opacita'
       zero resterebbe cliccabile e catturerebbe il fuoco col tabulatore. */
    opacity: 0;
    visibility: hidden;
    translate: -50% 8px;
    transition: opacity var(--transition), translate var(--transition),
                visibility var(--transition);
  }

  /* Il pannello sta 1.1rem piu' in basso della voce: senza un ponte invisibile
     su quello stacco, scendendo col mouse si perderebbe il passaggio e la
     tendina si richiuderebbe in faccia. */
  .tendina::before {
    content: "";
    position: absolute;
    left: 0; right: 0;
    top: -1.2rem;
    height: 1.2rem;
  }

  .ha-tendina:focus-within > .tendina,
  .ha-tendina.e-aperta > .tendina {
    opacity: 1;
    visibility: visible;
    translate: -50% 0;
  }

  /* Chiusura esplicita, e deve poter vincere su `:focus-within`. Premendo Esc
     il fuoco torna sul pulsante, che sta dentro la voce: senza questa regola
     la tendina resterebbe aperta e Esc sembrerebbe non fare niente.
     Stessa specificita' della regola qui sopra, quindi conta che venga dopo.
     main.js la toglie quando il puntatore o il fuoco escono dalla voce, cosi'
     un passaggio successivo la riapre normalmente. */
  .ha-tendina.e-chiusa > .tendina {
    opacity: 0;
    visibility: hidden;
    translate: -50% 8px;
  }

  .tendina-titolo { margin: 0 0 0.9rem; }

  /* In colonna e non per righe: l'elenco e' alfabetico, e riempiendolo per
     righe la A finirebbe accanto alla L invece che sopra la B. */
  .primary-nav .tendina-elenco {
    display: grid;
    grid-auto-flow: column;
    grid-template-rows: repeat(10, auto);
    column-gap: 2.25rem;
    row-gap: 0;
  }
  .primary-nav .tendina a { padding: 0.42rem 0 0.42rem 0.8rem; }

  .primary-nav .tendina .tendina-tutte {
    margin-top: 1rem;
    padding-top: 0.9rem;
    border-top: 1px solid var(--border);
  }
}


/* ==========================================================================
   Vetrina degli immobili in evidenza

   Due comportamenti sullo stesso markup.

   Base — e quindi anche senza JavaScript, su schermi stretti, con "riduci
   movimento" o su un browser senza timeline di scorrimento: una fila che si
   trascina in orizzontale, con aggancio alle schede.

   Avanzato: la sezione si blocca a schermo pieno e lo scorrimento verticale
   diventa avanzamento orizzontale. Nessun `preventDefault` sulla rotella: la
   pagina scorre come sempre, e' solo la fila a spostarsi in funzione di quanto
   si e' scorso. Rotella, trackpad, frecce, barra laterale e ricerca nel testo
   continuano a funzionare come su qualsiasi altra pagina, e alla fine delle
   schede la pagina riprende da sola a scorrere in verticale.
   ========================================================================== */

.showcase {
  /* Tenue e non chiaro: nell'ordine della home la vetrina sta fra la sezione
     dell'ospite e quella delle recensioni, entrambe chiare. */
  --carta: 300px;
  --spazio: 1.5rem;
  --bordo: max(1.5rem, calc((100vw - var(--container)) / 2));
  --tessere: 10;                 /* 9 immobili + la tessera finale */

  /* Larghezza della fila, calcolata invece che dedotta dal contenuto.
     `width: max-content` sembrava piu' pulito, ma su un contenitore flex
     Firefox non lo calcola dalla base flessibile delle tessere: misurava
     11694px al posto di 3936. Tutto quello che si appoggia a quella
     larghezza — a partire da `translateX(-100%)` — ne usciva sballato.
     Le tessere hanno larghezza fissa, quindi la somma qui e' esatta. */
  --larghezza-fila: calc(
    var(--tessere) * var(--carta)
    + (var(--tessere) - 1) * var(--spazio)
    + 2 * var(--bordo));

  /* Quanti pixel percorre la fila per ogni pixel scorso.
     A 1 il blocco durerebbe quanto tutta la corsa: corretto, ma da scorrere
     e' lungo. A 2 la fila va al doppio della rotella e il tratto incollato si
     dimezza, restando abbastanza lento da leggere le schede mentre passano.
     E' l'unico numero da toccare per accorciare o allungare la sezione. */
  --ritmo: 2;

  padding: 4.5rem 0;
  background: var(--bg-soft);
}

.showcase-head { margin-bottom: 2.5rem; }

.showcase-scroll {
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-padding-left: var(--bordo);
  overscroll-behavior-x: contain;   /* non trascina indietro la cronologia */
}

.showcase-track {
  display: flex;
  /* Senza una larghezza esplicita la fila e' larga quanto il contenitore e le
     tessere le escono fuori. La misura comprende i due margini laterali,
     perche' il progetto usa `border-box`. */
  width: var(--larghezza-fila);
  gap: var(--spazio);
  /* Il fondo lascia respiro al sollevamento della scheda, che altrimenti
     verrebbe tagliato dal contenitore. */
  padding: 0.25rem var(--bordo) 1.25rem;
  margin: 0;
  list-style: none;
}

.showcase-item {
  flex: 0 0 var(--carta);
  height: clamp(380px, 58vh, 520px);
  scroll-snap-align: start;
  display: flex;
}
.showcase-item > * { width: 100%; }

/* Altezza fissa per tutte le schede: il testo si taglia a due righe e le
   fotografie restano allineate invece di ballare di scheda in scheda. */
.showcase-item .property-card { height: 100%; }
/* La fotografia cede spazio prima del testo. Con `min-height: 120px` smetteva
   di stringersi e la differenza la pagava il corpo della scheda, che pero' non
   puo' rimpicciolirsi: sforava dal basso e `overflow: hidden` mangiava la riga
   di ospiti, camere e bagni. Su una finestra da 700px la scheda era alta 250px
   e il solo corpo ne voleva 292. */
.showcase-item .property-card-media {
  aspect-ratio: auto;
  flex: 1 1 auto;
  /* Zero, non ottanta. Qualunque soglia diversa da zero e' una scommessa su
     quanto sara' alta la finestra: superata quella, a cedere torna a essere il
     testo. Cosi' invece la garanzia e' strutturale — il corpo della scheda non
     puo' essere tagliato, al massimo si assottiglia la fotografia — e a tenere
     la fotografia di una misura decente ci pensa la soglia di altezza sotto la
     quale il carosello non si blocca affatto. */
  min-height: 0;
}
.showcase-item .property-card-body { flex: 0 0 auto; }
/* Senza l'estratto sopra, la riga dei numeri resterebbe a mezz'aria. */
.showcase-item .property-specs { margin-top: 1rem; padding-top: 1rem; }
.showcase-item .property-card-body h3 {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  /* Altezza fissa di due righe, non massima: un titolo corto lascerebbe
     comunque il suo spazio, cosi' le fotografie restano tutte alla stessa
     altezza lungo la fila. */
  line-height: 1.2;
  height: 2.4em;
}
/* Nel carosello l'estratto non c'e', a nessuna misura. E' due righe di
   descrizione troncata in una vetrina dove titolo, localita' e numeri dicono
   gia' tutto, e lo spazio che occupa la fotografia lo usa meglio. Toglierlo
   solo sulle finestre basse produceva pure un'incoerenza: a 900px di altezza
   la foto veniva piu' piccola che a 800. L'estratto resta dove serve — nella
   fila trascinabile della pagina Immobili e nelle schede dell'elenco. */
.showcase-item .property-excerpt { display: none; }

/* Tessera finale: chiude la fila su una destinazione invece che nel vuoto. */
.showcase-fine {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.75rem;
  height: 100%;
  padding: 2rem;
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  background: var(--accent-dim);
  color: var(--text);
  transition: background-color var(--transition), translate var(--transition);
}
.showcase-fine:hover { background: var(--surface); translate: 0 -4px; }
.showcase-fine-eyebrow {
  font-size: var(--t-2xs); font-weight: 600;
  letter-spacing: var(--tr-occhiello); text-transform: uppercase;
  color: var(--accent);
}
.showcase-fine-titolo {
  font-family: var(--font-display);
  font-size: var(--t-2xl); font-weight: 500;
  line-height: var(--lh-titolo); letter-spacing: var(--tr-titolo);
}
.showcase-fine-freccia svg { width: 30px; height: 30px; color: var(--accent); }
.showcase-fine:hover .showcase-fine-freccia svg { translate: 6px 0; }
.showcase-fine-freccia svg { transition: translate var(--transition); }

/* Senza blocco non serve: c'e' gia' la barra di scorrimento del contenitore. */
.showcase-avanzamento { display: none; }


/* ---------- Variante bloccata ----------
   La classe `e-bloccata` la mette main.js quando lo schermo e' largo e
   l'utente non ha chiesto di ridurre le animazioni. Fuori da quei casi non
   esiste e resta la fila trascinabile qui sopra.

   L'avanzamento (0 -> 1) arriva da `--avanzamento`. Chi ha le timeline di
   scorrimento lo ignora: il blocco @supports piu' sotto mette un'animazione
   sulle stesse proprieta', e un'animazione in corso ha la precedenza sulle
   dichiarazioni normali. Cosi' i browser capaci lo fanno sul compositor e gli
   altri con un ascoltatore di scroll, senza duplicare una riga di layout. */

.showcase.e-bloccata {
  /* Quanto c'e' da percorrere in orizzontale. Sopra i 1200px il margine
     laterale cresce quanto la finestra, quindi la corsa resta costante. */
  --corsa: calc(var(--larghezza-fila) - 100vw);

  /* Altezza = quanto resta incollato + il tratto da scorrere. Il primo addendo
     e' l'altezza del blocco (schermo meno intestazione), non lo schermo
     intero: solo cosi' l'intervallo `contain` torna esattamente pari al
     tratto, e la fila finisce la corsa nell'istante in cui il blocco si
     stacca — niente scorrimento a vuoto in coda.
     Il rapporto fra i due e' `--ritmo`, e main.js lo rilegge da qui per
     portare in vista una scheda raggiunta col tabulatore. */
  /* `svh` e non `vh`: su iOS `100vh` e' l'altezza con la barra dell'indirizzo
     gia' ritirata, quindi il blocco sborderebbe. E nemmeno `dvh`, che cambia
     mentre la barra si ritira: cambierebbe l'altezza della sezione a meta'
     corsa, e con essa il rapporto fra scorrimento e spostamento. `svh` e'
     l'unica delle tre che sta ferma. La riga con `vh` resta per i browser che
     non conoscono le unita' nuove. */
  height: calc(100vh - var(--header-h) + var(--corsa) / var(--ritmo));
  height: calc(100svh - var(--header-h) + var(--corsa) / var(--ritmo));
  padding: 0;

  view-timeline-name: --vetrina;
  /* L'intestazione del sito e' appiccicata in alto: la timeline deve partire
     da sotto, altrimenti va fuori passo di quei pixel. */
  view-timeline-inset: var(--header-h) 0px;
}

.showcase.e-bloccata .showcase-pin {
  position: sticky;
  top: var(--header-h);
  height: calc(100vh - var(--header-h));
  height: calc(100svh - var(--header-h));
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* Da quando la fila prende lo spazio che avanza, l'intestazione finisce
     appiccicata sotto quella del sito: questo respiro glielo restituisce. */
  padding: 1.25rem 0 0.75rem;
  /* `clip` e non `hidden`: `hidden` creerebbe un contenitore di scorrimento, e
     portando a fuoco una scheda fuori campo il browser lo farebbe scorrere di
     nascosto, sfasando tutto rispetto alla pagina. */
  overflow: clip;
}

.showcase.e-bloccata .showcase-scroll {
  overflow: clip;
  scroll-snap-type: none;
}

/* Intestazione, fila e barra devono stare nei pixel del blocco: se sforano,
   `overflow: clip` taglia in cima e l'occhiello sparisce. */
.showcase.e-bloccata .showcase-head { margin-bottom: 1.75rem; }

/* La scheda prende lo spazio che avanza invece di avere un'altezza indovinata
   in `vh`: il blocco e' una colonna flessibile, la fila e' l'unico elemento
   che si allunga. Cosi' non c'e' una combinazione di schermo e lunghezza del
   titolo che possa far sforare il contenuto — e sui telefoni piccoli la
   fotografia guadagna spazio invece di perderlo. */
.showcase.e-bloccata .showcase-scroll {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  align-items: stretch;
}
.showcase.e-bloccata .showcase-track { align-items: stretch; }
.showcase.e-bloccata .showcase-item {
  height: auto;
  max-height: 520px;   /* oltre, la scheda si allunga senza guadagnarci */
}

/* Finestra bassa ma larga — il portatile tipico, 1366x768 o 1280x700. Qui il
   blocco ha da spartire fra intestazione, schede e barra meno di settecento
   pixel: senza togliere qualcosa, alla fotografia resta una striscia. Cadono
   le due cose piu' sacrificabili — l'introduzione della sezione e l'estratto
   della scheda — e la fotografia torna a respirare. */
@media (min-width: 1000px) and (max-height: 880px) {
  .showcase.e-bloccata .showcase-head { margin-bottom: 1.25rem; }
  .showcase.e-bloccata .showcase-head .lead { display: none; }
  .showcase.e-bloccata .showcase-avanzamento { margin-top: 1.25rem; }
}

/* Sotto i 760px l'altezza utile e' poca e l'intestazione se la mangia: il
   titolo va su due righe e il testo introduttivo su quattro. Si stringe
   quello che si puo' e si toglie l'introduzione, che qui e' un di piu': il
   titolo dice gia' cosa sono le schede. */
@media (max-width: 760px) {
  .showcase { --carta: 260px; }

  .showcase.e-bloccata .showcase-head { margin-bottom: 1.25rem; }
  .showcase.e-bloccata .showcase-head .lead { display: none; }
  .showcase.e-bloccata .showcase-head h2 { font-size: var(--t-2xl); }
  .showcase.e-bloccata .showcase-head .gold-rule { margin: 1rem 0; }
  .showcase.e-bloccata .showcase-avanzamento { margin-top: 1.25rem; }

  /* Su schermi bassi ogni riga di testo la paga la fotografia. L'estratto e'
     la parte piu' sacrificabile: titolo, localita' e numeri dicono gia' tutto
     quello che serve per decidere se aprire la scheda. */

}

.showcase.e-bloccata .showcase-track {
  /* Si sposta di `--corsa`, non di `-100% + 100vw`: la percentuale
     dipenderebbe dalla larghezza calcolata dell'elemento, che e' proprio il
     dato di cui non ci si puo' fidare ovunque. */
  transform: translateX(calc(var(--avanzamento, 0) * -1 * var(--corsa)));
  will-change: transform;
}

.showcase.e-bloccata .showcase-avanzamento {
  display: block;
  position: relative;
  height: 2px;
  margin: 2rem var(--bordo) 0;
  background: var(--border);
}
.showcase.e-bloccata .showcase-avanzamento span {
  position: absolute;
  inset: 0 0 0 0;
  background: var(--accent);
  transform-origin: left center;
  transform: scaleX(var(--avanzamento, 0));
}

/* Dove il browser sa animare sulla posizione dello scorrimento, se ne occupa
   lui: gira sul compositor, non tocca il main thread e non perde un fotogramma
   nemmeno scorrendo di scatto. */
@supports (animation-timeline: view()) {
  .showcase.e-bloccata .showcase-track {
    animation: vetrina-scorri linear both;
    animation-timeline: --vetrina;
    /* `contain` e' esattamente il tratto in cui la sezione copre lo schermo,
       cioe' quello in cui il blocco resta incollato. */
    animation-range: contain 0% contain 100%;
  }
  .showcase.e-bloccata .showcase-avanzamento span {
    animation: vetrina-avanza linear both;
    animation-timeline: --vetrina;
    animation-range: contain 0% contain 100%;
  }
}

@keyframes vetrina-scorri {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-1 * var(--corsa))); }
}

@keyframes vetrina-avanza {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}


/* ==========================================================================
   Animazioni
   Attive solo se <html> porta la classe .js-anim, aggiunta dallo script inline
   in <head> quando: JS e' attivo, IntersectionObserver esiste e l'utente non ha
   chiesto di ridurre le animazioni. Senza quella classe nulla viene nascosto,
   quindi il sito resta perfettamente leggibile senza JS.
   ========================================================================== */

/* ---------- Rivelazione allo scroll ---------- */
.js-anim [data-reveal] {
  --reveal-delay: calc(var(--i, 0) * 90ms);
  opacity: 0;
  transform: translateY(22px);
  transition:
    opacity 900ms cubic-bezier(0.16, 1, 0.3, 1) var(--reveal-delay),
    transform 900ms cubic-bezier(0.16, 1, 0.3, 1) var(--reveal-delay);
}
.js-anim [data-reveal="fade"] { transform: none; }
.js-anim [data-reveal].is-visible { opacity: 1; transform: none; }

/* I passi del proprietario compaiono uno alla volta, non quasi insieme: il
   passo della cascata qui e' quasi il doppio di quello generale, perche' e'
   proprio la sequenza a raccontare che sono passi consecutivi. Vale dove il
   browser non ha le timeline di scorrimento; dove le ha, l'intervallo qui
   sotto ha la precedenza (un'animazione in corso batte una dichiarazione
   normale) e la cascata segue il dito invece del cronometro. */
.js-anim .passi-griglia > [data-reveal] {
  --reveal-delay: calc(var(--i, 0) * 170ms);
}

/* I tratti che uniscono i passi del percorso non compaiono: si tracciano.
   Ripiego senza timeline di scorrimento — il tratto segue la rivelazione del
   proprio passo. */
.js-anim .percorso-passo[data-reveal]::before {
  transform: scaleY(0);
  transition: transform 900ms cubic-bezier(0.22, 1, 0.36, 1);
}
.js-anim .percorso-passo[data-reveal].is-visible::before { transform: scaleY(1); }

@media (min-width: 900px) {
  .js-anim .percorso-passo[data-reveal]::before { transform: scaleX(0); }
  .js-anim .percorso-passo[data-reveal].is-visible::before { transform: scaleX(1); }
}

/* ---------- Parallax dell'hero ----------
   La fotografia scorre piu' lentamente della pagina. Due accorgimenti:

   1. Il movimento e' sul contenitore `.hero-media`, non sull'immagine: l'immagine
      ha gia' il proprio `transform` per lo zoom d'ingresso, e due animazioni sulla
      stessa proprieta' dello stesso elemento si escluderebbero a vicenda.
   2. Il contenitore e' piu' alto dell'hero, altrimenti scorrendo verso il basso
      si scoprirebbe una striscia vuota sul bordo superiore.

   Sta dentro `.js-anim`, quindi con `prefers-reduced-motion` non esiste: e' proprio
   il tipo di movimento che da' fastidio a chi soffre di disturbi vestibolari. */

@keyframes ev-parallax {
  from { transform: translateY(0); }
  to   { transform: translateY(15%); }
}

@supports (animation-timeline: scroll()) {
  .js-anim .hero-media {
    /* Il margine deve superare lo spostamento massimo, altrimenti a fondo
       corsa il bordo superiore si scopre. Lo spostamento e' il 15% dell'altezza
       del contenitore, che a sua volta e' il 140% dell'hero: 0,15 x 1,40 = 0,21,
       sotto il margine superiore di 0,22. */
    top: -22%;
    height: 140%;
    animation: ev-parallax linear both;
    /* `scroll(root)` e non `scroll()`: quest'ultimo vale `scroll(nearest)` e
       aggancerebbe .hero, che avendo `overflow: hidden` e' un contenitore di
       scorrimento a tutti gli effetti — ma non scorre mai, quindi la timeline
       resterebbe ferma a zero. */
    animation-timeline: scroll(root);
    /* Si esaurisce nel primo schermo di scorrimento: oltre, l'hero e' gia' via. */
    animation-range: 0 100vh;
  }
}

/* ---------- Variante nativa: animazioni guidate dallo scroll ----------
   Dove il browser supporta `animation-timeline: view()` la rivelazione smette di
   essere una transizione pilotata da JavaScript e diventa un'animazione legata
   alla posizione dell'elemento nello scrollport. Tre vantaggi concreti:

     - gira sul compositor, quindi non occupa il main thread (meglio per INP);
     - non dipende da callback: con lo scorrimento veloce nessun elemento resta
       indietro, perche' lo stato e' funzione della posizione, non di un evento;
     - il JavaScript dell'observer non viene nemmeno creato (vedi main.js).

   Resta tutto dentro `.js-anim`, quindi valgono ancora le due garanzie di prima:
   senza JavaScript non si nasconde nulla, e con `prefers-reduced-motion` la
   classe non viene aggiunta e le animazioni non esistono. */

@keyframes ev-reveal {
  from { opacity: 0; transform: translateY(56px) scale(0.97); }
  to   { opacity: 1; transform: none; }
}

@keyframes ev-reveal-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@supports (animation-timeline: view()) {
  .js-anim [data-reveal] {
    /* La transizione non serve piu': lo stato lo detta il keyframe.
       `both` tiene l'elemento allo stato iniziale prima del range e a quello
       finale dopo, cosi' non ricompare mai a meta'. */
    transition: none;
    animation: ev-reveal linear both;
    animation-timeline: view();
    /* L'intervallo resta dentro la fase `entry`, cioe' il tratto in cui
       l'elemento sta entrando dal basso. Usare `cover` come estremo finale
       spalmava la comparsa su oltre 700px di scorrimento: tecnicamente
       un'animazione, in pratica una velatura che l'occhio non legge.
       Qui si apre e si chiude mentre l'elemento entra, quindi si nota.

       Lo scaglionamento sposta l'intervallo in avanti in base a --i: i figli
       successivi completano un po' piu' tardi e si ottiene la cascata senza
       ritardi temporali, che su una timeline di scroll non esistono. Il
       moltiplicatore e' basso di proposito, per non sforare il 100%. */
    animation-range:
      entry calc(14% + var(--i, 0) * 2.5%)
      entry calc(56% + var(--i, 0) * 2.5%);
  }

  .js-anim [data-reveal="fade"] {
    animation-name: ev-reveal-fade;
  }

  /* --- I passi del proprietario, uno alla volta ---
     Sopra i 900px le quattro tessere stanno sulla stessa riga: hanno quindi la
     stessa geometria e la stessa timeline, e senza sfasamento comparirebbero
     tutte nello stesso fotogramma. Lo sfasamento e' `--i` — l'intervallo di
     ciascuna comincia dove finisce quello della precedente — e il passo e'
     ampio, 21%, non i 2,5% della rivelazione generale: li' serve appena a
     smussare un'entrata di gruppo, qui la sequenza *e'* il contenuto.

     La finestra di ognuna e' stretta (26%) perche' le quattro insieme stanno
     dentro il 100% dell'intervallo `entry`: l'ultima si apre al 63% e si chiude
     all'89%, quindi e' finita prima che la griglia abbia finito di entrare.
     Chi torna indietro con la rotella le vede sparire nell'ordine inverso, che
     e' il modo in cui si capisce che stanno seguendo lo scorrimento e non un
     cronometro partito una volta sola.

     Sotto i 900px la griglia e' a una o due colonne e le tessere si incontrano
     gia' una per volta scorrendo: lo sfasamento le farebbe soltanto tardare, e
     l'ultima comparirebbe quando e' quasi tutta passata. Li' resta buono
     l'intervallo generale. */
  @media (min-width: 900px) {
    .js-anim .passi-griglia > [data-reveal] {
      animation-range:
        entry calc(11% + var(--i, 0) * 21%)
        entry calc(37% + var(--i, 0) * 21%);
    }
  }

  /* Ogni tratto si disegna quando si arriva al proprio passo: la sequenza si
     costruisce sotto gli occhi invece di essere gia' li'. Lo scaglionamento
     con `--i` serve sopra i 900px, dove i quattro passi sono alla stessa
     altezza e senza sfasamento partirebbero tutti insieme. */
  .js-anim .percorso-passo::before {
    animation: ev-linea-verticale linear both;
    animation-timeline: view();
    animation-range:
      entry calc(32% + var(--i, 0) * 6%)
      entry calc(82% + var(--i, 0) * 6%);
  }
  @media (min-width: 900px) {
    .js-anim .percorso-passo::before { animation-name: ev-linea-orizzontale; }
  }

  /* I numeri si riempiono al passaggio, scaglionati da `--i` come le schede:
     la sequenza si legge anche stando fermi a meta' sezione. */
  .js-anim .percorso-nodo {
    animation: ev-nodo linear both;
    animation-timeline: view();
    animation-range:
      entry calc(34% + var(--i, 0) * 6%)
      entry calc(78% + var(--i, 0) * 6%);
  }

  /* Con la timeline non serve piu' la classe applicata dall'observer. */
  .js-anim [data-reveal].is-visible {
    opacity: 1;
    transform: none;
  }
}

@keyframes ev-linea-verticale {
  from { transform: scaleY(0); }
  to   { transform: scaleY(1); }
}

@keyframes ev-linea-orizzontale {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

@keyframes ev-nodo {
  from { background-color: var(--bg); color: var(--accent); border-color: var(--border); }
  to   { background-color: var(--accent-solid); color: var(--on-accent); border-color: var(--accent-solid); }
}

/* Ripiego senza timeline: il numero si riempie con la rivelazione del passo. */
.js-anim .percorso-passo[data-reveal].is-visible .percorso-nodo {
  background-color: var(--accent-solid);
  color: var(--on-accent);
  border-color: var(--accent-solid);
}

/* Indice progressivo per scaglionare i figli di un contenitore */
.js-anim [data-stagger] > :nth-child(1) { --i: 0; }
.js-anim [data-stagger] > :nth-child(2) { --i: 1; }
.js-anim [data-stagger] > :nth-child(3) { --i: 2; }
.js-anim [data-stagger] > :nth-child(4) { --i: 3; }
.js-anim [data-stagger] > :nth-child(5) { --i: 4; }
.js-anim [data-stagger] > :nth-child(6) { --i: 5; }
.js-anim [data-stagger] > :nth-child(7) { --i: 6; }
.js-anim [data-stagger] > :nth-child(8) { --i: 7; }
.js-anim [data-stagger] > :nth-child(9) { --i: 8; }
.js-anim [data-stagger] > :nth-child(10) { --i: 9; }
.js-anim [data-stagger] > :nth-child(11) { --i: 10; }
.js-anim [data-stagger] > :nth-child(12) { --i: 11; }

/* ---------- Sipario d'ingresso ----------
   Schermo nero con logo e claim, poi si dissolve sulla home.

   Il movimento e' tutto in CSS: JavaScript si limita ad aggiungere la classe
   `ev-intro` su <html> e a togliere il blocco dello scorrimento alla fine.
   Cosi', se lo script si interrompe a meta', il sipario se ne va lo stesso —
   l'animazione finale termina su `visibility: hidden`, che smette anche di
   intercettare i click.

   Le due durate sono dichiarate qui e rilette da main.js: un solo posto da
   toccare per cambiare il ritmo. Vanno tenute in millisecondi. */
:root {
  --intro-attesa: 1700ms;   /* dal caricamento all'inizio della dissolvenza */
  --intro-uscita: 620ms;    /* durata della dissolvenza */
}

/* Senza la classe su <html> il sipario non esiste. */
.intro { display: none; }

/* Niente scorrimento mentre il sipario e' alzato: sotto c'e' la home che si
   sta preparando, e uno scroll a vuoto tradirebbe il trucco. */
html.ev-intro { overflow: hidden; }

html.ev-intro .intro {
  display: grid;
  place-items: center;
  position: fixed;
  inset: 0;
  z-index: 1000;          /* sopra header (100) e banner cookie (200) */
  background: #0a0a0a;
  animation: ev-intro-esce cubic-bezier(0.65, 0, 0.35, 1) both;
  animation-duration: var(--intro-uscita);
  animation-delay: var(--intro-attesa);
}

.intro-inner {
  display: grid;
  justify-items: center;
  gap: 1.6rem;
  padding: 2rem;
  text-align: center;
  /* Il gruppo si allarga appena mentre il nero svanisce: da' l'impressione
     che il sipario si apra invece di spegnersi. */
  animation: ev-intro-allarga cubic-bezier(0.65, 0, 0.35, 1) both;
  animation-duration: var(--intro-uscita);
  animation-delay: var(--intro-attesa);
}

.intro-logo {
  width: min(400px, 66vw);
  height: auto;
  animation: ev-intro-logo 560ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

.intro-riga {
  display: block;
  width: min(260px, 52vw);
  height: 1px;
  background: linear-gradient(90deg, transparent, #dcbb4e 22%, #dcbb4e 78%, transparent);
  transform-origin: center;
  animation: ev-intro-riga 520ms cubic-bezier(0.16, 1, 0.3, 1) 340ms both;
}

.intro-claim {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--t-2xl);
  font-weight: 400;
  letter-spacing: var(--tr-titolo);
  color: #f4efe4;
  animation: ev-intro-claim 620ms cubic-bezier(0.16, 1, 0.3, 1) 560ms both;
}

@keyframes ev-intro-logo {
  from { opacity: 0; transform: translateY(14px) scale(0.96); }
  to   { opacity: 1; transform: none; }
}

@keyframes ev-intro-riga {
  from { transform: scaleX(0); opacity: 0; }
  to   { transform: scaleX(1); opacity: 1; }
}

@keyframes ev-intro-claim {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

@keyframes ev-intro-allarga {
  from { transform: scale(1); }
  to   { transform: scale(1.06); }
}

/* `visibility` non si interpola: resta `visible` per tutta l'animazione e
   scatta a `hidden` sull'ultimo fotogramma. E' quello che serve — il sipario
   smette di coprire e di ricevere click anche se il JS non arriva a togliere
   la classe. */
@keyframes ev-intro-esce {
  from { opacity: 1; visibility: visible; }
  to   { opacity: 0; visibility: hidden; }
}

/* ---------- Sequenza di ingresso della home ---------- */
/* Lieve zoom all'indietro sulla fotografia dell'hero */
.js-anim .hero-media img,
.js-anim .hero-media video {
  transform: scale(1.07);
  /* L'opacita' resta nella lista: sul video serve per la comparsa in
     dissolvenza, e sulla fotografia non fa nulla. */
  transition: transform 2200ms cubic-bezier(0.16, 1, 0.3, 1),
              opacity 900ms ease;
}
.js-anim.is-loaded .hero-media img,
.js-anim.is-loaded .hero-media video { transform: none; }

/* Testo dell'hero: comparsa scaglionata dall'alto verso il basso.
   Non usa [data-reveal] perche' non dipende dallo scroll ma dal caricamento. */
.js-anim .hero-inner > * {
  opacity: 0;
  transform: translateY(26px);
  transition:
    opacity 950ms cubic-bezier(0.16, 1, 0.3, 1) var(--d, 0ms),
    transform 950ms cubic-bezier(0.16, 1, 0.3, 1) var(--d, 0ms);
}
.js-anim .hero-inner > *:nth-child(1) { --d: 240ms; }
.js-anim .hero-inner > *:nth-child(2) { --d: 360ms; }
.js-anim .hero-inner > *:nth-child(3) { --d: 480ms; }
.js-anim .hero-inner > *:nth-child(4) { --d: 600ms; }
.js-anim.is-loaded .hero-inner > * { opacity: 1; transform: none; }

/* Header: solo opacita'. Un transform su un elemento sticky e' un rischio
   inutile, e qui non aggiungerebbe nulla. */
.js-anim .site-header { opacity: 0; transition: opacity 800ms ease 120ms; }
.js-anim.is-loaded .site-header { opacity: 1; }

/* ---------- Micro-interazioni ---------- */
.property-card-body h3 a,
.service-card { will-change: auto; }

/* Sicurezza: se la preferenza cambia dopo il caricamento, mostra tutto. */
@media (prefers-reduced-motion: reduce) {
  .js-anim [data-reveal],
  .js-anim .hero-inner > *,
  .js-anim .site-header {
    opacity: 1 !important;
    transform: none !important;
  }
  .js-anim .hero-media img,
  .js-anim .hero-media video { transform: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  /* Ridondante — senza `js-anim` la classe `ev-intro` non viene mai aggiunta —
     ma copre il caso in cui la preferenza cambi a pagina gia' aperta. */
  .intro { display: none !important; }
  html.ev-intro { overflow: visible !important; }

  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}


@media (min-width: 900px) and (hover: hover) {
  /* Su schermo tattile `:hover` resta appiccicato dopo il tocco: li' la
     tendina la comanda solo il pulsante. */
  .ha-tendina:hover > .tendina {
    opacity: 1;
    visibility: visible;
    translate: -50% 0;
  }
}



/* ==========================================================================
   Pop-up «Prenota ora» (solo home, una volta per visitatore)
   Un <dialog> modale: il browser lo mette nel top layer, sopra header e
   banner cookie senza gare di z-index. Lo sfondo e' un velo, non un muro:
   il sito sotto deve restare riconoscibile, cosi' e' chiaro che basta
   chiudere per tornarci.
   ========================================================================== */
.popup-prenota {
  width: min(28rem, calc(100% - 2rem));
  max-height: calc(100dvh - 4rem);
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 12px 48px rgba(0, 0, 0, 0.35);
  overflow: auto;
}
.popup-prenota::backdrop {
  background: rgba(10, 10, 10, 0.45);
}
.popup-prenota[open] { animation: popup-entra 320ms cubic-bezier(0.2, 0.7, 0.2, 1) both; }
@keyframes popup-entra {
  from { opacity: 0; transform: translateY(12px) scale(0.98); }
}
@media (prefers-reduced-motion: reduce) {
  .popup-prenota[open] { animation: none; }
}

.popup-chiudi-form { position: absolute; top: 0.5rem; right: 0.5rem; margin: 0; z-index: 1; }
/* 48px: la misura minima per un dito, e qui e' l'unica via d'uscita a parte
   il tasto Esc, che sul telefono non c'e'. */
.popup-chiudi {
  display: grid; place-items: center;
  width: 48px; height: 48px;
  padding: 0;
  border: 0; border-radius: 50%;
  background: rgba(10, 10, 10, 0.6);
  color: #f7f4ee;
  cursor: pointer;
  transition: background-color var(--transition);
}
.popup-chiudi:hover, .popup-chiudi:focus-visible { background: rgba(10, 10, 10, 0.85); }
.popup-chiudi svg { width: 26px; height: 26px; }

.popup-foto {
  display: block;
  width: 100%; height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

.popup-corpo { padding: 1.5rem 1.5rem 1.75rem; text-align: center; }
.popup-titolo {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--t-2xl);
  font-weight: 400;
  line-height: var(--lh-titolo);
  letter-spacing: var(--tr-titolo);
  color: var(--text);
}
.popup-titolo-en {
  margin: 0.5rem 0 0;
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--t-lg);
  color: var(--text-muted);
}
.popup-cta { margin-top: 1.5rem; }
.popup-cta-en { opacity: 0.85; }


/* ---------- Social nel footer ----------
   Icone senza riquadro, come il resto del footer. Area di tocco da 44px anche
   se il disegno e' piu' piccolo: sono sei bersagli fitti, e sul telefono un
   dito ne prenderebbe due. Niente sottolineatura: sotto un'icona non si legge. */
.footer-social {
  display: flex; flex-wrap: wrap; gap: 0.25rem;
  margin: 1.25rem 0 0 -0.6rem; padding: 0; list-style: none;
}
.footer-col .footer-social li { margin: 0; }
.footer-col .footer-social a {
  display: grid; place-items: center;
  width: 44px; height: 44px;
  color: var(--text-muted);
  text-decoration: none;
  transition: color var(--transition);
}
.footer-col .footer-social a::after { content: none; }
.footer-col .footer-social a:hover,
.footer-col .footer-social a:focus-visible { color: var(--accent); }
.footer-social svg { width: 20px; height: 20px; }
