:root {
  /* Round-24 — the colours are the client's brand sheet, to the digit.
     Names are kept from the earlier system so every page re-skins at once:
     --ink is "blu notte", --ink-70 is "blu acciaio" (the reading colour),
     --paper is "avorio caldo" (the page), --ivory is "sabbia chiara". */
  --ink:        #0e1b33;   /* blu notte      */
  --ink-deep:   #091223;
  --steel:      #2c3e57;   /* blu acciaio    */
  --alpine:     #a8b8c9;   /* azzurro alpino */
  --ink-70:     rgba(44, 62, 87, 0.92);
  --ink-46:     rgba(44, 62, 87, 0.60);
  --ink-14:     rgba(14, 27, 51, 0.14);
  --ink-08:     rgba(14, 27, 51, 0.07);

  --paper:      #f5f3f0;   /* avorio caldo — the page                    */
  --white:      #ffffff;   /* cards, forms, the filter bar               */
  --ivory:      #eae8e3;   /* sabbia chiara — alternate bands            */
  --line:       rgba(14, 27, 51, 0.11);
  --paper-70:   rgba(245, 243, 240, 0.72);
  --paper-40:   rgba(245, 243, 240, 0.46);
  --paper-18:   rgba(245, 243, 240, 0.20);

  /* Rules dissolve instead of stopping. */
  --rule:       linear-gradient(90deg, var(--ink-14) 0%, rgba(14, 27, 51, 0.03) 72%, transparent 100%);
  --rule-light: linear-gradient(90deg, var(--paper-18) 0%, rgba(245, 243, 240, 0.04) 72%, transparent 100%);

  /* Round-48 — le due famiglie del sito. Il serif parla, il grottesco conta.
     Scelte dal cliente su una prova: sono i disegni di Times New Roman e di
     Arial, con licenza aperta e nomi propri su Google Fonts. La riga di
     riserva non è un ripiego: «Times New Roman» e Arial hanno le stesse
     larghezze esatte, quindi una richiesta a Google che non arriva non muove
     un pixel dell'impaginato. */
  --serif: "Tinos", "Times New Roman", Times, serif;
  --sans:  "Arimo", Arial, "Helvetica Neue", Helvetica, sans-serif;
  /* Round-45 — era la stessa riga scritta due volte. Due dichiarazioni
     identiche di una cosa sola sono due dichiarazioni che possono divergere:
     bastava cambiarne una per avere due Montserrat diversi sulla stessa
     pagina. Adesso --prose *è* --sans, e non può più scollarsi. */
  --prose: var(--sans);

  /* Round-48 — la riga di lettura, in un posto solo.

     Arimo è più stretto del Montserrat che c'era prima: alla stessa larghezza
     di colonna la riga passava da 74 a 82 caratteri, cioè fuori dalla finestra
     in cui l'occhio ritrova da solo l'inizio della riga dopo. 510 px riportano
     il conto a **74 caratteri**, contati sul testo vero riga per riga
     (Range.getBoundingClientRect, non una media stimata).

     La misura conta doppio qui perché l'interlinea è 24 px — un passo della
     scala, deciso col cliente al round 31 — e un'interlinea corta vuole una
     riga corta.

     È lo stesso numero per il corpo di una guida, per il sommario di
     un'apertura e per la descrizione di un immobile: una riga sola in tutto il
     sito, che è quello che «tutto uniforme» vuol dire quando si scende dal
     carattere all'impaginato. */
  --measure: 510px;

  /* 8px rhythm: 8 · 16 · 24 · 32 · 48 · 64 · 96 · 128 */
  --gx: clamp(20px, 5vw, 72px);
  --shell: 760px;
  --shell-w: 1360px;
  --hdh: 80px;

  /* Round-46 - la tracciatura delle etichette maiuscole, in un posto solo.
     La scheda di brand ha un unico stile per tutto cio che e scritto in
     maiuscoletto - overline, etichette dei campi, voci di menu, pulsanti:
     «Montserrat / Uppercase / Spaced». Nel foglio era invece diventata sei
     valori diversi (0,18 · 0,20 · 0,24 · 0,26 · 0,30 em) e due pesi, quindi
     l'etichetta «TIPOLOGIA» della barra dei filtri e l'etichetta «NOME» del
     modulo sotto sembravano due caratteri diversi sulla stessa pagina. E la
     differenza che il cliente vede «susseguirsi» nel sito. Adesso e una
     costante: chi la cambia, la cambia dappertutto. */
  --track-label: 0.24em;
  /* E l'altro dei due stili maiuscoli della scheda: «TESTO PULSANTE -
     Montserrat / Medium / Uppercase». Tutto cio che si clicca - pulsanti,
     voci di menu, selettore di lingua, comandi della mappa - porta questa,
     piu stretta di quella delle etichette perche una parola che si clicca
     deve leggersi come una parola, non come una didascalia. */
  --track-btn: 0.16em;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  /* Round-39 — la curva dell'intro, e solo dell'intro.
     `--ease` è una easeOutQuint: scarica quasi tutto il movimento nel primo
     terzo e poi striscia. Sui dieci pixel di un reveal non si nota; su una
     sequenza lunga due secondi si legge come una frenata dietro l'altra, ed è
     la ragione per cui il cliente ha chiesto «senza bruschi freni di
     animazione». Questa parte piano, prende passo e si posa: nessun tratto ha
     un momento in cui la velocità cambia di colpo. */
  --ease-intro: cubic-bezier(0.4, 0, 0.2, 1);
  --boot: 0s;
}

/* Round-27 — il marchio è finito a 1,66 s e il velo se ne va fino a 2,14 s: il
   contenuto della pagina parte a 1,75 s, cioè dentro la dissolvenza, così la
   home non aspetta a sipario alzato ma si sta già rivelando mentre il velo
   sparisce. */
html.show-splash { --boot: 2.85s; }

/* ---- Base ---------------------------------------------------------------- */
* { margin: 0; padding: 0; box-sizing: border-box; }

/* Round-52 — `hidden` torna a nascondere.

   L'attributo `hidden` lo nasconde il foglio del browser, che è il foglio più
   debole di tutti: **qualunque** regola d'autore che dichiari un `display`
   sullo stesso elemento lo scopre di nuovo. Nessuno scrive quella regola
   apposta — la si scrive per l'elemento quando è visibile, e senza accorgersi
   si sta annullando il suo nascondiglio.

   Costava tre difetti insieme, e sono tre segnalazioni del cliente lette come
   problemi diversi:

   * `.lbx { display: flex }` — la galleria a schermo intero nasce `hidden` e
     si vedeva **sempre**. Aprire un immobile non portava alla scheda: portava
     a una fotografia a tutto schermo su fondo nero, e la crocetta in alto a
     destra «non funzionava» perché rimetteva un attributo che non decideva
     niente. Un difetto solo, arrivato come due.
   * `.map-tool { display: inline-flex }` — «Cancella l'area» compariva sulla
     mappa prima che un'area esistesse: un comando che non ha niente da
     cancellare, in cima alla carta.
   * `.card { display: flex }` — sulla mappa le schede si filtrano con
     `card.hidden = !ok`: restavano tutte in pagina, e l'elenco non rispondeva
     al disegno dell'area.

   Sta qui in cima, con `!important`, perché è l'unico modo di scriverla una
   volta sola: `hidden` è una promessa del linguaggio, non una classe del
   sito, e una promessa da riconfermare caso per caso non è una promessa. Chi
   vuole mostrare qualcosa toglie l'attributo — che è esattamente ciò che il
   codice già fa. */
[hidden] { display: none !important; }

html { scroll-behavior: smooth; }
/* Round-39 — la barra di scorrimento occupa il suo posto sempre, anche quando
   la pagina è bloccata durante l'intro. Senza, alla fine dell'intro succede
   questo: si toglie il blocco, la barra ricompare, e tutta la pagina scivola
   di lato di una quindicina di pixel in un fotogramma. È lo stesso scatto di
   cui parla il cliente, per una seconda causa — e su un Mac, dove le barre
   sono in sovraimpressione, non si vede mai: è il genere di difetto che si
   scopre solo su Windows. */
html { scrollbar-gutter: stable; }
/* The header is sticky, so a jump to #form would land the panel's first line
   underneath it. Reserve its height plus a little air. */
html { scroll-padding-top: calc(var(--hdh) + 18px); }
/* Round-39 — lo scorrimento è bloccato finché il velo è sullo schermo, e basta
   quello. La classe `show-splash` non viene più tolta (vedi site.js): porta i
   tempi delle animazioni, e toglierla a metà corsa era lo scatto che chiudeva
   l'intro. A finire è `intro-over`, che non tocca nessuna animazione. */
html.show-splash:not(.intro-over) { overflow: hidden; }

body {
  font-family: var(--prose);
  font-weight: 400;
  font-size: 0.95rem;
  line-height: 1.8;
  color: var(--ink-70);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ---- Round-45 — il grassetto è un taglio vero, non uno inventato -------------
   Il filtro `emphasis` di site_extras.py trasforma `**così**` in <strong>, e
   <strong> senza una regola vale 700. Di Montserrat il sito carica 300, 400,
   500 e 600: il 700 non arriva mai, e il browser lo fabbrica ingrossando il
   400 per conto suo — una finta che si vede, perché le lettere si allargano e
   i contorni si sporcano mentre intorno il testo è pulito. Su questo sito il
   grassetto compare dentro i paragrafi delle pagine di zona e delle dieci
   guide, cioè in mezzo al testo, dove il confronto è immediato.

   600 è il taglio più pesante che il sito carica davvero, ed è già quello del
   prezzo sulle schede: è il «peso forte» di questo alfabeto. Vale anche per
   <b>, che nessuno scrive a mano ma che può arrivare da un testo incollato. */
strong, b { font-weight: 400; }

img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

:focus-visible { outline: 1px solid currentColor; outline-offset: 4px; }
::selection { background: var(--ink); color: var(--paper); }

.shell   { max-width: var(--shell);   margin: 0 auto; padding: 0 var(--gx); }
.shell-w { max-width: var(--shell-w); margin: 0 auto; padding: 0 var(--gx); }

/* A rule that fades out rather than ending. */
.ruled {
  background-image: var(--rule);
  background-repeat: no-repeat;
  background-size: 100% 1px;
  background-position: 0 0;
}

/* ---- Type ----------------------------------------------------------------- */
/* Overline — Montserrat, upper case, widely tracked. The brand sheet gives
   this one job: labels and navigation. Nothing that is a sentence uses it. */
.tag {
  font-family: var(--sans);
  font-size: 0.64rem;
  font-weight: 400;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-46);
}
.tag-light { color: var(--paper-40); }

/* Section title — Cormorant Garamond. The sheet sets H1 in the serif and the
   mockups set every other title in it too: the only sans-serif type on a page
   is a label, a button or a figure of running text. */
.ttl {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.7rem, 2.9vw, 2.3rem);
  line-height: 1.22;
  letter-spacing: 0;
  color: var(--ink);
  margin-top: 16px;
}
.ttl-2 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.2rem, 1.9vw, 1.5rem);
  letter-spacing: 0;
  line-height: 1.3;
  color: var(--ink);
}
.lede {
  font-size: 0.95rem;
  line-height: 1.85;
  color: var(--ink-70);
  max-width: 560px;
  margin-top: 20px;
}

/* The lintel: the logo's floating bar, drawn above a heading. The only
   ornament in the system, so it is never doubled with a full-width rule. */
.lintel { position: relative; padding-top: 24px; }
.lintel::before {
  content: "";
  position: absolute;
  top: 0; left: 1px;
  width: 56px; height: 1px;
  background: var(--alpine);
  transform: scaleX(0);
  transform-origin: left center;
}
.lintel-c::before { left: 50%; margin-left: -23px; transform-origin: center; }
.blk-navy .lintel::before, .creed .lintel::before, .pledge .lintel::before { background: var(--paper); }
.is-in .lintel::before, .lintel.is-in::before { animation: lintelDraw 0.9s var(--ease) 0.2s both; }

@keyframes lintelDraw { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* ---- Buttons: primary, secondary, ghost — the sheet's three ---------------- */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 14px;
  padding: 17px 30px;
  font-family: var(--sans);
  font-size: 0.68rem;
  font-weight: 400;
  letter-spacing: var(--track-btn);
  text-transform: uppercase;
  border: 1px solid var(--ink);
  overflow: hidden;
  transition: color 0.45s var(--ease), border-color 0.45s var(--ease), background 0.45s var(--ease);
}
.btn span { position: relative; z-index: 1; display: inline-flex; align-items: center; gap: 14px; }
.btn::before {
  content: "";
  position: absolute; inset: 0;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.5s var(--ease);
}
.btn:hover::before { transform: scaleX(1); }

.btn-ink { background: var(--ink); color: var(--white); }
.btn-ink::before { background: var(--steel); }

.btn-ghost { color: var(--ink); background: transparent; }
.btn-ghost::before { background: var(--ink); }
.btn-ghost:hover { color: var(--white); }
.blk-navy .btn-ghost, .pledge .btn-ghost { color: var(--paper); border-color: var(--paper-18); }
.blk-navy .btn-ghost::before, .pledge .btn-ghost::before { background: var(--paper); }
.blk-navy .btn-ghost:hover, .pledge .btn-ghost:hover { color: var(--ink); border-color: var(--paper); }

/* The arrow travels on hover — the one gesture every call to action shares. */
.btn-arw { flex: none; transition: transform 0.5s var(--ease); }
.btn:hover .btn-arw, .lnk:hover .btn-arw { transform: translateX(5px); }

/* Ghost: a link with an arrow, no frame. */
.lnk {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--sans);
  font-size: 0.68rem;
  font-weight: 400;
  letter-spacing: var(--track-btn);
  text-transform: uppercase;
  color: var(--ink);
  padding-bottom: 6px;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-size: 0 1px;
  background-position: 0 100%;
  transition: background-size 0.5s var(--ease), opacity 0.4s ease;
}
.lnk:hover { background-size: 100% 1px; }

/* ---- Intro ------------------------------------------------------------------
   Round-27 — la E si disegna, poi scivola a sinistra e diventa la prima lettera
   di ELISON, che si compone dietro di lei. Non è una figura che sfuma in
   un'altra: è **la stessa lettera** che va al suo posto.

   Che si possa fare non è fortuna, è una proprietà del marchio: il monogramma
   della tavola è la E del logo, non una E somigliante. Misurata sul file
   elison-wordmark.png (1269 × 167 px), la sua E occupa x 0,4–141,4 e y
   3,7–163,5, e riporta esattamente le proporzioni del monogramma 90 × 104:
     barre        11 px su 160 = 6,9%   monogramma 7/104 = 6,7%
     montante     20 px su 141 = 14,2%  monogramma 13/90 = 14,4%
     stacco       54 px su 160 = 31,3%  monogramma 32/104 = 30,8%
     braccio     116 px su 141 = 82,3%  monogramma 74/90 = 82,2%
   Da qui vengono i numeri di .mono qui sotto: sono quella misura tradotta in
   percentuali della fotografia del marchio, ed è per questo che l'atterraggio
   è esatto invece che approssimato. Se il file del logo viene rifatto, questi
   numeri vanno rimisurati — è l'unico punto fragile di tutta la sequenza.

   Il ritmo, in secondi dal primo fotogramma:
     0,03 – 0,46  le tracce sottili disegnano la E
     0,26 – 0,65  i pieni le raggiungono: il monogramma si stabilizza
     0,68 – 1,10  la E scivola a sinistra e rimpicciolisce fino al suo posto
     0,92 – 1,32  ELISON si scopre da sinistra a destra, dietro di lei
     1,22 – 1,66  REAL ESTATE e la linea di caricamento chiudono il marchio
     1,70 – 2,14  dissolvenza; sotto, la home si sveglia dalla desaturazione

   Il fondo non è più il blu notte pieno di prima e il velo non si alza più
   come un sipario: la pagina è avorio, quindi si parte già dalla sua carta e
   alla fine non se ne va un colore, se ne va solo un velo. La tavola mette
   fra le cose da evitare tutto ciò che è appariscente, e un pannello che
   scorre via è un movimento in più.

   Chi ha chiesto meno movimento nel sistema non vede niente di tutto questo:
   la classe show-splash non viene nemmeno messa (base.html). ------------------ */
#site-splash { display: none; }

html.show-splash #site-splash {
  display: grid;
  place-items: center;
  position: fixed; inset: 0;
  z-index: 300;
  /* Il velo è decorativo: non deve intercettare il primo clic di chi arriva
     deciso e non ha voglia di aspettare due secondi. */
  pointer-events: none;
  /* Avorio caldo con un soffio di bianco al centro: la stessa carta della
     pagina, così alla fine non c'è un colore che se ne va, solo un velo. */
  background: radial-gradient(120% 100% at 50% 44%, var(--white) 0%, var(--paper) 78%);
  animation: splashFade 0.75s cubic-bezier(0.4, 0, 0.35, 1) 2.50s both;

  /* Larghezza del marchio finito: l'unica misura da cui dipende tutto il
     resto, monogramma compreso. */
  --lw: clamp(210px, 26vw, 320px);
  /* L'inchiostro del file del logo, che **non** è --ink: il disegno è stato
     esportato in un blu leggermente più acceso (rgb 15 33 75 contro 14 27 51).
     Siccome la E disegnata resta accanto alle lettere fotografate, deve avere
     il loro colore, non quello del sito, o al piede della parola si vedrebbe
     una lettera di tono diverso dalle altre cinque. */
  --mark-ink: #0f214b;
}

.sp-lockup { width: var(--lw); text-align: center; }
.sp-word { position: relative; }

/* La fotografia del marchio, tagliata dove finisce la E: la sua prima lettera
   non si vede mai — quel posto è della E disegnata, che ci arriva volando. Il
   taglio a 14,97% cade nel bianco fra la E (finisce a 141) e la L (comincia a
   239), quindi non tronca nulla. */
.sp-word img {
  display: block;
  width: 100%;
  height: auto;
  /* La parola si scopre quando la E ha già fatto due terzi di strada: se
     comincia prima, le lettere nascono sotto la lettera grande che sta
     ancora passando di lì, e per un decimo di secondo si legge un groviglio.
     Comincia comunque mentre la E viaggia — finisce dopo che è atterrata. */
  animation: wordOpen 0.48s cubic-bezier(0.4, 0, 0.2, 1) 0.98s both;
}

/* Il monogramma, in percentuali della fotografia del marchio: a scala 1 le sue
   quattro aste stanno esattamente sopra la E del logo. preserveAspectRatio è
   "none" perché la E del file è più larga del monogramma del 2%, e quei due
   punti percentuali si recuperano deformando, non spostando. */
#site-splash .mono {
  position: absolute;
  left: -0.709%;
  top: -3.305%;
  width: 12.593%;
  height: 106.73%;
  color: var(--mark-ink);
  /* Il centro ottico della E cade al 50/50 della casella: è il perno della
     salita di scala, e per questo la lettera rimpicciolisce restando ferma
     sul proprio centro mentre il resto della trasformazione la porta a posto. */
  transform-origin: 50% 50%;
  /* Il viaggio non usa --ease come tutto il resto del sito: quella curva
     scarica quasi tutto il movimento nella prima metà, ed è giusta per una
     cosa che entra di dieci pixel, non per una lettera che attraversa lo
     schermo — la si vedrebbe scattare e poi strisciare. Questa parte e
     arriva con la stessa cura. */
  animation: monoTravel 0.50s cubic-bezier(0.45, 0.03, 0.18, 1) 0.72s both;
}

/* 1 — la traccia. pathLength="1" normalizza le quattro lunghezze a 1, così
   una sola coppia dasharray/dashoffset le disegna tutte con lo stesso passo. */
.mono-trace {
  /* Una traccia da disegno tecnico: si deve vedere, non si deve leggere come
     una seconda E più chiara accanto a quella vera. */
  stroke-opacity: 0.62;
}
.mono-trace line {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation:
    traceDraw 0.34s var(--ease-intro) both,
    traceOut 0.26s ease 0.30s both;
}
.tr-lintel { animation-delay: 0.04s, 0.30s; }
.tr-stem   { animation-delay: 0.10s, 0.35s; }
.tr-mid    { animation-delay: 0.16s, 0.40s; }
.tr-base   { animation-delay: 0.22s, 0.45s; }

/* 2 — il pieno. Ogni asta cresce dal proprio inizio, nell'ordine in cui la
   mano l'avrebbe tirata: architrave, montante, braccio, base. */
#site-splash .mono-solid rect { fill: var(--mark-ink); transform-box: fill-box; }
.mono-lintel { transform-origin: left center; animation: monoWipe 0.28s var(--ease-intro) 0.30s both; }
.mono-stem   { transform-origin: top center;  animation: monoRise 0.28s var(--ease-intro) 0.35s both; }
.mono-mid    { transform-origin: left center; animation: monoWipe 0.28s var(--ease-intro) 0.40s both; }
.mono-base   { transform-origin: left center; animation: monoWipe 0.28s var(--ease-intro) 0.45s both; }

/* 3 — il descrittore e la linea di caricamento chiudono il marchio. */
.sp-lock {
  display: block;
  /* Round-39 — «il logo nell'intro ha proporzioni diverse dal logo vero: la
     scritta real estate è più corta di quello vero».

     Era vero, e la causa è che le due misure non erano legate. Nella testata il
     descrittore è tarato sul marchio: il disegno è alto 21 px — cioè largo
     21 × 1269/167 = 159,6 — e «REAL ESTATE» misura 0,56rem, cioè 8,96 px. Il
     rapporto fra i due è **0,0561**, ed è quello che fa finire le due righe
     alla stessa quota.

     Qui il descrittore aveva una misura sua, in vw, che non sapeva niente della
     larghezza del marchio: su una finestra da 1440 px il marchio è largo 320 e
     il descrittore restava a 9,6 px invece dei 18 che gli sarebbero spettati —
     poco più della metà. Da lontano si leggeva come un lockup diverso, ed è
     esattamente quello che il round 26 aveva già corretto fra testata e piede.

     Adesso la misura viene dal marchio, quindi le proporzioni sono le stesse a
     ogni larghezza di schermo, per costruzione. Anche lo stacco fra le due
     righe segue la stessa strada: 5 px su 159,6 nella testata. */
  margin-top: calc(var(--lw) * 0.0313);
  font-family: var(--sans);
  font-size: calc(var(--lw) * 0.0561);
  font-weight: 400;
  line-height: 1;
  /* Round-51 — le lettere si distribuiscono da un capo all'altro del marchio,
     come nella testata: la meccanica sta nella regola comune qui sopra
     (`.hd-brand .lock, .sp-lock`), così l'intro e la testata non possono più
     divergere nemmeno su questo. */
  text-transform: uppercase;
  color: var(--mark-ink);
  animation: lockIn 0.32s var(--ease-intro) 1.40s both;
}
.sp-load {
  display: block;
  width: calc(var(--lw) * 0.56);
  height: 1px;
  margin: clamp(18px, 2.4vw, 28px) auto 0;
  background: var(--ink-08);
  overflow: hidden;
  /* Anche il binario della linea si accende col marchio: lasciarlo acceso
     dall'inizio mette un filo grigio sotto la E mentre si disegna, e quel
     filo non è nel disegno di nessuno. */
  animation: lockIn 0.32s var(--ease-intro) 1.46s both;
}
.sp-load i {
  display: block;
  height: 100%;
  background: var(--mark-ink);
  transform: scaleX(0);
  /* Round-37 — «una sorta di barra di caricamento che scorre dolcemente da
     sinistra a destra dopo la comparsa del nome».

     Erano due cose sbagliate in una riga. La linea cresceva dal **centro**,
     perché è lì che sta il perno di una trasformazione quando non lo si
     dichiara: si aprivano due mezze linee verso i due lati, che è un fiore,
     non un caricamento. E partiva a 1,30s, cioè mentre «Real Estate»
     compariva ancora — la barra correva prima che ci fosse un nome sotto cui
     correre.

     Adesso il perno è a sinistra, la corsa comincia dopo che il marchio è
     finito (1,72s) e dura quasi il doppio, con una curva che parte piano,
     prende passo e si posa: è il movimento di una cosa che si carica, non di
     una cosa che scatta. */
  transform-origin: left center;
  animation: loadOpen 0.62s cubic-bezier(0.5, 0, 0.2, 1) 1.80s both;
}

/* 4 — sotto il velo la pagina si sveglia: parte leggermente desaturata e
   ritrova il colore mentre l'intro se ne va. La regola tocca solo #main:
   un filtro sulla testata le farebbe da blocco contenitore e il menu mobile,
   che è fisso, si troverebbe ancorato altrove per quei due secondi.

   Round-37 — «anche la comparsa del sito sotto deve essere più delicata e
   gentile, non troppo improvvisa». Prima il velo sfumava in 0,44s e sotto
   c'era già la pagina a piena forza: il velo se ne andava e la pagina
   *appariva*. Adesso le due cose si scambiano il posto — il velo esce in
   0,75s e la pagina entra in 1s partendo da un terzo di opacità, quindi per
   otto decimi di secondo sono tutte e due sullo schermo e nessuna delle due
   fa un ingresso. La curva è la stessa dei reveal del sito. */
html.show-splash #main { animation: pageWake 1s cubic-bezier(0.33, 1, 0.68, 1) 2.50s both; }

@keyframes traceDraw { to { stroke-dashoffset: 0; } }
@keyframes traceOut  { from { opacity: 1; } to { opacity: 0; } }
@keyframes monoWipe  { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes monoRise  { from { transform: scaleY(0); } to { transform: scaleY(1); } }

/* Il viaggio. Le percentuali della traslazione sono sulla casella del
   monogramma: 352,7% della sua larghezza è, fatti i conti, il 44,4% della
   larghezza del marchio — cioè la distanza fra il centro della E e il centro
   della parola, che è dove la lettera deve stare mentre si disegna. Il 50%
   dell'altezza la alza di quel tanto che compensa il descrittore e la linea
   sotto, così la E grande sta al centro dello schermo e non del marchio. */
@keyframes monoTravel {
  from { transform: translate(352.7%, 50%) scale(3.6); }
  to   { transform: translate(0, 0) scale(1); }
}
@keyframes wordOpen {
  from { clip-path: inset(0 85.03% 0 14.97%); }
  to   { clip-path: inset(0 0 0 14.97%); }
}
@keyframes lockIn {
  from { opacity: 0; transform: translateY(5px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes loadOpen  { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes splashFade {
  from { opacity: 1; }
  to   { opacity: 0; visibility: hidden; }
}
@keyframes pageWake {
  from { opacity: 0.35; filter: saturate(0.6); }
  to   { opacity: 1; filter: none; }
}

/* ---- Header ---------------------------------------------------------------
   The mark is the stacked lockup of the brand sheet: the ELISON drawing, and
   "Real Estate" set beneath it in tracked capitals, measured to the same width
   as the drawing above it (there is a test that checks the two agree). */
.hd {
  position: sticky;
  top: 0;
  z-index: 100;
  height: var(--hdh);
  background: var(--paper);
  transition: transform 0.55s var(--ease), background 0.5s ease, box-shadow 0.5s ease;
}
.hd.is-hidden { transform: translateY(-102%); }
.hd.is-scrolled {
  background: rgba(245, 243, 240, 0.9);
  backdrop-filter: blur(14px) saturate(1.1);
  -webkit-backdrop-filter: blur(14px) saturate(1.1);
  box-shadow: 0 18px 40px -34px rgba(9, 18, 35, 0.5);
}

.hd-in { display: flex; align-items: center; justify-content: space-between; gap: 24px; height: var(--hdh); }

/* Round-26 — inline-block, non block: il lockup deve essere largo quanto il
   disegno che contiene, o "Real Estate" si centra su qualcos'altro. Nella
   testata il marchio è dentro un flex e la larghezza veniva dal contenuto per
   conto suo; nel piede è dentro una cella di griglia, e da lì il descrittore
   si centrava sulla colonna intera invece che sotto le lettere. */
.hd-brand { display: inline-block; }
.hd-brand img { display: block; height: 21px; width: auto; }
/* Round-51 — «REAL ESTATE copre l'intera lunghezza».

   Il cliente ha portato il lockup come lo vuole: le due righe cominciano e
   finiscono sulla stessa verticale, il descrittore largo esattamente quanto il
   disegno. Misurato sul suo file: ELISON occupa 688 px, «REAL ESTATE» 684 —
   il 99,4%, cioè lo stesso bordo a destra e a sinistra. Qui il descrittore ne
   misurava 104 su 159,6, cioè il 65%: una riga corta appoggiata al centro.

   **Perché non è una tracciatura più larga.** Una tracciatura è un numero fisso
   in em: la riga viene giusta a un corpo solo. Questo lockup vive a cinque
   misure diverse (testata 21 px, telefono 17, piede, intro in --lw, firma
   email), e a ognuna il numero andrebbe ricalcolato a mano — cioè andrebbe
   sbagliato. In più la tracciatura aggiunge uno spazio anche **dopo** l'ultima
   lettera, ed è la ragione del `text-indent: 0.25em` che stava qui: mezzo em di
   troppo a destra, compensato spingendo la riga di un quarto. Un ripiego che
   funzionava solo perché la riga era centrata.

   Le lettere sono elementi di un flex con `space-between`: il browser calcola
   lui lo spazio che avanza e lo divide in parti uguali, quindi la prima lettera
   tocca il bordo sinistro del disegno e l'ultima il destro — **a qualunque
   corpo, in qualunque lingua, con qualunque carattere**, per costruzione e non
   per taratura. Fra REAL ed ESTATE c'è un elemento vuoto (`.lock-gap`), che
   raddoppia lo stacco in quel punto: sul file del cliente lo stacco fra le due
   parole è 101 px contro i 45,75 fra due lettere, cioè 2,2 volte.

   Il markup sta in _lock.html, una volta sola per testata, piede e intro. */
.lock,
.sp-lock {
  display: flex;
  justify-content: space-between;
  text-indent: 0;
  letter-spacing: 0;
}
.lock > span,
.sp-lock > span { display: block; }
/* Larghezza zero: lo stacco lo fanno i due spazi che gli stanno intorno. */
.lock-gap { flex: 0 0 0; }
.hd-brand .lock {
  margin-top: 5px;
  font-family: var(--sans);
  font-size: 0.56rem;
  font-weight: 400;
  line-height: 1;
  text-transform: uppercase;
  color: var(--ink);
}
.ft .hd-brand .lock, .ft-mark .lock { color: var(--paper); }

.hd-nav { display: flex; align-items: center; gap: clamp(18px, 2.6vw, 36px); }
.hd-nav a {
  font-family: var(--sans);
  font-size: 0.66rem;
  font-weight: 400;
  letter-spacing: var(--track-btn);
  text-transform: uppercase;
  color: var(--ink-70);
  padding: 6px 0;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-size: 0 1px;
  background-position: 0 100%;
  transition: background-size 0.45s var(--ease), color 0.35s ease;
}
.hd-nav a:hover { color: var(--ink); background-size: 100% 1px; }
.hd-nav a.on { color: var(--ink); background-size: 100% 1px; }
.hd-nav a.hd-cta {
  position: relative;
  color: var(--ink);
  border: 1px solid var(--ink);
  padding: 13px 22px;
  background-image: none;
  overflow: hidden;
  transition: color 0.45s var(--ease);
}
.hd-nav a.hd-cta span { position: relative; z-index: 1; }
.hd-nav a.hd-cta::before {
  content: ""; position: absolute; inset: 0;
  background: var(--ink);
  transform: scaleX(0); transform-origin: left center;
  transition: transform 0.5s var(--ease);
}
.hd-nav a.hd-cta:hover { color: var(--white); }
.hd-nav a.hd-cta:hover::before { transform: scaleX(1); }

.hd-tools { display: flex; align-items: center; gap: 18px; }
.lang { display: flex; gap: 2px; }
.lang a {
  font-family: var(--sans);
  font-size: 0.62rem;
  font-weight: 400;
  letter-spacing: var(--track-btn);
  text-transform: uppercase;
  padding: 5px 6px;
  color: var(--ink-46);
  transition: color 0.35s ease;
}
.lang a.on { color: var(--ink); text-decoration: underline; text-underline-offset: 5px; }
.lang a:hover { color: var(--ink); }

.hd-burger { display: none; flex-direction: column; gap: 6px; padding: 8px 2px; }
.hd-burger span { display: block; width: 22px; height: 1px; background: var(--ink); transition: transform 0.45s var(--ease); }
body.nav-open .hd-burger span:first-child { transform: translateY(3.5px) rotate(45deg); }
body.nav-open .hd-burger span:last-child  { transform: translateY(-3.5px) rotate(-45deg); }

/* ---- Photography: tinted into the same colour world as the type ------------ */
.ph { position: relative; background: linear-gradient(150deg, var(--ivory), #ddd8cc); }
.ph img { filter: saturate(0.9) contrast(1.02); }
.ph::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(185deg, rgba(16, 30, 54, 0.05) 0%, rgba(16, 30, 54, 0.17) 100%);
  pointer-events: none;
}
.ph.ph-dead img { display: none; }

/* ---- Hero -------------------------------------------------------------------
   Round-23 (seconda passata) — one photograph, edge to edge, and a veil of
   paper laid over it. The first attempt put a paper panel beside the picture:
   it left a vertical seam down the middle of the screen, which is exactly what
   the reference does not have. Here the picture fills the section and the veil
   is opaque where the words are, gone by the right-hand third — the boundary
   between text and image is made of light, like every other separation on this
   site. */
.hero {
  position: relative;
  display: flex;
  align-items: center;
  overflow: hidden;
  min-height: clamp(500px, calc(100vh - var(--hdh) - 150px), 760px);
}

.hero-ph {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: linear-gradient(150deg, var(--ivory), #ddd8cc);
  animation: uncoverDown 1.5s var(--ease) calc(var(--boot) + 0.15s) both;
}
.hero-ph img {
  width: 100%; height: 112%;
  object-fit: cover;
  filter: saturate(0.94) contrast(1.02);
  animation: settle 2.4s var(--ease) calc(var(--boot) + 0.15s) both;
}
.hero-ph.ph-dead img { display: none; }

/* Round-24, second correction — THERE IS NO VEIL.
   The client's reference shows the photograph at full strength from edge to
   edge, with the words simply laid over it. An earlier pass washed the left
   third with paper to protect the type; it was rejected on sight, and rightly:
   it turns a photograph into a background.

   What replaces it is a rule about the photograph itself: the opening picture
   must be bright where the words are (sky, haze, snow, a lit valley — as in
   every one of the reference images). The harness measures exactly that, on
   the rendered page, and fails if the type would fall below the contrast a
   person can read. If a dark photograph is ever needed there, add the class
   "scrim" to .hero-ph: a discreet darkening with the type turned to paper —
   never white smoke over the picture. */
.hero-ph.scrim::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, rgba(9, 18, 35, 0.55) 0%, rgba(9, 18, 35, 0.28) 46%, rgba(9, 18, 35, 0) 78%);
}
.hero-ph.scrim ~ .hero-in .hero-title,
.hero-ph.scrim ~ .hero-in .hero-lede,
.hero-ph.scrim ~ .hero-in .tag { color: var(--paper); }
.hero-ph.scrim ~ .hero-in .hero-rule { background: var(--paper-40); }

.hero-in { position: relative; z-index: 2; width: 100%; }

/* The words are inset a little further than the header mark above them, as in
   the reference: the opening screen breathes wider than the navigation. */
.hero-block { max-width: 700px; margin-left: clamp(0px, 2vw, 30px); }

.hero-tag { opacity: 0; animation: fadeUp 1s var(--ease) calc(var(--boot) + 0.15s) both; }

/* The eyebrow is set in spaced capitals, so the title is given the opposite
   voice: lower case, large, light, tracking almost off — round-20's rule, kept
   while the size grows to what the reference sets. */
.hero-title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(2.1rem, 4vw, 3.4rem);
  letter-spacing: 0;
  line-height: 1.16;
  color: var(--ink);
  margin-top: clamp(16px, 2.4vh, 26px);
}
/* Each line is uncovered from inside a clipped box, and a lower-case line has
   descenders hanging below its line box: without this the tails of "p" and "g"
   are shaved off. The negative margin gives back the space the padding takes. */
.hero-title .mask { padding-bottom: 0.2em; margin-bottom: -0.2em; }

/* The rule separates the promise from the explanation. */
.hero-rule {
  display: block;
  width: 56px; height: 1px;
  margin: clamp(24px, 3vh, 34px) 0 0;
  background: var(--alpine);
  transform: scaleX(0);
  transform-origin: left center;
  animation: lintelDraw 0.9s var(--ease) calc(var(--boot) + 1.35s) both;
}

.hero-lede {
  margin-top: 24px;
  font-size: 0.98rem;
  line-height: 1.9;
  color: var(--ink-70);
  max-width: 430px;
  opacity: 0;
  animation: fadeUp 1s var(--ease) calc(var(--boot) + 1.5s) both;
}

/* Two actions, and only two: the catalogue for whoever is buying, the
   valuation for whoever is selling. */
.hero-acts {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: clamp(30px, 3.8vh, 46px);
  opacity: 0;
  animation: fadeUp 1s var(--ease) calc(var(--boot) + 1.62s) both;
}
.hero-acts .btn { padding: 17px 28px; }
@keyframes uncoverDown { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes settle { from { scale: 1.09; } to { scale: 1; } }

.mask { display: block; overflow: hidden; }
.mask-in { display: block; transform: translateY(112%); animation: maskUp 1.1s var(--ease) both; }
/* Round-53 — per classe e non per posizione. Il sopratitolo è entrato nell'h1
   (vedi home.html) e i due `:nth-child` contavano *tutti* i figli: con uno
   span in più davanti, il primo selettore non trovava più niente e la prima
   riga dello slogan compariva ferma, senza salire. Una classe dice quale riga
   è, e continuerà a dirlo qualunque cosa venga aggiunta nel titolo. */
.hero-title .mask-1 .mask-in { animation-delay: calc(var(--boot) + 1.05s); }
.hero-title .mask-2 .mask-in { animation-delay: calc(var(--boot) + 1.15s); }

@keyframes maskUp { from { transform: translateY(112%); } to { transform: translateY(0); } }
@keyframes fadeUp { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }

/* ---- Search: one line, above the listings it filters ----------------------- */
.hsearch { padding: clamp(20px, 2.4vw, 34px) 0 0; }
.hero-search { display: flex; align-items: stretch; gap: clamp(18px, 3vw, 46px); }
.hs-field { display: flex; flex-direction: column; justify-content: center; gap: 3px; padding: 6px 0 18px; flex: 0 1 340px; }
.hs-field label {
  font-family: var(--sans);
  font-size: 0.6rem;
  font-weight: 400;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-46);
}
.hs-go {
  align-self: center;
  margin-left: auto;
  font-family: var(--sans);
  font-size: 0.7rem;
  letter-spacing: var(--track-btn);
  text-transform: uppercase;
  color: var(--paper);
  background: var(--ink);
  padding: 15px 34px;
  transition: opacity 0.35s ease;
}
.hs-go:hover { opacity: 0.86; }

/* Native select kept for the no-JS path. */
.hs-field select, .ffield select {
  border: 0;
  border-radius: 0;
  background: transparent;
  font-family: var(--sans);
  font-size: 0.92rem;
  color: var(--ink);
  padding: 7px 0;
  background-image: var(--rule);
  background-repeat: no-repeat;
  background-size: 100% 1px;
  background-position: 0 100%;
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
}

/* ---- Marks: what the agency is, in four words each --------------------------
   A quiet strip, not a feature box: no cards, no borders, no background of its
   own. The icons are drawn at the same hairline weight as the arrows and the
   rules, so the row reads as type with a small drawing in front of it. */
.marks {
  padding: clamp(30px, 3.4vw, 44px) 0 clamp(34px, 4vw, 52px);
  background: var(--ivory);
}
.marks-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(24px, 3vw, 54px);
}
.mk { display: grid; grid-template-columns: auto 1fr; gap: 16px; align-items: start; }
.mk-ic { display: flex; color: var(--ink); opacity: 0.85; margin-top: 2px; }
.mk-txt .tag { display: block; margin-bottom: 8px; color: var(--ink); }
.mk-txt p:last-child {
  font-size: 0.82rem;
  line-height: 1.65;
  color: var(--ink-46);
  max-width: 250px;
}

/* ---- Proof: four figures, each one true by construction ---------------------
   Named "proof", not "facts": .fact is already taken by the list of figures on
   a listing page, and that one is a flex row — the collision laid this band out
   sideways and it took a browser to see it. -----------------------
   The reference fills this band with 15+, 800+, 650M+, 98% — mockup numbers.
   What goes here instead are facts the site can stand behind: how many areas
   are covered, how many languages are spoken, what a valuation costs. The
   figure is set in the serif, big, and the label underneath in tracked
   capitals — the shape of the reference, with content that is checkable. */
.proof { background: var(--white); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.proof-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  padding: clamp(34px, 4vw, 56px) 0;
}
.proof-i { text-align: center; padding: 0 clamp(12px, 2vw, 28px); }
.proof-i + .proof-i { border-left: 1px solid var(--line); }
.proof-n {
  display: block;
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(2rem, 3.2vw, 2.7rem);
  line-height: 1;
  color: var(--ink);
}
.proof-i .tag { display: block; margin-top: 14px; color: var(--ink); }
.proof-i p { margin-top: 8px; font-size: 0.8rem; line-height: 1.6; color: var(--ink-46); }


/* ---- Catalogue (round-24) ---------------------------------------------------
   The banner is the opening screen of every inner page: one photograph, the
   paper veil, the title in the serif. Shorter than the home page's — a
   catalogue exists to be scrolled, not admired. */
.phero {
  position: relative;
  display: flex;
  align-items: center;
  overflow: hidden;
  min-height: clamp(320px, 40vh, 440px);
  padding-bottom: 36px;              /* room for the filter card that rides it */
}
.phero-in { position: relative; z-index: 2; width: 100%; }
.phero .hero-title { max-width: 900px; }
.phero .hero-lede { margin-top: 18px; max-width: 520px; }

/* The filters ride the bottom edge of the banner, as in the reference. */
.filters { position: relative; z-index: 3; margin-top: -36px; }
.fbar {
  display: grid;
  grid-template-columns: repeat(4, 1fr) auto;
  background: var(--white);
  border: 1px solid var(--line);
  box-shadow: 0 30px 60px -46px rgba(14, 27, 51, 0.5);
}
.fbar-field { padding: 16px clamp(14px, 1.6vw, 24px); border-right: 1px solid var(--line); }
.fbar-field label {
  display: block;
  font-family: var(--sans);
  font-size: 0.58rem;
  font-weight: 400;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-46);
  margin-bottom: 2px;
}
.fbar .sel-btn, .fbar select { padding-bottom: 4px; background-image: none; }
.fbar-go {
  font-family: var(--sans);
  font-size: 0.7rem;
  font-weight: 400;
  letter-spacing: var(--track-btn);
  text-transform: uppercase;
  color: var(--white);
  background: var(--ink);
  padding: 0 clamp(26px, 3vw, 44px);
  transition: background 0.4s ease;
}
.fbar-go:hover { background: var(--steel); }

.chips { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 18px; }
.chip {
  font-family: var(--sans);
  font-size: 0.66rem;
  letter-spacing: 0.06em;
  color: var(--ink-70);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 9px 18px;
  transition: color 0.35s ease, border-color 0.35s ease, background 0.35s ease;
}
.chip:hover { color: var(--ink); border-color: var(--alpine); }
.chip.on { background: var(--ink); border-color: var(--ink); color: var(--white); }
.chip-clear {
  margin-left: auto;
  font-family: var(--sans);
  font-size: 0.62rem;
  font-weight: 400;
  letter-spacing: var(--track-btn);
  text-transform: uppercase;
  color: var(--ink-46);
  transition: color 0.35s ease;
}
.chip-clear:hover { color: var(--ink); }

.results-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  margin-bottom: clamp(24px, 3vw, 36px);
}
.results-n { font-family: var(--sans); font-size: 0.8rem; color: var(--ink-46); }
.sortbar { display: flex; align-items: center; gap: 12px; }
.sortbar label {
  font-family: var(--sans);
  font-size: 0.6rem;
  font-weight: 400;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-46);
}
.sortbar .sel { min-width: 190px; }
.sel-plain .sel-btn { border: 1px solid var(--line); padding: 11px 16px; background-image: none; background: var(--white); }
.sel-plain .sel-btn:hover, .sel-plain.is-open .sel-btn { background-image: none; border-color: var(--alpine); }

/* Two classes, not one: .cards further down the file sets three columns and
   would otherwise win on source order alone. */
.cards.cards-4 { grid-template-columns: repeat(4, 1fr); }
.loadmore { display: flex; justify-content: center; margin-top: clamp(36px, 4.5vw, 64px); }

/* ---- Split band: copy on paper, photograph beside it ------------------------ */
.split { display: grid; grid-template-columns: 1fr 1fr; align-items: stretch; background: var(--ivory); }
.split-copy { display: flex; align-items: center; padding: clamp(48px, 6vw, 96px) 0; }
.split-in { max-width: 520px; margin-left: auto; padding: 0 clamp(28px, 4vw, 72px); }
.split-ph { position: relative; overflow: hidden; min-height: clamp(300px, 32vw, 460px); }
.split-ph img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }


/* ---- Team, method, services, closing band (round-24) ------------------------ */

/* The people. The portrait square is the same size whether it holds a
   photograph or the initials, so nothing on the page moves on the day the
   photographs arrive. */
/* auto-fit, not a fixed count: three people fill the row today and a
   fourth simply joins it. */
.team { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: clamp(18px, 2vw, 28px); }
.tm {
  display: flex;
  align-items: center;
  gap: 18px;
  background: var(--white);
  border: 1px solid var(--line);
  padding: 18px;
}
.tm-ph { flex: none; width: 84px; height: 104px; object-fit: cover; background: var(--ivory); }
.tm-mono {
  display: grid;
  place-items: center;
  font-family: var(--serif);
  font-size: 1.5rem;
  letter-spacing: 0.06em;
  color: var(--ink-46);
}
.tm-txt h3 { font-family: var(--serif); font-weight: 400; font-size: 1.12rem; color: var(--ink); }
.tm-txt .tag { display: block; margin-top: 8px; font-size: 0.56rem; }
.tm-mail { display: inline-block; margin-top: 10px; font-size: 0.76rem; color: var(--ink-46); }
.tm-mail:hover { color: var(--ink); }

/* The six steps. The rule that joins the numbers is drawn behind them and
   stops at the first and the last, so it never runs off the edge of the row. */
.steps {
  position: relative;
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  /* Lo spazio fra due passi ha un nome perché lo usa anche il filetto che li
     unisce quando vanno su più righe — round 35, punto 5. */
  --stepgap: clamp(14px, 1.6vw, 24px);
  gap: var(--stepgap);
  list-style: none;
  counter-reset: step;
}
.steps::before {
  content: "";
  position: absolute;
  top: 21px;
  left: calc(100% / 12);
  right: calc(100% / 12);
  height: 1px;
  background: var(--line);
}
.step { position: relative; text-align: center; padding: 0 6px; }
.step-n {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 42px; height: 42px;
  margin: 0 auto 18px;
  border: 1px solid var(--alpine);
  border-radius: 50%;
  background: var(--paper);
  font-family: var(--serif);
  /* Round-45 — il peso era ereditato, e quello che ereditava era 200: un peso
     che di Cormorant Garamond non esiste (la famiglia parte da 300) e che il
     browser quindi inventava allargando un altro taglio. Il numero nel cerchio
     usciva più magro e più largo di ogni altro serif della pagina — è una
     delle differenze di carattere segnalate dal cliente. 400 è il peso di
     tutti gli altri titoli serif del sito. */
  font-weight: 400;
  font-size: 1.05rem;
  color: var(--ink);
}
.blk-ivory .step-n { background: var(--ivory); }
.step h3 {
  font-family: var(--sans);
  font-weight: 400;
  font-size: 0.62rem;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink);
}
.step p { margin-top: 10px; font-size: 0.79rem; line-height: 1.65; color: var(--ink-46); }

/* The five services. */
.svc-kicker { display: block; text-align: center; margin-bottom: clamp(30px, 3.4vw, 46px); }
.svc-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: clamp(14px, 1.6vw, 24px); }
.svc {
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--line);
  padding: clamp(22px, 2vw, 30px);
  transition: box-shadow 0.6s var(--ease), transform 0.6s var(--ease);
}
.svc:hover { box-shadow: 0 30px 60px -44px rgba(14, 27, 51, 0.5); transform: translateY(-3px); }
.svc-ic { display: block; color: var(--ink); opacity: 0.85; margin-bottom: 26px; }
.svc-t { font-family: var(--serif); font-weight: 400; font-size: 1.2rem; line-height: 1.25; color: var(--ink); }
.svc-d { margin-top: 12px; font-size: 0.84rem; line-height: 1.7; color: var(--ink-46); }
.svc-more { margin-top: auto; padding-top: 22px; font-size: 0.6rem; }

/* The line we work by, beside a photograph. */
.saying { display: grid; grid-template-columns: 0.9fr 1.1fr; gap: clamp(24px, 3vw, 52px); align-items: center; }
.saying-ph { position: relative; aspect-ratio: 4 / 3; overflow: hidden; }
.saying-ph img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.saying-q { position: relative; }
.saying-mark {
  display: block;
  font-family: var(--serif);
  font-size: 3.4rem;
  line-height: 0.6;
  color: var(--alpine);
  margin-bottom: 18px;
}
.saying-q p {
  font-family: var(--serif);
  font-size: clamp(1.2rem, 2vw, 1.7rem);
  line-height: 1.45;
  color: var(--ink);
  max-width: 640px;
}
.saying-q footer { margin-top: 24px; }

/* The closing band: a photograph darkened to navy, never washed to white. */
/* The band is navy and carries a photograph on top of it at a third of its
   strength — not a photograph with a navy veil. Stated on the band itself, so
   the colour behind the type is knowable without looking at the picture. */
.ctaband { position: relative; overflow: hidden; background: var(--ink); color: var(--paper); }
.ctaband-ph { position: absolute; inset: 0; }
.ctaband-ph img { width: 100%; height: 100%; object-fit: cover; opacity: 0.34; }
.ctaband-ph.ph-dead img { display: none; }
.ctaband-in {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(24px, 4vw, 60px);
  flex-wrap: wrap;
  padding: clamp(48px, 6vw, 88px) var(--gx);
}
.ctaband-title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.5rem, 2.6vw, 2.2rem);
  line-height: 1.22;
  color: var(--paper);
}
.ctaband-copy p { margin-top: 12px; color: var(--paper-70); max-width: 460px; font-size: 0.9rem; }
.ctaband-acts { display: flex; gap: 14px; flex-wrap: wrap; }
.ctaband .btn-ink { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.ctaband .btn-ink::before { background: var(--paper); }
.ctaband .btn-ink:hover { color: var(--ink); }
.btn-light { color: var(--paper); border-color: var(--paper-18); background: transparent; }
.btn-light::before { background: var(--paper); }
.btn-light:hover { color: var(--ink); border-color: var(--paper); }

.marks-kicker { display: block; margin-bottom: clamp(22px, 2.4vw, 32px); }
.blk-head-c { text-align: center; max-width: none; margin-bottom: clamp(34px, 4vw, 54px); }
.split-flip .split-copy { order: 2; }
.split-flip .split-in { margin-left: 0; margin-right: auto; }
.split-flip .split-ph { order: 1; }


/* ---- Valuation and contacts (round-24) --------------------------------------
   The valuation page puts its form on the photograph, in a navy card: this
   page has one job, and the job is the asking. The card is dark so the type on
   it is paper on navy — the picture underneath is never washed out. */
.vhero { position: relative; display: flex; align-items: center; overflow: hidden; min-height: clamp(520px, 62vh, 700px); }
.vhero-in { position: relative; z-index: 2; width: 100%; padding-top: clamp(28px, 4vw, 56px); padding-bottom: clamp(28px, 4vw, 56px); }
.vhero-copy { max-width: 620px; }

.vform {
  max-width: 620px;
  margin-top: clamp(28px, 3.4vw, 44px);
  padding: clamp(22px, 2.4vw, 32px);
  background: rgba(14, 27, 51, 0.94);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: var(--paper);
}
.vform-lead { display: block; color: var(--paper); margin-bottom: 20px; }
.vform-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-bottom: 14px; }
/* On navy the fields are boxes, not underlines: a hairline rule that works on
   paper disappears on a dark card, and a form whose fields cannot be seen is
   not a form.

   Every rule here is written under ".vform" on purpose. ".field-dark label"
   and ".field label" have exactly the same specificity, and the forms section
   sits further down this file — so the paper-coloured label lost to the navy
   one on source order alone, and the labels came out navy on navy. It is the
   second time in this round that a two-class selector quietly beat a
   one-class selector; the harness now measures the contrast of labels as well
   as buttons, on every page and every width. */
.vform .field-dark label { color: var(--paper-70); }
.vform .field-dark input, .vform .field-dark textarea {
  color: var(--paper);
  background: rgba(255, 255, 255, 0.07);
  background-image: none;
  border: 1px solid rgba(255, 255, 255, 0.22);
  padding: 12px 14px;
}
.vform .field-dark input::placeholder, .vform .field-dark textarea::placeholder { color: var(--paper-40); }
.vform .field-dark input:focus, .vform .field-dark textarea:focus {
  border-color: var(--paper);
  background: rgba(255, 255, 255, 0.12);
}
.vform .sel-dark .sel-btn {
  color: var(--paper);
  background: rgba(255, 255, 255, 0.07);
  background-image: none;
  border: 1px solid rgba(255, 255, 255, 0.22);
  padding: 12px 14px;
}
.vform .sel-dark .sel-btn:hover, .vform .sel-dark.is-open .sel-btn { background-image: none; border-color: var(--paper); }
.vform .sel-dark .sel-caret { color: var(--paper-70); }
.vform .sel-dark select { color: var(--paper); background-image: none; }
.vform .consent-dark span { color: var(--paper-70); }
.vform .consent-dark input { border-color: rgba(255, 255, 255, 0.4); }
.vform .field { gap: 7px; }
.vform .form-alert { color: var(--paper); border-color: var(--paper-40); }
.vform-foot { display: flex; align-items: center; justify-content: space-between; gap: 18px; flex-wrap: wrap; margin-top: 22px; }
.vform-note {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: var(--sans);
  font-size: 0.68rem;
  color: var(--paper-40);
}

/* How it works: three numbered steps, side by side. */
.how { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(20px, 3vw, 52px); list-style: none; }
.how-i { display: grid; grid-template-columns: auto 1fr; gap: 18px; align-items: start; }
.how-n {
  display: grid;
  place-items: center;
  width: 40px; height: 40px;
  border: 1px solid var(--alpine);
  border-radius: 50%;
  font-family: var(--serif);
  font-size: 1.05rem;
  color: var(--ink);
}
.how-i h3 {
  font-family: var(--sans);
  font-weight: 400;
  font-size: 0.64rem;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink);
  padding-top: 11px;
}
.how-i p { margin-top: 10px; font-size: 0.85rem; line-height: 1.7; color: var(--ink-46); }

/* Why us: four quiet cards. */
.why { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(14px, 1.6vw, 24px); }
.why-i { background: var(--white); border: 1px solid var(--line); padding: clamp(20px, 2vw, 28px); }
.why-ic { display: block; color: var(--ink); opacity: 0.85; margin-bottom: 20px; }
.why-i h3 {
  font-family: var(--sans);
  font-weight: 400;
  font-size: 0.62rem;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink);
}
.why-i p { margin-top: 12px; font-size: 0.83rem; line-height: 1.7; color: var(--ink-46); }

/* The questions, in two columns. */
.faq2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 clamp(24px, 3vw, 48px); }
.faq2-single, .faq2-single .faq2 { grid-template-columns: 1fr; }
.faq-i { border-bottom: 1px solid var(--line); }
.faq-i summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
  padding: 20px 0;
  font-size: 0.88rem;
  color: var(--ink);
}
.faq-i summary::-webkit-details-marker { display: none; }
.faq-i summary::after { content: "+"; color: var(--ink-46); font-size: 1.1rem; line-height: 1; }
.faq-i[open] summary::after { content: "–"; }
.faq-i p { padding-bottom: 22px; font-size: 0.85rem; line-height: 1.8; color: var(--ink-46); max-width: 60ch; }

/* Contacts: two panels, side by side. */
/* Round-27 — «i due riquadri sono lunghi uguali, non uno più lungo e l'altro
   più corto, anche se non sono pienamente aderenti». Vale per tutte e due le
   griglie della pagina: l'allineamento in alto lasciava il riquadro dei
   recapiti a mezz'altezza accanto al modulo, e il gradino bianco che restava
   sotto era la prima cosa che si vedeva. «stretch» è il valore normale della
   griglia, quindi qui si tratta di togliere una riga, non di aggiungerne una. */
.contact-grid { display: grid; grid-template-columns: 1.15fr 0.85fr; gap: clamp(16px, 1.8vw, 26px); align-items: stretch; }

/* Le colonne diventano contenitori verticali perché il contenuto possa
   prendersi il vuoto che avanza invece di lasciarlo tutto in fondo: è
   «panel-mid» a farlo, sul pezzo che deve stare a metà. */
.contact-grid > .panel { display: flex; flex-direction: column; }
/* Due classi di peso, non una: «.where-wrap» è dichiarata più sotto e con un
   margine alto suo, e a parità di peso vincerebbe lei — il blocco tornerebbe
   ad appoggiarsi in cima al riquadro, che è il difetto da correggere.
   In una colonna flessibile i margini «auto» si mangiano lo spazio che avanza
   prima che intervenga qualunque altra regola, e messi sopra e sotto lo
   dividono in parti uguali: è la centratura, senza contare niente. */
.panel > .panel-mid { margin-block: auto; }

/* Il modulo non è una scheda: sta sulla carta della pagina, senza fondo né
   bordo, e l'unico riquadro della riga resta quello dei recapiti — che così
   diventa la cosa che si stacca invece di una fra due scatole affiancate.
   Il fianco destro resta perché il testo non arrivi a filo del riquadro
   accanto quando lo spazio fra le colonne si stringe. */
/* Due classi nel selettore, non una: «.panel» è dichiarata più sotto in questo
   stesso foglio e a parità di peso vincerebbe lei, rimettendo fondo e bordo. */
.panel.panel-bare {
  background: transparent;
  border: 0;
  padding: 0 clamp(0px, 1.4vw, 22px) 0 0;
}

/* Round-27 — «i due quadrati sono attaccati e lunghi uguali».
   Nella referenza mappa e domande non sono due schede: sono un rettangolo solo
   diviso da un filetto, e chiudono alla stessa quota. Due regole bastano —
   niente spazio fra le colonne, e il bordo sinistro della seconda tolto, o al
   centro si vedrebbe una riga doppia invece del filetto. «stretch» è ripetuto
   qui anche se dal round-27 è già il valore di .contact-grid: è la condizione
   che rende vero «lunghi uguali», e se un domani la griglia tornasse ad
   allineare in alto, questa deve restare com'è. */
.contact-grid.panels-joined { gap: 0; align-items: stretch; }
.contact-grid.panels-joined > .panel + .panel { border-left: 0; }
.panel { background: var(--white); border: 1px solid var(--line); padding: clamp(24px, 2.6vw, 40px); }
.panel-quiet { background: var(--ivory); }
.panel-t { font-family: var(--serif); font-weight: 400; font-size: clamp(1.3rem, 2vw, 1.6rem); color: var(--ink); }
.panel-sub { margin-top: 10px; font-size: 0.86rem; color: var(--ink-46); }
.panel .form { margin-top: 26px; }

.office { display: flex; flex-direction: column; gap: 24px; margin-top: 26px; }
.office li { display: grid; grid-template-columns: auto 1fr; gap: 16px; align-items: start; }
.office-ic { color: var(--ink-46); margin-top: 2px; }
.office-l {
  display: block;
  font-family: var(--sans);
  font-size: 0.56rem;
  font-weight: 400;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-46);
  margin-bottom: 6px;
}
.office p, .office a { font-size: 0.88rem; line-height: 1.6; color: var(--ink); }
.office a:hover { color: var(--steel); }
.office-social { display: flex; gap: 20px; margin-top: 28px; padding-top: 22px; border-top: 1px solid var(--line); }
.office-social a {
  font-family: var(--sans);
  font-size: 0.62rem;
  font-weight: 400;
  letter-spacing: var(--track-btn);
  text-transform: uppercase;
  color: var(--ink-46);
}
.office-social a:hover { color: var(--ink); }

/* Round-27 — le regole di «.where», l'elenco delle zone accanto alla mappa,
   sono state tolte da qui e dalle tre passate che lo avevano rifatto: griglia
   a due colonne, poi elenco con i filetti, poi elenco senza. Il cliente ha
   chiesto di togliere l'elenco, non di riscriverlo un'altra volta — «rimando
   semplicemente alla pagina del territorio» — e regole senza più un elemento
   che le porti sono la cosa che fa credere di poterlo rimettere. */
.where-cta { margin-top: 28px; }

/* The direct ways in: one row of cards, and only the ones that exist. */
.ways { display: grid; grid-template-columns: 0.8fr 2.2fr; gap: clamp(24px, 3vw, 56px); align-items: center; background: var(--ivory); padding: clamp(28px, 3.4vw, 48px); }
.ways-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: clamp(18px, 2vw, 34px); }
.way { display: block; padding-left: 20px; border-left: 1px solid var(--line); }
.way-ic { display: block; color: var(--ink-46); margin-bottom: 14px; }
.way .tag { display: block; color: var(--ink); }
.way p { margin-top: 10px; font-size: 0.8rem; line-height: 1.6; color: var(--ink-46); }
.way-go {
  display: inline-block;
  margin-top: 14px;
  font-family: var(--sans);
  font-size: 0.66rem;
  font-weight: 400;
  letter-spacing: 0.08em;
  color: var(--ink);
}
.way:hover .way-go { color: var(--steel); }

/* ---- Blocks: grounds shade into one another instead of switching -----------
   Attenzione: il ritmo verticale non si decide qui. Queste due righe sono la
   dichiarazione di partenza; le misure che il browser applica stanno nel
   blocco «G4 — il ritmo verticale», più in basso nel foglio, che le riscrive
   entrambe. Cambiare qui e non là è il modo più veloce di credere di aver
   corretto qualcosa. */
.blk       { padding: clamp(40px, 4.4vw, 54px) 0; }
.blk-tight { padding: clamp(32px, 3.4vw, 44px) 0; }
.blk-ivory { background: linear-gradient(180deg, var(--paper) 0%, var(--ivory) 26%, var(--ivory) 74%, var(--paper) 100%); }
.blk-navy  { background: linear-gradient(168deg, var(--ink) 0%, var(--ink-deep) 100%); color: var(--paper); }
.blk-navy .lede { color: var(--paper-70); }

.blk-head { max-width: 700px; margin-bottom: clamp(24px, 2.6vw, 40px); }
.blk-more { margin-top: clamp(24px, 2.8vw, 40px); }

/* A heading that carries its own way out: the link to the full catalogue sits
   on the last line of the heading instead of underneath the cards, where it
   was one scroll away from the section it belongs to. */
.blk-after-search { padding-top: clamp(32px, 3.4vw, 48px); }

.blk-head-split {
  max-width: none;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: clamp(24px, 4vw, 60px);
}
.bh-copy { max-width: 700px; }
.bh-link { flex: none; padding-bottom: 10px; color: var(--ink-70); }
.bh-link:hover { color: var(--ink); }

/* ---- Cards ------------------------------------------------------------------
   The brand sheet's property card: a white card on the warm page, a hairline
   frame, the photograph at 4:3, and underneath — place, name, price, and the
   four figures a buyer actually compares (surface, bedrooms, bathrooms, energy
   class). Every one of those comes from the CRM; none of them is decoration. */
.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(24px, 2.4vw, 32px);
}
.card {
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--line);
  transition: box-shadow 0.6s var(--ease), transform 0.6s var(--ease);
}
.card:hover { box-shadow: 0 30px 60px -40px rgba(14, 27, 51, 0.5); transform: translateY(-3px); }
.card-ph {
  position: relative;
  /* Round-32 — 16:9. Nella referenza la fotografia della card è alta poco più
     della metà della sua larghezza: a 3:2 pesava troppo sul corpo di testo, ed
     era la prima cosa che il cliente ha chiesto di correggere («le proporzioni
     dell'immagine rispetto al resto»). La scheda immobile tiene il suo 3:2:
     quella è una fotografia grande, non una miniatura in una griglia. */
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: linear-gradient(150deg, var(--ivory), #ded9cd);
}
.card-ph img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: scale 1.6s var(--ease);
}
.card:hover .card-ph img { scale: 1.05; }
.card-ph::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(200deg, rgba(14, 27, 51, 0) 55%, rgba(14, 27, 51, 0.22) 100%);
  opacity: 0.75;
  transition: opacity 0.6s var(--ease);
}
.card:hover .card-ph::after { opacity: 1; }
.card-ph-empty { height: 100%; display: grid; place-items: center; color: var(--ink-46); }

.card-tags { position: absolute; z-index: 1; top: 14px; left: 14px; display: flex; gap: 6px; }
.pill {
  font-family: var(--sans);
  font-size: 0.56rem;
  font-weight: 400;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  background: rgba(255, 255, 255, 0.94);
  color: var(--ink);
  padding: 7px 12px;
}
.pill-ink { background: rgba(14, 27, 51, 0.88); color: var(--white); }

/* Save: kept on the visitor's own device, never on our servers — no account,
   no cookie banner, nothing to ask consent for. See site.js. */
.card-fav {
  position: absolute;
  z-index: 2;
  top: 12px; right: 12px;
  width: 38px; height: 38px;
  display: grid;
  place-items: center;
  color: var(--white);
  background: rgba(14, 27, 51, 0.22);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border-radius: 50%;
  transition: background 0.4s ease, color 0.4s ease, transform 0.4s var(--ease);
}
.card-fav:hover { background: rgba(14, 27, 51, 0.5); transform: scale(1.06); }
.card-fav svg { fill: none; stroke: currentColor; stroke-width: 1.2; }
.card-fav.is-on { background: var(--white); color: var(--ink); }
.card-fav.is-on svg { fill: currentColor; }

/* ---- Concluded listings (round-17) --------------------------------------------------------
   A sold property stays on the site as proof of work, so it has to be legible
   as sold at a glance and never mistaken for stock. Two earlier attempts are
   worth recording, because both were wrong:

     * a diagonal corner ribbon — it sat in the top-left corner, which is where
       the "Vendita" / "In trattativa" pills already live, so the two collided
       by construction. The label now runs along the foot of the photograph,
       where nothing else ever sits.
     * full greyscale — it turned every concluded listing into a different
       kind of object, and a black-and-white interior stops looking like a
       room somebody lived in. The photograph keeps its colour; it is only
       quietened, so the difference reads as "archived", not "damaged".

   The work of saying it is done by the band, in words. */
.sold-band {
  position: absolute;
  z-index: 2;
  left: 0; right: 0; bottom: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  background: linear-gradient(180deg, rgba(16, 30, 54, 0) 0%, rgba(16, 30, 54, 0.72) 42%, rgba(16, 30, 54, 0.92) 100%);
  color: var(--paper);
  font-family: var(--sans);
  font-weight: 400;
  font-size: 0.6rem;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  pointer-events: none;
}
/* The short rule is the same mark as the lintel above every heading. */
.sold-band::before {
  content: "";
  flex: 0 0 auto;
  width: 20px;
  height: 1px;
  background: var(--paper);
  opacity: 0.75;
}
.sold-band-lg {
  padding: 20px clamp(18px, 2.4vw, 30px);
  font-size: 0.72rem;
  letter-spacing: 0.34em;
  gap: 16px;
}
.sold-band-lg::before { width: 34px; }

/* Quietened, not drained: enough desaturation to separate the archive from
   the portfolio, not enough to stop being a photograph of a home. */
.card-closed .card-ph img { filter: saturate(0.5) contrast(0.97); }
.card-closed .card-price,
.card-closed .card-meta { color: var(--ink-46); }
.mosaic.is-closed .mtile img { filter: saturate(0.55) contrast(0.97); }
/* "Tutte le foto" would otherwise sit underneath the band. */
.mosaic.is-closed .mmore { bottom: 74px; }

/* ---- Round-32 — il corpo della card, sulla referenza -----------------------
   «correggi la card immobile: le proporzioni dell'immagine rispetto al resto,
   la posizione della scritta relativa alla località, il titolo, il prezzo, le
   caratteristiche. tutto deve essere allineato tra le varie card».

   L'ordine è quello della referenza, e l'elenco della richiesta lo ripete:
   luogo, titolo, prezzo, dati. Il filetto e «scopri dettagli» non ci sono più
   — la referenza non li ha, e la card intera è già il collegamento.

   L'allineamento fra card affiancate non si ottiene rendendole alte uguali
   (lo erano già: sono celle di una griglia). Deve essere alto uguale **ogni
   pezzo**: con un titolo che va a capo una volta e quello accanto due, tutto
   quello che segue scivola di una riga. Quindi ogni riga ha un'altezza
   dichiarata — luogo una riga, titolo sempre due, prezzo una — e i dati sono
   appoggiati al fondo. Da lì ogni quota coincide per costruzione.

   Le misure sono prese dalla referenza in rapporto alla larghezza della card
   (~390px su tre colonne): occhiello 0,62rem, titolo 1,15rem, prezzo
   1,05rem, dati 0,7rem. Il prezzo è più piccolo del titolo, non più grande:
   era il rapporto sbagliato della versione precedente. */
.card-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 22px 24px 24px;
}
/* Il luogo, in occhiello sopra il titolo. Una riga sola e mai a capo: è la
   riga che in round-31 disallineava le due card affiancate, e adesso non può
   più farlo. Il testo è «Comune · Quartiere», non il nome completo della zona
   — quello ripeteva il comune fra parentesi e lungo il doppio. */
.card-zone {
  font-family: var(--sans);
  font-size: 0.62rem;
  font-weight: 400;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  line-height: 1.4;
  color: var(--ink-46);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.card-title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 1.15rem;
  line-height: 1.3;
  letter-spacing: 0;
  color: var(--ink);
  margin-top: 9px;
  /* Due righe sempre: riservate anche quando il titolo ne riempie una sola. */
  min-height: calc(2 * 1.3em);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}
/* Il prezzo sotto il titolo, mai a capo: «€ 265.000» spezzato in due righe
   lasciava il simbolo su una riga e la cifra su quella dopo, e abbassava di
   una riga tutto il resto della card. */
.card-price {
  font-family: var(--serif);
  font-size: 1.05rem;
  font-weight: 400;
  letter-spacing: 0.01em;
  line-height: 1.4;
  color: var(--ink);
  margin-top: 7px;
  white-space: nowrap;
}
.card-price .per { font-family: var(--sans); font-size: 0.68rem; font-weight: 400; color: var(--ink-46); margin-left: 6px; }

/* I quattro dati, su una riga sola in fondo alla card, ciascuno dietro il suo
   disegno. Incolonnati da sinistra e non distribuiti: un immobile senza classe
   energetica ha tre dati invece di quattro, e con «space-between» i tre si
   allargavano fuori squadra rispetto alla card accanto. */
.card-meta {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  justify-content: flex-start;
  gap: 8px 17px;
  margin-top: auto;
  padding-top: 16px;
}
/* Su una colonna sola i dati vanno a capo invece di stringersi. */
@media (max-width: 620px) {
  .card-meta { flex-wrap: wrap; gap: 8px 18px; }
}
.card-meta span {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--sans);
  font-size: 0.7rem;
  font-weight: 400;
  line-height: 1.4;
  white-space: nowrap;
  color: var(--ink-46);
}
.card-meta svg { flex: none; stroke: currentColor; fill: none; stroke-width: 1.1; opacity: 0.9; }

/* ---- Territory index -------------------------------------------------------- */
.index-row {
  position: relative;
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: clamp(16px, 3vw, 40px);
  padding: clamp(24px, 3.4vw, 38px) clamp(2px, 1vw, 12px);
  overflow: hidden;
  background-image: var(--rule);
  background-repeat: no-repeat;
  background-size: 100% 1px;
  background-position: 0 0;
  transition: padding 0.55s var(--ease);
}
.index-row:last-child {
  background-image: var(--rule), var(--rule);
  background-position: 0 0, 0 100%;
  background-size: 100% 1px, 100% 1px;
}
.index-row::before {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(16, 30, 54, 0.055), rgba(16, 30, 54, 0));
  opacity: 0;
  transition: opacity 0.5s var(--ease);
}
.index-row:hover::before { opacity: 1; }
.index-row:hover { padding-left: clamp(14px, 2vw, 28px); }
.index-row > * { position: relative; z-index: 1; }

/* Round-26 — l'elenco delle zone riportato alla scheda di brand.

   Era Cormorant a 2,3 rem, tutto maiuscolo, tracciato 0,1em, con 38 px di
   respiro sopra e sotto ogni riga: sette voci occupavano più di uno schermo e
   ognuna leggeva come un titolo di pagina. Ma un elenco di collegamenti non è
   una gerarchia di titoli — la scheda di brand riserva il maiuscolo tracciato
   alle etichette e alla navigazione, e il Cormorant ai titoli.

   Qui vale la misura che la referenza dà alla stessa cosa, il titolo di una
   scheda immobile: serif, minuscolo, nessuna tracciatura, poco più di un rem.
   Le sette zone stanno in uno schermo e si leggono come un indice. */
.ir-name {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.05rem, 1.6vw, 1.38rem);
  letter-spacing: 0;
  text-transform: none;
  line-height: 1.25;
  color: var(--ink);
}
.index-row { padding-block: clamp(15px, 1.7vw, 21px); }
.ir-meta {
  font-family: var(--sans);
  font-size: 0.64rem;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-46);
  display: flex;
  align-items: baseline;
  gap: 10px;
  white-space: nowrap;
}
.ir-count { font-size: 1.2rem; letter-spacing: 0.04em; color: var(--ink); }
.ir-arrow { color: var(--ink-46); display: flex; transform: translateX(-8px); opacity: 0.4; transition: transform 0.5s var(--ease), opacity 0.4s ease, color 0.4s ease; }
.index-row:hover .ir-arrow { transform: translateX(0); opacity: 1; color: var(--ink); }

/* ---- Duo -------------------------------------------------------------------- */
.duo {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(36px, 6vw, 110px);
  align-items: center;
}
.duo + .duo { margin-top: clamp(80px, 11vw, 160px); }
.duo-ph { aspect-ratio: 4 / 5; overflow: hidden; }
.duo-ph img { width: 100%; height: 116%; object-fit: cover; }
.duo-copy .btn { margin-top: 38px; }

/* ---- Pledge ------------------------------------------------------------------ */
.pledge {
  background: linear-gradient(168deg, var(--ink) 0%, var(--ink-deep) 100%);
  color: var(--paper);
  padding: clamp(72px, 10vw, 132px) 0;
}
.pledge-grid {
  margin-top: clamp(38px, 5vw, 64px);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(30px, 4vw, 66px);
}
.pg {
  position: relative;
  padding-top: 26px;
  background-image: var(--rule-light);
  background-repeat: no-repeat;
  background-size: 100% 1px;
  background-position: 0 0;
}
.pg::before {
  content: "";
  position: absolute;
  top: 0; left: 0;
  width: 40px; height: 2px;
  background: var(--paper);
  transform: scaleX(0);
  transform-origin: left center;
}
.pg.is-in::before { animation: lintelDraw 0.8s var(--ease) 0.25s both; }
.pg h3 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(0.95rem, 1.3vw, 1.08rem);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  line-height: 1.5;
}
.pg p { margin-top: 15px; font-size: 0.92rem; line-height: 1.8; color: var(--paper-70); max-width: 310px; }

/* ---- Creed -------------------------------------------------------------------- */
.creed {
  min-height: clamp(400px, 60vh, 600px);
  display: grid;
  place-items: center;
  overflow: hidden;
  text-align: center;
  color: var(--paper);
}
.creed > img { position: absolute; inset: 0; width: 100%; height: 122%; object-fit: cover; }
.creed::after { background: linear-gradient(180deg, rgba(10, 20, 36, 0.62), rgba(10, 20, 36, 0.82)); }
.creed-in { position: relative; z-index: 1; padding-top: 56px; padding-bottom: 56px; }
.creed blockquote {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.35rem, 2.7vw, 2.15rem);
  line-height: 1.55;
  max-width: 760px;
}
.creed-in::after {
  content: "";
  display: block;
  width: 46px; height: 1px;
  margin: 36px auto 0;
  background: var(--paper-40);
}

/* ---- Closing line ------------------------------------------------------------- */
.endcta { text-align: center; }
.endcta p { font-family: var(--serif); font-weight: 400; font-size: clamp(1.3rem, 2.4vw, 1.9rem); line-height: 1.4; letter-spacing: 0.01em; }
/* A centred sentence set at title size in a 720px column breaks wherever the
   column happens to end, which left "caffè." alone on a line of its own.
   `balance` spreads the words evenly across the lines instead — the browsers
   that do not know the property simply keep the old behaviour. */
.endcta .ttl { text-wrap: balance; }
.endcta .lnk { display: inline-block; margin-top: 30px; color: var(--ink-70); }
.endcta .lnk:hover { color: var(--ink); }
/* The framed button had no space above it at all: the rule below it was
   written for the bare link used on the home page, and this block uses a
   button. A box needs more air than a piece of text, hence 36 and not 30. */
.endcta .btn { margin-top: 36px; }

/* ---- Areas (round-22) ------------------------------------------------------------
   The landing pages for the parts of the province. Nothing new is invented
   here: the type, the rules and the rhythm are the ones the rest of the site
   already uses, and only the two lists below need their own geometry. */
.faq { margin-top: clamp(26px, 3.4vw, 40px); }
.faq-item { padding: clamp(20px, 2.4vw, 28px) 0; background-image: var(--rule); background-repeat: no-repeat; background-position: 0 100%; background-size: 100% 1px; }
.faq-item:last-child { background-image: none; }
.faq-item h3 { font-family: var(--serif); font-weight: 400; font-size: clamp(1.02rem, 1.5vw, 1.18rem); letter-spacing: 0.01em; line-height: 1.35; }
.faq-item p { margin-top: 12px; color: var(--ink-70); max-width: 62ch; }

/* Seven links that have to be reachable from every area page: a quiet row, not
   a navigation menu. */
.area-links { list-style: none; display: flex; flex-wrap: wrap; gap: 10px 30px; margin-top: 26px; }
.area-links a { font-family: var(--sans); font-size: 0.9rem; letter-spacing: 0.04em; color: var(--ink-70); transition: color 0.35s ease; }
.area-links a:hover { color: var(--ink); }
.area-more { margin-top: clamp(26px, 3vw, 38px); }

/* ---- L'indice dei comuni, in /valutazione/ (round-42) ------------------------
   Il round-40 lo stampava con .area-links: ventuno collegamenti che portavano
   ognuno la frase intera («Valutazione gratuita a Laives»), incolonnati. In
   riga larga era una siepe di testo, su un telefono una colonna di ventuno
   righe quasi identiche alta più di uno schermo e mezzo. Il cliente l'ha
   chiamata «quella lista orribile»: era esattamente quello.

   Qui la frase è salita nel titolo della sezione e restano i nomi, raccolti
   sotto la loro zona. Due scelte di impaginazione, entrambe dettate dai dati:

   · Colonne CSS, non griglia. I sette gruppi hanno da uno a cinque comuni
     (Val Pusteria ne ha uno, Oltradige cinque): una griglia allineerebbe le
     righe e lascerebbe mezze colonne vuote sotto i gruppi corti. Le colonne
     multiple invece impilano i gruppi e ne pareggiano l'altezza da sole, che è
     il comportamento giusto per un indice. `break-inside: avoid` è ciò che
     impedisce a un gruppo di spezzarsi fra il titolo e i suoi comuni.

   · Il titolo della zona è un occhiello (le maiuscole spaziate del sistema) e
     non un terzo titolo serif: qui sopra c'è già .ttl-2, e due serif uno sotto
     l'altro leggerebbero come due sezioni invece che come una.

   Niente fisarmoniche e niente JavaScript: quello che si legge è quello che un
   crawler segue, e i nomi sono tutti visibili senza un clic. */
.cmx {
  margin-top: clamp(28px, 3.2vw, 40px);
  columns: 4;
  column-gap: clamp(28px, 3.4vw, 56px);
}
.cmx-g {
  break-inside: avoid;
  /* `page-break-inside` per i motori che non hanno ancora la proprietà nuova:
     senza, un gruppo può finire a cavallo di due colonne. */
  page-break-inside: avoid;
  margin-bottom: clamp(22px, 2.4vw, 30px);
}
/* L'occhiello della zona, con il filetto che sfuma del sistema. È anche un
   collegamento alla pagina di zona: chi cerca «Bassa Atesina» e chi cerca
   «Egna» partono dallo stesso blocco. */
.cmx-zone {
  font-family: var(--sans);
  font-weight: 400;
  font-size: 0.62rem;
  letter-spacing: var(--track-label);
  line-height: 1.5;
  text-transform: uppercase;
  color: var(--ink-46);
  padding-bottom: 10px;
  background-image: var(--rule);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% 1px;
}
.cmx-zone a { color: inherit; transition: color 0.35s ease; }
.cmx-zone a:hover { color: var(--ink); }
.cmx-list { list-style: none; margin-top: 11px; }
/* `display: block` più il riempimento: il bersaglio di un dito è tutta la
   riga, non le sole lettere. È un indice, quindi si tocca. */
.cmx-list a {
  display: block;
  padding: 4px 0;
  font-family: var(--sans);
  /* Stessa misura di .area-links: è navigazione, e la scala della pagina ha
     tre gradini soli — titolo serif, corpo 0,95rem, occhiello maiuscoletto. */
  font-size: 0.95rem;
  line-height: 1.45;
  color: var(--ink-70);
  transition: color 0.35s ease;
}
.cmx-list a:hover { color: var(--ink); }
/* Le colonne scendono con la larghezza, e i gradini sono misurati, non scelti
   a occhio: a parità di contenuto il blocco è alto 342 px a 1440, 371 a 768,
   356 a 620 e 512 su un telefono da 390. La vecchia lista piatta, sullo stesso
   telefono, ne misurava 802 — un terzo di schermo in più solo per dire ventuno
   volte «Valutazione gratuita a».

   Le due colonne arrivano solo a 520 px e non prima. A tre, fino a lì, la
   colonna resta larga oltre 160 px, che è quanto serve ai nomi lunghi
   («Oltrisarco, Don Bosco ed Europa-Novacella») per stare in due righe invece
   che in quattro: scendere a due colonne troppo presto allungava il blocco di
   un quarto invece di accorciarlo. */
@media (max-width: 1120px) { .cmx { columns: 3; } }
/* La stretta tipografica vale da qui in giù, a due o tre colonne che sia. */
@media (max-width: 620px) {
  .cmx { column-gap: 24px; }
  .cmx-g { margin-bottom: 18px; }
  /* L'occhiello si stringe: in una colonna stretta «Oltradige e Strada del
     Vino» va a capo comunque, ma «Merano e Burgraviato» ci sta in una riga
     sola invece che in due. */
  .cmx-zone { font-size: 0.58rem; letter-spacing: 0.14em; padding-bottom: 8px; }
  .cmx-list { margin-top: 9px; }
}
@media (max-width: 520px) { .cmx { columns: 2; column-gap: 22px; } }

/* ---- Page heads ---------------------------------------------------------------- */
/* Round-31 — l'apertura di una pagina interna scende con il resto: 148px di
   aria sotto una testata già alta 80, davanti a sezioni che ora ne stanno 54,
   erano un'apertura sproporzionata al documento che introduce. */
.phead { padding: clamp(48px, 6vw, 88px) 0 clamp(32px, 3.6vw, 48px); }
.phead-c { text-align: center; }
.phead-c .lede { margin-left: auto; margin-right: auto; }
.phead-tall { min-height: 60vh; display: flex; align-items: center; }
.phead-tall .shell { width: 100%; }
.phead-long { max-width: 900px; }
.phead-actions { margin-top: 46px; display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; }

.rise, .rise-2, .rise-3, .rise-4 { opacity: 0; animation: fadeUp 0.95s var(--ease) both; }
.rise   { animation-delay: calc(var(--boot) + 0.05s); }
.rise-2 { animation-delay: calc(var(--boot) + 0.18s); }
.rise-3 { animation-delay: calc(var(--boot) + 0.32s); }
.rise-4 { animation-delay: calc(var(--boot) + 0.46s); }

/* ---- Catalogue -------------------------------------------------------------------- */
.cat { display: grid; grid-template-columns: 250px 1fr; gap: clamp(36px, 4.5vw, 76px); align-items: start; }
.cat-side { position: sticky; top: calc(var(--hdh) + 28px); }

.fbox summary {
  display: none;
  font-family: var(--sans);
  font-size: 0.72rem;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  padding: 15px 18px;
  border: 1px solid var(--ink-14);
  cursor: pointer;
  list-style: none;
}
.fbox summary::-webkit-details-marker { display: none; }

.fseg { display: flex; border: 1px solid var(--ink-14); }
.fseg a {
  flex: 1;
  text-align: center;
  font-family: var(--sans);
  font-size: 0.64rem;
  letter-spacing: var(--track-btn);
  text-transform: uppercase;
  padding: 12px 4px;
  color: var(--ink-46);
  transition: background 0.4s var(--ease), color 0.4s ease;
}
.fseg a + a { border-left: 1px solid var(--ink-08); }
.fseg a.on { background: var(--ink); color: var(--paper); }
.fseg a:hover:not(.on) { color: var(--ink); }

.fstack { margin-top: 32px; display: flex; flex-direction: column; gap: 26px; }
.ffield { display: flex; flex-direction: column; gap: 7px; }
.ffield label {
  font-family: var(--sans);
  font-size: 0.6rem;
  font-weight: 400;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-46);
}
.fapply { margin-top: 8px; text-align: center; }
.freset { align-self: flex-start; color: var(--ink-46); font-size: 0.68rem; }

.cat-empty { text-align: center; padding: clamp(60px, 9vw, 120px) 0; }
.cat-empty .lede { max-width: 440px; margin: 0 auto; }
.cat-empty .btn { margin-top: 36px; }

.pager { display: flex; align-items: center; justify-content: center; gap: 16px; margin-top: clamp(48px, 6vw, 78px); }
.pager a {
  display: grid; place-items: center;
  width: 46px; height: 46px;
  border: 1px solid var(--ink-14);
  font-size: 1.05rem;
  transition: background 0.4s var(--ease), color 0.4s ease, border-color 0.4s ease;
}
.pager a:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.pager .off { font-family: var(--sans); font-size: 0.7rem; letter-spacing: 0.2em; color: var(--ink-46); }

/* ---- Detail (round-24) ------------------------------------------------------
   The reference's listing page: breadcrumb, a gallery of one large photograph
   and three beside it, the enquiry form riding alongside them, then the name,
   the price, the five figures, the description, what the place has, the plan
   and the map. The old page put the form at the bottom of a single column;
   this one asks the question while the visitor is still looking. */
.det { padding: clamp(20px, 2.4vw, 34px) 0 clamp(48px, 6vw, 88px); }

.crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  font-family: var(--sans);
  font-size: 0.68rem;
  color: var(--ink-46);
  margin-bottom: clamp(16px, 2vw, 26px);
}
.crumbs a { transition: color 0.35s ease; }
.crumbs a:hover { color: var(--ink); }
.crumbs-here { color: var(--ink-70); }

.det-top {
  display: grid;
  grid-template-columns: 1fr clamp(300px, 26vw, 372px);
  gap: clamp(16px, 1.6vw, 24px);
  align-items: start;
}

/* Gallery: one photograph that carries the page, three that promise the rest. */
.gal { display: grid; grid-template-columns: 2fr 1fr; gap: 10px; align-items: stretch; }
.gal-main, .gal-tile { position: relative; display: block; overflow: hidden; background: var(--ivory); }
/* 3:2, misurato sulla tavola (733 × 499). Round-30: era 4:3, e a quel rapporto
   la fotografia di apertura usciva quasi quadrata. */
.gal-main { aspect-ratio: 3 / 2; }
/* The photographs are positioned, not flowed: an image with an intrinsic
   height would push the side column taller than the picture beside it, and the
   two would stop lining up at the foot — which is the one thing this
   arrangement has to get right. */
.gal-main img, .gal-tile img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  transition: scale 1.4s var(--ease);
}
.gal-main:hover img, .gal-tile:hover img { scale: 1.03; }
.gal-side { display: grid; grid-template-rows: repeat(3, 1fr); gap: 10px; min-height: 0; }
.gal-tile { min-height: 0; }
.gal:not(:has(.gal-side)) { grid-template-columns: 1fr; }

.gal-count {
  position: absolute;
  left: 14px; bottom: 14px;
  font-family: var(--sans);
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  color: var(--white);
  background: rgba(14, 27, 51, 0.82);
  padding: 7px 12px;
}
.gal-all {
  position: absolute;
  inset: auto 0 0 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 12px 10px;
  font-family: var(--sans);
  font-size: 0.62rem;
  font-weight: 400;
  letter-spacing: var(--track-btn);
  text-transform: uppercase;
  color: var(--white);
  background: rgba(14, 27, 51, 0.72);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  transition: background 0.4s ease;
}
.gal-tile:hover .gal-all { background: rgba(14, 27, 51, 0.88); }

.det-card {
  background: var(--white);
  border: 1px solid var(--line);
  padding: clamp(22px, 2vw, 30px);
}
.det-card .tag { display: block; color: var(--ink); }
.det-aside-sub { margin-top: 10px; font-size: 0.86rem; line-height: 1.65; color: var(--ink-46); }
.det-card .form { margin-top: 20px; }
.det-send { width: 100%; justify-content: center; }
.det-closed-flag {
  font-family: var(--sans);
  font-size: 0.6rem;
  font-weight: 400;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-46);
  margin-bottom: 10px;
}
.det-closed-actions { display: flex; flex-direction: column; align-items: flex-start; gap: 18px; margin-top: 24px; }

/* Name, price, and the three quiet actions opposite them. */
.det-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 30px;
  flex-wrap: wrap;
  margin-top: clamp(30px, 3.6vw, 52px);
  padding-bottom: clamp(24px, 3vw, 36px);
  border-bottom: 1px solid var(--line);
}
.det-place {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--sans);
  font-size: 0.66rem;
  font-weight: 400;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-46);
}
.det-place svg { flex: none; }
.det-sep { opacity: 0.5; }
.det-title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.9rem, 3.2vw, 2.7rem);
  line-height: 1.16;
  color: var(--ink);
  margin-top: 12px;
  max-width: 820px;
}
.det-price {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.4rem, 2.2vw, 1.85rem);
  color: var(--ink);
  margin-top: 12px;
}
.det-price .per { font-family: var(--sans); font-size: 0.8rem; color: var(--ink-46); margin-left: 8px; }
.det-ref {
  font-family: var(--sans);
  font-size: 0.62rem;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-46);
  margin-top: 10px;
}
.det-actions { display: flex; flex-direction: column; align-items: flex-start; gap: 14px; }
.det-act {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  font-family: var(--sans);
  font-size: 0.64rem;
  font-weight: 400;
  letter-spacing: var(--track-btn);
  text-transform: uppercase;
  color: var(--ink-70);
  transition: color 0.35s ease;
}
.det-act:hover { color: var(--ink); }
.det-act svg { flex: none; fill: none; }
.det-act.is-on svg { fill: currentColor; }
.det-act.is-on { color: var(--ink); }

/* The five figures. */
.keyrow {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(20px, 4vw, 64px);
  padding: clamp(26px, 3vw, 40px) 0;
  border-bottom: 1px solid var(--line);
}
.key { display: grid; grid-template-columns: auto auto; gap: 4px 12px; align-items: center; }
.key svg { grid-row: span 2; color: var(--ink-46); }
.key-n { font-family: var(--serif); font-size: 1.45rem; line-height: 1; color: var(--ink); }
.key .tag { font-size: 0.56rem; }

/* La descrizione dell'immobile — round-42: giustificata.
   ---------------------------------------------------------------------------
   È il solo testo lungo del sito che sia davvero un blocco compatto: sette,
   otto righe piene per capoverso, dentro una colonna di 820 px. A bandiera, il
   margine destro rientrava e usciva di quasi due centimetri riga dopo riga e
   il blocco sembrava sfrangiato accanto alla riga di cifre, che è allineata su
   entrambi i lati.

   Giustificato **senza sillabazione** però è peggio del male che cura: senza
   punti in cui spezzare, il browser allarga gli spazi fra le parole e nel
   testo si aprono i «fiumi» bianchi. Qui la sillabazione è accesa, e funziona
   perché <html lang="…"> porta già la lingua giusta (it/de/en) — è quella che
   dice al browser quale dizionario usare. Senza l'attributo, `hyphens: auto`
   non fa nulla: è il motivo per cui la regola sta qui e non si tocca il
   template. Vale soprattutto per il tedesco, dove una parola sola può essere
   lunga un terzo di riga.

   `text-align-last: left` chiude il discorso: l'ultima riga di ogni capoverso
   resta com'è, non viene stirata da un margine all'altro. Con
   `white-space: pre-line` ogni «a capo» scritto dall'agente è un fine riga
   forzato, e questa regola vale anche per quelli.

   Solo qui: il resto del sito resta a bandiera, come nella referenza del
   cliente. */
.det-desc {
  max-width: 820px;
  margin-top: clamp(26px, 3vw, 40px);
  font-size: 0.95rem;
  line-height: 1.9;
  color: var(--ink-70);
  white-space: pre-line;
  text-align: justify;
  text-align-last: left;
  -webkit-hyphens: auto;
  hyphens: auto;
  /* Nessuna parola spezzata sotto le sei lettere, e mai meno di tre lettere
     da una parte o dall'altra del trattino: è la differenza fra «trilo-cale»,
     che si legge, e «li-ving», che è un inciampo. I browser che non conoscono
     la proprietà la saltano e si tengono la sillabazione normale. */
  -webkit-hyphenate-limit-before: 3;
  -webkit-hyphenate-limit-after: 3;
  hyphenate-limit-chars: 6 3 3;
  /* Un indirizzo o un codice catastale dentro la descrizione non deve poter
     sfondare la colonna quando gli spazi sono già tirati. */
  overflow-wrap: break-word;
}

/* What the place has: one row, drawings at the same weight as the rules. */
.amen-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px clamp(20px, 3vw, 48px);
  margin-top: clamp(26px, 3vw, 40px);
  padding-top: clamp(26px, 3vw, 36px);
  border-top: 1px solid var(--line);
}
.amen-row li {
  display: flex;
  align-items: center;
  gap: 11px;
  font-size: 0.86rem;
  color: var(--ink-70);
}
.amen-row svg { flex: none; color: var(--alpine); }

.det-boxes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(16px, 1.6vw, 24px);
  margin-top: clamp(30px, 3.6vw, 52px);
}
.det-box { background: var(--white); border: 1px solid var(--line); padding: clamp(20px, 2vw, 28px); }
.det-box .tag { display: block; margin-bottom: 18px; color: var(--ink); }
.det-box-cta { margin-top: 18px; }
.plan-frame { display: block; background: var(--paper); border: 1px solid var(--line); padding: 14px; }
.plan-frame img { width: 100%; height: auto; mix-blend-mode: multiply; }

.det-more { margin-top: clamp(30px, 3.6vw, 48px); border-top: 1px solid var(--line); }
.det-more summary {
  list-style: none;
  cursor: pointer;
  padding: 22px 0;
  font-family: var(--sans);
  font-size: 0.66rem;
  font-weight: 400;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink);
  display: flex;
  align-items: center;
  gap: 12px;
}
.det-more summary::-webkit-details-marker { display: none; }
.det-more summary::after {
  content: "+";
  margin-left: auto;
  font-size: 1.1rem;
  color: var(--ink-46);
}
.det-more[open] summary::after { content: "–"; }

.facts { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0 clamp(24px, 4vw, 64px); padding-bottom: 26px; }
.fact {
  display: flex;
  justify-content: space-between;
  gap: 18px;
  padding: 13px 0;
  border-bottom: 1px solid var(--line);
}
.fact dt { font-family: var(--sans); font-size: 0.76rem; color: var(--ink-46); }
.fact dd { font-family: var(--sans); font-size: 0.8rem; color: var(--ink); text-align: right; }

.det-similar { background: var(--ivory); }
.det-similar .tag { display: block; margin-bottom: clamp(22px, 2.6vw, 34px); }

.mosaic-empty {
  position: relative;
  aspect-ratio: 16 / 9;
  display: grid;
  place-items: center;
  background: linear-gradient(150deg, var(--ivory), #ded9cd);
  color: var(--ink-46);
}

/* Print: the page a visitor takes to the viewing. */
@media print {
  .hd, .ft, .det-actions, .det-aside, .det-similar, #site-splash, .crumbs { display: none !important; }
  .det-top { display: block; }
  .gal { grid-template-columns: 1fr; }
  .gal-side, .gal-all, .gal-count { display: none; }
  body { background: #fff; }
}

/* ---- Map (round-17) --------------------------------------------------------
   The basemap is CARTO Positron; the filter takes the last of its blue-grey
   out and warms it towards the page's ivory, so the map reads as part of the
   sheet rather than as an embedded screenshot. Leaflet's own chrome is
   restyled to the site's square, quiet controls. */
.map-frame {
  position: relative;
  height: clamp(300px, 42vh, 420px);
  background: var(--ivory);
  overflow: hidden;
}
.map-canvas { position: absolute; inset: 0; }
.map-frame .leaflet-container {
  height: 100%;
  background: var(--ivory);
  font-family: var(--sans);
}
/* Round-30 — la mappa aveva una dominante che non è del marchio.
   «sepia(0.22)» tinge di bruno-arancio tutto quello che tocca: sulla scheda
   immobile la mappa usciva color pesca, cioè l'unico riquadro della pagina con
   un colore caldo che non compare in nessuna delle cinque tinte del marchio
   (blu notte, blu acciaio, azzurro alpino, sabbia chiara, avorio caldo).
   La correzione tiene lo stesso meccanismo e gli gira la tinta: la seppia
   serve solo a *creare* una dominante su un'immagine ormai grigia, e la
   rotazione di 178° la porta dal bruno all'azzurro alpino. Il resto —
   saturazione bassa, contrasto morbido — resta com'era, perché il compito del
   filtro è far leggere la mappa come parte del foglio e non come una
   fotografia incollata sopra. */
.map-frame .leaflet-tile-pane {
  filter: grayscale(1) sepia(0.45) hue-rotate(178deg) saturate(0.5) brightness(1.03) contrast(0.92);
}
.map-frame .leaflet-bar,
.map-frame .leaflet-bar a {
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: rgba(251, 250, 247, 0.94);
  color: var(--ink);
}
.map-frame .leaflet-bar a {
  width: 34px; height: 34px; line-height: 34px;
  font-family: var(--sans); font-weight: 400;
  transition: background 0.3s ease, color 0.3s ease;
}
.map-frame .leaflet-bar a + a { border-top: 1px solid var(--ink-08); }
.map-frame .leaflet-bar a:hover { background: var(--ink); color: var(--paper); }
.map-frame .leaflet-control-attribution {
  background: rgba(251, 250, 247, 0.88);
  color: var(--ink-46);
  font-family: var(--sans);
  font-size: 0.6rem;
  letter-spacing: 0.04em;
  padding: 3px 8px;
}
.map-frame .leaflet-control-attribution a { color: var(--ink-46); }

/* The pin: the site's navy drop, with a breathing halo underneath. */
.map-pin { background: none; border: 0; }
.map-pin svg { position: relative; z-index: 2; filter: drop-shadow(0 3px 6px rgba(16, 30, 54, 0.28)); }
.map-pin-halo {
  position: absolute;
  left: 50%; top: 34px;
  width: 46px; height: 46px;
  margin: -23px 0 0 -23px;
  border-radius: 50%;
  background: rgba(16, 30, 54, 0.13);
  animation: pinPulse 3.4s var(--ease) infinite;
}
@keyframes pinPulse {
  0%, 100% { transform: scale(0.72); opacity: 0.85; }
  50%      { transform: scale(1.15); opacity: 0.25; }
}
.map-note { margin-top: 14px; font-size: 0.82rem; color: var(--ink-46); line-height: 1.7; }
.map-note .lnk { margin-left: 6px; color: var(--ink); }

.det-aside { position: sticky; top: calc(var(--hdh) + 28px); min-width: 0; }
/* Round-29 — qui la scheda del modulo veniva ridipinta con una sfumatura
   sabbia e imbottita di 40px. Tolto: nella referenza è bianca col filetto, e
   quell'imbottitura è metà del motivo per cui il modulo era più alto della
   galleria. La scheda si veste una volta sola, nella sezione "la testata
   della scheda immobile" più in basso — dove sta anche la spiegazione. */
.det-aside-sub { margin: 14px 0 30px; font-size: 0.9rem; color: var(--ink-70); line-height: 1.75; }

/* Concluded listing: the panel that replaces the viewing form. */
.det-closed-flag {
  font-family: var(--sans);
  font-size: 0.62rem;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-46);
  margin-bottom: 12px;
}
.det-closed-actions { display: flex; flex-direction: column; align-items: flex-start; gap: 18px; }

/* ---- Prose --------------------------------------------------------------------------- */
.prose p + p { margin-top: 26px; }
.prose-lead {
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(1.2rem, 1.9vw, 1.45rem);
  line-height: 1.6;
  color: var(--ink);
}
.prose p { color: var(--ink-70); }

.band { position: relative; height: clamp(280px, 46vh, 500px); overflow: hidden; }
.band img { width: 100%; height: 124%; object-fit: cover; }

.tri  { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(30px, 4vw, 60px); }
.quad { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(26px, 3vw, 48px); }
.tri-cell {
  position: relative;
  padding-top: 26px;
  background-image: var(--rule);
  background-repeat: no-repeat;
  background-size: 100% 1px;
  background-position: 0 0;
}
.blk-navy .tri-cell { background-image: var(--rule-light); }
.tri-cell::before {
  content: "";
  position: absolute;
  top: 0; left: 0;
  width: 40px; height: 2px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
}
.is-in.tri-cell::before { animation: lintelDraw 0.8s var(--ease) 0.25s both; }
.tri-cell h3 {
  font-family: var(--sans);
  font-weight: 400;
  font-size: 1rem;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
}
.tri-cell p { margin-top: 15px; font-size: 0.92rem; line-height: 1.8; color: var(--ink-70); }
.blk-navy .tri-cell p { color: var(--paper-70); }
/* Attenzione: questa classe si chiama come i sei passi di _steps.html e vince
   su quella, perché è dichiarata più in basso (è il difetto del round-39, che
   qui aveva colpito il peso del carattere). Round-45: 200 non è un taglio di
   Montserrat che il sito carica — la richiesta a Google Fonts porta 300, 400,
   500 e 600 — quindi il browser lo inventava assottigliando il 300. La
   differenza si vedeva sul numero nel cerchio dei passi, che eredita da qui.
   300 è il taglio più leggero che esiste davvero. */
.step {
  display: block;
  font-family: var(--sans);
  font-weight: 400;
  font-size: 1.6rem;
  line-height: 1;
  color: var(--ink-46);
  margin-bottom: 14px;
}
.blk-navy .step { color: var(--paper-40); }

/* ---- Contact ---------------------------------------------------------------------------- */
.contact { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: clamp(40px, 6vw, 100px); align-items: start; }
.contact-form .form { margin-top: 32px; max-width: 540px; }
.office { margin-top: 28px; display: flex; flex-direction: column; gap: 28px; }
.office h3 { font-family: var(--sans); font-weight: 400; font-size: 1.05rem; letter-spacing: 0.06em; }
.office p { margin-top: 7px; color: var(--ink-70); }
.office-l {
  display: block;
  font-family: var(--sans);
  font-size: 0.6rem;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-46);
  margin-bottom: 5px;
}
.office a {
  font-size: 1rem;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-size: 0 1px;
  background-position: 0 100%;
  transition: background-size 0.45s var(--ease);
}
.office a:hover { background-size: 100% 1px; }

/* ---- Forms -------------------------------------------------------------------------------
   Round-17 — why the `min-width: 0` below matters.

   A grid item's default minimum width is `auto`, which means "never shrink
   below your content". An <input> reports a wide intrinsic width (browsers
   size it from the `size` attribute, ~180px), so the two-column `.form-row`
   inside the 370px sidebar demanded roughly 390px. The track grew to fit,
   every other row of the form stretched to that same oversized track, and the
   whole form spilled out past the right edge and the bottom of its card — the
   effect visible on the listing page's "Richiedi una visita" panel.

   Setting `min-width: 0` on the grid containers and their items lets the
   tracks shrink to the space actually available; the inputs then follow their
   `width: 100%`. The row also stops being two columns once the space is truly
   narrow, so the fields never become unusable slivers.
   ------------------------------------------------------------------------------------------- */
.form { display: grid; gap: 28px; min-width: 0; }
.form > * { min-width: 0; }
.form-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
  gap: 28px;
  min-width: 0;
}
.form-row > * { min-width: 0; }
.shell-form { max-width: 680px; }
.shell-form .form { margin-top: 36px; }
.form-send { justify-self: start; }

/* The sidebar column is narrow by design: stack the paired fields there. */
.det-card .form-row { grid-template-columns: 1fr; }
.det-card .form { max-width: 100%; }

.field { display: flex; flex-direction: column; gap: 9px; min-width: 0; }
.field label {
  font-family: var(--sans);
  font-size: 0.6rem;
  font-weight: 400;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-46);
  transition: color 0.35s ease;
}
.field input, .field textarea {
  width: 100%;
  min-width: 0;
  max-width: 100%;
  border: 0;
  border-radius: 0;
  background: transparent;
  font-family: var(--prose);
  font-size: 1rem;
  color: var(--ink);
  padding: 8px 0 11px;
  background-image: var(--rule);
  background-repeat: no-repeat;
  background-size: 100% 1px;
  background-position: 0 100%;
  transition: background-size 0.5s var(--ease);
}
.field textarea { min-height: 104px; resize: vertical; line-height: 1.65; }
.field input:focus, .field textarea:focus {
  outline: none;
  background-image: linear-gradient(90deg, var(--ink), var(--ink));
}
.field:focus-within label { color: var(--ink); }
.field.error input, .field.error textarea { background-image: linear-gradient(90deg, #a33b2e, #a33b2e); }

.consent { display: flex; gap: 13px; align-items: flex-start; cursor: pointer; }
.consent input {
  appearance: none;
  -webkit-appearance: none;
  width: 16px; height: 16px;
  min-width: 16px;
  border: 1px solid var(--ink-14);
  margin-top: 4px;
  cursor: pointer;
  display: grid; place-items: center;
  transition: background 0.3s ease, border-color 0.3s ease;
}
.consent input:checked { background: var(--ink); border-color: var(--ink); }
.consent input:checked::after { content: "✓"; color: var(--paper); font-size: 0.58rem; line-height: 1; }
.consent span { font-size: 0.82rem; color: var(--ink-46); line-height: 1.65; }
.consent.error span { color: #a33b2e; }

.form-alert { border: 1px solid #a33b2e; color: #a33b2e; font-size: 0.86rem; padding: 14px 18px; }
.hp-field { position: absolute; left: -6000px; width: 1px; height: 1px; overflow: hidden; }

/* ---- Dropdown ------------------------------------------------------------------------------ */
.sel { position: relative; }
.sel.is-ready > select { display: none; }

.sel-btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 8px 0 11px;
  text-align: left;
  font-family: var(--sans);
  font-size: 0.9rem;
  letter-spacing: 0.04em;
  color: var(--ink);
  background-image: var(--rule);
  background-repeat: no-repeat;
  background-size: 100% 1px;
  background-position: 0 100%;
  transition: background-image 0.4s ease;
}
.sel-btn:hover, .sel.is-open .sel-btn { background-image: linear-gradient(90deg, var(--ink), var(--ink)); }
.sel-val { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sel-caret { flex: none; display: flex; color: var(--ink-46); transition: transform 0.45s var(--ease); }
.sel.is-open .sel-caret { transform: rotate(180deg); }

.sel-list {
  position: absolute;
  z-index: 60;
  left: 0; right: 0;
  top: calc(100% + 8px);
  max-height: 292px;
  overflow-y: auto;
  scrollbar-width: thin;
  background: linear-gradient(180deg, var(--paper), var(--ivory));
  box-shadow: 0 26px 50px -30px rgba(10, 20, 36, 0.55), 0 0 0 1px var(--ink-08);
  opacity: 0;
  visibility: hidden;
  clip-path: inset(0 0 100% 0);
  transition: opacity 0.35s var(--ease), clip-path 0.45s var(--ease), visibility 0.45s;
}
.sel.is-open .sel-list { opacity: 1; visibility: visible; clip-path: inset(0 0 0 0); }

.sel-opt {
  position: relative;
  padding: 13px 18px;
  font-family: var(--sans);
  font-size: 0.76rem;
  letter-spacing: var(--track-btn);
  text-transform: uppercase;
  color: var(--ink-70);
  cursor: pointer;
  overflow: hidden;
  transition: color 0.35s ease;
}
.sel-opt::before {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(90deg, var(--ink), var(--ink-deep));
  transform: translateX(-100%);
  transition: transform 0.4s var(--ease);
}
.sel-opt > span { position: relative; z-index: 1; }
.sel-opt:hover, .sel-opt.is-active { color: var(--paper); }
.sel-opt:hover::before, .sel-opt.is-active::before { transform: translateX(0); }
.sel-opt.is-sel > span::after {
  content: "";
  display: inline-block;
  width: 14px; height: 1px;
  margin-left: 11px;
  vertical-align: middle;
  background: currentColor;
  opacity: 0.6;
}

/* ---- La galleria a schermo intero (round 51) ------------------------------------
   Il disegno e la ragione di ogni scelta stanno nel commento in
   listing_detail.html; qui c'è la sola meccanica. Tre note che servono a chi
   torna:

   * `--lbx-ground` è un **neutro**, non il blu notte del marchio. Un fondo
     colorato dietro una fotografia sposta la lettura di tutti i grigi
     dell'immagine, e in queste case il legno è dappertutto. È l'unico punto
     del sito in cui il colore giusto non è un colore del marchio, e la ragione
     è che qui la protagonista è la fotografia — la stessa linea del round 26
     sul velo dell'apertura, applicata a un caso in cui porta altrove.
   * L'altezza si misura in `svh` e non in `vh`: su iOS `vh` conta anche la
     barra degli indirizzi, e la striscia delle miniature finirebbe sotto di
     essa. Sotto, la barretta del gesto ha il suo inserto.
   * `overscroll-behavior: contain` sulla pista: senza, arrivati all'ultima
     fotografia il gesto continua e trascina la pagina sotto la galleria. */
.lbx {
  position: fixed;
  inset: 0;
  /* La larghezza è dichiarata e non lasciata a `inset: 0`. Finché la pagina
     sotto tiene la sua barra di scorrimento, un riquadro fisso disteso «da
     bordo a bordo» viene largo quanto la finestra **meno** quella barra:
     misurato, 1437 px su 1452, cioè quindici pixel di avorio lungo il bordo
     destro di una galleria nera. A toglierla è l'`overflow: hidden` su html
     più in basso; questa riga è la cintura, perché quel valore vale la
     finestra intera comunque, e quel che avanza lo taglia l'overflow qui
     sotto. */
  width: 100vw;
  z-index: 250;
  --lbx-ground: #131313;
  --lbx-ink: rgba(255, 255, 255, 0.92);
  --lbx-quiet: rgba(255, 255, 255, 0.42);
  background: var(--lbx-ground);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
/* Tutte e due, e non solo il corpo: se la barra di scorrimento resta, il
   riquadro fisso è largo quanto la finestra **meno** la barra, e lungo il
   bordo destro si vede una striscia della pagina sotto. Misurata: 15 px di
   avorio accanto a una galleria nera. */
html.lbx-open, body.lbx-open { overflow: hidden; }

/* La barra: a sinistra a che numero siamo, in mezzo di che immobile si tratta,
   a destra la chiusura. Il nome dell'immobile c'è perché la galleria copre
   tutta la pagina e senza di lui non si sa più che cosa si sta guardando. */
.lbx-bar {
  flex: none;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 18px;
  padding: calc(14px + var(--sat)) clamp(12px, 2vw, 26px) 14px;
  font-family: var(--sans);
}
.lbx-count {
  font-size: 0.62rem;
  letter-spacing: var(--track-label);
  color: var(--lbx-quiet);
  font-variant-numeric: tabular-nums;
}
.lbx-count span { color: var(--lbx-ink); }
.lbx-title {
  font-size: 0.66rem;
  letter-spacing: var(--track-btn);
  text-transform: uppercase;
  color: var(--lbx-quiet);
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.lbx-close {
  justify-self: end;
  width: 42px; height: 42px;
  display: grid; place-items: center;
  color: var(--lbx-ink);
  border: 1px solid rgba(255, 255, 255, 0.16);
  transition: transform 0.45s var(--ease), background 0.35s ease, border-color 0.35s ease;
}
.lbx-close:hover { transform: rotate(90deg); background: rgba(255, 255, 255, 0.08); border-color: rgba(255, 255, 255, 0.3); }

.lbx-stage { position: relative; flex: 1 1 auto; min-height: 0; display: flex; }
.lbx-track {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  overscroll-behavior: contain;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.lbx-track::-webkit-scrollbar { display: none; }
.lbx-track:focus-visible { outline: 1px solid rgba(255, 255, 255, 0.35); outline-offset: -2px; }
.lbx-item {
  position: relative;
  flex: 0 0 100%;
  scroll-snap-align: center;
  scroll-snap-stop: always;
  padding: 0 clamp(10px, 6vw, 96px);
  min-width: 0;
}
/* La fotografia è **posizionata**, non centrata da una griglia, e la ragione è
   una misura: dentro una griglia `max-height: 100%` si risolve su un'altezza
   che il browser considera indefinita, quindi non si applica — provato, una
   verticale da 1200 × 1600 usciva alla sua misura naturale e sbordava dallo
   schermo. Con `inset: 0` la scatola dell'immagine **è** quella del riquadro,
   che un'altezza definita ce l'ha, e `contain` ci fa entrare la fotografia
   intera senza tagliarla né deformarla: una verticale e un'orizzontale
   arrivano tutte e due com'erano. */
.lbx-item img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 30px 60px rgba(0, 0, 0, 0.55));
}
.lbx-arw {
  position: absolute;
  top: 50%;
  z-index: 2;
  transform: translateY(-50%);
  width: 46px; height: 46px;
  display: grid; place-items: center;
  color: var(--lbx-ink);
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: rgba(0, 0, 0, 0.28);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  transition: background 0.35s ease, border-color 0.35s ease;
}
.lbx-arw:hover { background: rgba(255, 255, 255, 0.12); border-color: rgba(255, 255, 255, 0.34); }
.lbx-prev { left: clamp(8px, 1.6vw, 22px); }
.lbx-next { right: clamp(8px, 1.6vw, 22px); }

.lbx-thumbs {
  flex: none;
  display: flex;
  gap: 8px;
  padding: 14px clamp(12px, 2vw, 26px) calc(16px + var(--sab));
  overflow-x: auto;
  scrollbar-width: none;
  scroll-behavior: smooth;
}
.lbx-thumbs::-webkit-scrollbar { display: none; }
.lbx-th {
  flex: 0 0 auto;
  width: 74px; height: 50px;
  overflow: hidden;
  opacity: 0.42;
  outline: 1px solid transparent;
  outline-offset: -1px;
  transition: opacity 0.35s ease, outline-color 0.35s ease;
}
.lbx-th img { width: 100%; height: 100%; object-fit: cover; display: block; }
.lbx-th:hover { opacity: 0.75; }
.lbx-th.is-on { opacity: 1; outline-color: rgba(255, 255, 255, 0.85); }

@media (max-width: 700px) {
  /* Sul telefono si sfoglia con il dito: le frecce sarebbero due bersagli sopra
     la fotografia, e la fotografia è tutto quello che c'è. */
  .lbx-arw { display: none; }
  .lbx-item { padding: 0 8px; }
  .lbx-title { display: none; }
  .lbx-bar { grid-template-columns: 1fr auto; }
  .lbx-th { width: 58px; height: 40px; }
}
@media (prefers-reduced-motion: reduce) {
  .lbx-track { scroll-behavior: auto; }
  .lbx-close:hover { transform: none; }
}

/* ---- Footer -----------------------------------------------------------------
   Light, like every page of the reference: the navy footer belonged to the old
   design. Four columns, the mark and the payoff on the left, and a closing line
   with the company details the law wants on every page. */
.ft {
  background: var(--paper);
  color: var(--ink-70);
  padding: clamp(56px, 6.5vw, 88px) 0 28px;
  /* Round-27 — «in fondo togli la riga divisoria del footer perché ci sono
     troppe righe». In fondo alla pagina dei contatti se ne contavano tre nel
     giro di pochi centimetri: il fondo della fascia dei modi diretti, questo
     filetto, e quello sopra la riga legale. Il piede si stacca già dal suo
     fondo e dallo spazio che ha sopra: il filetto qui era una terza
     ripetizione, non una separazione in più. */
}
.ft-grid {
  display: grid;
  /* Five columns since round-24: mark, Esplora, Servizi, Azienda, Contatti. */
  grid-template-columns: 1.5fr 1fr 1fr 1fr 1.2fr;
  gap: clamp(32px, 4vw, 64px);
  padding-bottom: clamp(40px, 5vw, 64px);
}
/* Round-26 — il marchio del piede eredita le regole della testata (.hd-brand),
   così i due lockup non possono divergere. Le misure che stavano qui —
   larghezza 190 px e tracciatura 0,42em — ne facevano una seconda versione,
   più larga e più stretta di spaziatura, ed era la differenza che si vedeva
   confrontando piede e banner. Resta solo il colore: il piede è chiaro. */
.ft-mark .hd-brand .lock { color: var(--ink); }
.ft-payoff {
  font-family: var(--serif);
  font-size: 1.12rem;
  line-height: 1.45;
  color: var(--ink);
  margin-top: 26px;
}
.ft-social { display: flex; gap: 16px; margin-top: 26px; }
.ft-social a { color: var(--ink-46); transition: color 0.35s ease; }
.ft-social a:hover { color: var(--ink); }
.ft-social svg { display: block; }

.ft-col h4 {
  font-family: var(--sans);
  font-weight: 400;
  font-size: 0.6rem;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink);
  margin-bottom: 20px;
}
.ft-col ul { display: flex; flex-direction: column; gap: 11px; }
.ft-col a, .ft-col p { color: var(--ink-70); font-size: 0.86rem; }
.ft-col a {
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-size: 0 1px;
  background-position: 0 100%;
  transition: background-size 0.45s var(--ease), color 0.35s ease;
}
.ft-col a:hover { color: var(--ink); background-size: 100% 1px; }
/* The filled button inside a footer column. ".ft-col a" is two classes deep
   and was winning over ".btn-ink" on specificity alone, which painted navy
   text on the navy fill: the label was there, and invisible. */
.ft-col a.ft-cta { margin-top: 24px; color: var(--white); background-image: none; }
/* Round-52 — «se vado sopra al pulsante contattaci diventa scuro e si fa
   fatica a leggere».

   La riga precedente diceva `color: var(--ink)` al passaggio del mouse, ed era
   la riga giusta copiata dal posto sbagliato. Nella fascia d'invito
   (`.ctaband`) il velo che entra da sinistra è avorio, quindi la scritta deve
   scurirsi per restare leggibile. Qui il velo è `--steel`, blu acciaio: la
   scritta si scuriva **sopra uno sfondo che si scuriva anche lui**. Blu notte
   su blu acciaio è un rapporto di contrasto di 1,6 a 1 — sotto la soglia di
   leggibilità (4,5) di quasi tre volte, e su un pulsante di dodici pixel in
   maiuscoletto spaziato, che è il testo che ne ha più bisogno.

   Il pulsante resta pieno e l'etichetta resta bianca: il passaggio del mouse
   si vede lo stesso, perché il fondo passa da blu notte a blu acciaio. Il
   segnale è lo schiarirsi del fondo, non lo scurirsi della scritta. */
.ft-col a.ft-cta:hover { color: var(--white); }

.ft-base {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 14px 28px;
  flex-wrap: wrap;
  padding-top: 24px;
  border-top: 1px solid var(--line);
  font-family: var(--sans);
  font-size: 0.7rem;
  color: var(--ink-46);
}
.ft-base a { color: var(--ink-46); transition: color 0.35s ease; }
.ft-base a:hover { color: var(--ink); }
.ft-legal { display: flex; flex-wrap: wrap; gap: 6px 18px; align-items: center; }
/* The VAT numbers are read digit by digit, not skimmed. */
.ft-vat { font-variant-numeric: tabular-nums; letter-spacing: 0.03em; }
.ft-made { display: inline-flex; align-items: center; gap: 12px; }
.ft-made svg { stroke: currentColor; fill: none; stroke-width: 1; }

/* ---- Motion: one idea — things are uncovered by a travelling edge ------------------------------------ */
html.js .io {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 1.05s var(--ease), transform 1.05s var(--ease);
  transition-delay: var(--d, 0s);
}
html.js .io.is-in { opacity: 1; transform: none; }

/* Images are not faded in: they are wiped open, with the frame settling.
   The clip sits on the image, never on the observed element — a fully
   clipped element reports no intersection and would never be revealed. */
html.js .io-wipe { opacity: 1; transform: none; }
html.js .io-wipe img {
  clip-path: inset(0 100% 0 0);
  scale: 1.12;
  transition: clip-path 1.35s var(--ease), scale 1.9s var(--ease);
  transition-delay: var(--d, 0s);
}
html.js .io-wipe.is-in img { clip-path: inset(0 0 0 0); scale: 1; }

html.js .io-blur { filter: blur(8px); transition: opacity 1.15s var(--ease), transform 1.15s var(--ease), filter 1.15s var(--ease); }
html.js .io-blur.is-in { filter: blur(0); }

/* ==== ROUND 25 — allineamento alle referenze del cliente =====================
   Questo blocco sta DOPO tutte le regole di base e PRIMA delle media query.
   È voluto: tre volte in due round una dichiarazione scritta in alto è stata
   annullata in silenzio da una riscrittura della classe base più in basso
   (.ft-col a, .field-dark label, .blk-head-c). Da qui in avanti le correzioni
   che devono vincere si scrivono qui, non a metà file.                        */

/* -- G8 — la classe che nasconde il testo per i soli lettori di schermo non
   esisteva, e base.html la usa quattro volte: le parole "LinkedIn" e
   "Instagram" erano disegnate accanto alle icone nel piede di ogni pagina. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* -- G9 — .blk-head-c dichiarava max-width:none, ma .blk-head la riportava a
   700px 200 righe più in basso: i titoletti "centrati" erano centrati dentro
   i primi 700px, cioè 258px a sinistra dell'asse della pagina. */
.blk-head-c { max-width: none; margin-inline: auto; text-align: center; }
.blk-head-c .tag::after { margin-inline: auto; }

/* -- G4 — il ritmo verticale. Erano 158px sopra e sotto ogni sezione, cioè
   316px di vuoto fra due blocchi; nelle referenze quello stacco misura 80-110.
   Round-31 — 92 per lato ne facevano ancora 184, ed è il vuoto che il cliente
   ha visto fra il team e «il nostro approccio», e fra i servizi e «il nostro
   processo»: mezzo schermo di niente. 54 per lato fa 108, dentro la misura
   della referenza e sulla scala degli 8px come tutto il resto della griglia.
   Scendono con lui le misure interne alla sezione: se restassero com'erano, il
   vuoto fra un occhiello e le sue schede sarebbe largo quanto quello fra due
   sezioni diverse, e la pagina smetterebbe di dire dove finisce una cosa. */
.blk        { padding: clamp(40px, 4.4vw, 54px) 0; }
.blk-tight  { padding: clamp(32px, 3.4vw, 44px) 0; }
.blk-head   { margin-bottom: clamp(24px, 2.6vw, 40px); }
.blk-head-c { margin-bottom: clamp(24px, 2.6vw, 40px); }
.marks      { padding: clamp(32px, 3.4vw, 44px) 0; }
.pledge     { padding: clamp(40px, 4.4vw, 54px) 0; }
.blk-more   { margin-top: clamp(24px, 2.8vw, 40px); }
.blk-after-search { padding-top: clamp(28px, 3vw, 40px); }

/* -- G3 — la scala dei titoli. L'h1 stava a 54px a 1440; nelle referenze
   legge fra i 62 e i 66. I titoli di sezione salgono di conseguenza. */
.hero-title { font-size: clamp(2.2rem, 4.6vw, 4.05rem); line-height: 1.12; }
.ttl        { font-size: clamp(1.65rem, 2.7vw, 2.5rem); line-height: 1.18; }
.hero-lede  { font-size: clamp(0.92rem, 1.05vw, 1.02rem); }

/* Le referenze spezzano i titoli in righe corte volute. In HTML sono <br>
   dentro <span class="brk">: qui vengono spenti sotto i 780px, dove una riga
   corta imposta a mano diventa una riga storta. */
@media (max-width: 780px) { .brk { display: none; } }

/* -- G1/G2 — la home. La fotografia riempie lo schermo e la testata ci sta
   sopra, trasparente, finché non si comincia a scorrere.
   Round-26: la regola vale su TUTTE le pagine, non più solo sulla home — vedi
   il blocco "La testata non è mai una barra" più in basso. */
body.is-home .hero { min-height: 100vh; }

/* -- H2 — il secondo pulsante della hero sta sopra una fotografia: nella
   scheda di brand è chiaro con il bordo avorio, non navy su navy. */
.hero-acts .btn-ghost, .hero-acts .btn-light {
  color: var(--ink);
  border: 1px solid var(--ink-14);
  background: rgba(255, 255, 255, 0.82);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
/* Round-29 — «quando vado sul mouse sul bottone valuta immobile viene fuori
   sfondo blu e scritto blu».

   Era una collisione di specificità, la stessa che aveva già colpito il
   pulsante nel piede. «.btn-ghost:hover» (una classe + una pseudo-classe) e
   «.hero-acts .btn-ghost» (due classi) pesano uguale: a parità di peso vince
   chi è scritto dopo, e la regola della hero sta millecinquecento righe più in
   basso. Il «color: var(--white)» del passaggio del mouse veniva quindi
   sovrascritto dal navy della regola della hero — mentre «.btn-ghost::before»,
   che è la tendina navy comune a tutti i pulsanti del sito, continuava a
   scorrere. Fondo navy, scritta navy: l'etichetta c'era ed era invisibile.

   Il rimedio è dichiarare il bianco qui, dove la specificità è quella giusta,
   invece di aspettarselo dalla regola generale. Il «background: var(--white)»
   che c'era prima è tolto: combatteva con la tendina navy senza vincere né
   perdere, ed è ciò che rendeva il difetto difficile da leggere. Così il
   secondo pulsante della hero si comporta come tutti gli altri del sito —
   tendina navy da sinistra, etichetta bianca, bordo navy. */
.hero-acts .btn-ghost:hover, .hero-acts .btn-light:hover {
  color: var(--white);
  border-color: var(--ink);
}

/* -- G5 — i campi. Nelle referenze ogni campo è un riquadro con bordo da 1px
   e il testo di aiuto dentro; da noi erano righe sottolineate. Vale per la
   scheda immobile, i contatti e la valutazione. */
.field input, .field textarea {
  border: 1px solid var(--line);
  background: var(--white);
  background-image: none;
  padding: 13px 16px;
  font-size: 0.92rem;
  transition: border-color 0.35s ease, box-shadow 0.35s ease;
}
.field input::placeholder, .field textarea::placeholder { color: var(--ink-46); opacity: 1; }
.field input:focus, .field textarea:focus {
  background-image: none;
  border-color: var(--ink);
  box-shadow: 0 0 0 1px var(--ink);
}
.field.error input, .field.error textarea { background-image: none; border-color: #a33b2e; }
.field textarea { min-height: 128px; }
.sel-plain .sel-btn, .sel .sel-btn {
  border: 1px solid var(--line);
  background: var(--white);
  background-image: none;
  padding: 13px 16px;
  font-size: 0.92rem;
}
.sel .sel-btn:hover, .sel.is-open .sel-btn { background-image: none; border-color: var(--ink); }
/* La barra dei filtri del catalogo è già una scheda bianca: lì i campi non
   vanno riquadrati un'altra volta. */
.fbar .sel .sel-btn { border: 0; background: transparent; padding: 0; }

/* Le etichette sopra il campo si accorciano: sono un'etichetta, non un titolo. */
.field label { font-size: 0.58rem; }
.form { gap: 20px; }

/* -- G10 — le tre icone social del piede, in fila sotto il payoff. */
.ft-social { display: flex; align-items: center; gap: 16px; margin-top: 22px; }
.ft-social a { display: inline-flex; color: var(--ink-46); transition: color 0.35s ease; }
.ft-social a:hover { color: var(--ink); }

/* -- G6 — la riga legale del piede porta anche privacy e cookie. */
.ft-policy { display: flex; flex-wrap: wrap; gap: 18px; }
.ft-policy a { color: inherit; text-decoration: none; border-bottom: 1px solid var(--ink-14); padding-bottom: 1px; }
.ft-policy a:hover { color: var(--ink); border-color: var(--ink); }


/* ---- Round 25, seconda parte: i moduli rifatti sulle referenze ----------- */

/* La fascia dei valori: sulla home è centrata con l'icona sopra l'etichetta
   (riquadro 6 della scheda), altrove resta icona a sinistra come nelle
   referenze di Chi siamo e Servizi. */
.marks-c .mk { grid-template-columns: 1fr; justify-items: center; text-align: center; gap: 14px; }
.marks-c .mk-ic { justify-content: center; margin-top: 0; }
.marks-c .mk-txt p:last-child { max-width: 230px; margin-inline: auto; }

/* La scheda della ricerca sulla home.
   Round-26 — scavalca il bordo della fotografia come quella del catalogo. Nel
   round precedente stava sotto, e fra la fine dell'immagine e la scheda
   restava una striscia di avorio vuota: le due pagine facevano la stessa cosa
   in due modi diversi. Sono gli stessi numeri di .filters. */
.hsearch {
  position: relative;
  z-index: 3;
  padding: 0;
  margin-top: clamp(-48px, -3.2vw, -30px);
}
/* Round-26 — la striscia fra la fotografia e la scheda prendeva il sabbia
   della fascia dei valori, per non essere un terzo colore fra due superfici.
   Round-29 — quel sabbia è **tolto**, ed è la seconda volta che il cliente
   segnala lo stesso rettangolo: «cancella quel rettangolo grigio scuro e
   rendilo chiaro come il resto così che tocchi l'immagine».

   Il ragionamento del round-26 era giusto e la premessa era sbagliata. La
   striscia deve avere il colore di *ciò che viene dopo*, ma ciò che viene dopo
   sulla home **dipende dai dati**: se c'è almeno un immobile in evidenza
   arriva .blk-after-search, che sta sull'avorio della pagina; solo quando il
   catalogo è vuoto la fascia sabbia dei valori sale al suo posto. In locale,
   senza immobili, il sabbia combaciava; online, con un immobile pubblicato, lo
   stesso sabbia diventava un rettangolo scuro appoggiato al bordo della
   fotografia. Un colore che vale solo per una certa quantità di dati non è il
   colore giusto.

   Senza niente da dipingere, in quello spazio si vede il fondo della pagina
   (--paper), che è il colore del resto: l'avorio arriva a filo dell'immagine
   da qualunque parte la si guardi e con qualsiasi catalogo. Le fasce che
   hanno un colore proprio — .marks, .blk-ivory — se lo dipingono da sé, come
   hanno sempre fatto. È anche il comportamento che il catalogo ha già con
   .filters, che una striscia non l'ha mai avuta: adesso le due pagine fanno
   la stessa cosa nello stesso modo.

   Il padding sotto la hero resta: è lo spazio che la scheda bianca scavalca
   col margine negativo, e senza di lui la scheda salirebbe sul titolo. */
.hero { padding-bottom: clamp(30px, 3.2vw, 48px); }
.hsearch .fbar { margin: 0; }
.hsearch .chips { margin-top: 16px; }

/* "Pulisci filtri" sta in fondo a destra della riga dei chip, come la referenza. */
.chips { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.chip-clear { margin-left: auto; }

/* La barra dei risultati: la referenza non scrive "ordina" accanto alla tendina. */
.sortbar { display: flex; align-items: center; gap: 12px; }

/* Round-26 — GRIGLIA e MAPPA, i due pulsanti che nella referenza stanno a
   sinistra dell'ordinamento. Stessa altezza della tendina accanto, così la
   riga ha una linea di base sola. */
/* Il conteggio a sinistra, i tre controlli tutti a destra: senza questo la
   riga ha tre figli e "space-between" spinge griglia/mappa in mezzo al vuoto. */
.results-bar .viewbar { margin-left: auto; }
.viewbar { display: flex; align-items: stretch; gap: 8px; }
.viewbtn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 12px 18px;
  border: 1px solid var(--line);
  background: var(--white);
  font-family: var(--sans);
  font-size: 0.6rem;
  font-weight: 400;
  letter-spacing: var(--track-btn);
  text-transform: uppercase;
  color: var(--ink-46);
  transition: color 0.35s ease, border-color 0.35s ease;
}
.viewbtn svg { flex: none; }
.viewbtn:hover { color: var(--ink); border-color: var(--alpine); }
.viewbtn.on { color: var(--ink); border-color: var(--ink-14); cursor: default; }

/* La scheda dei filtri scavalca il bordo inferiore della fotografia, come
   nella referenza: nel round precedente la fotografia finiva e la scheda
   cominciava sotto, con una striscia di avorio in mezzo. */
.phero { padding-bottom: clamp(30px, 3.2vw, 48px); }
.filters { margin-top: clamp(-48px, -3.2vw, -30px); }

/* ---- Scheda immobile ---------------------------------------------------- */
/* La galleria e il modulo finiscono alla stessa altezza: nella referenza le
   due colonne sono allineate in basso, da noi la galleria si fermava 260px
   più su e lasciava un buco. */
.det-top { align-items: stretch; }
.det-gallery { display: flex; min-height: 0; }
.det-gallery > .gal { flex: 1; min-height: 0; }
/* Round-31 — qui c'era «height: 100%» anche sulle miniature, ed era il difetto
   che il cliente vede da due giri: «le tre foto di lato sovrastano l'immagine
   di sotto».
   Il 100% di una cella di griglia non è l'altezza della sua riga: è l'altezza
   dell'intera griglia. Ogni miniatura diventava quindi alta quanto tutta la
   colonna, e tre miniature alte tutta la colonna fanno una colonna alta tre
   volte, che esce dal riquadro e finisce sopra quello che sta sotto. Non
   serviva a niente: le celle di una griglia si stirano da sole per riempire la
   riga, ed è quello che fanno adesso.

   Round-33 — era rimasto sulla fotografia grande, e lì faceva il danno
   opposto: la riga la decideva il modulo, e la fotografia si stirava con
   essa. Annullato in fondo al foglio, nel blocco round-33. */
.det-gallery .gal-main { height: 100%; }
.det-gallery .gal-main img, .det-gallery .gal-tile img { width: 100%; height: 100%; object-fit: cover; }
.det-aside .det-card { height: 100%; display: flex; flex-direction: column; }

/* ---- Round-29 — la testata della scheda immobile, rifatta sulla referenza --
   «la scheda immobile ha un problema di impaginazione delle foto».

   Sono tre difetti diversi che si sommavano nello stesso riquadro. Vale la
   pena tenerli distinti, perché due si vedono e uno no.

   1. LA COLONNA DELLE MINIATURE ERA SEMPRE ALTA TRE. «grid-template-rows:
      repeat(3, 1fr)» disegna tre righe **comunque**, anche quando le
      fotografie sono due: la terza restava vuota e le miniature si fermavano
      ai due terzi della fotografia grande, con un vuoto sotto. Nella
      referenza le miniature sono tre perché quell'immobile ha dodici foto;
      il nostro ne ha tre, quindi le miniature sono due — e devono riempire
      la colonna lo stesso. «grid-auto-rows» crea tante righe quante sono le
      fotografie e le fa uguali: due miniature stanno a metà, tre a un terzo,
      e l'impaginazione non dipende più da quante foto ha caricato l'agente.

   2. IL MODULO DETTAVA L'ALTEZZA. Le due colonne sono legate («stretch»), e
      quando una è più alta trascina l'altra. Il nostro modulo, con
      un'etichetta maiuscola sopra ogni campo e un'area di testo da 128px,
      era più alto della galleria: la fotografia grande veniva stirata ben
      oltre il suo 4:3 e la pagina si apriva su un'immagine sproporzionata.
      Nella referenza i campi portano il testo guida dentro e nessuna
      etichetta sopra, e il modulo sta comodamente dentro l'altezza della
      fotografia — che è il verso giusto: a comandare l'altezza dev'essere
      l'immagine.

      Le etichette non spariscono, si nascondono: restano nella pagina per i
      lettori di schermo. È il compromesso che la referenza fa e che qui si
      può fare perché riguarda **solo** questo modulo; contatti e valutazione
      tengono le etichette visibili, dove c'è spazio e dove il modulo è la
      cosa principale della pagina invece che una colonna di servizio.

   3. LA SCHEDA ERA GRIGIA. Più in basso nel foglio una seconda regola la
      ridipingeva con una sfumatura sabbia, coprendo il bianco col bordo
      sottile dichiarato più su. Nella referenza è una scheda bianca su fondo
      avorio, ed è così che si stacca dalla pagina.

   Le proporzioni delle tre colonne sono misurate sulla tavola della
   referenza: fotografia 52%, miniature 22%, modulo 24% della larghezza. Da
   noi erano 47 / 23 / 27 — il modulo rubava alla fotografia. */
.det-top { grid-template-columns: 1fr clamp(290px, 24vw, 340px); }
.gal { grid-template-columns: 7fr 3fr; }
.gal-side { grid-template-rows: none; grid-auto-rows: 1fr; }

.det-aside .det-card {
  background: var(--white);
  border: 1px solid var(--line);
  padding: clamp(18px, 1.6vw, 24px);
}
.det-aside .det-aside-sub { margin: 7px 0 0; font-size: 0.79rem; line-height: 1.55; }
.det-card .form { margin-top: 16px; gap: 11px; }
/* Il campo perde l'interlinea fra etichetta e riquadro, perché l'etichetta
   non occupa più spazio: è nascosta alla vista, non tolta. */
.det-card .field { gap: 0; }
.det-card .field > label {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.det-card .field input, .det-card .field textarea { padding: 11px 14px; font-size: 0.85rem; }
.det-card .field textarea { min-height: 84px; }
.det-card .consent { margin-top: 1px; }
.det-card .consent span { font-size: 0.73rem; line-height: 1.5; }
.det-card .form-note { margin-top: 8px; font-size: 0.67rem; line-height: 1.5; }

/* «Vedi tutte le foto»: sull'ultima miniatura, appoggiata al piede.
   Round-31 — era centrata in mezzo alla miniatura («non va bene che sta in
   mezzo a una foto»): un rettangolo navy piantato al centro di un'immagine
   sembra un errore di caricamento, non un comando. Al piede si legge per
   quello che è — la didascalia che apre la galleria — e lascia vedere la
   fotografia che sta coprendo. */
.gal-all {
  position: absolute; left: 50%; top: auto; right: auto; bottom: 12px;
  width: auto; height: auto; transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: 9px;
  padding: 10px 16px;
  background: rgba(14, 27, 51, 0.9); color: var(--paper);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  font-family: var(--sans); font-size: 0.58rem; letter-spacing: var(--track-btn); text-transform: uppercase;
  white-space: nowrap;
}

/* Il riferimento scende sotto le tre azioni. */
.det-actions .det-ref { margin-top: 14px; font-size: 0.6rem; letter-spacing: 0.24em; color: var(--ink-46); }

/* Le cinque cifre, separate da filetti come nella referenza. */
.keyrow > .key + .key { border-left: 1px solid var(--line); padding-left: clamp(18px, 2.4vw, 34px); }

/* Le caratteristiche su una riga sola, sei per riga come la referenza. */
.amen-row { display: grid; grid-template-columns: repeat(6, 1fr); gap: clamp(14px, 1.8vw, 26px); }
.amen-row li { align-items: flex-start; }

/* I punti di forza, accanto alla planimetria. */
.strengths { list-style: none; display: grid; gap: 13px; margin-top: 18px; }
.strengths li {
  display: grid; grid-template-columns: 16px 1fr; gap: 12px; align-items: start;
  font-size: 0.86rem; line-height: 1.6; color: var(--ink-70);
}
.strengths li svg { margin-top: 3px; color: var(--alpine); }

/* La mappa scende in una fascia sua, a tutta larghezza. */
.det-map { margin-top: clamp(26px, 3vw, 42px); }
.det-map .map-frame { margin-top: 16px; }

/* Gli immobili simili: intestazione con le frecce, come la referenza. */
.det-similar { background: transparent; }
.sim-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: clamp(20px, 2.4vw, 32px); }
.sim-nav { display: flex; gap: 10px; }
.sim-arw {
  width: 36px; height: 36px; display: grid; place-items: center;
  border: 1px solid var(--line); background: transparent; color: var(--ink);
  cursor: pointer; transition: border-color 0.35s ease, background 0.35s ease;
}
.sim-arw:hover { border-color: var(--ink); background: var(--white); }
.sim-track { scroll-behavior: smooth; }

/* La variante della scheda di brand: titolo, luogo, dati, poi prezzo e
   "scopri dettagli". Stesso HTML delle altre schede, solo un altro ordine. */
/* Round-31 — «card-alt» non esiste più: l'ordine della scheda di brand è quello
   di tutte le card del sito (vedi il blocco «Cards» più su nel foglio), quindi
   la variante non ha più niente da variare. Due versioni della stessa card
   sulla stessa pagina sono due oggetti diversi per chi guarda. */

/* ---- Round-30 — la scheda immobile, seconda passata ----------------------
   Sei correzioni del cliente, tutte sullo stesso foglio della referenza.

   1. LE PROPORZIONI DEL BLOCCO DELLE FOTO. Sulla tavola la fotografia grande
      occupa il 52% della larghezza, le miniature il 22%, il modulo il 24%, e
      la fotografia è in 3:2. Da noi la fotografia era dichiarata 4:3 e il
      modulo si prendeva il 28%: la fotografia partiva più stretta e più alta
      di quella della referenza, e siccome le due colonne sono legate in
      altezza, il modulo — che era più alto — la stirava ancora. Il risultato
      era un'immagine di apertura quasi quadrata.

      Ora la fotografia è 3:2 e il modulo è stato stretto quanto basta per
      starci dentro: l'altezza del blocco la decide l'immagine, che è il verso
      giusto, e il riquadro «Richiedi informazioni» comincia e finisce
      esattamente dove comincia e finisce la fotografia. Il pulsante è
      appoggiato al fondo del riquadro (margine automatico), così il modulo
      riempie la colonna invece di lasciare un fondo vuoto.

   2. OGNI CARATTERISTICA HA IL SUO DISEGNO — la scelta è in
      website/feature_icons.py; qui c'è solo lo spazio che il disegno occupa,
      identico per tutti, altrimenti le etichette non si allineano fra loro.

   3. PLANIMETRIA E PUNTI DI FORZA SI TOCCANO, come nella referenza: un
      pannello solo diviso da un filetto. Il corridoio di avorio in mezzo li
      faceva leggere come due sezioni diverse.

   4. I PUNTI DI FORZA RIEMPIONO IL LORO RIQUADRO. Erano tutti stretti in alto
      con mezzo riquadro vuoto sotto, perché la planimetria è alta e la lista
      no: le righe ora si distribuiscono sull'altezza disponibile, come sulla
      tavola, dove l'ultima voce arriva in fondo al pannello.

   5. LA MAPPA — vedi il blocco «Map» più su nel foglio: il filtro seppia le
      dava una dominante arancio che non sta in nessuna delle cinque tinte del
      marchio.

   6. GLI IMMOBILI SIMILI — la fascia c'è sempre (vedi la vista e il
      template); qui sotto solo l'impaginazione dell'invito che compare
      quando in catalogo non c'è nient'altro. */

/* 1. Le tre colonne. Il rapporto della fotografia è dichiarato una volta sola,
   su «.gal-main», nel blocco della galleria più su nel foglio. */
.det-top { grid-template-columns: minmax(0, 1fr) clamp(282px, 23.5vw, 330px); }

/* Il modulo: un modulo di servizio, non la pagina dei contatti. Ogni misura
   qui sotto serve a farlo stare dentro l'altezza della fotografia. */
.det-aside .det-card { padding: clamp(16px, 1.5vw, 22px); }
.det-card .form {
  display: flex;
  flex-direction: column;
  margin-top: 13px;
  gap: 10px;
  flex: 1;
}
.det-card .field input, .det-card .field textarea { padding: 10px 14px; }
.det-card .field textarea { min-height: 68px; }
/* Il pulsante e la nota si appoggiano al fondo: è quello che allinea il
   riquadro alla fotografia anche quando i campi lasciano spazio. */
.det-card .det-send { margin-top: auto; }
.det-card .form-note { margin-top: 7px; }

/* La pillola «vedi tutte le foto» non deve mai eccedere la miniatura. */
.gal-all { max-width: calc(100% - 18px); }

/* 2. Lo spazio del disegno di ogni caratteristica. */
.amen-ic {
  display: inline-flex;
  flex: none;
  width: 18px; height: 18px;
  margin-top: 2px;
  color: var(--alpine);
}

/* 3. e 4. I due riquadri: un pannello solo, e la lista che lo riempie. */
.det-boxes.panels-joined { gap: 0; align-items: stretch; }
.det-boxes.panels-joined > .det-box + .det-box { border-left: 0; }
.det-box { display: flex; flex-direction: column; }
/* Il pulsante della planimetria resta largo quanto il suo testo: in colonna
   flex, senza questa riga, si stirerebbe da un bordo all'altro del riquadro. */
.det-box .det-box-cta { align-self: flex-start; }

/* 6. L'invito che prende il posto delle schede quando non c'è altro. */
.sim-empty {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: clamp(18px, 2vw, 26px);
  max-width: 620px;
}
.sim-empty p { font-size: 0.95rem; line-height: 1.9; color: var(--ink-70); }

/* Sotto i 1120 il modulo non è più una colonna di servizio accanto alla
   fotografia: sta sotto, largo, e il pulsante non ha più motivo di stare
   appoggiato al fondo. */
@media (max-width: 1120px) {
  .det-card .det-send { margin-top: 4px; }
}

/* A 620 i due riquadri si impilano (vedi la media query in fondo al foglio):
   il filetto che li univa passa da verticale a orizzontale, altrimenti il
   pannello di sotto resta senza bordo alto. */
@media (max-width: 620px) {
  .det-boxes.panels-joined > .det-box + .det-box { border-left: 1px solid var(--line); border-top: 0; }
}

/* ---- Round-31 — la scheda immobile, terza passata ------------------------ */

/* La galleria è un contenitore posizionato: qualunque cosa dentro di lei si
   appoggi a un bordo (la fascia «venduto», domani un'altra etichetta) deve
   trovare il riferimento qui e non su per la pagina. */
.gal { position: relative; }

/* Su un immobile concluso il contatore lascia il piede alla fascia e sale in
   alto: erano due etichette bianche sulla stessa riga, una sopra l'altra. */
.gal.is-closed .gal-count { top: 14px; bottom: auto; }

/* La colonna di destra di un immobile venduto: «più ordinati i pulsanti e
   messi più centrali e organizzati».
   Non c'è un modulo da compilare, quindi non c'è motivo di tenere il testo
   appoggiato a sinistra come se ci fossero dei campi sotto: il riquadro
   diventa un annuncio, centrato, con le due strade — la valutazione e il
   catalogo — larghe uguali e appoggiate al fondo, come il pulsante del modulo
   nella scheda di un immobile ancora in vendita. */
.det-aside .det-card-closed { text-align: center; align-items: stretch; }
.det-card .det-closed-actions {
  margin-top: auto;
  align-items: stretch;
  gap: 12px;
}
.det-closed-actions .btn { width: 100%; justify-content: center; }
/* Il secondo modo è un pulsante come il primo, non un collegamento sciolto:
   due azioni allineate si leggono come una scelta, un pulsante e un link
   sciolto si leggono come un ripensamento. */
.det-closed-actions .lnk {
  justify-content: center;
  border: 1px solid var(--ink-14);
  padding: 16px 20px;
  background-image: none;
}
.det-closed-actions .lnk:hover { border-color: var(--ink); background-image: none; }

/* ---- Round-33 — la galleria della scheda immobile -------------------------
   «perché le foto dell'immobile in piazza mazzini non sono impaginate bene
   rispetto a quelle di laives. correggi e falle tutte allo stesso modo».

   IL DIFETTO. Le due colonne della testata sono legate («stretch»), e la
   fotografia grande aveva «height: 100%»: prendeva cioè l'altezza della riga,
   che è quella della colonna più alta delle due. Su un immobile in vendita la
   colonna più alta è il modulo, e la fotografia veniva stirata a 5:4; su un
   immobile venduto al posto del modulo c'è un riquadro corto, la riga la
   decideva la fotografia e restava il suo 3:2. Stessa pagina, stesso
   modello, due impaginazioni diverse — e la seconda, quella di Laives, è
   quella giusta.

   Il difetto è vecchio e si è già presentato due volte al contrario (round-29
   e round-31): ogni giro si è cercato di rimettere in riga il modulo perché
   non sforasse. È il verso sbagliato. Finché è l'altezza del modulo a
   decidere, la fotografia dipende da quanti campi ha il modulo, da quante
   righe prende un testo tradotto in tedesco, dal fatto che l'immobile sia
   venduto o no: cioè da tutto tranne che dalla fotografia.

   LA REGOLA, ADESSO. **Comanda la fotografia.** Il rapporto è 3:2, dichiarato
   una volta sola su «.gal-main», e niente lo stira più: venduto o in vendita,
   in italiano o in tedesco, la fotografia di apertura è sempre lo stesso
   riquadro. Ad adattarsi è il modulo, non l'immagine. */
.det-gallery .gal-main { height: auto; }

/* E la colonna di destra non entra più nel conto dell'altezza: la scheda è
   posizionata in assoluto dentro la sua colonna e riempie esattamente il
   riquadro che la fotografia ha deciso. («.det-aside» è già sticky, cioè un
   contenitore posizionato: è lui il riferimento dell'«inset: 0».)

   Da qui la garanzia che il cliente ha chiesto — «deve esserci uniformità
   totale»: venduto o in vendita, il riquadro della galleria e quello della
   scheda accanto sono gli stessi su ogni immobile, perché nessuno dei due
   dipende più da cosa c'è scritto dentro l'altro. */
.det-aside .det-card {
  position: absolute;
  inset: 0;
  overflow-y: auto;
}
/* Un immobile senza fotografie mette al posto della galleria il suo riquadro
   vuoto: adesso che l'altezza della riga la decide questa colonna, anche quel
   riquadro deve prendersi la larghezza, altrimenti non ha da cosa ricavare la
   propria altezza e la testata si accartoccia. */
.det-gallery > .mosaic-empty { flex: 1; }

/* ---- Round-33c — la planimetria e i punti di forza -------------------------
   «migliora l'impaginazione dei punti di forza, trova una soluzione
   esteticamente gradevole».

   Le due cose sono lo stesso problema, e la seconda è l'effetto della prima.

   LA PLANIMETRIA NON AVEVA UN'ALTEZZA. «width: 100%; height: auto» su un
   disegno quadrato largo mezza pagina fa un riquadro alto più di mille pixel.
   Il pannello dei punti di forza gli sta accanto ed è legato alla sua altezza:
   sei righe di testo distribuite su quell'altezza finivano a 180px l'una
   dall'altra, che non è una lista — è un elenco che si è disfatto.

   Adesso la planimetria ha una proporzione dichiarata, 4:3, e il disegno ci
   sta dentro intero («contain»): un foglio bianco con la pianta al centro, che
   è come si guarda una planimetria. Il pannello smette di essere alto quanto
   il file che l'agente ha caricato.

   I PUNTI DI FORZA DIVENTANO UNA TABELLA. Distribuire le righe sull'altezza
   («space-between») era il rimedio sbagliato al pannello troppo alto: teneva i
   vuoti uguali fra loro ma enormi, e senza niente in mezzo due righe lontane
   non si leggono più come una lista. Ora le righe sono celle alte uguali
   separate da un filetto: riempiono il pannello per costruzione, il vuoto
   diventa aria dentro una griglia invece che spazio fra frasi sospese, e la
   lista si legge come la scheda dei dati che è. */
.plan-frame { aspect-ratio: 4 / 3; }
.plan-frame img { height: 100%; object-fit: contain; }

.det-box .strengths {
  flex: 1;
  margin-top: 6px;
  gap: 0;                      /* a separare le righe è il filetto, non il vuoto */
  align-content: stretch;
  grid-auto-rows: minmax(52px, 1fr);
  border-top: 1px solid var(--line);
}
.det-box .strengths li {
  align-items: center;         /* la riga è alta: il segno sta a mezza altezza */
  padding: 12px 2px;
  border-bottom: 1px solid var(--line);
}
/* L'ultimo filetto cadrebbe a un'imbottitura dal bordo del pannello, cioè
   quasi sopra al bordo del pannello: due righe parallele a 28px di distanza. */
.det-box .strengths li:last-child { border-bottom: 0; }
.det-box .strengths li svg { margin-top: 0; }

/* A stare dentro è il modulo. L'area di testo è il pezzo elastico: tutto il
   resto ha un'altezza fissa e il messaggio prende quello che avanza — grande
   su uno schermo largo, ridotto al minimo su uno stretto. Prima era il
   contrario: l'area di testo aveva la misura fissa (84px) e la fotografia
   doveva stare dietro al totale. */
.det-card .form { min-height: 0; }
.det-card .field-grow { flex: 1; min-height: 0; }
.det-card .field-grow textarea { flex: 1; height: auto; min-height: 44px; }

/* E ogni altra misura del modulo è stretta di quel poco che serve perché il
   totale ci stia. Sono ~55px recuperati su una scheda che alla larghezza di
   una finestra da 1300px ne sforava una cinquantina: nessuno dei singoli tagli
   si nota, la somma sì. Il modulo qui è una colonna di servizio accanto a una
   fotografia — le pagine dei contatti e della valutazione, dove il modulo è la
   cosa principale, non sono toccate. */
.det-aside .det-card { padding: clamp(14px, 1.3vw, 18px); }
/* Un solo passo fra un campo e l'altro, dichiarato una volta sola.
   Round-33b — «rendi equidistanti i campi in maniera ordinata». Non lo erano:
   nome ed email sono una coppia affiancata («.form-row»), e nella colonna
   stretta la coppia si incolonna tenendosi però il suo interspazio da 28px,
   quello delle pagine larghe. Fra i primi due campi c'era il triplo dello
   spazio che c'era fra tutti gli altri. Ora la riga accoppiata usa lo stesso
   passo del modulo, e nessun elemento ne aggiunge di suo. */
.det-card .form { margin-top: 10px; gap: var(--det-form-gap); }
.det-card { --det-form-gap: 8px; }
.det-card .form-row { gap: var(--det-form-gap); }
.det-card .consent { margin-top: 0; }
.det-aside .det-aside-sub { margin-top: 5px; font-size: 0.76rem; line-height: 1.5; }
.det-card .field input, .det-card .field textarea { padding: 9px 13px; }
.det-card .consent span { font-size: 0.7rem; line-height: 1.45; }
.det-card .det-send { padding: 13px 24px; }
.det-card .form-note { margin-top: 0; font-size: 0.64rem; line-height: 1.45; }

/* Sotto i 1240 la testata non è più a due colonne. Il numero non è scelto a
   occhio: è la larghezza sotto la quale la fotografia, al suo 3:2, diventa più
   bassa del modulo anche col modulo compresso al minimo — e da lì in giù
   l'unico modo di tenerli affiancati sarebbe far scorrere il modulo dentro sé
   stesso. Prima di arrivarci, la scheda va sotto la fotografia, che intanto si
   prende tutta la riga e diventa più grande. Il conto è in
   tests_domain/test_listing_top.py, che lo rifà a 1360 e a 1170.

   Sotto, la scheda torna un elemento normale del flusso: non ha più
   un'altezza da riempire, quindi né compressione né campo elastico. */
@media (max-width: 1240px) {
  .det-top { grid-template-columns: 1fr; }
  .det-aside { position: static; max-width: 540px; }
  .det-aside .det-card { position: static; overflow: visible; padding: clamp(16px, 1.5vw, 22px); }
  .det-card { --det-form-gap: 11px; }
  .det-card .field-grow { flex: none; }
  .det-card .field-grow textarea { flex: none; min-height: 84px; }
  .det-card .field input, .det-card .field textarea { padding: 11px 14px; }
  .det-card .det-send { padding: 17px 30px; }
}

/* ---- Chi siamo: le schede del team -------------------------------------- */
.tm { align-items: stretch; }
.tm-role { margin-top: 4px; }
.tm-bio { margin-top: 12px; font-size: 0.84rem; line-height: 1.7; color: var(--ink-70); }
.tm-links { margin-top: 14px; display: flex; flex-direction: column; gap: 4px; }
.tm-links a { font-size: 0.8rem; color: var(--ink-46); transition: color 0.3s ease; }
.tm-links a:hover { color: var(--ink); }

/* ---- Valutazione: i tre passi con icona e filetti ----------------------- */
.how-i { position: relative; grid-template-columns: auto auto 1fr; align-items: start; }
.how-ic { display: inline-flex; color: var(--alpine); margin-top: 3px; }
.how > .how-i + .how-i { border-left: 1px solid var(--line); padding-left: clamp(20px, 2.6vw, 38px); }

/* Le domande frequenti: righe riquadrate, come nella referenza.

   Round-26, due correzioni.

   **Il difetto.** In due colonne, aprendo una domanda si "apriva" anche quella
   accanto. Non si apriva: le celle di una stessa riga di griglia hanno per
   difetto la stessa altezza, quindi quando il <details> aperto cresceva, il
   vicino cresceva con lui e mostrava un riquadro alto e vuoto. Sembrava un
   difetto del comportamento a fisarmonica ed era la griglia. ``align-items:
   start`` toglie lo stiramento e ogni riquadro torna alto quanto il suo
   contenuto.

   **L'ingombro.** Le righe erano alte una volta e mezzo quelle della
   referenza: 20 px di respiro sopra e sotto la domanda dentro un riquadro che
   ne aggiungeva altri 4, più 10 di distanza fra una riga e l'altra. Sei
   domande così diventano un muro, che è quello che il cliente ha visto. */
/* Round-27 — «le linee rettangolari intorno alla domanda devono combaciare con
   quella sotto, ossia non deve esserci spazio tra un rettangolo e l'altro, ma
   il bordo inferiore di una diventa il bordo superiore dell'altra».
   Gli 8 px di respiro facevano di sei domande sei scatole in fila; senza,
   diventano una tabella sola. Il bordo alto va tolto a tutte tranne la prima,
   o dove due riquadri si toccano la linea è doppia e pesa il doppio delle
   altre — che è lo stesso difetto del filetto fra i due riquadri grandi. */
.faq2 { align-items: start; row-gap: 0; }
.faq2 .faq-i { border: 1px solid var(--line); padding: 0 18px; background: var(--white); }
.faq2 .faq-i + .faq-i { margin-top: 0; border-top: 0; }
.faq2 .faq-i summary { padding: 14px 0; font-size: 0.84rem; }
.faq2 .faq-i p { padding-bottom: 16px; font-size: 0.82rem; line-height: 1.75; }

/* ---- Contatti ----------------------------------------------------------- */
/* Lo stacco dal sottotitolo è un riempimento e non un margine: dal round-27 il
   blocco si centra con i margini automatici, e un margine dichiarato qui li
   spegnerebbe da un lato solo — il disegno tornerebbe più in alto del centro. */
.where-wrap { display: grid; grid-template-columns: 1.15fr 1fr; gap: clamp(22px, 3vw, 44px); align-items: center; padding-top: 22px; }
.where-map svg { width: 100%; height: auto; color: var(--ink); }
/* Round-29 — qui c'era una seconda dichiarazione delle etichette della mappa
   (corpo 8, tracciatura 0,16). Era morta: più in basso, nella sezione della
   mappa, la stessa regola con lo stesso peso ridichiara tutte e quattro le
   proprietà, e a parità vince l'ultima. Toglierla non cambia un pixel — ma
   chi cercava «font-size» delle etichette trovava prima questa e la
   modificava senza che succedesse niente. È il tipo di trappola che ha reso
   difficile trovare il difetto dei nomi sul confine. Le etichette si
   dimensionano in un posto solo: cerca «.where-lbl text» nella sezione della
   mappa dell'Alto Adige. */
.where-copy p { font-size: 0.86rem; line-height: 1.7; color: var(--ink-70); }

/* Consenso e pulsante sulla stessa riga, pulsante a destra. */
.form-foot { display: flex; align-items: center; justify-content: space-between; gap: 22px; flex-wrap: wrap; }
.form-foot .form-send { justify-self: auto; }
.form-foot-note, .form-note { font-size: 0.72rem; line-height: 1.6; color: var(--ink-46); max-width: 34ch; }
.form-note { margin-top: 12px; max-width: none; }
.form-foot-note a, .form-note a { color: var(--ink-70); border-bottom: 1px solid var(--ink-14); }
.form-foot-note a:hover, .form-note a:hover { color: var(--ink); border-color: var(--ink); }

/* ---- Piede: le icone non collegate ------------------------------------- */
.ft-social-off { display: inline-flex; color: var(--ink-14); cursor: default; }
.ft-peaks { color: var(--ink-46); }

/* ---- Privacy e cookie --------------------------------------------------- */
.legal { padding: clamp(96px, 9vw, 150px) 0 clamp(56px, 6.4vw, 92px); }
.legal-t { margin-top: 14px; }
.legal .lede { margin-top: 16px; }
.legal-date { margin-top: 10px; font-family: var(--sans); font-size: 0.62rem; letter-spacing: var(--track-label); text-transform: uppercase; color: var(--ink-46); }
.legal-s { margin-top: clamp(30px, 3.4vw, 46px); }
.legal-s h2 { font-family: var(--serif); font-weight: 400; font-size: clamp(1.2rem, 1.7vw, 1.55rem); color: var(--ink); }
.legal-s p { margin-top: 12px; font-size: 0.9rem; line-height: 1.85; color: var(--ink-70); }
.legal-note { margin-top: clamp(34px, 4vw, 54px); padding-top: 22px; border-top: 1px solid var(--line); font-size: 0.86rem; color: var(--ink-70); }
.legal-note a { color: var(--ink); border-bottom: 1px solid var(--ink-14); }

/* ---- Proporzioni delle aperture ---------------------------------------- */
/* I banner delle pagine interne erano più bassi della referenza. */
.phero { min-height: clamp(300px, 30vw, 430px); }
.vhero { min-height: clamp(420px, 42vw, 620px); }
/* Nella referenza il titolo della fascia territorio sta su una riga sola:
   la colonna di testo va allargata, non il carattere rimpicciolito. */
.split-in { max-width: 600px; padding-right: clamp(28px, 3vw, 52px); }
.split-in .ttl { font-size: clamp(1.5rem, 2.2vw, 2.05rem); }

@media (max-width: 980px) {
  .amen-row { grid-template-columns: repeat(3, 1fr); }
  /* «.where-wrap» a colonna sola non sta più qui ma nella media query gemella
     in fondo al foglio. Le passate successive hanno riscritto la regola normale
     più in basso di questa, e a parità di peso vince chi è scritta dopo: da
     qui la mappa non andava più a capo su nessuno schermo stretto. */
  .how > .how-i + .how-i { border-left: 0; padding-left: 0; }
  .keyrow > .key + .key { border-left: 0; padding-left: 0; }
}
@media (max-width: 620px) {
  .amen-row { grid-template-columns: repeat(2, 1fr); }
  .marks-c .mk { flex-direction: row; text-align: left; }
  .form-foot { flex-direction: column; align-items: flex-start; }
}


/* Nella referenza ogni titolo di scheda servizio sta su una riga sola: a
   cinque colonne su 1440 sono circa 238px, e il titolo più lungo
   ("Consulenza investimenti") ci entra solo un filo più piccolo. */
.svc-t { font-size: clamp(0.92rem, 1.12vw, 1.02rem); letter-spacing: -0.005em; }
.svc { padding-inline: clamp(16px, 1.5vw, 22px); }


/* ---- Round 25, terza parte: le correzioni chieste dal cliente ------------ */

/* Il prezzo è un campo libero, non una tendina: chi cerca fino a 435.000 lo
   scrive. Ha lo stesso aspetto degli altri campi della barra. */
.fbar-num {
  width: 100%;
  border: 0;
  background: transparent;
  font-family: var(--sans);
  font-size: 0.9rem;
  letter-spacing: 0.04em;
  color: var(--ink);
  padding: 0;
}
.fbar-num::placeholder { color: var(--ink); opacity: 1; }
.fbar-num:focus { outline: none; }
.fbar-field:focus-within label { color: var(--ink); }

/* Nessuna freccetta nei campi numerici: sono decorazione del browser e
   spezzano l'allineamento della griglia. */
input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* ---- La mappa dell'Alto Adige ------------------------------------------- */
.where-map { padding-right: 8px; }
.where-map svg { width: 100%; height: auto; overflow: visible; }
/* Round-27 — il contorno è ricalcato dalla referenza e il suo sistema di
   coordinate è più fitto del vecchio: 380 unità dove prima ce n'erano 392 per
   una sagoma più bassa. Il tratto scende da 1,2 a 0,9 perché a 1,2 le anse
   strette del confine (la Val Venosta, la punta di Salorno) si chiudevano
   sotto la propria linea. «miter» invece di «round»: gli spigoli del confine
   sono spigoli, e arrotondarli è la stessa ammorbidita che il cliente aveva
   bocciato nel disegno. */
.where-shape { stroke: var(--ink); stroke-width: 0.9; stroke-linejoin: miter; stroke-miterlimit: 2; opacity: 0.42; }
/* Round-26 — gli spilli a goccia della referenza, non più pallini. */
.where-pins use { fill: var(--alpine); }
.where-pins .where-pin-hq { fill: var(--ink); }
.where-lbl text {
  font-family: var(--sans);
  /* Le etichette si dimensionano nel sistema del disegno, non in pixel di
     pagina. Il corpo è misurato sulla referenza invece che stimato: là
     "BRESSANONE" è largo 53 pixel su una sagoma larga 381, cioè il 14%. A 13
     unità da noi ne occupava il 31% e i nomi pesavano più del confine.

     Round-29 — da 8,4 a 7,0, ed è una correzione di aritmetica, non un
     ripensamento. L'8,4 veniva da un conto che dava "BRESSANONE" al 15%, ma
     quel conto moltiplicava il numero di lettere per la larghezza media del
     **minuscolo** di Montserrat (0,62 em) su un testo che ha
     ``text-transform: uppercase``. Le maiuscole sono più larghe — stanno fra
     0,30 (I) e 1,06 (W), e in "BRESSANONE" fanno media 0,70 — quindi la
     parola stava in realtà al 16,7%: un quinto più grande del bersaglio.
     Sommata alla tracciatura, quella differenza è ciò che portava BRUNICO
     fuori dalla sagoma e BRESSANONE a ridosso della linea, ed è il difetto
     che il cliente ha segnalato («non mi piace che alcune scritte sfiorano
     il confine»).

     Rifatto il conto lettera per lettera, il corpo che dà davvero il 14%
     della referenza è 7,0. A quel corpo nessuna etichetta si sposta di
     un'unità e tutte e cinque, in tutte e tre le lingue, hanno almeno 5
     unità di bianco fra sé e il confine. La mappa è la stessa: i nomi sono
     alla misura che avrebbero dovuto avere fin da subito. */
  font-size: 7px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  fill: var(--ink-70);
}
.where-lbl .hq { fill: var(--ink); font-weight: 400; }
/* L'alone che stacca il nome dal confine quando ci passa sopra. Scende con il
   corpo: a 3 unità su un testo da 8,4 mangiava le aste sottili, e a 2 su un
   testo da 7,0 le mangerebbe di nuovo — è sempre lo stesso rapporto. */
.where-lbl text { paint-order: stroke; stroke: var(--white); stroke-width: 1.7px; stroke-linejoin: round; }

.where-cta { margin-top: clamp(22px, 2.6vw, 34px); }

/* ---- Il modulo della valutazione ---------------------------------------- */
/* Tre colonne uguali, campi della stessa altezza, etichette su una riga.
   Prima l'etichetta della tipologia occupava tre righe e spingeva giù solo la
   sua colonna: le sei caselle non erano più allineate fra loro. */
.vform-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(14px, 1.6vw, 22px);
  align-items: end;
}
.vform-row + .vform-row { margin-top: clamp(14px, 1.6vw, 20px); }
.vform .field-dark { gap: 8px; }
.vform .field-dark label {
  font-size: 0.56rem;
  letter-spacing: 0.22em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.vform .field-dark input,
.vform .field-dark .sel-btn {
  height: 46px;
  padding: 0 15px;
  font-size: 0.9rem;
  line-height: 46px;
}
.vform .field-dark input { padding-block: 0; }
.vform .consent-dark { margin-top: clamp(18px, 2vw, 26px); }
.vform-foot { margin-top: clamp(18px, 2vw, 26px); }

/* ---- Le schede del team ------------------------------------------------- */
/* Nella referenza il ritratto riempie il lato sinistro della scheda: il
   monogramma tiene esattamente quella forma, così quando arriveranno le
   fotografie non si muoverà niente. */
.tm-ph { width: 132px; height: 100%; min-height: 190px; object-fit: cover; }
.tm-mono { display: grid; place-items: center; background: var(--ivory); font-family: var(--serif); font-size: 1.4rem; color: var(--ink-46); letter-spacing: 0.08em; }
/* La griglia della scheda, i recapiti e l'icona LinkedIn stanno nel blocco
   "Le schede del team" del round 26, più in basso. La riga che stava qui e
   spezzava l'indirizzo (word-break: break-word) è stata tolta: era la causa
   delle mail mandate a capo in mezzo al dominio. */

/* ---- La riga legale del piede ------------------------------------------- */
/* Solo le cifre portano lo stile tabellare: l'etichetta resta testo normale,
   così le due partite IVA e il © sembrano finalmente lo stesso carattere. */
.ft-legal > span { font-size: inherit; letter-spacing: inherit; }
.ft-vat { font-variant-numeric: tabular-nums; letter-spacing: 0.02em; }
/* Round-26 — l'indirizzo del piede non è più sottolineato in permanenza: la
   riga fissa sotto un indirizzo che occupa due righe faceva sembrare la voce
   un link rotto. Si comporta come le altre voci del piede, che si sottolineano
   al passaggio del mouse. */
.ft-addr { line-height: 1.55; }

@media (max-width: 780px) {
  .vform-row { grid-template-columns: 1fr; }
  .tm { grid-template-columns: 96px 1fr; }
  .tm-ph { width: 96px; min-height: 150px; }
}

/* ================================================================================
   ROUND 26 — le correzioni chieste dal cliente il 14 agosto 2026
   ================================================================================ */

/* ---- La testata non è mai una barra ------------------------------------------
   Indicazione del cliente, testuale: «non deve mai vedersi una barra in alto,
   ma le scritte e il logo devono essere in sovraimpressione sull'immagine di
   sfondo che copre la pagina». Fino al round 25 valeva solo per la home, perché
   le sei referenze impaginate mostrano la barra avorio con la foto sotto: la
   decisione del cliente prevale sulla referenza, ed è la stessa su tutte le
   pagine.

   Il meccanismo: la testata esce dal flusso (fixed), <main> si riprende la sua
   altezza con un padding, e le tre aperture fotografiche la riannullano con un
   margine negativo — così la fotografia parte dal bordo superiore della
   finestra e passa sotto al logo. .hero, .phero e .vhero compaiono una volta
   sola ciascuna, sempre come primo elemento della pagina: la regola non può
   raggiungere niente altro. */
.hd {
  position: fixed;
  top: 0; left: 0; right: 0;
  background: transparent;
}
main { padding-top: var(--hdh); }
.hero, .phero, .vhero {
  margin-top: calc(var(--hdh) * -1);
  padding-top: var(--hdh);
}
/* Sopra una fotografia la navigazione va scritta a piena forza: il grigio di
   lettura serve sulla carta, non sull'immagine. */
.hd-nav a { color: var(--ink); }
.hd.is-scrolled { background: rgba(245, 243, 240, 0.92); }
.hd.is-scrolled .hd-nav a { color: var(--ink-70); }
.hd.is-scrolled .hd-nav a.on,
.hd.is-scrolled .hd-nav a:hover { color: var(--ink); }

/* I banner interni erano alti quanto la referenza; ora devono contenere anche
   la testata che ci passa sopra, o il titolo finisce sotto alla navigazione. */
.phero { min-height: calc(var(--hdh) + clamp(300px, 30vw, 430px)); }
.vhero { min-height: calc(var(--hdh) + clamp(420px, 42vw, 620px)); }

/* ---- Il velo, e perché è chiaro ----------------------------------------------
   Il cliente segnala che «a volte non si riesce a leggere bene la scritta per
   via dei colori scuri delle immagini di sfondo». Ho misurato il contrasto
   reale del titolo navy sul riquadro che occupa, su tutte e sei le fotografie:

     home         15,6:1  (nel punto peggiore 1,0:1)
     immobili      9,8:1  (4,2:1)
     chi siamo     5,9:1  (1,1:1)   <- le due segnalate
     servizi       5,6:1  (1,3:1)   <-
     valutazione  13,4:1  (1,7:1)
     contatti      7,4:1  (3,5:1)

   La media è buona ovunque: a mancare è il punto peggiore, cioè le zone scure
   locali — il montante di legno che attraversa il titolo di Chi siamo, l'ombra
   della valle sotto la lede di Servizi. Sono zone SCURE sotto testo SCURO.

   Un velo navy con il testo avorio (la prima ipotesi) risolverebbe, ma la
   misura dice che servirebbe un'opacità fra il 73% e l'84% per reggere il
   testo chiaro sui cieli luminosi delle stesse foto: le sei fotografie
   diventerebbero quasi nere. Un velo avorio al 15% porta invece ogni pagina
   sopra 3:1 nel punto peggiore lasciando la fotografia riconoscibile. È la
   scelta confermata dal cliente.

   Due sfumature, non un pannello:
     * dall'alto, per la testata in sovraimpressione: logo e navigazione sono
       navy e passano sopra qualunque cosa ci sia lì;
     * dal lato delle parole, larga e in dissolvenza — a 88% della larghezza
       non c'è più niente, e la parte destra della fotografia è intatta.
   Sono le stesse due misure che il test tests_domain/test_hero_contrast.py
   ricontrolla a ogni giro sui file veri. */
/* ---- Round-45 — la sfumatura dall'alto non fa più una barra -------------------
   Segnalazione del cliente: «c'è una barra bianca sopra che non deve esserci,
   l'immagine deve essere da sfondo intero». Non c'era nessuna barra — la
   testata è trasparente e la fotografia parte davvero dal bordo dello schermo
   (il test qui sotto lo verifica). Quello che si vedeva era **una piega nella
   sfumatura**: scendeva 0,50 → 0,18 in 92 px e da lì proseguiva con un'altra
   pendenza verso lo zero. Due rette con pendenze diverse che si incontrano
   fanno uno spigolo visibile, e lo spigolo cadeva esattamente all'altezza
   della testata. L'occhio lo legge come il bordo inferiore di una barra.

   Adesso è una curva sola, senza spigoli, che parte più in basso: cinque
   fermate su una discesa liscia (i valori vengono da tools/veil_search.py, che
   li ha cercati misurando il contrasto sui file veri, non a occhio).

   Che cosa cambia, misurato:
     contrasto mediano del testo   8,8:1 → 8,8:1   (invariato)
     peggior 2% del testo          3,6:1 → 3,6:1   (invariato)
     sotto la testata              5,7:1 → 4,2:1   (soglia 3,0)
     opacità in cima               0,50  → 0,36
     velo medio sulla fotografia   0,043 → 0,033   (un quarto in meno)

   Cioè: la fotografia si vede di più e il testo si legge esattamente come
   prima. La leggibilità non è stata barattata con l'estetica — è la piega ad
   essere stata tolta, non il velo.                                            */
.hero-ph::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(180deg,
      rgba(245, 243, 240, 0.36) 0,
      rgba(245, 243, 240, 0.25) 30px,
      rgba(245, 243, 240, 0.16) 75px,
      rgba(245, 243, 240, 0.08) 130px,
      rgba(245, 243, 240, 0.03) 192px,
      rgba(245, 243, 240, 0) 260px),
    linear-gradient(96deg,
      rgba(245, 243, 240, 0.36) 0%,
      rgba(245, 243, 240, 0.29) 30%,
      rgba(245, 243, 240, 0.17) 55%,
      rgba(245, 243, 240, 0.05) 74%,
      rgba(245, 243, 240, 0) 88%);
}
/* ---- Il velo su uno schermo stretto (round-34) --------------------------------
   La sfumatura laterale qui sopra è tarata su una finestra larga: le parole
   stanno nella metà sinistra e a 88% della larghezza il velo è già finito,
   così la parte destra della fotografia resta intatta. Su un telefono le
   parole occupano **tutta** la larghezza, quindi metà del titolo cadeva fuori
   dal velo — e fino al round 33 sull'apertura della home il velo era tolto
   del tutto.

   Misurato con la stessa macchina di tests_domain/test_hero_contrast.py sui
   file veri, riquadro 390 px, il peggior 2% del testo valeva:

     home           2,0:1      immobili       1,4:1
     chi siamo      1,5:1      servizi        2,6:1
     contatti       2,1:1      valutazione    1,9:1

   Tutte e sei sotto la soglia di 3:1 — cioè la segnalazione del cliente
   («a volte non si riesce a leggere la scritta») era ancora vera sul telefono
   mentre sul desktop era risolta.

   La correzione tiene le due idee del round 26 — due sfumature, non un
   pannello; velo chiaro, testo navy — e gira quella laterale di 90°: dove non
   c'è un lato libero c'è un fondo libero. Il velo tiene 0,24 per tutta la
   banda delle parole e si spegne all'88% dell'altezza, così il piede della
   fotografia resta a piena forza. Gli stessi sei numeri diventano

     home           4,4:1      immobili       4,3:1
     chi siamo      4,5:1      servizi        5,2:1
     contatti       4,7:1      valutazione    4,3:1

   e sotto la testata non si scende mai sotto 7,5:1. Lo 0,24 non è scelto a
   occhio: è il valore più leggero che tiene tutte e sei sopra 4:1 anche
   sull'apertura alta uno schermo intero, ed è la stessa forza media che il
   velo laterale ha sul desktop dove stanno le parole. Il test lo rimisura. */
@media (max-width: 980px) {
  /* Round-45 — stessa correzione, stessa ragione: la discesa arriva al pianoro
     senza spigoli e parte da 0,32 invece che da 0,50. Il pianoro resta 0,24,
     che è il valore che tiene il testo: mediana 5,8:1 e peggior 2% 4,3:1,
     identici a prima. Sotto la testata si passa da 7,3:1 a 5,6:1, sempre ben
     sopra la soglia di 3,0. Valori cercati da tools/veil_phone_search.py. */
  .hero-ph::after {
    background: linear-gradient(180deg,
      rgba(245, 243, 240, 0.32) 0,
      rgba(245, 243, 240, 0.29) 40px,
      rgba(245, 243, 240, 0.26) 97px,
      rgba(245, 243, 240, 0.25) 165px,
      rgba(245, 243, 240, 0.24) 240px,
      rgba(245, 243, 240, 0.24) 88%,
      rgba(245, 243, 240, 0.05) 95%,
      rgba(245, 243, 240, 0) 100%);
  }
}

/* ---- Round-46 — la «barra bianca» sul telefono era cielo ---------------------
   Il cliente la vede ancora dopo il round 45, e aveva ragione a insistere:
   quella non era la piega del velo, era la **fotografia**.

   La fotografia della home è orizzontale, 3000×1800. Su uno schermo verticale
   `object-fit: cover` la scala fino a coprire l'altezza — e siccome il riquadro
   è molto più alto che largo, a essere ritagliati sono soltanto i **lati**: la
   fotografia si vede tutta, dall'alto in basso. Il quinto superiore di quella
   fotografia è cielo di controluce. Misurato sul file vero, in quella fascia
   la differenza di luminanza fra un pixel e l'altro è di **9 livelli su 255**:
   una superficie uniforme e chiarissima, che sotto un logo l'occhio legge come
   un pannello.

   Nessuna taratura del velo poteva risolverlo — lì il velo vale 0,32 e anche
   togliendolo del tutto il cielo resta — e nemmeno `object-position` verticale:
   senza avanzo in altezza non ha niente da spostare.

   Quindi si cambia che cosa il telefono inquadra. L'immagine si alza al 133%
   dell'apertura e si appoggia in basso: il cielo esce dal riquadro dall'alto e
   `overflow: hidden` lo taglia. Insieme si sposta l'inquadratura al 62% verso
   destra, dove ci sono la montagna e la casa. Sotto la testata arriva il
   profilo della montagna al posto del vuoto.

   I numeri, calcolati da tools/hero_mobile_crop.py:
     prima   si vedeva la sorgente x 1143-1857, y 193-1800   (cielo in cima)
     dopo    si vede           x 1487-2089, y  447-1800
     larghezza di sorgente campionata  714 px → 601 px
     ingrandimento su uno schermo 3x  1,58× → 1,87×  (nitidezza quasi uguale)

   E il testo continua a leggersi, misurato con la macchina del round 34 sul
   ritaglio nuovo: mediana 6,8:1 (soglia 4,5) e peggior 2% **4,3:1** contro i
   4,5:1 di prima, con la soglia a 3,0. Il caso peggiore — l'unico che conti —
   non si muove.

   Vale solo per l'apertura della home: `.phero` e `.vhero` hanno un `.hero-ph`
   loro ma non stanno dentro un `.hero`, e sono alte 380-500 px, dove la fascia
   di cielo è una striscia sottile e non un pannello. */
@media (max-width: 980px) {
  .hero .hero-ph img {
    position: absolute;
    left: 0;
    bottom: 0;
    height: 133%;
    object-position: 62% 50%;
  }
}

/* ---- Le schede del team -------------------------------------------------------
   Tre correzioni chieste dal cliente, e sono legate fra loro.

   1. «il team è impaginato male, forse ci sono troppe scritte che fanno
      diventare lungo il cubo». Le biografie sono state accorciate in
      translations.py; qui la scheda smette di essere un blocco unico e diventa
      due righe: in alto il ritratto accanto a nome, ruolo e biografia, in
      basso una fascia con i recapiti. Le tre schede finiscono alla stessa
      altezza perché la fascia è ancorata in fondo (grid-template-rows 1fr auto).

   2. «le mail degli agenti non possono assolutamente andare a capo». La causa
      era word-break: break-word dentro una colonna larga ~200 px: l'indirizzo,
      36 caratteri, si spezzava in mezzo al dominio. La fascia dei recapiti è
      larga quanto la scheda intera — a 1440 px sono 387 px meno 44 di respiro,
      cioè 343, contro i ~255 dell'indirizzo — e in più la riga è dichiarata
      nowrap: se un giorno un indirizzo più lungo non ci stesse, uscirebbe di
      un pelo invece di spezzarsi, che è il male minore.

   3. «deve esserci il rimando a linkedin dell'agente con il logo linkedin».
      L'icona sta a destra della fascia, come in fondo alle schede della
      referenza. */
/* Round-26, terza passata — la scheda rifatta intorno al ritratto.

   Il cliente ha segnalato due cose: «si vede che david tocca il bordo e
   stefano invece no» e «lo spazio per le foto è troppo allungato, deve essere
   più un quadrato per permettere di mettere la foto di ognuno».

   Erano lo stesso problema visto da due lati. Il ritratto era 112 px di
   larghezza per tutta l'altezza della scheda — un rettangolo 1:2, che nessuna
   fotografia di persona riempie — ed era stretto così per lasciare alla
   colonna del testo i 235 px che servivano all'indirizzo per esteso. Ma
   l'indirizzo più lungo (David, 38 caratteri) quei 235 px li superava lo
   stesso: da lì il bordo toccato, che non era un difetto di allineamento.

   Adesso il ritratto è 130 px in formato 3:4, cioè la proporzione di una
   fotografia di persona, e il testo si prende i 163 px che restano alla
   larghezza più stretta a cui le schede stanno ancora tre per riga (1240 px di
   finestra). Ci sta tutto quello che deve starci: il nome su una riga, il
   ruolo su una riga, la biografia — una frase — e il numero di telefono.
   L'indirizzo per esteso no, e per questo è passato dietro l'icona della
   busta: vedi about.html. */
.tm {
  display: grid;
  grid-template-columns: 130px 1fr;
  gap: clamp(16px, 1.8vw, 20px);
  padding: clamp(16px, 1.8vw, 20px);
  align-items: start;
}
.tm-ph {
  width: 130px;
  aspect-ratio: 3 / 4;
  height: auto;
  min-height: 0;
  object-fit: cover;
  /* La scheda si allunga per allineare i recapiti, il ritratto no: senza
     questo lo stiramento della griglia gli mangia la proporzione 3:4. */
  align-self: start;
}
.tm-mono { font-size: 1.6rem; }
.tm-bio { margin-top: 10px; }

/* Round-26, quarta passata — i recapiti delle tre persone sulla stessa riga.
   Le biografie non sono lunghe uguali e non lo saranno mai: se il blocco dei
   contatti segue il testo, sta a tre altezze diverse e le tre schede sembrano
   disallineate. Qui la colonna del testo è una colonna flessibile alta quanto
   la scheda e il blocco dei contatti è spinto in fondo, quindi numero, busta e
   LinkedIn cadono sulla stessa riga in tutte e tre. */
.tm { align-items: stretch; }
.tm-txt { padding: 0; display: flex; flex-direction: column; }
.tm-links { margin-top: auto; padding-top: 14px; }
.tm-links a {
  font-size: 0.78rem;
  white-space: nowrap;
  word-break: normal;
  overflow-wrap: normal;
  hyphens: none;
}

/* Busta e LinkedIn chiudono la colonna, in basso a sinistra come nella
   referenza. Sono collegamenti, non decorazione: la busta apre il programma di
   posta con l'indirizzo dell'agente, che resta anche nel title. */
.tm-icons { display: flex; align-items: center; gap: 14px; margin-top: 16px; }
/* Se una persona non avesse il numero, tocca alle icone scendere in fondo. */
.tm-bio + .tm-icons { margin-top: auto; padding-top: 14px; }
.tm-ic { display: inline-flex; color: var(--ink-46); transition: color 0.35s ease; }
.tm-ic:hover { color: var(--ink); }
.tm-ic-off { color: var(--ink-14); cursor: default; }

/* Con tre persone la riga è di tre schede piene: auto-fit lasciava che a
   larghezze intermedie diventassero due sopra e una spaiata sotto. */
/* Tre schede per riga fino a 1240 px, che è dove la colonna del testo scende a
   163 px — quanto basta al ruolo, che è la riga più lunga. Sotto, due schede
   larghe si leggono meglio di tre strette; sotto i 720 px diventa una colonna
   sola. */
@media (min-width: 1240px) {
  .team { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 1239px) {
  .team { grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); }
}
@media (max-width: 780px) {
  /* Il ritratto si stringe con la scheda: la regola del round 25 sta più in
     alto nel foglio e da sola non basterebbe più a scavalcare quella qui
     sopra, che non è dentro nessuna media query. */
  .tm { grid-template-columns: 116px 1fr; }
  .tm-ph { width: 116px; }
}

/* ---- Il primo blocco dopo un'apertura fotografica ----------------------------
   Fra la fine della fotografia e l'occhiello che segue restavano 92 px di
   respiro più i 46 dell'occhiello: 138 px di niente, e sulla pagina Servizi si
   vedeva come un buco. Un blocco che comincia subito sotto un'immagine non ha
   bisogno di prendere le distanze da sé stesso — l'immagine è già lo stacco. */
.phero + .blk,
.phero + .blk-tight,
.vhero + .blk,
.vhero + .blk-tight { padding-top: clamp(38px, 4.2vw, 60px); }

/* ---- La scala della tipografia sulle pagine di territorio --------------------
   Segnalazione del cliente: «nella scheda relativa al territorio molto spesso
   c'è incoerenza nella grandezza e scelta del font […] non può esserci testo
   più grande poi più piccolo».

   Aveva ragione, e la causa era una sola: il paragrafo d'apertura era
   Montserrat Light a 23 px, cioè **più grande del titolo che lo introduce** —
   il Cormorant di .ttl-2 leggeva 25 px ma con un'altezza delle minuscole
   molto minore, quindi otticamente il corpo vinceva sul titolo. Sotto, il
   paragrafo normale tornava a 15 px: grande, più grande, piccolo.

   La scheda di brand dà tre gradini e basta: titolo in Cormorant, corpo in
   Montserrat Regular, etichetta in Montserrat maiuscolo tracciato. Qui sotto
   ci sono quei tre, in ordine di grandezza e senza sorprese in mezzo: il
   titolo di sezione sale, il paragrafo d'apertura scende a poco più del corpo
   e prende lo stesso peso del corpo — resta l'attacco, smette di essere un
   secondo titolo. */
.ttl-2 { font-size: clamp(1.35rem, 2.1vw, 1.85rem); }
/* Round-31 — «nella scheda territorio devi correggere tutta la spaziatura dei
   testi rispettando le linee guida», e vale per tutti i comuni.

   La scala del marchio è di 8px: 8 · 16 · 24 · 32 · 48 · 64 · 96 · 128. La
   spaziatura di queste pagine non ci stava dentro da nessuna parte —
   interlinea 1,85 su un corpo di 15,2px fa 28,1px, e lo stacco fra due
   paragrafi era 20. Due misure che non sono passi della scala e che non sono
   nemmeno multiple l'una dell'altra: il testo respirava troppo dentro il
   paragrafo e troppo poco fra un paragrafo e l'altro, e l'occhio non trovava
   il ritmo.

   Ora l'interlinea è 1,6 — 24,3px, cioè il passo da 24 — e fra due paragrafi
   c'è un passo intero in più (24). Il paragrafo diventa un blocco compatto e
   lo stacco si vede: è la stessa regola con cui sono impaginate le tavole. */
.prose-lead {
  font-family: var(--sans);
  font-weight: 400;
  font-size: 1.02rem;
  line-height: 1.6;
  color: var(--ink);
}
.prose p { font-size: 0.95rem; line-height: 1.6; }
.prose p + p { margin-top: 24px; }
/* Fra il titolo di sezione e il testo che apre: un passo della scala. Prima
   era l'interlinea del paragrafo a fare da stacco, cioè nessuno stacco. */
.prose > .ttl-2 + p { margin-top: 24px; }
/* Le domande in fondo alla pagina di zona sono il terzo gradino, non un
   quarto: stesso serif del titolo di sezione, un passo più piccolo. */
.faq-item h3 { font-size: clamp(1rem, 1.35vw, 1.15rem); }
.faq-item p { font-size: 0.95rem; line-height: 1.6; margin-top: 8px; }
/* L'elenco delle altre zone in fondo: è navigazione, quindi corpo di lettura
   e non 0,9rem con una tracciatura sua. */
.area-links a { font-size: 0.95rem; letter-spacing: 0; }
/* Le aperture delle pagine di zona: stessa misura del corpo, come ovunque, e
   il sommario stacca dal titolo di un passo della scala. */
.phead .lede { font-size: 0.95rem; line-height: 1.6; margin-top: 24px; max-width: 760px; }
/* Il pulsante sotto il testo: un passo grande, perché chiude la sezione. */
.area-more { margin-top: 32px; }

/* ---- Contatti: la fascia dei modi diretti ------------------------------------
   Round-27 — «il rettangolo "preferisci parlare" è di un colore lievemente più
   scuro dello sfondo, così da differenziarsi». Il round-26 lo aveva svuotato
   fino a renderlo trasparente, tenuto insieme dal solo filetto: sulla carta
   della pagina non si staccava più, e un riquadro che non si vede è un
   riquadro in meno che serve. Il fondo torna sabbia — è un passo solo di
   scala, non una fascia colorata — e il filetto resta a chiudere il bordo.

   Le quattro schede stanno su una riga sola: «non va a capo il richiedi una
   telefonata, quindi devi farci stare tutto in linea come nella referenza».
   «auto-fit» con un minimo di 190 px mandava la quarta a capo appena la
   finestra si stringeva, e una fascia di quattro modi che ne mostra tre più
   uno legge come un errore di caricamento. Quattro colonne fisse, che si
   restringono insieme fino a quando la fascia va in colonna per davvero. */
.ways {
  background: var(--ivory);
  border: 1px solid var(--line);
  /* Quattro schede in riga hanno bisogno di larghezza, e la larghezza si
     recupera dai vuoti prima che dal contenuto: il testo di apertura cede un
     po' di colonna, e il respiro interno e lo stacco fra le due parti
     scendono. Sono i tre numeri che decidono quanto resta alle schede. */
  grid-template-columns: 0.72fr 2.28fr;
  gap: clamp(20px, 2.4vw, 40px);
  padding: clamp(26px, 3vw, 40px);
}
.ways-list { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(12px, 1.4vw, 22px); }
.way { padding-left: 16px; }
/* Anche il titolo della scheda sta su una riga. Il più lungo è "PRENOTA UN
   APPUNTAMENTO": 21 lettere, due spazi e 22 spaziature, cioè 15,7 volte il
   corpo. La colonna più stretta in cui le quattro schede stanno affiancate ne
   offre 146 px (a 1121 px di finestra, appena sopra il punto in cui la fascia
   va in colonna); il corpo fluido lì vale 8 px, e 15,7 × 8 fa 126. Il margine
   resta sopra il 15% a ogni larghezza, che è quanto serve perché Montserrat
   possa essere un po' più larga della media con cui è fatto il conto. */
.way .tag { white-space: nowrap; font-size: clamp(0.5rem, 0.66vw, 0.58rem); letter-spacing: 0.06em; }

/* Il blocco della sede: tre righe di indirizzo, interlinea da indirizzo e non
   da paragrafo, e nessuna sottolineatura fissa — è un recapito, non un menu. */
.office-addr { margin-top: 5px; }
.office-addr a { display: inline-block; line-height: 1.7; font-size: 0.88rem; }

/* Round-27 — il numero provvisorio. Stessa misura del numero vero, così la
   riga non cambia altezza quando arriverà, ma nel colore del testo secondario
   e non in quello dei collegamenti: è la differenza che dice, senza scriverlo,
   che non c'è niente da toccare. */
.office-draft { font-size: 0.88rem; line-height: 1.7; color: var(--ink-46); }

/* Round-26, quarta passata — "Dove operiamo" rimontato sulla referenza.
   La mappa si prende più spazio (là occupa poco più della metà del riquadro) e
   la colonna destra è una sequenza sola: paragrafo, elenco, pulsante. Le due
   colonne partono dall'alto, non si centrano fra loro: allineate al centro,
   con la mappa più alta dell'elenco, il paragrafo scendeva a mezz'aria. */
/* Round-27 — la mappa si prende i due terzi che si prende nella referenza.
   Là il disegno è largo 381 pixel su 594 di colonna: il 65%. Da noi con
   1,35fr contro 1fr ne aveva il 55%, e siccome le etichette sono dimensionate
   nel sistema del disegno, una mappa più stretta le rimpicciolisce insieme a
   sé finché non si leggono più. Allargarla è quindi anche l'unico modo per
   tenere i nomi leggibili senza gonfiarli rispetto alla sagoma. */
.where-wrap { grid-template-columns: 1.9fr 1fr; align-items: center; }
.where-copy p { font-size: 0.9rem; line-height: 1.8; }
.where-cta { margin-top: clamp(20px, 2.4vw, 30px); }

/* La riga di chiusura del modulo: spunta a sinistra, pulsante a destra, sulla
   stessa riga come nella referenza. La spunta prende lo spazio che avanza ma
   non supera la misura di lettura, o su uno schermo largo diventa una riga
   sola lunghissima accanto a un pulsante. */
.form-foot .consent { flex: 1 1 280px; max-width: 46ch; align-items: center; }
.form-foot .consent span { font-size: 0.76rem; line-height: 1.55; }
.form-foot .consent input { margin-top: 0; }
.form-foot .form-send { flex: none; }

/* ---- Le vie dirette che esistono ma non sono ancora attive -------------------
   La referenza mostra quattro schede e il cliente ha chiesto che si vedano
   tutte e quattro anche senza il numero. Quelle spente si distinguono per il
   grigio dell'icona, non per un'etichetta: una scheda barrata o marcata
   "non disponibile" pesa più di quanto informa. */
.way-off .way-ic { color: var(--ink-14); }
.way-off .tag { color: var(--ink-46); }
.way-go { transition: color 0.35s ease; }
.way-off .way-go { color: var(--ink-46); }
.way-off .way-go:hover { color: var(--ink); }

/* ---- Responsive ---------------------------------------------------------------------------------------- */
/* Between 980 and 1280 the panel and the photograph still stand side by side,
   but the panel is narrow: the two actions only hold one row if they give back
   some of their padding and tracking. Measured in the browser, in all three
   languages — German and English set the longest labels. */
@media (max-width: 1280px) {
  .hero-acts .btn { padding: 15px 22px; letter-spacing: 0.12em; }
}

@media (max-width: 1280px) {
  .cards.cards-4 { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 1120px) {
  .why { grid-template-columns: repeat(2, 1fr); }
  .contact-grid { grid-template-columns: 1fr; }
  /* In colonna il filetto condiviso cambia lato: torna il bordo sinistro e si
     toglie quello alto della seconda scheda, che sennò raddoppia sul basso
     della prima. */
  .contact-grid.panels-joined > .panel + .panel { border-left: 1px solid var(--line); border-top: 0; }
  .ways { grid-template-columns: 1fr; align-items: start; }
  /* La riga di quattro tiene finché la fascia ha tutta la larghezza per sé:
     sotto i 1120 il testo di apertura passa sopra e le schede si prendono i
     1216 px pieni, cioè 284 a testa contro i 198 di prima. */
  .svc-grid { grid-template-columns: repeat(3, 1fr); }
  .steps { grid-template-columns: repeat(3, 1fr); row-gap: 34px; }
  .steps::before { display: none; }
  .det-top { grid-template-columns: 1fr; }
  .det-aside { max-width: 520px; }
  .amen-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cards { grid-template-columns: repeat(2, 1fr); }
  .cards.cards-4 { grid-template-columns: repeat(2, 1fr); }
  .fbar { grid-template-columns: repeat(2, 1fr); }
  .fbar-field:nth-child(2n) { border-right: 0; }
  .fbar-field { border-bottom: 1px solid var(--line); }
  .fbar-go { grid-column: 1 / -1; padding: 18px; }
  .marks-grid { grid-template-columns: repeat(2, 1fr); gap: clamp(22px, 3.4vw, 40px); }
  .quad { grid-template-columns: repeat(2, 1fr); }
  .det-grid { grid-template-columns: 1fr; }
  .det-aside { position: static; max-width: 540px; }
}

@media (max-width: 980px) {
  .how { grid-template-columns: 1fr; gap: 26px; }
  .faq2 { grid-template-columns: 1fr; }
  /* La mappa e il testo che la accompagna vanno uno sotto l'altro. La regola
     stava nella media query gemella a metà foglio, prima delle passate che
     hanno riscritto «.where-wrap» qui sotto: a parità di peso vinceva la più
     recente, e la mappa restava affiancata a una colonna di testo larga tre
     parole. Le due regole vanno tenute vicine a quelle che correggono. */
  .where-wrap { grid-template-columns: 1fr; }
  /* Quattro schede su una riga hanno bisogno di 178 px di colonna per tenere
     il titolo su una riga; sotto i 980 la fascia non li ha più. Due e due:
     restano allineate fra loro, che è la cosa che il cliente aveva chiesto. */
  .ways-list { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: clamp(22px, 3vw, 34px); }
  .vform-row { grid-template-columns: 1fr 1fr; }
  .saying { grid-template-columns: 1fr; }
  .split { grid-template-columns: 1fr; }
  /* Stacked, the story reads before its photograph on every band. */
  .split-flip .split-copy { order: 1; }
  .split-flip .split-ph { order: 2; }
  .split-in { margin-left: 0; max-width: none; padding: 0 var(--gx); }
  .split-ph { min-height: 58vw; }
  /* Round-34 — l'apertura NON si impila più.
     Fino al round 33 qui la fotografia scendeva sotto le parole e diventava
     una fascia, con il testo su un rettangolo avorio: sul telefono la home
     era un'altra pagina, e la testata — che il cliente vuole sempre in
     sovraimpressione sulla fotografia — si trovava sopra la carta.
     L'apertura sul telefono è la stessa del desktop: una fotografia da bordo
     a bordo, le parole sopra, il velo a renderle leggibili. Il velo ora è
     obbligatorio e ricalibrato più sotto: senza, la misura dice 1,1:1. */
  .hero-block { max-width: none; margin-left: 0; }
  .hero-acts .btn { flex: 1 1 240px; text-align: center; }
  .hero-search { flex-direction: column; gap: 4px; }
  .hs-field { padding: 12px 0; flex: 1 1 auto; }
  .hs-go { align-self: stretch; text-align: center; margin-top: 18px; margin-left: 0; }

  .hd-burger { display: flex; }
  .hd-nav {
    position: fixed;
    inset: 0;
    z-index: -1;
    background: linear-gradient(165deg, var(--ink) 0%, var(--ink-deep) 100%);
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 30px;
    padding: var(--hdh) var(--gx) 40px;
    clip-path: inset(0 0 100% 0);
    transition: clip-path 0.75s var(--ease);
  }
  body.nav-open .hd-nav { clip-path: inset(0 0 0 0); }
  body.nav-open { overflow: hidden; }
  /* The panel is fixed to the viewport, so the header must not become its
     containing block: backdrop-filter and transform both do that, which is
     why a scrolled page used to trap the menu inside the 78px bar. */
  body.nav-open .hd,
  body.nav-open .hd.is-scrolled {
    background: transparent;
    box-shadow: none;
    transform: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  body.nav-open .hd-brand img { filter: brightness(0) invert(1); }
  body.nav-open .hd-burger span { background: var(--paper); }
  body.nav-open .lang a { color: var(--paper-40); }
  body.nav-open .lang a.on, body.nav-open .lang a:hover { color: var(--paper); }
  /* Every item on the dark panel is paper — including the current page and
     the call to action, which carry their own colour on the desktop bar. */
  .hd-nav a,
  .hd-nav a.on,
  .hd-nav a.hd-cta {
    color: var(--paper);
    font-size: 1.3rem;
    font-weight: 400;
    letter-spacing: 0.2em;
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 0.5s ease, transform 0.6s var(--ease), color 0.45s var(--ease);
  }
  body.nav-open .hd-nav a { opacity: 1; transform: none; }
  body.nav-open .hd-nav a:nth-child(1) { transition-delay: 0.2s; }
  body.nav-open .hd-nav a:nth-child(2) { transition-delay: 0.28s; }
  body.nav-open .hd-nav a:nth-child(3) { transition-delay: 0.36s; }
  body.nav-open .hd-nav a:nth-child(4) { transition-delay: 0.44s; }
  .hd-nav a.hd-cta { border-color: var(--paper-18); padding: 14px 26px; font-size: 0.84rem; }
  .hd-nav a.hd-cta::before { background: var(--paper); }
  .hd-nav a.hd-cta:hover, .hd-nav a.hd-cta:active { color: var(--ink); }

  .duo, .duo-flip { grid-template-columns: 1fr; gap: 32px; }
  .duo-flip .duo-copy { order: 2; }
  .duo-flip .duo-ph { order: 1; }
  .duo-ph { aspect-ratio: 3 / 2; }

  .cat { grid-template-columns: 1fr; }
  .cat-side { position: static; }
  .fbox summary { display: block; }
  .fbox:not([open]) .fbody { display: none; }
  .fbody { border: 1px solid var(--ink-14); border-top: 0; padding: 24px 18px; }

  .contact { grid-template-columns: 1fr; }
  .pledge-grid { grid-template-columns: 1fr; }
  .tri { grid-template-columns: 1fr; }
  .facts { grid-template-columns: 1fr; }
  .amen { columns: 1; }
  .ft-grid { grid-template-columns: 1fr 1fr; }

  .mosaic { height: auto; grid-template-columns: 1fr 1fr; grid-template-rows: none; }
  .mosaic .m0 { grid-column: 1 / -1; grid-row: auto; aspect-ratio: 3 / 2; }
  .mtile { aspect-ratio: 3 / 2; }
  .mosaic .m3, .mosaic .m4, .mosaic.n4 .m3 { display: none; }
}

@media (max-width: 780px) {
  .blk-after-search { padding-top: clamp(32px, 3.4vw, 48px); }

.blk-head-split { flex-direction: column; align-items: flex-start; gap: 22px; }
  .bh-link { padding-bottom: 7px; }
}

@media (max-width: 620px) {
  .why, .vform-row { grid-template-columns: 1fr; }
  /* Su telefono la riga di quattro non ci sta in nessun modo: le schede vanno
     una sotto l'altra, e il filetto passa dal fianco alla testa. Il titolo può
     tornare ad andare a capo — in colonna non spezza più nessun allineamento. */
  .ways-list { grid-template-columns: 1fr; }
  .way .tag { white-space: normal; }
  .way { padding-left: 0; border-left: 0; border-top: 1px solid var(--line); padding-top: 20px; }
  .svc-grid { grid-template-columns: 1fr; }
  .steps { grid-template-columns: repeat(2, 1fr); }
  .ctaband-in { flex-direction: column; align-items: flex-start; }
  .gal { grid-template-columns: 1fr; }
  .gal-side { grid-template-rows: none; }
  /* Le colonne delle miniature e la misura di «vedi tutte le foto» stanno nel
     blocco ROUND 34, punto 5, in fondo al foglio. */
  .amen-row, .facts, .det-boxes { grid-template-columns: 1fr; }
  .det-actions { flex-direction: row; flex-wrap: wrap; gap: 18px; }
  .cards.cards-4 { grid-template-columns: 1fr; }
  .fbar { grid-template-columns: 1fr; }
  .fbar-field { border-right: 0; }
  .results-bar { align-items: flex-start; flex-direction: column; }
  .sortbar .sel { min-width: 0; flex: 1; }
  /* The lockup keeps its proportions on a phone: the drawing and the word
     underneath shrink together, or "Real Estate" ends up wider than the name. */
  .hd-brand img { height: 17px; }
  .hd-brand .lock { font-size: 0.45rem; }
  .cards { grid-template-columns: 1fr; }
  .ft-grid { grid-template-columns: 1fr; }
  .marks-grid { grid-template-columns: 1fr; gap: 26px; }
  .mk-txt p:last-child { max-width: none; }
  /* La misura del titolo dell'apertura sta nel blocco ROUND 34, punto 2: qui
     era 24px, cioè più piccola dei titoli di sezione della stessa pagina. */
  .quad { grid-template-columns: 1fr; }
  .form-row { grid-template-columns: 1fr; }
  /* L'indice territorio tiene le sue tre colonne e la sua freccia — ROUND 34,
     punto 4. */
}

/* ================================================================================
   ROUND 34 — il telefono
   ================================================================================
   Richiesta: «il sito mobile deve risultare il più simile possibile a quello
   desktop». Non vuol dire rimpicciolire il desktop — quattro colonne su 390px
   fanno celle da 84px, e una cifra grande dentro 84px non è più una cifra
   grande. Vuol dire che la pagina sul telefono deve dire **le stesse cose con
   gli stessi mezzi**: stessa apertura fotografica, stesse proporzioni delle
   immagini, stessi filetti, stesse gerarchie di carattere, e soprattutto
   nessun pezzo che sul telefono sparisce o esce dallo schermo.

   Questo blocco sta in fondo al foglio, dopo tutte le altre media query,
   perché corregge cose scritte in più punti e a parità di peso vince chi è
   scritta dopo. Le correzioni all'apertura non sono qui: stanno dove stavano
   le regole che sostituiscono, nella sezione "Responsive" e nel blocco del
   velo del round 26. */

/* -- 1. L'altezza dello schermo, sul telefono, non è 100vh ---------------------
   Su iOS e su Android `100vh` vale l'altezza della finestra **senza** la barra
   dell'indirizzo, che però all'apertura della pagina c'è: l'apertura nasce più
   alta dello schermo, il piede del titolo finisce sotto il bordo, e appena si
   scorre di un dito la barra si ritira e tutto salta. `100svh` è la misura
   piccola, quella che tiene conto della barra: è la stessa idea, scritta con
   l'unità giusta. La riga in vh resta prima come riserva per i browser vecchi,
   che ignorano la seconda e tengono la prima. */
@media (max-width: 980px) {
  .hero { min-height: clamp(500px, calc(100svh - var(--hdh) - 150px), 760px); }
  body.is-home .hero { min-height: 100svh; }
}

/* -- 2. Il titolo dell'apertura era più piccolo dei titoli di sezione ----------
   Sul desktop l'h1 misura 64,8px e i titoli di sezione 40: l'apertura pesa una
   volta e mezza il resto della pagina, che è quello che la rende un'apertura.
   Sotto i 620 l'h1 scendeva a 24px e i titoli di sezione restavano a 26,4: la
   gerarchia si rovesciava, e la prima cosa che si leggeva era la più piccola.

   La misura non può crescere a piacere — le due righe del titolo sono due
   caselle animate, e una riga che va a capo dentro la casella si taglia da
   sola. Il vincolo è la riga più lunga delle tre lingue ("Einzigartige
   Objekte.", 21 caratteri): in Cormorant occupa circa 9,7 volte il corpo,
   quindi il corpo massimo è la larghezza utile diviso 9,7. A 390px di schermo
   sono 36px, a 320px sono 28,8. La clamp qui sotto sta sotto quel limite su
   ogni larghezza e riporta l'apertura a 1,25 volte i titoli di sezione. */
@media (max-width: 620px) {
  .hero-title { font-size: clamp(1.7rem, 8.4vw, 2.3rem); }
  /* La gerarchia si fa in due: il titolo dell'apertura non può salire più di
     così senza andare a capo, quindi scendono i titoli di sezione. La clamp
     arriva a 1,65rem esatti a 620px, cioè al valore che il desktop ha lì:
     al confine fra le due regole non si vede nessuno scalino. */
  .ttl { font-size: clamp(1.4rem, 4.3vw, 1.65rem); }
}

/* -- 3. I quattro numeri della home --------------------------------------------
   `.proof-grid` era l'unica griglia del sito senza uno scalino per il
   telefono: quattro colonne fino a 320px, cioè celle da 70px con dentro una
   cifra da 32 e una frase. Due e due, con il filetto che passa da verticale a
   orizzontale fra le due righe — lo stesso filetto, girato, come già fanno
   `.way` e `.contact-grid`. */
@media (max-width: 620px) {
  .proof-grid { grid-template-columns: repeat(2, 1fr); }
  .proof-i:nth-child(2n+1) { border-left: 0; }
  .proof-i:nth-child(n+3) {
    margin-top: clamp(26px, 6vw, 34px);
    padding-top: clamp(26px, 6vw, 34px);
    border-top: 1px solid var(--line);
  }
}

/* -- 4. La freccia dell'indice territorio --------------------------------------
   Sotto i 620 era spenta con display:none. È il segno che dice che la riga è
   un collegamento e non una voce di elenco: toglierlo sul telefono — dove non
   esiste il passaggio del mouse che la fa scorrere, quindi è l'unico segno
   rimasto — significa lasciare sette righe che non sembrano cliccabili.
   Ci sta: nome 140px, conteggio 95, freccia 20, spazi 32, su 335 di riga. */
@media (max-width: 620px) {
  .index-row { grid-template-columns: 1fr auto auto; gap: 14px; }
  .ir-arrow { display: flex; opacity: 1; transform: none; }
}

/* -- 5. «Vedi tutte le foto» ----------------------------------------------------
   Sul telefono le tre miniature passano da colonna a riga, e l'etichetta —
   che sta sull'ultima — si trovava dentro 105px: era stata rimpicciolita a
   0,5rem, cioè 8px, con la tracciatura quasi tolta. Un comando di 8px non si
   legge e non si preme.

   L'ultima miniatura prende tutta la riga e la proporzione 3:2 della
   fotografia grande — la proporzione unica del sito, decisa al round 31 — e
   l'etichetta torna alla misura che ha sul desktop. */
@media (max-width: 620px) {
  /* `grid-auto-rows: 1fr` (round 32) rende tutte le righe alte uguali: là
     serviva, perché le tre miniature erano incolonnate dentro un'altezza
     data dalla fotografia grande. Qui le righe sono due e diverse — due
     quadrati sopra, un 3:2 sotto — e pareggiarle stirerebbe i quadrati, che
     la proporzione se la portano da soli. */
  .gal-side { grid-template-columns: repeat(2, 1fr); grid-auto-rows: auto; }
  .gal-tile { aspect-ratio: 1; }
  .gal-tile:last-child { grid-column: 1 / -1; aspect-ratio: 3 / 2; }
  .gal-all { font-size: 0.58rem; letter-spacing: 0.16em; padding: 10px 16px; }
}

/* -- 6. Le aree da premere -----------------------------------------------------
   Le tre lingue nella testata sono alte 22px compreso il respiro, e stanno a
   2px l'una dall'altra: con un dito si prende quella sbagliata. Le linee guida
   di Apple e di Google chiedono 44 e 48px; qui il bersaglio cresce senza che
   la scritta cambi misura, perché a crescere è il respiro. Vale solo dove
   esiste un dito, cioè sotto i 980, dove compare anche il menù. */
@media (max-width: 980px) {
  .lang { gap: 2px; }
  .lang a { padding: 18px 6px; }
  .hd-burger { padding: 12px 6px; min-height: 44px; justify-content: center; margin-right: -6px; }
  /* Il piede è fatto di elenchi di collegamenti incolonnati: sul telefono
     stanno uno sotto l'altro e devono avere l'altezza di un dito. */
  .ft-col li { line-height: 2.35; }
}
/* Il respiro guadagnato dai bersagli va tolto da qualche parte, o su uno
   schermo da 320px la testata non ci sta più: marchio 129px, tre lingue 78,
   menù 34 e i due spazi fanno 269 su 280 di riga utile. Gli spazi della
   testata sono l'unica misura che si può stringere senza toccare né il
   marchio né i bersagli. */
@media (max-width: 620px) {
  .hd-in { gap: 14px; }
  .hd-tools { gap: 10px; }
}

/* -- 7. Niente esce di lato ----------------------------------------------------
   Tre etichette sono dichiarate `nowrap` perché sul desktop devono stare su
   una riga: il prezzo della card, i quattro dati della card e il conteggio
   dell'indice. Sul desktop la riga c'è; su 320px il prezzo di un immobile a
   sette cifre con la valuta non ci sta, e una parola in nowrap non allarga il
   suo blocco — sfonda, e con lei la pagina intera, che diventa scorrevole di
   lato. La cifra si rimpicciolisce quel tanto che basta invece di uscire.

   La riga su `html` è la rete di sicurezza: se un giorno qualcosa sfonda
   comunque, la pagina non diventa trascinabile di lato. Non nasconde il
   difetto — un elemento tagliato si vede — ma evita che tutto il sito
   sembri storto per colpa di una parola.

   `clip` e non `hidden`: `hidden` fa della pagina un contenitore di
   scorrimento, e un contenitore di scorrimento rompe `position: sticky` di
   tutto quello che ha dentro. `clip` taglia e basta. I browser che non lo
   conoscono leggono la riga prima. */
@media (max-width: 620px) {
  html { overflow-x: hidden; overflow-x: clip; }
  .card-price { font-size: clamp(0.86rem, 4.4vw, 1.02rem); }
  .card-meta span { font-size: 0.66rem; }
  .ir-meta { font-size: 0.58rem; letter-spacing: 0.18em; }
}

/* -- 8. Le tabelle di dati della scheda immobile -------------------------------
   `.keyrow` perde i filetti verticali sotto i 980 (giustamente: le cinque
   cifre vanno a capo), ma senza filetti e con 20px di spazio le cinque
   diventano un ammasso. Tornano a essere cinque cose distinte con un filetto
   orizzontale fra le righe, che è quello che il desktop fa in verticale. */
@media (max-width: 620px) {
  .keyrow { gap: 0; }
  .keyrow > .key {
    flex: 1 0 100%;
    padding: 13px 0;
    background-image: var(--rule);
    background-repeat: no-repeat;
    background-size: 100% 1px;
    background-position: 0 100%;
  }
  .keyrow > .key:last-child { background-image: none; }
}

/* ================================================================================
   ROUND 35 — il telefono, seconda passata
   ================================================================================
   Stessa richiesta del round 34: «il sito mobile deve risultare il più simile
   possibile a quello desktop». Il round 34 ha rimesso a posto l'impaginazione
   — l'apertura, le griglie, le misure dei titoli. Restavano sei cose, e la
   prima è la più grave perché non si vede leggendo il foglio di stile: si
   vede solo prendendo in mano un telefono.

   Come il blocco precedente, questo sta in fondo al foglio: corregge regole
   scritte in più punti, e a parità di peso vince chi è scritta dopo. */

/* -- 1. Il telefono ingrandiva la pagina appena si toccava un campo -----------
   È il difetto peggiore che restava, ed è quello che più di ogni altro faceva
   sembrare il sito «un'altra cosa» sul telefono.

   Safari su iPhone, e Chrome su iPad, hanno una regola non scritta: se si
   tocca un campo di testo il cui corpo è **sotto i 16 px**, il browser decide
   che il testo è troppo piccolo da leggere mentre si scrive e ingrandisce la
   pagina da solo. Non è uno zoom che si annulla da sé: la pagina resta
   ingrandita, la testata esce dallo schermo a sinistra, il piede a destra, e
   per tornare a vedere il sito bisogna pizzicare lo schermo all'indietro.

   I campi del sito erano tutti sotto quella soglia:

     modulo contatti / valutazione   14,7 px
     scheda immobile (colonna)       13,6 px
     valutazione (campi scuri)       14,4 px
     tendine della ricerca           14,7 px

   Quindi capitava su ogni modulo del sito e a ogni tentativo di scrivere.
   Non esiste un modo di disattivare quel comportamento — `user-scalable=no`
   nel viewport lo farebbe, ma toglie al visitatore la possibilità di
   ingrandire la pagina, che è un requisito di accessibilità e che Safari
   ignora comunque da anni. L'unico rimedio è dare ai campi i 16 px che il
   browser chiede.

   Cambia solo sul telefono e solo dentro i campi: le etichette, i pulsanti e
   tutto il resto della pagina restano alle misure del round 34. E 16 px in un
   campo alto 46 non stanno stretti — è la misura del corpo di lettura. */
@media (max-width: 980px) {
  .field input,
  .field textarea,
  .det-card .field input,
  .det-card .field textarea,
  .vform .field-dark input,
  .vform .field-dark textarea,
  .hs-field select,
  .ffield select,
  .fbar select,
  .sortbar select,
  .sel select,
  input[type="text"],
  input[type="email"],
  input[type="tel"],
  input[type="number"],
  input[type="search"],
  textarea,
  select { font-size: 16px; }
  /* Il campo scuro della valutazione ha l'altezza e l'interlinea dichiarate
     insieme: cresciuto il corpo, l'interlinea va ridichiarata o il testo si
     appoggia al bordo alto. */
  .vform .field-dark input,
  .vform .field-dark .sel-btn { line-height: 46px; }
  /* Il bottone della tendina disegnata non è un campo — non fa ingrandire
     niente — ma sta in fila con i campi veri: se resta a 14,7 px accanto a
     uno da 16 la riga si vede storta. I selettori sono scritti per esteso e
     non come `.sel-btn` perché le regole che portano la misura di partenza
     pesano due o tre classi: una regola più leggera, per quanto scritta dopo,
     non le scavalca. */
  .sel .sel-btn,
  .sel-plain .sel-btn,
  .fbar .sel .sel-btn,
  .vform .sel-dark .sel-btn,
  .vform .field-dark .sel-btn { font-size: 16px; }
}

/* -- 2. La scheda immobile, dentro la colonna, sul telefono --------------------
   La colonna della scheda immobile ha misure sue, più strette di quelle del
   modulo grande, perché sul desktop sta in una colonna da 330 px. Sul telefono
   quella colonna non esiste più — scende sotto la fotografia e prende tutta la
   larghezza — quindi le misure strette non servono più a niente e restano solo
   come un modulo più piccolo degli altri. Torna quello grande. */
@media (max-width: 980px) {
  .det-card .consent span { font-size: 0.82rem; line-height: 1.65; }
  .det-card .form-note { font-size: 0.72rem; line-height: 1.6; }
  .det-card .field input, .det-card .field textarea { padding: 13px 16px; }
}

/* -- 3. Le tre schede del team uscivano dallo schermo -------------------------
   `repeat(auto-fit, minmax(340px, 1fr))` vuol dire: colonne larghe **almeno**
   340 px. Su un iPhone da 390 px la colonna utile è 350 e ci sta; su un
   iPhone 13 mini (375) è 335, su un SE (320) è 280 — e la scheda resta larga
   340 comunque, cioè esce dallo schermo di 5 px sul mini e di 60 sul SE. La
   rete di sicurezza del round 34 (`overflow-x: clip`) impediva alla pagina di
   trascinarsi di lato, ma la scheda restava tagliata: il ritratto si vedeva,
   il telefono dell'agente no.

   `min(340px, 100%)` dice la stessa cosa con una riserva: almeno 340 px,
   **ma mai più della colonna che c'è**. È la forma corretta di auto-fit e non
   cambia niente sopra i 380 px di schermo. */
@media (max-width: 1239px) {
  .team { grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr)); }
}

/* -- 4. Titolo di sezione e sottotitolo: perché restano quasi uguali -----------
   Questa NON è una correzione: è la nota di una cosa che ho provato a
   correggere e che non si può correggere. Sta qui perché senza la nota, la
   prossima volta si riprova.

   Sul desktop la scala dei titoli ha tre gradini netti: 38,9 px il titolo di
   sezione (.ttl), 29,6 il sottotitolo (.ttl-2), 16,3 il paragrafo d'apertura.
   Sul telefono i due titoli finiscono entrambi contro il minimo della loro
   clamp — 22,4 e 21,6 — e fra i due resta il 3 %, cioè niente.

   Le due strade sono chiuse tutte e due, e ognuna è chiusa da una regola già
   scritta e già misurata:

     * abbassare il sottotitolo. Il round 26 misura che .ttl-2 deve stare
       almeno al 140 % del paragrafo d'apertura, perché il Cormorant ha le
       minuscole molto più basse del Montserrat: sotto quella soglia il
       titolo si legge più piccolo del testo che introduce, che è esattamente
       la segnalazione del cliente al round 31. Il paragrafo sta a 16,3 px e
       non può scendere — è il corpo di lettura — quindi il sottotitolo non
       può scendere sotto i 21,4.
     * alzare il titolo di sezione. Il round 34 misura che il titolo
       dell'apertura deve pesare almeno il 110 % dei titoli di sezione, e
       l'apertura sul telefono ha un tetto suo: le sue due righe sono caselle
       animate e una riga che va a capo si taglia, il che su uno schermo da
       320 px la ferma a 27,2 px. Da lì il titolo di sezione non può passare
       i 24,7.

   Fra 21,4 e 24,7 c'è tutto lo spazio che il telefono concede, e non basta a
   fare il gradino che si vede sul desktop. Il gradino sul telefono lo fanno il
   carattere e lo spazio sopra, non la misura. */

/* -- 5. Il filetto che unisce i sei passi ------------------------------------
   I sei passi del metodo (ascolto · analisi · strategia · promozione ·
   trattativa · risultato) sono sei numeri in un cerchio, uniti sul desktop da
   un filetto che passa dietro di loro. Sotto i 1120 px il filetto era spento
   con `display: none`, e per un buon motivo: è **una** riga orizzontale
   disegnata a 21 px dall'alto della fascia, e quando i sei passi vanno su due
   o tre righe quella riga attraversa solo la prima e poi passa dietro al testo
   delle altre.

   Ma spegnerlo vuol dire che sul telefono i sei passi non sono più una
   sequenza: sono sei riquadri numerati. Il filetto è il segno che dice che si
   va da 1 a 6, ed è uno dei «stessi mezzi» del round 34.

   Il filetto ora non è più uno per la fascia: è uno per passo, che va dal suo
   cerchio a quello alla sua destra, e si spegne sull'ultimo di ogni riga.
   Così segue le righe qualunque siano — tre e tre sotto i 1120, due e due e
   due sotto i 620 — e non tocca mai il testo, perché resta all'altezza del
   centro dei cerchi.

   La misura: il cerchio è largo 42 px, quindi il filetto parte dal centro
   della cella più 21 e arriva al centro della cella accanto meno 21. Il
   centro della cella accanto, misurato dal bordo destro di questa, sta a
   «metà cella più lo spazio fra le due»: da qui il -50% e `--stepgap`, che è
   lo stesso spazio dichiarato sulla griglia — così le due misure non possono
   divergere. */
@media (max-width: 1120px) {
  .step::after {
    content: "";
    position: absolute;
    top: 21px;
    left: calc(50% + 21px);
    right: calc(-50% - var(--stepgap) + 21px);
    height: 1px;
    background: var(--line);
  }
  /* Tre per riga: si spegne sul terzo, sul sesto e comunque sull'ultimo. */
  .step:nth-child(3n)::after, .step:last-child::after { content: none; }
}
@media (max-width: 620px) {
  /* Due per riga: il terzo torna a essere unito al quarto, il secondo no. */
  .step:nth-child(3n)::after { content: ""; }
  .step:nth-child(2n)::after, .step:last-child::after { content: none; }
}

/* -- 6. Le ultime cose che si premono con un dito ------------------------------
   Il round 34 ha portato a 44 px i bersagli della testata e del piede. Ne
   restavano tre, tutti fatti di un disegno piccolo senza niente intorno: le
   tre icone sociali del piede (17 px), la busta e il LinkedIn di ogni persona
   del team (15 px) e il numero di telefono degli agenti. Come nel round 34, a
   crescere è il respiro: il disegno resta della misura che ha sul desktop.

   Il conto è fatto perché la fila **non cambi aspetto**. Lo spazio fra due
   icone passa dalla griglia al respiro delle icone stesse: nel piede era un
   gap di 16 px, e diventa gap 0 con 8 px di respiro per lato — la distanza
   che si vede è la stessa 16, ma i due bersagli si toccano invece di lasciare
   in mezzo 16 px di niente che non risponde al dito. In verticale il respiro
   è pieno, perché lì sopra e sotto non c'è nient'altro da premere: 17 px di
   disegno più 14 e 14 fanno 45.

   Il margine negativo rimette la fila allineata al bordo della colonna: senza,
   il respiro sinistro della prima icona la spingerebbe dentro di 8 px rispetto
   al marchio che ha sopra. */
@media (max-width: 980px) {
  .ft-social { gap: 0; margin-left: -8px; }
  .ft-social a, .ft-social-off { padding: 14px 8px; }
  .tm-icons { gap: 0; margin-left: -7px; }
  .tm-ic { padding: 15px 7px; }
  /* Il numero di telefono è una riga di testo alta 20 px: il respiro sopra e
     sotto la porta a 44 senza spostare niente, perché il blocco dei recapiti
     è ancorato in fondo alla scheda e cresce verso l'alto. */
  .tm-links a { display: inline-block; padding: 12px 0; }
}

/* -- 7. L'ultima voce del menù compariva per prima -----------------------------
   Il pannello del menù sul telefono fa entrare le voci una dopo l'altra, con
   un ritardo dichiarato per la prima, la seconda, la terza e la quarta. Le
   voci però sono cinque: la quinta è «Valutazione», che è un pulsante. Senza
   un ritardo suo entrava con ritardo zero, cioè **prima di tutte le altre** —
   il pulsante appariva per primo e i quattro collegamenti lo raggiungevano
   dopo. Prende il gradino che le spetta. */
@media (max-width: 980px) {
  body.nav-open .hd-nav a:nth-child(5) { transition-delay: 0.52s; }
}

/* ---- Reduced motion -------------------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001s !important;
    animation-delay: 0s !important;
    transition-duration: 0.001s !important;
    transition-delay: 0s !important;
  }
  html.js .io, html.js .io-blur { opacity: 1; transform: none; filter: none; }
  html.js .io-wipe img { clip-path: inset(0 0 0 0); scale: 1; }
  .mask-in { transform: none; }
  .lintel::before, .tri-cell::before, .pg::before, .hero-rule { transform: scaleX(1); }
  .mono-lintel, .mono-mid, .mono-base { transform: scaleX(1); }
  .mono-stem { transform: scaleY(1); }
  .mono-trace line { stroke-dashoffset: 0; }
  #site-splash .mono { transform: none; }
  .sp-word img { clip-path: inset(0 0 0 14.97%); }
  .sp-load i { transform: scaleX(1); }
  html.show-splash #main { filter: none; }
  .rise, .rise-2, .rise-3, .rise-4, .hero-lede, .hero-tag, .hero-acts { opacity: 1; }
  .hero-ph { clip-path: inset(0 0 0 0); }
  .hero-ph img { scale: 1; }
}

/* ================================================================================
   ROUND 36 — le correzioni chieste dal cliente il 15 agosto 2026
   ================================================================================
   Undici punti, sei sul desktop e cinque sul telefono. Quattro di questi sono
   lo stesso difetto scritto quattro volte: una regola nata per la testata
   sopra una fotografia pesa **due classi** e vince su quella che dovrebbe
   correggerla, che ne pesa una. Il rimedio non è spostare le regole — è
   scriverle con il peso che serve, e dirlo. */

/* -- 1. «Valuta il tuo immobile»: la scritta restava blu su blu ---------------
   Passando il mouse, il rettangolo del pulsante si riempie di blu e la scritta
   deve diventare bianca. Sulla pagina appena aperta funzionava; appena si
   scorreva di un dito, no — e la scritta spariva dentro il proprio fondo.

   La causa è il peso dei selettori. `.hd-nav a.hd-cta:hover` (due classi) è
   scritto a metà foglio; `.hd.is-scrolled .hd-nav a:hover` (due classi anche
   lui, ma scritto **dopo**) è la regola che scurisce la navigazione quando la
   testata scorre sopra la carta. A parità di peso vince l'ultima scritta, e
   l'ultima diceva «blu».

   Qui il pulsante viene nominato con la testata davanti: tre classi contro
   due, e la questione è chiusa per sempre — non dipende più dall'ordine. */
.hd.is-scrolled .hd-nav a.hd-cta { color: var(--ink); }
.hd.is-scrolled .hd-nav a.hd-cta:hover { color: var(--white); }

/* -- 2. Il menù del telefono aveva le scritte scure sul fondo scuro -----------
   Stessa causa, e questa volta il difetto è grave: il pannello del menù è blu
   notte e le voci devono essere avorio. `.hd-nav a { color: var(--paper) }`
   dentro la media query pesa **una** classe e un elemento; la regola della
   testata scorsa — `.hd.is-scrolled .hd-nav a` — ne pesa due. Chi apre il menù
   dopo aver scorso la pagina (cioè quasi tutti) vedeva quattro scritte blu su
   un fondo blu.

   `body.nav-open` davanti a tutto: quattro classi, e vale solo a menù aperto,
   che è esattamente il momento in cui il pannello è scuro. */
body.nav-open .hd.is-scrolled .hd-nav a,
body.nav-open .hd.is-scrolled .hd-nav a.on,
body.nav-open .hd.is-scrolled .hd-nav a.hd-cta,
body.nav-open .hd .hd-nav a,
body.nav-open .hd .hd-nav a.on { color: var(--paper); }
body.nav-open .hd .hd-nav a:hover,
body.nav-open .hd.is-scrolled .hd-nav a:hover { color: var(--white); }
/* La lingua scelta e il segno del menù sullo stesso fondo scuro. */
body.nav-open .hd.is-scrolled .lang a { color: var(--paper-40); }
body.nav-open .hd.is-scrolled .lang a.on { color: var(--paper); }
body.nav-open .hd.is-scrolled .hd-burger span { background: var(--paper); }

/* -- 3. «I nostri contatti»: il vuoto in fondo e la mail di un'altra misura ---
   Due cose, e la seconda spiega la prima.

   La mail era scritta a 16 px e l'indirizzo della sede a 14: due misure per
   due recapiti che stanno uno sotto l'altro, ed è quello che si vedeva come
   «un font diverso». Non lo era — era la stessa Montserrat, più grande. Ora i
   quattro recapiti hanno una misura sola.

   Il vuoto: il riquadro dei recapiti è alto quanto il modulo che ha accanto —
   è la regola del round 27, e va tenuta, perché due schede affiancate che
   chiudono a quote diverse sono la cosa che il cliente aveva già segnalato.
   Ma il contenuto si fermava in cima e lasciava tutto il resto bianco. Adesso
   i quattro recapiti si distribuiscono sull'altezza del riquadro **separati da
   un filetto**: il vuoto smette di essere un buco in fondo e diventa aria
   dentro una tabella, che è lo stesso rimedio adottato al round 30 per i punti
   di forza della scheda immobile. Il filetto arriva ai bordi del riquadro,
   perché una riga che si ferma prima sembra rotta.

   A riempire l'altezza sono **le righe**, non i vuoti fra loro: è la stessa
   scelta del round 33c per i punti di forza, ed è la differenza fra una
   tabella e quattro frasi sospese. Con «space-between» il filetto di ogni riga
   resterebbe attaccato alla riga e lontano dalla successiva — di nuovo linee
   che non si toccano. */
.office a, .office p, .office-addr a, .office-draft {
  font-size: 0.88rem;
  line-height: 1.7;
}
/* Round-40 — «lascia così l'impaginazione dei nostri contatti ma leva le
   linee divisorie». I filetti se ne vanno, il resto resta identico: i quattro
   recapiti continuano a dividersi l'altezza del riquadro in parti uguali
   (`flex: 1` sulle righe) e a stare ciascuno al centro della propria, quindi
   né la posizione né il respiro cambiano di un pixel. Cambia solo che a
   separarli adesso è lo spazio.

   Il rientro negativo e l'imbottitura laterale sono usciti insieme ai filetti:
   servivano a portare la riga da un bordo all'altro del riquadro, e si
   annullavano a vicenda: toglierli non sposta niente. */
.panel-quiet .office {
  flex: 1;
  gap: 0;
  margin-top: 22px;
}
.panel-quiet .office li {
  flex: 1;
  align-items: center;
  align-content: center;
  padding-block: clamp(16px, 1.8vw, 24px);
}

/* -- 4. «I tuoi dati restano fra noi» va nell'angolo --------------------------
   Stava in mezzo alla riga di chiusura del modulo di valutazione: quando non
   c'era spazio per stare accanto al pulsante andava a capo e si ritrovava da
   sola in mezzo a una fascia blu, che è il posto in cui una nota di servizio
   dà più nell'occhio di quanto serva. Va nell'angolo in basso a destra e ci
   resta anche quando va a capo, un gradino più piccola. */
.vform-foot { align-items: flex-end; }
.vform-note {
  margin-left: auto;
  text-align: right;
  font-size: 0.64rem;
}
@media (max-width: 620px) {
  /* Su una colonna sola «a destra» non vuol dire niente: la nota torna sotto
     il pulsante, allineata a lui. */
  .vform-foot { align-items: flex-start; }
  .vform-note { margin-left: 0; text-align: left; }
}

/* -- 5. Le cifre del prezzo -------------------------------------------------
   «cambia il font che usi per i numeri del prezzo, lo voglio più sobrio e in
   linea con il resto».

   Il Cormorant disegna le cifre **all'antica**: il 5 e il 6 scendono sotto la
   riga, lo 0 è basso come una minuscola, l'1 sembra una I. Su un titolo è un
   pregio; su «€ 565.000» e su «107 m²» diventa una scritta ondulata, e accanto
   ai numeri della card — che sono in Montserrat — sembra un altro sito.

   Le cifre passano al grottesco, che è il carattere con cui questo sito scrive
   già ogni dato. `tabular-nums` incolonna le cifre tutte della stessa
   larghezza, così due prezzi affiancati stanno in squadra. La misura scende di
   un filo perché il grottesco, a parità di corpo, legge più grande del serif.

   La referenza mette il prezzo in serif. Vale qui quello che vale per la
   testata e per il velo: la decisione del cliente prevale sulla referenza, ed
   è annotata dove qualcuno andrà a cercarla — nel test del round 32. */
.card-price, .det-price, .key-n {
  font-family: var(--sans);
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
  letter-spacing: 0.01em;
}
.card-price { font-size: 0.95rem; font-weight: 400; }
.det-price { font-size: clamp(1.25rem, 1.9vw, 1.6rem); font-weight: 400; }
.key-n { font-size: 1.22rem; font-weight: 400; }
@media (max-width: 620px) {
  .card-price { font-size: clamp(0.8rem, 4vw, 0.95rem); }
}

/* -- 6. La planimetria resta piccola, e sempre della stessa misura ------------
   Il riquadro era largo mezza pagina: su 1360 px sono 660, e con la
   proporzione 4:3 il disegno diventava alto 495 — la cosa più grande della
   scheda dopo la fotografia di apertura, per un allegato che si apre a parte.
   E siccome cresceva con la colonna, cambiava misura a ogni larghezza di
   finestra.

   Adesso ha una misura sua, dichiarata in pixel: 360 px di lato lungo, gli
   stessi su ogni schermo. È una miniatura, che è quello che è — il disegno
   vero si apre con il pulsante sotto. `flex: none` è la riga che le impedisce
   di allungarsi quando il riquadro accanto è più alto del suo. */
.plan-frame {
  flex: none;
  width: 100%;
  max-width: 360px;
  aspect-ratio: 4 / 3;
  padding: 12px;
}
.plan-frame img { width: 100%; height: 100%; object-fit: contain; }

/* -- 7. I punti di forza: una tabella, non righe con i filetti spaiati --------
   «senza linee sconnesse»: il difetto sono i filetti, non l'altezza.

   Le righe erano già celle alte uguali che riempiono il riquadro — è il round
   30, ed è la correzione a una segnalazione precedente del cliente («sono
   tutti in alto e sotto è tutto vuoto»): quella resta com'è. A non funzionare
   era il filetto. Era largo quanto il testo, dentro un riquadro il cui bordo
   sta 28 px più in là: ogni riga cominciava e finiva in un punto suo, il
   filetto sotto l'ultima riga non c'era, e sopra la prima nemmeno — cinque
   trattini sospesi invece di una tabella.

   Adesso il filetto va da un bordo all'altro del riquadro, come fa quello che
   separa le due metà del pannello. Il respiro che il testo perde ai lati glielo
   restituisce l'imbottitura della riga, quindi la scritta non si sposta. */
.det-box { --boxpad: clamp(20px, 2vw, 28px); padding: var(--boxpad); }
.det-box .strengths {
  margin-inline: calc(var(--boxpad) * -1);
}
.det-box .strengths li { padding: 12px var(--boxpad); }

/* -- 8. I cinque dati dell'immobile, sul telefono -----------------------------
   `.key` è una griglia di due colonne dichiarate `auto auto`: il disegno e il
   testo, ciascuna larga quanto il suo contenuto. Finché le cinque schede
   stanno in fila, la cella è larga quanto serve e le due colonne si toccano.
   Dal round 35 ogni scheda prende tutta la riga sul telefono — e lo spazio che
   avanza, in una griglia con due colonne `auto`, si divide **in parti uguali
   fra le due**: metà andava al disegno, che è largo 20 px. Risultato: l'icona
   a sinistra e la cifra che cominciava a metà schermo, con l'etichetta sotto.

   La seconda colonna prende tutto lo spazio che avanza e il testo torna
   attaccato al suo disegno. */
@media (max-width: 620px) {
  .keyrow > .key { grid-template-columns: auto minmax(0, 1fr); justify-items: start; }
  .keyrow > .key > * { text-align: left; }
}

/* -- 9. Le fotografie della scheda immobile, sul telefono ---------------------
   La galleria è un contenitore flessibile che sul desktop deve stare alto
   quanto la colonna del modulo che le sta accanto: da lì `flex: 1`,
   `min-height: 0` e le altezze al 100 % sulla fotografia grande. Sul telefono
   quella colonna non esiste più — scende sotto — e quelle tre regole restano
   in piedi senza avere più niente a cui riferirsi: la fotografia di apertura
   può ridursi a un filo e sparire.

   Sul telefono la galleria smette di essere un contenitore flessibile e torna
   a essere quello che si vede: una fotografia 3:2 a piena larghezza e sotto le
   tre miniature del round 34. */
@media (max-width: 980px) {
  .det-gallery { display: block; }
  .det-gallery > .gal { flex: none; min-height: 0; }
  .det-gallery .gal-main { height: auto; aspect-ratio: 3 / 2; }
  .det-gallery .gal-main img, .det-gallery .gal-tile img {
    position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  }
}

/* -- 10. «Trattativa conclusa» ------------------------------------------------
   Il riquadro dell'immobile venduto, sul telefono, era una colonna di servizio
   del desktop rimasta com'era: testo centrato su misura da colonna stretta,
   i due pulsanti appoggiati al fondo con `margin-top: auto` — che in un
   riquadro alto quanto il suo contenuto non spinge niente, ma se il riquadro
   cresce apre un vuoto — e nessun respiro fra la fine del testo e il primo
   pulsante.

   Sul telefono diventa un annuncio a tutta larghezza: stessi passi della scala
   (16 · 24 · 32) fra titolo, testo e pulsanti. */
@media (max-width: 980px) {
  .det-aside .det-card-closed { padding: clamp(24px, 6vw, 34px); }
  .det-card .det-closed-actions { gap: 14px; }
  .det-card-closed .det-closed-flag { margin-bottom: 16px; }
  .det-card-closed .det-aside-sub { margin: 16px 0 0; }
}

/* -- 11. «Invia il messaggio»: i vuoti del modulo sul telefono ----------------
   Il modulo è una griglia. Una griglia con righe automatiche, se il suo
   contenitore è più alto del contenuto, allunga le righe per riempirlo — è il
   valore normale di `align-content`, e basta un riquadro alto perché i campi
   si allontanino fra loro senza che nessuno l'abbia chiesto. `start` dice alla
   griglia di stare in cima e di lasciare il vuoto dov'è: in fondo.

   La riga di chiusura, sul telefono, non ha più due estremi da separare —
   spunta e pulsante stanno uno sotto l'altro — quindi lo spazio fra loro è
   quello dichiarato e basta, e il pulsante prende tutta la larghezza come ogni
   altro pulsante di invio del sito. */
.form { align-content: start; }
@media (max-width: 620px) {
  .form { gap: 20px; }
  .form-foot { justify-content: flex-start; gap: 18px; }
  .form-foot .consent { flex: none; max-width: none; align-items: flex-start; }
  .form-foot .form-send { width: 100%; justify-content: center; }
}

/* ================================================================================
   ROUND 37 — l'intro, e tre allineamenti
   ================================================================================
   I tempi dell'intro non stanno qui: stanno dove stavano, in cima al foglio,
   perché una sequenza scritta in due punti diventa impossibile da leggere. Qui
   ci sono i tre allineamenti. */

/* -- 1. La testata della scheda immobile ---------------------------------------
   «posiziona meglio il blocco salva immobile + condividi + rif, rendilo un po'
   più centrale e in linea».

   Erano due disallineamenti, uno per direzione.

   In verticale la colonna dei comandi era appesa in alto (`flex-start`), a
   fianco di un titolo che può essere di una o di due righe: con due righe il
   blocco restava sospeso in cima e sotto gli si apriva un vuoto lungo quanto
   il prezzo. Adesso la colonna si centra sull'altezza del titolo, quindi sta
   ferma dove sta il baricentro della testata qualunque sia la lunghezza del
   nome dell'immobile.

   In orizzontale il riferimento era l'unica riga senza disegno davanti, quindi
   cominciava 28 px più a sinistra delle tre scritte sopra di lui — la larghezza
   dell'icona più il suo spazio. Ora è rientrato esattamente di quei 28 px e i
   quattro testi partono dalla stessa colonna. Il filetto sopra lo lega ai tre
   comandi invece di lasciarlo cadere lì sotto: è largo quanto il blocco, non
   quanto la scritta, perché un filetto che finisce prima sembra rotto — è la
   stessa regola dei punti di forza al round 36. */
.det-head { align-items: center; }
.det-actions { gap: 16px; }

/* -- 2. «Più recenti» in linea con Griglia e Mappa ------------------------------
   Sul telefono la barra dei risultati diventava una colonna di tre righe: il
   conteggio, i due pulsanti spinti a destra e la tendina a sinistra, sfalsati
   fra loro. Sono tre comandi della stessa riga e devono stare su una riga.

   Il conteggio si prende la prima riga per sé — è una frase, non un comando —
   e i tre controlli scendono sulla seconda, allineati sulla stessa base e alti
   uguali. La tendina prende lo spazio che avanza; se non ce n'è abbastanza
   (schermi da 320 px) va a capo da sola invece di sfondare, che è il
   comportamento normale di una riga flessibile e l'unica uscita onesta.

   La misura: due pulsanti da 99 e 84 px più la tendina, su 350 di riga utile a
   390 px di schermo. Ci sta perché ai pulsanti si stringe l'imbottitura e la
   tracciatura, non il corpo — restano leggibili, occupano meno. */
@media (max-width: 620px) {
  .results-bar {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: stretch;
    gap: 10px;
  }
  .results-n { flex: 1 0 100%; align-self: center; }
  .results-bar .viewbar { margin-left: 0; flex: none; }
  .viewbtn { padding: 12px 12px; gap: 7px; letter-spacing: 0.12em; }
  .sortbar { flex: 1 1 130px; min-width: 0; margin-left: auto; }
  .sortbar .sel { min-width: 0; flex: 1; }
  /* La tendina dell'ordinamento non è un campo in cui si scrive: non fa
     ingrandire la pagina, quindi non ha bisogno dei 16 px del round 35, e a
     16 px non starebbe in riga con i due pulsanti accanto. Torna alla misura
     dei comandi che le stanno a fianco. */
  .sortbar .sel .sel-btn { font-size: 0.62rem; letter-spacing: var(--track-btn);
    text-transform: uppercase; padding: 12px 12px; }
}

/* -- 3. Il prezzo del filtro, scritto con i punti --------------------------------
   «quando un utente scrive il prezzo nel filtro metti automaticamente i punti
   delimitanti delle migliaia per aiutare la digitazione».

   La formattazione la fa site.js mentre si scrive; qui c'è solo la misura del
   campo, che con i punti diventa più lungo di due caratteri ogni milione, e le
   cifre incolonnate — le stesse del prezzo, dal round 36, perché è lo stesso
   numero scritto due volte sulla stessa pagina. */
.fbar-num {
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
}

/* ================================================================================
   ROUND 38 — la mappa del catalogo, e il riferimento al suo posto
   ================================================================================ */

/* -- 1. Il riferimento torna nella colonna dei dati -----------------------------
   «metti il rif sotto al prezzo e abbassa il blocco salva + condividi +
   stampa».

   Il riferimento stava in fondo alla colonna dei comandi, dove faceva da coda a
   tre pulsanti con cui non ha niente in comune — ed era l'unica riga senza
   disegno davanti, quindi disallineata per costruzione. È un dato
   dell'immobile, come il luogo, il nome e il prezzo: sta sotto il prezzo, nella
   colonna dei dati, e il filetto che al round 37 gli avevo messo sopra non
   serve più — lì sotto non deve legarsi a niente, deve solo chiudere l'elenco.

   I comandi scendono: la colonna si appoggia al fondo della testata invece di
   centrarsi, così l'ultimo di loro chiude alla stessa quota del prezzo. */
.det-head { align-items: flex-end; }
.det-ref {
  align-self: auto;
  margin-top: 14px;
  padding: 0;
  border-top: 0;
}
.det-actions { padding-bottom: 4px; }
@media (max-width: 780px) {
  /* Quando la testata va a capo, «in fondo» non vuol dire più niente: le due
     parti tornano una sotto l'altra, allineate a sinistra. */
  .det-head { align-items: flex-start; }
  .det-actions { padding-bottom: 0; }
}

/* -- 2. Il riquadro della mappa, in grande -------------------------------------
   «la grafica della mappa deve essere la solita usata anche nella scheda
   immobile»: infatti è la stessa classe, `.map-frame`, quindi le stesse
   tessere, lo stesso filtro di colore che le porta verso l'avorio della pagina
   e gli stessi due pulsanti dello zoom. Qui cambia solo l'altezza — là la mappa
   è un dettaglio della scheda, qui è la pagina. */
.map-frame-lg {
  height: clamp(420px, 62vh, 660px);
  border: 1px solid var(--line);
}
.map-frame-lg .leaflet-container { background: var(--ivory); }

/* L'apertura fotografica di questa pagina è più bassa delle altre: sotto c'è
   la barra dei filtri e poi subito la mappa, e tre fasce alte una sopra
   l'altra spingerebbero la mappa — che è il motivo per cui si è qui — sotto il
   bordo dello schermo. */
.phero-short { min-height: calc(var(--hdh) + clamp(220px, 22vw, 320px)); }

/* -- 3. I due comandi del disegno ----------------------------------------------
   Stanno sopra la mappa, in alto a sinistra, dove Leaflet non mette niente: lo
   zoom è in basso a destra e l'attribuzione in basso. Sono i pulsanti del
   sito — carta bianca, filetto, maiuscoletto tracciato — non quelli di una
   libreria di disegno con la sua grafica. */
.map-tools {
  position: absolute;
  z-index: 500;
  top: 14px; left: 14px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.map-tool {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 11px 16px;
  border: 1px solid var(--ink-14);
  background: var(--white);
  font-family: var(--sans);
  font-size: 0.6rem;
  font-weight: 400;
  letter-spacing: var(--track-btn);
  text-transform: uppercase;
  color: var(--ink);
  cursor: pointer;
  box-shadow: 0 10px 26px -20px rgba(9, 18, 35, 0.55);
  transition: color 0.35s ease, background 0.35s ease, border-color 0.35s ease;
}
.map-tool svg { flex: none; }
.map-tool:hover { border-color: var(--ink); }
/* Acceso: il pulsante diventa il fondo scuro del sito, come ogni stato attivo
   di questa interfaccia. */
.map-tool.is-on { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.map-tool-quiet { color: var(--ink-46); letter-spacing: 0.14em; }
.map-tool-quiet:hover { color: var(--ink); }

/* L'istruzione compare solo mentre si disegna, e dice due cose diverse a
   seconda che ci sia un dito o un mouse: sono due gesti diversi, non lo stesso
   gesto con due nomi. */
.map-hint {
  position: absolute;
  z-index: 500;
  left: 14px; right: 14px; bottom: 14px;
  max-width: 520px;
  padding: 12px 16px;
  background: rgba(16, 30, 54, 0.9);
  color: var(--paper);
  font-family: var(--sans);
  font-size: 0.72rem;
  line-height: 1.5;
}
/* Mentre si disegna il puntatore dice che la mappa è un foglio, non una
   carta da trascinare. */
.map-frame.is-drawing .leaflet-container { cursor: crosshair; }
/* E il tocco non deve far scorrere la pagina sotto il dito che sta tracciando:
   `touch-action` è l'unica cosa che lo impedisce davvero, perché lo scorrimento
   del browser non passa dagli eventi che JavaScript può fermare. */
.map-frame.is-drawing .map-canvas { touch-action: none; }

/* -- 4. La scheda che si apre da un segnaposto ---------------------------------
   È la card del catalogo, in piccolo: fotografia, luogo, nome, prezzo. Leaflet
   disegna il suo fumetto con angoli tondi e un'ombra da libreria: qui è un
   rettangolo bianco con un filetto, come ogni altra scheda del sito. */
.map-pop-wrap .leaflet-popup-content-wrapper {
  border-radius: 0;
  padding: 0;
  border: 1px solid var(--line);
  box-shadow: 0 22px 50px -30px rgba(9, 18, 35, 0.6);
}
.map-pop-wrap .leaflet-popup-content { margin: 0; width: 240px !important; }
.map-pop-wrap .leaflet-popup-tip { display: none; }
.map-pop { display: block; color: inherit; }
.map-pop-ph { display: block; aspect-ratio: 3 / 2; overflow: hidden; background: var(--ivory); }
.map-pop-ph img { width: 100%; height: 100%; object-fit: cover; }
.map-pop-txt { display: block; padding: 14px 16px 16px; }
.map-pop-zone {
  display: block;
  font-family: var(--sans);
  font-size: 0.58rem;
  font-weight: 400;
  letter-spacing: var(--track-btn);
  text-transform: uppercase;
  color: var(--ink-46);
}
.map-pop-title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  margin-top: 7px;
  font-family: var(--serif);
  font-size: 1rem;
  line-height: 1.3;
  color: var(--ink);
}
/* Le cifre sono quelle del round 36: grottesco, incolonnate. */
.map-pop-price {
  display: block;
  margin-top: 7px;
  font-family: var(--sans);
  font-size: 0.9rem;
  font-weight: 400;
  font-variant-numeric: tabular-nums lining-nums;
  color: var(--ink);
}

/* Il segnaposto di un immobile già concluso è più quieto: sta sulla mappa come
   prova del lavoro fatto, non come offerta. */
.map-pin-closed .map-pin-halo { opacity: 0.35; }

/* La nota che prende il posto della mappa quando non c'è niente da mostrare, o
   quando Leaflet non si carica: un blocco di prosa, non un riquadro vuoto. */
.map-note-alone {
  max-width: 620px;
  font-size: 0.95rem;
  line-height: 1.8;
  color: var(--ink-70);
}
#map-empty-area { margin-top: 18px; }

/* -- 5. Sul telefono ------------------------------------------------------------
   La mappa si prende quasi tutta l'altezza dello schermo — è la pagina — e i
   comandi del disegno scendono di misura per non coprire il primo segnaposto. */
@media (max-width: 620px) {
  .map-frame-lg { height: clamp(380px, 66svh, 560px); }
  .map-tools { top: 10px; left: 10px; right: 10px; }
  .map-tool { padding: 11px 13px; letter-spacing: 0.12em; }
  .map-hint { left: 10px; right: 10px; bottom: 10px; font-size: 0.7rem; }
  .map-pop-wrap .leaflet-popup-content { width: 210px !important; }
}

/* ================================================================================
   ROUND 39 — la fine dell'intro, il lockup, e la scheda «trattativa conclusa»
   ================================================================================
   Le prime due correzioni non stanno qui: stanno in cima al foglio, dove
   stanno l'intro e il suo marchio. Spostarle in fondo avrebbe voluto dire
   scrivere la sequenza in due punti, che è il modo di renderla illeggibile.
   Qui c'è la terza. */

/* -- La scritta della scheda di un immobile concluso ----------------------------
   «correggi l'impaginazione della scritta nella scheda trattativa conclusa».

   Il testo è centrato — la scheda è un annuncio, non un modulo, ed è la
   decisione del round 30 — ma centrato non vuol dire impaginato. Erano quattro
   righe di lunghezze qualunque, con l'ultima quasi piena e la terza corta, e
   un blocco centrato con le righe sbilanciate si legge come un sasso.

   Tre cose, tutte sulla stessa riga di ragionamento:

   * `text-wrap: balance` chiede al browser di dividere il testo in righe di
     lunghezza simile invece di riempire ogni riga fino all'orlo. È fatto
     apposta per i blocchi corti e centrati; i browser che non lo conoscono
     ignorano la riga e impaginano come prima.
   * una misura massima. Un testo centrato lungo più di una cinquantina di
     caratteri per riga costringe l'occhio a ritrovare l'inizio della riga
     successiva ogni volta, perché l'inizio non sta mai nello stesso punto.
   * l'interlinea del testo di lettura, non quella stretta della colonna di
     servizio: qui non è più un modulo da far stare dentro l'altezza di una
     fotografia, è un annuncio da leggere. */
.det-card-closed .det-aside-sub {
  max-width: 46ch;
  margin-inline: auto;
  font-size: 0.88rem;
  line-height: 1.75;
  text-wrap: balance;
  color: var(--ink-70);
}
/* Il titolo prende lo stesso trattamento: «Trattativa conclusa» sta su una
   riga sola, ma il giorno in cui una delle tre lingue lo manda a capo deve
   spezzarsi in due righe pari e non in una lunga e una di due parole. */
.det-card-closed .ttl-2 { text-wrap: balance; }
/* Lo stacco fra la scritta e i due pulsanti diventa un passo della scala del
   marchio — ma solo da dove la scheda smette di stare accanto alla fotografia.
   Sopra i 1240 px i due pulsanti restano appoggiati al fondo: è la richiesta 8
   del round 31 («più ordinati e più centrali»), ed è quello che fa chiudere la
   colonna alla stessa quota della fotografia. Sotto, la fotografia è sopra e
   non c'è più niente a cui pareggiare: il vuoto in fondo sarebbe solo vuoto. */
@media (max-width: 1240px) {
  .det-card .det-closed-actions { margin-top: clamp(28px, 3.4vw, 40px); }
}

/* ---- Round-40: la valutazione, comune per comune -----------------------------
   Il blocco che sta sulle pagine di zona. Ogni comune è una domanda con la sua
   risposta: la stessa forma delle domande frequenti poco più in basso nella
   pagina, e non una griglia di riquadri, perché è testo da leggere — è la
   risposta a «quanto vale casa a Laives», non una scheda prodotto.

   Il filetto separa e basta: venticinque blocchi in cornice sarebbero un
   catalogo, e questa pagina non ne ha bisogno. L'ultimo non porta filetto,
   come nelle FAQ, perché sotto ricomincia una sezione. */
.comuni { margin-top: clamp(28px, 3.2vw, 40px); }
.comune {
  padding: clamp(22px, 2.6vw, 30px) 0;
  background-image: var(--rule);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% 1px;
  /* Un'ancora che finisce sotto la testata fissa manda il lettore a metà del
     paragrafo: chi arriva da Google su #valutazione-laives deve vedere il
     titolo del comune, non la riga dopo. */
  scroll-margin-top: calc(var(--hdh) + 24px);
}
.comune:last-child { background-image: none; }
.comune-h {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.05rem, 1.6vw, 1.28rem);
  letter-spacing: 0.01em;
  line-height: 1.35;
}
.comune p { margin-top: 12px; color: var(--ink-70); max-width: 62ch; }
.comune-cta { margin-top: 14px; }

/* La riga che compare quando si arriva da «Valutazione gratuita a Merano»: dice
   che cosa il modulo ha già capito, in modo che nessuno lo compili due volte. */
.vform-prefill {
  font-family: var(--sans);
  font-size: 0.82rem;
  line-height: 1.55;
  color: var(--paper);
  opacity: 0.78;
  margin-bottom: 18px;
  max-width: 52ch;
}

@media (max-width: 860px) {
  .comune-h { font-size: clamp(1rem, 1.4vw, 1.15rem); }
  .comune p { font-size: 0.95rem; line-height: 1.6; margin-top: 8px; }
}

/* ---- Round-44 — la biblioteca del venditore ------------------------------
   /vendere-casa/ e le dieci guide. Tre componenti nuovi e nessuna regola
   esistente toccata: le classi qui sotto non compaiono altrove nel foglio,
   quindi non c'è nulla che possa essere ridefinito più in basso (il difetto
   del round-39).

   Il carattere, i colori e i ritmi sono quelli della scheda di brand: nessun
   valore nuovo, solo composizioni nuove di variabili che esistono già.        */

/* Gli otto passi dell'hub. Numerati con un contatore CSS invece che con un
   <span>: il numero è decorazione tipografica e non deve finire nel testo che
   un lettore di schermo — o un motore di ricerca — estrae dal titolo.         */
.sq { list-style: none; counter-reset: sq; }
.sq-i {
  counter-increment: sq;
  position: relative;
  padding: clamp(22px, 2.6vw, 30px) 0;
  background-image: var(--rule);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% 1px;
  /* L'ancora /vendere-casa/#passo-3 deve fermarsi sopra il titolo del passo,
     non sotto la testata fissa. */
  scroll-margin-top: calc(var(--hdh) + 24px);
}
.sq-i:last-child { background-image: none; }
.sq-h {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.15rem, 1.9vw, 1.45rem);
  letter-spacing: 0.01em;
  line-height: 1.3;
  color: var(--ink);
  margin-bottom: 14px;
}
.sq-i p { color: var(--ink-70); max-width: 64ch; }
.sq-i p + p { margin-top: 18px; }

/* Le schede delle guide. Due colonne di riquadri leggeri; l'intera scheda è il
   collegamento, così l'area cliccabile su un telefono è tutta la scheda e non
   una riga di testo alta diciotto pixel.                                      */
.gdx {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(14px, 1.6vw, 22px);
  margin-top: clamp(26px, 3.2vw, 38px);
}
.gdx-i {
  position: relative;
  display: block;
  padding: clamp(20px, 2.2vw, 28px);
  padding-right: clamp(40px, 4vw, 56px);
  background: var(--white);
  border: 1px solid var(--line);
  color: inherit;
  transition: border-color 0.4s ease, transform 0.5s var(--ease);
}
.gdx-i:hover { border-color: var(--ink-14); transform: translateY(-2px); }
.gdx-h {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1rem, 1.5vw, 1.18rem);
  letter-spacing: 0.01em;
  line-height: 1.35;
  color: var(--ink);
}
.gdx-p {
  margin-top: 10px;
  font-size: 0.86rem;
  line-height: 1.75;
  color: var(--ink-46);
  /* Tre righe e poi si ferma: le introduzioni delle dieci guide hanno lunghezze
     diverse e senza questo le schede della griglia si allineano male. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.gdx-a {
  position: absolute;
  right: clamp(18px, 2vw, 24px);
  top: clamp(20px, 2.2vw, 28px);
  color: var(--ink-46);
  transform: translateX(-6px);
  opacity: 0.4;
  transition: transform 0.5s var(--ease), opacity 0.4s ease, color 0.4s ease;
}
.gdx-i:hover .gdx-a { transform: translateX(0); opacity: 1; color: var(--ink); }
/* L'elenco completo dell'hub: dieci schede stanno meglio su tre colonne. */
.gdx-wide { grid-template-columns: repeat(3, minmax(0, 1fr)); }

/* Il corpo di una guida. Il titolo di sezione ha bisogno di più aria sopra che
   sotto, altrimenti dentro .prose si appoggia al paragrafo precedente.        */
.gd-h2 { margin-top: clamp(38px, 4.4vw, 58px); }
.prose > .gd-h2:first-child { margin-top: 0; }

/* «In breve»: l'elenco puntato che riassume la guida. Il segno è un trattino
   composto, non un pallino: la scheda di brand non usa i pallini da nessuna
   parte.                                                                      */
.gd-check { list-style: none; margin-top: clamp(20px, 2.4vw, 28px); }
.gd-check li {
  position: relative;
  padding: 12px 0 12px 26px;
  color: var(--ink-70);
  background-image: var(--rule);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% 1px;
  max-width: 66ch;
}
.gd-check li:last-child { background-image: none; }
.gd-check li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 1.35em;
  width: 12px;
  height: 1px;
  background: var(--ink-46);
}

/* Le fonti ufficiali. Sottolineate sempre, non solo al passaggio del mouse:
   sono collegamenti che escono dal sito e chi legge deve vederlo.             */
.gd-src { list-style: none; margin-top: clamp(18px, 2.2vw, 26px); }
.gd-src li { padding: 9px 0; }
.gd-src a {
  font-family: var(--sans);
  font-size: 0.88rem;
  line-height: 1.6;
  color: var(--ink-70);
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-color: var(--ink-14);
  transition: color 0.35s ease, text-decoration-color 0.35s ease;
}
.gd-src a:hover { color: var(--ink); text-decoration-color: var(--ink-46); }

/* La riga fissa in fondo a ogni guida: informazione generale, non consulenza. */
.gd-note {
  margin-top: clamp(22px, 2.6vw, 30px);
  font-size: 0.8rem;
  line-height: 1.75;
  color: var(--ink-46);
  max-width: 74ch;
}

/* Selettore doppio, non per vezzo: `.endcta p` esiste già e vale più di una
   classe sola, quindi senza `.endcta` davanti questa riga verrebbe stampata
   nel serif grande della chiusura e farebbe concorrenza al titolo che ha
   sopra. */
.endcta .gd-cta-p {
  margin-top: 18px;
  font-family: var(--prose);
  font-size: 0.9rem;
  line-height: 1.75;
  color: var(--ink-70);
  max-width: 56ch;
  margin-left: auto;
  margin-right: auto;
}

@media (max-width: 1120px) {
  .gdx-wide { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 780px) {
  .gdx, .gdx-wide { grid-template-columns: minmax(0, 1fr); }
  .gdx-p { -webkit-line-clamp: 4; }
  .sq-h { font-size: clamp(1.08rem, 1.6vw, 1.28rem); }
  .sq-i p { font-size: 0.95rem; line-height: 1.65; }
}

/* ---- Round-44 — la testata con cinque voci --------------------------------
   Aggiunta «Vendere casa» al menu, la barra andava a capo fra i 981 e i
   1120 px: due righe di menu sopra il marchio, su una larghezza da portatile.

   La causa non era la mancanza di spazio — a 1024 px il menu naturale misura
   665 px e ne ha 717 a disposizione — ma il fatto che `.hd-in` è un flex e il
   menu, potendo restringersi, si restringeva sotto la propria larghezza e
   mandava a capo l'ultima voce. `flex: 0 0 auto` gli dice di tenere la propria
   misura; il resto è aria che c'era già.

   Misurato con Chromium a 1600, 1440, 1366, 1280, 1200, 1120, 1060, 1024,
   1000 e 985 px nelle tre lingue: una riga sola ovunque, almeno 24 px liberi
   sia verso il marchio sia verso il selettore di lingua, nessuno scorrimento
   orizzontale. Sotto i 980 px comanda il menu a tendina e questo blocco non
   si applica.                                                                */
@media (min-width: 981px) {
  .hd-nav { flex: 0 0 auto; flex-wrap: nowrap; }
  /* Round-46 — e il marchio nemmeno.
     La riga qui sopra ha risolto il menu e rotto il logo, ed è un difetto che
     vale la pena raccontare per esteso perché è tipico dei flex. `.hd-in` è un
     flex con tre figli: marchio, menu, strumenti. Rendendo rigido il menu, il
     compito di restringersi è passato tutto all'unico figlio rimasto elastico
     — il marchio. Il disegno del marchio è un <img> con `height: 21px` e
     `width: auto`, ma la regola generale `img { max-width: 100% }` lo obbliga a
     stare dentro la scatola che si stringe: l'altezza resta 21 px, la larghezza
     no, e la parola ELISON si schiaccia.

     Misurato con Chromium sulla home: a 1060 px il marchio usciva 128 px
     invece di 160 (**-19,5%** di rapporto), a 1000 px 111 px (**-30,7%**).
     Sopra i 1150 px non si vedeva, ed è il motivo per cui a schermo intero
     sembrava tutto a posto. Con queste due righe il rapporto reso è 7,598
     contro un naturale di 7,599 a ogni larghezza fra 985 e 1600 px. */
  .hd-brand { flex: 0 0 auto; }
  .hd-brand img { max-width: none; }
}
@media (min-width: 981px) and (max-width: 1240px) {
  .hd-nav { gap: clamp(16px, 1.9vw, 26px); }
  .hd-nav a.hd-cta { padding-inline: 22px; }
}
/* Il menu a tendina ha adesso sei voci: la sesta entrava senza ritardo, cioè
   in anticipo su tutte le altre. */
@media (max-width: 980px) {
  body.nav-open .hd-nav a:nth-child(6) { transition-delay: 0.6s; }
}

/* ================================================================================
   ROUND 47 — la spina dorsale delle pagine documento, l'apertura del telefono,
   l'indice delle guide e il marchio nella scheda del browser
   ================================================================================ */

/* -- 1. Una pagina, un margine sinistro ----------------------------------------
   Sulle guide, sull'hub «vendere casa», sulle pagine di zona e sulle
   informative il titolo stava dentro `.shell-w` (1360 px) e il corpo dentro
   `.shell` (760 px). Sono due contenitori centrati di larghezza diversa, quindi
   **due margini sinistri diversi nella stessa pagina**: su /vendere-casa/
   documenti… l'h1 attaccava a 126 px e il primo paragrafo a 425. Fra una
   sezione e l'altra la pagina si spostava di trecento pixel a destra e a
   sinistra, ed è la ragione per cui quelle pagine sembravano montate e non
   composte.

   La correzione non tocca nessuna delle due classi: le porta alla stessa
   misura **solo** dentro `body.page-doc`, che base.html assegna alle pagine di
   testo lungo. Il peso è di due classi, quindi vince sulla dichiarazione
   generale a una classe qualunque sia l'ordine — la lezione del round 26.

   1180 e non 1360: una pagina che si legge riga per riga non vuole la larghezza
   di una vetrina. La misura di lettura resta quella giusta perché la limita
   `.prose` qui sotto, non il contenitore.                                       */
body.page-doc { --shell-doc: 1180px; }
/* `main` non è un vezzo: la testata e il piede usano `.shell-w` anche loro e
   devono restare larghi 1360 su tutto il sito. Senza questa parola il piede
   di una guida sarebbe più stretto del piede della home — cioè si sarebbe
   corretta l'incoerenza dentro la pagina creandone una fra le pagine. */
body.page-doc main .shell,
body.page-doc main .shell-w { max-width: var(--shell-doc); }

/* La colonna di lettura.

   Attenzione al peso, che qui è tutto: `.shell` dentro `body.page-doc` vale due
   classi, quindi una regola scritta `.prose { max-width: … }` — una classe sola
   — perderebbe e il testo resterebbe largo 1036 px. È la lezione del round 26,
   ed è il modo in cui questa correzione poteva sembrare fatta e non esserlo.

   Non si stringe il **contenitore**, si stringono i suoi figli: se stringessi
   il contenitore, essendo centrato, il testo tornerebbe a un margine sinistro
   diverso da quello del titolo e il difetto ricomparirebbe da un'altra porta.

   La larghezza è `--measure`, dichiarata una volta sola in :root: dal round 48
   vale 510 px, cioè 74 caratteri di Arimo a 15,2 px contati sul testo vero
   delle guide. Il numero sta lì e non qui perché è lo stesso per il corpo di
   una guida, per il sommario di un'apertura e per la descrizione di un
   immobile — una riga sola in tutto il sito. Quello che questa regola
   aggiunge è dove applicarla, e con che peso di selettore. */
body.page-doc main .shell.prose > *,
body.page-doc main .shell > .faq,
body.page-doc main .shell > .gd-note { max-width: var(--measure); }

/* Il titolo e il sommario dell'apertura vivono nella stessa colonna del testo:
   con la spina dorsale a posto, `.phead-long` a 900 px lascerebbe l'h1 più
   largo del documento che introduce. */
body.page-doc .phead-long { max-width: 820px; }
body.page-doc .phead .lede { max-width: var(--measure); }
/* La chiusura resta un blocco centrato, non una riga larga quanto la pagina. */
body.page-doc .endcta { max-width: 760px; margin-inline: auto; }

/* Le griglie di schede, contate sui pezzi che ci vanno dentro e non sul nome
   della classe:

   `.gdx`      — in fondo a una guida ce ne sono **tre** («continua con»), e
                 tre schede su due colonne lasciano la terza sola sotto le
                 altre due. Tre colonne.
   `.gdx-wide` — sull'hub ce ne sono **dieci**, e dieci su tre colonne lasciano
                 di nuovo l'ultima sola. Due colonne, cinque righe piene, e i
                 titoli — che sono frasi intere — hanno il doppio dello spazio. */
body.page-doc .gdx { grid-template-columns: repeat(3, minmax(0, 1fr)); }
body.page-doc .gdx-wide { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 900px) {
  body.page-doc .gdx { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  body.page-doc .gdx,
  body.page-doc .gdx-wide { grid-template-columns: minmax(0, 1fr); }
}

/* -- 2. L'indice in cima a ogni guida ------------------------------------------
   Numerato, con il numero nel margine: il numero è tipografia, il titolo è il
   collegamento. Su uno schermo largo va su due colonne, perché una colonna di
   nove righe alta quanto mezzo schermo si legge come un menu e non come un
   sommario.                                                                     */
.gd-toc {
  /* Alla stessa misura del titolo che sta sopra: la pagina ha due larghezze —
     820 per il titolo e il sommario, 580 per la riga di lettura — e non tre. */
  max-width: 820px;
  margin-top: clamp(6px, 1vw, 14px);
  padding: clamp(24px, 2.6vw, 32px) clamp(24px, 2.6vw, 34px);
  border: 1px solid var(--line);
  background: var(--white);
}
.gd-toc-t { margin-bottom: 18px; color: var(--ink-46); }
.gd-toc-l {
  list-style: none;
  counter-reset: none;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2px clamp(24px, 3vw, 44px);
}
.gd-toc-l a {
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding: 9px 0;
  color: var(--ink-70);
  transition: color 0.35s ease;
}
.gd-toc-l a:hover { color: var(--ink); }
.gd-toc-n {
  flex: 0 0 auto;
  font-family: var(--sans);
  font-size: 0.62rem;
  font-weight: 400;
  letter-spacing: var(--track-label);
  color: var(--alpine);
  transition: color 0.35s ease;
}
.gd-toc-l a:hover .gd-toc-n { color: var(--ink-46); }
.gd-toc-h {
  font-size: 0.9rem;
  line-height: 1.55;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0 1px;
  transition: background-size 0.45s var(--ease);
}
.gd-toc-l a:hover .gd-toc-h { background-size: 100% 1px; }

/* Il titolo di sezione, raggiunto da un collegamento, deve fermarsi sotto la
   testata fissa e non dietro. */
.gd-h2 { scroll-margin-top: calc(var(--hdh) + 28px); }

/* Sul telefono l'indice va su una colonna sola: a due, un titolo di guida
   («Certificato energetico, condominio, mutuo») occupa quattro righe da tre
   parole e il sommario diventa più difficile da leggere dei titoli che
   riassume. */
@media (max-width: 720px) {
  .gd-toc-l { grid-template-columns: minmax(0, 1fr); }
  .gd-toc { padding: 22px 22px 24px; }
}

/* -- 3. Il rilievo dentro il testo ----------------------------------------------
   `**così**` diventa <strong>, e il round 45 gli ha dato 600 — il taglio più
   pesante che il sito carica davvero. Restava un difetto di colore: il
   paragrafo è scritto in `--ink-70` e la parola in rilievo lo era anche lei,
   quindi l'unica differenza era lo spessore. In una guida dove il rilievo
   ricorre ogni due righe, dieci parole più grasse dello stesso colore fanno
   una macchia. Con il blu notte pieno il rilievo si legge come «questa parola
   conta di più», che è quello che vuole dire, e la pagina resta pulita.        */
.prose strong, .sq-i strong, .gd-check strong { color: var(--ink); }

/* -- 4. L'apertura del telefono ------------------------------------------------
   Il round 46 alzava la fotografia orizzontale al 133% e la appoggiava in
   basso, per far uscire dal riquadro il cielo piatto in cima. Restavano 170 px
   di cielo e l'ingrandimento saliva a 1,87×. Adesso il telefono riceve una
   fotografia verticale sua (vedi home.html), quindi quella regola non serve più
   e va **disfatta**, non lasciata a combattere con l'immagine nuova.

   `object-position` a 88%: il file è inquadrato con la casa sul bordo destro e
   la valle a sinistra; su uno schermo da 390 px si vede il 70% della larghezza
   e la casa deve restarci tutta.                                               */
@media (max-width: 980px) {
  .hero .hero-ph img {
    position: absolute;
    inset: 0;
    left: 0;
    bottom: auto;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Round-49 — al centro. L'88% era tarato sul file precedente, che aveva la
       casa sul bordo destro; il taglio di adesso è già inquadrato (vedi
       tools/hero_phone_crop.py) e non ha niente da correggere. Fra l'altro non
       avrebbe più molto da spostare: il riquadro del telefono lascia 250 px di
       scorrimento su 1200, cioè un pollice di fotografia. */
    object-position: 88% 50%;
  }
}

/* -- 5. Le fasce delle pagine interne, sul telefono -----------------------------
   Le sei fotografie di apertura sono composte tutte allo stesso modo — il
   soggetto a destra, la valle in controluce a sinistra — perché sul desktop le
   parole stanno a sinistra. Su un telefono `cover` ritaglia una fascia da
   2,5:1 fino a 390 × 380 px e quello che resta è il **centro**: cioè la parte
   più mossa, e proprio sotto le parole, che lì occupano tutta la larghezza.

   Spostare l'inquadratura al 30% rimette sotto il testo la parte quieta per cui
   quelle fotografie erano state scelte. Misurato con la macchina del round 34
   sui file veri, contrasto mediano e peggior 2%:

     vendere casa   6,4→7,0 / 4,4→4,5     servizi        9,0→12,6 / 5,2→5,2
     immobili       9,3→11,6 / 4,3→4,4    contatti      14,0→14,7 / 4,7→4,9
     chi siamo      5,8→7,5 / 4,5→4,4     valutazione    7,7→9,1 / 4,3→4,5

   Una classe sola di proposito: l'apertura della home ha la sua regola a due
   classi (`.hero .hero-ph img`) e continua a vincere su questa, com'è giusto —
   lì la fotografia è già verticale e inquadrata apposta.                      */
@media (max-width: 980px) {
  .hero-ph img { object-position: 30% 50%; }
}

/* -- 6. La griglia sa quante schede ha ------------------------------------------
   Difetto trovato sul sito vero, non nei sorgenti: in catalogo c'è **un**
   immobile pubblicato, e la home lo mostrava in una griglia da tre colonne. Una
   scheda in alto a sinistra e due terzi di riga vuoti: la pagina non sembra una
   pagina con un immobile, sembra una pagina rotta. Sul catalogo, dove le
   colonne sono quattro, è peggio — e succede anche a una ricerca che
   restituisce due risultati, cioè tutti i giorni.

   La griglia riceve il numero di schede da chi le stampa (`data-n`) e cambia
   forma. Non c'è nessun caso speciale nel codice: c'è una griglia che si
   adatta al contenuto, che è quello che una griglia dovrebbe fare.

   Con una scheda sola non si "allarga la scheda": si cambia composizione. Una
   scheda larga quanto la pagina con la fotografia a 16:9 sarebbe una banda
   pubblicitaria; girata su un fianco — fotografia a sinistra, dati a destra,
   titolo e prezzo a misura maggiore — è una **scheda in evidenza**, che è
   esattamente quello che un immobile solo merita.                             */
/* Il numero di colonne scende soltanto: queste regole non devono mai **alzare**
   quelle che il telefono e il portatile hanno già ridotto. È il difetto che il
   test del round 34 ha preso al volo — `.cards.cards-4[data-n="3"]` pesa tre
   classi e batteva `.cards { grid-template-columns: 1fr }` della media query
   del telefono, cioè avrebbe messo tre colonne su uno schermo da 390 px.
   Quindi ogni riduzione vive dentro la larghezza in cui ha senso, e sotto i
   1120 px comandano le regole che c'erano già. */
.cards[data-n="1"] { grid-template-columns: minmax(0, 1fr); }
@media (min-width: 1121px) {
  .cards[data-n="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cards.cards-4[data-n="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 781px) {
  .cards[data-n="1"] .card { flex-direction: row; align-items: stretch; }
  .cards[data-n="1"] .card-ph {
    flex: 0 0 54%;
    /* In riga la fotografia non ha più una proporzione sua: prende l'altezza
       della colonna di testo accanto, che è quella che detta la scheda. */
    aspect-ratio: auto;
    min-height: 340px;
  }
  .cards[data-n="1"] .card-body {
    justify-content: center;
    padding: clamp(30px, 3.6vw, 52px);
  }
  .cards[data-n="1"] .card-zone { font-size: 0.66rem; }
  .cards[data-n="1"] .card-title {
    font-size: clamp(1.3rem, 2vw, 1.75rem);
    line-height: 1.24;
    margin-top: 14px;
    /* Le due righe riservate servono a incolonnare schede affiancate: qui non
       c'è nessuno accanto, e una riga vuota sotto un titolo corto si vede. */
    min-height: 0;
    -webkit-line-clamp: 3;
    line-clamp: 3;
  }
  .cards[data-n="1"] .card-price { font-size: 1.35rem; margin-top: 14px; }
  .cards[data-n="1"] .card-meta {
    margin-top: clamp(22px, 2.6vw, 34px);
    padding-top: clamp(18px, 2vw, 26px);
    gap: 8px clamp(20px, 2.4vw, 34px);
    background-image: var(--rule);
    background-repeat: no-repeat;
    background-position: 0 0;
    background-size: 100% 1px;
  }
  .cards[data-n="1"] .card-meta span { font-size: 0.76rem; }
}
/* Sotto i 780 px la griglia è già a una colonna per tutti: la scheda torna
   verticale da sola, senza che questo blocco debba disfare niente. */

/* -- 7. Il pulsante principale non può essere blu su blu ------------------------
   Difetto trovato sul sito vero: nella fascia di chiusura — quella che sta in
   fondo a chi siamo, servizi, valutazione, contatti e alle guide — i due
   pulsanti sono «Valuta il tuo immobile» e «Contattaci». Il primo è il
   principale e portava `background: var(--ink)` con `border-color: var(--ink)`
   **sopra un fondo blu notte**: un rettangolo un po' più scuro della fascia,
   senza bordo, che diventava un pulsante solo al passaggio del mouse. Accanto,
   il secondario col suo filetto chiaro si vedeva molto di più del principale.

   È lo stesso difetto del round 36 punto 1 («la scritta restava blu su blu»),
   in un altro posto: su un fondo scuro il principale si **inverte**, non si
   ripete. Avorio pieno, testo blu notte; al passaggio del mouse la campitura
   scorre al blu e il testo torna avorio, cioè il gesto di tutti gli altri
   pulsanti del sito, letto al contrario.

   Stesso ragionamento per l'unico altro pulsante di invio che vive su un
   pannello scuro: quello del modulo di valutazione, che è il gesto per cui
   quella pagina esiste e non può essere il più debole dei due che si vedono. */
.ctaband .btn-ink,
.vform-foot .btn-light {
  background: var(--paper);
  border-color: var(--paper);
  color: var(--ink);
}
.ctaband .btn-ink::before,
.vform-foot .btn-light::before { background: var(--ink); }
.ctaband .btn-ink:hover,
.vform-foot .btn-light:hover { color: var(--paper); border-color: var(--paper); }

/* -- 8. La scheda di un immobile: la riga di lettura e due margini sommati -----
   1. La descrizione era larga 820 px, cioè un centinaio di caratteri per riga:
      la stessa riga troppo lunga corretta sulle pagine documento, in un altro
      posto. 700 px sono 89 caratteri di Montserrat a 15,2 px — la riga resta
      più lunga di quella delle guide perché qui è giustificata e sillabata,
      cioè costruita per una misura ampia, ma smette di essere una tavola.

   2. «Immobili simili» aveva 66 px di vuoto fra l'etichetta e quello che la
      segue, e non erano voluti: sono due margini che si sommano senza sapere
      l'uno dell'altro — `.det-similar .tag` ne dichiara 34 e `.sim-head`, che
      contiene quel tag, altri 32. Lo spazio lo decide il contenitore; il tag
      dentro non ne aggiunge un secondo.                                       */
.det-desc { max-width: var(--measure); }
/* Round-49, seconda passata — con i capoversi veri lo stacco lo dà il margine
   e non più il ritorno a capo di `white-space: pre-line`, che resta dichiarato
   più su nel foglio e che su un capoverso senza «a capo» dentro non fa nulla.
   Mezza riga: quanto basta a dire «qui finisce una cosa e ne comincia
   un'altra» senza aprire un buco in mezzo alla colonna. */
.det-desc > p + p { margin-top: 0.55em; }
.sim-head .tag { margin-bottom: 0; }

/* -- 9. Sul telefono il modulo non viene prima del prezzo -----------------------
   Sulla scheda di un immobile il modulo «Richiedi informazioni» sta nella
   colonna di destra: sul desktop è accanto alla fotografia e si legge insieme
   a tutto il resto. Su un telefono le colonne diventano righe e l'ordine del
   documento va in scena così com'è — fotografia, **modulo**, e solo dopo il
   titolo, il prezzo e i metri quadri. Si chiedono nome, email e telefono a
   qualcuno che non sa ancora che cosa sta guardando.

   L'ordine giusto è quello di una visita: la fotografia, che immobile è,
   quanto costa, quant'è grande — e a quel punto il modulo, che è la domanda
   naturale dopo quelle risposte. Poi la descrizione e il resto.

   `display: contents` su `.det-top` scioglie la griglia a due colonne e
   consegna i suoi due figli direttamente alla colonna della pagina, che è
   l'unico modo perché `order` possa spostare il modulo **oltre** un elemento
   che non è suo fratello. Sotto i 780 px `.det-top` non è più una griglia in
   nessun caso, quindi non si perde niente.                                    */
@media (max-width: 780px) {
  .det > .shell-w { display: flex; flex-direction: column; }
  .det > .shell-w > * { order: 5; }
  .det > .shell-w > .crumbs { order: 0; }
  .det-top { display: contents; }
  .det-gallery { order: 1; }
  .det > .shell-w > .det-head { order: 2; }
  .det > .shell-w > .keyrow { order: 3; }
  .det-aside { order: 4; margin-top: clamp(22px, 4vw, 30px); }
}

/* ================================================================================
   ROUND 48 — due caratteri soli, un taglio solo
   ================================================================================
   Richiesta del cliente, sopra una prova stampata: «voglio che tutto il sito usi
   questi font — anche i numeri e i segni speciali. No corsivo, no grassetto,
   tutto uniforme».

   Le famiglie sono cambiate in `:root` (Tinos e Arimo, i disegni di Times New
   Roman e di Arial). Qui c'è quello che rende la richiesta **vera** invece che
   dichiarata: senza queste quattro regole il sito continuerebbe a stampare
   corsivi sintetici, grassetti finti e cifre di un'altra faccia in mezzo alle
   proprie.

   Le misure non si toccano. Il cliente ha approvato una pagina composta con
   queste due facce a **queste** misure: cambiare la scala adesso vorrebbe dire
   fargli approvare una cosa e pubblicarne un'altra. Times e Arial hanno le
   minuscole più alte del Cormorant e del Montserrat, quindi a parità di corpo
   leggono più grandi — ed è esattamente l'effetto che ha fatto scegliere questa
   prova.                                                                        */

/* -- 1. Nessun corsivo, in nessun posto ----------------------------------------
   Nel foglio non c'era un solo `font-style: italic`, e il difetto non era lì: è
   il browser che **inclina il carattere da solo** quando incontra <em>, <cite>,
   <address>, <i> o <blockquote>, che l'HTML mette in corsivo per impostazione
   predefinita. Un corsivo sintetico è il tondo storto: è la cosa che si vede di
   più in una pagina che vuole essere uniforme. */
em, i, cite, var, address, blockquote, q, dfn { font-style: normal; }
body { font-style: normal; }

/* -- 2. Nessun grassetto ---------------------------------------------------------
   `<strong>` senza regola vale 700, e il sito adesso scarica il solo 400: il
   browser lo fabbrica ingrossando il tondo, e si vede. Il rilievo dentro il
   testo — il filtro `emphasis` di site_extras.py, che ricorre ogni due righe
   nelle dieci guide e nelle pagine di zona — non sparisce: cambia strumento.
   Il paragrafo è scritto in blu acciaio, la parola in rilievo in blu notte
   pieno. Si legge «questa parola conta di più», che è quello che vuole dire,
   e la riga resta di un peso solo. Vale anche per i titoli del CRM e per
   qualunque <b> arrivi da un testo incollato. */
strong, b, th, h1, h2, h3, h4, h5, h6, optgroup, summary {
  font-weight: 400;
}
.prose strong, .sq-i strong, .gd-check strong, .area-copy strong { color: var(--ink); }

/* -- 3. Le cifre e i segni, nella stessa faccia delle parole ---------------------
   «anche i numeri e i segni speciali». Due cose separate, e servono tutte e due.

   La prima: le cifre di Tinos e Arimo sono **allineate** (tutte alte uguali,
   tutte appoggiate sulla riga di base) e non all'antica come quelle del
   Cormorant, dove il 5 e il 6 scendevano sotto la riga e l'1 sembrava una I.
   La dichiarazione qui sotto lo mette per iscritto invece di lasciarlo al
   valore predefinito della faccia, che una versione futura potrebbe cambiare.

   La seconda: € · — – « » “ ” ‰ ² m² ↑ → sono nel corredo di tutte e due le
   facce (Arimo ne mappa 2364), quindi non c'è nessun ripiego su un terzo
   carattere in mezzo a una riga. Era la cosa che si vedeva di più: un simbolo
   di euro di un'altra faccia accanto a una cifra. */
body { font-variant-numeric: lining-nums; }
/* Dove le cifre stanno una sotto l'altra o una accanto all'altra vanno anche
   incolonnate: stessa larghezza per ogni cifra, così due prezzi affiancati
   stanno in squadra. */
.card-price, .det-price, .key-n, .proof-n, .step, .step-n, .sq-h::before,
.gd-toc-n, .fbar-num, .pg-n, .cnt {
  font-variant-numeric: lining-nums tabular-nums;
}

/* -- 4. Il maiuscoletto, con un taglio solo -------------------------------------
   La scheda di brand chiedeva «Montserrat / Medium» per etichette e pulsanti, e
   il foglio lo scriveva con il peso 500. Con un taglio solo quel gradino non
   esiste più, e va rifatto con l'unico strumento che resta a un carattere di un
   peso solo: la **tracciatura**. Non è un ripiego — è come si distingue una
   maiuscola in tipografia da cinquecento anni, e le due costanti esistevano già
   (--track-label per le didascalie, --track-btn per ciò che si clicca). Restano
   quelle: qui si dichiara soltanto che il peso non le accompagna più. */
.tag, .hd-nav a, .btn, .lnk, .card-zone, .tri-cell h3, .det-box .tag,
.hd-brand .lock, .lang a { font-weight: 400; }

/* -- 5. Il selettore di lingua sopra la fotografia -------------------------------
   Trovato guardando /servizi/ e /chi-siamo/ a schermo intero: IT · DE · EN
   stanno all'estremo destro della testata, e lì il velo delle aperture è
   finito da un pezzo — si spegne all'88% della larghezza, di proposito, perché
   la fotografia deve restare intatta dove non ci sono parole. Solo che una
   parola c'è, ed è scritta in `--ink-46`.

   Misurato sul listello di legno dell'apertura dei servizi: il navy pieno
   regge **5,4:1**, `--ink-70` scende a 3,9:1 e `--ink-46` a **1,9:1**. Sotto
   due, "DE" e "EN" non si leggono: si indovinano.

   La correzione non aggiunge nessun pannello — la testata non è mai una barra,
   è una decisione del cliente del 14 agosto. Alza le due voci spente al colore
   di lettura del sito, che è quello che porta già il menù accanto, e lascia
   che a dire qual è la lingua attiva sia il filetto sotto, che c'era già.
   Fra l'altro è più uniforme, non meno: le voci del menù e quelle della lingua
   smettono di essere scritte in due colori diversi.                            */
.hd .lang a { color: var(--ink-70); }

/* ================================================================================
   ROUND 49 — le pagine che si fermavano a metà
   ================================================================================
   Sei segnalazioni del cliente, e cinque sono lo stesso difetto in cinque posti
   diversi: un blocco composto per una colonna stretta lasciato dentro una pagina
   larga il doppio. «Lascia mezza pagina vuota» è la frase che ricorre.

   La riga di lettura del sito (--measure, 510 px = 74 caratteri) non si tocca:
   è giusta, ed è quella che rende leggibili le guide. Quello che cambia è che
   cosa sta **accanto** a quella colonna, invece di lasciarci il vuoto.        */

/* -- 1. «Vedi tutte le foto» nell'angolo, come il contatore ---------------------
   Richiesta testuale: «il "vedi tutte le foto" deve essere nell'angolino come
   "1/4", con le stesse distanze e proporzioni dal bordo».

   Il round 31 l'aveva già tolto dal centro dell'ultima miniatura e appoggiato al
   piede, ma centrato in larghezza e con misure sue: 12 px dal fondo contro i 14
   del contatore, 10x16 di respiro interno contro 7x12, corpo 0,58 contro 0,62.
   Due pillole navy sulla stessa fotografia, di due misure diverse, in due
   allineamenti diversi.

   Adesso sono la stessa cosa scritta due volte: stesso angolo (in basso a
   sinistra del proprio riquadro), stesse distanze dal bordo, stesso respiro
   interno, stesso corpo, stessa campitura. Sul desktop finiscono sulla stessa
   linea di base, perché le due colonne della galleria si chiudono alla stessa
   altezza.

   Il peso: il blocco del round 30 scrive `.gal-all { position: absolute; left:
   50% … }` e vale una classe, come questa — vince chi è scritta dopo, e questa
   è l'ultima del foglio. `transform: none` non è ridondante: senza, resterebbe
   il `translateX(-50%)` di prima e la pillola uscirebbe dal riquadro a
   sinistra. */
.gal-all {
  left: 14px;
  right: auto;
  bottom: 14px;
  top: auto;
  transform: none;
  padding: 7px 12px;
  gap: 8px;
  font-size: 0.62rem;
  letter-spacing: var(--track-btn);
  background: rgba(14, 27, 51, 0.82);
  /* Mai oltre il riquadro che la ospita, con lo stesso margine dall'altra
     parte: 14 a sinistra, 14 a destra. */
  max-width: calc(100% - 28px);
}
/* Il disegno della macchina fotografica scende a filo del maiuscoletto: a
   15 px accanto a un corpo di 0,62rem sporgeva sopra e sotto la riga. */
.gal-all svg { width: 13px; height: 13px; flex: none; }

/* Sul telefono la miniatura diventa larga quanto la pagina e la pillola, se
   restasse centrata, tornerebbe in mezzo alla fotografia — che è la
   segnalazione da cui era partito il round 31. Stesso angolo, stesse distanze:
   la regola qui sopra vale già, e questa rimette solo il corpo, che la media
   query dei 780 px abbassava a 0,58 quando la pillola stava al centro. */
@media (max-width: 780px) {
  .gal-all { font-size: 0.62rem; letter-spacing: var(--track-btn); padding: 7px 12px; }
}

/* -- 2. La descrizione dell'immobile, su due colonne ----------------------------
   «Devi correggere l'impaginazione giustificata della scheda immobile perché
   attualmente lascia mezza pagina vuota.» Misurato su /proprieta/EL-0001/ a
   1440 px: la riga delle cinque cifre è larga 1216, la descrizione sotto 510.

   Il rimedio non è allargare la riga — 1216 px sono 150 caratteri, cioè il
   difetto opposto — ma affiancare due colonne della misura giusta. Un testo
   giustificato e sillabato è composto apposta per la colonna stretta, e due
   colonne separate da un filetto sono il modo in cui si impagina su carta.

   `break-inside: avoid` sui capoversi tiene un capoverso in una colonna sola
   dove ci sta; `orphans/widows` impediscono che una riga sola resti in fondo o
   in cima a una colonna. La classe la mette il template contando le battute —
   vedi listing_detail.html. */
@media (min-width: 1000px) {
  .det-desc-2 {
    max-width: none;
    columns: 2;
    column-gap: clamp(40px, 4.4vw, 68px);
  }
  /* Un capoverso che sta in una colonna non si spezza fra due — vedi il
     commento nel template. Vale solo dove i capoversi sono più d'uno: su un
     testo scritto tutto di seguito «non spezzare» lascerebbe vuota la seconda
     colonna. Per quel caso restano orphans e widows, che dentro un figlio il
     browser onora. */
  .det-desc-blocchi > p { break-inside: avoid; }
  .det-desc-2 > p { orphans: 3; widows: 3; }
}

/* -- 3. La scheda «vendere casa», rifatta ---------------------------------------
   «Correggi tutta l'impaginazione della scheda vendere casa.» Tre cose, e
   la terza è quella che il cliente ha descritto come «la scritta della guida è
   un po' distante da tutto e non è bella».

   3a. GLI OTTO PASSI SU DUE COLONNE. Erano larghi 510 in una pagina da 1036, e
   sulla stessa pagina l'indice delle dieci guide, poco più sotto, ne usa 1036
   su due colonne: due ritmi diversi nella stessa pagina. Otto passi su due
   colonne fanno quattro righe piene — nessuno spaiato in fondo.

   Il peso, che qui è tutto: `body.page-doc main .shell.prose > *` (round 47)
   vale due elementi e tre classi e stringe ogni figlio a 510 px. Per disfarlo
   su questo solo elenco serve **una classe in più sullo stesso ramo**, non una
   regola scritta `.sq-2 { … }`, che perderebbe qualunque sia l'ordine. È la
   lezione del round 26, applicata prima di sbagliare invece che dopo.

   Il filetto sotto ogni passo diventa il filetto sopra: in una colonna sola
   separava un passo dal successivo, in griglia deve dire dove **comincia**
   ognuno, altrimenti le due colonne, che finiscono a altezze diverse, chiudono
   con due filetti sfalsati. */
body.page-doc main .shell.prose > .sq-2 {
  max-width: none;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: clamp(34px, 4vw, 60px);
}
.sq-2 .sq-i {
  background-position: 0 0;
  padding: clamp(20px, 2.2vw, 26px) 0 clamp(24px, 2.8vw, 34px);
}
/* L'ultima riga della griglia non porta il filetto in fondo: non c'è niente da
   separare. Con otto passi le ultime due celle sono la quarta riga. */
.sq-2 .sq-i:last-child { background-image: var(--rule); }
/* Nella colonna il testo torna alla misura di lettura: la cella è larga ~490,
   quindi non serve stringere altro, ma il tetto in caratteri resta scritto. */
.sq-2 .sq-i p { max-width: 62ch; }

@media (max-width: 900px) {
  body.page-doc main .shell.prose > .sq-2 { grid-template-columns: minmax(0, 1fr); }
  /* A una colonna torna la composizione di prima: filetto in fondo, e l'ultimo
     passo senza. */
  .sq-2 .sq-i { background-position: 0 100%; padding: clamp(22px, 2.6vw, 30px) 0; }
  .sq-2 .sq-i:last-child { background-image: none; }
}

/* 3b. «DOVE LAVORIAMO» SU DUE COLONNE — il titolo a sinistra, quello che dice e
   il rimando a destra. Erano tre righe corte incolonnate a sinistra dentro una
   pagina larga il doppio: l'ultimo posto della pagina in cui il vuoto tornava.
   La colonna del titolo è la stessa larghezza di una colonna dei passi, quindi
   la pagina ha una sola griglia dall'inizio alla fine. */
.docband { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: clamp(34px, 4vw, 60px); }
.docband-h { margin: 0; }
/* Il primo blocco della colonna di destra parte allineato al titolo: il suo
   margine superiore serviva a staccarlo da ciò che aveva sopra, e sopra non ha
   più niente. Scritto sul figlio e non su `.prose-lead`, che è una classe con
   una regola sua altrove nel foglio e non va sdoppiata. */
.docband-c > :first-child { margin-top: 0; }
@media (max-width: 900px) {
  .docband { grid-template-columns: minmax(0, 1fr); row-gap: clamp(14px, 2vw, 20px); }
}

/* 3c. LA NOTA CHE CHIUDE IL DOCUMENTO. Stava in una fascia tutta sua, fra due
   respiri: sommati, ~190 px di vuoto sopra e altrettanti sotto, per tre righe
   di stampatello minuto che non hanno niente da annunciare. Da fuori non si
   legge come una nota in calce, si legge come un blocco dimenticato in mezzo
   alla pagina.

   Adesso chiude il testo dove il testo finisce, sotto un filetto che attraversa
   tutta la pagina: il filetto è il segno che il documento è finito e che quello
   che segue — l'invito alla valutazione — è di un altro ordine. Il filetto è
   largo quanto la pagina, la nota resta alla misura di lettura: una nota in
   calce lunga 150 caratteri per riga sarebbe illeggibile due volte, perché è
   anche più piccola. */
.gd-endnote {
  margin-top: clamp(30px, 3.6vw, 46px);
  padding-top: clamp(18px, 2vw, 24px);
  border-top: 1px solid var(--line);
}
.gd-endnote .gd-note { margin-top: 0; }

/* 3d. LA CHIUSURA TORNA UN BLOCCO CENTRATO. `body.page-doc .endcta { max-width:
   760px }` (round 47) non ha mai avuto effetto: sull'hub la chiusura porta
   anche `.shell`, e `body.page-doc main .shell` vale un elemento in più — 1180
   contro 760. Il titolo e l'invito si stiravano su tutta la pagina invece di
   stare in colonna. Stessa lezione del round 26, terzo caso in questo foglio:
   una correzione scritta con meno peso di quella che vuole correggere sembra
   fatta e non lo è. */
body.page-doc main .shell.endcta { max-width: 820px; }

/* -- 4. I servizi senza disegni -------------------------------------------------
   «Nella scheda servizi togli le icone e quindi impagina correttamente il
   tutto.» La seconda metà della frase è la parte difficile: tolto il disegno,
   la scheda non è la stessa scheda con un buco in cima. Il disegno era l'unica
   cosa che occupava il terzo alto del riquadro e che dava al titolo qualcosa
   contro cui appoggiarsi; senza, restano un titolo attaccato al bordo e due
   terzi di aria sotto.

   Al suo posto c'è il numero d'ordine del servizio, in maiuscoletto sopra un
   filetto: la stessa coppia con cui il sito numera i passi della vendita e le
   voci dell'indice delle guide. Non è un'illustrazione sostituita da un'altra —
   è tipografia, che si compone con il titolo invece di stargli sopra, e dice
   una cosa vera in più: che i servizi sono cinque e in quest'ordine.

   Il resto è ritmo. Il riquadro perde 26 px di margine sotto il disegno e ne
   guadagna in respiro, il titolo può crescere di un gradino (senza il disegno
   sopra, la riga più lunga — «Valorizzazione immobile» — ci sta lo stesso), e
   «scopri di più» resta appoggiato al fondo, che è ciò che tiene le cinque
   schede alla stessa altezza. */
.svc { padding: clamp(26px, 2.4vw, 34px) clamp(18px, 1.7vw, 24px) clamp(22px, 2vw, 28px); }
.svc-n {
  font-family: var(--sans);
  font-size: 0.62rem;
  font-weight: 400;
  letter-spacing: var(--track-label);
  color: var(--ink-46);
  padding-bottom: 14px;
  margin-bottom: 18px;
  font-variant-numeric: lining-nums tabular-nums;
  background-image: var(--rule);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% 1px;
}
.svc-t { font-size: clamp(0.97rem, 1.2vw, 1.1rem); }
.svc-d { margin-top: 14px; }
.svc-more { padding-top: 26px; }
/* Al passaggio del mouse si accende anche il numero: la scheda intera è un
   oggetto solo, e prima l'unica cosa che si muoveva era l'ombra. */
.svc:hover .svc-n { color: var(--ink); }

/* -- 5. Il modulo di valutazione: comune e indirizzo -----------------------------
   «Nella scheda della valutazione separa il comune amministrativo
   dall'indirizzo.» Il perché sta in website/forms.py — a Gries il comune è
   Bolzano, a Cornaiano è Appiano, e con un campo solo il comune non arrivava
   mai. Qui c'è solo la riga in più: l'indirizzo è l'unica risposta lunga del
   modulo e si prende una riga intera, invece di stringere a 130 px le quattro
   colonne di un pannello largo 556. */
.vform-row-1 { grid-template-columns: minmax(0, 1fr); }

/* -- 6. Le parole stanno nella parte quieta della fotografia ---------------------
   Le sei fasce interne centravano il loro blocco di testo in verticale. Con
   blocchi alti da una a quattro righe, questo vuol dire che ogni pagina
   scriveva a un'altezza diversa — e su /vendere-casa/ scriveva **sull'edificio**:
   il titolo finiva sulle vetrate scure e nel punto peggiore reggeva 2,9:1,
   sotto la soglia di 3 del testo grande.

   Le sette fotografie sono composte tutte allo stesso modo, ed è una scelta di
   chi le ha scattate: il soggetto a destra, la valle in controluce in alto a
   sinistra. La parte quieta sta **in alto**, non a metà. Allineare in alto il
   blocco non è quindi una preferenza: è mettere le parole dove la fotografia
   le aspetta, e per giunta le sei fasce cominciano finalmente tutte alla stessa
   altezza, che è la coerenza che il round 47 ha cercato sui margini.

   Misurato sui pixel delle lettere, peggior 2%:

     vendere casa  titolo    2,9 → 5,8      immobili  titolo    12,8 → 15,8
     servizi       sommario  7,3 → 7,4      immobili  sommario  10,5 → 11,3

   `.phero.phero` non è un refuso: la regola del round 26
   (`.hero, .phero, .vhero { padding-top: var(--hdh) }`) vale una classe, e una
   correzione scritta con lo stesso peso perderebbe o vincerebbe a seconda
   dell'ordine nel foglio. Ripetuta, la classe ne vale due e il risultato non
   dipende più da dove sta scritta. È la lezione del round 26. */
.phero { align-items: flex-start; }
.phero.phero { padding-top: calc(var(--hdh) + clamp(34px, 3.6vw, 52px)); }

/* -- 7. Sul telefono le fasce interne inquadrano la parte alta -------------------
   L'ultima riga che non reggeva la soglia era il sommario di /chi-siamo/ sul
   telefono: 2,1:1 nel peggior 2%, e circa metà delle lettere sotto 4,5. Si
   vede: la terza riga passa sopra al divano scuro in primo piano.

   Il velo non poteva risolverlo, e anche qui è stato provato per davvero — il
   pianoro del telefono portato da 0,24 a 0,42, cioè quasi il doppio di avorio
   sull'intera fotografia, guadagnava in tutto 1,3 decimi (2,1 → 3,4). Sopra un
   pixel quasi nero il navy avrebbe bisogno di un velo al 53%: la fotografia
   diventerebbe una velina. Provate e scartate anche le altre due leve: sette
   valori di `object-position` (il 30% del round 47 è già il migliore) e quattro
   altezze della fascia (le peggiorano tutte, perché cambiando l'altezza cambia
   il ritaglio).

   La causa vera è geometrica. Le sette fotografie sono 2,5:1; la fascia sul
   telefono è quasi quadrata (390 x 380), e `cover` in un riquadro più alto che
   largo ritaglia **solo i lati**: la fotografia si vede tutta, dall'alto in
   basso, primo piano compreso. È esattamente il difetto che il round 46 aveva
   diagnosticato sull'apertura della home — «senza avanzo in altezza
   object-position non ha niente da spostare» — e la soluzione è la stessa:
   dare al riquadro un avanzo da spostare.

   L'immagine si alza al 135% della fascia e si appoggia in alto, così il primo
   piano esce dal riquadro dal basso e `overflow: hidden` lo taglia. Sotto le
   parole resta la parte alta della fotografia — cielo, cresta, valle in
   controluce — che è la parte per cui queste fotografie erano state scelte.

   I due numeri vengono da una ricerca vera (h fra 120 e 150%, x fra 20 e 45%),
   misurando ogni volta tutte le pagine con tools/overlay_contrast_real.py.
   Peggior 2%, prima e dopo:

     chi siamo  sommario   2,1 → 5,8      contatti   sommario   6,7 → 15,4
     servizi    sommario   6,6 → 11,8     immobili   sommario  11,9 → 14,1
     vendere    titolo     6,6 →  7,4     valutaz.   sommario  14,2 → 14,5

   Il prezzo è l'ingrandimento: su uno schermo da 390 px a 3x si campionano 912
   px di sorgente per 1170 px di schermo, cioè 1,28x. Il 140% dava mezzo punto
   in più di contrasto e 1,33x; il 135 è il taglio più leggero che porta tutte
   le righe sopra soglia con margine.

   Il peso: tre classi, quindi batte la regola del round 47
   (`.hero-ph img { object-position: 30% 50% }`, una classe) senza toccarla, e
   non può raggiungere l'apertura della home, che non è dentro nessun `.phero`.
   Vale fino a 980 px, la stessa soglia degli altri due blocchi del telefono. */
@media (max-width: 980px) {
  .phero .hero-ph, .vhero .hero-ph { overflow: hidden; }
  .phero .hero-ph img, .vhero .hero-ph img {
    position: absolute;
    top: 0; bottom: auto; left: 0;
    width: 100%; height: 135%;
    object-fit: cover;
    object-position: 20% 0;
  }
}

/* -- 8. Le scritte sopra le fotografie, misurate una per una ---------------------
   «Assicurati che le scritte in sovraimpressione sull'immagine siano
   perfettamente leggibili.» Il velo del round 45 tiene i titoli — sono grandi,
   e la soglia del testo grande è 3:1 — ma sopra la stessa fotografia ci sono
   anche due righe **piccole**, per cui la soglia è 4,5:1: il soprattitolo in
   maiuscoletto (0,62rem) e il sommario (0,95rem). Sono le due che il cliente
   legge peggio, ed erano scritte in grigio: `--ink-46` vale il 60% del navy,
   cioè butta via quattro decimi del contrasto che il velo ha appena comprato.

   La correzione non aggiunge velo — la fotografia deve restare la fotografia,
   ed è la decisione del cliente del 14 agosto. Applica invece una regola che
   questo foglio ha già scritto due volte e mai fino in fondo: **sopra una
   fotografia si scrive a piena forza**. È del round 26, per il menù («il
   grigio di lettura serve sulla carta, non sull'immagine»), ed è del round 48
   per il selettore di lingua. Il soprattitolo e il sommario delle aperture
   erano rimasti indietro — e sono le due righe piccole, cioè quelle che hanno
   la soglia più alta.

   Misurato con tools/overlay_contrast_real.py, sui pixel che le lettere
   dipingono davvero, peggior 2% sulle sette aperture:

     soprattitolo   1,5 → 13,3   (era --ink-46, il 60% del navy)
     sommario       2,1 →  ...   (era --ink-70, il 92%)

   Il titolo non si tocca: era già navy pieno.

   I selettori nominano il **blocco di parole** dell'apertura, non l'apertura:
   `.tag` e `.hero-lede` esistono anche sulla carta, dove il grigio è giusto, e
   dentro `.vhero` c'è anche il modulo di valutazione, che è un pannello blu
   notte — un `.tag` navy lì dentro sarebbe blu su blu, che è il difetto del
   round 36 rifatto da capo. `.vhero-copy` e non `.vhero`, quindi. */
.hero-in .tag, .phero-in .tag, .vhero-copy .tag { color: var(--ink); }
.hero-in .hero-lede, .phero-in .hero-lede, .vhero-copy .hero-lede { color: var(--ink); }

/* ================================================================================
   ROUND 49, seconda passata — quello che si vedeva solo sulla pagina vera
   ================================================================================
   Sette correzioni del cliente sopra le pagine del round 49. Nessuna rimette in
   discussione una scelta: cinque sono rifiniture di misura, una è una richiesta
   nuova sull'apertura di «vendere casa», e una sola disfa una regola — la
   soglia delle battute sulla descrizione.                                      */

/* -- 1. Le due pillole della galleria sono lo stesso oggetto --------------------
   «Il bottone vedi tutte le foto deve essere posizionato alla stessa distanza
   dai bordi del bottone 1/4.»

   Misurate su otto larghezze da 1280 a 2560, le due distanze erano **già**
   identiche: 14 px a sinistra e 14 px sotto, stesso respiro interno, stesso
   corpo, stessa campitura. Quello che restava diverso non era una distanza, era
   il **disegno**: un'icona da 13 px comincia esattamente sul bordo del proprio
   riquadro, mentre una cifra ha il suo bianco laterale. A parità di 12 px di
   respiro dichiarato, la macchina fotografica partiva due o tre pixel più
   vicina al bordo della «1», e a quella misura si vede.

   Via l'icona, quindi. Non è una perdita: le due pillole diventano la stessa
   cosa scritta due volte — maiuscoletto avorio su blu notte — che è
   letteralmente quello che il cliente ha chiesto, ed è la stessa strada presa
   sulle schede dei servizi in questo round. Il disegno stava nel template, e
   di qui è sparita anche la riga che gli dava spazio. */
.gal-all { gap: 0; }

/* -- 2. «Al momento questo è l'unico immobile…» non va a capo a metà pagina -----
   L'invito che prende il posto delle schede quando in catalogo non c'è
   nient'altro era largo 620 px dentro una pagina di 1216: andava a capo poco
   dopo la metà, e una riga che si spezza lì sembra spezzata per errore.

   La misura di 620 px veniva dal round 30, quando quel blocco stava dentro una
   colonna. Adesso sta da solo su tutta la larghezza della pagina, e la frase —
   165 battute — ci sta comodamente in due righe piene invece che in due righe
   corte. `text-wrap: pretty` è la garanzia che l'ultima riga non resti di una
   parola sola il giorno in cui il testo cambia. */
.sim-empty { max-width: none; }
.sim-empty p { max-width: none; text-wrap: pretty; }

/* -- 3. Il paragrafo della scheda venduta, equidistante -------------------------
   «Metti il paragrafo "questo immobile è stato venduto…" al centro equidistante
   dalle altre scritte sopra e sotto.»

   La causa era una riga sola: `.det-closed-actions { margin-top: auto }`. In una
   colonna flex un margine automatico **si mangia tutto lo spazio libero**, e lo
   spazio libero qui è quello che avanza perché il riquadro è alto quanto la
   fotografia accanto. Risultato: 24 px sopra il paragrafo e ottanta sotto.

   Il margine automatico serviva, e resta — è quello che fa chiudere la colonna
   alla stessa quota della fotografia, richiesta 8 del round 31 — ma cambia
   posto: passa **sopra e sotto il paragrafo**, che è l'unico modo di dividere
   quello spazio in parti uguali senza sapere in anticipo quanto sia. Due
   margini automatici si spartiscono l'avanzo a metà: è la stessa aritmetica di
   `margin-inline: auto`, girata in verticale.

   Vale dove il riquadro è davvero stirato, cioè accanto alla fotografia. Sotto
   i 1240 px non c'è avanzo da dividere, e lì i due stacchi si pareggiano a mano
   con lo stesso passo della scala. */
@media (min-width: 1241px) {
  .det-aside .det-card-closed .det-aside-sub { margin-block: auto; }
  .det-aside .det-card-closed .det-closed-actions { margin-top: 0; }
}
@media (max-width: 1240px) {
  .det-aside .det-card-closed .det-aside-sub {
    margin-top: clamp(22px, 2.6vw, 32px);
    margin-bottom: 0;
  }
  .det-aside .det-card-closed .det-closed-actions {
    margin-top: clamp(22px, 2.6vw, 32px);
  }
}

/* -- 4. «Dove lavoriamo»: le due colonne partono dalla stessa riga --------------
   Il titolo a sinistra e il testo a destra cominciavano a due altezze diverse —
   il titolo più in basso di una quarantina di pixel — e da fuori si legge come
   un blocco che non è stato allineato.

   Il colpevole è `.lintel`, che riserva 24 px sopra il titolo per il filetto
   del marchio, più la differenza di interlinea fra un serif da 1,5rem e un
   paragrafo da 0,98. Sommare a mano quei due numeri sarebbe una taratura da
   rifare a ogni cambio di corpo: `align-items: baseline` lo fa fare al browser,
   che allinea la **prima riga di base** delle due colonne. Il filetto resta
   dov'è, sopra il titolo, perché non è testo. */
.docband { align-items: baseline; }
/* `align-self: start` sul titolo, che stava qui dal primo giro, batteva
   l'allineamento: un elemento che decide da sé come stare nella riga non
   ascolta più `align-items`. Tolto — era lì per impedire al titolo di
   stirarsi, e `baseline` lo impedisce già. */
/* Sul telefono le due colonne diventano due righe: allineare le basi non ha più
   niente da allineare, e `baseline` su una griglia a una colonna sarebbe solo
   un modo per non far crescere le celle. */
@media (max-width: 900px) {
  .docband { align-items: start; }
}

/* ================================================================================
   ROUND 50 — sei segnalazioni del cliente, 28 agosto 2026

   1. La mappa stampava «API KEY REQUIRED» su ogni tessera.
   2. «Vedi tutte le foto» va nell'angolo **destro**, speculare a «1 / 4».
   3. Il banner «Nuovo» sulle schede appena pubblicate.
   4. «Dove lavoriamo» lasciava un buco in mezzo alla fascia.
   5. La nota della guida copriva mezza pagina.

   Come sempre in questo foglio, le regole stanno in fondo e nominano abbastanza
   classi da vincere su quelle che correggono: una correzione scritta con meno
   peso di quella che vuole correggere sembra fatta e non lo è.
   ================================================================================ */

/* -- 1. Le tessere della mappa non chiedono più una chiave ----------------------
   CARTO ha chiuso `basemaps.cartocdn.com` a chi non ha un account: le tessere
   continuavano ad arrivare — per questo la mappa non risultava «rotta» a nessun
   controllo — ma con «API KEY REQUIRED» stampato sopra in diagonale. Adesso
   arrivano da OpenStreetMap, che non chiede chiavi.

   Il filtro qui sopra (round 30, riga `.map-frame .leaflet-tile-pane`) **non è
   stato ritoccato, ed è voluto**: la sua prima operazione è `grayscale(1)`, e
   dopo quella il colore del fornitore non esiste più — resta solo la
   luminosità. Le luminosità della tavolozza di OpenStreetMap, calcolate in
   Rec. 709 sui colori dichiarati dal foglio di stile di osm-carto, cadono nella
   stessa banda chiara della carta di prima: fondo #F2EFE9 → 239, acqua #AAD3DF
   → 203, edifici #D9D0C9 → 209, bosco #ADD19E → 198 su 255. Cambiare il
   fornitore non cambia quello che il filtro riceve, quindi non c'è niente da
   ritarare: sarebbe un numero nuovo senza una misura dietro.

   Il pallore che ne esce lo tiene la coppia in coda al filtro
   (`brightness(1.03) contrast(0.92)`): il fondo esce a 237 su 255, cioè la
   carta resta un piano chiaro sul quale il segnaposto navy è l'unica cosa che
   si vede — che è il compito di questa mappa. */

/* -- 2. «Vedi tutte le foto» passa nell'angolo destro ---------------------------
   «Mettila nell'angolo a destra, speculare a 1 / 4.»

   Il round 49 le aveva dato lo stesso angolo del contatore — in basso a
   sinistra, ognuna nel proprio riquadro — e a leggersi erano due pillole
   incolonnate sullo stesso bordo, non una coppia. Speculare vuol dire l'altra
   cosa: il contatore appoggiato al bordo sinistro della fotografia grande, la
   didascalia appoggiata al bordo **destro** della miniatura, alla stessa
   distanza. Le due si guardano da capo a capo della galleria e la chiudono.

   Tutto il resto resta identico al contatore — respiro interno, corpo,
   tracciatura, campitura — perché era già la stessa cosa scritta due volte, e
   quello non cambia: cambia da che parte sta. `left: auto` non è ridondante:
   senza, la regola del round 49 continuerebbe a fissare il bordo sinistro e la
   pillola resterebbe incollata lì, larga tutta la miniatura.

   Il valore è scritto una volta sola, in una variabile, così la distanza dal
   bordo non può divergere fra le due pillole il giorno che la si cambia. */
:root { --gal-inset: 14px; }
.gal-count { left: var(--gal-inset); right: auto; bottom: var(--gal-inset); }
.gal-all {
  left: auto;
  right: var(--gal-inset);
  bottom: var(--gal-inset);
  top: auto;
  transform: none;
  /* Mai oltre il riquadro che la ospita, con lo stesso margine dall'altra
     parte: 14 a destra, 14 a sinistra. */
  max-width: calc(100% - var(--gal-inset) * 2);
}

/* -- 3. Il banner «Nuovo» -------------------------------------------------------
   «Un piccolo banner "nuovo" quando un immobile viene pubblicato sul sito.»

   Piccolo davvero: è la pillola che il catalogo ha già per «Affitto» e «In
   trattativa», nello stesso angolo e con lo stesso disegno. Un banner di forma
   nuova avrebbe voluto dire un terzo linguaggio in cima alla stessa fotografia,
   per dire una cosa dello stesso ordine delle altre due.

   L'unica differenza è la campitura, ed è la differenza che serve: bianca è la
   pillola neutra («Affitto» è una categoria), navy piena è quella che segnala
   («In trattativa» è uno stato). «Nuovo» è dell'ordine del navy, e ha in più il
   filetto sotto che nel resto del sito vuol dire «guarda qui». Chi non
   distingue i colori legge comunque la parola: la pillola non è mai il solo
   portatore dell'informazione. */
.pill-new {
  background: var(--ink);
  color: var(--paper);
  box-shadow: inset 0 -2px 0 0 var(--alpine);
}
/* Sulla scheda, dov'è una voce della riga del luogo e non una pillola sopra una
   fotografia: lì la riga è tutta in maiuscoletto grigio, e la novità è l'unica
   parola che va letta per prima. Colore pieno, niente riquadro. */
.det-new { color: var(--ink); }

/* -- 4. «Dove lavoriamo»: tre colonne, tutte con qualcosa dentro ----------------
   Il round 49 aveva messo la fascia su due colonne uguali per toglierle il
   vuoto a destra. Misurato sulla pagina vera a 1000 px di larghezza, il vuoto
   si era solo spostato: il titolo occupa 158 px della sua colonna da 440, il
   testo ne occupa 400 della sua, e fra la fine del titolo e l'inizio del testo
   restano **295 px di niente** in mezzo alla fascia. Due blocchi appoggiati ai
   due capi opposti di una riga non si leggono come una composizione: si leggono
   come due cose che non si parlano.

   La correzione non è stringere il buco, è dargli un abitante. Il rimando —
   «Territorio →» — stava incolonnato sotto il testo, dove ripete il movimento
   della colonna che ha sopra; portato in fondo alla riga diventa la terza voce
   della fascia e la chiude sul bordo destro della pagina. Titolo, ciò che dice,
   dove si va: l'ordine in cui si legge, da sinistra a destra, senza salti.

   Le tre misure, e nessuna è un numero inventato:

     * il titolo occupa **quanto è largo il titolo** (`auto`, cioè il suo
       max-content). Una frazione gli darebbe una colonna più larga di lui, e il
       vuoto che avanza è precisamente il difetto da correggere: provato a
       0,78fr, restavano 106 px di niente dopo l'ultima lettera;
     * il testo è largo `--measure`, la riga di lettura del sito — 510 px, 74
       caratteri, lo stesso numero del corpo di una guida e della descrizione di
       un immobile. Qui capita di essere anche la larghezza giusta per la fascia,
       il che vuol dire che non c'è una misura nuova da difendere;
     * la terza prende quel che resta (`1fr`) e ci appoggia il rimando al bordo
       destro. Lo spazio che avanza sta *prima* del collegamento, non fra due
       blocchi di testo: là si legge come l'aria davanti a un numero di pagina,
       che è quello che il rimando è.

   Misurato a 1000 px di larghezza: prima 295 px di vuoto in mezzo alla fascia,
   ora 32 (la gronda fra titolo e testo) e il bordo destro occupato.
   `align-items: baseline` (round 49) vale ancora e adesso allinea tre prime
   righe invece di due. */
.docband { grid-template-columns: auto minmax(0, var(--measure)) 1fr; column-gap: clamp(28px, 3.2vw, 48px); }
/* Il rimando si appoggia al bordo destro della sua colonna, che è il bordo
   destro della pagina. Il margine che lo staccava dal paragrafo che aveva sopra
   non ha più niente sopra da cui staccarsi. */
.docband-a { margin-top: 0; justify-self: end; white-space: nowrap; }
@media (max-width: 900px) {
  /* Sul telefono le tre colonne tornano tre righe, e il rimando riprende il suo
     stacco e il suo allineamento: in colonna è di nuovo l'ultima cosa della
     fascia, non la terza voce di una riga, e va incolonnato a sinistra come
     tutto il resto. */
  .docband { grid-template-columns: minmax(0, 1fr); row-gap: clamp(14px, 2vw, 20px); }
  .docband-a { margin-top: clamp(18px, 2.4vw, 26px); justify-self: start; }
}

/* -- 5. La nota che chiude la guida, su due colonne -----------------------------
   «L'impaginazione del disclaimer della guida copre solo mezza pagina.»

   Misurata: la nota è larga `--measure`, 510 px, dentro un documento largo 926 —
   il 55%. È il valore giusto per un testo che si legge riga dopo riga, e quello
   sbagliato per tre righe di stampatello minuto che chiudono la pagina: la riga
   di lettura serve all'occhio che deve tornare a capo dieci volte di seguito,
   non a chi legge una nota in calce.

   Le due strade erano allargare la riga o dividerla. Allargarla la porterebbe a
   135 caratteri — il doppio della finestra in cui l'occhio ritrova da solo
   l'inizio della riga dopo, e per giunta in un corpo più piccolo del testo:
   illeggibile due volte, ed è la ragione scritta nel round 49 per lasciarla
   stretta. Dividerla no: due colonne da 74 caratteri sono due righe di lettura
   giuste, e insieme coprono la pagina intera fino al filetto che le sovrasta.

   È la stessa correzione, con la stessa aritmetica, che questo foglio applica
   già alla descrizione dell'immobile (`.det-desc-2`) e agli otto passi
   (`.sq-2`): una pagina, un ritmo.

   Il peso, che qui è tutto: `body.page-doc main .shell.prose > *` (round 47) e
   `body.page-doc main .shell > .gd-note` (idem) valgono tre classi e due
   elementi. Le due regole qui sotto ne nominano quattro, quindi vincono a peso
   e non per l'ordine nel foglio — che è la lezione già pagata tre volte qui
   dentro. */
body.page-doc main .shell.gd-endnote > .gd-note,
body.page-doc main .shell.prose > .gd-note {
  max-width: none;
  columns: 2;
  column-gap: clamp(34px, 4vw, 60px);
}
@media (max-width: 900px) {
  /* Due colonne di trentasette caratteri sono due colonne, non due letture. */
  body.page-doc main .shell.gd-endnote > .gd-note,
  body.page-doc main .shell.prose > .gd-note { columns: 1; }
}

/* ================================================================================
   ROUND 51 — le nove segnalazioni del cliente, 30 agosto 2026

   1. La firma email, e le tre icone social ovunque.
   2. Il marchio con «REAL ESTATE» a tutta lunghezza (la meccanica sta in alto,
      nel blocco della testata, perché lì è dove il lockup è definito).
   3. Facebook collegato ovunque.
   4. La mappa: minimalista.
   5. «Dove lavoriamo»: impaginazione.
   6. I comuni: colonne sfalsate.
   7. La galleria a schermo intero: il blu di sfondo.
   8. L'exposè di stampa.
   9. La striscia bianca in cima sul telefono.

   Come sempre in questo foglio le regole stanno in fondo e nominano abbastanza
   classi da vincere su quelle che correggono. Vedi il blocco ROUND 50.
   ================================================================================ */

/* -- 9. La zona sicura dell'iPhone ---------------------------------------------
   «Quella striscia bianca rettangolare in alto che interrompe l'immagine di
   sfondo.» La causa e la misura stanno nel commento accanto al meta viewport in
   base.html: senza `viewport-fit=cover` Safari impagina dentro i margini di
   sicurezza e riempie il resto con `--paper`.

   Messo `cover`, la pagina arriva al bordo fisico dello schermo e la
   fotografia passa sotto la barra di stato — che è quello che il cliente
   chiede. Resta da rimettere a mano l'aria che Safari toglieva da sé, o il
   logo finisce sotto l'orologio:

     * la testata cresce dell'inserto e se lo prende come riempimento sopra,
       quindi `.hd-in` resta alto `--hdh` e la riga non si muove di un pixel;
     * `main` e le tre aperture fotografiche seguono la stessa somma, o il
       margine negativo che porta la fotografia a filo si ferma troppo in basso
       — cioè la striscia tornerebbe, più sottile;
     * `--gx` non scende mai sotto l'inserto laterale: in orizzontale la tacca
       mangia il margine sinistro di ogni `.shell`.

   Dove `env()` non esiste il ripiego è 0px e non cambia niente: su un desktop
   questo blocco è aritmetica che dà gli stessi numeri di prima. */
:root {
  --sat: env(safe-area-inset-top, 0px);
  --sab: env(safe-area-inset-bottom, 0px);
  --gx: max(clamp(20px, 5vw, 72px), env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px));
}
.hd { padding-top: var(--sat); height: calc(var(--hdh) + var(--sat)); }
main { padding-top: calc(var(--hdh) + var(--sat)); }
.hero, .phero, .vhero {
  margin-top: calc((var(--hdh) + var(--sat)) * -1);
  padding-top: calc(var(--hdh) + var(--sat));
}
/* I due banner interni contengono la testata: se cresce lei, crescono loro. */
.phero { min-height: calc(var(--hdh) + var(--sat) + clamp(300px, 30vw, 430px)); }
.vhero { min-height: calc(var(--hdh) + var(--sat) + clamp(420px, 42vw, 620px)); }
@media (max-width: 980px) {
  /* Il pannello del menu copre tutto lo schermo, tacca compresa: è una
     campitura navy e sta bene a filo. Le voci però no — cominciano sotto la
     barra di stato e finiscono sopra la barretta del gesto. */
  .hd-nav { padding-top: calc(var(--hdh) + var(--sat)); padding-bottom: calc(40px + var(--sab)); }
}

/* -- 3. Facebook e Instagram anche fuori dal piede -----------------------------
   La riga dei profili in fondo al riquadro dei recapiti. Le icone sono le
   stesse del piede (_social.html); qui stanno su carta chiara, quindi il grigio
   di lettura invece del chiaro, e allineate al testo che le annuncia. */
.office-social {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-top: 26px;
  padding-top: 22px;
  background-image: var(--rule);
  background-repeat: no-repeat;
  background-position: 0 0;
  background-size: 100% 1px;
}
.office-social .ft-social { margin-top: 0; }
.ft-social-ink a { color: var(--ink-46); }
.ft-social-ink a:hover { color: var(--ink); }

/* -- 4. La mappa, minimalista --------------------------------------------------
   «Sistema estetica della mappa e rendila minimalista e perfetta.»

   Il grosso della correzione non è qui: è la carta stessa, cambiata in
   _map_base.html — un fondo disegnato per stare sotto a qualcos'altro invece
   della carta escursionistica di OpenStreetMap ingrigita da un filtro. Quello
   che resta al foglio di stile sono quattro cose.

   **Il filtro, molto più leggero.** Quello del round 30 era tarato su una
   tavolozza satura: `sepia(0.45) saturate(0.5) contrast(0.92)` serviva a
   spegnere il verde dei boschi e l'arancio delle statali. La carta chiara non
   ha niente da spegnere — il suo fondo è già un grigio quasi bianco — e
   riceverlo tutto la sbianca fino a far sparire le strade. Qui la seppia serve
   solo a **creare** una dominante su un'immagine già grigia, e la rotazione la
   porta sull'azzurro alpino del marchio: è la stessa meccanica del round 30 con
   la dose giusta per la carta nuova. Il filtro pesante resta scritto, e torna da
   solo sul ripiego (`.is-osm`), che è esattamente la tavolozza per cui era
   stato calcolato.

   **Il riquadro è una lastra, non un buco.** Un filetto `--line` tutt'intorno,
   come i pannelli del modulo e dei recapiti: senza, la mappa è l'unico
   rettangolo della pagina che comincia senza dire dove comincia.

   **Il cerchio del bacino si legge come una stima.** Riempimento più tenue e
   contorno tratteggiato: la didascalia sotto dice «la posizione è indicativa» e
   un cerchio a contorno pieno dice il contrario.

   **I comandi si fanno piccoli.** Due quadrati da 32 px con il filetto del
   sito, senza ombra e senza angoli tondi — il linguaggio di tutti gli altri
   pulsanti quieti di questo sito — e la dicitura delle fonti senza campitura,
   perché una targhetta bianca in un angolo è un elemento in più da guardare. */
.map-frame { border: 1px solid var(--line); }
.map-frame .leaflet-tile-pane {
  filter: grayscale(1) sepia(0.28) hue-rotate(178deg) saturate(0.62) brightness(1.02) contrast(0.97);
}
/* Il ripiego riprende il filtro del round 30, calcolato sulla tavolozza di
   OpenStreetMap: fondo #F2EFE9 → 239, acqua #AAD3DF → 203, bosco #ADD19E → 198
   su 255, tutti nella stessa banda chiara. */
.map-frame .leaflet-container.is-osm .leaflet-tile-pane {
  filter: grayscale(1) sepia(0.45) hue-rotate(178deg) saturate(0.5) brightness(1.03) contrast(0.92);
}
.map-frame .leaflet-bar { box-shadow: none; }
.map-frame .leaflet-bar a,
.map-frame .leaflet-bar a:hover {
  width: 32px; height: 32px; line-height: 32px;
  font-size: 0.95rem;
  border: 1px solid var(--line);
  background: rgba(251, 250, 247, 0.92);
}
.map-frame .leaflet-bar a + a { border-top: 0; }
.map-frame .leaflet-bar a:hover { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.map-frame .leaflet-control-attribution {
  background: transparent;
  color: var(--ink-46);
  font-size: 0.56rem;
  padding: 2px 7px;
}
.map-frame .leaflet-control-attribution a { color: var(--ink-46); text-decoration: none; }
.map-frame .leaflet-control-attribution a:hover { color: var(--ink); }
/* Il segnaposto resta l'unica cosa navy del riquadro, e l'alone che respira è
   ciò che lo fa trovare in un secondo: su una carta senza texture funziona
   meglio di prima, non peggio. Si ferma soltanto per chi ha chiesto meno
   movimento. */
@media (prefers-reduced-motion: reduce) {
  .map-pin-halo { animation: none; transform: scale(0.9); opacity: 0.5; }
}

/* -- 5. «Dove lavoriamo»: un margine sinistro solo, e il vuoto abitato --------
   Terza segnalazione sulla stessa fascia (round 49, 50, 51), e la misura dice
   perché le prime due non bastavano. Su /vendere-casa/ **ogni cosa comincia a
   200,5 px**: il titolo della pagina, gli otto passi, il titolo dell'indice
   delle guide, il suo sommario, la nota finale. La fascia no — titolo a 200,5,
   testo accanto a 438,4. Due margini sinistri nella stessa pagina, cioè il
   difetto per cui esiste `page-doc` (round 47), rientrato dalla finestra.

   Ora il titolo sta sopra, come su ogni altra sezione di questa pagina, e sotto
   di lui il sommario riparte dallo stesso margine di tutto il resto. Accanto al
   sommario ci sono i nomi delle sette zone: la risposta a «lascia mezza pagina
   vuota» non è allargare la riga di lettura — è dare al vuoto un abitante, ed è
   la prima delle tre risposte che questo foglio usa già altrove.

   La colonna dei nomi è un elenco, non prosa: un elenco accanto a un paragrafo
   non fa due margini sinistri, li fa un secondo paragrafo. È la stessa
   distinzione per cui `.sq-2` e `.cards` possono stare in colonna e `.prose`
   no.

   Le due misure: il sommario resta `--measure`, la riga di lettura del sito;
   i nomi prendono quel che avanza e vanno a capo da soli. */
.docband {
  grid-template-columns: minmax(0, var(--measure)) 1fr;
  column-gap: clamp(34px, 4.5vw, 72px);
  align-items: start;
}
.docband-h {
  grid-column: 1 / -1;
  margin-bottom: clamp(18px, 2.2vw, 28px);
}
.docband-c { margin-top: 0; }
/* I nomi delle zone: due colonne quando c'è posto, perché sette voci in
   colonna singola sarebbero più alte del paragrafo che affiancano e la fascia
   finirebbe sbilenca dall'altra parte. */
.docband-z {
  margin-top: 4px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px clamp(20px, 2.4vw, 34px);
  align-content: start;
}
.docband-z li { min-width: 0; }
.docband-z a { display: inline-block; }
/* Il rimando all'indice chiude l'elenco e sta su una riga sua: è di un altro
   ordine rispetto ai sette nomi — non è una zona, è dove stanno tutte. */
.docband-all {
  grid-column: 1 / -1;
  margin-top: clamp(8px, 1.2vw, 14px);
  padding-top: clamp(12px, 1.4vw, 18px);
  background-image: var(--rule);
  background-repeat: no-repeat;
  background-position: 0 0;
  background-size: 100% 1px;
}
@media (max-width: 900px) {
  /* In colonna il paragrafo e l'elenco si impilano, e i nomi restano su due
     colonne finché ci stanno: sette righe piene di seguito sono la «lista
     orribile» che il round 42 ha già tolto da /valutazione/. */
  .docband { grid-template-columns: minmax(0, 1fr); row-gap: clamp(18px, 2.6vw, 26px); }
  .docband-z { margin-top: 0; }
}
@media (max-width: 520px) {
  .docband-z { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  .docband-z a { padding: 5px 0; }
}

/* -- 6. I comuni: le colonne cominciano tutte alla stessa quota ----------------
   «Sistema impaginazione dei comuni, sono sfalsati.»

   Misurato sulla schermata del cliente, pixel per pixel (2680 × 752, cioè 1340
   px a 2×): le intestazioni della prima, della seconda e della quarta colonna
   cominciano a 43 e il loro filetto a 83; quelle della **terza** a 103 e 143.
   Uno scarto di 60 px a 2×, cioè **30 px netti** — e trenta è esattamente il
   `margin-bottom` di `.cmx-g` a quella larghezza (`clamp(22px, 2.4vw, 30px)`,
   con 2,4vw = 34,8 che tocca il tetto). Non è un caso e non è un'altra misura:
   è quel margine, riapparso in cima a una colonna.

   È il comportamento dei margini al taglio di colonna. Quando un gruppo
   inizia una colonna nuova — cosa che `break-inside: avoid` rende frequente,
   perché sposta il gruppo intero invece di spezzarlo — il margine inferiore di
   quello che lo precedeva può restare attaccato al taglio. Chromium lo
   tronca, WebKit no, ed è per questo che qui non si vedeva niente e sul
   Safari del cliente sì. La conferma sta nel resto della misura: dentro la
   terza colonna la distanza fra le due intestazioni è giusta (155 px contro i
   185 della quarta, che ha un comune in più), quindi non è il contenuto a
   essere sbagliato — è tutta la colonna traslata in basso di quei 30 px.

   **La correzione è togliere il margine, non compensarlo.** Lo stacco fra un
   gruppo e il successivo diventa riempimento *dentro* il gruppo: il
   riempimento inferiore di una scatola resta in fondo alla scatola in
   qualunque colonna finisca, e al taglio non c'è più niente che possa
   avanzare. Stessa aria fra i gruppi, stesse quattro colonne, stessi gradini
   di larghezza del round 42 — e nessun browser può più sfalsarle.

   Il peso: `.cmx-g` da sola perderebbe contro la regola del round 42 se questa
   stesse prima; sta dopo, a parità di peso, quindi vince. Il `margin-bottom: 0`
   è dichiarato e non sottinteso, perché è la metà della correzione. */
.cmx-g { margin-bottom: 0; padding-bottom: clamp(22px, 2.4vw, 30px); }
@media (max-width: 620px) {
  .cmx-g { margin-bottom: 0; padding-bottom: 18px; }
}

/* ================================================================================
   ROUND 52 — le otto segnalazioni del cliente, 2 settembre 2026

   1. La galleria a schermo intero non si chiudeva, e si apriva da sola: una
      causa sola, e sta in cima al foglio (`[hidden]`), perché ne guariva altre
      due.
   2. «Contattaci» illeggibile al passaggio del mouse (nel blocco del piede).
   3. La pagina Facebook nei collegamenti (config/settings.py).
   4. «Dove lavoriamo» — quarta versione, e la prima senza due colonne.
   5. Il disclaimer sulle normative: una colonna sola, con un occhiello.
   6. La mappa: nitidezza al doppio, nomi in secondo piano, riquadro caldo.
   7. Sul telefono: via il rettangolo sabbia, e i filtri salgono sulla
      fotografia.
   8. «Meno è meglio»: le sproporzioni delle sezioni lunghe.
   ================================================================================ */

/* -- 6. La mappa: nitida, calda, e con i nomi al loro posto ---------------------
   «Correggi estetica mappa e risoluzione e font delle scritte.»

   La nitidezza si compra in `_map_base.html` (`detectRetina`): è la metà della
   correzione e non è scritta qui. Qui c'è il resto, che sono tre cose.

   **I nomi vanno in secondo piano.** Non si può cambiare il loro carattere —
   sono disegnati dentro l'immagine della tessera, non sono testo — ma si può
   togliere loro il diritto di parlare a voce alta. A 0,72 di opacità e con un
   filo di contrasto in meno restano leggibili quando li si cerca e smettono di
   competere con l'unico carattere della pagina, che è Arimo. È la stessa
   scelta del velo dell'apertura: non nascondere, abbassare.

   **Il riquadro è caldo come la pagina.** Il fondo della carta chiara è un
   grigio-bianco (#f2f2f2 circa) e la pagina è avorio caldo (#f5f3f0): la
   mappa era l'unico rettangolo freddo di un sito che non ha nessun altro
   grigio. La seppia sale da 0,28 a 0,34 e la rotazione scende da 178° a 166°:
   la dominante resta azzurro alpino — è il colore del marchio — ma con dentro
   quel tanto di caldo che la fa sedere sull'avorio invece di bucarlo.

   **Il segnaposto sta più fermo.** L'ombra sotto la goccia era una nuvola da
   6 px: su una carta priva di texture è l'unica cosa morbida della pagina.
   Scende a 3 px e si scurisce, che è un'ombra e non un alone. */
.map-frame .leaflet-tile-pane .map-nomi {
  opacity: 0.72;
  filter: contrast(0.88);
}
.map-frame .leaflet-tile-pane {
  filter: grayscale(1) sepia(0.34) hue-rotate(166deg) saturate(0.6) brightness(1.03) contrast(0.96);
}
.map-pin svg { filter: drop-shadow(0 2px 3px rgba(9, 18, 35, 0.34)); }
/* La dicitura delle fonti: era una targhetta bianca appoggiata sull'angolo.
   Senza campitura e senza filetto è quello che deve essere — una riga dovuta,
   non un elemento da guardare. */
.map-frame .leaflet-control-attribution {
  background: transparent;
  padding: 2px 6px;
  font-size: 0.56rem;
  color: rgba(44, 62, 87, 0.42);
}

/* -- 4. «Dove lavoriamo»: la quarta versione, e la prima senza due colonne ------
   «Correggi impaginazione sezione dove lavoriamo e rendila esteticamente
   gradevole.»

   Quarta segnalazione sulla stessa fascia (49, 50, 51, 52). Le prime tre hanno
   provato tre disposizioni diverse — due colonne uguali, tre colonne, testo a
   sinistra e zone a destra — e hanno in comune l'errore: **mettevano due cose
   una accanto all'altra.** Due blocchi affiancati hanno due altezze, e due
   altezze diverse fanno un vuoto in fondo a quello più corto. Il round 51 aveva
   un paragrafo di tre righe accanto a un elenco di quattro: centottanta pixel
   di niente sotto il paragrafo, e la riga «Val Pusteria» sola in fondo a una
   colonna di quattro. Rifare il calcolo con proporzioni diverse avrebbe
   spostato il vuoto, non tolto.

   Round 52 smette di affiancare. La fascia è una colonna sola, a tutta
   larghezza, e legge dall'alto in basso come tutto il resto della pagina:

     occhiello · titolo · una riga di testo · i sette nomi · il rimando

   I nomi stanno su **quattro colonne**, che è la griglia dei comuni (`.cmx`) e
   quella del piede: sette voci fanno 4 + 3, cioè due righe piene e una cella
   che finisce prima — che su un elenco di parole non si legge come un buco,
   perché non c'è nessuna scatola a disegnarlo. Il rimando all'indice chiude
   sotto un filetto **largo quanto la fascia**: prima era largo quanto la
   colonna di destra, cioè un frammento di riga che cominciava a metà pagina
   senza che niente lo spiegasse.

   Un solo margine sinistro, che è la regola di `page-doc` (round 47) e la
   ragione per cui il round 51 aveva alzato il titolo. Qui non è più una
   correzione: è la forma. */
.docband {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  column-gap: 0;
  align-items: start;
}
.docband-h { grid-column: 1 / -1; margin-bottom: clamp(14px, 1.8vw, 22px); }
.docband-c { margin-top: 0; max-width: var(--measure); }
.docband-z {
  margin-top: clamp(26px, 3vw, 40px);
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(12px, 1.4vw, 18px) clamp(20px, 2.4vw, 34px);
  align-content: start;
}
.docband-all {
  grid-column: 1 / -1;
  margin-top: clamp(16px, 2vw, 24px);
  padding-top: clamp(14px, 1.6vw, 20px);
  background-image: var(--rule);
  background-repeat: no-repeat;
  background-position: 0 0;
  background-size: 100% 1px;
}
@media (max-width: 1000px) { .docband-z { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 720px)  { .docband-z { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 420px) {
  .docband-z { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  .docband-z a { padding: 5px 0; }
}

/* -- 5. Il disclaimer sulle normative: una colonna, e un occhiello -------------
   «Correggi impaginazione disclaimer sulle normative.»

   Il round 50 l'aveva diviso in due colonne per non lasciare mezza pagina
   vuota — la segnalazione del round 49. Il conto era giusto e la premessa no:
   `columns: 2` bilancia le due colonne per **altezza**, quindi tre righe
   diventano due più una, e in mezzo resta un vuoto che l'occhio attraversa a
   metà periodo. Sulla schermata del cliente si legge «…del tecnico che segue»
   e poi, sessanta pixel più in là e una riga più in alto, «l'immobile.» Non è
   un testo su due colonne: è un testo interrotto.

   Le colonne di testo funzionano da un certo numero di righe in su — è la
   ragione per cui `.det-desc-2` e `.sq-2` le usano e questa nota no. Sotto
   quella soglia l'unica forma giusta è una colonna.

   E il vuoto a destra? Non si riempie: si dichiara. L'occhiello «Nota» a
   sinistra dice che quello che segue è materiale di calce, e una nota di calce
   larga quanto si legge (`--measure`, la riga di tutto il sito) con del bianco
   accanto è impaginazione, mentre lo stesso paragrafo senza occhiello è un
   paragrafo che si è fermato a metà. Costa una parola in tre lingue.

   Il peso: `body.page-doc main .shell.prose > *` (round 47) vale tre classi e
   due elementi, quindi qui se ne nominano quattro — la lezione già pagata tre
   volte in questo foglio. */
body.page-doc main .shell.gd-endnote > .gd-note,
body.page-doc main .shell.prose > .gd-note {
  columns: auto;
  max-width: var(--measure);
}
.gd-endnote {
  display: grid;
  grid-template-columns: clamp(84px, 9vw, 132px) minmax(0, 1fr);
  align-items: baseline;
  column-gap: clamp(18px, 2vw, 30px);
}
.gd-note-lbl {
  margin: 0;
  font-family: var(--sans);
  font-size: 0.6rem;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-46);
}
@media (max-width: 620px) {
  /* Sul telefono l'occhiello non ha una colonna in cui stare: sale sopra la
     nota, che è il posto in cui un occhiello sta quando lo spazio finisce —
     come su ogni altra sezione del sito. */
  .gd-endnote { grid-template-columns: minmax(0, 1fr); row-gap: 8px; }
}

/* -- 7. Il telefono: via il rettangolo sabbia, e i filtri salgono sulla foto ----
   «Nel sito mobile devi correggere e togliere quel rettangolo color sabbia più
   scuro e mettere i filtri di ricerca per un pezzo in sovraimpressione
   sull'immagine.»

   **Il rettangolo.** Misurato sulla schermata del cliente (1320 px di
   larghezza, cioè 440 CSS a 3×): sotto il bordo della fotografia corrono
   sessantaquattro pixel netti di un colore che va da #E2DED6 a #DCD8CD, per
   tutta la larghezza. Non è una fascia della pagina: è il **fondo di
   `.hero-ph`**, `linear-gradient(150deg, var(--ivory), #ddd8cc)`, che si vede
   dove la fotografia non arriva. Su Chromium, qui, non si vede — l'immagine
   copre il riquadro alla riga; da lui no, ed è la terza volta che una
   differenza fra i due motori arriva come una segnalazione di impaginazione.

   La correzione non prova a indovinare quel pixel: **toglie il colore**. Un
   fondo dietro una fotografia che copre non si vede mai, quindi l'unica cosa
   che può fare è comparire quando qualcosa va storto — e allora deve essere
   del colore della pagina, non un terzo colore. È esattamente il ragionamento
   del round 29 sulla striscia fra la fotografia e la scheda, applicato al
   fondo invece che alla striscia. Il sabbia resta dov'era giusto: su
   `.ph-dead`, cioè quando la fotografia non c'è davvero e il riquadro deve
   dire qualcosa da solo.

   Che cosa **non** serve, e l'ho tolto dopo averlo scritto: una cintura sulla
   misura dell'immagine. Il `133%` del round 46 è codice morto — il round 49 lo
   ha disfatto trenta righe più in basso con `inset: 0; height: 100%; object-fit:
   cover`, e c'è un controllo che pretende che quella resti l'ultima regola di
   `.hero .hero-ph img`. Aggiungerne un'altra dopo l'avrebbe fatto fallire per
   una riga che non cambiava niente: l'immagine copre già il riquadro alla
   dichiarazione. Il colore è la correzione, non la geometria.

   **I filtri sulla fotografia.** Il pannello scavalcava il bordo di trenta
   pixel — sul desktop sono quarantasei e si vedono, su uno schermo da 440 px
   sono un'unghia, e infatti dalla sua parte il pannello sembrava appoggiato
   sotto l'immagine invece che sopra. Adesso ne scavalca un centinaio: quanto
   basta perché il primo campo, «Tipologia», stia **dentro** la fotografia. È
   lo stesso numero in due posti — il riempimento sotto l'apertura e il margine
   negativo del pannello — perché l'uno è lo spazio che l'altro attraversa: se
   divergono, il pannello sale sui pulsanti dell'apertura. */
.hero-ph { background: var(--paper); }
.hero-ph.ph-dead { background: linear-gradient(150deg, var(--ivory), #ddd8cc); }
@media (max-width: 780px) {
  .hero { padding-bottom: clamp(76px, 21vw, 104px); }
  .hsearch { margin-top: calc(-1 * clamp(76px, 21vw, 104px)); }
}

/* -- 8. «Meno è meglio»: le sproporzioni della scheda immobile ------------------
   «Correggi in generale l'impaginazione di tutte le schede, evitando
   sproporzioni e rendendo il tutto più semplice, elegante e professionale
   possibile. Meno è meglio.»

   Sulla scheda immobile — che è la pagina che il cliente non riusciva più a
   vedere, perché la galleria le stava sopra — le sproporzioni sono tre, e sono
   tutte lo stesso errore: **un impaginato disegnato per un catalogo pieno,
   mostrato con un catalogo di due immobili.** È la malattia che il round 47 ha
   già curato sulle griglie di schede con `data-n`, ricomparsa in tre punti che
   allora non erano stati toccati.

   1. La descrizione su due colonne quando il testo non basta a riempirle: tre
      righe a sinistra, due a destra. La cura sta nel template (soglia a 720
      battute); qui resta soltanto la misura da tenere quando la colonna è una.
   2. Un riquadro solo — «Punti di forza» senza planimetria, che è il caso
      normale — dentro una griglia da due: metà riga bianca. Adesso la griglia
      sa quanti riquadri ha, e con uno lo distende. L'elenco dei punti va su due
      colonne dentro il riquadro disteso, perché sei righe corte in una colonna
      larga 1180 px sono sei righe che finiscono al primo quarto.
   3. Gli immobili simili: una scheda in una riga da quattro. `data-n` sul
      contenitore chiama le regole del round 47, che sono già scritte — la
      scheda sola si gira su un fianco, due prendono due colonne larghe. Non
      c'era da inventare niente: c'era da dichiarare il numero.
   Le due righe che qui **non** ci sono: `.det-desc { max-width: var(--measure) }`
   sta già al suo posto dal round 32, e `.det-desc-2 { max-width: none }` sta
   dentro la `min-width: 1000px` del round 47. Riscriverle in fondo al foglio
   avrebbe rotto proprio il caso lungo — una regola scritta dopo, a parità di
   peso, batte una scritta dentro una media query. È la lezione dei pesi dei
   selettori, applicata al verso opposto. */

.det-boxes[data-n="1"] { grid-template-columns: minmax(0, 1fr); }
/* Il riquadro disteso cambia la forma dell'elenco, e non per vezzo: quando i
   riquadri sono due l'elenco è una colonna stretta e i filetti fra le righe
   sono ciò che lo fa leggere come la scheda dei dati che è. Disteso su 1180 px,
   quegli stessi filetti diventano quattro righe orizzontali lunghe un metro con
   sei parole all'inizio di ognuna. Due colonne senza filetti, con il segno di
   spunta a fare da elenco: la stessa informazione, e il bianco resta dove
   serve. Due e non tre — quattro punti in tre colonne fanno 3 + 1, cioè un
   orfano, che è il difetto da cui parte tutto questo round.
   `columns` non si può usare: `.strengths` è una griglia, e una griglia ignora
   la multicolonna. Sono le colonne della griglia stessa. */
@media (min-width: 900px) {
  .det-boxes[data-n="1"] .strengths {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: clamp(30px, 3.4vw, 64px);
    row-gap: 4px;
    grid-auto-rows: auto;
    align-content: start;
    flex: 0 0 auto;
    margin-inline: 0;
    margin-top: 4px;
    border-top: 0;
  }
  .det-boxes[data-n="1"] .strengths li { padding: 9px 0; border-bottom: 0; }
}

/* -- 9. Le pagine di zona: i blocchi indipendenti escono dalla colonna --------
   Stessa segnalazione, applicata dove pesa di più. Su /zone/bolzano/ — la
   pagina più lunga del sito, 5745 px — **ogni** cosa sta in una colonna larga
   510 px dentro un documento largo 926: l'introduzione, «Vendere casa a
   Bolzano», i tre comuni della valutazione, le tre domande. Il 45% della
   pagina è bianco per tutta la sua altezza, e il cliente scorre cinque schermi
   di colonna stretta.

   Metà di quel bianco è giusto e non si tocca: la prosa si legge a `--measure`
   (round 48), e allargarla sarebbe il difetto opposto. L'altra metà no. I
   comuni e le domande **non sono prosa**: sono blocchi indipendenti, ognuno con
   il suo titolo, che si leggono uno per volta e in qualunque ordine. Per loro
   la colonna di lettura non è una regola, è un'abitudine presa dal vicino.

   È esattamente la distinzione che il round 50 ha già fatto per gli otto passi
   (`.sq-2`), con la stessa meccanica: una classe in più sullo stesso ramo per
   disfare `body.page-doc main .shell.prose > *`, e il filetto che passa da
   sotto a sopra, perché in griglia deve dire dove ognuno **comincia** — due
   colonne che finiscono a altezze diverse chiuderebbero con due filetti
   sfalsati.

   `data-n` decide: con un blocco solo (Val Pusteria ha un comune) due colonne
   vorrebbero dire una cella piena e una vuota, cioè il difetto che si sta
   correggendo, scritto in griglia. */
@media (min-width: 900px) {
  body.page-doc main .shell.prose > .comuni:not([data-n="1"]),
  body.page-doc main .shell > .faq:not([data-n="1"]) {
    max-width: none;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: clamp(34px, 4vw, 60px);
  }
  .comuni:not([data-n="1"]) .comune,
  .faq:not([data-n="1"]) .faq-item {
    background-position: 0 0;
    padding: clamp(20px, 2.2vw, 26px) 0 clamp(24px, 2.8vw, 34px);
  }
  /* In griglia l'ultimo blocco tiene il suo filetto: è quello che apre la sua
     cella, non quello che chiude l'elenco. */
  .comuni:not([data-n="1"]) .comune:last-child,
  .faq:not([data-n="1"]) .faq-item:last-child { background-image: var(--rule); }
}

/* -- 10. Le ultime tre sproporzioni, piccole e visibili ------------------------
   «Meno è meglio.» Tre righe, tre difetti che si vedono e non si spiegano.

   **La chiusura.** Il sommario sotto «Vuoi sapere quanto vale il tuo
   immobile?» era largo 56 caratteri dentro un blocco da 820 px: tre righe
   centrate, la terza con due parole. Un testo centrato di tre righe con
   l'ultima corta è la forma più fragile che ci sia — l'occhio legge il gradino,
   non la frase. A 64 caratteri diventano due righe, e `text-wrap: balance`
   chiede al browser di spartirsele invece di riempire la prima e lasciare gli
   avanzi alla seconda.

   **Quello che non ho fatto, e perché.** La stessa spartizione andrebbe bene
   sui titoli di sezione, che vanno a capo con una parola sola in seconda riga.
   Ma `.ttl-2` ha un controllo (round 26, poi 39) che legge **l'ultima regola
   con quel selettore esatto** e pretende che dichiari il corpo in rem: una riga
   scritta in fondo al foglio gliela farebbe leggere al posto di quella giusta,
   e il controllo che sorveglia la scala tipografica smetterebbe di sorvegliare
   qualcosa. Una rifinitura non vale un guardiano. Se un giorno serve, va scritta
   dentro la regola che porta già il corpo, non dopo di lei.

   **La riga dei dati sulla scheda.** `.det-desc` porta ora la misura di lettura
   anche quando è corta (round 32), quindi la riga dei quattro dati sopra di lei
   è l'unica cosa larga 1180: sta bene così, ed è scritto qui perché la prossima
   persona non la stringa «per uniformità». Una riga di quattro cifre non si
   legge, si scorre: la misura di lettura non la riguarda. */
.endcta .gd-cta-p { max-width: 64ch; text-wrap: balance; }


/* ============================================================ ROUND 53
   Il sopratitolo dentro il titolo dell'apertura.

   Prima era un <p> fuori dall'h1; ora è uno <span> dentro. Tre cose vanno
   rimesse a mano, e sono esattamente le tre che il <p> faceva da sé:

   1. tornare un blocco — uno span è in linea, e in linea finirebbe sulla
      stessa riga della prima parola dello slogan;
   2. non ereditare il corpo del titolo — `.tag` dichiara già il suo, quindi
      basta non farsi scavalcare: nessuna regola qui tocca font-size;
   3. lo stacco. Il margine che separava sopratitolo e slogan stava sopra
      l'h1: ora quel margine allontanerebbe l'intero blocco dalla fotografia
      invece che le due righe fra loro. Si sposta dove serve, cioè sotto il
      sopratitolo, e l'h1 resta attaccato dov'era.

   Le misure sono le stesse di prima alla cifra: chi guarda la home non vede
   una pagina diversa. */
.hero-block .hero-title { margin-top: 0; }
/* Round-55 — lo stesso sopratitolo ora sta anche sull'h1 della valutazione.
   Il selettore si allunga invece di duplicarsi: una regola nuova più in basso
   vincerebbe per posizione e una più in alto perderebbe, e in entrambi i casi
   ci sarebbero due posti da tenere allineati. Senza `display: block` il
   sopratitolo resterebbe in linea col titolo — è esattamente il difetto che
   `hidden` che non nasconde ha già insegnato a cercare. */
.hero-block .hero-kick,
.vhero-copy .hero-kick {
  display: block;
  margin-bottom: clamp(16px, 2.4vh, 26px);
  /* Il titolo è nel serif, il sopratitolo no: senza questa riga erediterebbe
     il Tinos dell'h1 e smetterebbe di essere un'etichetta. */
  font-family: var(--sans);
  line-height: 1.4;
}
