/* esca — il meteo per la pesca. Sistema visivo dell'handoff Claude Design:
   fondo alba a mare, card "glass", verde/ambra/rosso a semaforo, Plex Mono per i dati. */

/* ---------------------------------------------------------------------------
   FONT SELF-HOSTATI (round 28). Prima erano caricati dal CDN di Google: quel
   `<link>` faceva inviare l'INDIRIZZO IP di ogni visitatore a Google prima di
   qualsiasi consenso, senza base giuridica (Landgericht München I, 3 O 17493/20,
   20 gennaio 2022). Non era un dettaglio di performance: era l'unica cosa
   concretamente illecita nel sito, e determinava se servisse un banner di consenso.
   Ora i file stanno in static/fonts/ e NESSUNA richiesta esce verso terzi.

   Entrambe le famiglie sono sotto SIL Open Font License 1.1, che consente il
   self-hosting. Subset: `latin` + `latin-ext` per il testo, solo `latin` per il
   monospace (serve a numeri e coordinate). Totale 77 KB, meno di due round-trip.

   ⚠️ Se qualcuno rimette un <link> a fonts.googleapis.com, torna anche il problema
   giuridico: allora Google va dichiarato in privacy.html §6-7 e serve il banner.
   --------------------------------------------------------------------------- */

/* Plus Jakarta Sans: font VARIABILE, un solo file copre i pesi 400-800 */
@font-face {
  font-family: 'Plus Jakarta Sans';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;   /* mostra subito il fallback: mai testo invisibile in attesa */
  src: url('/static/fonts/plus-jakarta-sans-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Plus Jakarta Sans';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/static/fonts/plus-jakarta-sans-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* IBM Plex Mono: statico, un file per peso (500/600/700, gli unici usati) */
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('/static/fonts/ibm-plex-mono-500-latin.woff2') format('woff2');
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('/static/fonts/ibm-plex-mono-600-latin.woff2') format('woff2');
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('/static/fonts/ibm-plex-mono-700-latin.woff2') format('woff2');
}

:root {
  --ink:#26333D; --ink2:#3E4C57; --muted:#5E6D77; --faint:#8A97A0; --faint2:#9AA6AE;
  --blue:#1E6CA4; --blue-strong:#155E8C; --amber:#C68A12; --red:#C0442E;
  --card:rgba(255,255,255,.55); --card-brd:rgba(255,255,255,.6);
  --sun:#FCE4CC;
  --sans:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,sans-serif;
  --mono:'IBM Plex Mono',ui-monospace,monospace;
  --shadow:0 10px 30px -14px rgba(20,40,60,.25);
}

* { box-sizing:border-box; }
html, body { margin:0; padding:0; }
/* NB: niente overflow-x:hidden/clip su html/body: su iOS Safari rompe il position:fixed (overlay mappa
   disallineato). Il drift orizzontale si contiene alla fonte (scroller con max-width:100% + contain). */
body {
  font-family:var(--sans); color:var(--ink);
  background:linear-gradient(180deg,#FCE4CC 0%,#F5DAD9 22%,#E6DCE8 44%,#D2E2F1 70%,#C3DBEF 100%);
  background-attachment:fixed; min-height:100vh; padding:0 0 44px;
  -webkit-font-smoothing:antialiased;
  /* manipulation: consente pan e pinch-zoom ma disabilita il DOPPIO-TAP-zoom di iOS (che zoomava
     la vista analisi tappando mappa/celle, lasciandola "spostata a sinistra"). */
  touch-action:manipulation;
}
.hidden { display:none !important; }
.wrap { max-width:1040px; margin:0 auto; padding:0 20px; }
.mono { font-family:var(--mono); font-variant-numeric:tabular-nums; }

.card {
  background:var(--card); backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px);
  border:1px solid var(--card-brd); border-radius:26px; box-shadow:var(--shadow);
}
.sec { padding:20px; margin-top:14px; }
.sec-head { display:flex; align-items:baseline; justify-content:space-between; gap:10px; flex-wrap:wrap; margin-bottom:12px; }
.sec-title { font-size:17px; font-weight:800; letter-spacing:-.01em; }
.sec-hint { font-size:12.5px; font-weight:600; color:var(--muted); }
.link { font-size:12.5px; font-weight:700; color:var(--blue); text-decoration:none; }
.foot { text-align:center; margin-top:24px; font-size:11.5px; line-height:1.6; color:var(--faint); font-weight:500; }
.btn { margin-top:14px; background:rgba(255,255,255,.7); border:1.5px solid var(--card-brd); border-radius:14px;
  padding:10px 16px; font-family:var(--sans); font-size:13.5px; font-weight:700; color:var(--ink); cursor:pointer; }

/* ---- top bar ---- */
.topbar { display:flex; align-items:center; flex-wrap:wrap; gap:8px 12px; padding-top:22px; padding-bottom:6px; }
.brand { display:flex; align-items:center; gap:9px; text-decoration:none; color:var(--ink); margin-right:auto; }
.top-loc { order:1; } .topmenu { order:2; }
.logo { width:28px; height:28px; border-radius:9px; background:var(--ink); display:grid; place-items:center; }
.hook { width:9px; height:9px; border:2px solid var(--sun); border-radius:0 0 9px 0; border-top:none; border-left:none; transform:rotate(8deg); }
.brand-name { font-weight:800; font-size:18px; letter-spacing:-.01em; }
.kb-chip { display:flex; align-items:center; gap:8px; background:rgba(255,255,255,.55); backdrop-filter:blur(10px);
  padding:7px 13px; border-radius:20px; font-size:12.5px; font-weight:600; color:var(--muted); box-shadow:0 2px 8px rgba(20,40,60,.06); }
.kb-chip .dot { width:7px; height:7px; border-radius:50%; background:var(--blue); flex:none; }
/* menu persistente della top-bar: Logga (primario) · I miei log · utente.
   #topLoc è lo slot contestuale (chip posizione) mostrato solo in analisi. */
.top-loc:empty { display:none; }
.topmenu { display:flex; align-items:center; gap:8px; flex-wrap:wrap; justify-content:flex-end; }
/* pulsanti di navigazione: pill bianche uguali (nessuna priorità di colore). Il nero
   è per le AZIONI primarie (.btn-primary), il blu solo per accenti/link. */
.menu-btn { display:inline-flex; align-items:center; text-decoration:none; white-space:nowrap;
  background:rgba(255,255,255,.92); border:1px solid rgba(20,40,60,.1); color:var(--ink);
  font-size:12.5px; font-weight:700; padding:9px 16px; border-radius:999px; cursor:pointer;
  box-shadow:0 2px 8px rgba(20,40,60,.08); transition:background .15s, transform .15s, box-shadow .15s; }
.menu-btn:hover { background:#fff; transform:translateY(-1px); box-shadow:0 5px 14px -4px rgba(20,40,60,.2); }
/* identità utente + logout: a fondo pagina, centrato (fuori dalla top-bar, dove un
   nome lungo romperebbe l'allineamento delle pill). */
/* banner "conferma l'indirizzo": ambra, non rosso — è un promemoria, non un errore.
   Compare solo agli autenticati non verificati (round 23). */
.verify-banner { display:flex; align-items:center; justify-content:space-between; gap:12px;
  flex-wrap:wrap; background:#FBF0DD; border:1px solid rgba(138,91,16,.22); border-radius:16px;
  padding:12px 16px; margin:14px 0 0; font-size:13.5px; font-weight:600; color:#6E4A0E; }
.verify-banner button { background:transparent; border:1px solid rgba(138,91,16,.35);
  color:#6E4A0E; border-radius:999px; padding:7px 14px; font-family:var(--sans); font-size:12.5px;
  font-weight:700; cursor:pointer; white-space:nowrap; }
.verify-banner button:hover { background:rgba(138,91,16,.09); }

/* footer legale: link a informativa e termini. Discreto ma presente su OGNI pagina —
   l'informativa deve essere raggiungibile da qualsiasi punto (art. 12 GDPR: accessibile).
   `position:relative; z-index:1` NON è decorativo: le pagine con la mappa di sfondo hanno
   `.bg-map` in `position:fixed; z-index:0`, che essendo posizionata si dipinge SOPRA questo footer
   statico e ne intercettava i click. Risultato misurato in produzione: i due link erano nell'HTML
   di ogni pagina ma NESSUNO dei due era cliccabile — raggiungibili solo da tastiera, perché
   `display` non è `none`. Alzarlo di un livello lo rimette davanti alla mappa. */
.legal-foot { position:relative; z-index:1;
  text-align:center; margin:30px auto 22px; font-size:12px; font-weight:600;
  color:var(--faint); display:flex; gap:9px; justify-content:center; align-items:center;
  flex-wrap:wrap; padding:0 16px; }
.legal-foot a { color:var(--muted); text-decoration:none; font-weight:700; }
.legal-foot a:hover { color:var(--ink2); text-decoration:underline; }
.legal-foot .dot { opacity:.5; }

/* ---- fascia fissa in fondo alla SPA: chip utente + pill "Legale", affiancate --------------------
   Nella SPA il footer nel flusso non può funzionare: la home è una mappa fissa a tutto schermo che
   gli si dipinge sopra, e in analisi il fondo è già occupato dalla chip utente. Quindi i link
   legali diventano una pill fissa accanto a quella chip: sempre a video (il requisito è
   "permanentemente accessibile") ma richiusa, perché il fondo dello schermo su mobile è la zona
   più contesa. Il contenitore non intercetta i gesti dove è vuoto, così la mappa resta trascinabile
   fra le due pill. ---- */
/* z-index 31: sopra il cartiglio della mappa (30), che altrimenti tagliava a metà il popover
   legale. Questa fascia porta comandi, il cartiglio è decorativo: la precedenza è sua. */
.bottom-bar { position:fixed; left:50%; bottom:14px; transform:translateX(-50%); z-index:31;
  display:flex; align-items:center; justify-content:center; gap:8px; flex-wrap:wrap;
  max-width:calc(100% - 24px); pointer-events:none; }
.bottom-bar > * { pointer-events:auto; }

.user-foot { text-align:center; font-size:12.5px; font-weight:600; color:var(--muted); }
.user-foot a { color:var(--blue); text-decoration:none; font-weight:700; }
/* la pill: forma condivisa fra la chip utente e quella legale, così stanno bene affiancate */
.user-foot.fixed, .legal-pill { background:rgba(255,255,255,.9);
  backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px); border-radius:999px;
  box-shadow:0 4px 14px -6px rgba(20,40,60,.3); border:1px solid rgba(20,40,60,.06); }
.user-foot.fixed { padding:7px 16px; }

.legal-pill { position:relative; display:flex; align-items:center; font-size:12px; font-weight:600; }
.legal-toggle { display:flex; align-items:center; gap:6px; padding:7px 14px; background:none;
  border:none; cursor:pointer; font:inherit; color:var(--muted); border-radius:999px;
  -webkit-tap-highlight-color:transparent; }
.legal-chev { width:9px; height:6px; flex:none; transition:transform .18s ease; }
.legal-pill.aperto .legal-chev { transform:rotate(180deg); }
/* Si apre VERSO L'ALTO, come popover ancorato alla pill. Allargandosi in linea invece sforava:
   a 390px il contenuto chiede ~330px, la fascia diventava larga quanto lo schermo e finiva sopra i
   comandi zoom in basso a sinistra. Così la fascia in fondo resta stretta e non si riorganizza. */
.legal-body { display:none; }
.legal-pill.aperto .legal-body { display:flex; align-items:center; justify-content:center;
  /* larghezza ESPLICITA, non `max-width`: essendo in posizione assoluta il popover si stringe sul
     contenuto, e col wrap finiva a incolonnare una parola per riga (misurato: 78px per 186 di alto). */
  flex-wrap:wrap; gap:4px 8px; width:226px;
  position:absolute; bottom:calc(100% + 8px); left:50%; transform:translateX(-50%);
  padding:9px 15px; border-radius:16px; color:var(--faint); text-align:center;
  background:rgba(255,255,255,.95); backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
  box-shadow:0 8px 22px -10px rgba(20,40,60,.4); border:1px solid rgba(20,40,60,.06); }
.legal-body a { color:var(--muted); text-decoration:none; font-weight:700; }
.legal-body a:hover { color:var(--ink2); text-decoration:underline; }
.legal-body .dot { opacity:.5; }
/* chip posizione = stessa pill dei pulsanti del menu (altezza/raggio/peso coerenti) */
.loc-chip { display:inline-flex; align-items:center; gap:7px; white-space:nowrap; max-width:100%;
  background:rgba(255,255,255,.92); border:1px solid rgba(20,40,60,.1); backdrop-filter:blur(10px);
  padding:9px 16px; border-radius:999px; font-size:12.5px; font-weight:700; color:var(--ink);
  box-shadow:0 2px 8px rgba(20,40,60,.08); cursor:pointer; }
.loc-chip .loc-name { overflow:hidden; text-overflow:ellipsis; }
.loc-chip .sep { width:1px; height:12px; background:rgba(38,51,61,.2); margin:0 3px; flex:none; }
.loc-chip .chg { color:var(--muted); font-weight:600; flex:none; }

/* ---- home hero ---- */
.hero-home { padding:30px 28px 26px; margin-top:14px; }
.kicker { font-size:12.5px; font-weight:700; color:var(--blue); letter-spacing:.08em; text-transform:uppercase; }
.hero-title { font-size:38px; font-weight:800; letter-spacing:-.025em; margin-top:8px; line-height:1.02; }
.hero-sub { font-size:15px; line-height:1.55; color:var(--muted); font-weight:500; margin-top:10px; max-width:560px; }
.hero-sub b { color:var(--ink); }
.search { display:flex; align-items:center; gap:11px; background:rgba(255,255,255,.7); border:1.5px solid rgba(255,255,255,.8);
  border-radius:999px; padding:11px 12px 11px 18px; margin-top:20px; box-shadow:0 2px 10px rgba(20,40,60,.06); }
/* Su desktop `.search-row` e `.search-field` sono trasparenti e non si vedono: la pill è `.search`,
   come è sempre stata. Esistono per il mobile, dove i tre pezzi si separano (vedi la @media in fondo). */
.search-row { display:flex; align-items:center; gap:11px; flex:1; min-width:0; }
.search-field { display:flex; align-items:center; gap:11px; flex:1; min-width:0; }
.search input { flex:1; background:transparent; border:none; outline:none; color:var(--ink); font-family:var(--sans);
  /* 16px: sotto i 16px iOS Safari fa auto-zoom al focus dell'input (e lo zoom resta: "pagina spostata") */
  font-size:16px; font-weight:500; min-width:0; }
.search-key { font-size:11px; font-weight:700; color:#fff; background:var(--ink); border:none; border-radius:999px; padding:9px 16px; flex:none; cursor:pointer; user-select:none; -webkit-tap-highlight-color:transparent; transition:background .12s, transform .12s; }
.search-key:hover { background:var(--ink2); }
.search-key:active { background:var(--ink2); transform:scale(.96); }
.search.busy .search-key { opacity:.4; }
.search-msg { font-size:12.5px; font-weight:600; color:var(--muted); min-height:16px; margin-top:7px; padding-left:4px; }
.steps { display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr)); gap:10px; margin-top:16px; }
.step { display:flex; gap:11px; background:rgba(255,255,255,.5); border-radius:16px; padding:13px 15px; }
.step-n { font-size:12px; font-weight:800; color:var(--blue); font-family:var(--mono); }
.step-t { font-size:13.5px; font-weight:700; }
.step-d { font-size:12px; color:var(--muted); font-weight:500; margin-top:2px; line-height:1.35; }

.home-map { height:340px; border-radius:16px; overflow:hidden; }

.recents { display:grid; grid-template-columns:repeat(auto-fit,minmax(240px,1fr)); gap:10px; }
.recent { text-decoration:none; color:var(--ink); display:block; background:rgba(255,255,255,.6); border:1.5px solid rgba(255,255,255,.7);
  border-radius:18px; padding:15px 16px; cursor:pointer; transition:transform .15s, box-shadow .15s; }
.recent:hover { transform:translateY(-2px); box-shadow:0 8px 20px -12px rgba(20,40,60,.3); }
.recent-top { display:flex; align-items:center; justify-content:space-between; gap:10px; }
.recent-name { font-size:16px; font-weight:800; letter-spacing:-.01em; }
.recent-coord { font-family:var(--mono); font-size:11px; color:var(--faint); font-weight:500; margin-top:2px; }
.recent-badge { border-radius:14px; min-width:54px; height:50px; display:flex; align-items:center; justify-content:center; flex:none; }
.recent-badge span { font-family:var(--mono); font-size:26px; font-weight:700; color:var(--ink); letter-spacing:-.02em; line-height:1; }
.recent-foot { display:flex; align-items:center; gap:7px; margin-top:12px; }
.recent-sp { font-size:12px; font-weight:700; }
.tech-pill { display:inline-flex; white-space:nowrap; font-size:11.5px; font-weight:700; color:var(--blue);
  background:rgba(30,108,164,.12); padding:6px 13px; border-radius:999px; }
/* solo nella lista specie: pill a destra che non deve mai rompere la riga (cap + ellissi) */
.prey-top .tech-pill { flex:0 0 auto; max-width:48%; overflow:hidden; text-overflow:ellipsis; }

/* ---- leaflet skin ---- */
.leaflet-container { background:#D2E2F1 !important; font-family:var(--sans) !important; border-radius:16px; }
.leaflet-control-attribution { background:rgba(255,255,255,.6) !important; color:var(--muted) !important; font-size:8px !important; }
.leaflet-control-attribution a { color:var(--blue) !important; }
.esc-cell { background:none; border:none; }

/* ---- home variante: mappa a tutto schermo + overlay ---- */
.topbar { position:relative; z-index:20; pointer-events:none; }   /* i vuoti della topbar lasciano passare i gesti alla mappa */
.topbar .brand, .topbar .top-loc, .topbar .topmenu, .topbar .method-sel { pointer-events:auto; }
.home-map-full { position:fixed; inset:0; z-index:1; border-radius:0 !important; }
/* mappa come SFONDO (landing, accedi): non interattiva, con velo alba a mare che
   la lega al brand e fa staccare le card in vetro sopra. */
.bg-map { position:fixed; inset:0; z-index:0; }
.bg-map.leaflet-container { border-radius:0 !important; background:#D2E2F1 !important; }
.bg-veil { position:fixed; inset:0; z-index:0; pointer-events:none;
  background:linear-gradient(180deg, rgba(252,228,204,.62) 0%, rgba(230,220,232,.5) 45%, rgba(195,219,239,.6) 100%); }
body.has-bgmap .page { position:relative; z-index:2; }
/* velo scuro sfumato nella fascia ALTA (solo su mappa): migliora la leggibilità
   di logo e pill sopra la mappa chiara. Corto, così non tinge le card sotto. */
body.map-visible::before, body.has-bgmap::before {
  content:""; position:fixed; top:0; left:0; right:0; height:78px; z-index:15; pointer-events:none;
  background:linear-gradient(180deg, rgba(20,40,60,.30) 0%, rgba(20,40,60,0) 100%); }
/* sopra la mappa i chip della topbar vanno resi più solidi per leggerli bene */
.map-mode .kb-chip { background:rgba(255,255,255,.9); border:1px solid rgba(20,40,60,.06); }
/* Il marchio sopra la mappa: le etichette geografiche del basemap gli passano dietro e "esca" si
   leggeva sopra i nomi delle regioni. Non è un problema di contrasto (il velo scuro basta) ma di
   RUMORE. Qui c'era un pill bianco, che risolveva ma faceva sembrare il marchio un pulsante, in fila
   con "Accedi". Un alone bianco fa lo stesso lavoro — stacca la scritta da ciò che le passa dietro —
   senza disegnare un contorno. Il quadratino del logo ha già una forma piena sua e non serve.
   Agganciato alle stesse classi del velo qui sopra (`map-visible`/`has-bgmap`): la condizione è
   "c'è una mappa dietro", non "quale home è attiva" — in analisi la mappa non c'è e l'alone non
   serve. */
body.map-visible .brand-name, body.has-bgmap .brand-name {
  text-shadow:0 0 6px rgba(255,255,255,.95), 0 0 14px rgba(255,255,255,.8); }
.home-map-full.leaflet-container { border-radius:0 !important; }
/* tre blocchi: ricerca (compatta, in alto) + tutorial (chiudibile) + recenti, che si alternano:
   il tutorial serve a chi arriva la prima volta, i recenti a chi torna */
.map-overlay { position:fixed; z-index:10; top:92px; left:0; right:0; display:flex; flex-direction:column; align-items:center; gap:10px; padding:0 16px; pointer-events:none; }
/* sopra la mappa chiara la card translucida sparisce: qui la rendiamo quasi opaca
   con bordo netto e ombra più marcata, così stacca bene e i bordi si vedono */
.ov-search, .ov-tut, .ov-recents { pointer-events:auto; width:min(560px,100%);
  background:rgba(255,255,255,.94); border:1px solid rgba(20,40,60,.09);
  box-shadow:0 16px 38px -16px rgba(20,40,60,.45); }
.ov-search { padding:14px 18px 13px; }
.ov-search .kicker { display:block; }
.ov-title { font-size:20px; font-weight:800; letter-spacing:-.02em; margin:3px 0 0; }
/* la card è bianca piena: il campo va "rientrato" con fondo e bordo definiti */
.ov-search .search { margin-top:11px; background:rgba(20,40,60,.05); border:1px solid rgba(20,40,60,.13); box-shadow:none; }
.ov-search .search:focus-within { border-color:rgba(30,108,164,.5); background:rgba(30,108,164,.05); }
.ov-tut { position:relative; padding:15px 40px 16px 18px; max-height:calc(100vh - 230px); overflow-y:auto; }
.ov-tut .kicker { display:block; margin-bottom:10px; }
/* Nell'overlay la griglia è larga 500px: `auto-fit` ci fa stare due colonne, e i tre passi
   lasciavano un buco in basso a destra. In colonna singola non c'è buco e la sequenza 01→02→03 si
   legge nell'ordine in cui va letta. */
.ov-tut .steps { margin-top:0; grid-template-columns:1fr; }
/* Recenti sull'overlay: RICHIUSI di default, si aprono col tocco sull'intestazione.
   Richiusi occupano solo la riga del titolo (~46px), così la mappa resta l'elemento dominante.
   Aperti mostrano `--recenti-visibili` voci e poi scorrono: l'altezza massima è calcolata dalle
   voci, non dal viewport, così la card non cresce mai fino a coprire lo schermo. */
.ov-recents { padding:0 18px 0; }
.ov-recents .kicker { display:block; }
.rec-toggle { display:flex; align-items:center; gap:9px; width:100%; padding:14px 0; background:none;
  border:none; cursor:pointer; color:var(--ink); font-family:var(--sans); text-align:left;
  -webkit-tap-highlight-color:transparent; }
.rec-n { font-size:12px; font-weight:600; color:var(--faint); margin-right:auto; }
.rec-chev { width:11px; height:7px; color:var(--muted); flex:none; transition:transform .18s ease; }
.ov-recents.aperta .rec-chev { transform:rotate(180deg); }
/* Nell'overlay i recenti stanno in colonna, non nella griglia della home a scheda. Aperto/chiuso è
   `display`, non una transizione su `max-height`: animare `max-height` obbliga a dichiarare un
   valore finito, quindi a stimare quanto è alta una voce — un numero che dipende dal contenuto (un
   nome che va a capo cresce) e che sbagliato taglia l'ultima voce a metà. Le voci sono tre e ci
   stanno tutte: non c'è niente da misurare e niente da far scorrere. */
.ov-recents .recents { grid-template-columns:1fr; display:none; }
.ov-recents.aperta .recents { display:grid; padding-bottom:16px; }
.tut-close { position:absolute; top:11px; right:11px; width:28px; height:28px; display:grid; place-items:center; border:none;
  border-radius:50%; background:rgba(38,51,61,.06); color:var(--muted); cursor:pointer; transition:background .15s, color .15s; }
.tut-close:hover { background:rgba(38,51,61,.12); color:var(--ink); }
.tut-close svg { width:13px; height:13px; }
.map-hint { position:fixed; z-index:30; left:50%; bottom:56px; transform:translateX(-50%); pointer-events:none; max-width:calc(100% - 32px); transition:opacity .18s ease; }
/* Con un pannello aperto (recenti o legale) il cartiglio finirebbe sopra il contenuto: si toglie,
   tanto in quel momento l'utente non sta toccando la mappa. La classe la mette JS in un punto solo
   (`segnaPannelloAperto`) invece di dedurla in CSS con `:has()`, che sui browser meno recenti non
   c'è: così il comportamento non dipende dal supporto del selettore. */
body.pannello-aperto .map-hint { opacity:0; }
.map-hint span { display:inline-block; background:rgba(255,255,255,.9); backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
  color:var(--muted); font-size:12px; font-weight:600; padding:8px 14px; border-radius:16px; border:1px solid rgba(20,40,60,.06);
  box-shadow:0 6px 18px -6px rgba(20,40,60,.28); white-space:nowrap; }
@media (prefers-reduced-motion: reduce) { .tut-body, .tut-toggle .chev { transition:none; } }
@media (max-width:560px) { .map-hint span { white-space:normal; text-align:center; } }

/* ---- analisi: hero specie-driven ---- */
.an-hero { padding:22px 24px; margin-top:14px; }
.an-hero-head { display:flex; align-items:center; justify-content:space-between; gap:10px 12px; flex-wrap:wrap; margin-bottom:16px; }
.an-hero-head .t { font-size:17px; font-weight:800; letter-spacing:-.01em; flex:1 1 auto; min-width:0; }
.badge-best { display:flex; align-items:center; gap:6px; background:rgba(21,94,140,.16); padding:6px 12px; border-radius:16px;
  font-size:12px; font-weight:700; color:var(--blue-strong); white-space:nowrap; }
.badge-rank { background:rgba(38,51,61,.07); padding:6px 12px; border-radius:16px; font-size:12px; font-weight:700; color:var(--muted); white-space:nowrap; }
/* bollino SCADUTA (post-mareggiata) — verde-acqua distinto dai badge blu/grigio */
.badge-scaduta { display:flex; align-items:center; gap:5px; background:rgba(20,140,120,.14); padding:6px 12px; border-radius:16px;
  font-size:12px; font-weight:700; color:#0E7C68; white-space:nowrap; }
/* bollino ZONA (insenatura/foce/molo/scoglio favorevole alla specie) — indaco */
.badge-zona { display:flex; align-items:center; gap:5px; background:rgba(92,80,160,.14); padding:6px 12px; border-radius:16px;
  font-size:12px; font-weight:700; color:#544A9C; white-space:nowrap; }
/* bollino STAGIONE (fenologia): "c'è, in questo mese?" — distinto dalla temperatura.
   .on = mese di punta (verde) · .off = fuori periodo (ambra, è un avviso non un errore) */
.badge-stagione { display:flex; align-items:center; gap:5px; padding:6px 12px; border-radius:16px;
  font-size:12px; font-weight:700; white-space:nowrap; }
.badge-stagione.on  { background:rgba(46,140,90,.14);  color:#256B47; }
.badge-stagione.off { background:rgba(190,120,20,.14); color:#8A5A0F; }
/* indicatore discreto "affino la zona…" durante il caricamento della morfologia OSM in background */
.refining-tag { position:fixed; z-index:40; left:50%; bottom:18px; transform:translateX(-50%);
  display:flex; align-items:center; gap:7px; background:rgba(255,255,255,.92); backdrop-filter:blur(8px);
  border:1px solid var(--card-brd); box-shadow:var(--shadow); border-radius:999px; padding:8px 15px;
  font-size:12px; font-weight:700; color:var(--muted); pointer-events:none; }
.refining-dot { width:8px; height:8px; border-radius:50%; background:var(--blue); animation:refpulse 1s ease-in-out infinite; }
@keyframes refpulse { 0%,100% { opacity:.35; transform:scale(.8); } 50% { opacity:1; transform:scale(1.15); } }
.an-hero-row { display:flex; align-items:center; gap:26px; flex-wrap:wrap; }
.score-box { display:flex; align-items:flex-start; gap:6px; border-radius:22px; padding:12px 22px 14px; }
.score-box .n { font-family:var(--mono); font-size:72px; font-weight:600; line-height:.82; letter-spacing:-.03em; color:var(--ink); }
.score-box .d { font-family:var(--mono); font-size:16px; font-weight:500; color:var(--faint); margin-top:7px; }
.verdict { flex:1; min-width:240px; }
.verdict .vt { font-size:23px; font-weight:800; letter-spacing:-.01em; }
.verdict .vw { font-size:14.5px; font-weight:700; color:var(--ink2); margin-top:3px; }
.verdict .vw b { color:var(--blue); font-weight:700; }
.verdict .vd { font-size:14px; line-height:1.5; color:var(--muted); font-weight:500; margin-top:9px; }

.spstrip { display:flex; gap:7px; overflow-x:auto; overscroll-behavior-x:contain; max-width:100%; margin-top:18px; padding-bottom:2px; }
.spstrip::-webkit-scrollbar { height:0; }
.spchip { flex:none; cursor:pointer; display:flex; align-items:center; gap:8px; padding:8px 13px; border-radius:15px;
  background:rgba(255,255,255,.4); border:1.5px solid rgba(255,255,255,.55); transition:all .15s; }
.spchip.sel { background:rgba(255,255,255,.9); border-color:var(--blue); }
.spchip .cdot { width:8px; height:8px; border-radius:50%; flex:none; }
.spchip .cname { font-size:13px; font-weight:700; color:var(--muted); white-space:nowrap; }
.spchip.sel .cname { color:var(--ink); }
.spchip .cscore { font-family:var(--mono); font-size:13.5px; font-weight:700; color:var(--ink); }

.astro { display:flex; gap:8px; margin-top:14px; flex-wrap:wrap; }
.astro span { display:flex; align-items:center; gap:7px; background:rgba(255,255,255,.6); padding:7px 13px; border-radius:14px; font-size:12.5px; font-weight:600; }
.astro .adot { width:7px; height:7px; border-radius:50%; }
.astro .aico { width:16px; height:16px; flex:none; display:block; margin:-1px 0; }

/* ---- analisi: giorno + curva ---- */
/* strip scorrevole su mobile (7 giorni non stanno in larghezza), griglia da ≥600px */
/* NB: niente `-webkit-overflow-scrolling:touch`: su iOS crea un layer di scroll separato che sballa il
   contenimento orizzontale (drift della pagina); su iOS moderno lo scroll a inerzia è già il default. */
.day-sel { display:flex; gap:6px; overflow-x:auto; overscroll-behavior-x:contain; max-width:100%; scroll-snap-type:x proximity; margin-bottom:18px; }
.day-sel::-webkit-scrollbar { height:0; }
.day-chip { flex:0 0 auto; min-width:60px; scroll-snap-align:start; cursor:pointer; border-radius:15px; padding:11px 8px 10px; text-align:center;
  background:rgba(255,255,255,.35); border:1.5px solid rgba(255,255,255,.5); transition:all .15s; }
@media (min-width:600px) {
  .day-sel { display:grid; grid-template-columns:repeat(7,1fr); overflow:visible; }
  .day-chip { min-width:0; padding-left:4px; padding-right:4px; }
}
.day-chip.sel { background:rgba(255,255,255,.85); border-color:var(--blue); }
.day-chip .star { font-size:12px; font-weight:700; height:14px; }
.day-chip .dn { font-size:12.5px; font-weight:600; margin-top:1px; }
.day-chip .dp { display:inline-block; border-radius:9px; padding:2px 9px; margin-top:5px; }
.day-chip .dp span { font-family:var(--mono); font-size:19px; font-weight:700; color:var(--ink); letter-spacing:-.02em; }

.chart-wrap { position:relative; }
#chartHit { position:relative; touch-action:none; cursor:crosshair; }
.chart-tip { position:absolute; top:0; transform:translateX(-50%); background:var(--ink); color:#fff; padding:5px 11px;
  border-radius:12px; font-size:12.5px; font-weight:800; white-space:nowrap; pointer-events:none;
  box-shadow:0 6px 16px rgba(20,40,60,.28); z-index:5; }
.legend { display:flex; gap:16px; flex-wrap:wrap; padding:6px 4px 0 44px; }
.legend span { display:flex; align-items:center; gap:6px; font-size:11.5px; font-weight:600; color:var(--muted); }
.legend .lb { display:inline-block; }

.day-windows { margin-top:16px; display:flex; flex-direction:column; gap:8px; }
.win { display:flex; align-items:center; gap:10px 14px; flex-wrap:wrap; background:rgba(255,255,255,.5); border-radius:15px; padding:12px 15px; }
.win-score { border-radius:11px; min-width:46px; height:44px; display:flex; align-items:center; justify-content:center; flex:none; }
.win-score span { font-family:var(--mono); font-size:21px; font-weight:700; color:var(--ink); letter-spacing:-.02em; }
.win-body { flex:1 1 55%; min-width:0; }
.win-time { font-size:14.5px; font-weight:700; }
.win-cond { font-size:12.5px; color:var(--muted); font-weight:500; margin-top:1px; }
.win-note { font-size:12.5px; color:var(--muted); font-weight:600; background:rgba(255,255,255,.5); border-radius:12px; padding:9px 13px; }
.win-note b { color:var(--ink); }

/* ---- griglia condizioni + scomposizione ---- */
.grid2 { display:flex; gap:14px; flex-wrap:wrap; margin-top:14px; }
.grid2 > * { flex:1 1 340px; min-width:0; margin-top:0; }
.cond-grid { display:grid; grid-template-columns:repeat(4,1fr); gap:9px; }
.cond { background:rgba(255,255,255,.6); border-radius:15px; padding:12px 13px; display:flex; flex-direction:column; justify-content:center; min-height:64px; }
.cond .k { font-size:11px; color:var(--muted); font-weight:600; line-height:1.2; }
/* Valore e unità su UNA riga sempre. Il tile su desktop ha circa 80px utili (colonna 492,
   card 452, quattro tile con gap 9, meno il padding): a 18/10 il caso peggiore misura 76px,
   quindi resta margine. `nowrap` è la rete di sicurezza se un giorno arriva un valore più lungo:
   meglio un troncamento visibile di un a capo silenzioso che sposta l'unità sotto al numero. */
.cond .v { font-family:var(--mono); font-size:18px; font-weight:600; letter-spacing:-.02em; margin-top:5px; line-height:1; white-space:nowrap; }
.cond .v .u { font-size:10px; font-weight:500; color:var(--faint); }

.brk { display:flex; flex-direction:column; gap:12px; }
.brk-row .rl { display:flex; justify-content:space-between; font-size:12.5px; margin-bottom:5px; }
.brk-row .rl .bk { color:var(--ink2); font-weight:600; }
.brk-row .rl .bv { font-family:var(--mono); font-weight:600; color:var(--ink); }
.brk-track { height:6px; background:rgba(38,51,61,.08); border-radius:4px; overflow:hidden; }
.brk-fill { height:100%; border-radius:4px; }
/* Riva a largo: asse (riva sx · largo dx) con pallino sulla posizione preferita della specie */
.shore-row .rl { margin-bottom:8px; }
.shore-axis { display:flex; align-items:center; gap:9px; }
.shore-axis .se { font-size:11px; font-weight:600; color:var(--muted); flex:none; }
.shore-track { position:relative; flex:1; height:6px; background:rgba(38,51,61,.09); border-radius:4px; }
.shore-ideal { position:absolute; top:50%; z-index:1; width:2.5px; height:17px; border-radius:2px; background:var(--ink2); transform:translate(-50%,-50%); }
.shore-dot { position:absolute; top:50%; z-index:2; width:13px; height:13px; border-radius:50%; border:2.5px solid #fff;
  transform:translate(-50%,-50%); box-shadow:0 1px 4px rgba(20,40,60,.35); }
.shore-legend { display:flex; gap:16px; margin-top:9px; }
.shore-legend span { display:flex; align-items:center; gap:6px; font-size:11px; font-weight:600; color:var(--muted); }
.shore-legend .lg-dot { width:9px; height:9px; border-radius:50%; border:1.5px solid #fff; box-shadow:0 0 0 1px rgba(20,40,60,.18); flex:none; }
.shore-legend .lg-tick { width:2.5px; height:12px; border-radius:2px; background:var(--ink2); flex:none; }

.habitat { display:flex; align-items:center; justify-content:space-between; gap:10px; border-radius:14px; padding:11px 14px; margin-top:14px; }
.habitat .ht { font-size:12.5px; font-weight:700; color:var(--ink2); }
.habitat .hs { font-size:11.5px; color:var(--muted); font-weight:500; margin-top:1px; }
.habitat .hx { font-family:var(--mono); font-size:19px; font-weight:700; color:var(--ink); letter-spacing:-.01em; white-space:nowrap; }

/* ---- scomposizione v2: frase-guida + assi ideale a adesso + gruppi ---- */
/* nome pesce differenziato dal titolo (tag), badge punteggio a semaforo */
.brk-head { align-items:flex-start; }
.brk-head .head-left { flex:1; min-width:0; }
.brk-head .sec-title { display:block; }
.sp-tag { display:inline-flex; align-items:center; margin-top:8px; background:rgba(255,255,255,.6);
  border:1px solid var(--card-brd); border-radius:999px; padding:4px 11px; font-size:12px; font-weight:700; color:var(--ink2); }
.sp-tag .sp-dot { width:7px; height:7px; border-radius:50%; background:var(--blue); margin-right:7px; flex:none; }
.score-badge { flex:none; font-family:var(--mono); font-size:16px; font-weight:700; letter-spacing:-.01em;
  border-radius:11px; padding:2px 11px; line-height:1.35; }
/* frase-guida: nomina il fattore che frena (Liebig) */
.brk-lead { font-size:13.5px; line-height:1.5; color:var(--muted); font-weight:500; margin:2px 0 4px; }
.brk-lead b { color:var(--ink); font-weight:700; }
/* gruppi con divisore sobrio + intestazione che nomina i contenuti */
.brk-grp { margin-top:18px; padding-top:16px; border-top:1px solid rgba(38,51,61,.09); }
.brk-grp.first { margin-top:16px; }
.brk-grp-h { font-size:11.5px; font-weight:700; letter-spacing:.07em; text-transform:uppercase; color:var(--faint); margin-bottom:14px; }
/* riga condizione: asse con banda ideale + linietta ottimo + pallino "adesso".
   UNICO elemento colorato dalla valutazione = il pallino (.fit-dot). */
.fit + .fit { margin-top:15px; }
.fit-h { display:flex; justify-content:space-between; font-size:12.5px; margin-bottom:9px; }
.fit-h .fk { font-weight:600; color:var(--ink2); }
.fit-h .fv { font-family:var(--mono); font-weight:600; color:var(--ink); }
.fit-axis { position:relative; height:20px; }
.fit-track { position:absolute; top:50%; left:0; right:0; height:6px; transform:translateY(-50%); background:rgba(38,51,61,.09); border-radius:4px; }
.fit-band { position:absolute; top:50%; height:6px; transform:translateY(-50%); border-radius:4px; background:rgba(21,94,140,.24); }
.fit-gap { position:absolute; top:50%; height:0; transform:translateY(-50%); border-top:2px dotted rgba(38,51,61,.30); z-index:1; }
.fit-ideal { position:absolute; top:50%; z-index:2; width:2.5px; height:17px; border-radius:2px; background:var(--ink2); transform:translate(-50%,-50%); }
.fit-dot { position:absolute; top:50%; z-index:3; width:13px; height:13px; border-radius:50%; border:2.5px solid #fff; transform:translate(-50%,-50%); box-shadow:0 1px 4px rgba(20,40,60,.35); }
.fit-poles { display:flex; justify-content:space-between; margin-top:4px; }
.fit-poles span { font-size:11px; font-weight:600; color:var(--muted); }
.fit-legend { display:flex; gap:16px; margin-top:15px; flex-wrap:wrap; }
.fit-legend span { display:flex; align-items:center; gap:6px; font-size:11px; font-weight:600; color:var(--muted); }
.fit-legend .lg-band { width:15px; height:6px; border-radius:3px; background:rgba(21,94,140,.24); flex:none; }
.fit-legend .lg-tick { width:2.5px; height:12px; border-radius:2px; background:var(--ink2); flex:none; }
.fit-legend .lg-dot { width:9px; height:9px; border-radius:50%; border:1.5px solid #fff; box-shadow:0 0 0 1px rgba(20,40,60,.18); flex:none; background:var(--blue); }
/* modificatori: fattori a basso peso, quieti — nome(muted) < giudizio(ink2) < valore(faint) */
.mods { margin-top:12px; display:flex; flex-direction:column; gap:1px; }
.mods-row { display:flex; justify-content:space-between; align-items:baseline; gap:14px; padding:7px 2px; }
.mods-row + .mods-row { border-top:1px solid rgba(38,51,61,.06); }
.mods-row .mf { font-size:12.5px; font-weight:600; color:var(--muted); }
.mods-row .mj { font-size:12.5px; font-weight:700; color:var(--ink2); margin-left:8px; }
.mods-row .mval { font-size:11.5px; font-weight:500; color:var(--faint); white-space:nowrap; }

/* ---- analisi: colonna singola su mobile, DUE colonne su desktop (più leggibile).
   Niente buchi: le due colonne sono stack indipendenti (`.an-col` in flex-column), non una
   griglia con righe allineate. Su mobile le card tornano in una colonna sola nell'ordine di
   lettura, con la mappa in fondo (vedi `layoutColumns()` in app.js).
   Hero e Altre specie restano a piena larghezza (headline / lista lunga). ---- */
/* clip sul contenitore dell'analisi (NON su html/body: lì rompe il position:fixed su iOS): contiene
   l'eventuale sforo orizzontale degli scroller interni senza effetti collaterali sugli elementi fissi. */
#anBody { max-width:640px; margin-left:auto; margin-right:auto; overflow-x:clip; }
.an-cols { display:flex; flex-direction:column; gap:14px; margin-top:14px; }
.an-col { display:flex; flex-direction:column; gap:14px; min-width:0; }
.an-col:empty { display:none; }                    /* su mobile la 2ª colonna è vuota */
.an-cols .sec { margin-top:0; }                    /* spaziatura via gap, non via margin-top */

@media (min-width:900px) {
  #anBody { max-width:1000px; }
  /* Due colonne di ALTEZZA UGUALE (align-items:stretch). La composizione è FISSA e sta in
     index.html: a sinistra Indice/Condizioni/Composizione, a destra Scheda specie/Mappa. A
     pareggiare i fondi ci pensa il solo `flex-grow` della card mappa qui sotto: lo spazio extra
     resta DENTRO quella card, senza buchi fra le colonne e senza spostare nulla. */
  .an-cols { flex-direction:row; align-items:stretch; gap:16px; }
  .an-col { flex:1 1 0; gap:16px; }
  .an-col:empty { display:flex; }                  /* la colonna vuota riserva comunque il suo 50% */
  /* NB: qui c'era `.an-fill`, che allungava l'ultima card della colonna corta distribuendone le
     sezioni. Rimossa il 2026-07-26: ora a pareggiare i fondi è la card della mappa (vedi
     `.cell-card`), che può crescere senza deformare nulla. Stirare una card di dati a righe fisse
     era la causa dell'effetto "Composizione stirata" dopo la crescita della scheda specie. */
  .cell-card { flex:1 1 auto; }                    /* la mappa è l'elemento elastico della colonna */
  .prey-list { display:grid; grid-template-columns:1fr 1fr; gap:10px; }  /* lista specie su 2 colonne */
}

/* ---- Scheda "Come insidiarla" ---- */
.sc-sp { display:inline-flex; align-items:baseline; background:rgba(255,255,255,.6); border:1px solid var(--card-brd);
  border-radius:999px; padding:5px 12px; font-size:13px; font-weight:800; color:var(--ink); flex:none; max-width:62%; overflow:hidden; }
.sc-sp .d { width:7px; height:7px; border-radius:50%; background:var(--blue); margin-right:7px; flex:none; align-self:center; }
.sc-sp .lat { font-style:italic; font-weight:600; color:var(--faint); margin-left:6px; font-size:11.5px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* esca suggerita: il protagonista della scheda */
.esca-box { border-radius:16px; padding:14px 15px; background:rgba(21,94,140,.10); border:1px solid rgba(21,94,140,.22); }
.esca-k { display:flex; align-items:center; font-size:11px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--blue-strong); margin-bottom:8px; }
/* marchio amo del logo, in blu */
.hookmark { display:inline-block; width:9px; height:9px; border:2px solid var(--blue-strong); border-top:none; border-left:none;
  border-radius:0 0 9px 0; transform:rotate(8deg); margin-right:9px; flex:none; }
.esca-tipo { font-size:21px; font-weight:800; letter-spacing:-.01em; line-height:1.05; }
.esca-size { font-family:var(--mono); font-size:12.5px; font-weight:600; color:var(--muted); margin-top:5px; }
.esca-size .b { color:var(--blue-strong); font-weight:700; }
.esca-line { font-size:12.5px; font-weight:600; color:var(--ink2); margin-top:8px; }
.esca-line .dot { color:var(--faint); margin:0 6px; }
.esca-why { font-size:11.5px; color:var(--muted); font-weight:500; margin-top:10px; padding-top:9px; border-top:1px solid rgba(21,94,140,.15); line-height:1.4; }
.sc-grp { margin-top:16px; }
.sc-grp-h { font-size:11.5px; font-weight:700; letter-spacing:.07em; text-transform:uppercase; color:var(--faint); margin-bottom:9px; }
.sc-bio { font-size:13px; line-height:1.5; color:var(--muted); font-weight:500; }
.sc-bio b { color:var(--ink2); font-weight:700; }
.sc-chips { display:flex; gap:7px; flex-wrap:wrap; }
.sc-chip { font-size:11.5px; font-weight:700; color:var(--ink2); background:rgba(255,255,255,.6); border:1px solid var(--card-brd); border-radius:999px; padding:5px 12px; }

/* ---- scheda specie: identità statica (identikit, riconoscimento, taglie, norma) ---- */
.sc-fam { display:inline-block; font-size:11.5px; font-weight:600; font-style:italic; color:var(--faint); margin:-6px 0 2px; }
.sc-hint { font-size:11px; font-weight:600; color:var(--faint); margin-top:11px; }
/* Illustrazione scontornata: sfondo trasparente, quindi nessun riquadro né bordo, solo respiro.
   ALTEZZA FISSA, non `max-height`, e il motivo NON è più quello di prima. Nasceva come rimedio al
   "flash" al cambio giorno: la card cresceva quando l'immagine arrivava e `balanceColumns()`, che
   misurava le altezze, ridistribuiva le card dopo. Quel meccanismo non esiste più (le colonne sono
   fisse e a pareggiare i fondi è la mappa via CSS), quindi oggi l'altezza fissa è una SCELTA e non
   un vincolo: tiene tutte e 38 le tavole nello stesso rettangolo, come in un atlante.
   Conseguenza accettata: `object-fit:contain` centra senza deformare, e il rettangolo (3,2:1) sta
   in mezzo agli estremi del roster (occhiata 1,9:1, aguglia 5,9:1), quindi le specie tozze lasciano
   margine ai lati e quelle affusolate sopra e sotto. Chi volesse togliere quel margine deve
   rinunciare al formato unico: è un compromesso, non un difetto rimasto da sistemare. */
.sc-fig { margin:10px 0 2px; height:130px; }
.sc-fig img { display:block; width:100%; max-width:420px; height:100%; margin:0 auto;
  object-fit:contain; }
.sc-note { font-size:11px; line-height:1.45; color:var(--faint); font-weight:500; margin-top:10px; }
/* Avvertenza: sicurezza (spine velenose) o vincolo di prelievo. Segnalata dal colore e dal
   bordo, non da un'icona: deve leggersi come una nota tecnica, non come un adesivo. */
.sc-warn { font-size:12.5px; line-height:1.45; font-weight:600; color:#8A4B12;
  background:rgba(201,143,20,.12); border:1px solid rgba(201,143,20,.34);
  border-radius:12px; padding:10px 12px; margin-top:12px; }
.sc-metrics { display:grid; grid-template-columns:repeat(auto-fit,minmax(148px,1fr)); gap:9px; }
.sc-metric { background:rgba(255,255,255,.55); border:1px solid var(--card-brd); border-radius:12px; padding:9px 11px; min-width:0; }
.sc-metric-k { font-size:10.5px; font-weight:700; letter-spacing:.05em; text-transform:uppercase; color:var(--faint); }
.sc-metric-v { font-family:var(--mono); font-size:14px; font-weight:700; color:var(--ink2); margin-top:4px; }
.sc-metric-v b { color:var(--blue-strong); }
/* L'unità (TL/FL/SL/ML) è più piccola ma sempre presente: senza, i numeri non sono confrontabili. */
.sc-metric-v .u { font-size:10.5px; font-weight:600; color:var(--faint); margin-left:2px; }
.sc-metric-v .na { font-family:var(--sans,inherit); font-size:12px; font-weight:600; color:var(--muted); }
.sc-metric-v .iucn-alert { color:#B0552A; }
.sc-metric-h { font-size:10px; line-height:1.35; color:var(--faint); font-weight:500; margin-top:4px; }

/* ---- muro della prova gratuita (anonimi) ---- */
.trial-wall { position:fixed; inset:0; z-index:200; display:flex; align-items:center; justify-content:center; padding:24px;
  background:rgba(20,40,60,.42); backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px); }
.trial-card { position:relative; width:100%; max-width:420px; background:var(--card); border:1px solid var(--card-brd);
  border-radius:26px; box-shadow:var(--shadow); padding:30px 28px 26px; text-align:center; }
.trial-close { position:absolute; top:14px; right:14px; width:32px; height:32px; border-radius:50%; border:none; cursor:pointer;
  background:rgba(20,40,60,.06); color:var(--muted); display:flex; align-items:center; justify-content:center; padding:0; }
.trial-close:hover { background:rgba(20,40,60,.12); }
.trial-close svg { width:14px; height:14px; }
.trial-title { font-size:23px; font-weight:800; letter-spacing:-.01em; line-height:1.15; margin:12px 0 10px; }
.trial-sub { font-size:14.5px; line-height:1.55; color:var(--muted); font-weight:500; margin:0 0 24px; }
.trial-cta { display:flex; flex-direction:column; gap:10px; }
.trial-cta a { display:inline-flex; align-items:center; justify-content:center; text-decoration:none; font-size:15px; font-weight:700;
  padding:14px 22px; border-radius:999px; transition:background .15s, transform .15s, box-shadow .15s; }
.trial-cta .btn-primary { background:var(--ink); color:#fff; box-shadow:0 8px 20px -10px rgba(20,40,60,.55); }
.trial-cta .btn-primary:hover { background:var(--ink2); transform:translateY(-1px); }
.trial-cta .btn-ghost { background:rgba(255,255,255,.85); color:var(--ink); border:1px solid rgba(20,40,60,.1); }
.trial-cta .btn-ghost:hover { background:#fff; }

/* ---- "Altre specie": chevron di selezione (l'esca vive nella Scheda) ---- */
.prey-chev { flex:none; color:var(--faint2); }

/* ---- cosa pescare ---- */
.prey { cursor:pointer; border:1.5px solid rgba(255,255,255,.55); background:rgba(255,255,255,.6); border-radius:16px; padding:12px 14px; transition:all .15s; }
.prey.sel { background:rgba(30,108,164,.09); border-color:var(--blue); }
.prey-top { display:flex; align-items:center; gap:12px; }
.prey-badge { border-radius:14px; min-width:48px; height:48px; display:flex; align-items:center; justify-content:center; flex:none; }
.prey-badge span { font-family:var(--mono); font-size:22px; font-weight:700; color:var(--ink); letter-spacing:-.02em; line-height:1; }
.prey-main { flex:1 1 auto; min-width:0; }
.prey-name { font-size:15.5px; font-weight:800; letter-spacing:-.01em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.prey-latin { font-size:11.5px; color:var(--faint); font-style:italic; margin-top:1px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.prey-list { display:flex; flex-direction:column; gap:8px; }
.prey-bar { height:5px; background:rgba(38,51,61,.08); border-radius:3px; overflow:hidden; margin-top:10px; }
.prey-bar > span { display:block; height:100%; border-radius:3px; }

/* La card della cella fa da JOLLY nel bilanciamento delle due colonne (balanceColumns): finisce
   nella colonna più corta e cresce fino a pareggiare i fondi. Per questo la mappa al suo interno
   è l'elemento elastico (flex:1) e la card non ha altezza propria. */
.cell-card { display:flex; flex-direction:column; }
/* Limiti dell'elasticità: sotto i 220px la mappa non si legge più, sopra i 560 il pareggio delle
   colonne non vale una mappa sproporzionata rispetto alle card di dati che le stanno accanto. */
/* Corsa della mappa: è lei a pareggiare i fondi delle due colonne, quindi i limiti non sono
   arbitrari. Misurata l'altezza che le serve per pareggiare su tutte le specie × 7 giorni × 10
   tecniche, in tre larghezze di viewport e su due punti diversi: sta fra 350 e 854 px, col massimo
   sul bolentino a 1024 px di viewport. I limiti qui sotto tengono quell'intervallo con margine per
   parte. Vanno tenuti LARGHI di proposito: la mappa cresce solo quanto serve, mentre un tetto
   stretto la manderebbe a fondo corsa e lo spazio non assorbito ricomparirebbe come bianco dentro
   la card, sotto i meta. Se un domani il contenuto cresce ancora, il sintomo è quello. */
.cell-map { flex:1; min-height:260px; max-height:1000px; border-radius:16px; overflow:hidden; }
.cell-meta { display:flex; gap:10px; flex-wrap:wrap; margin-top:12px; }
.cell-meta .m { font-size:12px; font-weight:600; color:var(--ink2); background:rgba(255,255,255,.6); padding:6px 11px; border-radius:13px; }
.cell-meta .m.mono { font-family:var(--mono); font-size:11px; font-weight:500; }

.land-title { font-size:22px; font-weight:800; letter-spacing:-.01em; }
.land-sub { font-size:14px; color:var(--muted); font-weight:500; margin-top:6px; line-height:1.5; }

/* ---- skeleton ---- */
.sk { display:block; background:linear-gradient(90deg,rgba(255,255,255,.35),rgba(255,255,255,.6),rgba(255,255,255,.35));
  background-size:200% 100%; animation:sh 1.3s ease-in-out infinite; border-radius:12px; }
@keyframes sh { 0%{background-position:200% 0;} 100%{background-position:-200% 0;} }
.sk-row { display:flex; justify-content:space-between; gap:10px; margin-bottom:14px; }
.sk-title { width:180px; height:20px; } .sk-hint { width:90px; height:16px; }
.sk-big { width:100%; height:96px; margin-bottom:14px; }
.sk-chips { display:grid; grid-template-columns:repeat(4,1fr); gap:8px; margin-bottom:14px; }
.sk-chip { height:44px; } .sk-chart { width:100%; height:200px; }
.sk-note { display:flex; align-items:center; gap:8px; font-size:13px; color:var(--muted); font-weight:600; margin-top:12px; }
.spin { width:14px; height:14px; border:2px solid rgba(38,51,61,.2); border-top-color:var(--blue); border-radius:50%; display:inline-block; animation:sp .8s linear infinite; }
@keyframes sp { to { transform:rotate(360deg); } }

@media (max-width:560px) {
  .hero-title { font-size:30px; }
  .score-box .n { font-size:60px; }
  .cond-grid { grid-template-columns:repeat(2,1fr); }
  /* top-bar mobile: logo + menu sulla PRIMA riga; la chip posizione va a tutta
     larghezza sulla SECONDA riga (niente wrap che stringe il logo). */
  .topbar { padding-top:16px; }
  .menu-btn { padding:8px 13px; font-size:12px; }
  .user-chip .uname { display:none; }        /* su mobile resta solo "esci" */
  .topmenu { order:1; }
  .top-loc { order:2; flex:1 1 100%; }
  .top-loc .loc-chip { width:100%; }
  .top-loc .loc-label { display:none; }      /* su mobile: solo nome + "cambia" */
  .map-overlay { top:78px; }
  /* lista specie: badge/pill più compatti così il NOME resta leggibile e nulla si rompe */
  .prey-top { gap:10px; }
  .prey-badge { min-width:42px; height:42px; }
  .prey-badge span { font-size:19px; }
  .prey-name { font-size:15px; }
  .prey-top .tech-pill { max-width:46%; padding:5px 11px; }
}

/* selettore METODO di pesca (ricerca home + top-bar analisi) — pill azzurra coerente coi token,
   simmetrica al pulsante INVIO; la label si tronca con "…" se lunga (Surfcasting: Surfca…). */
.method-sel {
  flex:none; appearance:none; -webkit-appearance:none;
  background:rgba(30,108,164,.10); border:1px solid rgba(30,108,164,.22);
  color:var(--blue-strong); font-family:var(--sans); font-size:12px; font-weight:700;
  border-radius:999px; padding:9px 26px 9px 14px; cursor:pointer; line-height:1.1;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23155E8C' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 12px center; background-size:9px;
}
.method-sel:focus { outline:none; border-color:var(--blue); }
.method-sel-top { order:0; }   /* nella top-bar: a sinistra della chip posizione */
/* barra di ricerca: pill compatta e simmetrica a INVIO (label troncata).
   NB: queste regole stanno DOPO ogni @media sopra: vincono per ordine di sorgente. */
.search .method-sel { max-width:170px; }

/* ---- SOTTO I 600px: il selettore ESCE dalla pill di ricerca ---------------------------------
   Il vincolo è di spazio, misurato a 390px di viewport: dentro la pill ci sono 290px, e selettore
   compatto (96) + lente (18) + INVIO (64) + spazi lasciano 88px all'input, mentre "Cerca una
   località…" ne chiede 147. In una riga sola non ci sta, qualunque segnaposto si scelga.
   Il primo rimedio lo mandava a capo restando DENTRO la pill: risultato, un blocco grigio alto
   99px con un campo azzurro dentro, che si leggeva come due campi vuoti sovrapposti. Ora sono due
   elementi distinti: sopra il pill azzurro della tecnica a tutta larghezza, sotto la barra grigia
   col tasto INVIO dentro a destra. `.search` diventa un contenitore trasparente.
   La soglia è 600px in tutte le regole coinvolte: prima il selettore passava a piena larghezza già
   sotto i 600 mentre `flex-wrap` scattava a 560, e nella fascia 560-599 la riga non andava a capo
   e schiacciava tutto. ---- */
@media (max-width:599px) {
  /* `--pill-h`: un'unica altezza per tutti e tre i pezzi. Prima erano scompagnati (selettore 40px,
     barra 56px) e si vedeva. 44px è anche il bersaglio minimo comodo per un dito. */
  .search { --pill-h:44px; background:none; border:none; box-shadow:none; padding:0;
    flex-direction:column; align-items:stretch; gap:8px; }
  /* `.ov-search .search` ha specificità 0,2,0 e vincerebbe su `.search` anche stando più in alto:
     va azzerata con pari specificità, non basta scrivere dopo. */
  .ov-search .search { background:none; border:none; box-shadow:none; padding:0; }
  .search .method-sel { width:100%; max-width:none; height:var(--pill-h); }
  /* campo e INVIO restano sulla stessa riga, ma sono due pill distinte */
  .search-row { flex:none; gap:8px; }
  .search-field { flex:1; height:var(--pill-h); padding:0 14px 0 16px; border-radius:999px;
    background:rgba(255,255,255,.7); border:1.5px solid rgba(255,255,255,.8);
    box-shadow:0 2px 10px rgba(20,40,60,.06); }
  .search-key { height:var(--pill-h); display:flex; align-items:center; padding:0 18px; }
  /* nell'overlay sopra la mappa il campo è "rientrato" e non bianco: segue `.ov-search .search` */
  .ov-search .search-field { background:rgba(20,40,60,.05); border:1px solid rgba(20,40,60,.13); box-shadow:none; }
  .ov-search .search-field:focus-within { border-color:rgba(30,108,164,.5); background:rgba(30,108,164,.05); }
}
