/* TROVA-mi Adesso — sistema visivo.
   La palette è quella di brand/BRAND.md, girata al negativo: petrolio come
   fondo, carta come superficie, ambra come unica luce. Non è un capriccio —
   quest'app si apre alle sette di sera con una mano sola, e il fondo scuro
   è il colore di quell'ora. Il pannello del banco (banco.html) fa il
   contrario: chiaro, perché si usa di giorno e deve sembrare un documento. */

:root {
  --petrolio: #0e4c5c;
  --petrolio-scuro: #093843;
  --fondo: #062730;
  --fondo-alto: #0a3a46;
  --ambra: #e8a33d;
  --ambra-chiara: #f2c078;
  --carta: #f7f4ef;
  --inchiostro: #14232e;
  --grigio: #5b6770;
  --linea: #e5dfd4;
  --su-scuro: #c6dbe2;
  --su-scuro-tenue: #86a5b1;
  --bronzo: #96600f;
  --verde: #1a7a52;

  --raggio: 20px;
  --raggio-piccolo: 12px;
  --barra-alta: 3.9rem;
  --molla: cubic-bezier(0.22, 1, 0.36, 1);
  --sicuro-basso: env(safe-area-inset-bottom, 0px);
  --sicuro-alto: env(safe-area-inset-top, 0px);
}

@font-face { font-family: Manrope; src: url(font/manrope-regular.woff2) format("woff2"); font-weight: 400; font-display: swap }
@font-face { font-family: Manrope; src: url(font/manrope-semibold.woff2) format("woff2"); font-weight: 600; font-display: swap }
@font-face { font-family: Manrope; src: url(font/manrope-extrabold.woff2) format("woff2"); font-weight: 800; font-display: swap }

* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent }

html { -webkit-text-size-adjust: 100% }

body {
  font-family: Manrope, system-ui, -apple-system, sans-serif;
  background: var(--fondo);
  color: var(--su-scuro);
  line-height: 1.5;
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
  min-height: 100dvh;
  overscroll-behavior-y: none;
}

button, input, select, textarea { font: inherit; color: inherit }
button { background: none; border: 0; cursor: pointer }
a { color: inherit; text-decoration: none }

:focus-visible { outline: 3px solid var(--ambra); outline-offset: 2px; border-radius: 6px }

/* ── testata ───────────────────────────────────────────────────────── */

.testata {
  position: sticky; top: 0; z-index: 30;
  padding: calc(var(--sicuro-alto) + 0.85rem) 1.1rem 0.7rem;
  background: linear-gradient(180deg, var(--fondo) 72%, rgba(6, 39, 48, 0));
  backdrop-filter: blur(12px);
}
.testata-riga { display: flex; align-items: center; justify-content: space-between; gap: 0.8rem }
.marchio { font-weight: 800; font-size: 1.06rem; letter-spacing: -0.03em; color: #fff; white-space: nowrap }
.marchio i { color: var(--ambra); font-style: normal }

.orologio { display: flex; align-items: center; gap: 0.45rem; font-size: 0.8rem; font-weight: 600; color: var(--su-scuro-tenue) }
.pallino { width: 7px; height: 7px; border-radius: 50%; background: var(--ambra); position: relative; flex: none }
.pallino::after {
  content: ""; position: absolute; inset: -4px; border-radius: 50%;
  border: 1.5px solid var(--ambra); animation: respira 2.6s ease-out infinite;
}
@keyframes respira { 0% { transform: scale(0.6); opacity: 0.9 } 100% { transform: scale(1.9); opacity: 0 } }

.titolone {
  font-size: clamp(1.55rem, 7.4vw, 2.05rem); font-weight: 800; letter-spacing: -0.035em;
  color: #fff; line-height: 1.08; margin-top: 0.55rem;
}
.titolone em { font-style: normal; color: var(--ambra) }
.sottotitolone { font-size: 0.87rem; color: var(--su-scuro-tenue); margin-top: 0.28rem }

/* ── filtri ────────────────────────────────────────────────────────── */

.filtri {
  display: flex; gap: 0.45rem; overflow-x: auto; padding: 0.85rem 1.1rem 0.2rem;
  scrollbar-width: none; scroll-snap-type: x proximity;
}
.filtri::-webkit-scrollbar { display: none }
.filtri[hidden] { display: none }
.filtro {
  flex: none; padding: 0.62rem 0.9rem; border-radius: 999px; font-size: 0.845rem; font-weight: 600;
  color: var(--su-scuro); background: rgba(255, 255, 255, 0.07);
  border: 1px solid rgba(255, 255, 255, 0.09); scroll-snap-align: start;
  transition: background 0.16s ease, color 0.16s ease, border-color 0.16s ease;
}
.filtro[aria-pressed="true"] { background: var(--ambra); color: #0b2b34; border-color: var(--ambra) }
.filtro.salvati { display: inline-flex; align-items: center; gap: 0.32rem }
.filtro.salvati svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2 }
.filtro.salvati[aria-pressed="true"] svg { fill: currentColor }
/* Ultima, e con la stessa specificità della regola che imposta il display:
   fra due regole pari vince quella che viene dopo. */
.filtro[hidden], .filtro.salvati[hidden] { display: none }

/* ── lista ─────────────────────────────────────────────────────────── */

.schermo { padding: 0.55rem 1.1rem calc(var(--barra-alta) + var(--sicuro-basso) + 1.6rem) }
.schermo[hidden] { display: none }

.striscia {
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.11em; text-transform: uppercase;
  color: var(--su-scuro-tenue); margin: 1.5rem 0 0.6rem 0.15rem;
}
.striscia:first-child { margin-top: 0.5rem }
.spiegazione { font-size: 0.8rem; color: var(--su-scuro-tenue); margin: -0.35rem 0 0.7rem 0.15rem; line-height: 1.4 }

/* ── i più amati ───────────────────────────────────────────────────── */

/* Nella graduatoria la foto sta sopra e a tutta larghezza: qui si guarda per
   farsi venire voglia, non per decidere in trenta secondi come nella lista.
   È il motivo per cui nella lista la foto non c'è: lì il titolo dell'offerta
   deve arrivare prima di qualsiasi immagine. */
.offerta.amato { padding: 0; overflow: hidden }
.foto-guscio { position: relative; aspect-ratio: 2 / 1; background: var(--fondo-alto) }
.foto-guscio img { width: 100%; height: 100%; object-fit: cover; display: block }
.foto-guscio::after {
  content: ""; position: absolute; inset: 40% 0 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(6, 39, 48, 0), rgba(6, 39, 48, 0.82));
}
.foto-nome {
  position: absolute; left: 0.95rem; right: 0.95rem; bottom: 0.62rem; z-index: 1;
  color: #fff; font-size: 1.22rem; font-weight: 800; letter-spacing: -0.028em;
  line-height: 1.14; text-shadow: 0 1px 12px rgba(0, 0, 0, 0.45);
}
/* L'autore della foto: con un'immagine presa da Google è una condizione
   d'uso, non una gentilezza. */
.foto-autore {
  position: absolute; right: 0.6rem; top: 0.55rem; z-index: 1;
  font-size: 0.6rem; font-weight: 600; color: rgba(255, 255, 255, 0.8);
  background: rgba(6, 39, 48, 0.5); border-radius: 5px; padding: 0.1rem 0.36rem;
  backdrop-filter: blur(4px); max-width: 55%; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.amato-corpo { padding: 0.75rem 1rem 0.9rem }
.offerta.amato .dettaglio { margin-top: 0 }
.segnale {
  display: inline-block; margin-top: 0.55rem; font-size: 0.775rem; font-weight: 600;
  color: var(--bronzo); background: #fdf3e4; border-radius: 999px; padding: 0.2rem 0.6rem;
}

/* Lo spazio a pagamento deve *sembrare* diverso, non solo dirlo: cornice
   tratteggiata e nessun bordo ambra, che qui dentro significa «sta accadendo». */
/* Lo spazio a pagamento sta in mezzo alle altre schede, e deve *sembrare*
   diverso, non solo dirlo: cornice tratteggiata, nessun bordo ambra (che qui
   dentro significa «sta accadendo»), etichetta sempre addosso. */
.offerta.sponsor { box-shadow: 0 10px 24px rgba(0, 0, 0, 0.26); outline: 1.5px dashed #b9c2c8; outline-offset: -1.5px }
.offerta.sponsor::before { display: none }
.marchietto {
  display: inline-block; font-size: 0.665rem; font-weight: 800; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--grigio); border: 1px solid var(--linea);
  border-radius: 5px; padding: 0.1rem 0.34rem; margin-bottom: 0.5rem;
}
.foto-guscio .marchietto {
  position: absolute; left: 0.6rem; top: 0.55rem; z-index: 1; margin: 0;
  color: #fff; border-color: rgba(255, 255, 255, 0.45);
  background: rgba(6, 39, 48, 0.55); backdrop-filter: blur(4px);
}

/* Il cuoricino che pulsa quando salvi: mezzo secondo di riscontro, e si
   capisce che è successo qualcosa senza doverlo leggere. */
@keyframes batti { 0%, 100% { transform: scale(1) } 30% { transform: scale(1.22) } 60% { transform: scale(0.96) } }
.azioneLocale.salvato { animation: batti 0.42s var(--molla) }

.offerta {
  display: block; width: 100%; text-align: left;
  background: var(--carta); color: var(--inchiostro);
  border-radius: var(--raggio); padding: 0.88rem 1rem 0.82rem;
  margin-bottom: 0.62rem; position: relative; overflow: hidden;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.26);
  animation: entra 0.42s var(--molla) backwards;
  transition: transform 0.16s var(--molla);
}
.offerta:active { transform: scale(0.982) }
@keyframes entra { from { opacity: 0; transform: translateY(14px) } to { opacity: 1; transform: none } }

/* La luce ambra è riservata a ciò che sta succedendo adesso: se la si mette
   ovunque smette di dire qualcosa. */
.offerta.viva { box-shadow: 0 10px 24px rgba(0, 0, 0, 0.3), 0 0 0 1.5px var(--ambra) }
.offerta.viva::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--ambra);
}
.offerta.dopo { opacity: 0.9 }

.offerta-testa { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.7rem }
.offerta h3 {
  font-size: 1.13rem; font-weight: 800; letter-spacing: -0.024em; line-height: 1.18;
  text-wrap: balance;
}
.prezzo {
  flex: none; font-weight: 800; font-size: 1.13rem; letter-spacing: -0.03em;
  color: var(--petrolio); white-space: nowrap;
}
.offerta .dettaglio { font-size: 0.865rem; color: var(--grigio); margin-top: 0.2rem; line-height: 1.38 }

.quando { display: flex; align-items: center; gap: 0.45rem; flex-wrap: wrap; margin-top: 0.6rem }
.pillola {
  font-size: 0.775rem; font-weight: 600; padding: 0.24rem 0.62rem; border-radius: 999px;
  background: rgba(14, 76, 92, 0.09); color: var(--petrolio); white-space: nowrap;
}
.pillola.ora { background: var(--ambra); color: #4a2f00 }
.pillola.evento { background: rgba(26, 122, 82, 0.12); color: var(--verde) }
.pillola.pieno { background: #f2eae7; color: #8d5a52 }
.pillola.ora .conto { font-variant-numeric: tabular-nums }
.ricorrenza { font-size: 0.79rem; color: var(--grigio) }

.locale-riga {
  display: flex; align-items: baseline; gap: 0.38rem; flex-wrap: wrap;
  margin-top: 0.68rem; padding-top: 0.6rem; border-top: 1px solid var(--linea);
}
.locale-nome { font-weight: 600; font-size: 0.925rem; letter-spacing: -0.012em }
.locale-dove { font-size: 0.795rem; color: var(--grigio) }

/* Le stelle stanno in fondo e piccole: rassicurano, non decidono.
   Chi decide è l'offerta. Il brief lo chiedeva così, e ha ragione: se le
   stelle stessero in cima l'app tornerebbe a essere una classifica. */
.google { display: flex; align-items: center; gap: 0.3rem; font-size: 0.755rem; color: var(--grigio); margin-top: 0.28rem }
.stella { width: 10px; height: 10px; flex: none; fill: var(--ambra) }
.google b { font-weight: 600; color: var(--inchiostro) }
.citazione {
  font-size: 0.79rem; color: var(--grigio); font-style: italic; line-height: 1.38;
  margin-top: 0.34rem; padding-left: 0.56rem; border-left: 2px solid var(--linea);
  /* Due righe al massimo: la citazione è un cenno, non un paragrafo. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.citazione span { font-style: normal; color: #8a939b }
/* La frase del titolare si distingue: bordo ambra e il suo nome in tondo.
   Le stelle vengono da Google, la frase viene da lui — e si vede. */
.citazione.sua { border-left-color: var(--ambra) }
.citazione .chiVoce { font-style: normal; font-weight: 600; color: var(--bronzo) }

/* Il riassunto in fondo alla lista: una frase in italiano che dice cosa c'è.
   Serve a chi legge di fretta e a chi indicizza — compresi i modelli, che di
   una frase capiscono più che di un elenco. Non si nasconde con display:none:
   un testo scritto per i motori e invisibile alle persone è esattamente ciò
   che i motori puniscono. */
.riassunto-seo {
  max-width: 30rem; margin: 0.2rem auto calc(var(--barra-alta) + var(--sicuro-basso) + 1.4rem);
  padding: 0 1.1rem; font-size: 0.8rem; color: var(--su-scuro-tenue); line-height: 1.5;
}
.riassunto-seo[hidden] { display: none }

.vuoto { text-align: center; padding: 3.2rem 1.2rem; color: var(--su-scuro-tenue) }
.vuoto strong { display: block; color: #fff; font-size: 1.12rem; font-weight: 800; margin-bottom: 0.42rem; letter-spacing: -0.02em }

.scheletro {
  height: 128px; border-radius: var(--raggio); margin-bottom: 0.7rem;
  background: linear-gradient(100deg, rgba(255,255,255,.05) 30%, rgba(255,255,255,.1) 50%, rgba(255,255,255,.05) 70%);
  background-size: 300% 100%; animation: scorri 1.3s linear infinite;
}
@keyframes scorri { from { background-position: 150% 0 } to { background-position: -150% 0 } }

/* ── il gesto del «trova-mi» ───────────────────────────────────────────
   Si tira giù la lista e il radar cerca qui intorno. È il nome del marchio
   fatto gesto: l'unica cosa che il cliente finale tocca con le dita, e deve
   essere quella. Le onde sono le stesse del sito, dove escono dalla card. */

.radar {
  position: fixed; left: 0; right: 0; top: 0; z-index: 25;
  height: 0; overflow: visible; display: grid; place-items: center;
  pointer-events: none; opacity: 0;
}
.radar .onde { position: relative; width: 0; height: 0; margin-top: 46px }
.radar .onde i {
  position: absolute; left: 0; top: 0; width: 10px; height: 10px; margin: -5px;
  border-radius: 50%; border: 1.5px solid var(--ambra); opacity: 0;
}
.radar-testo {
  position: absolute; top: 78px; font-size: 0.74rem; font-weight: 600;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--ambra-chiara);
  white-space: nowrap;
}
.radar.pronto .radar-testo { color: var(--ambra) }
/* Mentre cerca, le onde partono davvero: tre impulsi sfalsati. */
.radar.cerca .onde i { animation: cerca 1.15s ease-out infinite }
.radar.cerca .onde i:nth-child(2) { animation-delay: 0.38s }
.radar.cerca .onde i:nth-child(3) { animation-delay: 0.76s }
@keyframes cerca {
  0% { width: 10px; height: 10px; margin: -5px; opacity: 0.85 }
  100% { width: 132px; height: 132px; margin: -66px; opacity: 0 }
}

/* Il corpo segue il dito: è ciò che fa sentire il gesto invece di vederlo. */
main { transition: transform 0.3s var(--molla) }
body.tirando main { transition: none }

/* ── sorprendimi ───────────────────────────────────────────────────── */

.sorprendimi {
  position: fixed; z-index: 34; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--barra-alta) + var(--sicuro-basso) + 0.85rem);
  display: flex; align-items: center; gap: 0.45rem;
  padding: 0.62rem 1.05rem; border-radius: 999px;
  background: var(--ambra); color: #4a2f00; font-size: 0.9rem; font-weight: 800;
  letter-spacing: -0.01em; box-shadow: 0 8px 22px rgba(0, 0, 0, 0.38);
  animation: salta 0.45s var(--molla) backwards;
}
.sorprendimi[hidden] { display: none }
.sorprendimi svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round }
.sorprendimi:active { transform: translateX(-50%) scale(0.95) }
.sorprendimi.gira svg { animation: gira 0.5s linear infinite }
@keyframes salta { from { opacity: 0; transform: translate(-50%, 14px) } to { opacity: 1; transform: translateX(-50%) } }
@keyframes gira { to { transform: rotate(360deg) } }

/* ── quello che sta per accendersi ─────────────────────────────────── */

.fraPoco {
  max-width: 30rem; margin: 0 auto; padding: 0 1.1rem 0.2rem;
  font-size: 0.83rem; font-weight: 600; color: var(--ambra-chiara); line-height: 1.45;
}
.fraPoco[hidden] { display: none }

/* ── l'evento di oggi ──────────────────────────────────────────────── */
/* In cima a tutto, prima dei gruppi. Un bordo ambra pieno tutto intorno,
   non solo l'accento a sinistra di «viva»: qui l'ambra non dice «in corso»,
   dice «è questa la scelta del giorno» — ed è l'unica scheda della lista che
   la riceve. */
.offerta.eventoGiorno { box-shadow: 0 10px 26px rgba(0, 0, 0, 0.32), 0 0 0 2px var(--ambra); margin-bottom: 0.85rem }
.offerta.eventoGiorno .occhiello {
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.11em; text-transform: uppercase;
  color: var(--bronzo); margin-bottom: 0.32rem;
}

/* ── l'invito alla posizione ───────────────────────────────────────── */
/* Fondo petrolio chiaro, non carta: è un messaggio dell'app, non un'offerta
   di un locale — non deve potersi confondere con una scheda. Il motivo sta
   scritto qui, prima che parta qualsiasi prompt nativo (HIG: il permesso si
   chiede dopo un gesto, con la ragione davanti agli occhi). */
.invitoGeo {
  display: flex; flex-direction: column; align-items: flex-start; gap: 0.5rem;
  background: var(--petrolio); color: var(--su-scuro); border-radius: var(--raggio);
  padding: 1rem 1.05rem 1.1rem; margin-bottom: 0.85rem;
  animation: entra 0.42s var(--molla) backwards;
  transition: opacity 0.26s ease, transform 0.26s ease;
}
.invitoGeo.scompare { opacity: 0; transform: scale(0.96) }
.invitoGeo-icona { width: 22px; height: 22px; stroke: var(--ambra-chiara); stroke-width: 1.7; fill: none }
.invitoGeo-titolo { font-size: 1rem; font-weight: 800; letter-spacing: -0.02em; line-height: 1.26; color: #fff }
.invitoGeo-riga { font-size: 0.82rem; line-height: 1.42 }
.invitoGeo-bottone {
  align-self: stretch; margin-top: 0.3rem; min-height: 44px; padding: 0.7rem 1rem;
  border-radius: 12px; background: var(--ambra); color: #4a2f00; font-weight: 800; font-size: 0.92rem;
}
.invitoGeo-bottone:active { transform: scale(0.97) }
.invitoGeo-bottone:disabled { opacity: 0.75 }

/* La riga che segue un rifiuto: discreta, e si toglie da sola. */
.geoBloccata {
  font-size: 0.8rem; color: var(--su-scuro-tenue); text-align: center;
  padding: 0.6rem 1.1rem; margin-bottom: 0.85rem; animation: svanisce 4.2s ease forwards;
}
@keyframes svanisce { 0%, 78% { opacity: 1 } 100% { opacity: 0 } }

/* ── questo weekend ────────────────────────────────────────────────── */
/* Gli eventi che scegliamo noi a mano, in giro per Milano — mai generati
   dalla piattaforma. Vive fuori da #schermo-adesso, come #fraPoco e
   #riassunto, e si nasconde con loro sulle altre schede. */
.questoWeekend { max-width: 30rem; margin: 0 auto; padding: 0 1.1rem calc(var(--barra-alta) + var(--sicuro-basso) + 1.6rem) }
.questoWeekend[hidden] { display: none }

.filtriWeekend {
  display: flex; gap: 0.4rem; overflow-x: auto; margin: 0.2rem 0 0.85rem;
  scrollbar-width: none; scroll-snap-type: x proximity;
}
.filtriWeekend::-webkit-scrollbar { display: none }
.filtroWeekend {
  flex: none; padding: 0.62rem 0.82rem; border-radius: 999px; font-size: 0.8rem; font-weight: 600;
  color: var(--su-scuro); background: rgba(255, 255, 255, 0.07); border: 1px solid rgba(255, 255, 255, 0.09);
  scroll-snap-align: start; transition: background 0.16s ease, color 0.16s ease, border-color 0.16s ease;
}
.filtroWeekend[aria-pressed="true"] { background: var(--ambra); color: #0b2b34; border-color: var(--ambra) }

/* Una scheda esterna somiglia alle altre — stessa carta, stesso raggio — ma
   porta in fondo la riga della fonte, in grigio: è un evento altrui, e la
   verità sta lì, non da noi. */
.offerta.esterno .ricorrenza { display: block; margin-top: 0.55rem }
.fonteEsterna {
  font-size: 0.78rem; color: var(--grigio); margin-top: 0.6rem;
  padding-top: 0.58rem; border-top: 1px solid var(--linea);
}

/* ── mappa ─────────────────────────────────────────────────────────── */
/* Tre mappe nello stesso guscio: la SVG schematica (sempre pronta, sotto),
   e sopra di lei una delle due vere — Google Maps (primaria, quando c'è la
   chiave) o MapLibre (a costo zero, altrimenti) — mai lazy caricate
   insieme, vedi adesso.js → attivaMappaVera. Chi apre la scheda vede
   sempre qualcosa subito; quando la vera è pronta lo scambio è un'opacità
   che sale, mai un buco. Se nessuna delle due vere arriva mai (offline,
   tile/chiave irraggiungibili), la schematica resta ed è quella buona: non
   è un ripiego vergognoso, è il piano di riserva che promettevamo. */

.mappa-guscio { position: relative; border-radius: var(--raggio); overflow: hidden; background: var(--fondo-alto); aspect-ratio: 1 / 1.15 }

.mappa-svg { width: 100%; height: 100%; display: block; touch-action: none }
.mappa-anello { fill: none; stroke: rgba(198, 219, 226, 0.14); stroke-width: 1 }
.mappa-etichetta { fill: var(--su-scuro-tenue); font-size: 9px; font-weight: 600 }
.mappa-io { fill: var(--su-scuro) }
.mappa-punto { fill: var(--carta); cursor: pointer; transition: r 0.18s var(--molla) }
.mappa-punto.viva { fill: var(--ambra) }
.mappa-punto:hover { r: 9 }
.mappa-nota { font-size: 0.8rem; color: var(--su-scuro-tenue); margin-top: 0.75rem; text-align: center }

/* La mappa vera (Google o MapLibre, stesso guscio): dimensionata fin da
   subito (entrambi i motori ne hanno bisogno per caricare le mattonelle
   giuste), ma trasparente e sorda al tocco finché non ha uno stile
   applicato e i primi punti — così sotto, la schematica resta quella che
   risponde. Quando è pronta sale in opacità e prende il tocco: mai una
   tavolozza grigia a metà carico sopra la schematica che stava già bene, e
   mai due mappe che si contendono lo stesso trascinamento. */
#mappa-vera { position: absolute; inset: 0; z-index: 1; opacity: 0; pointer-events: none; transition: opacity 0.4s ease }
#mappa-vera.pronta { opacity: 1; pointer-events: auto }
#mappa-vera .maplibregl-map { width: 100%; height: 100% }
#mappa-vera .maplibregl-canvas-container { touch-action: pan-x pan-y }

.mappa-caricamento {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 2;
  font-size: 0.78rem; font-weight: 600; color: var(--su-scuro-tenue); pointer-events: none;
}
.mappa-caricamento[hidden] { display: none }

/* «Centra su di me»: rotonda, sopra la mappa, in basso a destra — il pollice
   la trova senza cercarla. 46px: sopra i 44px minimi di un bersaglio a tocco. */
.mappa-bussola {
  position: absolute; right: 0.7rem; bottom: 0.7rem; z-index: 3;
  width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center;
  background: var(--petrolio); border: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4); transition: transform 0.15s var(--molla);
}
.mappa-bussola[hidden] { display: none }
.mappa-bussola svg { width: 22px; height: 22px; fill: none; stroke: #fff; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round }
.mappa-bussola:active { transform: scale(0.92) }

/* I marcatori sono div HTML, mai layer GL né google.maps.Marker: usati sia
   da maplibregl.Marker sia da un OverlayView scritto a mano (vedi adesso.js
   → costruisciMarcatorePunto/-Cluster/-Io), sempre con le stesse classi —
   chi guarda non deve indovinare quale motore c'è sotto. Solo un div
   semplice permette all'anello che pulsa sul punto attivo di essere una
   vera animazione CSS (respira, la stessa del pallino in testata) invece
   di un'illusione ricalcolata a mano fotogramma per fotogramma. */
.marcatore-cluster {
  width: 34px; height: 34px; border-radius: 50%; cursor: pointer;
  background: #1a6a7e; border: 1.5px solid rgba(255, 255, 255, 0.4);
  display: grid; place-items: center; color: #fff; font-size: 0.8rem; font-weight: 800;
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.4);
}
.marcatore-punto {
  width: 13px; height: 13px; border-radius: 50%; cursor: pointer; position: relative;
  background: var(--carta); border: 1.5px solid rgba(6, 39, 48, 0.55);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
}
.marcatore-punto.viva { width: 15px; height: 15px; background: var(--ambra); border-color: #4a2f00 }
.marcatore-punto.viva::after {
  content: ""; position: absolute; inset: -6px; border-radius: 50%;
  border: 1.5px solid var(--ambra); animation: respira 2.6s ease-out infinite;
}
/* «Tu»: bianco e fermo — la pulsazione è il linguaggio riservato a «è
   attivo adesso», e qui direbbe una cosa che non è vera. */
.marcatore-io { width: 15px; height: 15px; border-radius: 50%; background: #fff; position: relative; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.45) }
.marcatore-io::after { content: ""; position: absolute; inset: -6px; border-radius: 50%; border: 1.5px solid rgba(255, 255, 255, 0.55) }

/* L'attribuzione OpenStreetMap/OpenFreeMap è un obbligo della licenza ODbL
   dei dati, non una cortesia: resta sempre visibile, solo riportata nei
   colori dell'app perché non sembri un adesivo di un'altra interfaccia. */
.maplibregl-ctrl-bottom-left { left: 0 }
.maplibregl-ctrl-attrib, .maplibregl-ctrl-attrib.maplibregl-compact {
  background: rgba(6, 39, 48, 0.72) !important; color: var(--su-scuro-tenue) !important;
}
.maplibregl-ctrl-attrib a { color: var(--su-scuro-tenue) !important }
.maplibregl-ctrl-attrib-button { filter: invert(1) brightness(1.6) }

/* ── foglio di dettaglio ───────────────────────────────────────────── */

.velo {
  position: fixed; inset: 0; z-index: 40; background: rgba(3, 18, 22, 0.62);
  backdrop-filter: blur(3px); opacity: 0; transition: opacity 0.28s ease;
}
.velo[hidden] { display: none }
.velo.aperto { opacity: 1 }

.foglio {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 41;
  max-height: 92dvh; overflow-y: auto; overscroll-behavior: contain;
  background: var(--carta); color: var(--inchiostro);
  border-radius: 26px 26px 0 0;
  padding: 0.65rem 1.15rem calc(1.6rem + var(--sicuro-basso));
  transform: translateY(101%); transition: transform 0.38s var(--molla);
  box-shadow: 0 -18px 44px rgba(0, 0, 0, 0.4);
}
.foglio[hidden] { display: none }
.foglio.aperto { transform: none }
.maniglia { width: 40px; height: 4px; border-radius: 3px; background: var(--linea); margin: 0.3rem auto 1rem }

.foglio h2 { font-size: 1.42rem; font-weight: 800; letter-spacing: -0.03em; line-height: 1.14; text-wrap: balance }
.foglio .dove { font-size: 0.88rem; color: var(--grigio); margin-top: 0.28rem }

.azione {
  display: flex; align-items: center; justify-content: center; gap: 0.42rem;
  padding: 0.82rem 0.6rem; border-radius: 13px; font-weight: 600; font-size: 0.925rem;
  background: var(--petrolio); color: #fff;
}
.azione:active { transform: scale(0.975) }

/* ── riga di gesti del locale ──────────────────────────────────────── */
/* Tre gesti alla pari (due se manca il telefono), leggeri: icona sopra,
   etichetta sotto. Sostituiscono i due bottoni giganti di prima — qui non è
   più «l'azione della schermata», è solo il modo per arrivarci o salvarlo. */
.azioniLocale { display: flex; gap: 0.55rem; margin: 1.05rem 0 0.35rem }
.azioneLocale {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0.3rem; min-height: 56px; padding: 0.55rem 0.4rem; border-radius: 12px;
  background: #fff; border: 1px solid var(--linea); color: var(--petrolio);
  font-size: 0.78rem; font-weight: 600; text-align: center;
}
.azioneLocale svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round }
.azioneLocale:active { transform: scale(0.96) }
.azioneLocale.salvato { color: var(--verde); background: #eef4f2; border-color: #cfe3da }
.azioneLocale.salvato svg { fill: currentColor }

/* ── le offerte, come righe che si aprono ─────────────────────────── */
/* Chiusa: solo pillola di stato, titolo, prezzo — il bersaglio è l'intera
   riga, ben oltre i 44px minimi. Aperta: il dettaglio e una sola azione,
   con una transizione di altezza che rispetta prefers-reduced-motion (vedi
   in fondo al file: lì le transizioni si azzerano per chi lo chiede). */
.foglio .elenco-offerte { margin-top: 1.15rem }
.offertaVoce { border-top: 1px solid var(--linea) }
.offertaVoce:first-child { border-top: 0 }

.offertaRiga {
  width: 100%; display: flex; align-items: center; gap: 0.55rem;
  min-height: 44px; padding: 0.85rem 0; text-align: left;
}
.offertaRiga-titolo {
  flex: 1; font-weight: 800; font-size: 0.98rem; letter-spacing: -0.015em; line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.offertaRiga-prezzo { flex: none; font-weight: 800; font-size: 0.98rem; color: var(--petrolio) }
.offertaRiga-freccia {
  flex: none; width: 16px; height: 16px; fill: none; stroke: var(--grigio); stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round; transition: transform 0.28s var(--molla);
}
.offertaVoce.aperta .offertaRiga-freccia { transform: rotate(180deg) }

/* Il trucco dell'altezza morbida: si anima grid-template-rows, non
   max-height — niente valore magico da indovinare, e la transizione parte
   sempre dall'altezza vera del contenuto. */
.offertaAperta-esterno { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.34s var(--molla) }
.offertaVoce.aperta .offertaAperta-esterno { grid-template-rows: 1fr }
.offertaAperta-interno { overflow: hidden }
.offertaAperta { padding-bottom: 0.95rem }
.offertaAperta .quando:empty { display: none }

/* Il secondo segnale, quando affianca «La prendo»: un link, non un bottone —
   la differenza di peso è quello che tiene vera la regola di una sola
   azione primaria per offerta. */
.azioneSecondaria {
  display: block; width: 100%; margin-top: 0.65rem; padding: 0.3rem 0;
  font-size: 0.8rem; font-weight: 600; color: var(--petrolio); text-decoration: underline; text-align: center;
}

.rimando { display: inline-block; margin-top: 1.15rem; font-size: 0.8rem; color: var(--grigio); text-decoration: underline }

/* ── iscrizione a un evento ────────────────────────────────────────── */

form.iscrizione { margin-top: 0.85rem; background: #fff; border: 1px solid var(--linea); border-radius: 14px; padding: 0.85rem }
form.iscrizione .campi { display: grid; gap: 0.5rem }
form.iscrizione input[type="text"] {
  width: 100%; font: inherit; font-size: 1rem; padding: 0.68rem 0.75rem;
  border: 1px solid var(--linea); border-radius: 10px; background: var(--carta); color: var(--inchiostro);
}
form.iscrizione .quanti { display: flex; align-items: center; gap: 0.5rem; font-size: 0.88rem; color: var(--grigio); margin-top: 0.6rem }
form.iscrizione .quanti input {
  width: 4.2rem; font: inherit; font-weight: 600; padding: 0.42rem 0.5rem; text-align: center;
  border: 1px solid var(--linea); border-radius: 9px; background: var(--carta); color: var(--inchiostro);
}
form.iscrizione .spunta { display: flex; gap: 0.55rem; align-items: flex-start; margin-top: 0.72rem; font-size: 0.79rem; color: var(--grigio); line-height: 1.4 }
form.iscrizione .spunta input { width: 1.25rem; height: 1.25rem; margin-top: 0.1rem; flex: none; accent-color: var(--petrolio) }
form.iscrizione .spunta a { color: var(--petrolio); text-decoration: underline }
form.iscrizione button { width: 100%; margin-top: 0.85rem }
.errore-riga { background: #fdecea; border: 1px solid #f2c4bf; color: #a8322a; padding: 0.55rem 0.7rem; border-radius: 10px; font-size: 0.84rem; font-weight: 600; margin-bottom: 0.7rem }
.errore-riga[hidden] { display: none }

/* ── il giro che si chiude ─────────────────────────────────────────── */

.seiQui {
  background: var(--ambra); color: #4a2f00; border-radius: 12px;
  padding: 0.6rem 0.85rem; font-size: 0.95rem; font-weight: 600;
  margin: 0.2rem 0 0.9rem; text-align: center;
}
.giaStato {
  font-size: 0.82rem; font-weight: 600; color: var(--verde);
  background: #eaf5f0; border-radius: 999px; padding: 0.24rem 0.7rem;
  display: inline-block; margin-top: 0.7rem;
}
.azione.riscatta { width: 100%; margin-top: 0.8rem; background: var(--ambra); color: #4a2f00 }
/* Pieno petrolio, non più bordato: nella nuova offerta-riga «probabilmente
   ci sarò» non è mai un ripiego accanto a un altro bottone — o è l'unica
   azione dell'offerta (e allora è primaria quanto «La prendo»), o non c'è. */
.azione.presenza { width: 100%; margin-top: 0.8rem; background: var(--petrolio); color: #fff }

.riscatto {
  margin-top: 0.85rem; background: #0e4c5c; color: #fff; border-radius: 14px;
  padding: 0.85rem 1rem; text-align: center;
}
.etichettaRiscatto {
  display: block; font-size: 0.68rem; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--ambra-chiara);
}
.codiceRiscatto {
  display: block; font-size: 2.4rem; font-weight: 800; letter-spacing: 0.16em;
  line-height: 1.15; margin: 0.15rem 0 0.1rem;
}
.notaRiscatto { display: block; font-size: 0.75rem; color: var(--su-scuro-tenue) }

.iscritto { margin-top: 0.85rem; background: #e9f5ef; border: 1px solid #c7e5d6; border-radius: 14px; padding: 0.8rem 0.9rem; font-size: 0.9rem; line-height: 1.45; color: #17513a }
.iscritto b { font-weight: 800 }
.iscritto code { font-family: inherit; font-weight: 800; letter-spacing: 0.06em; background: #fff; border-radius: 6px; padding: 0.06rem 0.34rem }

/* Lo stesso verde tenue dell'iscritto: è la stessa famiglia di «ci sei»,
   solo più morbida. Il telefono è il gesto vero se i piani cambiano, quindi
   dev'essere il bersaglio più grande, non una riga di testo qualsiasi. */
.cisarai { margin-top: 0.85rem; background: #e9f5ef; border: 1px solid #c7e5d6; border-radius: 14px; padding: 0.8rem 0.9rem; font-size: 0.9rem; line-height: 1.45; color: #17513a }
.cisarai p { margin-bottom: 0.6rem }
.cisarai .telefono-locale {
  display: flex; align-items: center; justify-content: center; width: 100%;
  padding: 0.62rem 0.7rem; margin-bottom: 0.55rem; border-radius: 10px;
  background: #fff; border: 1px solid #c7e5d6; color: var(--petrolio); font-weight: 700; text-decoration: none;
}
.cisarai .disdici { font-size: 0.79rem; font-weight: 600; color: #4c7d68; text-decoration: underline }

/* ── barra in basso ────────────────────────────────────────────────── */

.barra {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 35;
  display: grid; grid-template-columns: repeat(3, 1fr);
  background: rgba(9, 56, 67, 0.93); backdrop-filter: blur(16px);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  padding-bottom: var(--sicuro-basso);
}
.tab {
  display: flex; flex-direction: column; align-items: center; gap: 0.16rem;
  padding: 0.6rem 0.3rem 0.55rem; font-size: 0.68rem; font-weight: 600;
  color: var(--su-scuro-tenue); position: relative;
}
.tab svg { width: 21px; height: 21px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round }
.tab[aria-current="page"] { color: var(--ambra) }
.tab .conteggio[hidden] { display: none }
.tab .conteggio {
  position: absolute; top: 0.34rem; right: 50%; margin-right: -1.5rem;
  min-width: 17px; height: 17px; padding: 0 4px; border-radius: 9px;
  background: var(--ambra); color: #4a2f00; font-size: 0.63rem; font-weight: 800;
  display: grid; place-items: center;
}

/* ── nastro dei dati di prova ──────────────────────────────────────── */

.nastro {
  background: var(--bronzo); color: #fff; font-size: 0.755rem; font-weight: 600;
  padding: 0.42rem 1.1rem; text-align: center; line-height: 1.35;
}

/* ── movimento ─────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important }
}

@media (min-width: 720px) {
  /* Su schermo largo l'app resta una colonna: è nata per il pollice. */
  .testata, .filtri, .schermo, .nastro { max-width: 30rem; margin-inline: auto }
  .barra { max-width: 30rem; margin-inline: auto; border-radius: 18px 18px 0 0 }
  .foglio { max-width: 30rem; margin-inline: auto; border-radius: 26px 26px 0 0 }
}
