/* ============================================================
   Agenzia Immobiliare Firenze: stile principale

   CARATTERE: Montserrat, ospitato sul nostro sito.
   I file .woff2 stanno in /vendor/fonts e NON vengono chiesti a Google. Il
   motivo non e' tecnico ma legale: caricare un font dal CDN di Google
   significa mandare a Google l'indirizzo IP di ogni visitatore, mentre la
   nostra cookie policy dichiara che nessun dato viene condiviso con terze
   parti. Ospitandolo qui la dichiarazione resta vera (ed e' anche piu'
   veloce: nessuna connessione a un secondo dominio).
   E' un font variabile: un solo file copre tutti i pesi da 100 a 900.

   PALETTE DELLA DEMO: ROSSO FIRENZE #8A1C1C E CREMA #F8F3EA (22/09/2026).
   Il foglio viene da CASAREALE, che era bianco e blu con UN SOLO blu a
   tinta unita. La regola e' rimasta identica, e' cambiato il colore: un solo
   rosso, --primario, a tinta unita, niente varianti chiare o scure. Le
   variabili si chiamavano --navy: rinominate in --primario perche' un
   «navy» rosso avrebbe ingannato chiunque le leggesse.

   IL CREMA E' IL SECONDO FONDO, non un secondo colore: sta dove CASAREALE
   usava il grigio chiarissimo (--bg-alt, le fasce alterne delle sezioni).
   Inchiostro e bordi sono stati scaldati di conseguenza (--ink, --line):
   un grigio freddo sul crema sembra sporco.

   LA FASCETTA «VENDUTO» NON E' PIU' ROSSA. In CASAREALE era l'unico rosso
   del sito, proprio per spiccare sul blu; qui il rosso e' il marchio, e una
   fascetta rossa si confonderebbe con tutte le altre. E' diventata
   antracite (--venduto): resta un colore di stato, distinto dal marchio.

   DOVE SERVIVA UN SECONDO COLORE SI INVERTE, non si schiarisce. Un pulsante
   rosso al passaggio del mouse diventa bianco con testo e bordo rossi, e
   viceversa.

   RESTANO FUORI DALLA PALETTE, di proposito, i colori che non decidiamo noi:
   il verde di WhatsApp, il viola di Instagram e la scala colore della classe
   energetica (--ok/--warn e `energyBadgeColor`), che e' normata.
   ============================================================ */

/* Montserrat variabile: sottoinsiemi latin e latin-ext, gli unici che servono
   a un sito in italiano. `font-display: swap` mostra subito il testo con il
   carattere di sistema e lo sostituisce appena il font e' pronto: nessuna
   pagina bianca in attesa. */
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/vendor/fonts/montserrat-latin.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: 'Montserrat';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/vendor/fonts/montserrat-latin-ext.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;
}
@font-face {
  font-family: 'Montserrat';
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('/vendor/fonts/montserrat-italic-latin.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: 'Montserrat';
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('/vendor/fonts/montserrat-italic-latin-ext.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;
}

:root {
  /* IL BLU. Uno solo, su tutto il sito e su tutto il gestionale.
     Gli alias qui sotto puntano allo stesso valore: se da qualche parte
     restasse un --primario-soft dimenticato, resta comunque questo blu.
     Non esistono --red, --red-dark, --red-light: sono stati tolti il
     01/09/2026 e non vanno rimessi (vedi la nota in cima al file). */
  --primario: #8A1C1C;
  --primario-soft: #8A1C1C;
  --primario-2: #8A1C1C;

  /* Velatura del blu sopra le fotografie (etichette sulle immagini, fondo
     dell'immagine di apertura). Non e' un secondo blu: e' lo stesso colore,
     con un'unica opacita' usata dappertutto, cosi' le etichette hanno la
     stessa intensita' su ogni foto. */
  --primario-velo: rgba(138, 28, 28, .88);

  --ink: #2A2522;
  --ink-soft: #6B625A;
  --line: #E9E1D4;
  --bg: #FFFFFF;
  --bg-alt: #F8F3EA;
  --wa: #25D366;
  --wa-dark: #1EBE5A;
  --ig: #C13584;
  /* L'ORO DELLE STELLE DELLE RECENSIONI (09/09/2026, richiesta del
     committente: «lo stesso stile di stelle di Google»).
     E' il giallo con cui Google disegna le stelle piene sulle schede
     attivita' e nei risultati di ricerca. Prima le stelle erano `--primario`,
     cioe' del colore del sito: leggevano bene ma non si riconoscevano a
     colpo d'occhio come un voto, che e' l'unica cosa che una stella deve
     fare.

     >>> NON E' UN COLORE DELLA PALETTE DEL SITO, ED E' VOLUTO: e' una
     citazione. Va usato SOLO per le stelle piene delle recensioni. Metterlo
     su un pulsante o su un titolo introdurrebbe un terzo colore nel sito e
     farebbe perdere alla stella il suo significato.

     LE STELLE VUOTE RESTANO `--line` (grigio chiarissimo), non una versione
     smorta dell'oro: sono lo sfondo del voto, non parte del voto.

     Il contrasto di questo giallo sul bianco e' basso, e non e' un problema
     di accessibilita': ogni gruppo di stelle e' decorativo
     (`aria-hidden="true"`) e il voto vero sta scritto accanto e nell'
     `aria-label` («5 stelle su 5»), che e' quello che leggono i lettori di
     schermo. Chi non distingue il giallo legge il numero. */
  --stella-oro: #FBBC04;
  /* `--ig-dark` (#A02B6D) E' STATA TOLTA il 07/09/2026: serviva solo al fondo
     del pulsante Instagram al passaggio del mouse, che ora porta il gradiente
     e non cambia piu' colore (il perche' e' sotto, su `.float-ig`). */
  /* IL GRADIENTE UFFICIALE DI INSTAGRAM, in una variabile SUA e non dentro
     `--ig` (07/09/2026, richiesta del committente: «il logo originale con i
     veri colori e il giusto gradient»).
     `--ig` NON si puo' sostituire con questo: e' usata anche come
     `border-color` sulla targhetta del video in homepage, e un bordo non
     accetta un gradiente — la targhetta perderebbe il contorno. Le due
     convivono: il colore piatto dove serve un colore, il gradiente dove
     serve il marchio. I cinque punti sono quelli del marchio (giallo,
     arancio, magenta, viola, blu) a 45 gradi, cioe' dal basso a sinistra
     verso l'alto a destra come nell'originale. */
  --ig-gradiente: linear-gradient(45deg,
    #FEDA75 0%, #FA7E1E 25%, #D62976 50%, #962FBF 75%, #4F5BD5 100%);
  --ok: #1E7D32;
  --warn: #B77400;

  /* ============================================================
     L'UNICO ROSSO DEL SITO: LA FASCETTA «VENDUTO».

     La palette e' bianco e blu e resta tale (vedi la nota in cima al file):
     questo NON e' il ritorno del rosso dei pulsanti e dei collegamenti, che
     restano blu. E' un colore di stato, come il verde di --ok e l'arancio di
     --warn, e ha un compito solo: far capire a colpo d'occhio, scorrendo
     l'elenco, quali immobili sono ancora in vendita e quali no. Richiesta
     esplicita del committente del 07/09/2026 («in modo da vedere visivamente
     la differenza tra un immobile da vendere e uno venduto»): finche' la
     fascetta era blu come quella «Vendita», la differenza si vedeva solo
     leggendo la parola.

     NON VA USATO PER NIENT'ALTRO. Un secondo elemento rosso in pagina e la
     fascetta smette di essere l'eccezione che si nota.

     Il valore e' un rosso scuro, non acceso: sul bianco della scheda regge il
     rapporto di contrasto 4.5:1 richiesto dalle WCAG per il testo bianco
     dentro la fascetta, cosa che un rosso vivo non farebbe.
     ============================================================ */
  --venduto: #33302D;

  --radius: 12px;
  /* Altezza della barra di navigazione. Sta qui e non scritta a mano in tre
     punti perche' l'apertura della homepage ci si incastra sotto: la
     fotografia sale di tanto quanto la barra e' alta, e il testo scende
     dell'altrettanto. Due numeri diversi vorrebbero dire o una striscia
     bianca sopra la foto o il titolo mezzo coperto dal menu. */
  --altezza-navbar: 96px;
  --shadow: 0 2px 10px rgba(58, 22, 18, .10);
  --shadow-lg: 0 10px 34px rgba(58, 22, 18, .16);
  --container: 1180px;
  --font: 'Montserrat', system-ui, -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
/* L'ATTRIBUTO `hidden` DEVE VINCERE SEMPRE, ED E' UNA CORREZIONE, NON UNA
   precauzione. Il browser lo applica con un `display: none` di serie, che
   e' il piu' debole di tutti: basta una qualunque regola di questo foglio
   che dichiari `display: flex` o `display: block` sullo stesso elemento e
   l'elemento resta visibile pur essendo marcato come nascosto. E' cosi' che
   nel gestionale compariva un rettangolo scuro vuoto sopra al grafico delle
   visite, e che sulla mappa il contatore delle caratteristiche mostrava uno
   zero che non doveva esserci. Ogni elemento che il JavaScript accende e
   spegne con `.hidden = true/false` dipende da questa riga. */
[hidden] { display: none !important; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--font);
  font-optical-sizing: auto;
  color: var(--ink);
  background: var(--bg);
  line-height: 1.65;
  font-size: 16px;
}
/* Moduli, pulsanti e menu a tendina non ereditano il carattere da soli. */
input, textarea, select, button { font-family: inherit; }
img { max-width: 100%; display: block; }
a { color: var(--primario); text-decoration: none; }
a:hover { text-decoration: underline; }
h1, h2, h3, h4 { line-height: 1.25; color: var(--primario); font-weight: 700; }
ul, ol { list-style-position: inside; }

.container { max-width: var(--container); margin: 0 auto; padding: 0 20px; }
.center { text-align: center; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--primario); color: #fff; padding: 10px 18px; border-radius: 0 0 8px 0;
}
.skip-link:focus { left: 0; }

/* ---------- Bottoni ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 12px 22px; border-radius: 999px; border: 2px solid transparent;
  font-weight: 600; font-size: .97rem; cursor: pointer; text-decoration: none !important;
  transition: background .18s, color .18s, border-color .18s, transform .12s;
  line-height: 1.2;
}
.btn:active { transform: scale(.97); }
/* SI INVERTE, NON SI SCHIARISCE. Con una palette di due colori il passaggio
   del mouse non puo' essere "lo stesso blu un po' piu' scuro": sarebbe il
   secondo blu che questa palette esiste per evitare. Pieno diventa vuoto e
   vuoto diventa pieno. Il bordo e' gia' dichiarato trasparente su `.btn`,
   quindi nessun pulsante cambia misura passandoci sopra. */
.btn-primary { background: var(--primario); color: #fff; border-color: var(--primario); }
.btn-primary:hover { background: #fff; color: var(--primario); }
.btn-light { background: #fff; color: var(--primario); border-color: #fff; }
.btn-light:hover { background: transparent; color: #fff; border-color: #fff; }
.btn-outline { background: transparent; color: var(--primario); border-color: var(--primario); }
.btn-outline:hover { background: var(--primario); color: #fff; }
.btn-whatsapp { background: var(--wa); color: #fff; }
.btn-whatsapp:hover { background: var(--wa-dark); }
/* `.btn-openhouse` e' stato cancellato il 01/09/2026 insieme al pulsante
   "Openhouse, prenota un appuntamento": vedi la nota in src/helpers.js. */
/* SOPRA IL BLU IL PULSANTE PRINCIPALE SI INVERTE.
   Con la palette a due colori un `.btn-primary` blu sopra una fascia blu
   sparisce: prima non capitava perche' il pulsante era rosso. Su ogni
   superficie blu del sito il pieno diventa bianco con la scritta blu, e al
   passaggio del mouse si svuota lasciando bordo e testo bianchi. */
.hero .btn-primary,
.page-hero .btn-primary,
.cta-band .btn-primary,
.oh-hero .btn-primary,
.cookie-banner .btn-primary,
.site-footer .btn-primary {
  background: #fff; color: var(--primario); border-color: #fff;
}
.hero .btn-primary:hover,
.page-hero .btn-primary:hover,
.cta-band .btn-primary:hover,
.oh-hero .btn-primary:hover,
.cookie-banner .btn-primary:hover,
.site-footer .btn-primary:hover {
  background: transparent; color: #fff; border-color: #fff;
}
/* NELL'APERTURA I DUE PULSANTI SONO UGUALI, ED E' VOLUTO.
   Prima erano uno pieno e uno vuoto, per indicare l'azione principale. Sopra
   una fotografia in movimento il rettangolo bianco pieno era una macchia che
   spegneva l'immagine, e fra "guarda gli immobili" e "cerca sulla mappa" non
   c'e' una scelta preferibile: sono due modi di fare la stessa cosa.
   Entrambi partono trasparenti col bordo bianco e si riempiono al passaggio
   del mouse, secondo la regola dell'inversione valida su tutto il sito. */
/* QUI C'ERANO LE DUE REGOLE DEL PULSANTE CHIARO DELL'APERTURA
   (`.hero-actions .btn-light`, normale e al passaggio del mouse: trasparente
   col bordo bianco, che si riempiva di bianco al passaggio). Tolte il
   22/09/2026 insieme al pulsante, che il committente ha fatto sparire
   dall'apertura su tutti i dispositivi. Erano l'unico punto del sito che
   usava quel selettore. Se un domani il pulsante tornasse, il posto e' questo:
     .hero-actions .btn-light { background: transparent; color: #fff; border-color: #fff; }
     .hero-actions .btn-light:hover { background: #fff; color: var(--primario); border-color: #fff; } */
.btn-lg { padding: 15px 30px; font-size: 1.05rem; }
.btn-sm { padding: 8px 16px; font-size: .88rem; }
.btn-block { width: 100%; }

/* ---------- Topbar ---------- */
.topbar { background: var(--primario); color: #fff; font-size: .82rem; }
.topbar-inner { display: flex; align-items: center; gap: 22px; min-height: 36px; }
.topbar-item { display: inline-flex; align-items: center; gap: 6px; }
.topbar-item a { color: #fff; display: inline-flex; align-items: center; gap: 6px; }
.topbar-social { margin-left: auto; display: inline-flex; gap: 14px; }
.topbar-social a { color: #fff; display: inline-flex; }
.topbar-social a:hover { text-decoration: none; }

/* ---------- Navbar ---------- */
.site-header {
  position: sticky; top: 0; z-index: 100; background: #fff; box-shadow: var(--shadow);
  transition: background-color .28s ease, box-shadow .28s ease;
}
.navbar-inner { display: flex; align-items: center; justify-content: space-between; min-height: var(--altezza-navbar); gap: 20px; }

/* ============================================================
   LA BARRA SOPRA LA FOTOGRAFIA (solo homepage)
   ============================================================
   All'apertura della homepage la barra deve sembrare parte dell'immagine:
   niente fondo bianco, scritte e marchio in bianco. Appena si scorre oltre
   l'apertura torna quella di sempre, bianca con le scritte blu.

   L'INTERRUTTORE E' LA CLASSE `compatta`, che main.js aggiunge e toglie
   guardando dove e' finito il bordo inferiore dell'apertura. Senza
   JavaScript la barra resta trasparente per tutta la pagina: sarebbe
   illeggibile sul bianco, quindi la trasparenza vale solo dopo che il
   copione ha confermato di essere partito, aggiungendo `js-attivo` a
   <html>. E' il motivo per cui la regola qui sotto e' scritta al contrario
   di come verrebbe naturale.

   LA BARRETTA BLU IN CIMA (indirizzo e telefoni) NON CAMBIA: e' gia' blu,
   quindi si legge come il bordo superiore della fotografia. Diventarla
   trasparente vorrebbe dire due numeri di telefono bianchi sopra un cielo
   bianco. */
.js-attivo .site-header-suFoto:not(.compatta) {
  background: transparent; box-shadow: none;
}
/* UNA VELATURA SOTTO ALLA SOLA BARRA, dal 01/09/2026.
   Finche' la fotografia aveva addosso il velo blu all'82%, le voci bianche
   del menu si leggevano ovunque. Tolto quel velo (vedi `.hero-velo`), sopra
   restano il cielo e le nuvole, cioe' bianco su bianco: le voci del menu
   sparivano contro le zone chiare. Qui la velatura e' alta quanto la barra e
   svanisce del tutto sul suo bordo inferiore: continua visivamente la
   barretta blu qui sopra, non tocca la fotografia sotto, e sparisce insieme
   alla trasparenza appena la barra torna bianca. */
.js-attivo .site-header-suFoto:not(.compatta) .navbar {
  background: linear-gradient(to bottom, rgba(11, 20, 36, .5), rgba(11, 20, 36, 0));
}
/* Il pulsante WhatsApp resta verde: e' l'unica voce del menu che non fa parte
   dell'identita' del sito e non segue la regola dell'inversione. */
.js-attivo .site-header-suFoto:not(.compatta) .main-nav > a:not(.nav-cta) {
  color: #fff; text-shadow: 0 1px 8px rgba(11, 20, 36, .6);
}
/* Anche il marchio chiaro e' bianco: sopra una nuvola si perdeva.
   DUE OMBRE SOVRAPPOSTE, non una piu' forte. Il marchio e' fatto di tratti
   sottili (il profilo della casa, il sottotitolo in maiuscoletto): una sola
   ombra larga li circonda di grigio senza staccarli dal cielo. La prima e'
   stretta e serve a disegnare il contorno, la seconda e' larga e stacca
   l'insieme dallo sfondo. Sono state rinforzate il 07/09/2026 insieme
   all'ingrandimento del marchio: piu' grande vuol dire piu' superficie
   bianca sopra il cielo, quindi piu' occasioni di perdersi. */
.js-attivo .site-header-suFoto:not(.compatta) .brand-logo-chiaro {
  filter: drop-shadow(0 0 2px rgba(11, 20, 36, .65)) drop-shadow(0 2px 14px rgba(11, 20, 36, .7));
}
.js-attivo .site-header-suFoto:not(.compatta) .main-nav > a:not(.nav-cta):hover { background: #fff; color: var(--primario); }
.js-attivo .site-header-suFoto:not(.compatta) .nav-toggle span { background: #fff; }

/* Il marchio: sopra la foto quello bianco, sul bianco quello blu.
   Sono due immagini nello stesso posto (vedi il commento in `layout.js`): qui
   si sceglie solo quale far vedere.

   LE DUE CLASSI INSIEME, `.brand-logo.brand-logo-chiaro`, NON SONO UN VEZZO.
   Con la sola `.brand-logo-chiaro` la regola perdeva: `.brand-logo` — che
   dichiara `display: block` — sta piu' avanti nel foglio e a parita' di peso
   vince l'ultima. Risultato: appena la barra tornava bianca comparivano
   ENTRAMBI i marchi, quello blu e quello bianco (invisibile sul bianco, ma
   largo quanto l'altro), e il menu si spostava a destra. */
.brand-logo.brand-logo-chiaro { display: none; }
.js-attivo .site-header-suFoto:not(.compatta) .brand-logo.brand-logo-scuro { display: none; }
.js-attivo .site-header-suFoto:not(.compatta) .brand-logo.brand-logo-chiaro { display: block; }
.brand { display: inline-flex; align-items: center; gap: 12px; text-decoration: none !important; color: var(--primario); }
/* Il marchio è un'immagine unica (casa + nome): width/height sono dichiarati
   nell'HTML per evitare lo spostamento del contenuto durante il caricamento. */
.brand-logo { display: block; width: auto; max-width: 100%; }

/* ============================================================
   IL MARCHIO E' PIU' GRANDE DI PRIMA (07/09/2026)
   ============================================================
   Richiesta del committente: «il logo va visualizzato piu' in grande, in modo
   che si legga bene anche il testo».

   >>> NON ERA SGRANATO, ERA PICCOLO. Due cose diverse, e la differenza conta
   perche' porta a due rimedi opposti. Il file sorgente e' 408 x 336 pixel e
   veniva mostrato alto 52px, cioe' largo 63: a quella misura la scritta
   "CASAREALE" dentro al marchio era alta dieci pixel e il sottotitolo
   "AGENZIA IMMOBILIARE" quattro. Illeggibile, ma nitido: 408 pixel veri
   distribuiti su 63 sono una riduzione di sei volte, molto piu' della
   soglia oltre cui un'immagine perde definizione anche sugli schermi
   Retina. Ingrandire era quindi la mossa giusta; se il file fosse stato
   davvero sgranato, ingrandirlo avrebbe peggiorato le cose.

   LE MISURE DI OGGI. Il marchio in barra e' alto 76px, cioe' largo 92: la
   scritta "CASAREALE" arriva a quindici pixel e il sottotitolo a sei, che e'
   il minimo per leggerlo. Anche cosi' il file sorgente e' ancora quattro
   volte piu' grande di quanto serve su uno schermo ad alta densita': c'e'
   margine, non si e' andati "al limite".

   >>> IL LIMITE VERO NON E' LA RISOLUZIONE, E' LA FORMA DEL MARCHIO. E' un
   lockup verticale (casa sopra, nome sotto, sottotitolo in fondo) largo poco
   piu' di quanto e' alto: in una barra di navigazione, che e' una striscia
   orizzontale, il sottotitolo non potra' mai diventare grande senza far
   crescere la barra a dismisura. Per guadagnare davvero servirebbe una
   VERSIONE ORIZZONTALE del marchio (casa a sinistra, nome e sottotitolo a
   destra): a parita' di altezza della barra il testo raddoppierebbe. E' una
   cosa da chiedere a chi ha disegnato il marchio, non da ritagliare qui.

   LA BARRA E' CRESCIUTA DI CONSEGUENZA, da 74 a 96px (--altezza-navbar).
   Quella variabile non decora: l'apertura della homepage e quelle di
   /immobili, /vendi-casa e delle due pagine nuove ci si incastrano sotto con
   un margine negativo pari alla sua altezza. Cambiarla qui aggiusta tutto
   insieme; scrivere 96 a mano in un punto solo avrebbe prodotto una striscia
   bianca sopra le fotografie. */
.brand-logo-nav { height: 76px; }
.brand-logo-footer { height: 84px; }
.brand-logo-card { height: 72px; }


.main-nav { display: flex; align-items: center; gap: 4px; }
.main-nav a {
  color: var(--ink); font-weight: 600; font-size: .95rem;
  padding: 9px 13px; border-radius: 8px; text-decoration: none !important;
}
.main-nav a:hover { color: var(--primario); background: var(--bg-alt); }
.main-nav a.active { color: var(--primario); }
.main-nav a.nav-cta {
  background: var(--wa); color: #fff; border-radius: 999px; padding: 9px 18px; margin-left: 8px;
  display: inline-flex; align-items: center; gap: 7px;
}
.main-nav a.nav-cta:hover { background: var(--wa-dark); color: #fff; }

.nav-toggle {
  display: none; flex-direction: column; gap: 5px; background: none; border: 0;
  padding: 10px; cursor: pointer;
}
.nav-toggle span { width: 24px; height: 3px; background: var(--primario); border-radius: 2px; transition: transform .2s, opacity .2s; }
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(8px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }

/* ---------- Hero ---------- */
.hero { position: relative; color: #fff; overflow: hidden; }
/* Velo a TINTA UNITA sopra la fotografia: stesso blu, stessa intensita' da un
   bordo all'altro. Prima era una sfumatura che partiva blu e finiva rossa: il
   titolo cambiava sfondo mentre lo si leggeva e il blu dell'apertura non
   corrispondeva a quello di nessun'altra sezione. I due estremi identici
   producono un colore piatto, non una sfumatura. */
.hero-bg {
  position: absolute; inset: 0;
  background:
    linear-gradient(var(--primario-velo), var(--primario-velo)),
    url('/images/hero.png') center/cover no-repeat;
}

/* ============================================================
   LE UNDICI FOTOGRAFIE CHE SI ALTERNANO (homepage)
   ============================================================
   Undici riquadri sovrapposti nello stesso posto, ognuno con la sua
   fotografia di sfondo. Ogni fotografia sta a schermo sei secondi, con una
   dissolvenza di otto decimi in mezzo: giro completo 66 secondi, poi
   ricomincia.

   >>> ERANO SEI FINO AL 10/09/2026 (sera), su un giro di 36 secondi. Il
   committente ne ha consegnate cinque in piu'. Cambiare il numero di
   fotografie NON e' aggiungere righe: sposta la durata del giro e TUTTE le
   percentuali dei fotogrammi chiave, che sono frazioni di quella durata.
   I conti rifatti stanno qui sotto.

   >>> TUTTA LA ROTAZIONE E' QUI. Non c'e' una riga di JavaScript.
   Fino all'08/09/2026 la comandava `public/js/main.js`, perche' la prima
   fotografia doveva durare quanto il video Instagram che le stava accanto e
   quella e' una misura che il foglio di stile non puo' conoscere. Tolto il
   video (09/09/2026), le sei fotografie durano sei secondi ciascuna: e'
   esattamente quello che un'animazione CSS sa fare da sola, e farlo qui
   significa che l'apertura si comporta allo stesso modo con gli script
   attivi e con gli script bloccati. La regola `.js-attivo .hero-scatto` che
   spegneva questa animazione NON ESISTE PIU': non cercarla.

   ------------------------------------------------------------
   I CONTI DELLE PERCENTUALI, PERCHE' NON SONO NUMERI A CASO
   ------------------------------------------------------------
   Il giro dura 66 secondi, quindi un secondo vale 1,5152%. Da li':
     - 1,212%  = 0,8 s  -> fine della dissolvenza in entrata;
     - 9,091%  = 6,0 s  -> fine del turno (6 secondi a piena opacita');
     - 10,303% = 6,8 s  -> la fotografia successiva ha finito di coprirla;
     - 11,2%   = 7,4 s  -> margine di sicurezza, spiegato piu' sotto.
   I ritardi sono 0, 6, 12, 18, 24, 30, 36, 42, 48, 54 e 60 secondi: la
   fotografia che entra comincia la propria dissolvenza (il suo 0%)
   esattamente quando quella prima di lei arriva a fine turno (il suo
   9,091%), perche' 6 s di ritardo valgono 9,091% del giro. Come si passano
   il testimone e' spiegato per esteso nel blocco lungo sotto ai `nth-child`:
   NON e' una dissolvenza incrociata, ed e' voluto.

   >>> IL CONTO CHE TIENE IN PIEDI TUTTO, per un numero N qualsiasi di
   >>> fotografie: la k-esima e' completamente opaca da `6(k-1)+0,8` a
   >>> `6(k-1)+6,8` secondi, e la (k+1)-esima parte opaca esattamente da
   >>> `6k+0,8`, che e' lo stesso istante. Le finestre si toccano senza
   >>> lasciare buchi, ed e' per questo che la prima puo' restare accesa per
   >>> tutto il giro senza mai ricomparire in mezzo (vedi piu' sotto).

   >>> ERRORE DA NON RIFARE: il giro DEVE valere sei secondi per fotografia,
   >>> cioe' `durata = 6s * numero di fotografie`. Il 09/09/2026 qui c'erano
   >>> cinque riquadri su un giro di 24 secondi, con ritardi 0/6/12/18/24: un
   >>> ritardo di 24 secondi su un'animazione che si ripete ogni 24 secondi e'
   >>> identico a un ritardo di zero, quindi la quinta fotografia compariva
   >>> INSIEME alla prima e non si vedeva mai da sola. Chi aggiunge o toglie
   >>> una fotografia deve rifare QUATTRO cose insieme: la durata (`66s` qui
   >>> sotto, in due punti perche' le animazioni sono due), l'elenco dei
   >>> `nth-child` con i ritardi, le percentuali dei fotogrammi chiave delle
   >>> due dissolvenze, e il `10.4%` dei movimenti (che vale 6,84 s, cioe' la
   >>> finestra in cui la fotografia si vede: sei secondi piu' le due
   >>> dissolvenze).
   >>> E DEVE SPOSTARE `apertura-scatto-ultima` SULL'ULTIMO RIQUADRO: e'
   >>> l'unica dissolvenza che si spegne davvero, perche' e' l'unica sopra
   >>> alla quale non c'e' nessuno. Lasciata al sesto posto quando le
   >>> fotografie sono undici non si nota quasi — ed e' proprio per questo
   >>> che e' pericolosa.

   ------------------------------------------------------------
   IL MOVIMENTO: UNO DIVERSO PER OGNI FOTOGRAFIA
   ------------------------------------------------------------
   Richiesta del committente del 09/09/2026: «effetti di zoom/scorrimento per
   ogni immagine, per una visualizzazione piu' elegante e pulita da tutti i
   dispositivi». Prima il movimento era uno solo, uguale per tutte: un
   avvicinamento dal 100% al 112%.

   Sono undici animazioni distinte (`apertura-movimento-1..11`), assegnate
   per posizione con `:nth-child`, e la scelta e' fatta SUL SOGGETTO, non a
   caso:
     - le tre riprese dall'alto (1, 6 e 10: il centro di Bassano, il paese
       con l'uliveto e di nuovo Bassano col Grappa sul fondo) piu' la villa
       col giardino (2) hanno un movimento largo, chi entra e chi si
       allontana: e' il modo in cui si guarda un panorama;
     - i sette interni (3, 4, 5, 7, 8, 9, 11) hanno movimenti piu' corti e
       mirati, che accompagnano l'occhio dove sta il soggetto (la cucina, le
       travi, il camino, la vasca, la stufa, la lampada, il muro in sasso)
       invece di trascinare tutta la stanza.
   Avvicinamenti e allontanamenti si alternano il piu' possibile, cosi' due
   fotografie di seguito non fanno quasi mai lo stesso gesto.

   >>> I MOVIMENTI SEGUONO LA FOTOGRAFIA, NON IL POSTO. Il 10/09/2026 la
   sala da pranzo col muro in sasso e' passata dal sesto all'undicesimo
   posto: con lei e' stato rinominato il suo movimento (l'ex
   `apertura-movimento-6` e' oggi `apertura-movimento-11`), non riassegnato
   al nuovo sesto riquadro. Un movimento scelto su un interno stretto
   addosso a una veduta aerea non e' un guasto e non da' errori: e' solo
   sbagliato, e nessuno lo collega a una rinumerazione di mesi prima.

   >>> PERCHE' LA SCALA NON SCENDE MAI SOTTO 1,035 E LO SPOSTAMENTO NON
   >>> SUPERA L'1,1%. Sono due numeri legati fra loro. Uno spostamento
   >>> scopre il bordo della fotografia, a meno che l'immagine non sia gia'
   >>> piu' grande del riquadro che la contiene: a scala 1,035 sporge dell'
   >>> 1,75% per lato, cioe' piu' del massimo spostamento. Alzare uno dei due
   >>> senza guardare l'altro fa comparire una striscia del velo blu sul
   >>> bordo, che si vede solo su certi formati di schermo ed e' per questo
   >>> difficile da attribuire.

   NIENTE `will-change` QUI. Verrebbe naturale metterlo, ma sono UNDICI
   riquadri grandi quanto lo schermo: promuoverli tutti a livello grafico
   separato costa decine di megabyte di memoria video sul telefono, e in
   prova (quando erano quattro) ha prodotto zone bianche mentre si scorreva
   la pagina, perche' il browser teneva in memoria i livelli e non
   ridisegnava il resto. Le animazioni cambiano solo opacita' e
   trasformazione, che sono le due proprieta' che il browser sa gia' animare
   senza ridisegnare la pagina: e' gia' abbastanza leggero da non averne
   bisogno, e con undici riquadri il margine e' minore di quando erano sei,
   non maggiore. Vale anche per il peso: l'apertura scarica 4,7 MB di
   fotografie (il conto per esteso sta in cima a `src/views/home.js`). */
.hero-scatti { position: absolute; inset: 0; overflow: hidden; }
.hero-scatto {
  position: absolute; inset: 0;
  background-position: center; background-size: cover; background-repeat: no-repeat;
  opacity: 0;
  /* DUE ANIMAZIONI SULLO STESSO ELEMENTO, E NON E' UN DOPPIONE: la prima
     governa SOLO l'opacita', la seconda SOLO la trasformazione. Tenerle
     separate e' quello che permette di avere un movimento diverso per
     fotografia senza riscrivere sei volte anche i tempi della dissolvenza.
     Se un domani le si unisse in una sola, attenzione: due animazioni che
     toccano la stessa proprieta' non si sommano, vince l'ultima dichiarata,
     e il movimento sparirebbe senza un errore da nessuna parte.

     Durata, andatura e ripetizione stanno QUI perche' sono identiche per
     tutte e undici; il nome e il ritardo stanno sui singoli riquadri qui
     sotto, che e' l'unica cosa che cambia da una fotografia all'altra. I due
     valori separati dalla virgola sono uno per animazione: le due liste
     devono avere sempre la stessa lunghezza, altrimenti il browser le
     ricicla in ordine e i tempi si mescolano. */
  animation-duration: 66s, 66s;
  animation-timing-function: linear, linear;
  animation-iteration-count: infinite, infinite;
}

/* ------------------------------------------------------------
   UNA RIGA PER FOTOGRAFIA: quale dissolvenza e quale movimento le tocca, e
   con quanti secondi di ritardo.
   ------------------------------------------------------------
   >>> SENZA `animation-name` UN RIQUADRO NON SI VEDE MAI: nasce a opacita'
   zero (qui sopra) e senza animazione resta li'. E' il motivo per cui una
   DODICESIMA fotografia aggiunta al solo elenco in `src/views/home.js` non
   comparirebbe, e non darebbe nessun errore. Aggiungerne una vuol dire
   aggiungere anche la sua riga qui, il suo movimento in fondo, spostare
   `apertura-scatto-ultima` sull'ultima, e rifare i conti della durata
   (12 x 6 = 72s) e delle percentuali.

   ============================================================
   IL CAMBIO NON E' UN INCROCIO FRA DUE DISSOLVENZE, ED E' LA PARTE
   CHE SI SBAGLIA GUARDANDOLA.
   ============================================================
   Verrebbe naturale far sparire la fotografia che esce mentre quella che
   entra compare: una dissolvenza in uscita e una in entrata, in contemporanea.
   E' come era fatto fino all'08/09/2026, ED E' IL MOTIVO DI UN DIFETTO che si
   vede e non si sa spiegare: a metа' del cambio le due fotografie sono
   entrambe a mezza opacita', quindi la loro somma non copre il fondo e per
   quattro decimi di secondo si intravede il velo blu sotto. Misurato: la
   copertura scendeva al 75%, cioe' un quarto di velo a ogni cambio, sei volte
   per giro.

   COME SI EVITA, SENZA UN SOLO FOTOGRAMMA IN PIU'. I riquadri sono impilati
   nell'ordine in cui stanno nel codice: il primo sta in fondo, l'undicesimo
   sopra tutti. Quindi la fotografia che entra e' SEMPRE piu' in alto di
   quella che esce, e le basta comparire sopra: quella sotto non ha bisogno
   di andarsene, e resta opaca fino a quando e' completamente coperta. La
   copertura resta al 100% per tutto il cambio.
     - dalla 1 alla 10 (`apertura-scatto`): compaiono in dissolvenza, restano
       opache anche DOPO il proprio turno e si spengono solo all'11,2% del
       giro, cioe' un attimo dopo che quella successiva le ha coperte del
       tutto. Quel calo non lo vede nessuno: succede sotto a un'immagine
       opaca.
     - la 11 (`apertura-scatto-ultima`) e' l'unica che si dissolve DAVVERO in
       uscita, perche' e' in cima alla pila e sotto di lei c'e' la prima:
       sparendo la scopre. Anche qui la copertura resta piena, perche' la
       prima sotto e' opaca.
     - la 1 NON HA UNA DISSOLVENZA (`animation-name: none` sul primo posto
       della lista): e' `opacity: 1` e basta, per tutto il giro. Due cose in
       una: chi apre il sito vede la fotografia al primo fotogramma invece di
       otto decimi di blu (che e' proprio quello che il `preload` in
       `src/views/home.js` esiste per evitare), ed e' lo sfondo pieno che
       rende pulito il rientro dall'undicesima alla prima.

   >>> PERCHE' LA PRIMA PUO' RESTARE OPACA PER SESSANTASEI SECONDI senza
   >>> comparire dove non deve: dal momento in cui la seconda la copre
   >>> (10,303% del giro) fino alla fine, sopra di lei c'e' SEMPRE almeno una
   >>> fotografia completamente opaca — le finestre di piena opacita' delle
   >>> altre dieci si toccano estremo contro estremo e non lasciano buchi
   >>> (il conto e' in cima al blocco). Chi cambia i tempi qui sotto rifaccia
   >>> quel conto: se fra due fotografie si aprisse un buco, la prima
   >>> ricomparirebbe per un istante nel mezzo del giro, e sarebbe un difetto
   >>> difficilissimo da attribuire.
   ------------------------------------------------------------ */
.hero-scatto:nth-child(1)  { opacity: 1; animation-name: none,       apertura-movimento-1;  animation-delay: 0s,  0s;  }
.hero-scatto:nth-child(2)  { animation-name: apertura-scatto,        apertura-movimento-2;  animation-delay: 6s,  6s;  }
.hero-scatto:nth-child(3)  { animation-name: apertura-scatto,        apertura-movimento-3;  animation-delay: 12s, 12s; }
.hero-scatto:nth-child(4)  { animation-name: apertura-scatto,        apertura-movimento-4;  animation-delay: 18s, 18s; }
.hero-scatto:nth-child(5)  { animation-name: apertura-scatto,        apertura-movimento-5;  animation-delay: 24s, 24s; }
.hero-scatto:nth-child(6)  { animation-name: apertura-scatto,        apertura-movimento-6;  animation-delay: 30s, 30s; }
.hero-scatto:nth-child(7)  { animation-name: apertura-scatto,        apertura-movimento-7;  animation-delay: 36s, 36s; }
.hero-scatto:nth-child(8)  { animation-name: apertura-scatto,        apertura-movimento-8;  animation-delay: 42s, 42s; }
.hero-scatto:nth-child(9)  { animation-name: apertura-scatto,        apertura-movimento-9;  animation-delay: 48s, 48s; }
.hero-scatto:nth-child(10) { animation-name: apertura-scatto,        apertura-movimento-10; animation-delay: 54s, 54s; }
.hero-scatto:nth-child(11) { animation-name: apertura-scatto-ultima, apertura-movimento-11; animation-delay: 60s, 60s; }

/* Dalla 2 alla 10: entra in dissolvenza, poi resta opaca fino a quando e'
   coperta e si spegne al riparo. Il 10,303% e' l'istante in cui la fotografia
   dopo di lei ha finito la propria entrata (6 s di ritardo = 9,091%, piu'
   0,8 s di dissolvenza = 1,212%): da li' in poi e' invisibile, e il calo fino
   all'11,2% e' solo un margine di sicurezza contro gli arrotondamenti. */
@keyframes apertura-scatto {
  0%      { opacity: 0; }
  1.212%  { opacity: 1; }
  10.303% { opacity: 1; }
  11.2%   { opacity: 0; }
  100%    { opacity: 0; }
}
/* L'undicesima e ultima: e' in cima alla pila, quindi per far tornare la
   prima deve andarsene davvero. La sua uscita cade fra il 9,091% e il
   10,303% del PROPRIO tempo, cioe' fra la fine del giro e i primi otto
   decimi del giro dopo. */
@keyframes apertura-scatto-ultima {
  0%      { opacity: 0; }
  1.212%  { opacity: 1; }
  9.091%  { opacity: 1; }
  10.303% { opacity: 0; }
  100%    { opacity: 0; }
}

/* GLI UNDICI MOVIMENTI.
   Ognuno fa il suo gesto fra lo 0% e il 10,4% del giro, cioe' nei 6,8
   secondi in cui la sua fotografia si vede (sei secondi pieni piu' le due
   dissolvenze). Dal 10,4% al 100% torna al punto di partenza: e' un tragitto
   lento e all'indietro, ma cade nei cinquantanove secondi in cui quel
   riquadro e' a opacita' zero e sotto alle altre, quindi non lo vede
   nessuno. Serve perche' al giro successivo il movimento riparta da fermo e
   non con uno scatto.

   >>> IL 10,4% E' 6,84 SECONDI SU 66, e finche' il giro durava 36 secondi la
   stessa misura si scriveva `19%`. E' il numero che si dimentica di
   cambiare quando si aggiunge una fotografia: il gesto continuerebbe a
   svolgersi, ma su un tratto quasi doppio del tempo in cui la fotografia si
   vede, cioe' rallentato fino a sembrare fermo. Non da' nessun errore.

   >>> IL PRIMO E L'ULTIMO FOTOGRAMMA DI OGNI MOVIMENTO DEVONO ESSERE
   IDENTICI. Vale per tutti, ma sul primo e' l'unico caso che si vede: la
   prima fotografia e' `opacity: 1` per tutto il giro, quindi un 0% diverso
   dal 100% le fa fare uno scatto a ogni ripartenza, davanti agli occhi di
   chi sta guardando. */

/* 1 - IL CENTRO DI BASSANO DALL'ALTO. Entra piano e sale verso le
      montagne sul fondo: e' la direzione in cui si guarda la fotografia. */
@keyframes apertura-movimento-1 {
  0%    { transform: scale(1.04) translate3d(0.9%, 0.6%, 0); }
  10.4% { transform: scale(1.11) translate3d(-0.7%, -0.5%, 0); }
  100%  { transform: scale(1.04) translate3d(0.9%, 0.6%, 0); }
}
/* 2 - LA VILLA COL GIARDINO, RIPRESA DALL'ALTO. Si allontana invece di
      entrare: la casa e' al centro e inquadrata intera, avvicinandosi le si
      taglierebbero il tetto e la piscina. */
@keyframes apertura-movimento-2 {
  0%    { transform: scale(1.11) translate3d(-0.6%, -0.7%, 0); }
  10.4% { transform: scale(1.04) translate3d(0.5%, 0.4%, 0); }
  100%  { transform: scale(1.11) translate3d(-0.6%, -0.7%, 0); }
}
/* 3 - LA CUCINA. Scorrimento orizzontale con avvicinamento: accompagna
      l'occhio dal corridoio in primo piano alla cucina in fondo. */
@keyframes apertura-movimento-3 {
  0%    { transform: scale(1.04) translate3d(1.1%, 0, 0); }
  10.4% { transform: scale(1.11) translate3d(-1.0%, 0, 0); }
  100%  { transform: scale(1.04) translate3d(1.1%, 0, 0); }
}
/* 4 - IL SOGGIORNO CON LE TRAVI. Movimento verticale: parte alto, sulle
      travi in legno, e scende sul divano. In una stanza alta il gesto
      naturale e' questo, non uno spostamento di lato. */
@keyframes apertura-movimento-4 {
  0%    { transform: scale(1.04) translate3d(0, -1.0%, 0); }
  10.4% { transform: scale(1.11) translate3d(0, 0.8%, 0); }
  100%  { transform: scale(1.04) translate3d(0, -1.0%, 0); }
}
/* 5 - LA TAVERNA COL CAMINO. Si allontana e scorre a sinistra, verso il
      camino: si parte vicini al dettaglio e si scopre l'ambiente. */
@keyframes apertura-movimento-5 {
  0%    { transform: scale(1.11) translate3d(0.9%, 0.5%, 0); }
  10.4% { transform: scale(1.04) translate3d(-0.8%, -0.4%, 0); }
  100%  { transform: scale(1.11) translate3d(0.9%, 0.5%, 0); }
}
/* 6 - IL PAESE CON L'ULIVETO, RIPRESO DALL'ALTO (consegnata il 10/09/2026).
      La casa da guardare e' quella bassa in mezzo agli ulivi, non il paese
      dietro: il movimento e' una discesa lenta verso il centro-basso
      dell'inquadratura, come un drone che scende sull'immobile. */
@keyframes apertura-movimento-6 {
  0%    { transform: scale(1.04) translate3d(-0.8%, -0.6%, 0); }
  10.4% { transform: scale(1.11) translate3d(0.6%, 0.5%, 0); }
  100%  { transform: scale(1.04) translate3d(-0.8%, -0.6%, 0); }
}
/* 7 - IL BAGNO CON LA VASCA (10/09/2026). E' l'inquadratura piu' larga e
      piu' bassa di tutte: una stanza stretta ripresa per il lungo. Si
      allontana scorrendo verso destra, dove stanno la vasca e la finestra,
      cioe' verso la parte della stanza che vale la pena vedere. */
@keyframes apertura-movimento-7 {
  0%    { transform: scale(1.11) translate3d(-1.0%, 0, 0); }
  10.4% { transform: scale(1.04) translate3d(0.9%, 0, 0); }
  100%  { transform: scale(1.11) translate3d(-1.0%, 0, 0); }
}
/* 8 - IL SOGGIORNO CON LA STUFA E LA SCALA (10/09/2026). Avvicinamento con
      discesa: si parte dalle travi e dalla scala in alto e si arriva al
      divano. Stessa logica della 4, che e' pero' lontana nel giro (due
      minuti di distanza) e non si nota come una ripetizione. */
@keyframes apertura-movimento-8 {
  0%    { transform: scale(1.035) translate3d(0, -0.9%, 0); }
  10.4% { transform: scale(1.10) translate3d(0, 0.7%, 0); }
  100%  { transform: scale(1.035) translate3d(0, -0.9%, 0); }
}
/* 9 - LA CUCINA RUSTICA CON LA LAMPADA (10/09/2026). Si allontana e sale:
      si parte addosso al tavolo in primo piano e si scopre il soffitto a
      travi con la lampada, che e' quello che si guarda in questa stanza. */
@keyframes apertura-movimento-9 {
  0%    { transform: scale(1.11) translate3d(0, 0.9%, 0); }
  10.4% { transform: scale(1.04) translate3d(0, -0.7%, 0); }
  100%  { transform: scale(1.11) translate3d(0, 0.9%, 0); }
}
/* 10 - BASSANO COL GRAPPA SUL FONDO (e' la stessa fotografia che apre
      /chi-siamo). Avvicinamento largo che sale verso le montagne. E' il
      gesto della 1, ed e' voluto: sono lo stesso soggetto ripreso dallo
      stesso punto, e dargli movimenti diversi le farebbe sembrare due
      fotografie sbagliate invece di due inquadrature della stessa citta'. */
@keyframes apertura-movimento-10 {
  0%    { transform: scale(1.035) translate3d(0, 0.8%, 0); }
  10.4% { transform: scale(1.10) translate3d(0, -0.6%, 0); }
  100%  { transform: scale(1.035) translate3d(0, 0.8%, 0); }
}
/* 11 - LA SALA DA PRANZO COL MURO IN SASSO. Chiude il giro con un
      avvicinamento centrato e un filo piu' marcato degli altri: e' la
      fotografia dopo la quale l'apertura ricomincia, e un movimento pulito
      rende il ritorno alla prima meno avvertibile.
      ERA `apertura-movimento-6` FINO AL 10/09/2026: la fotografia e' la
      stessa, e' cambiato il suo numero nella serie. */
@keyframes apertura-movimento-11 {
  0%    { transform: scale(1.035); }
  10.4% { transform: scale(1.12); }
  100%  { transform: scale(1.035); }
}

/* ============================================================
   IL VELO BLU A TUTTO SCHERMO NON C'E' PIU'
   ============================================================
   Era un rettangolo di blu all'82% steso su tutta la fotografia. Teneva
   leggibile il titolo bianco, ma spegneva l'immagine: le fotografie aeree
   della Pedemontana arrivavano al visitatore slavate e virate di blu, cioe'
   proprio il difetto segnalato dal committente («togliere il filtro blu
   sulle immagini in homepage per avere una qualita' migliore»).

   COSA C'E' AL SUO POSTO. Una sfumatura verticale che parte TRASPARENTE in
   alto e scende fino al blu in basso, dove sta il testo. Il cielo e le
   montagne — la meta' alta dell'inquadratura, quella che si guarda — restano
   a colori pieni; il titolo, il sottotitolo e i due pulsanti stanno sul
   terzo basso, che resta scuro abbastanza da tenerli leggibili.

   PERCHE' NON SI TOGLIE E BASTA. Il testo e' bianco. Su una fotografia con
   il cielo chiaro — tre delle quattro dell'apertura ce l'hanno — un titolo
   bianco senza niente sotto sparisce. Non e' una questione estetica: e' il
   requisito di contrasto delle WCAG, e vale anche per il bordo bianco della
   targhetta e per quello dei due pulsanti.

   NON SI TOCCA `--primario-velo`. Quella variabile la usano anche l'apertura
   delle pagine interne, le targhette sulle schede immobile e il calendario
   del gestionale: cambiarla qui li cambierebbe tutti.

   I MEZZI DI LEGGIBILITA' SONO TRE, E SI SOMMANO: questa sfumatura, l'ombra
   sotto al testo (`text-shadow`, qui sotto) e i bordi bianchi resi piu'
   spessi. Serviva tutto e tre: la sola sfumatura non basta su una foto con
   una casa bianca in basso a sinistra. */
.hero-velo {
  position: absolute; inset: 0;
  background: linear-gradient(
    to bottom,
    rgba(58, 22, 18, .06) 0%,
    rgba(58, 22, 18, .18) 38%,
    rgba(58, 22, 18, .52) 72%,
    rgba(58, 22, 18, .78) 100%);
}
/* L'ombra e' l'unica cosa che tiene il titolo leggibile se sotto capita una
   parete bianca in pieno sole. E' larga e tenue, non un contorno: sul blu
   della sfumatura non si vede, sul bianco si'. */
.hero-inner h1,
.hero-inner .hero-sub { text-shadow: 0 2px 14px rgba(11, 20, 36, .55); }
/* Bordi bianchi piu' decisi: su una fotografia ora piu' chiara, un filo da
   un pixel al 100% di bianco si perdeva contro le nuvole.
   >>> QUI C'ERA ANCHE `.hero-inner .hero-kicker`, in tutte e due i gruppi
   (l'ombra qui sopra e il bordo qui sotto): il confetto «Agenzia immobiliare
   a Bassano del Grappa» e' stato tolto il 14/09/2026 su richiesta del
   committente. L'ombra del titolo NON si tocca — e' quella che lo tiene
   leggibile sopra una parete bianca in pieno sole. */
/* E QUI C'ERA il rinforzo dello stesso pulsante quando stava sopra a una
   fotografia (bordo 2px e un'ombra, perche' un bordo da 1px su un'immagine
   chiara sparisce). Tolto il 22/09/2026 col pulsante. Era:
     .hero-actions .btn-light { border-width: 2px; box-shadow: 0 2px 14px rgba(11, 20, 36, .3); } */

/* CHI HA CHIESTO MENO ANIMAZIONI VEDE UNA FOTOGRAFIA FERMA.
   Non una a caso: la prima, che e' anche l'unica precaricata. Le altre
   cinque restano nel codice ma non si vedono mai.

   NIENTE ROTAZIONE E NIENTE MOVIMENTO: si spengono entrambe le animazioni
   (`animation: none` le tocca tutte e due) e si azzera la trasformazione,
   altrimenti la fotografia resterebbe ferma ma ingrandita al valore del
   primo fotogramma del suo movimento.

   >>> LE ALTRE CINQUE IL BROWSER LE SCARICA COMUNQUE, anche qui: sono sfondi
   di riquadri presenti nella pagina, e `opacity: 0` non e' `display: none`.
   Prima in questo punto c'era scritto il contrario («quindi il browser non
   le scarica nemmeno»), ed era falso. Non e' una svista da poco: e' la
   ragione per cui la compressione delle sei copie ridotte conta anche per
   chi non vedra' mai la rotazione. */
@media (prefers-reduced-motion: reduce) {
  .hero-scatto { animation: none; opacity: 0; transform: none; }
  .hero-scatto:nth-child(1) { opacity: 1; }
}
/* L'APERTURA COMINCIA SOTTO ALLA BARRA DI NAVIGAZIONE.
   La fotografia sale di quanto e' alta la barra, e il testo dentro scende
   dell'altrettanto: il risultato e' una barra trasparente appoggiata sopra
   l'immagine invece di una striscia bianca sopra di essa. Solo in homepage:
   `.hero-home` non esiste da nessun'altra parte. */
.hero-home { margin-top: calc(var(--altezza-navbar) * -1); }
.hero-home .hero-inner { padding-top: calc(84px + var(--altezza-navbar)); }

.hero-inner { position: relative; padding: 84px 20px 60px; max-width: var(--container); }
/* L'ETICHETTA A CONFETTO (`.hero-kicker`) E' STATA TOLTA il 14/09/2026 su
   richiesta del committente, insieme alle sue regole: era il confetto col
   bordo bianco «Agenzia immobiliare a Bassano del Grappa» sopra al titolo
   dell'apertura, e la homepage era l'unico punto del sito che lo usava (vedi
   `src/views/home.js`). Se un domani tornasse, il posto e' questo. */
.hero h1 { color: #fff; font-size: clamp(2rem, 5vw, 3.3rem); max-width: 640px; }
.hero h1 em { font-style: normal; color: #fff; }
.hero-sub { margin: 18px 0 26px; font-size: 1.12rem; max-width: 560px; }
/* E QUI C'ERA il contenitore dei pulsanti dell'apertura
   (`.hero-actions { display: flex; gap: 14px; flex-wrap: wrap; }`), che
   affiancava i due pulsanti di un tempo e mandava a capo il secondo quando
   non ci stava. Tolto il 22/09/2026: l'apertura e' titolo piu' riga di
   presentazione, senza nessun pulsante. */

/* I TRE NUMERI SOTTO AI PULSANTI (`.hero-stats`, `.hero-stat`) SONO STATI
   TOLTI il 01/09/2026 su richiesta del committente, insieme alle loro
   regole: erano l'unico punto del sito che li usava. Se un domani tornassero,
   il posto e' questo. */

/* LA CLASSE `.solo-schermo-largo` NON ESISTE PIU', dal 22/09/2026.
   Serviva a far sparire qualcosa sotto una certa larghezza senza toglierlo
   dall'HTML, e ha avuto due utilizzatori in vita sua, mai piu' di uno alla
   volta: la riga di presentazione dell'apertura (dal 01/09, soglia 760px) e
   poi il pulsante «Guarda gli immobili» (dal 21/09, soglia 1100px). Oggi il
   committente ha fatto togliere il pulsante da TUTTI i dispositivi: senza
   utilizzatori, una regola che nasconde per larghezza e' solo un invito a
   cercare chi la usa.
   Se servisse di nuovo, era una riga sola:
     @media (max-width: 1100px) { .solo-schermo-largo { display: none; } }
   e 1100px non era un numero a caso: e' la soglia del menu a tendina, scelta
   perche' 1024px (tablet in orizzontale) le stia sotto. Vedi il commento
   esteso accanto al blocco `@media (max-width: 1100px)` piu' in basso. */

/* ---------- Sezioni ---------- */
.section { padding: 56px 0; }
.section-alt { background: var(--bg-alt); }
.section-title { font-size: clamp(1.5rem, 3vw, 2rem); margin-bottom: 22px; position: relative; }
.section-title.center { text-align: center; }
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.section-link { font-weight: 600; white-space: nowrap; }

.page-hero { background: var(--primario); color: #fff; padding: 46px 0; }
.page-hero h1 { color: #fff; font-size: clamp(1.7rem, 4vw, 2.5rem); }
.page-hero p { margin-top: 8px; font-size: 1.05rem; }
.page-hero-slim { padding: 30px 0; }

/* ---------- Apertura delle pagine interne sopra una fotografia ----------
   Chi siamo, Vendi casa e Immobili aprono come la homepage: titolo e
   descrizione dentro l'immagine invece che su una banda blu piatta.

   IL FONDO BLU RESTA DICHIARATO (lo eredita da `.page-hero`) e non e'
   ridondante: e' quello che si vede nel mezzo secondo in cui la fotografia
   non e' ancora arrivata, e quello che resta se il file sparisce. Senza,
   in quel mezzo secondo il titolo sarebbe bianco su bianco.

   La fascia e' piu' alta di quella piatta: una fotografia in una striscia da
   46px non si legge come una fotografia, si legge come una texture.
   `.container` va rialzato sopra al velo, altrimenti resta sotto. */
.page-hero-foto {
  position: relative; overflow: hidden;
  padding: 76px 0 66px;
  background-position: center; background-size: cover; background-repeat: no-repeat;
}
.page-hero-foto .page-hero-velo { position: absolute; inset: 0; background: var(--primario-velo); }
.page-hero-foto > .container { position: relative; }
@media (max-width: 760px) { .page-hero-foto { padding: 52px 0 46px; } }

/* ---------- Apertura «grande»: identica a quella della homepage ----------
   >>> NESSUNA PAGINA LA USA DAL 09/09/2026. Le regole restano perche' il
   committente su questo punto ha cambiato idea due volte in nove giorni
   (fascia piatta -> apertura alta il 01/09 -> di nuovo fascia normale il
   09/09): il perche' della conservazione sta accanto al parametro `grande` in
   src/views/layout.js. Si riaccende passando `grande: true` a `pageHero()` e
   `navbarSuFoto: true` a `page()`, in coppia. Fino ad allora TUTTO QUELLO CHE
   SEGUE, compreso il centraggio verticale, non si vede da nessuna parte.

   Nata su richiesta del committente del 01/09/2026 per /immobili e
   /vendi-casa: «ingrandire in altezza per vedere meglio l'immagine, con lo
   stesso funzionamento della barra della homepage».

   TRE COSE INSIEME, non solo l'altezza:
     1. la fotografia sale sotto alla barra di navigazione (margine negativo
        pari all'altezza della barra), e il testo scende dell'altrettanto:
        e' la stessa coppia di righe di `.hero-home`;
     2. la fascia diventa alta come l'apertura della homepage, cosi'
        dell'immagine si vede una porzione e non una striscia;
     3. il velo passa dal blu pieno alla stessa sfumatura della homepage:
        la fotografia si vede per quello che e'.
   La barra trasparente non e' regolata qui: la accende `navbarSuFoto` nella
   pagina e la riporta bianca `aggiornaBarra()` in main.js, che cerca la
   classe `hero-suFoto` che questa fascia porta con se'. */
/* TITOLO E DESCRIZIONE AL CENTRO DELL'IMMAGINE, NON IN BASSO (07/09/2026,
   richiesta del committente per /vendi-casa, /immobili, /vendite-di-successo
   e /dicono-di-noi: «centrati all'immagine in centro», su ogni dispositivo).
   Prima erano appoggiati al bordo inferiore (`align-items: flex-end`).

   NON BASTA CAMBIARE `align-items`, E QUI STA LA PARTE CHE SI SBAGLIA.
   Il centraggio avviene dentro il riquadro del contenuto, cioe' DOPO aver
   tolto i margini interni: con 120px sopra e 68px sotto il centro di quel
   riquadro cade 26px piu' in basso del centro della fotografia, e il testo
   continua a leggersi basso. I due margini vanno quindi pareggiati, e
   l'altezza della barra di navigazione si somma SOLO a quello di sopra,
   perche' e' la barra a coprire quella striscia (vedi il margine negativo
   qui sopra): senza quella somma il testo salirebbe sotto al menu. */
.page-hero-grande {
  margin-top: calc(var(--altezza-navbar) * -1);
  padding: calc(94px + var(--altezza-navbar)) 0 94px;
  display: flex; align-items: center;
  /* IL `min-height` HA UN TETTO, e non e' un dettaglio.
     L'apertura della homepage e' alta quanto la fa il suo margine interno:
     circa 500px su qualunque schermo, perche' non ha nessuna misura legata
     all'altezza della finestra. Con `min-height: 62vh` e basta, su un monitor
     alto 1300px questa fascia arrivava a 800px — meta' piu' alta di quella
     che dovrebbe imitare — e spingeva l'elenco degli immobili sotto al bordo
     dello schermo. Il tetto la tiene allineata alla homepage sugli schermi
     alti; il `62vh` continua a valere su quelli bassi, dove serve davvero a
     non ridurre la fotografia a una striscia. */
  min-height: min(62vh, 520px);
}
/* LA SFUMATURA QUI E' PIU' DECISA CHE IN HOMEPAGE, e non e' una svista.
   In homepage il testo sta in basso a sinistra su una fotografia aerea:
   sotto ci sono sempre tetti e alberi, cioe' colori medi. Qui le fotografie
   sono soggetti singoli e vicini — una villa bianca, una facciata gialla in
   pieno sole — e il testo ci finisce sopra per forza. Con i valori della
   homepage il sottotitolo, che e' piu' piccolo del titolo, si perdeva sul
   giallo della facciata di /vendi-casa.

   >>> IL BUIO STA IN MEZZO, E VA LETTO INSIEME AL CENTRAGGIO QUI SOPRA. <<<
   Finche' il testo era appoggiato in basso, bastava scurire il fondo: la
   sfumatura arrivava a .86 all'ultima riga e la meta' alta restava pulita.
   Da quando il testo e' al centro (07/09/2026) quella distribuzione lo
   lasciava nella fascia piu' chiara, cioe' riapriva esattamente il difetto
   della facciata gialla di /vendi-casa che i valori vecchi erano nati per
   chiudere. Adesso la parte scura e' un ripiano fra il 42% e il 76%, che e'
   dove cade il blocco di testo (titolo + descrizione centrati dentro
   `min-height: min(62vh, 520px)`); il primo quarto resta chiaro, perche' e'
   li' che si guarda la fotografia, e l'ultimo si scurisce solo per non
   tagliare l'immagine di netto sul bianco della pagina. */
.page-hero-grande .page-hero-velo {
  background: linear-gradient(
    to bottom,
    rgba(58, 22, 18, .10) 0%,
    rgba(58, 22, 18, .30) 26%,
    rgba(58, 22, 18, .58) 42%,
    rgba(58, 22, 18, .60) 76%,
    rgba(58, 22, 18, .74) 100%);
}
.page-hero-grande h1 { text-shadow: 0 2px 16px rgba(11, 20, 36, .7); }
.page-hero-grande p { text-shadow: 0 1px 12px rgba(11, 20, 36, .75); max-width: 620px; }
/* Sul telefono l'apertura non puo' prendersi due terzi dello schermo: sotto
   ci sono i filtri e le case, ed e' quello che si e' venuti a vedere. */
@media (max-width: 760px) {
  .page-hero-grande {
    /* Pareggiati come sul monitor, e per lo stesso motivo: il committente ha
       chiesto il testo centrato «per tutti i tipi di dispositivi», e con 78px
       sopra e 58px sotto sul telefono si vedeva ancora basso. */
    padding: calc(68px + var(--altezza-navbar)) 0 68px;
    min-height: 46vh;
  }
}

/* ---------- Card immobili ---------- */
.prop-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); gap: 26px;
}
.prop-card {
  background: #fff; border-radius: var(--radius); overflow: hidden;
  box-shadow: var(--shadow); transition: transform .18s, box-shadow .18s;
  display: flex; flex-direction: column;
}
.prop-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.prop-card-media { position: relative; aspect-ratio: 3 / 2; overflow: hidden; }
.prop-badge {
  position: absolute; top: 12px; left: 12px;
  background: var(--primario); color: #fff; font-size: .74rem; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase; padding: 5px 11px; border-radius: 999px;
}
.prop-badge-status { left: auto; right: 12px; background: var(--primario); }
.prop-badge-status.off { background: var(--ink-soft); }
.prop-badge-status.warn { background: var(--warn); }

/* VENDUTO: stessa fascetta di «Vendita», stesso posto, stessa forma.
   CAMBIA SOLO IL COLORE, ED E' L'UNICO ROSSO DEL SITO (vedi --venduto in
   cima al file). Blu come quella «Vendita» costringeva a leggere la parola
   per capire lo stato dell'immobile: scorrendo un elenco di venti schede,
   nessuno la legge. Rossa si vede da lontano e non si confonde.
   Non e' una seconda etichetta accanto alla prima: e' la prima che cambia
   parola e colore, altrimenti sulla foto si leggerebbero due stati in
   contraddizione. */
.prop-badge-venduto { background: var(--venduto); }

/* La fotografia di un immobile venduto perde un po' di saturazione: e' il
   segnale che la mente coglie prima ancora di leggere la fascetta, e distingue
   l'archivio dall'offerta attiva senza togliere nulla dall'elenco. */
.prop-card-venduto .prop-card-foto { filter: saturate(.55); }
.prop-card-venduto:hover .prop-card-foto { filter: saturate(1); }
.prop-photos-count {
  position: absolute; bottom: 10px; right: 12px; display: inline-flex; align-items: center; gap: 5px;
  background: var(--primario-velo); color: #fff; font-size: .76rem; padding: 4px 9px; border-radius: 999px;
}
.prop-card-body { padding: 18px 18px 20px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.prop-price { color: var(--ink); font-weight: 800; font-size: 1.3rem; }
.prop-price-big { font-size: 2rem; margin-top: 10px; }
.prop-title { font-size: 1.06rem; }
.prop-title a { color: var(--primario); text-decoration: none; }
.prop-title a:hover { color: var(--primario); text-decoration: underline; }
.prop-location { color: var(--ink-soft); font-size: .9rem; display: flex; align-items: center; gap: 5px; }
.prop-specs { list-style: none; display: flex; flex-wrap: wrap; gap: 8px 18px; margin-top: auto; padding-top: 12px; border-top: 1px solid var(--line); font-size: .9rem; color: var(--ink-soft); align-items: center; }
.energy-badge {
  display: inline-block; color: #fff; font-weight: 700; font-size: .78rem;
  padding: 3px 9px; border-radius: 6px;
}

/* ---------- Filtri ---------- */
.filters-bar {
  display: flex; flex-wrap: wrap; gap: 14px 18px; align-items: end;
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
  padding: 16px 18px; margin-bottom: 30px; box-shadow: var(--shadow);
}
.filter-group { display: flex; flex-direction: column; gap: 4px; }
.filter-group label { font-size: .78rem; font-weight: 700; color: var(--ink-soft); text-transform: uppercase; letter-spacing: .04em; }
.filter-group select {
  padding: 9px 12px; border: 1.5px solid var(--line); border-radius: 8px;
  font: inherit; font-size: .93rem; color: var(--ink); background: #fff; min-width: 150px;
}
.filter-group select:focus { outline: 2px solid var(--primario); outline-offset: 1px; border-color: var(--primario); }
.filters-reset { font-size: .9rem; align-self: center; margin-left: auto; }
.empty-state { background: var(--bg-alt); border-radius: var(--radius); padding: 46px 26px; text-align: center; }
.empty-state p { margin-bottom: 14px; }
/* ---------- Mappe ----------
   QUI C'ERANO GLI STILI DELLA PAGINA MAPPA, ELIMINATA IL 07/09/2026:
   la mappa a tutta pagina (`.big-map`), la barra dei filtri dedicata, il
   pannello «Caratteristiche particolari» (`.map-avanzati`) e l'avviso di
   ricerca senza risultati. Sono spariti insieme a `public/js/map.js` e a
   `mapPage()` in `src/views/pages.js`: nessun'altra pagina li usava.

   QUELLO CHE RESTA QUI SOTTO SERVE ANCORA, e non va tolto per simmetria:
   `.prop-map` e' il riquadro della mappa nella scheda del singolo immobile,
   `.contacts-map` quello della sede in Chi siamo, `.marker-pin` il segnaposto
   di entrambe e le regole `.leaflet-*` danno forma al fumetto. Li disegna
   `public/js/prop-map.js` con la copia locale di Leaflet. */
.prop-map { height: 340px; border-radius: var(--radius); z-index: 1; }
.contacts-map { margin-top: 18px; }
.map-privacy-note { font-size: .85rem; color: var(--ink-soft); margin-bottom: 10px; }
/* Il fumetto con foto, prezzo e caratteristiche (`.map-popup*`) apparteneva
   alla mappa grande: la mini-mappa della scheda immobile mostra il segnaposto
   e basta. Tolto insieme alla pagina. */
.leaflet-popup-content { margin: 0 !important; }
.leaflet-popup-content-wrapper { border-radius: 10px; overflow: hidden; padding: 0; }
.marker-pin {
  width: 34px; height: 34px; border-radius: 50% 50% 50% 0; background: var(--primario);
  transform: rotate(-45deg); border: 2.5px solid #fff; box-shadow: 0 2px 8px rgba(0,0,0,.35);
  display: flex; align-items: center; justify-content: center;
}
.marker-pin::after { content: ''; width: 11px; height: 11px; background: #fff; border-radius: 50%; }
/* LA SEDE SI DEVE DISTINGUERE DAGLI IMMOBILI. Prima erano due colori diversi
   (rosso gli immobili, blu la sede); ora che il colore e' uno solo, la sede
   e' lo stesso segnaposto a colori invertiti: bianco con il punto blu. */
.marker-pin-agency { background: #fff; border-color: var(--primario); }
.marker-pin-agency::after { background: var(--primario); }

/* ---------- Valori ---------- */
.values-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 22px; margin-top: 30px; }
.value-card { background: #fff; border-radius: var(--radius); padding: 26px 22px; box-shadow: var(--shadow); }
.value-icon {
  width: 52px; height: 52px; border-radius: 14px; background: var(--primario); color: #fff;
  display: flex; align-items: center; justify-content: center; margin-bottom: 14px;
}
.value-card h3 { font-size: 1.05rem; margin-bottom: 8px; }
.value-card p { font-size: .92rem; color: var(--ink-soft); }

/* ---------- "Chi siamo" in apertura di «Perche' scegliere CASAREALE» ------
   Fotografia a sinistra, tre righe di presentazione a destra, e sotto le
   quattro motivazioni. Le motivazioni dicevano cosa sappiamo fare a chi non
   sapeva ancora chi siamo: questo blocco da' loro un soggetto.

   `align-items: center` e non `start`: le due colonne non hanno la stessa
   altezza (la foto e' verticale, il testo corto) e allineate in alto la foto
   sembrerebbe sporgere. `max-width` sul testo perche' su un monitor largo
   una riga da mille pixel non si legge, si scorre. */
.chisiamo-blocco {
  display: grid; grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
  gap: 34px; align-items: center;
  margin: 26px 0 40px;
}
.chisiamo-foto {
  width: 100%; height: auto; display: block;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg-alt);
  /* RITRATTO, QUINDI INQUADRATURA VERTICALE.
     Il rapporto e' imposto e non lasciato al file: cosi' il riquadro non
     cambia altezza il giorno in cui si sostituisce la fotografia, e con lui
     non si sposta tutto quello che sta sotto. 4:5 e' il formato del ritratto
     da profilo, quello a cui l'occhio e' abituato.
     `object-position` alto: `cover` centrerebbe il ritaglio a meta' altezza,
     cioe' sul torace, tagliando la testa. Il 18% tiene il viso dentro
     l'inquadratura qualunque sia la fotografia caricata.
     IL BORDO NON E' UN VEZZO: lo sfondo dello scatto e' bianco come la
     pagina, e senza bordo la giacca sembrerebbe ritagliata e appoggiata
     sul testo. Stessa ragione del ritratto nella pagina Chi siamo. */
  aspect-ratio: 4 / 5; object-fit: cover; object-position: center 18%;
}
.chisiamo-testo { max-width: 560px; }
.chisiamo-occhiello {
  text-transform: uppercase; letter-spacing: .14em; font-size: .74rem;
  font-weight: 700; color: var(--primario); margin-bottom: 8px;
}
.chisiamo-testo h3 { font-size: 1.35rem; margin-bottom: 12px; }
.chisiamo-testo p { color: var(--ink-soft); margin-bottom: 12px; }
.chisiamo-testo .btn { margin-top: 4px; }

/* Sul telefono la foto va sopra: due colonne da centosettanta pixel non sono
   ne' una fotografia leggibile ne' un testo leggibile. */
@media (max-width: 860px) {
  .chisiamo-blocco { grid-template-columns: 1fr; gap: 22px; }
  .chisiamo-foto { max-width: 300px; margin: 0 auto; }
  .chisiamo-testo { max-width: none; }
}

/* ---------- CTA band ---------- */
.cta-band { background: var(--primario); color: #fff; }
.cta-band-inner { display: flex; align-items: center; justify-content: space-between; gap: 26px; flex-wrap: wrap; }
.cta-band h2 { color: #fff; font-size: 1.5rem; }
.cta-band p { margin-top: 6px; }

/* ---------- Dettaglio immobile ---------- */
.breadcrumbs { font-size: .86rem; color: var(--ink-soft); padding-top: 18px; }
.breadcrumbs a { color: var(--ink-soft); }
.breadcrumbs span { color: var(--primario); font-weight: 600; }
.prop-detail { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 36px; padding: 22px 20px 56px; }
.prop-detail-main { min-width: 0; }
.prop-detail-header h1 { font-size: clamp(1.4rem, 3vw, 2rem); margin: 10px 0 6px; }
.prop-detail-header { margin-top: 22px; }

.gallery-main { position: relative; border-radius: var(--radius); overflow: hidden; background: var(--bg-alt); }
/* LA FOTO GRANDE HA UNA FORMA SOLA, PER TUTTI GLI IMMOBILI E TUTTI GLI SCHERMI.
   `height: auto` NON E' RIDONDANTE, ED E' LA CORREZIONE PRINCIPALE.
   Il tag <img> porta gli attributi `width="960" height="640"`, che servono a
   riservare lo spazio prima che la foto arrivi. Il browser li tratta come una
   dichiarazione di stile: senza `height: auto` che la annulla, l'altezza
   restava inchiodata a 640 pixel e `aspect-ratio` non veniva mai applicato.
   Sul telefono voleva dire una fotografia alta 640 pixel su uno schermo alto
   812: l'immagine occupava tutto lo schermo, tagliata sopra e sotto, e per
   arrivare al prezzo bisognava scorrere. Sul computer non si notava, perche'
   lo spazio era piu' largo che alto.

   Con `height: auto` la forma la decide `aspect-ratio` e nient'altro: 3:2 su
   computer e tablet, un po' piu' schiacciata sul telefono. Non dipende dalle
   dimensioni del file caricato, quindi vale identica per gli immobili gia' in
   archivio e per tutti quelli che verranno: `object-fit: cover` ritaglia il
   di piu' senza mai deformare la fotografia. */
.gallery-main img { width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover; }
@media (max-width: 760px) { .gallery-main img { aspect-ratio: 16 / 10; } }
.gallery-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 44px; height: 44px; border-radius: 50%; border: 0; cursor: pointer;
  background: rgba(255,255,255,.92); color: var(--primario); font-size: 1.6rem; line-height: 1;
  display: flex; align-items: center; justify-content: center; box-shadow: var(--shadow);
}
.gallery-nav:hover { background: #fff; }
.gallery-prev { left: 14px; }
.gallery-next { right: 14px; }
.gallery-counter {
  position: absolute; bottom: 12px; right: 14px; background: var(--primario-velo); color: #fff;
  font-size: .8rem; padding: 4px 10px; border-radius: 999px;
}
.gallery-thumbs {
  display: grid; grid-auto-flow: column; grid-auto-columns: 104px; gap: 8px;
  overflow-x: auto; margin-top: 10px; padding-bottom: 6px; scrollbar-width: thin;
}
.gallery-thumb { border: 2.5px solid transparent; border-radius: 8px; overflow: hidden; padding: 0; cursor: pointer; background: none; }
.gallery-thumb img { width: 100%; height: 68px; object-fit: cover; }
.gallery-thumb.active { border-color: var(--primario); }

/* Riquadri dei dati principali (m², locali, camere, bagni, classe).
   GRIGLIA A PASSO FISSO, non flex: con `flex: 1` un solo dato si allargava a
   tutta la riga e il numero finiva al centro, con due grandi vuoti ai lati.
   Con `auto-fill` i riquadri hanno sempre la stessa misura e partono da
   sinistra: uno o cinque dati, l'allineamento non cambia. */
.prop-key-specs {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr));
  gap: 12px; margin: 22px 0; justify-content: start;
}
.key-spec {
  background: var(--bg-alt); border-radius: 10px; padding: 12px 16px; text-align: left; min-width: 0;
}
.key-spec-value { display: block; font-weight: 800; font-size: 1.35rem; color: var(--primario); overflow-wrap: anywhere; }
.key-spec-label { font-size: .78rem; color: var(--ink-soft); text-transform: uppercase; letter-spacing: .04em; }

/* ---------- Descrizione accorciata, con «Continua a leggere» ----------
   Il taglio vale solo dove lo script e' partito (`.js-attivo`): senza, il
   testo resta tutto visibile e il pulsante non compare mai. E' l'unica
   disposizione che non lascia nessuno con mezza descrizione.

   L'altezza e' espressa in `em`, cioe' in righe di testo: 15em con
   interlinea 1,65 sono circa nove righe. In pixel, un domani che si cambi il
   corpo del carattere, sarebbero nove righe su un computer e cinque su un
   telefono.

   LA SFUMATURA IN FONDO NON E' UN COLORE NUOVO. Il taglio cade a meta' di una
   riga, e una riga tranciata a meta' sembra un guasto. La velatura va dal
   trasparente al bianco della pagina: e' un accorgimento di leggibilita' sul
   fondo che c'e' gia', non un secondo colore dell'identita' (la regola sulla
   palette in cima al file riguarda i colori del marchio). */
.prop-description { margin: 26px 0; }
.js-attivo .prop-descrizione[data-descrizione]:not(.aperta) {
  position: relative; max-height: 15em; overflow: hidden;
}
.js-attivo .prop-descrizione[data-descrizione]:not(.aperta)::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 4.2em;
  background: linear-gradient(rgba(255, 255, 255, 0), #fff 88%);
  pointer-events: none;
}
.prop-descrizione-comando {
  margin-top: 6px; padding: 8px 0; background: none; border: 0;
  color: var(--primario); font-weight: 700; font-size: .95rem; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
}
.prop-descrizione-comando::after {
  content: ''; width: 8px; height: 8px; margin-top: -4px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg); transition: transform .18s;
}
.prop-descrizione-comando[aria-expanded="true"]::after { transform: rotate(-135deg); margin-top: 2px; }
.prop-descrizione-comando:hover { text-decoration: underline; }
.prop-descrizione-comando:focus-visible { outline: 2px solid var(--primario); outline-offset: 3px; border-radius: 4px; }
.prop-description h2, .prop-specs-table h2, .prop-map-section h2 { font-size: 1.3rem; margin-bottom: 14px; }
.prop-description p { margin-bottom: 12px; }
.specs-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 26px; }
.spec-row { display: flex; justify-content: space-between; gap: 14px; padding: 9px 2px; border-bottom: 1px solid var(--line); font-size: .93rem; }
.spec-row dt { color: var(--ink-soft); }
.spec-row dd { font-weight: 600; color: var(--primario); text-align: right; }
.prop-specs-table h3 { font-size: 1.05rem; margin: 20px 0 10px; }
.features-list { list-style: none; display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 8px 18px; }
.features-list li { display: flex; align-items: center; gap: 8px; font-size: .92rem; }
.features-list svg { color: var(--ok); flex: none; }
.prop-map-section { margin-top: 28px; }

.prop-detail-sidebar { min-width: 0; }
/* IL RIQUADRO DEI CONTATTI NON SEGUE PIU' LO SCORRIMENTO.
   Era `position: sticky`: restava agganciato sotto la barra mentre si
   leggevano descrizione e caratteristiche. Richiesta del committente del
   01/09/2026: deve restare in alto, accanto alle foto e al prezzo, e
   scorrere via col resto della pagina. Chi arriva in fondo ha comunque il
   pulsante WhatsApp fisso in basso a destra. */
.contact-card {
  background: #fff; border: 1px solid var(--line);
  border-radius: var(--radius); padding: 22px; box-shadow: var(--shadow-lg);
}
.contact-card-agency { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; color: var(--primario); }
.contact-card-ref { color: var(--ink-soft); font-size: .88rem; margin-bottom: 14px; }
.contact-card .btn { margin-bottom: 10px; }

/* ---------- Form ---------- */
.contact-form label { display: block; font-size: .85rem; font-weight: 700; color: var(--primario); margin: 12px 0 4px; }
.contact-form input:not([type="checkbox"]), .contact-form textarea, .contact-form select {
  width: 100%; padding: 11px 13px; border: 1.5px solid var(--line); border-radius: 8px;
  font: inherit; font-size: .95rem; background: #fff; color: var(--ink);
}
.contact-form input:focus, .contact-form textarea:focus, .contact-form select:focus {
  outline: 2px solid var(--primario); outline-offset: 1px; border-color: var(--primario);
}
.contact-form textarea { resize: vertical; }
.contact-form h3 { margin: 18px 0 4px; font-size: 1.02rem; }
.contact-form button { margin-top: 16px; }
.privacy-check { display: flex !important; align-items: flex-start; gap: 8px; font-weight: 400 !important; font-size: .82rem !important; color: var(--ink-soft) !important; margin-top: 12px !important; }
.privacy-check input { margin-top: 3px; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }
.hp-field { position: absolute !important; left: -9999px !important; height: 0; width: 0; opacity: 0; }
.contact-form-page { max-width: 640px; }
.alert { border-radius: 10px; padding: 14px 18px; margin-bottom: 20px; }
.alert-success { background: #E7F5EA; border: 1px solid #B5DFC0; color: #175226; }

/* ---------- Pagine info ---------- */
.contacts-grid, .agency-grid { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(280px, 1fr); gap: 40px; }
.info-card { background: #fff; border: 1px solid var(--line); border-radius: var(--radius); padding: 22px; margin-bottom: 18px; box-shadow: var(--shadow); }
.info-card h3 { font-size: 1rem; margin-bottom: 10px; }
.info-card p { font-size: .93rem; margin-bottom: 8px; }
.info-card-accent { border-color: var(--primario); background: var(--bg-alt); }
.checklist { list-style: none; }
.checklist li { padding: 6px 0 6px 26px; position: relative; font-size: .93rem; }
.checklist li::before {
  content: '✓'; position: absolute; left: 2px; color: var(--ok); font-weight: 800;
}
.steps-list { list-style: none; counter-reset: step; }
.steps-list li { counter-increment: step; padding: 10px 0 10px 40px; position: relative; font-size: .92rem; }
.steps-list li::before {
  content: counter(step); position: absolute; left: 0; top: 10px;
  width: 27px; height: 27px; border-radius: 50%; background: var(--primario); color: #fff;
  font-weight: 700; font-size: .85rem; display: flex; align-items: center; justify-content: center;
}
/* Le quattro pillole blu (`.agency-badges`, `.badge-pill`) sono state
   sostituite il 01/09/2026 dai riquadri `.credenziali` piu' sotto: erano
   rettangoli blu con l'angolo tondo e due parole dentro, cioe' avevano la
   forma di un pulsante senza esserlo. */

/* ---------- Ritratto dell'agente, in fondo a "La nostra agenzia" ----------
   Fotografia a sinistra col nome sopra, le quattro credenziali incolonnate a
   destra: si legge come "questa persona, queste qualifiche".
   `align-items: center` tiene le credenziali al centro dell'altezza del
   ritratto: le due colonne non hanno la stessa altezza e non devono averla,
   ma allineate in alto sembrerebbero cadute li' per sbaglio.

   IL RIQUADRO ATTORNO ALLA FOTO NON E' UN VEZZO. Lo sfondo dello scatto e'
   quasi bianco come la pagina: senza bordo la giacca sembrerebbe ritagliata e
   appoggiata sul testo, e su uno schermo poco contrastato il margine
   dell'immagine sparirebbe del tutto. */
.agente-blocco {
  display: grid; grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
  gap: 26px; align-items: center; margin-top: 22px;
  max-width: 760px;
}
/* IL NOME IN STAMPATELLO, SUBITO SOPRA IL RITRATTO.
   `text-transform` e non il nome scritto in maiuscolo nel codice: cosi' i
   lettori di schermo pronunciano "Filippo Furlani" invece di compitare
   F-I-L-I-P-P-O. La spaziatura fra le lettere serve perche' un maiuscolo
   stretto, in un carattere geometrico come il Montserrat, si legge peggio del
   minuscolo: le lettere si toccano. */
.agente-nome {
  text-transform: uppercase; letter-spacing: .09em;
  font-weight: 700; font-size: .98rem; color: var(--primario);
  margin-bottom: 2px;
}
/* IL RUOLO SOTTO AL NOME, attaccato a lui e non alla fotografia: nome e ruolo
   sono una didascalia sola, e i 10px che prima separavano il nome dal
   ritratto sono passati qui sotto. Piu' piccolo e attenuato del nome, perche'
   la persona viene prima del ruolo; stessa spaziatura fra le lettere, cosi'
   le due righe si leggono come un blocco unico e non come due etichette
   accostate per caso. */
.agente-ruolo {
  text-transform: uppercase; letter-spacing: .09em;
  font-weight: 600; font-size: .78rem; color: var(--ink-soft);
  margin-bottom: 10px;
}
.agente-foto {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--bg-alt);
}

/* ---------- Le quattro credenziali accanto al ritratto ----------
   Stessa forma dei riquadri di "Perche' scegliere CASAREALE" in homepage:
   icona tonda blu, titolo, una riga di spiegazione. Prima erano pillole blu
   piene, che avevano la forma di un pulsante senza esserlo (01/09/2026).
   Incolonnate e non affiancate: accanto a una fotografia verticale, due
   colonne di riquadri sarebbero larghe centoquaranta pixel l'una. */
.credenziali { display: grid; gap: 12px; }
.credenziale {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 14px;
  align-items: center;
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
  padding: 14px 16px; box-shadow: var(--shadow);
}
/* L'icona e' la stessa di `.value-icon` ma piu' piccola: qui i riquadri sono
   quattro in colonna, non quattro in fila, e hanno meno altezza a testa. */
.credenziale .value-icon { width: 40px; height: 40px; margin: 0; flex: 0 0 auto; }
.credenziale h4 { font-size: .95rem; color: var(--primario); margin-bottom: 3px; }
.credenziale p { font-size: .85rem; color: var(--ink-soft); line-height: 1.5; }
.legal-text { max-width: 760px; }
.legal-text h2 { font-size: 1.15rem; margin: 22px 0 8px; }
.legal-text p { margin-bottom: 10px; }

/* ---------- FAQ ---------- */
.faq-section { padding: 46px 0; background: var(--bg-alt); border-top: 1px solid var(--line); }
.faq-section + .faq-section { border-top: 0; padding-top: 0; }
.faq-list { max-width: 820px; }
.faq-item {
  background: #fff; border: 1px solid var(--line); border-radius: 10px;
  margin-bottom: 10px; overflow: hidden;
}
.faq-item summary {
  list-style: none; cursor: pointer; padding: 15px 46px 15px 18px; font-weight: 600;
  color: var(--primario); position: relative; user-select: none;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-icon { position: absolute; right: 16px; top: 50%; width: 14px; height: 14px; transform: translateY(-50%); }
.faq-icon::before, .faq-icon::after {
  content: ''; position: absolute; background: var(--primario); border-radius: 2px; transition: transform .2s;
}
.faq-icon::before { width: 14px; height: 2.5px; top: 6px; }
.faq-icon::after { width: 2.5px; height: 14px; left: 6px; }
.faq-item[open] .faq-icon::after { transform: scaleY(0); }
.faq-answer { padding: 0 18px 16px; color: var(--ink-soft); font-size: .94rem; }

/* ---------- Footer ---------- */
.site-footer { background: var(--primario); color: #C6CFDC; margin-top: 30px; }
.footer-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 34px; padding: 50px 20px 34px; }
.footer-col h3 { color: #fff; font-size: .95rem; text-transform: uppercase; letter-spacing: .08em; margin-bottom: 14px; }
.footer-col p { font-size: .9rem; margin-bottom: 10px; }
.footer-col a { color: #E8EDF5; }
.footer-col nav a { display: block; padding: 4px 0; font-size: .9rem; }
.brand-footer { color: #fff; margin-bottom: 14px; }
.footer-social { display: flex; gap: 12px; margin-top: 14px; }
.footer-social a {
  width: 38px; height: 38px; border-radius: 50%; background: rgba(255,255,255,.1);
  display: flex; align-items: center; justify-content: center; color: #fff;
}
.footer-social a:hover { background: #fff; color: var(--primario); }
.footer-bottom { border-top: 1px solid rgba(255,255,255,.12); padding: 18px 0; font-size: .8rem; }
.footer-bottom .container { display: flex; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.footer-portals a { color: #E8EDF5; }
/* Partita IVA, REA e iscrizione alla mediazione: obbligatori sul sito
   (art. 7 D.Lgs. 70/2003), ma sono un dato di servizio, non un messaggio.
   Vanno sotto al copyright e piu' in sordina, non accanto ai portali. */
.footer-intestazione p { margin: 0; }
.footer-legal { margin-top: 4px !important; font-size: .95em; opacity: .72; }

/* ---------- Pulsanti fissi: WhatsApp e Instagram ---------- */
/* Colonna in basso a destra. In colonna e non affiancati perche sul telefono
   due cerchi da 58px uno accanto all'altro mangiano meta della larghezza
   utile; impilati restano sul bordo, dove il pollice arriva da solo.
   WhatsApp resta il piu in basso: e il canale su cui si risponde davvero. */
.float-actions {
  position: fixed; right: 18px; bottom: 18px; z-index: 90;
  display: flex; flex-direction: column; gap: 12px;
}
.float-btn {
  width: 58px; height: 58px; border-radius: 50%; color: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-lg);
  transition: transform .15s, background .15s;
}
.float-btn:hover { transform: scale(1.08); text-decoration: none; }
.float-wa { background: var(--wa); }
.float-wa:hover { background: var(--wa-dark); }
/* Instagram a tinta unita: il logo ufficiale e una sfumatura, ma qui ogni
   colore ha un valore solo e nessun elemento e sfumato. */
/* IL PULSANTE INSTAGRAM PORTA IL GRADIENTE DEL MARCHIO, il glifo resta
   bianco: accanto al cerchio verde di WhatsApp, con il suo glifo bianco, i
   due si leggono come una coppia invece che come due elementi di due siti
   diversi. Il marchio si riconosce dal gradiente, che e' la sua parte
   riconoscibile; farlo al contrario (glifo colorato su cerchio bianco)
   avrebbe dato un cerchio bianco su una pagina bianca.

   NIENTE CAMBIO DI FONDO AL PASSAGGIO DEL MOUSE, e non e' una dimenticanza:
   un gradiente non si puo' interpolare verso un colore piatto, quindi la
   transizione non avverrebbe e il pulsante scatterebbe da cinque colori a
   un viola pieno in un fotogramma. Il segnale del passaggio c'e' gia' ed e'
   condiviso con WhatsApp: `.float-btn:hover` lo ingrandisce dell'8%. */
.float-ig { background: var(--ig-gradiente); }

/* ---------- Cookie banner ---------- */
.cookie-banner {
  position: fixed; left: 16px; right: 16px; bottom: 16px; z-index: 120;
  background: var(--primario); color: #fff; border-radius: 12px; padding: 16px 20px;
  display: flex; align-items: center; gap: 18px; box-shadow: var(--shadow-lg);
  max-width: 720px; margin: 0 auto;
}
.cookie-banner[hidden] { display: none; }
.cookie-banner p { font-size: .85rem; flex: 1; }
.cookie-banner a { color: #fff; text-decoration: underline; }

/* ---------- Responsive ---------- */
/* L'APERTURA DELLA HOMEPAGE NON HA PIU' REGOLE PROPRIE PER IL TELEFONO.
   Qui c'era il blocco `@media (max-width: 860px)` che sotto quella larghezza
   trasformava l'apertura in una colonna (`.hero-home { display: flex }`) per
   spostare il pannello del video SOTTO al titolo invece che di fianco, e che
   rimpiccioliva telaio, targhetta e pulsante dell'audio. Tolto il video
   (09/09/2026) non restava una sola dichiarazione con un effetto: senza
   `flex` l'apertura torna un blocco normale e si vede identica.
   Le fotografie e il velo non c'entravano nemmeno prima: sono
   `position: absolute`, quindi fuori dal flusso. */
@media (max-width: 960px) {
  .prop-detail { grid-template-columns: 1fr; }
  .contacts-grid, .agency-grid { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
}

/* ============================================================
   LA BARRA DIVENTA UN MENU A TENDINA GIA' A 1100px
   ============================================================
   Fino al 10/09/2026 succedeva a 760px, insieme a tutto il resto del
   telefono. E' SALITA PERCHE' LA VOCE PIU' LUNGA E' PASSATA DA «Vendite» a
   «Vendite di successo» (richiesta del committente): sei voci piu' il
   pulsante WhatsApp non stanno piu' su una riga sotto ai 1100px, e una barra
   di navigazione che va a capo su due righe alza la barra stessa e fa
   scendere l'apertura della homepage di una ventina di pixel.

   >>> E' UNA SOGLIA DI CONTENUTO, NON DI DISPOSITIVO. Non corrisponde a un
   telefono ne' a un tablet: corrisponde alla larghezza sotto la quale QUESTE
   sei etichette non ci stanno. Se un giorno le voci diventano cinque, o
   l'etichetta lunga torna corta, questo numero va rimisurato, non lasciato
   li'. Si misura cosi', con la barra ancora in versione computer:
       [...document.querySelectorAll('.main-nav > a')]
         .reduce((s, a) => s + a.offsetWidth, 0)
   piu' il marchio e i margini del contenitore.

   MISURATO IL 10/09/2026: le sei voci piu' WhatsApp occupano 836px, il
   marchio 92px, i margini 60px — totale 988px. La riga si spezza davvero
   fra 1020 e 1000px. LA SOGLIA E' A 1100 E NON A 1010 DI PROPOSITO: quei
   90px di margine servono a un caso che capita davvero, cioe' il carattere
   Montserrat che non arriva (rete lenta, `font-display: swap`) e le voci
   disegnate col carattere di sistema, che e' piu' largo. Con la soglia
   appiccicata alla misura esatta, la barra andrebbe a capo per il primo
   secondo di ogni visita e poi si sistemerebbe: un difetto che non si
   riproduce quasi mai e non si spiega mai.
   E' anche il motivo per cui 1024px — tablet in orizzontale, il formato
   piu' diffuso di quella fascia — sta dalla parte del menu a tendina: li' le
   voci ci starebbero per quattro pixel.

   >>> PERCHE' IL BLOCCO STA QUI E NON DENTRO A QUELLO DEI 760px. Le regole
   del telefono devono poter correggere queste (il carattere, l'altezza della
   barra), e in CSS a parita' di specificita' vince l'ultima scritta: questo
   blocco deve restare PRIMA di quello dei 760px. Spostarlo dopo non da'
   nessun errore, cambia solo quale delle due vince. */
@media (max-width: 1100px) {
  .nav-toggle { display: flex; }
  .main-nav {
    display: none; position: absolute; top: 100%; left: 0; right: 0;
    background: #fff; flex-direction: column; align-items: stretch; gap: 0;
    padding: 10px 16px 18px; box-shadow: var(--shadow-lg); border-top: 1px solid var(--line);
  }
  .main-nav.open { display: flex; }
  .main-nav a { padding: 13px 10px; border-bottom: 1px solid var(--line); border-radius: 0; font-size: 1rem; }
  .main-nav a.nav-cta { margin: 14px 0 0; justify-content: center; border-bottom: 0; }
  /* NIENTE REGOLA PER LE VOCI BIANCHE SU PANNELLO BIANCO, e non e' una
     dimenticanza: in homepage la barra e' trasparente e le voci sono
     bianche, ma `public/js/main.js` aggiunge `compatta` alla barra nel
     momento in cui il pannello si apre, proprio per questo. Vale identico
     da 761 a 1100px, dove il pannello ora si apre sopra alla fotografia
     dell'apertura. */
}

@media (max-width: 760px) {
  /* SUL TELEFONO RESTANO I DUE NUMERI, non l'indirizzo: sono le uniche voci
     della barra che si possono premere per fare qualcosa. Carattere e spazi
     si stringono quel tanto che basta perche' i due numeri stiano su una
     riga sola: a capo, "Tel. 0424 / 066716" sembra un numero spezzato. */
  .topbar { font-size: .76rem; }
  .topbar-inner { justify-content: center; gap: 12px; }
  .topbar-item { white-space: nowrap; }
  .topbar-item:first-child { display: none; }
  /* IL PULSANTE A TRE RIGHE NON COMPARE PIU' QUI: la sua soglia e' salita a
     1100px ed e' nel blocco poco sopra. Vedi la nota li'. */
  /* SUL TELEFONO LA BARRA NON CRESCE COME SUL COMPUTER. A 96px si mangerebbe
     un settimo di uno schermo alto 700px, e resta comunque appiccicata in
     cima mentre si scorre. 78px sono il compromesso: il marchio e' alto 58,
     cioe' un terzo piu' di prima e con il sottotitolo al limite del
     leggibile, e la barra resta una barra.
     La variabile si ridichiara qui invece di scrivere l'altezza a mano nei
     punti che la usano: le aperture fotografiche continuano a incastrarsi
     sotto da sole (vedi la nota accanto a .brand-logo-nav). */
  :root { --altezza-navbar: 78px; }
  .brand-logo-nav { height: 58px; }
  .hero-inner { padding: 54px 20px 44px; }
  /* QUI C'ERA `.hero-actions { margin-top: 30px }`, TOLTA IL 21/09/2026
     INSIEME ALLA RAGIONE PER CUI ESISTEVA: dava aria fra il titolo e il
     pulsante (richiesta del 07/09/2026) perche' sotto i 760px la riga di
     presentazione non si vedeva e il pulsante finiva appiccicato alla "o" di
     "posto giusto".
     Dal 22/09/2026 la questione non si pone piu' in nessun verso: nell'
     apertura non c'e' NESSUN pulsante, su nessuno schermo. La distanza sotto
     al titolo la da' il margine della riga di presentazione, uguale a tutte
     le larghezze. */
  .specs-grid { grid-template-columns: 1fr; }
  .form-row { grid-template-columns: 1fr; }
  .cta-band-inner { flex-direction: column; align-items: flex-start; }
  .footer-bottom .container { flex-direction: column; }
  .cookie-banner { flex-direction: column; align-items: stretch; text-align: center; }
  /* IL RITRATTO PASSA SOPRA ALLE CREDENZIALI. Affiancati su un telefono
     resterebbero due colonne da centoquaranta pixel: la foto illeggibile e il
     testo dei riquadri spezzato su tre righe. Sopra e sotto, invece, la foto
     resta grande abbastanza da riconoscere la persona. */
  .agente-blocco { grid-template-columns: 1fr; gap: 18px; }
  .agente-ritratto { max-width: 300px; margin: 0 auto; }
  .credenziali { width: 100%; }
}

@media (max-width: 480px) {
  .prop-grid { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr; }
  .filter-group { flex: 1 1 45%; }
  .filter-group select { min-width: 0; width: 100%; }
  .gallery-thumbs { grid-auto-columns: 84px; }
  /* Sotto i 480px i due numeri hanno la precedenza sulle icone social, che
     sul telefono sono gia' il pulsante fisso in basso a destra. */
  .topbar-social { display: none; }
  /* Su schermo stretto due riquadri per riga: restano comunque allineati
     a sinistra e della stessa misura. */
  .prop-key-specs { grid-template-columns: repeat(2, 1fr); }
}

/* ============================================================
   PAGINA «VENDITE DI SUCCESSO CON IL METODO CASAREALE»
   ============================================================
   Le schede assomigliano a quelle degli immobili — stessa cornice, stessa
   ombra, stessa proporzione della fotografia — e dal 10/09/2026 (sera) NE
   RIUSANO LA PARTE FOTOGRAFICA per intero, classi comprese: `.prop-card-media`,
   `.prop-card-foto-pila`, `.prop-card-foto`, `.prop-card-foto-nav`,
   `.prop-photos-count`.

   >>> QUI SOPRA C'ERA SCRITTO L'OPPOSTO, ed e' utile sapere perche'. Il
   commento diceva che queste schede NON riusano `.prop-card` proprio perche'
   «le fotografie non si sfogliano: la vendita e' conclusa, chi vuole i
   dettagli apre la scheda». Il committente ha chiesto le frecce anche qui,
   «come per gli immobili»: quella premessa e' decaduta, e con lei la ragione
   di tenere due impianti separati.

   >>> IL MOTIVO VERO PER CUI SI RIUSANO LE CLASSI NON E' RISPARMIARE RIGHE
   DI CSS: e' che a sfogliare le fotografie e' `public/js/main.js`, con un
   ascoltatore solo per tutta la pagina che cerca `.prop-card-foto-nav` e
   lavora dentro a `.prop-card-media`. Classi diverse avrebbero voluto dire
   un secondo ascoltatore, da correggere due volte per sempre.

   RESTA DIVERSO IL CORPO DELLA SCHEDA, e li' non si eredita niente: qui i
   prezzi sono due e incolonnati, c'e' l'etichetta del risultato sopra e i
   giorni di vendita sotto.

   >>> LA SPIEGAZIONE «PERCHE' PUBBLICHIAMO TUTTI E DUE I PREZZI» NON C'E'
   PIU'. Erano `.vendite-intro` e `.vendite-intro p`, tolte il 10/09/2026 su
   richiesta del committente («in modo da avere subito gli immobili»). Le due
   regole sono sparite con il testo: se un giorno il riquadro torna, torna
   anche il suo stile. */

/* >>> LA FASCIA DEI NUMERI IN CIMA NON C'E' PIU' (22/09/2026). Era il
   riquadro blu con «3 immobili venduti · 1,2% scarto medio · 100% assistenza
   fino al rogito notarile». Tolta su richiesta del committente, che non
   l'aveva mai chiesta: compariva da sola da tre vendite confrontabili in su,
   e si e' accesa quando la modifica sui prezzi uguali ha dato uno scarto
   anche alla terza vendita. Il perche' per esteso sta accanto al posto in cui
   stava `riepilogo()`, in `src/views/vendite.js`.
   Erano quattro regole, ed erano l'unico punto del sito che le usava:
     .vendite-riepilogo {
       display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px;
       background: var(--primario); color: #fff; border-radius: var(--radius);
       padding: 26px 24px; margin-bottom: 34px;
     }
     .vendite-dato { text-align: center; }
     .vendite-dato-numero { display: block; font-size: 2rem; font-weight: 800; line-height: 1.1; }
     .vendite-dato-etichetta { display: block; font-size: .84rem; margin-top: 6px; opacity: .88; }
   piu' una riga sotto i 760px, che la impilava in colonna. */

.vendite-griglia {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 26px;
}
/* `position: relative` NON E' DECORATIVO: e' il riferimento su cui si
   appoggia il collegamento allargato a tutta la scheda (`.vendita-titolo
   a::after`, poco piu' sotto). Togliendolo, quel rettangolo si aggrapperebbe
   al primo antenato posizionato — cioe' alla pagina — e coprirebbe tutto lo
   schermo con un collegamento invisibile. */
.vendita-card {
  position: relative;
  background: #fff; border-radius: var(--radius); overflow: hidden;
  box-shadow: var(--shadow); display: flex; flex-direction: column;
  border: 1px solid var(--line);
}
/* Proporzione e ritaglio arrivano da `.prop-card-media`, che questa scheda
   porta insieme a `.vendita-media`: qui resta solo quello che e' diverso
   dalla scheda di un immobile in vendita. */
/* LA FOTOGRAFIA E' DESATURATA, come nelle schede degli immobili venduti
   dell'elenco: e' il segnale che si coglie prima di leggere la fascetta e
   dice «archivio», non «offerta». Qui pero' NON torna a colori passandoci
   sopra: nell'elenco quel ritorno serviva a dire «la scheda si puo' ancora
   aprire», mentre qui sono tutte vendute e l'effetto sarebbe solo un
   tremolio a ogni passaggio del mouse. */
.vendita-media .prop-card-foto { filter: saturate(.6); }
/* LE FRECCE COMPAIONO AL PASSAGGIO DEL MOUSE SULLA SCHEDA.
   La regola generale e' scritta su `.prop-card:hover`, che qui non c'e': la
   scheda di una vendita e' `.vendita-card`. Senza questa riga le frecce
   resterebbero invisibili su tutto il parco desktop e visibili solo sui
   dispositivi a tocco (`pointer: coarse`), cioe' un difetto che non si vede
   provando col telefono. */
.vendita-card:hover .prop-card-foto-nav { opacity: 1; }
/* LE FRECCE STANNO SOPRA AL COLLEGAMENTO CHE COPRE LA SCHEDA (z-index 3):
   sono pulsanti veri e devono restare premibili. `main.js` ferma comunque la
   propagazione del clic, ma se la freccia finisse SOTTO al rettangolo del
   collegamento il clic non arriverebbe mai al pulsante e la pagina si
   aprirebbe lo stesso.
   Le fascette e il contatore restano a 2, cioe' SOTTO al collegamento: e'
   voluto, perche' il committente ha chiesto che si entri nella scheda
   «cliccando nel badge». */
.vendita-card .prop-card-foto-nav { z-index: 4; }
.vendita-corpo { padding: 18px 18px 20px; display: flex; flex-direction: column; gap: 8px; flex: 1; }
/* ============================================================
   UN SOLO `margin-top: auto` PER SCHEDA, E DEVE ESSERE QUELLO DEI GIORNI.
   ============================================================
   `.prop-specs` — la riga «Appartamento · 120 m² · 5 locali», in comune con
   la scheda degli immobili — porta `margin-top: auto`, che li' serve a
   incollarla in fondo. QUI DENTRO SONO DUE, insieme a quello di
   `.vendita-giorni`, e il flexbox NON sceglie: divide lo spazio libero in
   parti uguali fra tutti i margini automatici.

   COSA SI VEDEVA (misurato il 10/09/2026, tre schede in fila): la scheda
   venduta a prezzo pieno non ha la riga del prezzo di pubblicita' ne' lo
   scarto, quindi le avanzano 91px; divisi in due facevano scendere le
   caratteristiche di 45px rispetto alle schede accanto, aprendo un buco
   sotto al comune. Sembrava un errore di impaginazione di quella scheda, e
   invece era una regola scritta per un'altra pagina.

   Azzerandolo, tutto lo spazio libero va all'unico margine automatico
   rimasto: la riga dei giorni resta incollata in fondo — che e' quello che
   serve, perche' le schede della griglia sono alte uguali — e tutto il resto
   sta in cima, allineato da una scheda all'altra. */
.vendita-corpo .prop-specs { margin-top: 0; }
.vendita-titolo { font-size: 1.06rem; }
.vendita-titolo a { color: var(--ink); }
.vendita-card:hover .vendita-titolo a { color: var(--primario); }
/* ============================================================
   TUTTA LA SCHEDA E' UN COLLEGAMENTO, DAL 10/09/2026
   ============================================================
   Il collegamento «Vedi la scheda dell'immobile →» che stava in fondo e'
   stato tolto su richiesta del committente: si entra premendo la scheda.
   Il rettangolo qui sotto e' il collegamento del TITOLO allargato a tutta la
   scheda.

   >>> UNO SOLO, NON DUE. La scheda di un immobile in vendita ha un secondo
   collegamento invisibile sulla sola fotografia (`.prop-card-link`): qui non
   c'e', di proposito. Due rettangoli invisibili sovrapposti sono il modo
   piu' rapido di ritrovarsi con le frecce che non rispondono in una zona
   della scheda e rispondono in un'altra, senza capire perche'.

   >>> ED E' IL COLLEGAMENTO DEL TITOLO, non un `<a>` vuoto messo sopra:
   cosi' chi naviga con la tastiera o con un lettore di schermo trova UNA
   voce sola, annunciata col titolo dell'immobile, invece di un collegamento
   senza nome. */
.vendita-titolo a::after { content: ''; position: absolute; inset: 0; z-index: 3; }

/* ============================================================
   L'ETICHETTA DEL RISULTATO (10/09/2026, richiesta del committente)
   ============================================================
   Una riga sopra ai due prezzi che dice com'e' andata: «Venduto in Tempi
   Record», «... a prezzo pieno», «... e in Over Price». Quale delle tre lo
   decide `ETICHETTE_RISULTATO` in `src/views/vendite.js`, e sta scritto solo
   li'.

   >>> UN COLORE SOLO PER TUTTE, DAL 22/09/2026: blu pieno e scritta bianca.
   Richiesta del committente, alla lettera: i badge «devono essere sempre
   tutti dello stesso colore (interno blu e scritta bianca)».

   QUI C'ERANO TRE VARIANTI, e vale la pena sapere perche' non ci sono piu'.
   Si distinguevano per QUANTO erano piene, non per tinta — `-sopra` chiara,
   `-pari` col contorno blu, `-sotto` blu pieno — e la piu' forte toccava al
   caso «venduto sotto al prezzo di pubblicita'», seguendo la corrispondenza
   dettata dal committente. Era anche il punto su cui quella corrispondenza
   si vedeva a occhio, e per mesi e' stata la domanda aperta piu' urgente del
   progetto: il risultato migliore prendeva l'etichetta piu' scarna.
   La domanda si e' chiusa da sola in due mosse: il 21/09 le frasi sono
   diventate scrivibili a mano dal gestionale, e oggi il colore smette di
   dire qualcosa. Adesso com'e' andata la vendita lo dicono le PAROLE e lo
   SCARTO, che sono due cose che si leggono; il colore fa da contenitore e
   basta.

   CONSEGUENZA DA SAPERE: `-pari` e `-sotto` NON ESISTONO PIU', e nemmeno
   nell'HTML — `schedaVendita()` non stampa piu' la classe della variante,
   perche' un gancio senza regola attaccata e' un invito a cercare il codice
   che lo legge. Se un domani si volesse tornare a distinguerle:
     .vendita-etichetta-pari  { border-color: var(--primario); }
     .vendita-etichetta-sotto { background: var(--primario); border-color: var(--primario); color: #fff; }
   e la classe si rimette in `src/views/vendite.js`, dov'era.

   NIENTE VERDE E NIENTE ROSSO, e questo non cambia: vendere sotto al prezzo
   di pubblicita' non e' un fallimento e venderci sopra non e' un merito, e
   due colori d'allarme su una pagina che parla di trasparenza direbbero il
   contrario. Il blu pieno e' il colore del sito, non un giudizio. */
.vendita-etichetta {
  display: inline-flex; align-items: center; gap: 7px;
  align-self: flex-start;
  margin-top: 6px;
  padding: 6px 12px; border-radius: 999px;
  /* IL BORDO RESTA, ED E' DELLO STESSO BLU DEL FONDO: senza, il confetto
     cambierebbe di due pixel in altezza rispetto a prima e, su un fondo
     chiaro, perderebbe il contorno netto che aveva. Uguale al fondo non si
     vede, ma tiene la misura. */
  background: var(--primario); color: #fff;
  border: 1px solid var(--primario);
  font-size: .8rem; font-weight: 700; line-height: 1.25;
}
/* Il segno di spunta non aggiunge informazione ed e' `aria-hidden` nel
   codice: serve a far leggere la riga come un esito e non come un titolo.
   Eredita `currentColor`, quindi e' diventato bianco da solo. */
.vendita-etichetta svg { flex: none; }

/* I DUE PREZZI, INCOLONNATI E CON UNA RIGA IN MEZZO.
   Affiancati su una scheda da 300px il secondo numero andava a capo e
   sembrava un terzo dato. Uno sopra l'altro, con l'etichetta a sinistra e la
   cifra a destra, si leggono come le due righe di una ricevuta: e' esattamente
   il confronto che si vuole far fare. */
.vendita-prezzi {
  margin-top: 4px; border-top: 1px solid var(--line); padding-top: 12px;
  display: flex; flex-direction: column; gap: 6px;
}
/* ============================================================
   IL SIMBOLO DELL'EURO NON SI STACCA MAI DAL NUMERO.
   ============================================================
   `fmtPrice()` scrive «€ 1.185.000» con uno spazio normale, e uno spazio
   normale e' un punto in cui il browser puo' andare a capo. Misurato su uno
   schermo da 320px con i caratteri ingranditi del telefono: l'etichetta
   «Prezzo di vendita» e il numero non ci stavano su una riga, il numero e'
   andato a capo, e ad andare a capo e' stato lo SPAZIO — cioe' e' rimasto un
   «€» solo, su una riga sua, con «1.185.000» sotto. Sembra un errore di
   programmazione, e su una pagina che parla di prezzi e' il posto peggiore
   dove sembrarlo.

   DUE RIGHE PER RISOLVERLO, e devono stare insieme:
     - `white-space: nowrap` sulla cifra la tiene tutta intera. Da sola pero'
       la farebbe sporgere dal bordo della scheda, perche' non ci sta;
     - `flex-wrap: wrap` sulla riga permette alla cifra di scendere INTERA
       sotto alla propria etichetta quando lo spazio non basta.
   `margin-left: auto` la tiene a destra anche quando e' sola sulla sua riga:
   senza, `space-between` con un elemento solo lo appoggia a sinistra e le due
   cifre non sarebbero piu' incolonnate fra loro, che e' tutto il punto di
   questa tabella.

   Succede solo con i prezzi a sette cifre su schermi molto stretti: da
   150.000 a 999.000 euro, che e' quasi tutto quello che si vende qui, la
   riga resta una. */
.vendita-prezzo { display: flex; align-items: baseline; justify-content: space-between; gap: 4px 12px; flex-wrap: wrap; }
/* LE ETICHETTE DELLA SCHEDA, E SONO TRE, NON DUE.
   «Prezzo di pubblicita'», «Prezzo di vendita» e — dal 14/09/2026, per
   richiesta del committente — «rispetto al prezzo di pubblicita'», la nota in
   fondo alla riga dello scarto. Sono tutte e tre la stessa cosa: la
   didascalia che dice CHE COS'E' il numero accanto. Percio' stanno sulla
   stessa regola, e chi ne cambia una le cambia tutte.
   `.vendita-scarto-nota` E' L'UNICA CHE HA BISOGNO DEL PESO SCRITTO: i `dt`
   sono gia' 400 di loro, mentre la nota vive dentro `.vendita-scarto`, che e'
   700, e senza questa riga lo erediterebbe.
   NOTA STORICA: per qualche ora quel giorno la nota e' stata grande e blu
   come le cifre — era la lettura sbagliata di «stesso stile dei prezzi». Il
   committente ha chiarito: come le ETICHETTE, non come le cifre. */
.vendita-prezzo dt,
.vendita-scarto-nota { color: var(--ink-soft); font-size: .84rem; font-weight: 400; }
.vendita-prezzo dd { font-weight: 700; white-space: nowrap; margin-left: auto; }
/* I DUE PREZZI SI SCRIVONO UGUALI, ED E' UNA RICHIESTA DEL COMMITTENTE
   (14/09/2026): stesso colore, stesso corpo, stesso peso.
   Prima il prezzo di pubblicita' era BARRATO e attenuato — «il numero
   superato dai fatti» — mentre quello di vendita era piu' grande e blu. Il
   committente ha chiesto di togliere la barratura e di pareggiare i due
   valori: chi legge confronta due numeri messi sullo stesso piano, e a dire
   com'e' andata ci pensano l'etichetta sopra e lo scarto sotto.
   >>> I DUE NOMI STANNO SULLA STESSA REGOLA APPOSTA, non su due regole
   gemelle: «uguali» diventa una cosa che il foglio di stile non puo' piu'
   sbagliare, invece di una coincidenza che la prossima modifica rompe
   cambiandone una sola. Vale identico nel riquadro sotto i 1024px piu'
   avanti. Se un giorno tornassero diversi, si separano qui e li'.
   >>> QUI C'ERA `font-weight: 800`, E NON HA MAI FATTO NIENTE. Il peso lo
   decide `.vendita-prezzo dd` piu' su, che vale di piu' (una classe PIU' un
   nome di elemento batte una classe sola): i due prezzi sono sempre stati
   700, misurato sul browser. Tolto perche' una riga che dichiara un valore
   che non si vede manda a cercare il guasto dove non c'e'. Chi volesse
   davvero l'800 lo mette su `.vendita-prezzo dd`, o aggiunge `dd` qui.
   >>> QUI SONO SOLO LE CIFRE. Per qualche ora del 14/09/2026 su questa regola
   c'e' stato anche `.vendita-scarto-nota`, cioe' «rispetto al prezzo di
   pubblicita'»: era la lettura sbagliata della richiesta. Quella non e' una
   cifra ma un'etichetta, e sta con le altre due etichette, piu' su. */
.vendita-prezzo-pubblicita,
.vendita-prezzo-vendita { color: var(--primario); font-size: 1.32rem; }

/* Lo scarto fra i due prezzi. Il colore NON e' semaforico (verde/rosso):
   vendere sotto al prezzo di pubblicita' non e' un fallimento e venderci
   sopra non e' un merito, e due colori d'allarme su una pagina che parla di
   trasparenza direbbero il contrario. Resta il blu, con l'unica differenza
   del segno. */
/* LA MISURA E' QUELLA DEI PREZZI. Era .9rem, cioe' una riga di commento sotto
   ai due numeri; dal 14/09/2026 il committente vuole tutte le CIFRE della
   scheda della stessa misura, e l'importo dello scarto e' una cifra.
   ATTENZIONE A COSA EREDITA CHI STA QUI DENTRO: questa regola vale anche per
   `.vendita-scarto-nota`, che e' un figlio e sarebbe cresciuto con lei. La
   nota e' un'etichetta e non deve crescere, percio' misura, colore e peso
   glieli riscrive la regola delle etichette piu' su — peso compreso, che
   altrimenti erediterebbe il 700 di questa riga. */
.vendita-scarto {
  font-size: 1.32rem; color: var(--primario); font-weight: 700;
  display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap;
}
/* IL PESO 800 QUI FUNZIONA, a differenza di quello tolto dai prezzi: non c'e'
   nessuna regola piu' forte che lo contenda. La percentuale resta l'unica
   cosa in grassetto pieno della riga. */
.vendita-scarto-perc { font-weight: 800; }
/* `.vendita-scarto-nota` NON HA UNA REGOLA SUA, E NON DEVE AVERLA. Fino al
   14/09/2026 stava qui con `font-weight: 400; color: var(--ink-soft);
   font-size: .82rem`: una didascalia attenuata, ma attenuata per conto suo,
   con un .82rem che non corrispondeva all'.84rem delle altre due etichette
   della scheda. Differenza invisibile a occhio e senza nessuna ragione.
   Oggi il suo nome sta sulla regola delle etichette, piu' su: e' la stessa
   cosa delle altre due e si scrive in un posto solo. */

/* ============================================================
   «VENDUTO IN X GIORNI», ULTIMA RIGA DELLA SCHEDA
   ============================================================
   Richiesta del committente del 10/09/2026 (sera). E' l'unica riga della
   scheda scritta tutta in maiuscolo, ed e' voluto: chiude, non si confonde
   con i due prezzi sopra e si legge anche guardando la pagina di sfuggita.

   >>> IL MAIUSCOLO LO METTE QUESTA RIGA, NON IL TESTO NEL CODICE.
   `text-transform` cambia solo come la parola viene disegnata: nel codice
   resta «Venduto in 12 giorni», quindi il testo copiato, la ricerca dentro
   alla pagina e i lettori di schermo trovano parole normali. Scritto
   maiuscolo nel codice, molti lettori di schermo lo compiterebbero lettera
   per lettera.

   `margin-top: auto` LO SPINGE IN FONDO: le schede della griglia sono alte
   uguali (sono celle di una `grid`) e i corpi hanno testi di lunghezza
   diversa. Senza, questa riga resterebbe a mezz'aria a un'altezza diversa
   per ogni scheda. Prima lo faceva il collegamento «Vedi la scheda
   dell'immobile →», che stava proprio qui ed e' stato tolto lo stesso
   giorno. */
/* >>> INGRANDITA IL 22/09/2026 (richiesta del committente), da .82rem a
   .95rem. Il passo e' stato scelto, non preso a caso: le ETICHETTE della
   scheda — i due `dt` dei prezzi e la nota dello scarto — stanno a .84rem, e
   questa riga doveva staccarsi da loro senza arrivare a competere con le
   CIFRE, che sono a 1.32rem. A .95rem resta l'ultima riga che si legge, piu'
   marcata delle didascalie e piu' piccola dei numeri: la gerarchia di
   lettura della scheda non cambia, cambia il peso di questa riga dentro di
   essa. Spingendola oltre il rem comincia a sembrare un secondo titolo. */
.vendita-giorni {
  margin-top: auto; padding-top: 12px;
  text-transform: uppercase; letter-spacing: .06em;
  font-size: .95rem; font-weight: 800; color: var(--primario);
}

/* I due pulsanti in fondo alla pagina stanno su una riga sola finche' c'e'
   spazio; sul telefono la fascia diventa gia' una colonna (vedi
   `.cta-band-inner` nella sezione responsive). */
.cta-band-azioni { display: flex; gap: 12px; flex-wrap: wrap; }

/* ============================================================
   SUL TELEFONO E SUL TABLET I PREZZI SONO PIU' GRANDI
   ============================================================
   Richiesta del committente del 10/09/2026 (sera): «i prezzi devono
   risaltare di piu'» sui dispositivi piccoli.

   >>> PIU' GRANDI SUL PICCOLO, NON PIU' PICCOLI SUL GRANDE, e la differenza
   non e' formale. Di solito un foglio di stile RIDUCE i caratteri quando lo
   schermo si stringe. Qui succede il contrario, ed e' giusto: sul telefono
   la scheda occupa tutta la larghezza dello schermo e la si guarda a
   trenta centimetri dagli occhi, quindi lo spazio per il numero c'e' e la
   scheda non e' piu' una fra tre in fila ma L'unica cosa che si sta
   guardando. Su un monitor le stesse misure sfonderebbero l'equilibrio con
   il titolo dell'immobile, che e' piu' in alto e deve restare il primo dato.

   PERCHE' 1024px E NON 760px. E' la larghezza di un tablet in orizzontale,
   cioe' l'ultimo formato che il committente chiama «tablet». Sopra a quella
   misura la griglia mette gia' due o tre schede in fila e siamo nel caso da
   monitor. Non coincide con nessun'altra soglia del foglio di stile ed e'
   voluto: e' una soglia di leggibilita', non di impaginazione.

   NIENTE INGRANDIMENTO PER LE ETICHETTE, E SONO TRE: «Prezzo di
   pubblicita'», «Prezzo di vendita» (i `dt`) e «rispetto al prezzo di
   pubblicita'» (`.vendita-scarto-nota`). Restano dove sono di proposito: sono
   la didascalia del numero, e ingrandirle insieme avrebbe riportato la scheda
   allo stesso equilibrio di prima, cioe' non avrebbe fatto risaltare niente.
   QUI DENTRO CRESCONO SOLO LE CIFRE, ed e' il senso di tutto il riquadro. */
@media (max-width: 1024px) {
  /* UN NOME SOLO NON BASTAVA: qui i due prezzi erano 1,14rem e 1,68rem, cioe'
     e' QUESTO il punto in cui «stessa grandezza» si rompeva sul telefono
     anche dopo aver pareggiato la regola di base. Ingranditi insieme, e con
     loro l'importo dello scarto e la percentuale, che sono cifre anche loro.
     `.vendita-scarto-nota` NON STA QUI, e non e' una dimenticanza: e'
     un'etichetta, e le etichette non crescono (vedi il commento qui sopra).
     Per qualche ora del 14/09/2026 ci e' stata, ed era sbagliato. */
  .vendita-prezzo-pubblicita,
  .vendita-prezzo-vendita,
  .vendita-scarto,
  .vendita-scarto-perc { font-size: 1.68rem; }
  /* SUL TELEFONO RESTA PIU' GRANDE CHE SUL COMPUTER, com'era gia' dal
     10/09/2026: qui la scheda e' larga quanto lo schermo e i numeri sopra
     crescono a 1.68rem, quindi questa riga deve crescere con loro o sparisce
     in fondo alla scheda. Il rapporto fra le due misure e' rimasto quello di
     prima (.92/.82 diventa 1.05/.95). */
  .vendita-giorni { font-size: 1.05rem; }
}

@media (max-width: 760px) {
  /* QUI C'ERA `.vendite-riepilogo { grid-template-columns: 1fr; … }`, che
     impilava in colonna i tre numeri della fascia. Tolta il 22/09/2026 con la
     fascia stessa: vedi il commento piu' in alto. */
  .vendite-griglia { grid-template-columns: 1fr; }
}

/* ============================================================
   PAGINA «DICONO DI NOI»
   ============================================================
   Le singole recensioni NON riusano la scheda della homepage: sono la stessa
   scheda, lo stesso HTML, prodotto da `schedaRecensione()` di
   src/views/recensione.js. Qui cambia soltanto come sono disposte. */
.recensioni-testata {
  display: flex; align-items: center; gap: 28px; flex-wrap: wrap;
  background: var(--bg-alt); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 26px 28px; margin-bottom: 32px;
}
.recensioni-punteggio { text-align: center; line-height: 1; }
.recensioni-punteggio-numero { display: block; font-size: 3.4rem; font-weight: 800; color: var(--primario); }
.recensioni-punteggio-su { display: block; font-size: .82rem; color: var(--ink-soft); margin-top: 6px; }
.recensioni-testata-testo { flex: 1; min-width: 240px; }
.recensioni-stelle-grandi { color: var(--stella-oro); letter-spacing: .12em; font-size: 1.4rem; line-height: 1; }
.recensioni-testata .recensioni-conta { margin-top: 10px; color: var(--ink-soft); }
.recensioni-azioni { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 16px; }

/* ============================================================
   IL MURO: LE RECENSIONI A INCASTRO (dal 10/09/2026)
   ============================================================
   PRIMA ERA UNA GRIGLIA, e una griglia ragiona per righe: dentro a una riga
   la scheda piu' alta detta l'altezza della riga, e sotto alle altre resta
   il vuoto. Con `align-items: start` il vuoto usciva dalla scheda (che
   finiva col suo testo, ed era gia' giusto cosi') ma restava nella pagina:
   quindici recensioni che vanno da zero a 636 caratteri lasciavano buchi
   bianchi quasi a ogni riga.

   ADESSO E' UN IMPAGINATO A COLONNE. Le schede scorrono in colonna e ognuna
   si appoggia sotto alla precedente, senza aspettare nessuno: dove finisce
   il testo finisce la scheda e comincia quella dopo. Il pareggio delle
   colonne lo fa il browser da solo, ed e' questo che toglie i vuoti in fondo.

   PERCHE' `columns` E NON UNA GRIGLIA A INCASTRO. Perche' l'incastro vero di
   CSS (`grid-template-rows: masonry`) nel 2026 non e' ancora acceso in tutti
   i browser, e l'alternativa e' calcolare le altezze con JavaScript e
   ricalcolarle a ogni ridimensionamento e a ogni carattere che finisce di
   caricarsi. `columns` fa la stessa cosa da sola, e la fa dal 2011.

   >>> SI LEGGE PER COLONNE (prima colonna dall'alto in basso, poi la
   seconda), non per righe. Per un muro di recensioni va bene; per un elenco
   in cui la POSIZIONE vuol dire qualcosa — i piu' recenti, i piu' importanti
   — non andrebbe bene, e questa e' la riga da rileggere prima di riusare
   `columns` altrove.

   Il numero di colonne non e' scritto da nessuna parte: si dichiara quanto
   dev'essere larga una colonna (340px) e al massimo quante (3), il resto lo
   conta il browser. Sul telefono ne fa una, sul tablet due. */
.recensioni-elenco {
  columns: 340px 3;
  column-gap: 22px;
}
.recensioni-elenco .recensione {
  /* Lo stacco fra una scheda e la successiva e' un margine, non un `gap`:
     in un impaginato a colonne `column-gap` separa le COLONNE, non le
     schede una sopra l'altra. */
  margin: 0 0 22px;
  /* NESSUNA SCHEDA VA SPEZZATA FRA DUE COLONNE. Senza questa riga una
     recensione lunga finisce per meta' in fondo a una colonna e per meta' in
     cima alla successiva — bordo, ombra e virgolette tagliati a meta'.
     La riga `-webkit-` serve ai Safari piu' vecchi, che conoscono solo
     quella: e' la stessa dichiarazione, non un ripiego diverso. */
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
}

.recensioni-fonte {
  margin-top: 26px; padding-top: 18px; border-top: 1px solid var(--line);
  color: var(--ink-soft); font-size: .9rem;
}

@media (max-width: 620px) {
  .recensioni-testata { gap: 18px; padding: 22px 20px; }
  .recensioni-punteggio-numero { font-size: 2.6rem; }
  /* Una colonna sola. In verita' ci arriverebbe da se' (sotto ai 620px non
     c'e' spazio per due colonne da 340px), ma scritta rende la cosa
     leggibile a chi cambia quelle misure: `grid-template-columns` qui non
     avrebbe piu' alcun effetto, perche' questo non e' piu' un `grid`. */
  .recensioni-elenco { columns: 1; }
}

/* ============================================================
   OPENHOUSE: pagina pubblica di prenotazione
   Pensata prima per il telefono: chi riceve il link in chat lo apre da lì.
   ============================================================ */
.oh-hero { background: var(--primario); color: #fff; padding: 40px 0 34px; }
.oh-hero-inner { text-align: center; }
.oh-kicker { text-transform: uppercase; letter-spacing: .14em; font-size: .74rem; font-weight: 700; color: #fff; margin-bottom: 10px; }
.oh-hero h1 { color: #fff; font-size: clamp(1.5rem, 4vw, 2.2rem); margin-bottom: 10px; }
.oh-indirizzo { display: inline-flex; align-items: center; gap: 6px; font-size: .95rem; }
.oh-durata { margin-top: 8px; font-size: .9rem; }

.oh-grid { display: grid; grid-template-columns: 1fr 320px; gap: 36px; align-items: start; }
.oh-colonna { min-width: 0; }
.oh-aside { position: sticky; top: 20px; }
.oh-foto { width: 100%; border-radius: var(--radius); margin-bottom: 16px; aspect-ratio: 3/2; object-fit: cover; }
.oh-prezzo { color: var(--ink); font-weight: 800; font-size: 1.4rem; margin-bottom: 8px; }
.oh-specs { list-style: none; display: flex; gap: 16px; flex-wrap: wrap; font-size: .9rem; color: var(--ink-soft); margin-bottom: 12px; }
.oh-nota { background: #FFF6E5; border-left: 3px solid #E8B93B; padding: 10px 12px; border-radius: 6px; font-size: .88rem; margin: 12px 0; }

.oh-giorni { display: flex; flex-direction: column; gap: 10px; margin: 20px 0; }
.oh-giorno { border: 1.5px solid var(--line); border-radius: var(--radius); overflow: hidden; background: #fff; }
.oh-giorno[open] { border-color: var(--primario); }
.oh-giorno summary {
  cursor: pointer; padding: 14px 18px; font-weight: 700; color: var(--primario);
  display: flex; justify-content: space-between; align-items: center; gap: 12px; list-style: none;
}
.oh-giorno summary::-webkit-details-marker { display: none; }
.oh-giorno summary:hover { background: var(--bg-alt); }
.oh-giorno-nome { text-transform: capitalize; }
.oh-giorno-conta { font-size: .8rem; font-weight: 600; color: var(--ink-soft); }
.oh-slots { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 9px; padding: 4px 18px 18px; }
.oh-slot {
  padding: 12px 6px; border: 1.5px solid var(--line); border-radius: 9px;
  background: #fff; font: inherit; font-size: .95rem; font-weight: 600; color: var(--primario);
  cursor: pointer; transition: border-color .15s, background .15s, color .15s;
  /* Bersaglio comodo da toccare: sotto i 44px il dito sbaglia. */
  min-height: 46px;
}
.oh-slot:hover { border-color: var(--primario); color: var(--primario); }
.oh-slot:focus-visible { outline: 2px solid var(--primario); outline-offset: 2px; }
.oh-slot-scelto { background: var(--primario); border-color: var(--primario); color: #fff; }

.oh-riepilogo { background: var(--bg-alt); border-radius: var(--radius); padding: 14px 18px; margin: 18px 0; }
.oh-riepilogo p { margin: 0; }
.oh-cambia { background: none; border: 0; color: var(--primario); text-decoration: underline; cursor: pointer; font: inherit; font-size: .9rem; margin-left: 8px; }

.oh-dati { background: #fff; border: 1.5px solid var(--line); border-radius: var(--radius); padding: 22px; margin-top: 18px; }
.oh-dati h3 { margin-bottom: 14px; }
.oh-dati label { display: block; font-size: .85rem; font-weight: 600; color: var(--primario); margin: 12px 0 5px; }
.oh-dati input:not([type="checkbox"]), .oh-dati textarea {
  width: 100%; padding: 12px 14px; border: 1.5px solid var(--line); border-radius: 9px;
  font: inherit; font-size: 1rem; background: #fff;
}
.oh-dati input:focus, .oh-dati textarea:focus { outline: 2px solid var(--primario); outline-offset: 1px; }
.oh-dati .privacy-check { display: flex; align-items: start; gap: 9px; font-size: .87rem; font-weight: 400; color: var(--ink-soft); margin: 14px 0; line-height: 1.5; }
.oh-dati .privacy-check input { margin-top: 3px; flex: none; }
.oh-dati .form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.oh-dati button[type="submit"] { margin-top: 18px; }
.oh-nota-finale { text-align: center; margin-top: 12px; }
.oh-campo-aiuto { margin: -6px 0 4px; font-size: .82rem; line-height: 1.5; }
/* Conferma d'invio della ricevuta: è la prova, per chi ha appena prenotato,
   che l'email è partita e a quale indirizzo. */
.oh-email-avviso {
  display: flex; align-items: flex-start; gap: 10px; text-align: left;
  background: #E7F5EA; border: 1px solid #B5DFC0; color: #175226;
  border-radius: 10px; padding: 13px 16px; margin: 18px 0; font-size: .93rem; line-height: 1.55;
}
.oh-email-avviso svg { flex: none; margin-top: 2px; }

.oh-conferma { max-width: 620px; margin: 0 auto; text-align: center; padding: 40px 20px; }
.oh-check {
  width: 78px; height: 78px; border-radius: 50%; background: #E7F5EA; color: var(--ok);
  display: flex; align-items: center; justify-content: center; margin: 0 auto 22px;
}
.oh-quando { font-size: 1.2rem; color: var(--primario); margin-bottom: 20px; text-transform: capitalize; }
.oh-dettagli { text-align: left; margin: 22px 0; }
.oh-azioni { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin: 26px 0; }

@media (max-width: 880px) {
  .oh-grid { grid-template-columns: 1fr; gap: 24px; }
  .oh-aside { position: static; order: -1; }
  .oh-foto { aspect-ratio: 16/9; }
}
@media (max-width: 520px) {
  .oh-dati .form-row { grid-template-columns: 1fr; }
  .oh-slots { grid-template-columns: repeat(auto-fill, minmax(74px, 1fr)); padding: 4px 12px 14px; }
}

/* Tabella dentro le pagine legali: deve restare leggibile sul telefono,
   quindi scorre in orizzontale invece di far scorrere tutta la pagina. */
.legal-text { max-width: 820px; }
.legal-text h2 { margin: 28px 0 10px; font-size: 1.15rem; }
.legal-text p, .legal-text li { margin-bottom: 10px; }
.legal-text ul { margin: 0 0 14px 20px; }
.legal-table { width: 100%; border-collapse: collapse; font-size: .88rem; margin: 14px 0 22px; display: block; overflow-x: auto; }
.legal-table th { text-align: left; background: var(--bg-alt); padding: 9px 11px; border-bottom: 2px solid var(--line); font-size: .78rem; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-soft); }
.legal-table td { padding: 9px 11px; border-bottom: 1px solid var(--line); vertical-align: top; min-width: 130px; }

/* ============================================================
   FIRMA DELLA MAPPA
   Leaflet disegna una bandiera accanto al proprio nome nella firma in basso
   a destra. Qui si nasconde SOLO quella: il testo della fonte
   (OpenStreetMap, Leaflet) resta visibile e cliccabile, perche' la licenza
   dei dati cartografici ne impone la citazione.
   Il vero intervento e' nel JavaScript delle mappe, che imposta una firma
   senza bandiera; questa regola e' la seconda rete, per le mappe che un
   domani venissero create senza passare da li'.
   ============================================================ */
.leaflet-container .leaflet-attribution-flag { display: none !important; }

/* ============================================================
   CAROSELLO DEGLI IMMOBILI (homepage)

   Due sole frecce, una per lato. Niente barra di scorrimento, niente pallini,
   niente "3 di 12": erano tre modi di dire la stessa cosa e nessuno dei tre
   aiutava a scegliere una casa.

   Sotto c'e' un contenitore che scorre davvero, con aggancio ai bordi delle
   schede. Cosi' funziona col dito sul telefono, con la rotellina e con la
   tastiera; e se il JavaScript non parte, le schede restano scorrevoli.
   ============================================================ */
.carosello { position: relative; }
.carosello-pista {
  display: grid; grid-auto-flow: column;
  /* Tre schede per volta su schermo largo, con lo stesso spazio della griglia.
     La quarta si intravede appena oltre il bordo: e' quello che dice "ce ne
     sono altre" senza bisogno di un indicatore. */
  grid-auto-columns: calc((100% - 52px) / 3);
  gap: 26px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  /* La barra di scorrimento si nasconde: la richiesta era esplicita, e con le
     frecce sempre presenti non serve. Il contenitore resta comunque
     raggiungibile da tastiera (tabindex nell'HTML). */
  scrollbar-width: none;
  -ms-overflow-style: none;
  /* Spazio per non tagliare l'ombra delle schede durante lo scorrimento. */
  padding: 6px 4px 10px;
}
.carosello-pista::-webkit-scrollbar { display: none; }
.carosello-pista > * { scroll-snap-align: start; }
.carosello-pista:focus-visible { outline: 2px solid var(--primario); outline-offset: 4px; border-radius: var(--radius); }

.carosello-freccia {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 3;
  width: 46px; height: 46px; border-radius: 50%; border: 0; cursor: pointer;
  background: var(--primario); color: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-lg);
  transition: background .15s, opacity .15s;
}
.carosello-freccia:hover { background: #fff; color: var(--primario); box-shadow: inset 0 0 0 2px var(--primario), var(--shadow-lg); }
.carosello-freccia:focus-visible { outline: 2px solid var(--primario); outline-offset: 3px; }
/* Ai due estremi la freccia resta al suo posto ma smette di essere premibile:
   sparire farebbe saltare le schede a destra e a sinistra a ogni scorrimento. */
.carosello-freccia[disabled] { opacity: .28; cursor: default; background: var(--primario); }
.carosello-prec { left: -22px; }
.carosello-succ { right: -22px; }

@media (max-width: 1240px) {
  /* Sotto la larghezza massima del contenitore le frecce non hanno piu'
     margine esterno: rientrano sopra le schede. */
  .carosello-prec { left: 6px; }
  .carosello-succ { right: 6px; }
}
@media (max-width: 960px) { .carosello-pista { grid-auto-columns: calc((100% - 26px) / 2); } }
@media (max-width: 640px) { .carosello-pista { grid-auto-columns: 100%; } }

/* ============================================================
   I PALLINI DEL CAROSELLO: SOLO SUL TELEFONO
   ============================================================
   Sotto i 760px le frecce spariscono e al loro posto compare una fila di
   pallini, uno per immobile. Due motivi, entrambi pratici:

   - le frecce stavano sui bordi dello schermo, esattamente dove passa il
     pollice mentre si scorre, e su una scheda larga quanto la pagina
     coprivano la fotografia;
   - col dito si scorre e basta, un comando non serve. Serve invece sapere
     a che punto si e' arrivati e quanti immobili restano, che e' l'unica
     cosa che le frecce non dicevano.

   I pallini restano premibili: chi vuole tornare al terzo immobile lo fa
   con un tocco invece di scorrere all'indietro.

   FINESTRA SCORREVOLE. Gli immobili disponibili possono essere venti: venti
   pallini su uno schermo da telefono diventano una riga di puntini
   indistinguibili. Se ne mostrano al piu' sette (`--punti-visibili`), la
   fila scorre sotto una finestra fissa e i due ai bordi si rimpiccioliscono
   per far capire che l'elenco continua. E' il comportamento a cui si e'
   abituati sulle gallerie dei telefoni.

   Il contenitore nasce con `hidden` nel codice HTML: se JavaScript non parte
   non resta un rettangolo vuoto sotto le schede. */
.carosello-punti { display: none; }

@media (max-width: 760px) {
  .carosello-freccia { display: none !important; }

  .carosello-punti[hidden] { display: none; }
  .carosello-punti {
    --punto: 9px;          /* diametro del pallino */
    --passo: 22px;         /* pallino + spazio: e' il passo dello scorrimento */
    --punti-visibili: 7;
    display: block;
    /* LA FINESTRA E' LARGA QUANTO I PALLINI CHE CI SONO DAVVERO.
       Prima era fissa a sette passi anche quando gli immobili erano quattro:
       la finestra restava centrata nella pagina, ma i quattro pallini si
       appoggiavano al suo bordo sinistro e finivano 33 pixel piu' a sinistra
       del centro (meta' dei tre passi vuoti). Sul telefono, sotto una scheda
       larga quanto lo schermo, lo scarto si vedeva a occhio nudo.
       `max-content` fa misurare la finestra sui pallini presenti; il tetto la
       ferma comunque a sette quando ce ne sono di piu', e da li' in poi
       ricomincia a scorrere sotto la finestra come prima. */
    width: max-content;
    max-width: min(100%, calc(var(--passo) * var(--punti-visibili)));
    margin: 16px auto 0;
    overflow: hidden;
  }
  .carosello-punti-pista {
    display: flex; align-items: center; justify-content: flex-start;
    transition: transform .28s ease;
  }
  .carosello-punto {
    flex: 0 0 var(--passo);
    height: var(--passo);
    padding: 0; border: 0; background: none; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
  }
  .carosello-punto::before {
    content: ''; display: block;
    width: var(--punto); height: var(--punto); border-radius: 50%;
    background: var(--primario); opacity: .28;
    transition: opacity .2s ease, transform .2s ease;
  }
  .carosello-punto[aria-current]::before { opacity: 1; transform: scale(1.25); }
  /* I due ai bordi della finestra si rimpiccioliscono: dicono "l'elenco
     continua" senza aggiungere una freccia o un numero. */
  .carosello-punto-bordo::before { transform: scale(.6); }
  .carosello-punto:focus-visible { outline: 2px solid var(--primario); outline-offset: 2px; border-radius: 50%; }
}

@media (prefers-reduced-motion: reduce) {
  .carosello-punti-pista { transition: none; }
  .carosello-punto::before { transition: none; }
}

/* ============================================================
   FOTO SFOGLIABILI DALLA SCHEDA
   Come su qualunque portale immobiliare: due frecce sopra l'immagine
   cambiano fotografia senza aprire la pagina dell'immobile.
   ============================================================ */
.prop-card-foto-pila { position: absolute; inset: 0; }
.prop-card-foto {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transition: opacity .18s;
}
.prop-card-foto.attiva { opacity: 1; }
/* Il collegamento alla scheda copre tutta l'immagine e sta SOTTO alle frecce:
   e' quello che permette di avere pulsanti veri sopra a un'area cliccabile
   senza annidare un <button> dentro a un <a>, che non e' HTML valido. */
.prop-card-link { position: absolute; inset: 0; z-index: 1; }
.prop-card-foto-nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 32px; height: 32px; border-radius: 50%; border: 0; cursor: pointer;
  background: #fff; color: var(--primario);
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow);
  /* Sul computer compaiono al passaggio del mouse, per non sporcare la foto.
     Sul telefono (dove il passaggio del mouse non esiste) sono sempre visibili:
     vedi la regola pointer: coarse piu' sotto. */
  opacity: 0; transition: opacity .15s, background .15s;
}
.prop-card:hover .prop-card-foto-nav,
.prop-card-foto-nav:focus-visible { opacity: 1; }
.prop-card-foto-nav:hover { background: var(--bg-alt); }
.prop-card-foto-prev { left: 10px; }
.prop-card-foto-next { right: 10px; }
@media (pointer: coarse) { .prop-card-foto-nav { opacity: 1; } }
.prop-badge, .prop-photos-count { z-index: 2; }

/* ============================================================
   DICONO DI NOI: le recensioni Google
   ============================================================ */
.recensioni-sintesi { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; color: var(--ink-soft); font-size: .95rem; margin-top: -10px; }
.recensioni-voto { font-weight: 800; font-size: 1.25rem; color: var(--primario); }
.recensioni-stelle { color: var(--stella-oro); letter-spacing: .08em; }
.recensioni-conta { font-size: .9rem; }

/* LE TRE SCHEDE STANNO IN UNA RIGA SOLA E NON SI ALTERNANO PIU'
   (10/09/2026, pomeriggio).

   COSA C'ERA QUI FINO A STAMATTINA, e perche' non c'e' piu'. Le quindici
   recensioni giravano a gruppi di tre: i gruppi si scambiavano ogni sette
   secondi, quello fuori vista aveva `display: none`, quello che entrava una
   comparsa breve (`@keyframes recensione-entra`), e sotto c'erano i pallini
   (`.recensioni-punti`). Insieme a loro se ne sono andate `.recensioni-piste`
   e `.recensioni-giostra`, che erano i contenitori della pila. Il committente
   ha chiesto tre recensioni ferme, scelte a mano, e un pulsante che porti a
   /dicono-di-noi: quali siano lo dice `RECENSIONI_IN_VETRINA` in
   src/views/home.js, e il codice della giostra sta in `.backup-2026-09-10/`.

   >>> CON LA GIOSTRA E' SPARITO IL PROBLEMA PIU' GROSSO DI STAMATTINA, e vale
   la pena scriverlo perche' mezzo foglio di stile e mezzo documento di
   consegna parlavano di lui: da quando ogni scheda e' alta quanto il suo
   testo i gruppi non erano piu' alti uguali, quindi la sezione CAMBIAVA
   ALTEZZA a ogni scambio (227px misurati su schermo largo, 260px sul
   telefono) e le tre sezioni sotto si spostavano. Era il prezzo dichiarato
   della scelta della mattina, e c'erano tre strade per pagarlo meno — un
   tetto alle righe del testo, un contenitore ad altezza fissa, niente cambio
   automatico. Non ne serve piu' nessuna: senza scambio non c'e' salto.
   Ne restano tolte anche le tracce: il tetto delle nove righe (che era gia'
   stato scartato perche' una scheda tagliata finisce dove finisce il tetto e
   non dove finisce il testo) e `gruppiBilanciati()` in src/views/home.js, che
   mescolava le lunghezze per tenere i gruppi simili fra loro.

   `auto-fit` E NON `auto-fill`: le schede adesso sono tre e basta. Con
   `auto-fill` il browser continuerebbe a creare colonne vuote quando ci sta,
   e su uno schermo molto largo le tre schede si stringerebbero lasciando un
   buco a destra; `auto-fit` fa collassare le colonne che non hanno niente
   dentro. Non e' pero' l'unica cosa che serve: vedi il salto da tre colonne a
   una qui sotto.

   `align-items: start` E' LA RIGA DA NON TOGLIERE: e' quella che tiene ogni
   scheda alta quanto il suo testo. Basta cambiarla in `stretch` per riavere
   le tre schede pari — ma pari all'altezza della piu' alta, cioe' con il
   vuoto sotto alle altre due: e' esattamente il difetto che il committente ha
   fatto correggere la mattina del 10/09/2026. Le tre in vetrina sono state
   scelte da lui perche' si somigliano gia' (misurate a 365px di colonna:
   234px, 310px, 335px), non perche' qualcuno le pareggi a forza. */
.recensioni-griglia {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); gap: 22px;
  align-items: start; margin-top: 24px;
}

/* IL PULSANTE VERSO L'ELENCO COMPLETO, centrato sotto alle tre schede.
   Non e' decorazione: tolta la giostra, le altre dodici recensioni non sono
   raggiungibili in nessun altro modo dalla homepage — il collegamento in
   testata porta alla scheda Google, cioe' fuori dal sito.
   Contorno e non pieno: la sezione ha gia' un fondo grigio (`section-alt`) e
   un pulsante blu pieno qui peserebbe piu' delle recensioni che deve
   accompagnare. */
.recensioni-azione { margin-top: 26px; text-align: center; }

/* SI PASSA DA TRE COLONNE A UNA, SENZA FERMARSI A DUE — ED E' IL PUNTO DI
   QUESTA REGOLA. Lasciato a se stesso, fra i 620 e i 960 pixel (tablet in
   verticale, finestra stretta su un portatile) `auto-fit` faceva stare due
   schede per riga: le prime due affiancate e la terza sola sotto, con
   accanto un buco largo mezza pagina. Tre schede non si dispongono su due
   colonne senza che una resti spaiata — e' aritmetica, non impaginazione —
   quindi sotto ai 960px si incolonnano tutte e tre.
   960px e' la misura in cui tre colonne da 290px stanno ancora esatte
   (290x3 + 22x2 di stacco + 40 di margini = 954): sopra ci stanno, sotto no.
   >>> SE UN GIORNO LE SCHEDE IN VETRINA DIVENTASSERO DUE O QUATTRO questa
   riga va riguardata: `auto-fit` sopra ai 960px si arrangia da solo (con due
   schede fa due colonne, non tre con un vuoto), ma la soglia qui sotto e'
   scritta pensando a tre. */
@media (max-width: 960px) {
  .recensioni-griglia { grid-template-columns: 1fr; }
}

.recensione {
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
  padding: 24px 22px 20px; box-shadow: var(--shadow); margin: 0;
  display: flex; flex-direction: column; gap: 14px;
}
/* Le virgolette aperte fanno da segno grafico al posto della fotografia del
   recensore, che Google non consente di ripubblicare. */
.recensione-stelle { color: var(--stella-oro); letter-spacing: .1em; font-size: 1.05rem; line-height: 1; }
.recensione-stelle-vuote { color: var(--line); }
.recensione blockquote { position: relative; padding-top: 18px; }
.recensione blockquote::before {
  content: '\201C'; position: absolute; top: -14px; left: -4px;
  font-size: 3.4rem; line-height: 1; color: var(--primario); font-family: Georgia, 'Times New Roman', serif;
}
/* GLI «A CAPO» DEL RECENSORE SI VEDONO (`pre-line`), e non e' un vezzo
   tipografico: parecchie recensioni sono scritte a capoversi («Abbiamo appena
   acquistato la nostra prima casa. / Un professionista competente... /
   Consigliatissimo!») e appiattite in un blocco unico diventano un muro che
   non si legge. `pre-line` tiene gli a capo e continua a riunire gli spazi
   doppi, che e' esattamente cio' che serve su un testo incollato da fuori.
   >>> GLI A CAPO DEVONO ESSERE QUELLI VOLUTI: un testo copiato da una colonna
   stretta arriva spezzato a meta' frase, e qui si vedrebbe spezzato. Le
   quindici recensioni consegnate sono state ricucite a mano per questo (vedi
   la nota in `src/recensioni-consegnate.js`). */
.recensione blockquote p { font-size: .96rem; color: var(--ink); white-space: pre-line; }
/* IL NOME STA SUBITO SOTTO AL TESTO. Fino al 10/09/2026 c'era
   `margin-top: auto`, che lo spingeva in fondo alla scheda: serviva a tenere
   allineati i nomi di tre schede affiancate, quando le schede erano alte
   uguali per forza. Ora che ognuna e' alta quanto il suo testo non c'e' piu'
   nessun fondo verso cui spingere — `auto` non avrebbe piu' niente da
   distribuire — e il nome sta attaccato a cio' che si e' appena letto. */
.recensione figcaption { font-weight: 700; color: var(--primario); font-size: .9rem; }
.recensione-data { font-weight: 400; color: var(--ink-soft); }

/* LA RECENSIONE SENZA TESTO — cinque stelle e il nome, niente altro: su
   Google si puo' fare, e l'agenzia ne ha una (Graziana Tardino) — NON HA PIU'
   BISOGNO DI UNA REGOLA SUA, e la classe `.recensione-senzaTesto` e' stata
   tolta anche dall'HTML il 10/09/2026. Serviva ad azzerare il
   `margin-top: auto` del nome, che in una scheda alta per forza e senza
   testo lasciava le stelle in cima e il nome dieci centimetri sotto. Tolto
   l'`auto` (vedi qui sopra) e tolta l'altezza imposta, quella scheda e' due
   righe e finisce li' da sola.
   Il `<blockquote>` continua a non essere disegnato affatto: lo salta la
   vista, vedi `schedaRecensione()` in src/views/recensione.js. */

/* La colonna dei servizi nella pagina Chi siamo: stessa scheda delle altre,
   ma con un po' d'aria sopra perche' segue i badge. */
.info-card-servizi { margin-top: 26px; }
.agency-side .section-title { margin-bottom: 16px; }
/* Quando tutte le schede stanno gia' a schermo il carosello non ha niente da
   scorrere: le frecce vengono tolte invece di restare spente. */
.carosello-fermo .carosello-freccia { display: none; }
.carosello-fermo .carosello-pista { scroll-snap-type: none; }

/* I PULSANTI FISSI SUL TELEFONO.
   Restano dove sono (in basso a destra: e' il posto in cui li si cerca), ma
   rimpiccioliti. Motivo concreto, misurato: a schermo stretto un pulsante a
   tutta larghezza - per esempio "Conferma la visita" nella pagina Openhouse -
   passa sotto alla colonna, e la porzione coperta riceve il tocco al posto
   suo. Con i cerchi a 58px erano 33 pixel di pulsante su 289; a 48px si
   scende a 23, e la colonna resta comunque un bersaglio comodo da toccare
   (il minimo consigliato e' 44). Il centro del pulsante, che e' dove il
   pollice va davvero, e' libero in entrambi i casi. */
@media (max-width: 760px) {
  .float-actions { right: 12px; bottom: 12px; gap: 10px; }
  .float-btn { width: 48px; height: 48px; }
  .float-btn svg { width: 24px; height: 24px; }
}

/* ============================================================
   LA FOTOGRAFIA A SCHERMO INTERO (schede immobile)
   ============================================================
   Richiesta del committente del 01/09/2026: premendo una fotografia
   dell'annuncio deve aprirsi grande, su computer, tablet e telefono.

   E' un riquadro nero costruito da main.js e appeso in fondo alla pagina,
   non l'apertura a schermo intero del browser: `requestFullscreen()` su
   iPhone e iPad non esiste per le immagini, e su quei dispositivi il tocco
   non avrebbe fatto niente. La nota lunga sta in main.js.

   ALTEZZA: PRIMA `100vh`, POI `100dvh` PER CHI LO CONOSCE.
   Sul telefono la barra dell'indirizzo compare e sparisce mentre si scorre;
   `100vh` e' l'altezza calcolata CON la barra nascosta, quindi finche' la
   barra c'e' il riquadro e' piu' alto dello schermo e il contatore in basso
   resta tagliato fuori. `100dvh` segue l'altezza vera. Le due righe in
   quest'ordine: i browser che non conoscono `dvh` ignorano la seconda e
   tengono la prima, invece di ritrovarsi senza altezza.

   `object-fit: contain`: la fotografia si vede INTERA. Nella pagina e'
   ritagliata a 3:2 per tenere le schede tutte uguali; qui il ritaglio non
   deve esserci, perche' il motivo per cui la si apre grande e' vedere
   quello che nel ritaglio non entrava. */
.foto-schermo {
  position: fixed; inset: 0; z-index: 2000;
  display: flex; align-items: center; justify-content: center;
  height: 100vh;
  height: 100dvh;
  padding: 16px;
  background: rgba(6, 9, 16, .97);
  /* Il dito che scorre sull'immagine non deve trascinare la pagina dietro. */
  overscroll-behavior: contain;
  animation: foto-schermo-entra .18s ease-out;
}
.foto-schermo[hidden] { display: none; }
@keyframes foto-schermo-entra { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .foto-schermo { animation: none; } }

.foto-schermo-img {
  max-width: 100%; max-height: 100%;
  width: auto; height: auto;
  object-fit: contain;
  border-radius: 4px;
  /* L'immagine e' l'unica cosa che non chiude il riquadro quando la si
     preme: il fondo si', l'immagine no (vedi main.js). */
  cursor: default;
}

/* I COMANDI SONO BIANCHI SU UN CERCHIO SCURO, non bianchi e basta: una
   fotografia puo' avere un angolo bianco (un muro, una parete, il cielo) e
   li' una X bianca sparirebbe. Il cerchio garantisce il contrasto su
   qualunque immagine. */
.foto-schermo-chiudi,
.foto-schermo-freccia {
  position: absolute; z-index: 1;
  display: flex; align-items: center; justify-content: center;
  border: 0; cursor: pointer; color: #fff;
  background: rgba(8, 12, 20, .55);
  border-radius: 50%;
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
}
.foto-schermo-chiudi:hover,
.foto-schermo-freccia:hover { background: rgba(8, 12, 20, .85); }
.foto-schermo-chiudi:focus-visible,
.foto-schermo-freccia:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

/* 48px e non 44: e' un bersaglio che si preme col pollice, spesso in piedi e
   con una mano sola. `max(...)` tiene i comandi fuori dalla tacca e dalla
   barra di sistema sui telefoni con lo schermo a tutta faccia. */
.foto-schermo-chiudi {
  top: max(14px, env(safe-area-inset-top)); right: max(14px, env(safe-area-inset-right));
  width: 48px; height: 48px;
}
.foto-schermo-freccia { top: 50%; transform: translateY(-50%); width: 52px; height: 52px; }
.foto-schermo-prec { left: max(12px, env(safe-area-inset-left)); }
.foto-schermo-succ { right: max(12px, env(safe-area-inset-right)); }

.foto-schermo-conta {
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: max(16px, env(safe-area-inset-bottom));
  color: #fff; font-size: .9rem; font-weight: 600;
  background: rgba(8, 12, 20, .55); padding: 6px 14px; border-radius: 999px;
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
}

/* SUL TELEFONO LE FRECCE SPARISCONO. Stanno esattamente dove passa il
   pollice mentre si scorre la fotografia col dito, e su uno schermo stretto
   coprono un quinto dell'immagine per lato. Si sfoglia trascinando, che e'
   il gesto che si fa d'istinto; il contatore dice a che punto si e'. E' la
   stessa scelta gia' fatta per il carosello della homepage. */
@media (max-width: 760px) {
  .foto-schermo { padding: 0; }
  .foto-schermo-freccia { display: none; }
  .foto-schermo-img { border-radius: 0; }
}

/* La pagina sotto non scorre mentre la fotografia e' aperta.
   `position: fixed` sarebbe piu' sicuro ma fa saltare la pagina all'inizio
   alla chiusura: `overflow: hidden` conserva il punto in cui si era. */
body.foto-schermo-aperto { overflow: hidden; }

/* Il segnale che la fotografia si puo' aprire.
   Il puntatore a lente lo vede solo chi ha un mouse: sul telefono l'unico
   segnale e' il comando in basso a destra, qui sotto. */
.gallery-main-img-ingrandibile { cursor: zoom-in; }
.gallery-espandi {
  position: absolute; right: 12px; bottom: 12px;
  width: 40px; height: 40px; border: 0; border-radius: 9px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  background: var(--primario-velo); color: #fff;
}
.gallery-espandi:hover { background: var(--primario); }
.gallery-espandi:focus-visible { outline: 2px solid #fff; outline-offset: -3px; }
/* Il contatore delle foto sta nello stesso angolo: si sposta a sinistra del
   comando invece di finirci sotto. */
.gallery-main:has(.gallery-espandi:not([hidden])) .gallery-counter { right: 62px; }

/* ---------- Cartellino DEMO (vedi floatingActions in views/layout.js) ---------- */
.demo-cartellino {
  position: fixed; left: 14px; bottom: 14px; z-index: 60;
  margin: 0; padding: 7px 12px; border-radius: 999px;
  background: var(--ink); color: #fff; font-size: .72rem; letter-spacing: .02em;
  box-shadow: var(--shadow); pointer-events: none; opacity: .92;
}
.demo-cartellino strong { color: #F3C9A8; letter-spacing: .08em; }
.demo-corto { display: none; }
@media (max-width: 760px) {
  .demo-cartellino { font-size: .66rem; left: 10px; bottom: 10px; padding: 6px 10px; }
  .demo-lungo { display: none; }
  .demo-corto { display: inline; }
}

/* Avviso sulle pagine legali della demo (vedi legalPage in views/pages.js). */
.nota-demo-legale {
  background: var(--bg-alt); border-left: 4px solid var(--primario);
  padding: 12px 16px; border-radius: 8px; margin-bottom: 24px;
}
