/* Public catalogue card (CAT-4).
 *
 * Standalone: this page does not live inside the tenant shell, so it carries
 * its own type scale and colours rather than depending on the shell's. Class
 * prefix `cpub-` keeps it from colliding with anything, including the module's
 * own `catalog-` styles when the preview frames it.
 *
 * Mobile first: the layout is a single column and only widens at 40rem, so the
 * 390px viewport is the design and 1280px is the enhancement, not the reverse.
 */

/* Lo scorrimento verso un'ancora è ANIMATO, e solo in CSS: chi arriva da una
 * pillola vede dove sta andando invece di trovarsi teletrasportato, ed è ciò
 * che rende leggibile un salto di duemila pixel.
 *
 * `prefers-reduced-motion` NON È UNA CORTESIA: per chi ha disturbi vestibolari
 * un movimento non richiesto è un sintomo, e il sistema operativo lo dichiara
 * apposta. Chi l'ha chiesto ottiene il salto secco, che è il comportamento di
 * sempre. */
html {
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

/* ============================================================================
 * I TOKEN (CAT-SCHEDA-3 C1, decisione D4).
 *
 * Sono i valori del mock di design, adottati 1:1 sulla scheda PUBBLICA. A
 * verbale, perché è una scelta e non una svista: **l'identità di ciò che il
 * pubblico vede è diversa da quella dell'applicazione**. La shell del tenant
 * resta com'è; qui vive una palette calda con i suoi due font, e la ragione è
 * che un annuncio lo guarda qualcuno che non ha mai visto il nostro software e
 * non gli interessa vederlo.
 *
 * Sono VARIABILI e non esadecimali sparsi perché questa è la base del
 * white-label: cambiare la tinta di un portale dovrà restare un blocco di
 * `:root`, non una caccia per millecinquecento righe.
 *
 * L'UNICA deroga al «1:1» è dichiarata in D3: le pastiglie sopra le foto
 * restano CHIARE. Il mock le vuole scure; la regola di CAT-UX-2 dice che sopra
 * la foto di qualcuno non va un pannello nero, e c'è uno smoke che misura la
 * luminanza e pretende zero. Una regola che si aggira in silenzio è peggio di
 * una regola che si cambia, e questa non si cambia.
 * ========================================================================= */
:root {
  /* --- superfici e inchiostri ------------------------------------------ */
  --cpub-bg: #FFFDFB;          /* fondo pagina, crema caldo */
  --cpub-surface: #FFFFFF;     /* card, barre, input */
  --cpub-ink: #1E1C19;         /* titoli, valori, bottone primario */
  --cpub-ink-2: #33302B;       /* corpo della descrizione, voci d'indice */
  --cpub-ink-3: #55514A;       /* indirizzo, «/ mese» */
  --cpub-muted: #6E6A62;       /* etichette 11-14px (5.38:1 su bianco) */

  /* --- filetti ---------------------------------------------------------- */
  --cpub-line: #F3EEE6;        /* bordi card, filetti di sezione */
  --cpub-line-row: #F8F5EF;    /* filetti di riga nelle liste dati */
  --cpub-line-nav: #F9F6F1;    /* filetti dell'indice laterale */
  --cpub-border-soft: #F4F0E8; /* bordo dei quadrati media */
  --cpub-border: #EAE3D8;      /* bordo bottoni secondari, input */

  /* --- accento ---------------------------------------------------------- */
  --cpub-accent: #B96206;        /* link, icone dei media */
  --cpub-accent-strong: #8A4A04; /* hover, categorie dei servizi, badge */
  --cpub-accent-bg: #F0E2CE;     /* badge affitto, avatar agenzia */
  --cpub-accent-bg-soft: #F7EFE2;/* bottoni tenui */
  --cpub-accent-bg-line: #E7D6BC;
  --cpub-accent-mark: #E0A33A;   /* quadratini e pallini decorativi */

  /* --- badge per transazione (D6: vendita e asta hanno la loro) --------- */
  --cpub-tag-bg: var(--cpub-accent-bg);
  --cpub-tag-ink: var(--cpub-accent-strong);

  /* --- raggi ------------------------------------------------------------ */
  --cpub-r-sm: 6px;
  --cpub-r-md: 8px;
  --cpub-r-lg: 10px;
  --cpub-r-xl: 12px;
  --cpub-r-pill: 999px;
  --cpub-radius: var(--cpub-r-lg);   /* alias storico, usato da CAT-GEO/MEDIA */
  --cpub-gap: 1rem;

  /* --- pastiglie sopra le foto: CHIARE, vedi D3 ------------------------- */
  --cpub-chip-ink: var(--cpub-accent-strong);
  --cpub-chip-surface: var(--cpub-accent-bg-soft);
  --cpub-chip-line: var(--cpub-accent-bg-line);
  --cpub-active: var(--cpub-accent);
  --cpub-veil: rgba(255, 253, 251, 0.86);
  --cpub-pill: rgba(255, 255, 255, 0.94);

  /* --- alias di compatibilità ------------------------------------------- */
  --cpub-soft: var(--cpub-bg);
}

* { box-sizing: border-box; }

body.cpub {
  margin: 0;
  padding: 0;
  background: var(--cpub-bg);
  color: var(--cpub-ink);
  /* Cabin è servito da noi (`core/css/fonts.css`): la CSP resta
   * `font-src 'self'` e nessun visitatore viene consegnato a un dominio Google
   * per aver guardato un annuncio. Il ripiego è di sistema, come nel mock. */
  font-family: Cabin, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* La pagina è larga 1160px e il padding è fluido, come nel mock: sotto quella
 * misura il contenuto respira ai lati invece di attaccarsi al vetro. */
.cpub-card {
  max-width: 1160px;
  margin: 0 auto;
  background: transparent;
  padding: 0 clamp(16px, 3vw, 24px) 80px;
}

/* ---------------------------------------------------------------- il fuoco
 *
 * IL MOCK NON LO DEFINISCE e il README lo dichiara «da implementare nel
 * codebase»: eccolo, in un punto solo e per tutto ciò che si può raggiungere
 * con la tastiera. Prima esisteva su due elementi (il badge della mappa e la
 * chiusura del riquadro) e altrove cambiava un colore di bordo — che su una
 * pastiglia chiara non si vede.
 *
 * `:focus-visible` e non `:focus`: chi usa il mouse non deve vedere l'anello,
 * chi usa la tastiera sì. Il raggio si eredita, così l'anello segue la forma
 * dell'elemento invece di disegnargli attorno un rettangolo. */
.cpub :focus-visible {
  outline: 2px solid var(--cpub-accent);
  outline-offset: 2px;
  border-radius: inherit;
}

/* ------------------------------------------------------------------ header */

/* ------------------------------------------ CAT-SCHEDA-3 C2 — la testata
 *
 * Gerarchia del mock: occhiello con il badge della transazione, titolo grande
 * fluido, indirizzo, riga del prezzo. Nessuna CTA qui — è una scelta esplicita
 * del design: in alto risultava troppo pesante, e i bottoni stanno nella
 * colonna laterale.
 */
.cpub-header {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 32px 0 0;
}

.cpub-eyebrow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 0;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--cpub-muted);
}

/* Il badge della transazione. I due token si ridefiniscono per vendita e asta
 * (D6): il colore dice di che affare si tratta prima che lo dica la parola. */
.cpub-transaction {
  padding: 5px 10px;
  border-radius: var(--cpub-r-sm);
  background: var(--cpub-tag-bg);
  color: var(--cpub-tag-ink);
  letter-spacing: 0.09em;
  font-weight: 600;
}

.cpub-transaction--vendita {
  --cpub-tag-bg: #DDE7DF;
  --cpub-tag-ink: #2F5D42;
}

.cpub-transaction--asta {
  --cpub-tag-bg: #E4E1EC;
  --cpub-tag-ink: #4B3F72;
}

.cpub-place::before {
  content: "";
}

.cpub-title {
  margin: 0;
  font-size: clamp(30px, 5.4vw, 46px);
  line-height: 1.06;
  font-weight: 700;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

/* L'indirizzo della TESTATA ha un nome suo: `.cpub-address` è già l'indirizzo
 * della sezione Posizione, e due ruoli diversi con lo stesso nome sono due
 * regole che prima o poi si pestano i piedi — l'ha trovato uno smoke che
 * contava «quanti indirizzi c'è in pagina» e ne ha trovati due. */
.cpub-hero-address {
  margin: 0;
  font-size: 18px;
  color: var(--cpub-ink-3);
}

.cpub-price {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 24px;
  margin: 0;
  padding-top: 4px;
}

.cpub-price-value {
  font-size: clamp(30px, 4vw, 38px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.05;
}

.cpub-price-value--absent {
  font-size: 22px;
  font-weight: 600;
  color: var(--cpub-muted);
}

.cpub-price-unit {
  font-size: 17px;
  font-weight: 600;
  color: var(--cpub-ink-3);
}

.cpub-price-label {
  font-size: 15px;
  color: var(--cpub-muted);
}

/* ------------------------------------ CAT-SCHEDA-3 C2 — i dati chiave
 *
 * Quattro colonne FISSE a ogni larghezza, anche a 390px: sono numeri corti, e
 * farle diventare due su telefono raddoppierebbe l'altezza di un blocco che
 * serve a essere letto in un'occhiata. Due soli filetti, sopra e sotto, come
 * nel mock: le celle non hanno bordi propri.
 */
/* CAT-SCHEDA-3-FIX2 (V1) — LA FASCIA SI CHIUDE.
 *
 * I filetti erano 1px in --cpub-line, cioè il tono con cui la pagina separa
 * due righe di una tabella: sulla fascia alta — che è l'insegna dell'annuncio,
 * non una tabella — sparivano, e i dati chiave galleggiavano fra il prezzo e
 * le foto senza appartenere a niente.
 *
 * ESTERNO PIÙ MARCATO DELL'INTERNO, ed è la ragione della variante: 2px in
 * --cpub-border (#EAE3D8, il bordo dei bottoni secondari — il tono più deciso
 * della scala prima dell'inchiostro) chiudono la fascia sopra e sotto; 2px in
 * --cpub-line separano le file dentro. Così le due file restano una cosa
 * sola invece di diventare due strisce.
 *
 * LA RIGA INTERNA STA SULLE CELLE, NON SUL FONDO DELLA GRIGLIA. Col fondo, le
 * tracce VUOTE della seconda fila si dipingevano anche loro: un blocco beige
 * largo tre colonne accanto a «Piano». Le nostre file sono quasi sempre
 * parziali, perché si rendono solo i campi valorizzati (CAT-UX-3 / D6) — la
 * fila piena del mock è il caso raro, non quello normale. Visto in uno
 * screenshot delle varianti, non dedotto.
 *
 * `nth-child(n+5)` VUOL DIRE «dopo la prima fila», e lo vuol dire soltanto
 * perché le colonne sono QUATTRO FISSE a ogni larghezza. È un vincolo, non un
 * caso: chi rendesse la griglia responsive deve riscrivere anche questa riga,
 * o il filetto comparirà in mezzo a una fila. */
.cpub-facts {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0;
  margin: 0;
  border-top: 2px solid var(--cpub-border);
  border-bottom: 2px solid var(--cpub-border);
}

.cpub-fact {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 16px 14px 0;
}

.cpub-fact:nth-child(n+5) {
  border-top: 2px solid var(--cpub-line);
}

.cpub-fact dt {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--cpub-muted);
}

.cpub-fact dd {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin: 0;
  font-size: clamp(18px, 2vw, 21px);
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* Il quadratino della classe energetica: un segno, non una parola in più. */
.cpub-fact-mark {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  background: var(--cpub-accent-mark);
}

.cpub-ref {
  margin: 0;
  padding-top: 20px;
  border-top: 1px solid var(--cpub-line);
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px;
  color: var(--cpub-muted);
}

.cpub-ref code {
  font-family: inherit;
  font-size: inherit;
}

/* ------------------------------------------- riepilogo (CAT-UX-3 / 3b) */

/* I dati che si leggono per primi, come FRASI separate da un punto medio:
 * «50 m² · 2 locali · 1 camera · Piano 1». La coppia numero-sopra-etichetta
 * funziona in una tabella; qui si legge di corsa, e una riga di sostantivi si
 * legge di corsa. Il separatore è decorativo (::after), quindi non finisce nel
 * testo che un lettore di schermo annuncia né in un copia-incolla. */

.cpub-summary {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem 0.75rem;
  margin: 0.75rem 0 0.6rem;
  padding: 0.6rem 0;
  border-top: 1px solid var(--cpub-line);
  border-bottom: 1px solid var(--cpub-line);
  list-style: none;
  font-size: 0.9375rem;
  font-weight: 550;
}

.cpub-summary-item {
  display: inline-flex;
  align-items: baseline;
  white-space: nowrap;
}

.cpub-summary-item:not(:last-child)::after {
  content: "·";
  margin-left: 0.75rem;
  color: var(--cpub-muted);
  font-weight: 400;
}

/* ----------------------------------------------------------------- sections */

/* CAT-MEDIA-2-FIX — OGNI SEZIONE BERSAGLIO DI UN'ANCORA ATTERRA PULITA.
 *
 * Senza `scroll-margin-top` il browser incolla il bordo dell'elemento al bordo
 * alto della finestra: il titolo della sezione finisce a filo, tagliato dalla
 * barra del browser su telefono, e sembra che la pagina sia saltata a metà
 * invece di essere arrivata. Il valore è lo stesso `padding` della sezione più
 * un respiro, così il titolo si stacca dal bordo esattamente come si stacca
 * dalla sezione precedente.
 *
 * Vale per TUTTE le sezioni con un `id`, non solo per le tre che le pillole
 * nominano oggi: una sezione nuova che diventi bersaglio domani non deve
 * dover ricordarsi di aggiungerlo. */
/* --------------------------------------- CAT-SCHEDA-3 C4 — le sezioni
 *
 * Nel mock le sezioni non hanno filetti né imbottiture: sono separate da 44px
 * di respiro e basta, e il titolo è una piccola etichetta maiuscola invece di
 * un'intestazione grande. È ciò che fa sembrare la pagina un documento e non
 * una serie di riquadri.
 */
.cpub-section {
  padding: 0;
  border-top: 0;
  scroll-margin-top: 1.75rem;
}

.cpub-section h2 {
  margin: 0 0 16px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--cpub-muted);
}

/* ----------------------------------------------------------------- gallery */

.cpub-room + .cpub-room {
  margin-top: 1rem;
}

.cpub-room-name {
  margin: 0 0 0.5rem;
  font-size: 0.8125rem;
  font-weight: 600;
  text-transform: capitalize;
  color: var(--cpub-muted);
}

.cpub-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--cpub-gap);
}

.cpub-figure {
  margin: 0;
  border-radius: var(--cpub-radius);
  overflow: hidden;
  background: var(--cpub-soft);
}

.cpub-figure img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
}

.cpub-figure figcaption {
  padding: 0.4rem 0.6rem;
  font-size: 0.8125rem;
  color: var(--cpub-muted);
}

/* ----------------------------------------------------- gallery (CAT-UX-2) */

/* La copertina. 4:3 sul telefono, 16:10 da 40rem in su: le due proporzioni sono
 * quelle che riempiono lo schermo senza tagliare una stanza a metà. `aspect-ratio`
 * riserva lo spazio prima che l'immagine arrivi, quindi la pagina non salta. */

.cpub-hero {
  margin: 0 0 0.75rem;
}

.cpub-hero-frame {
  position: relative;
  display: block;
  aspect-ratio: 4 / 3;
  border-radius: 12px;
  overflow: hidden;
  background: var(--cpub-soft);
  cursor: zoom-in;
  /* È un <a>: senza questo, la sottolineatura di default del browser passa
   * sotto le due pillole e le fa sembrare due link a sé. */
  text-decoration: none;
}

/* CAT-UX-3 — l'invito ad aprire la galleria. Pillola CHIARA come il contatore:
 * l'affordance non si paga con un velo scuro sopra la foto. Sta in basso a
 * sinistra, dalla parte opposta del contatore, così le due non si toccano mai
 * nemmeno con etichette lunghe. */
.cpub-hero-hint {
  position: absolute;
  left: 0.6rem;
  bottom: 0.6rem;
  padding: 0.15rem 0.6rem;
  border: 1px solid var(--cpub-line);
  border-radius: 999px;
  background: var(--cpub-pill);
  color: var(--cpub-ink);
  font-size: 0.8125rem;
  font-weight: 550;
}

.cpub-hero-hint::before {
  content: "⤢";
  margin-right: 0.35rem;
}

.cpub-hero-frame:hover .cpub-hero-hint,
.cpub-hero-frame:focus-visible .cpub-hero-hint {
  border-color: var(--cpub-active);
  color: var(--cpub-chip-ink);
}

.cpub-hero-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Il contatore: pillola CHIARA in basso a destra. Nessun velo scuro sopra la
 * foto — la foto è il prodotto, e un pannello nero sopra il prodotto è la cosa
 * che i portali fanno e che qui non si fa. */
.cpub-hero-counter {
  position: absolute;
  right: 0.6rem;
  bottom: 0.6rem;
  margin: 0;
  padding: 0.15rem 0.55rem;
  border: 1px solid var(--cpub-line);
  border-radius: 999px;
  background: var(--cpub-pill);
  color: var(--cpub-ink);
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
}

.cpub-hero-caption {
  padding: 0.4rem 0.1rem 0;
  font-size: 0.875rem;
  color: var(--cpub-muted);
}

/* I chip dei media tipizzati. */

.cpub-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0 0 0.9rem;
  padding: 0;
  list-style: none;
}

.cpub-chip {
  display: inline-block;
  padding: 0.25rem 0.7rem;
  border: 1px solid var(--cpub-chip-line);
  border-radius: 999px;
  background: var(--cpub-chip-surface);
  color: var(--cpub-chip-ink);
  font-size: 0.8125rem;
  font-weight: 550;
  text-decoration: none;
}

.cpub-chip:hover,
.cpub-chip:focus-visible {
  border-color: var(--cpub-active);
}

/* Il carosello. Scorrimento nativo + scroll-snap: sul telefono è lo swipe del
 * sistema, su desktop è la rotella o la barra, e in nessun caso è JavaScript. */

.cpub-strip {
  display: flex;
  gap: 0.6rem;
  margin: 0;
  padding: 0 0 0.4rem;
  list-style: none;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: thin;
}

.cpub-strip-item {
  flex: 0 0 auto;
  scroll-snap-align: start;
}

.cpub-thumb {
  display: block;
  width: 150px;
  border: 2px solid transparent;
  border-radius: 10px;
  overflow: hidden;
  background: var(--cpub-bg);
  color: inherit;
  text-decoration: none;
}

.cpub-thumb-frame {
  position: relative;
  display: block;
  aspect-ratio: 4 / 3;
  background: var(--cpub-soft);
}

.cpub-thumb-frame img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Il nome della stanza sta SOTTO la foto, su fondo chiaro: mai sovrapposto. */
.cpub-thumb-label {
  display: block;
  padding: 0.3rem 0.35rem;
  background: var(--cpub-soft);
  color: var(--cpub-ink);
  font-size: 13px;
  line-height: 1.3;
  text-align: center;
  text-transform: capitalize;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cpub-thumb--current {
  border-color: var(--cpub-active);
}

.cpub-thumb:hover .cpub-thumb-label,
.cpub-thumb:focus-visible .cpub-thumb-label {
  color: var(--cpub-chip-ink);
}

/* La card «Vedi tutte» senza anteprima (la striscia mostra già tutte le foto):
 * un riquadro chiaro con una freccia, non un buco. Lo stato è una CLASSE decisa
 * dal server e non un `:has(img)`: un selettore che il browser non conoscesse
 * lascerebbe il bordo tratteggiato attorno a una foto. */
.cpub-thumb-frame--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px dashed var(--cpub-line);
  border-radius: 8px;
  color: var(--cpub-muted);
}

.cpub-thumb-frame--empty::after {
  content: "→";
  font-size: 1.5rem;
}

/* «Vedi tutte»: l'unico velo della pagina, ed è CHIARO. */
.cpub-thumb-veil {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--cpub-veil);
  color: var(--cpub-ink);
  font-size: 0.9375rem;
  font-weight: 600;
}

.cpub-nophotos {
  margin: 0;
  padding: 1.25rem;
  border: 1px dashed var(--cpub-line);
  border-radius: var(--cpub-radius);
  background: var(--cpub-soft);
  color: var(--cpub-muted);
  text-align: center;
  font-size: 0.9375rem;
}

/* ------------------------------------------------- full photo view (Fase 3) */

.cpub-header--photos {
  margin-bottom: 1rem;
}

.cpub-back {
  margin: 0 0 0.5rem;
  font-size: 0.875rem;
}

.cpub-room-section:first-of-type {
  border-top: 0;
  padding-top: 0;
}

/* Foto grandi: due colonne su desktop invece delle tre della griglia comune —
 * questa pagina esiste per guardare le fotografie, non per elencarle. Una sola
 * colonna sul telefono la eredita da .cpub-grid. */
.cpub-grid--photos {
  gap: 1.25rem;
}

/* L'ancora non deve incollare la foto al bordo superiore della finestra: senza
 * questo, arrivando da `#foto-<n>` non si vede che quella foto ha un titolo di
 * stanza sopra, e si perde il contesto proprio nel momento in cui serve. */
.cpub-photo-card {
  scroll-margin-top: 1.5rem;
  margin: 0;
  border: 2px solid transparent;
  border-radius: var(--cpub-radius);
  overflow: hidden;
  background: var(--cpub-soft);
}

.cpub-photo-card img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.cpub-photo-card figcaption {
  padding: 0.4rem 0.6rem;
  background: var(--cpub-soft);
  color: var(--cpub-ink);
  font-size: 13px;
  text-align: center;
}

.cpub-photo-card--cover {
  border-color: var(--cpub-active);
}

.cpub-room-fallback {
  text-transform: capitalize;
}

/* Visibile al lettore di schermo, non alla vista. */
.cpub-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------- specifics */

/* ------------------------------------------ CAT-SCHEDA-3 C4 — la descrizione
 *
 * 66ch e non la larghezza della colonna: una riga di prosa piu' lunga di
 * ~66 caratteri si legge male perche' l'occhio perde il capo della riga
 * successiva. E' la sola misura del mock che non e' un'estetica ma una regola
 * di leggibilita', ed e' il motivo per cui il testo qui e' piu' grande (18px)
 * del resto della pagina: e' l'unico blocco che si LEGGE invece di scorrere. */
.cpub-description {
  margin: 0;
  max-width: 66ch;
  font-size: 18px;
  line-height: 1.62;
  color: var(--cpub-ink-2);
  text-wrap: pretty;
  white-space: normal;
}

/* ------------------------------------- CAT-SCHEDA-3 C4 — la card dei dati
 *
 * Il riquadro bianco su fondo caldo e' cio' che separa i dati dalla prosa
 * senza mettere un titolo grande: si vede che e' una tabella prima di averla
 * letta. `auto-fit` con minimo 250px e' il mock: due colonne quando ci stanno,
 * una quando non ci stanno, e nessuna media query da tenere allineata alla
 * larghezza della colonna laterale.
 *
 * Il filetto e' CONTINUO e non punteggiato: il punteggiato faceva sembrare
 * ogni riga un campo da compilare. */
/* La cornice bianca e' condivisa: dati di schema e servizi vicini sono la
 * stessa cosa — una tabella di fatti — e devono somigliarsi. */
.cpub-specs,
.cpub-databox {
  background: var(--cpub-surface);
  border: 1px solid var(--cpub-line);
  border-radius: var(--cpub-r-lg);
  padding: 8px clamp(16px, 2.2vw, 24px) 22px;
}

.cpub-specs {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  column-gap: 48px;
}

.cpub-spec {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  padding: 13px 0;
  border-bottom: 1px solid var(--cpub-line-row);
  font-size: 16px;
}

.cpub-spec dt {
  color: var(--cpub-muted);
}

.cpub-spec dd {
  margin: 0;
  font-weight: 600;
  text-align: right;
}

/* ------------------------------------------------------------ media & links */

.cpub-video {
  width: 100%;
  border-radius: var(--cpub-radius);
  background: #000;
}

.cpub-caption,
.cpub-videolink,
.cpub-address {
  margin: 0.5rem 0 0;
  font-size: 0.9375rem;
}

/* --------------------------------- CAT-SCHEDA-3 C3 — i quadrati media
 *
 * Quattro card quadrate sotto il mosaico, con l'icona sopra e il conteggio
 * sotto. Sostituiscono le pillole e non le loro destinazioni.
 */
.cpub-media {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  /* CAT-SCHEDA-3-FIX — LO STACCO DAL MOSAICO, e il numero non e' arbitrario.
   *
   * La scala del design ha tre ritmi verticali, e questo e' il secondo:
   * 16px separa un titolo dal suo blocco (`h2`), 24px separa due BLOCCHI
   * dentro la stessa sezione, 44px separa una sezione dall'altra
   * (`.cpub-body`). I quadrati sono un blocco a se' dentro la sezione «Foto»,
   * quindi 24 — con 16 sarebbero sembrati la didascalia del mosaico, con 44 un
   * capitolo nuovo.
   *
   * NON e' un token: sarebbe un token usato una volta sola, e un nome che vale
   * per un posto solo e' un nome che il prossimo dovra' comunque andare a
   * leggere. Il valore sta nella scala, e la scala e' scritta qui sopra. */
  margin: 24px 0 0;
  padding: 0;
  list-style: none;
}

/* LA MISURA STA SUL `<li>`, non sull'ancora. L'elenco e' `ul > li > a`: i
 * figli flessibili sono i `<li>`, e un `flex: 0 1 116px` scritto sull'ancora
 * non lo legge nessuno — la card si allargava sul suo contenuto, e «1
 * planimetria» (l'etichetta piu' lunga) diventava piu' alta delle altre tre
 * sfilando la riga. Visto nello screenshot, non dedotto.
 *
 * `align-items: stretch` (il default) fa poi il resto: le quattro caselle
 * hanno tutte l'altezza della piu' alta, quindi la riga resta una riga anche
 * quando un'etichetta va a capo. */
.cpub-media > li {
  display: flex;
  flex: 0 1 116px;
}

.cpub-media-card {
  display: flex;
  flex: 1;
  min-width: 0;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 9px;
  aspect-ratio: 1;
  padding: 10px;
  border: 1px solid var(--cpub-border-soft);
  border-radius: var(--cpub-r-xl);
  background: var(--cpub-surface);
  color: var(--cpub-ink);
  text-align: center;
  text-decoration: none;
}

.cpub-media-card:hover,
.cpub-media-card:focus-visible {
  border-color: var(--cpub-border);
  background: #FDFAF4;
  color: var(--cpub-ink);
  text-decoration: none;
}

.cpub-media-card span {
  font-size: 14px;
  font-weight: 600;
}

.cpub-media-card svg {
  fill: none;
  stroke: var(--cpub-accent);
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Su telefono i quadrati si dividono la riga a due a due invece di scendere in
 * colonna: 116px fissi su 390 px lascerebbero un vuoto a destra. */
@media (max-width: 26rem) {
  .cpub-media > li { flex: 1 1 calc(50% - 4px); }
}

/* ------------------------------------------- CAT-MEDIA-2 B2 — il mosaico
 *
 * Una foto grande e fino a quattro celle. Su telefono è una colonna: la foto
 * grande e sotto le celle a due a due — quattro francobolli in fila su 390 px
 * sarebbero illeggibili, e la foto è il prodotto.
 */
/* IL RETTANGOLO UNICO, e come si costruisce.
 *
 * Le celle hanno un rapporto fisso (4/3) e sono le RIGHE della griglia a
 * nascere da lì; la cover spanna le righe che esistono, quindi il suo bordo
 * alto e il suo bordo basso coincidono con quelli della prima e dell'ultima
 * fila **per costruzione** — non per un'altezza scritta a mano che il giorno
 * dopo non torna più. `object-fit: cover` su tutte le immagini fa il resto: il
 * rapporto dell'originale non deforma mai una cella.
 *
 * Le quattro disposizioni sotto esistono perché con meno di quattro celle una
 * griglia «naturale» lascerebbe un buco, e un buco è un bordo che sfila. Sono
 * quattro righe di CSS, e sono la ragione per cui il numero di celle sta nel
 * markup come classe.
 */
.cpub-mosaic {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* --- telefono: la cover a tutta larghezza, le celle a due a due ----------- */
.cpub-mosaic-hero {
  grid-column: 1 / -1;
}

/* Su TELEFONO, con una cella sola o con la terza dispari, la cella si allarga:
 * mezza riga vuota è il bordo sfilato che questo mandato vieta. Da 40rem in su
 * queste due righe vengono sovrascritte dalla disposizione a rettangolo. */
@media (max-width: 39.999rem) {
  .cpub-mosaic--n1 .cpub-mosaic-cell,
  .cpub-mosaic--n3 .cpub-mosaic-cell:last-child {
    grid-column: 1 / -1;
  }

  /* A tutta larghezza il 4/3 diventa un'immagine alta quanto mezzo telefono e
   * ruba la scena alla copertina: la cella dispari resta panoramica. */
  .cpub-mosaic--n1 .cpub-mosaic-cell .cpub-mosaic-open,
  .cpub-mosaic--n3 .cpub-mosaic-cell:last-child .cpub-mosaic-open {
    aspect-ratio: 16 / 9;
  }
}

/* CAT-MEDIA-2-FIX2 — LA TESSERA GRANDE NON CONTIENE PIÙ NIENTE OLTRE ALLA
 * FOTO. La didascalia era un paragrafo dentro questa cella e le rubava
 * l'altezza: il bordo basso della cover finiva 33 px sopra quello delle
 * miniature. Il rettangolo unico si tiene togliendo la causa, non
 * compensandola — per questo qui sotto non c'è più nessuna regola che rimetta
 * in colonna la cella grande. */
.cpub-mosaic-open {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--cpub-radius);
  background: var(--cpub-soft);
  aspect-ratio: 4 / 3;
}

.cpub-mosaic-hero .cpub-mosaic-open {
  aspect-ratio: 16 / 10;
}

/* L'IMMAGINE È FUORI DAL FLUSSO, ed è la riga che rende il rettangolo esatto
 * invece che fortunato.
 *
 * Con l'immagine nel flusso, l'altezza naturale della foto grande partecipa a
 * dimensionare le righe della griglia: con quattro celle i conti tornavano per
 * caso (le due file erano più alte della cover), con una cella sola no — il
 * bordo basso sfilava di 163 px, e con una foto verticale sarebbe sfilato
 * anche negli altri casi. Posizionata in assoluto, la foto NON dice più niente
 * sull'altezza: la decidono le celle, e la cover si stira su quello che c'è.
 *
 * `object-fit: cover` fa il resto: il rapporto dell'originale — orizzontale,
 * verticale, quadrato — non deforma mai una cella. */
.cpub-mosaic-img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Il velo dell'ultima cella è CHIARO, come ogni altro velo di questa pagina:
 * un pannello nero sopra la foto è ciò che fanno i portali e che qui non si fa
 * (CAT-UX-2). */
.cpub-mosaic-veil {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--cpub-veil);
  color: var(--cpub-ink);
  font-size: 1rem;
  font-weight: 600;
}

.cpub-mosaic-open:hover .cpub-hero-hint,
.cpub-mosaic-open:focus-visible .cpub-hero-hint {
  border-color: var(--cpub-active);
  color: var(--cpub-chip-ink);
}

/* ------------------------------------------ CAT-MEDIA-2 B1 — il riquadro
 *
 * Zero JavaScript: apre `:target`, chiude un link. Le due proprietà che lo
 * rendono utilizzabile stanno qui sotto e non sono decorazione.
 */
/* CHIUSO NON ESISTE. `display: none` sul contenitore fa due cose in una riga:
 * niente riquadro, e — poiché un `<img>` in un sottoalbero non renderizzato non
 * viene scaricato — nessuna delle immagini grandi parte al caricamento della
 * pagina. È ciò che rende sostenibili ventitré riquadri in una scheda: senza,
 * il mosaico risparmierebbe banda e il riquadro la ributterebbe via.
 *
 * LO SCROLL-JUMP NON C'È, ed è misurato: aprendo `#lb-3` da metà pagina
 * `scrollY` non si muove (uno smoke lo verifica cambiando l'ancora, non
 * cliccando — un clic fa scorrere il browser di test prima ancora di premere,
 * e per un'ora quella è sembrata la pagina che saltava). */
.cpub-lb {
  display: none;
}

.cpub-lb:target {
  display: flex;
  position: fixed;
  inset: 0;
  z-index: 50;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  /* L'UNICO fondo scuro ammesso in questa pagina, e non è sopra la foto di
   * qualcuno: è il buio INTORNO, che è ciò che un riquadro deve fare per far
   * risaltare l'immagine. La regola «mai un velo scuro sopra una foto» resta
   * intatta. */
  background: rgba(15, 17, 20, 0.92);
}

/* LA PAGINA SOTTO NON SCORRE mentre il riquadro è aperto. `clip` e non
 * `hidden`: il secondo crea un contenitore di scorrimento e può riposizionare
 * la pagina. `:has()` è supportato da tutti i motori correnti; dove non lo
 * fosse, lo sfondo scorre e il riquadro resta leggibile — una degradazione che
 * si vede e non rompe niente. */
body:has(.cpub-lb:target) {
  overflow: clip;
}

.cpub-lb-backdrop {
  position: absolute;
  inset: 0;
}

/* Il pannello si stringe SULL'IMMAGINE (`fit-content`) e non sulla finestra:
 * altrimenti la barra con il contatore e la X si allarga per tutto lo schermo
 * e i controlli finiscono lontani dalla foto a cui appartengono — visto in uno
 * screenshot, non dedotto. */
.cpub-lb-panel {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  width: fit-content;
  max-width: min(96vw, 76rem);
  max-height: 94vh;
}

.cpub-lb-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  color: #fff;
}

.cpub-lb-counter {
  font-size: 0.9375rem;
  font-variant-numeric: tabular-nums;
}

/* La X è il PRIMO elemento focalizzabile del pannello: senza focus trap (che
 * senza JavaScript non esiste) almeno il primo Tab dentro il riquadro cade
 * sulla chiusura. */
.cpub-lb-close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
  font-size: 1.5rem;
  line-height: 1;
  text-decoration: none;
}

.cpub-lb-close:hover,
.cpub-lb-close:focus-visible {
  background: rgba(255, 255, 255, 0.28);
}

.cpub-lb-img {
  display: block;
  max-width: 100%;
  max-height: 82vh;
  margin: 0 auto;
  object-fit: contain;
  border-radius: 6px;
}

.cpub-lb-caption {
  margin: 0;
  color: #fff;
  font-size: 0.9375rem;
  text-align: center;
}

/* LE FRECCE SONO GRANDI, ed è la contropartita dichiarata della rinuncia allo
 * swipe: su un telefono si preme col pollice, quindi 3rem e non un chevron da
 * un centimetro. */
.cpub-lb-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
  font-size: 2rem;
  line-height: 1;
  text-decoration: none;
}

.cpub-lb-nav:hover,
.cpub-lb-nav:focus-visible {
  background: rgba(255, 255, 255, 0.28);
}

.cpub-lb-prev { left: -0.25rem; }
.cpub-lb-next { right: -0.25rem; }

@media (min-width: 40rem) {
  .cpub-lb-prev { left: -3.5rem; }
  .cpub-lb-next { right: -3.5rem; }
}

/* ------------------------------------- CAT-MEDIA-FIX-1 — la facciata video
 *
 * Un riquadro NOSTRO che si comporta come un pulsante: nessun fotogramma preso
 * da un terzo (sarebbe una richiesta a Google al caricamento di una pagina
 * pubblica) e nessun iframe (`frame-src` non è aperto, e nei due frame inerti
 * non si potrebbe sostituire al clic). Dice che c'è un video e dove porta —
 * che è ciò che serviva e che una riga di testo azzurro non diceva.
 */
/* CAT-SCHEDA-3 C3 — la facciata prende i valori del mock: card bianca, bordo
 * che si scurisce al passaggio, miniatura 120x78 su fondo inchiostro. Il
 * comportamento non cambia di una riga: e' sempre un link che porta fuori e
 * lo dice. */
.cpub-videocard {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-top: 0.75rem;
  padding: 16px;
  border: 1px solid var(--cpub-line);
  border-radius: var(--cpub-r-lg);
  background: var(--cpub-surface);
  color: var(--cpub-ink);
  text-decoration: none;
}

.cpub-videocard:hover,
.cpub-videocard:focus-visible {
  border-color: var(--cpub-ink);
  color: var(--cpub-ink);
  text-decoration: none;
}

.cpub-videocard-frame {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 120px;
  height: 78px;
  border-radius: var(--cpub-r-sm);
  /* Il rettangolo scuro è il CONTENITORE del pulsante, non un velo sopra la
   * foto di qualcuno: qui non c'è nessuna immagine sotto. */
  background: var(--cpub-ink);
  /* L'ambra chiaro del mock (#E08A0C) sta sull'inchiostro, non sul testo: e'
   * un elemento grafico, non una parola da leggere. */
  color: #e08a0c;
}

/* Con la miniatura il riquadro diventa un fotogramma: più largo, in 16/9, e il
 * pulsante play ci sta sopra — che è la forma che tutti riconoscono. Senza,
 * resta il rettangolo disegnato: stessa riga, stessa altezza, nessun salto di
 * layout fra una voce che ha la miniatura e una che non ce l'ha. */
.cpub-videocard-frame--poster {
  position: relative;
  width: 12rem;
  height: 6.75rem;
  overflow: hidden;
}

.cpub-videocard-title {
  font-size: 18px;
}

.cpub-videocard-poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.cpub-videocard-play {
  position: relative;
  width: 2.25rem;
  height: 2.25rem;
  /* Sopra la miniatura serve un contorno: un cerchio ambra su un fotogramma
   * chiaro sparisce, e il play è l'unica cosa che dice «si può premere». */
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.55));
}

.cpub-videocard-text {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}

.cpub-videocard-title {
  font-weight: 600;
  overflow-wrap: anywhere;
}

/* DOVE SI VA, scritto prima del clic. Un link che porta fuori dal sito senza
 * dirlo è il genere di link che un visitatore impara a non premere. */
.cpub-videocard-host {
  font-size: 14px;
  color: var(--cpub-muted);
}

/* -------------------------- CAT-MEDIA-FIX-1 — aprire un media a grandezza vera
 *
 * Planimetria e foto usano la STESSA classe: erano gli unici due media della
 * scheda che non si potevano guardare da vicino, e ora si aprono allo stesso
 * modo. La pillola è chiara come tutte le altre di questa pagina — mai un velo
 * scuro sopra l'immagine di qualcun altro. */
.cpub-figure-open {
  position: relative;
  display: block;
  color: inherit;
  text-decoration: none;
}

/* SEMPRE VISIBILE, come la pillola della copertina — e per la stessa ragione
 * già scritta in CAT-UX-3: che un media si possa aprire va DETTO. Un cursore
 * che cambia lo scopre solo chi ha un mouse e ci passa sopra per caso, e su un
 * telefono non esiste affatto. Mostrarla al passaggio sarebbe stato più
 * elegante e meno utile — e avrebbe ricreato in piccolo il difetto che questo
 * mandato chiude: un'azione che c'è e non si vede. */
.cpub-figure-hint {
  position: absolute;
  right: 0.6rem;
  bottom: 0.6rem;
  padding: 0.15rem 0.6rem;
  border: 1px solid var(--cpub-line);
  border-radius: 999px;
  background: var(--cpub-pill);
  color: var(--cpub-ink);
  font-size: 0.8125rem;
  font-weight: 550;
}

.cpub-figure-hint::before {
  content: "⤢";
  margin-right: 0.35rem;
}

/* ---------------------------------------- CAT-SCHEDA-3 C4 — le planimetrie
 *
 * Tessere affiancate alte 260px, non una griglia di ritagli 3:2. Una
 * planimetria e' un DISEGNO: ritagliata perde proprio i bordi delle stanze,
 * che sono l'informazione. `contain` la mostra intera su fondo bianco, come
 * un foglio appoggiato sul tavolo.
 *
 * Il badge «Ingrandisci» sta a cavallo del bordo basso, centrato: e' la forma
 * del mock, e ha il pregio di non coprire il disegno. Per stare a cavallo
 * serve `overflow: visible` sulla tessera, quindi gli angoli arrotondati li
 * porta il link dentro. */
.cpub-plans {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  /* Lo spazio che il badge sporgente si prende sotto l'ultima riga. */
  padding-bottom: 14px;
}

.cpub-plans .cpub-figure {
  flex: 1 1 300px;
  position: relative;
  overflow: visible;
  background: var(--cpub-surface);
  border: 1px solid var(--cpub-line);
  border-radius: var(--cpub-r-lg);
}

.cpub-plans .cpub-figure-open {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 260px;
  padding: 10px;
  overflow: hidden;
  border-radius: var(--cpub-r-lg);
}

.cpub-plans .cpub-figure-open img {
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  object-fit: contain;
}

.cpub-plans .cpub-figure-hint {
  right: auto;
  left: 50%;
  bottom: -14px;
  transform: translateX(-50%);
  padding: 8px 14px;
  border: 1px solid var(--cpub-border);
  border-radius: var(--cpub-r-pill);
  background: var(--cpub-surface);
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
}

.cpub-plans .cpub-figure figcaption {
  padding: 0.5rem 0.6rem 0;
  text-align: center;
}

.cpub-figure-open:hover .cpub-figure-hint,
.cpub-figure-open:focus-visible .cpub-figure-hint {
  border-color: var(--cpub-active);
  color: var(--cpub-chip-ink);
}

.cpub-docs {
  margin: 0;
  padding-left: 1.1rem;
}

.cpub-docs li + li {
  margin-top: 0.3rem;
}

/* -------------------------------------------- CAT-SCHEDA-3 C4 — i link
 *
 * IL COLORE DEL LINK E' L'UNICO PUNTO IN CUI IL MOCK NON SI ADOTTA 1:1, e la
 * ragione e' quella dichiarata nella gerarchia delle fonti: dove il design
 * confligge con un obbligo di piattaforma, vince la piattaforma.
 *
 * Il mock usa `--accent` (#B96206) per il testo dei link: su fondo crema fa
 * 4,3:1, sotto il 4,5:1 che WCAG 2.1 AA chiede per il testo — e questa e' una
 * pagina PUBBLICA, cioe' esattamente il perimetro dello European Accessibility
 * Act. Il testo dei link prende quindi `--accent-strong` (6,76:1), che e' il
 * colore che il mock stesso usa al passaggio: la tavolozza non cambia, cambia
 * quale dei suoi due ambra porta il testo.
 *
 * `--accent` resta dov'e' giusto: icone, anello di fuoco, segni decorativi.
 * Sono elementi non testuali, per i quali la soglia e' 3:1 e 4,3:1 la supera. */
/* `:where()` NON PESA NULLA sulla specificita', ed e' la ragione per cui e'
 * scritto cosi'. Con un normale `.cpub a` questa regola varrebbe (0,1,1) e
 * batterebbe OGNI componente scritto con una classe sola: il testo bianco del
 * bottone scuro diventava ambra (illeggibile: 1,9:1), e con lui le etichette
 * dei quadrati media e l'invito dell'assistente. Visto nello screenshot della
 * pagina «in costruzione», non dedotto.
 *
 * Con `:where(.cpub)` la regola vale quanto un selettore di tipo: e' il colore
 * di DEFAULT di un link, e qualunque componente lo sovrascrive semplicemente
 * esistendo. */
:where(.cpub) a {
  color: var(--cpub-accent-strong);
  text-decoration: none;
}

:where(.cpub) a:hover {
  text-decoration: underline;
}

a {
  color: #0b5cad;
}

/* CAT-GEO-3 — la mappa della posizione. Stessa cornice della galleria: raggio
 * `--cpub-radius`, fondo tenue mentre l'immagine carica, nessun velo e nessuna
 * scritta sopra. `aspect-ratio` corrisponde al 640x400 che gli adapter
 * chiedono ai provider (8/5): senza, la pagina salta di 200px quando
 * l'immagine arriva, e su una connessione lenta il salto capita mentre si sta
 * leggendo l'indirizzo. */
.cpub-map {
  margin: 0.75rem 0 0;
  /* CAT-GEO-3b — il riferimento del pulsante di ingrandimento, che gli sta
   * sopra. Senza questo, `position: absolute` risalirebbe fino alla pagina e
   * il pulsante finirebbe in un angolo dello schermo. */
  position: relative;
}

.cpub-map-img {
  display: block;
  width: 100%;
  aspect-ratio: 8 / 5;
  object-fit: cover;
  border-radius: var(--cpub-r-lg);
  background: var(--cpub-soft);
  border: 1px solid var(--cpub-line);
}

/* CAT-GEO-3b — «Ingrandisci mappa». SOPRA l'immagine, in basso a destra: è la
 * convenzione dei portali immobiliari, ed è dove la mano lo cerca. Fondo
 * quasi-bianco (`--cpub-pill`, lo stesso dei controlli della galleria) perché
 * deve leggersi su qualunque cosa ci sia sotto — mare, bosco, centro storico —
 * senza mettere un velo sull'immagine. */
/* CAT-SCHEDA-3 C4 — il badge passa IN ALTO a destra, com'e' nel mock. In
 * basso a destra e' dove i provider stampano la loro attribuzione dentro
 * l'immagine (e' la condizione della licenza): il pulsante ci finiva sopra, e
 * coprire un'attribuzione dovuta e' un problema di licenza prima che di
 * grafica. */
.cpub-map-zoom {
  position: absolute;
  right: 12px;
  top: 12px;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.4rem 0.7rem;
  font: inherit;
  font-size: 0.875rem;
  color: var(--cpub-ink);
  background: var(--cpub-surface);
  border: 1px solid var(--cpub-border);
  border-radius: var(--cpub-r-pill);
  font-weight: 600;
  cursor: pointer;
  box-shadow: 0 1px 3px rgb(0 0 0 / 18%);
}

.cpub-map-zoom:hover {
  background: #fff;
}

.cpub-map-zoom:focus-visible {
  outline: 2px solid var(--cpub-accent);
  outline-offset: 2px;
}

/* ------------------------------------------------- CAT-GEO-3b — l'overlay */

/* Quasi a schermo pieno, come su Idealista o Booking: la mappa serve a
 * guardarsi intorno, e un francobollo non lo permette. `padding: 0` perché il
 * contenuto è una testata e una tela, e la tela arriva ai bordi. */
.cpub-mapmodal {
  width: min(96vw, 1100px);
  height: min(90vh, 780px);
  padding: 0;
  border: 0;
  border-radius: var(--cpub-radius);
  background: var(--cpub-bg);
  color: var(--cpub-ink);
  overflow: hidden;
}

.cpub-mapmodal::backdrop {
  background: rgb(0 0 0 / 55%);
}

.cpub-mapmodal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.6rem 0.75rem 0.6rem 1rem;
  border-bottom: 1px solid var(--cpub-line);
}

/* L'INDIRIZZO ANCHE QUI. Chi apre la mappa a schermo pieno perde di vista la
 * scheda sotto: senza l'indirizzo nella testata resterebbe a guardare un
 * punto su una mappa senza sapere più di quale casa si sta parlando. */
.cpub-mapmodal-title {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cpub-mapmodal-close {
  flex: none;
  width: 2rem;
  height: 2rem;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--cpub-muted);
  background: transparent;
  border: 0;
  border-radius: 999px;
  cursor: pointer;
}

.cpub-mapmodal-close:hover {
  background: var(--cpub-soft);
  color: var(--cpub-ink);
}

.cpub-mapmodal-close:focus-visible {
  outline: 2px solid var(--cpub-accent);
  outline-offset: 1px;
}

.cpub-mapmodal-canvas {
  width: 100%;
  height: calc(100% - 3rem);
  background: var(--cpub-soft);
}

/* Il marker: ambra come quello dell'immagine statica, così l'ingrandimento
 * continua la stessa mappa invece di cambiarle aspetto. È CSS e non
 * un'immagine per una ragione precisa — vedi `catalog-map-modal.js`. */
.cpub-mapmodal-marker {
  background: var(--cpub-accent);
  border: 3px solid #fff;
  border-radius: 999px;
  box-shadow: 0 1px 4px rgb(0 0 0 / 45%);
}

/* Il proxy risponde 503 quando il budget della card è finito: senza una
 * frase, il visitatore resta davanti a un riquadro grigio e conclude che il
 * sito sia rotto. Compare solo quando il JS ha visto abbastanza tile cadere. */
.cpub-mapmodal-degraded {
  display: none;
  margin: 0;
  padding: 0.6rem 1rem;
  font-size: 0.875rem;
  color: var(--cpub-muted);
  background: var(--cpub-soft);
  border-top: 1px solid var(--cpub-line);
}

.cpub-mapmodal.is-degraded .cpub-mapmodal-degraded {
  display: block;
}

.cpub-mapmodal.is-degraded .cpub-mapmodal-canvas {
  height: calc(100% - 6rem);
}

/* Su telefono l'overlay prende tutto: i controlli di Leaflet e la X restano
 * raggiungibili col pollice, e non resta un bordo di pagina cliccabile per
 * sbaglio mentre si panna. */
@media (max-width: 40rem) {
  .cpub-mapmodal {
    width: 100vw;
    height: 100dvh;
    max-width: none;
    max-height: none;
    border-radius: 0;
  }
}

.cpub-footer {
  margin-top: 1.5rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--cpub-line);
  font-size: 0.8125rem;
  color: var(--cpub-muted);
}

/* --------------------------------------------------------------- wide screens */

@media (min-width: 40rem) {
  .cpub-card { padding: 2rem 2.5rem; }
  .cpub-title { font-size: 2rem; }
  .cpub-price-value { font-size: 1.75rem; }
  .cpub-grid { grid-template-columns: repeat(3, 1fr); }
  .cpub-hero-frame { aspect-ratio: 16 / 10; }
  /* CAT-MEDIA-FIX-1 — due o tre colonne secondo quanto spazio c'è, invece di
   * due fisse: `auto-fill` con una larghezza minima riempie la riga da sé, e
   * con una griglia sola (non più una per stanza) è ciò che impedisce alla
   * pagina di tornare una colonna con mezzo schermo bianco. Su mobile resta
   * una colonna, che la eredita da `.cpub-grid`. */
  .cpub-grid--photos { grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr)); }
  /* CAT-SCHEDA-3 C3 (D2) — IL MOSAICO PRENDE LA GEOMETRIA DEL MOCK.
   *
   * L'altezza la dichiara il CONTENITORE (`clamp(240px,38vw,460px)`) e le righe
   * valgono `1fr` ciascuna: il rettangolo è esatto per costruzione, e la cover
   * che spanna tutte le righe combacia con la prima e con l'ultima **senza che
   * nessuno calcoli niente**. È più robusto di quello che sostituisce — le
   * altezze derivate dal rapporto 4/3 delle celle hanno già richiesto due
   * correzioni (l'immagine fuori dal flusso, le righe esplicite) — e lascia
   * intatto ciò che lo smoke [4-decies] misura a ±1px.
   *
   * Le tessere restano FINO A QUATTRO (D2): il mock ne mostra due, ma quattro
   * è ciò che questa piattaforma ha già e mostrarne meno vorrebbe dire far
   * vedere meno casa. */
  /* LE RIGHE SONO ESPLICITE, e non è un dettaglio: con righe implicite
   * `grid-row: 1 / -1` conta fino all'ultima linea della griglia ESPLICITA —
   * che non esiste — e la cover finiva alta una riga sola (misurato: 170 px di
   * sfilamento). Due righe dichiarate, `auto` entrambe, dimensionate dal
   * rapporto delle celle. */
  .cpub-mosaic {
    grid-template-columns: 2fr 1fr 1fr;
    grid-template-rows: 1fr 1fr;
    height: clamp(240px, 38vw, 460px);
  }
  .cpub-mosaic-hero { grid-column: 1; grid-row: 1 / -1; }
  /* Con l'altezza sul contenitore nessuna cella dichiara più un rapporto: si
   * stirano tutte sulla riga che le ospita, ed è il motivo per cui il
   * rettangolo non può sfilare. */
  .cpub-mosaic-open,
  .cpub-mosaic-hero .cpub-mosaic-open { aspect-ratio: auto; height: 100%; }

  /* Nessuna cella: la cover prende tutto, con un rapporto suo — non c'è niente
   * a cui allinearsi, e una foto sola alta come due file sarebbe un manifesto. */
  .cpub-mosaic--n0 { grid-template-columns: 1fr; grid-template-rows: 1fr; }

  /* Una cella: due colonne, UNA riga. Cover e cella hanno la stessa altezza,
   * che è la definizione di rettangolo. */
  .cpub-mosaic--n1 { grid-template-columns: 2fr 1fr; grid-template-rows: 1fr; }
  .cpub-mosaic--n1 .cpub-mosaic-cell { grid-column: 2; }

  /* Due celle: due colonne, due righe, le celle impilate a destra. */
  .cpub-mosaic--n2 { grid-template-columns: 2fr 1fr; grid-template-rows: 1fr 1fr; }
  .cpub-mosaic--n2 .cpub-mosaic-cell { grid-column: 2; }

  /* Tre celle: tre colonne, e la terza si allarga sulle due di destra — così
   * la seconda fila è piena e il bordo basso resta uno solo.
   *
   * La cella larga NON detta la propria altezza (`aspect-ratio: auto`): con il
   * suo 4/3 su una larghezza doppia sarebbe alta il doppio della fila di sopra,
   * e il rettangolo diventerebbe sbilenco — allineato ai bordi, ma con due file
   * palesemente diverse. Si stira sulla riga, che vale `1fr` come l'altra. */
  .cpub-mosaic--n3 .cpub-mosaic-cell:last-child {
    grid-column: 2 / -1;
  }

  /* (Il rapporto sulle celle non esiste più: lo dà la riga.) */
  .cpub-summary { font-size: 1.0625rem; }
}

/* ------------------------------------------------------------ not available */

.cpub-empty {
  max-width: 32rem;
  margin: 4rem auto;
  padding: 2rem;
  text-align: center;
  background: var(--cpub-bg);
  border-radius: var(--cpub-radius);
}

.cpub-empty h1 {
  margin: 0 0 0.5rem;
  font-size: 1.25rem;
}

.cpub-empty p {
  margin: 0;
  color: var(--cpub-muted);
}

/* --------------------------------- CAT-GEO-4c — i servizi nelle vicinanze
 *
 * UNA GRIGLIA, NON UN ELENCO PUNTATO. È la resa che usano i portali (la
 * sezione POI di Tecnocasa, di Zillow) e la usano perché funziona: l'occhio
 * scorre una colonna di icone molto più in fretta di una colonna di parole, e
 * la distanza allineata a destra si confronta senza leggerla.
 *
 * Le righe sono `<li>` dentro `<ul>` per macro-gruppo: la semantica vera è
 * «un elenco di luoghi sotto un titolo», e il titolo è un `<h3>` — chi naviga
 * per intestazioni con uno screen reader salta da «Spesa quotidiana» a
 * «Trasporti» invece di attraversare quaranta righe.
 */
/* La classe che governa TUTTE le icone: il colore lo prende dal testo
 * (`currentColor` nel tag), quindi basta cambiare il colore del contenitore
 * per cambiare l'icona, e non esiste un'icona con un colore proprio da
 * inseguire. */
.poi-icon {
  display: inline-block;
  vertical-align: -0.15em;
  flex: none;
}

.cpub-nearby-group + .cpub-nearby-group {
  margin-top: 26px;
}

/* CAT-SCHEDA-3 C4 — l'etichetta di macro-gruppo prende la forma del mock:
 * ambra scuro, piccola, spaziata. E' il solo testo colorato della card, e
 * serve a far vedere i gruppi senza disegnare una riga di separazione fra
 * l'uno e l'altro. */
.cpub-nearby-head {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 18px 0 2px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--cpub-accent-strong);
}

.cpub-nearby-headicon {
  flex: none;
  color: var(--cpub-accent);
}

/* Due colonne da 40rem in su, una sotto: la regola sta nel blocco responsive
 * in fondo al file, insieme alle altre. Qui la colonna singola, che è il
 * default mobile-first del resto del foglio. */
.cpub-nearby-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.cpub-nearby-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: baseline;
  gap: 0.55rem;
  /* Senza questo la riga NON si stringe: le celle di una griglia hanno
   * `min-width: auto`, la colonna della distanza è `nowrap`, e la riga
   * diventava più larga della sua colonna facendo debordare la sezione. Lo
   * ha trovato lo smoke, guardando lo screenshot tagliato a destra. */
  min-width: 0;
  padding: 13px 0;
  border-bottom: 1px solid var(--cpub-line-row);
  font-size: 16px;
  color: var(--cpub-ink);
  /* Una riga non si spezza mai fra due pagine stampate: mezzo servizio in
   * fondo a un foglio si legge come un servizio diverso. */
  break-inside: avoid;
}

.cpub-nearby-icon {
  /* `baseline` sull'intera riga allineerebbe il fondo del disegno al testo e
   * l'icona sembrerebbe cadere: si allinea a mano, una volta. */
  align-self: center;
  flex: none;
  color: var(--cpub-muted);
}

.cpub-nearby-name {
  min-width: 0;
  font-weight: 600;
  /* Un nome lungo va a capo invece di spingere via la distanza: è la distanza
   * il dato che si confronta fra righe, e deve restare incolonnata. */
  overflow-wrap: anywhere;
}

/* La colonna della distanza PUÒ andare a capo fra la misura e i minuti — sono
 * due pezzi, non una frase sola — ma nessuno dei due si spezza al proprio
 * interno: «risulta a 1,8» su una riga e «km» sull'altra sarebbe illeggibile. */
.cpub-nearby-dist {
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--cpub-muted);
  font-size: 14px;
}

.cpub-nearby-metres {
  white-space: nowrap;
}

/* I minuti a piedi vanno a capo sotto i metri quando la riga è stretta: sono
 * la stessa misura detta in un altro modo, non un secondo dato, e su un
 * telefono guadagnare quella riga vale più che tenerli affiancati. */
.cpub-nearby-walk {
  display: block;
  white-space: nowrap;
  color: var(--cpub-muted);
  font-size: 0.8125rem;
}

/* La piega. `<details>` è HTML: nessun JavaScript, e le due superfici con
 * `script-src 'none'` si comportano come la pubblica. */
.cpub-nearby-more {
  margin-top: 0.9rem;
}

.cpub-nearby-more > summary {
  display: inline-block;
  padding: 0.35rem 0.75rem;
  border: 1px solid var(--cpub-line);
  border-radius: 999px;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--cpub-chip-ink);
  background: var(--cpub-chip-surface);
  cursor: pointer;
}

.cpub-nearby-more > summary:hover {
  border-color: var(--cpub-chip-line);
}

.cpub-nearby-more-body {
  margin-top: 0.9rem;
}

/* «indicato dall'inserzionista»: SEMPRE visibile, mai un titolo al passaggio
 * del mouse. La differenza fra un dato che abbiamo misurato e uno che ci
 * hanno detto deve essere leggibile da chi compra, non solo da noi — e su un
 * telefono un tooltip non esiste. */
/* «indicato dall'inserzionista» NON perde visibilità nel layout nuovo: la
 * pastiglia resta accanto al nome — dove la si legge insieme al nome, non in
 * fondo alla riga dove si legge insieme alla distanza — e l'icona della riga
 * prende l'ambra della scheda. Chi compra deve poter distinguere ciò che
 * abbiamo misurato da ciò che ci hanno detto, e su un telefono un tooltip non
 * esiste. */
.cpub-nearby-row--declared .cpub-nearby-icon {
  color: var(--cpub-accent);
}

.cpub-nearby-declared {
  display: inline-block;
  margin-left: 0.25rem;
  padding: 0.05rem 0.4rem;
  font-size: 0.75rem;
  color: var(--cpub-chip-ink);
  background: var(--cpub-chip-surface);
  border: 1px solid var(--cpub-chip-line);
  border-radius: 999px;
}

/* CAT-GEO-4c — due colonne da 40rem in su. STA QUI E NON NEL BLOCCO
 * RESPONSIVE GENERALE più in alto nel file: le regole base della griglia sono
 * scritte dopo quel blocco, e a parità di specificità vince l'ultima — la
 * media query perdeva, la scheda restava a una colonna su desktop e nessun
 * test Python poteva accorgersene. L'ha trovato lo smoke misurando
 * `grid-template-columns` nel browser. */
@media (min-width: 40rem) {
  .cpub-nearby-grid { grid-template-columns: 1fr 1fr; column-gap: 2rem; }
  .cpub-nearby-walk { display: inline; margin-left: 0.35rem; }
  .cpub-nearby-walk::before { content: "· "; }
}

.cpub-nearby-source {
  margin: 0.75rem 0 0;
  font-size: 0.8125rem;
  color: var(--cpub-muted);
}

/* ================================================ CAT-SCHEDA-3 C5 — le colonne
 *
 * WRAP INTRINSECO, NESSUNA MEDIA QUERY. `flex-wrap` piu' due larghezze minime:
 * finche' il contenuto sta in 520px e la colonna in 300px stanno affiancati,
 * altrimenti la colonna va a capo e diventa l'ultimo blocco della pagina.
 *
 * E' il meccanismo del mock, e ha un pregio che una media query non ha: la
 * soglia la decide il CONTENUTO e non la finestra. Questa scheda e' resa anche
 * dentro due frame larghi quanto capita — l'anteprima del tenant e la console
 * dell'aggregatore — dove `min-width` in pixel di viewport misurerebbe la
 * finestra sbagliata e manderebbe due colonne dentro uno spazio da una.
 */
.cpub-cols {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 40px 56px;
}

/* Il corpo della scheda: una colonna con 44px fra un blocco e l'altro. */
.cpub-body {
  flex: 1 1 520px;
  min-width: min(100%, 520px);
  display: flex;
  flex-direction: column;
  gap: 44px;
  padding-top: 32px;
}

.cpub-side {
  flex: 0 1 336px;
  min-width: min(100%, 300px);
  max-width: 100%;
  padding-top: 32px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  position: sticky;
  top: 20px;
  /* IL FONDO DELLA COLONNA RESTA RAGGIUNGIBILE. Una colonna appiccicata piu'
   * alta della finestra nasconde per sempre la propria coda: sticky la ferma
   * in alto e cio' che sporge sotto non si vede piu' scorrendo. Con tre card
   * compatte non capita quasi mai, e quando capita la colonna scorre per conto
   * suo invece di tagliare. */
  max-height: calc(100vh - 40px);
  overflow-y: auto;
}

/* Quando la colonna e' andata a capo (schermi stretti) non c'e' piu' niente a
 * cui restare appiccicati: e' l'ultimo blocco della pagina. Sticky la' non fa
 * danno, ma il taglio dell'altezza si': la colonna diventerebbe un riquadro
 * che scorre dentro una pagina che scorre.
 *
 * E QUI C'E' UNA MEDIA QUERY, dopo aver detto che il wrap non ne usa. E'
 * deliberato e vale la pena scriverne il motivo.
 *
 * Con la sola `flex-basis: 336px` la colonna andata a capo resta larga 336px
 * dentro una riga da 358: 22px di vuoto a destra che si leggono come un
 * errore di allineamento, non come una scelta (misurato a 390px). Portandola
 * a `100%` sotto la soglia, la colonna riempie la riga E la soglia del wrap
 * diventa quella dichiarata qui — le due smettono di poter divergere.
 *
 * Misurare il viewport NON rompe i due frame: un documento dentro un iframe
 * ha il PROPRIO viewport, che è la dimensione del frame. La media query
 * misura quindi lo spazio vero anche là dentro, che era l'unica ragione per
 * cui il wrap intrinseco andava preferito. */
@media (max-width: 63.99rem) {
  .cpub-side {
    flex: 1 1 100%;
    position: static;
    max-height: none;
    overflow: visible;
  }
}

/* ------------------------------------------------------- le card laterali */

.cpub-sidecard {
  background: var(--cpub-surface);
  border: 1px solid var(--cpub-line);
  border-radius: var(--cpub-r-xl);
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.cpub-sideprice {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.cpub-sideprice-value {
  font-size: 30px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.05;
}

.cpub-sideprice-unit {
  font-size: 16px;
  font-weight: 600;
  color: var(--cpub-ink-3);
}

.cpub-sidenote {
  font-size: 14px;
  color: var(--cpub-muted);
}

.cpub-sideactions {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* ------------------------------------------------------------- i bottoni
 *
 * Sono LINK, non `<button>`: portano a un'altra pagina, e un `<button>` che
 * naviga richiede o un form o del JavaScript — il primo e' vietato dalla CSP
 * dei due frame (`form-action 'none'`), il secondo dal modulo. Un link che
 * sembra un bottone e si comporta da link e' la forma onesta.
 * `min-height: 48px` e' il bersaglio tattile minimo (WCAG 2.5.8). */
.cpub-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 14px;
  font: inherit;
  font-size: 16px;
  font-weight: 600;
  text-align: center;
  text-decoration: none;
  border-radius: var(--cpub-r-md);
  cursor: pointer;
}

.cpub-btn--primary {
  background: var(--cpub-ink);
  color: #fff;
  border: 0;
}

.cpub-btn--primary:hover {
  background: var(--cpub-ink-2);
  color: #fff;
  text-decoration: none;
}

.cpub-btn--ghost {
  background: var(--cpub-surface);
  color: var(--cpub-ink);
  border: 1px solid var(--cpub-border);
}

.cpub-btn--ghost:hover {
  border-color: var(--cpub-ink);
  color: var(--cpub-ink);
  text-decoration: none;
}

.cpub-btn--soft {
  background: var(--cpub-accent-bg-soft);
  border: 1px solid var(--cpub-accent-bg-line);
  color: var(--cpub-accent-strong);
  font-size: 15px;
  padding: 11px 16px;
  min-height: 44px;
}

.cpub-btn--soft:hover {
  background: var(--cpub-accent-bg);
  color: var(--cpub-accent-strong);
  text-decoration: none;
}

/* ---------------------------------------------- il riferimento commerciale */

.cpub-agency {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-top: 16px;
  border-top: 1px solid var(--cpub-line-row);
}

.cpub-agency-avatar {
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: var(--cpub-r-pill);
  background: var(--cpub-accent-bg);
  color: var(--cpub-accent-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  font-weight: 700;
}

.cpub-agency-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.cpub-agency-name {
  font-size: 15px;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.cpub-agency-role {
  font-size: 13px;
  color: var(--cpub-muted);
}

/* ------------------------------------------------------ l'assistente AI */

.cpub-assist {
  background: var(--cpub-surface);
  border: 1px solid var(--cpub-line);
  border-radius: var(--cpub-r-xl);
  padding: 18px 22px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.cpub-assist-key {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--cpub-muted);
}

.cpub-assist-dot {
  width: 8px;
  height: 8px;
  border-radius: var(--cpub-r-pill);
  background: var(--cpub-accent-mark);
}

.cpub-assist p {
  margin: 0;
  font-size: 15px;
  line-height: 1.5;
  color: var(--cpub-ink-2);
}

/* IL CAMPO E' UN LINK CHE NE HA LA FORMA, e non un `<input>`.
 *
 * Un input vero qui sarebbe una promessa che la pagina non puo' mantenere:
 * senza JavaScript non si intercetta l'invio, e un `<form>` e' rifiutato dalla
 * CSP dei due frame (`form-action 'none'`). Chi scrivesse una domanda e
 * premesse Invio non otterrebbe niente — un fallimento silenzioso, che e'
 * esattamente cio' che questa piattaforma non ammette.
 *
 * Quindi si dichiara cosa succede: si preme e si apre la porta. Il testo e'
 * un invito, non un segnaposto — e non finge di essere scrivibile. */
.cpub-assist-field {
  display: block;
  padding: 11px 12px;
  min-height: 44px;
  border: 1px solid var(--cpub-border);
  border-radius: var(--cpub-r-md);
  background: #fefcf8;
  color: var(--cpub-muted);
  font-size: 15px;
  text-decoration: none;
}

.cpub-assist-field:hover {
  border-color: var(--cpub-ink);
  color: var(--cpub-ink-2);
  text-decoration: none;
}

.cpub-assist-note {
  font-size: 12px;
  color: var(--cpub-muted);
}

/* ------------------------------------------------------------ l'indice */

.cpub-index {
  background: var(--cpub-surface);
  border: 1px solid var(--cpub-line);
  border-radius: var(--cpub-r-xl);
  padding: 16px 22px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.cpub-index-key {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--cpub-muted);
  padding-bottom: 8px;
}

.cpub-index a {
  font-size: 15px;
  color: var(--cpub-ink-2);
  padding: 7px 0;
  border-bottom: 1px solid var(--cpub-line-nav);
}

.cpub-index a:last-child {
  border-bottom: 0;
}

.cpub-index a:hover {
  color: var(--cpub-accent-strong);
}

/* SOTTO LA SOGLIA L'INDICE NON C'E' (CAT-SCHEDA-3-FIX). Su una colonna unica
 * promette una struttura che lo schermo non ha, e le sue voci diventano un
 * secondo elenco da attraversare prima di arrivare alle foto. Non esiste piu'
 * nemmeno una copia sotto la testata: il markup e' UNO, ed e' quello della
 * colonna che su desktop c'e' davvero. `display: none` lo toglie anche
 * dall'albero di accessibilita', quindi su telefono non lo incontra nessuno. */
@media (max-width: 63.99rem) {
  .cpub-index {
    display: none;
  }
}

/* ============================== CAT-SCHEDA-3 C5 — il velo dell'assistente
 *
 * STESSA TECNICA DEL RIQUADRO FOTO (`:target`), e per la stessa ragione: e'
 * l'unico modo di aprire un pannello senza JavaScript, quindi l'unico che
 * funziona identico sulle tre superfici. Chiuderlo e' un link che riporta
 * all'ancora della card da cui si e' partiti — non il tasto «indietro».
 *
 * Il fondo scuro qui e' legittimo: sotto non c'e' la foto di nessuno, c'e' la
 * pagina. La regola CAT-UX-2 vieta il velo SOPRA UNA FOTO. */
.cpub-veilbox {
  display: none;
}

.cpub-veilbox:target {
  display: flex;
  position: fixed;
  inset: 0;
  z-index: 50;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background: rgba(15, 17, 20, 0.72);
}

body:has(.cpub-veilbox:target) {
  overflow: clip;
}

.cpub-veilbox-backdrop {
  position: absolute;
  inset: 0;
}

.cpub-veilbox-panel {
  position: relative;
  width: min(100%, 26rem);
  background: var(--cpub-surface);
  border-radius: var(--cpub-r-xl);
  padding: 26px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  box-shadow: 0 18px 48px rgb(0 0 0 / 28%);
}

.cpub-veilbox-title {
  margin: 0;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.cpub-veilbox-panel p {
  margin: 0;
  font-size: 16px;
  line-height: 1.55;
  color: var(--cpub-ink-2);
}

.cpub-veilbox-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.cpub-veilbox-actions .cpub-btn {
  flex: 1 1 8rem;
}

/* ==================================== CAT-SCHEDA-3 D8 — «in costruzione»
 *
 * Una pagina intera, centrata, con il disegno sopra. Vive nello stesso foglio
 * della scheda perche' e' la stessa identita' visiva e lo stesso perimetro
 * pubblico: un secondo foglio sarebbe una seconda tavolozza da tenere
 * allineata a mano. */
.cpub-wip {
  max-width: 34rem;
  margin: 0 auto;
  padding: clamp(48px, 12vh, 96px) 0 80px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  text-align: center;
}

.cpub-wip-art {
  width: min(100%, 20rem);
  height: auto;
}

.cpub-wip h1 {
  margin: 0;
  font-size: clamp(28px, 5vw, 38px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.cpub-wip p {
  margin: 0;
  font-size: 18px;
  line-height: 1.6;
  color: var(--cpub-ink-2);
}

.cpub-wip-note {
  font-size: 15px;
  color: var(--cpub-muted);
}

/* ------------------------------------------------------------------- stampa
 *
 * LA SCHEDA SI STAMPA — un'agenzia la porta in appuntamento — e in stampa un
 * `<details>` chiuso è una parte di documento che non esiste. Qui si forza
 * aperto: la piega serve a chi scorre uno schermo, non a chi legge un foglio
 * dove scorrere non si può.
 *
 * Due meccanismi perché i motori non concordano: `::details-content` è la
 * pseudo-classe nuova, `display` sul contenuto è il modo che funziona sui
 * motori che non ce l'hanno ancora. Nessuno dei due fa danno all'altro.
 */
@media print {
  /* CAT-MEDIA-2 B5 — IL RIQUADRO NON SI STAMPA. È un pannello sopra la pagina:
   * su carta sarebbe una foto gigante al posto della scheda, e se ne
   * stamperebbe una per ogni blocco. Le foto stanno già nel mosaico. */
  .cpub-lb { display: none !important; }

  /* Il mosaico su carta: la copertina a tutta larghezza e le celle a due a due,
   * cioè la forma del telefono. Le disposizioni a rettangolo del desktop si
   * annullano tutte qui — su un foglio A4 le colonne sono strette e una cover
   * alta due file diventerebbe una striscia. Mai una foto spezzata fra due
   * fogli. */
  /* L'ALTEZZA FISSA VA TOLTA, non solo le righe. `.cpub-mosaic` ha un
   * `height: clamp(240px, 38vw, 460px)`: lasciandolo, le tessere disposte su
   * più file traboccano da quei 460px e si stampano SOPRA la descrizione e i
   * dati — che sparivano sotto le foto. Visto nello screenshot di stampa. */
  .cpub-mosaic,
  .cpub-mosaic--n0,
  .cpub-mosaic--n1,
  .cpub-mosaic--n2 {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto;
    height: auto;
  }
  .cpub-mosaic-hero { grid-column: 1 / -1; grid-row: auto; }
  .cpub-mosaic-hero .cpub-mosaic-open { aspect-ratio: 16 / 10; height: auto; }
  .cpub-mosaic-cell .cpub-mosaic-open { aspect-ratio: 4 / 3; height: auto; }
  .cpub-mosaic--n1 .cpub-mosaic-cell,
  .cpub-mosaic--n3 .cpub-mosaic-cell:last-child { grid-column: 1 / -1; }
  /* Stessa specificità della regola del desktop, altrimenti quella vince e la
   * cella larga resta alta zero: su carta spariva del tutto — visto nello
   * screenshot di stampa, non dedotto. */
  .cpub-mosaic--n3 .cpub-mosaic-cell:last-child .cpub-mosaic-open {
    aspect-ratio: 16 / 9;
    height: auto;
  }
  .cpub-mosaic-open { break-inside: avoid; }
  /* Le pillole «Ingrandisci» sono azioni: su carta non si preme niente. Vale
   * anche per i quadrati media (aprono il riquadro o scorrono a una sezione)
   * e per il badge della mappa. Il conteggio delle foto non si perde: la
   * tessera «+N foto» del mosaico è stampata. */
  .cpub-hero-hint,
  .cpub-figure-hint,
  .cpub-map-zoom,
  .cpub-media { display: none; }

  /* La facciata del video diventa una riga di testo: il fotogramma senza il
   * pulsante non dice niente, e l'indirizzo non si può cliccare su un foglio. */
  .cpub-videocard-frame { display: none; }

  .cpub-nearby-more > summary { display: none; }
  .cpub-nearby-more::details-content { content-visibility: visible; }
  .cpub-nearby-more > .cpub-nearby-more-body { display: block; }
  .cpub-nearby-more-body { margin-top: 0; }
  .cpub-nearby-group { break-inside: avoid; }
  .cpub-nearby-grid { grid-template-columns: 1fr 1fr; column-gap: 1.5rem; }
  .cpub-nearby-row { border-bottom: 1px solid #d4d4d8; }

  /* CAT-SCHEDA-3-FIX2 — su carta i due toni chiari della scala non esistono:
   * una stampante laser li rende bianchi, e la fascia tornerebbe a non avere
   * bordi proprio dove serve di più (un foglio non ha il fondo crema che sullo
   * schermo la stacca). Si passa ai grigi di stampa già usati qui sopra,
   * tenendo l'esterno più marcato dell'interno. */
  .cpub-facts {
    border-top-color: #a1a1aa;
    border-bottom-color: #a1a1aa;
  }
  .cpub-fact:nth-child(n+5) { border-top-color: #d4d4d8; }

  /* CAT-SCHEDA-3 C5 — SU CARTA LA COLONNA NON E' UNA COLONNA. Sticky non
   * esiste in stampa, e due colonne su A4 lasciano il contenuto in una
   * striscia stretta: si torna a un flusso solo, con la colonna in coda. */
  .cpub-cols { display: block; }
  .cpub-side {
    position: static;
    max-height: none;
    overflow: visible;
    padding-top: 44px;
    display: block;
  }

  /* Cio' che su carta non si puo' premere non si stampa: i due bottoni,
   * l'invito all'assistente e l'indice (che rimanda ad ancore inesistenti su
   * un foglio). Restano il prezzo e il riferimento commerciale, che sono le
   * due informazioni per cui una scheda si porta in appuntamento. */
  .cpub-sideactions,
  .cpub-assist,
  .cpub-index { display: none; }

  .cpub-veilbox { display: none !important; }

  .cpub-sidecard {
    border: 1px solid #d4d4d8;
    break-inside: avoid;
  }
}
