/* bus-buster.it — stili della SPA (mappa.html).
   Estratto dal blocco <style> inline di mappa.html il 2026-07-10
   (ANALISI_DEBOLEZZE §3.1): servito hashato da WhiteNoise, precachato dal SW.
   tb.css resta separato: serve solo le pagine SEO (base_public.html). */
/* V05-bis: fallback metric-matched (size-adjust calcolato dai woff2 con
   fontTools vs Arial/Georgia di sistema). Con fonts.css async, il primo paint
   usa questi fallback con le STESSE metriche dei webfont → lo swap non
   sposta il layout (CLS da "Web font loaded" era 0.31 sul .hero-form). */
@font-face { font-family:'DM Sans Fallback'; src:local('Arial');
  size-adjust:103.53%; ascent-override:95.82%; descent-override:29.94%; line-gap-override:0%; }
@font-face { font-family:'Fredoka Fallback'; src:local('Arial');
  size-adjust:101.75%; ascent-override:95.73%; descent-override:23.20%; line-gap-override:0%; }
@font-face { font-family:'DM Serif Display Fallback'; src:local('Georgia');
  size-adjust:100.47%; ascent-override:103.11%; descent-override:33.34%; line-gap-override:0%; }
:root {
  --sea: #0a4f6e; --sea-light: #1a7fa0; --sea-pale: #e8f4f8;
  --sand: #f5efe6; --sand-dark: #d4b896; --text: #1a1a2e;
  --text-muted: #5b6370; --white: #ffffff; --accent: #e8622a;
  /* A11y: --accent (3.38:1 su bianco) solo per sfondi/decorazioni;
     per TESTO accent usare --accent-text (4.66:1 su bianco, 4.18:1 su --accent-light). */
  --accent-text: #c4501a;
  --accent-light: #fdf0eb; --green: #2d7a4f; --green-light: #e8f5ee;
  --border: rgba(10,79,110,0.15);
  /* A11y (WCAG 1.4.11): bordo dei CONTROLLI interattivi ≥3:1 su bianco */
  --border-input: rgba(10,79,110,0.62);
  --shadow: 0 4px 24px rgba(10,79,110,0.12); --radius: 12px;
}
* { margin:0; padding:0; box-sizing:border-box; }
body { font-family:'DM Sans','DM Sans Fallback',sans-serif; background:var(--sand); color:var(--text); height:100vh; display:flex; flex-direction:column; overflow:hidden; }
/* P21: l'header non ha piu' uno stile suo qui. Guscio, marchio, badge,
   tasto Mappa, hamburger e cassetto stanno in `tb.css`, perche' l'header
   e' UNO (`_header.html`) ed e' lo stesso su ogni pagina del sito.
   Restano qui sotto solo le regole che dipendono dallo STATO della SPA
   (`body.s-results` / `body.s-map`), che e' un'altra cosa: non e'
   l'header che cambia da pagina a pagina, e' la SPA che si stringe
   quando la scheda di viaggio prende la scena (UX-A). */
.app { flex:1; display:flex; overflow:hidden; }
.sidebar { width:380px; flex-shrink:0; background:var(--white); display:flex; flex-direction:column; overflow:hidden; border-right:1px solid var(--border); z-index:100; }
.search-form { padding:16px; border-bottom:1px solid var(--border); background:var(--sea-pale); }
.search-label { font-size:11px; font-weight:600; text-transform:uppercase; letter-spacing:0.08em; color:var(--sea); margin-bottom:8px; }
/* ── cascade selettore ── */
.cascade-wrap { position:relative; margin-bottom:8px; }
.cascade-field { display:flex; align-items:center; padding:0 36px 0 32px; border:1.5px solid var(--border-input); border-radius:8px; background:white; transition:border-color 0.2s; position:relative; min-height:42px; }
/* GATE B: spazio per il tasto «Comuni e fermate» dentro il campo */
.cascade-field { padding-right:150px; }
/* GATE B · 1a: la domanda e' un'etichetta VERA sopra il campo */
.hero-label { display:flex; align-items:center; justify-content:space-between; margin:0 0 6px; }
.hero-label label { font-family:'Fredoka','Fredoka Fallback',sans-serif; font-size:18px; font-weight:600; color:var(--sea); cursor:pointer; }
.hero-label-to { margin-top:14px; }
/* GATE B · 2b: il tasto che apre la tendina (l'unico modo, oltre a ↓) */
.btn-elenco { position:absolute; right:8px; top:50%; transform:translateY(-50%);
  display:inline-flex; align-items:center; gap:4px; border:1.5px solid var(--border);
  border-radius:14px; background:white; color:var(--sea); font-size:12px; font-weight:600;
  padding:5px 10px; font-family:'DM Sans','DM Sans Fallback',sans-serif; cursor:pointer; z-index:2; }
.btn-elenco:hover, .btn-elenco:focus-visible { background:var(--sea-pale); border-color:var(--sea); }
/* stato compilato: al posto del tasto c'e' la x (uno dei due alla volta) */
.cascade-field.filled .btn-elenco { display:none; }
.cascade-field.filled { padding-right:36px; }
/* terzo livello: l'affordance sulla riga del comune e il filtro di testo */
.cascade-vedi-fermate { border:none; background:none; color:var(--sea-light); font-size:11px;
  font-weight:600; cursor:pointer; padding:6px 4px; white-space:nowrap; font-family:inherit; }
.cascade-vedi-fermate:hover, .cascade-vedi-fermate:focus-visible { color:var(--sea); text-decoration:underline; }
.cascade-comune-testa { font-weight:700; background:var(--sea-pale); }
.cascade-filtro { display:block; width:calc(100% - 28px); margin:8px 14px; padding:8px 10px;
  border:1.5px solid var(--border); border-radius:8px; font-size:13px;
  font-family:'DM Sans','DM Sans Fallback',sans-serif; outline:none; }
.cascade-filtro:focus { border-color:var(--sea); }
.cascade-field:focus-within { border-color:var(--sea-light); }
.cascade-field.filled { border-color:var(--sea); background:var(--sea-pale); }
.cascade-input { flex:1; border:none; outline:none; background:transparent; font-size:14px; font-family:'DM Sans','DM Sans Fallback',sans-serif; color:var(--text); padding:10px 0; min-width:0; }
.cascade-input::placeholder { color:var(--text-muted); }
.cascade-field.filled .cascade-input { color:var(--sea); font-weight:500; }
.autocomplete-dot { position:absolute; left:12px; top:50%; transform:translateY(-50%); width:10px; height:10px; border-radius:50%; border:2px solid var(--sea); z-index:1; pointer-events:none; }
.autocomplete-dot.end { background:var(--accent); border-color:var(--accent); }
.autocomplete-clear { display:none; position:absolute; right:10px; top:50%; transform:translateY(-50%); width:18px; height:18px; border-radius:50%; background:var(--text-muted); color:white; font-size:12px; line-height:18px; text-align:center; cursor:pointer; z-index:2; user-select:none; border:none; }
.autocomplete-clear:hover { background:var(--accent); }
.autocomplete-clear.visible { display:block; }
/* A11y: hit-area 44x44 senza cambiare il layout (il pallino resta 18px) */
.autocomplete-clear::after { content:''; position:absolute; inset:-13px; border-radius:50%; }
.cascade-dropdown { position:absolute; top:calc(100% + 4px); left:0; right:0; background:white; border:1.5px solid var(--border); border-radius:8px; box-shadow:var(--shadow); z-index:1000; max-height:260px; overflow-y:auto; display:none; }
.cascade-dropdown.open { display:block; }
.cascade-section { padding:5px 14px 3px; font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:0.08em; color:var(--text-muted); }
.cascade-fermata { padding:9px 14px; cursor:pointer; font-size:13px; border-bottom:1px solid var(--border); display:flex; align-items:center; justify-content:space-between; gap:8px; transition:background 0.1s; }
.cascade-fermata:hover { background:var(--sea-pale); }
.cascade-fermata-nome { flex:1; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.cascade-prov { padding:11px 14px; cursor:pointer; font-size:14px; font-weight:600; color:var(--sea); border-bottom:1px solid var(--border); display:flex; align-items:center; justify-content:space-between; transition:background 0.1s; }
.cascade-prov:hover { background:var(--sea-pale); }
.cascade-prov-badge { font-size:11px; font-weight:400; color:var(--text-muted); }
.cascade-back { padding:8px 14px; font-size:12px; color:var(--sea-light); cursor:pointer; border-bottom:1px solid var(--border); display:flex; align-items:center; gap:6px; background:var(--sea-pale); font-weight:500; }
.cascade-back:hover { background:var(--sea-pale); filter:brightness(0.95); }
.cascade-comune { padding:10px 14px 10px 20px; cursor:pointer; font-size:13px; border-bottom:1px solid var(--border); transition:background 0.1s; display:flex; align-items:center; justify-content:space-between; gap:8px; }
.cascade-comune:hover { background:var(--sea-pale); }
.cascade-comune:last-child { border-bottom:none; }
.cascade-comune-right { display:flex; align-items:center; gap:6px; flex-shrink:0; }
.cascade-badge { font-size:10px; font-weight:600; padding:2px 7px; border-radius:10px; white-space:nowrap; }
.cascade-badge-diretto { background:var(--green-light); color:var(--green); }
.cascade-badge-cambio { background:var(--sand); color:var(--text-muted); }
/* UX-C (8/09): il dubbio sulla POSIZIONE accanto alla voce-fermata del form.
   Stessa coppia ambra dell'avviso in timeline (.vd-incerta) e del popup
   (.coord-unknown): tre superfici, un colore solo. Non si restringe (il testo
   è già l'etichetta corta); a restringersi è il nome, che su mobile va a capo
   (.cascade-fermata-nome white-space:normal). */
.cascade-badge-incerta { background:#fef3c7; color:#92400e; flex-shrink:0; }
.cascade-escape { padding:9px 14px; font-size:12px; color:var(--sea-light); cursor:pointer; border-top:1px solid var(--border); text-align:center; background:var(--sea-pale); }
.cascade-escape:hover { filter:brightness(0.95); }
/* UX-C: affinamento fermata — link sotto il campo compilato, riga discreta
   sulla raggiungibilità per comune, fermata selezionata nella lista */
.affina-link { display:block; border:none; background:none; color:var(--sea-light); font-size:12px;
  font-weight:600; cursor:pointer; padding:4px 2px 0; margin:2px 0 0 12px; font-family:inherit; text-align:left; }
.affina-link:hover, .affina-link:focus-visible { color:var(--sea); text-decoration:underline; }
.affina-link[hidden] { display:none; }
.cascade-nota { padding:7px 14px; font-size:11px; color:var(--text-muted); border-top:1px solid var(--border); cursor:default; }
/* P32: l'elenco dei collegamenti è provvisorio (la frase la manda il server). */
.cascade-nota-provvisoria { color:var(--text); }
.cascade-fermata.sel { background:var(--sea-pale); font-weight:600; }
.search-connector { width:2px; height:8px; background:var(--sea); opacity:0.3; margin:0 0 8px 16px; }
.ora-row { margin-bottom:10px; min-width:0; overflow:hidden; }
.ora-label { font-size:11px; font-weight:600; text-transform:uppercase; letter-spacing:0.06em; color:var(--text-muted); margin-bottom:6px; }
.ora-chips-wrap { position:relative; min-width:0; flex:1; }
.ora-chips-wrap::before, .ora-chips-wrap::after {
  content:''; position:absolute; top:0; bottom:6px; width:24px; pointer-events:none;
  opacity:0; transition:opacity 0.15s;
}
.ora-chips-wrap::before { left:0; background:linear-gradient(to right, var(--sea-pale), transparent); }
.ora-chips-wrap::after { right:0; background:linear-gradient(to left, var(--sea-pale), transparent); }
.ora-chips-wrap.can-scroll-left::before { opacity:1; }
.ora-chips-wrap.can-scroll-right::after { opacity:1; }
.ora-chips { display:flex; gap:5px; overflow-x:auto; padding-bottom:6px; padding-right:16px; scrollbar-width:none; -ms-overflow-style:none; cursor:grab; }
.ora-chips::-webkit-scrollbar { display:none; }
.ora-chips.dragging { cursor:grabbing; }
.ora-chip { flex-shrink:0; padding:6px 12px; border-radius:20px; font-size:13px; font-family:'DM Sans','DM Sans Fallback',sans-serif; font-weight:500; border:1.5px solid var(--border-input); cursor:pointer; background:white; color:var(--text-muted); transition:all 0.15s; user-select:none; }
.ora-chip:hover { border-color:var(--sea-light); color:var(--sea); }
.ora-chip.active { background:var(--sea); color:white; border-color:var(--sea); }
.diretti-row { margin-bottom:10px; }
.diretti-toggle { display:flex; align-items:center; gap:8px; font-size:13px; color:var(--text-muted); cursor:pointer; user-select:none; }
.diretti-toggle input { width:16px; height:16px; accent-color:var(--sea); cursor:pointer; }
.btn-search { width:100%; padding:11px; background:var(--sea); color:white; border:none; border-radius:8px; font-family:'DM Sans','DM Sans Fallback',sans-serif; font-size:14px; font-weight:600; cursor:pointer; transition:background 0.2s; display:flex; align-items:center; justify-content:center; gap:8px; }
.btn-search:hover { background:var(--sea-light); }
.btn-search:disabled { background:var(--text-muted); cursor:not-allowed; }

/* ── Form "Quando" v2: data + preset + toggle ──────────────────────── */
/* UX2 blocco A: rimosso il time picker "Parti dopo le", i 5 preset sotto
   (.ora-presets) sono l'unico controllo orario — la data ha tutta la riga. */
.when-row { display:grid; grid-template-columns:1fr; gap:8px; margin-bottom:10px; }
.when-field { display:flex; flex-direction:column; gap:6px; min-width:0; position:relative; }
/* GATE B · 1a: «Quando parti?» nello stesso registro delle altre due
   domande (era «QUANDO» in maiuscoletto, un registro diverso). */
.when-label { font-family:'Fredoka','Fredoka Fallback',sans-serif; font-size:17px; font-weight:600; color:var(--sea); }
/* UX3 Blocco B: striscia orizzontale di 14 chip-giorno («Oggi · Domani ·
   gio 28 …») + chip «Altra data» col picker nativo come fallback. Nessun
   giorno «spento» (coerenza col Blocco A: si può sempre cercare). */
/* P26: il padding in più (col margine negativo uguale: la striscia non si
   sposta) è lo spazio dell'anello di focus, 4 px fuori dal chip, che
   `overflow-x:auto` altrimenti taglierebbe. */
.when-days-wrap { overflow-x:auto; -webkit-overflow-scrolling:touch; scrollbar-width:thin; margin:-4px -6px -1px; padding:4px 6px 1px; }
.when-days { display:flex; gap:5px; padding-bottom:3px; }
.day-chip { flex-shrink:0; padding:8px 13px; border-radius:20px; font-size:13px; font-weight:500; border:1.5px solid var(--border-input); cursor:pointer; background:white; color:var(--text-muted); font-family:'DM Sans','DM Sans Fallback',sans-serif; transition:all 0.15s; min-height:38px; white-space:nowrap; }
.day-chip:hover, .day-chip:focus-visible { border-color:var(--sea-light); color:var(--sea); }
.day-chip.active { background:var(--sea); color:white; border-color:var(--sea); }
.day-chip-altra-wrap { position:relative; flex-shrink:0; display:flex; }
/* P26: il Tab va all'input trasparente (opacity:0 spegne anche il suo
   anello), e l'anello lo porta il chip «Altra data» che gli sta sotto. */
.day-chip-altra-wrap:has(.when-native-overlay:focus-visible) .day-chip-altra { outline:2px solid var(--sea-light); outline-offset:2px; }
/* Overlay nativo: l'input date sta SOPRA il chip «Altra data», trasparente ma
   tappabile. Cosi' un tap apre il picker nativo su TUTTI i dispositivi
   (iOS/Android/desktop) senza dipendere solo da showPicker(), che su diversi
   mobile non apriva nulla (bug "tasti Quando / Parti dopo le"). */
.when-native-overlay {
  position:absolute; inset:0; width:100%; height:100%;
  margin:0; padding:0; border:0; background:transparent;
  opacity:0; cursor:pointer; z-index:2;
  font-size:16px; /* evita lo zoom automatico iOS al focus */
  -webkit-appearance:none; appearance:none;
}

.ora-presets { display:flex; flex-wrap:wrap; gap:5px; margin-bottom:12px; }
.ora-preset { padding:7px 13px; border-radius:20px; font-size:13px; font-weight:500; border:1.5px solid var(--border-input); cursor:pointer; background:white; color:var(--text-muted); font-family:'DM Sans','DM Sans Fallback',sans-serif; transition:all 0.15s; min-height:34px; }
.ora-preset:hover, .ora-preset:focus-visible { border-color:var(--sea-light); color:var(--sea); }
.ora-preset.active { background:var(--sea); color:white; border-color:var(--sea); }

.diretti-switch { display:flex; align-items:center; justify-content:space-between; gap:10px; padding:10px 2px; cursor:pointer; user-select:none; font-size:14px; color:var(--text); font-weight:500; }
.diretti-switch input { position:absolute; opacity:0; pointer-events:none; width:0; height:0; }
.switch-track { width:42px; height:24px; background:rgba(10,79,110,0.15); border:1.5px solid var(--border-input); box-sizing:border-box; border-radius:14px; position:relative; transition:background 0.2s; flex-shrink:0; display:block; }
.switch-thumb { position:absolute; top:2px; left:2px; width:20px; height:20px; background:white; border-radius:50%; box-shadow:0 1px 3px rgba(0,0,0,0.2); transition:transform 0.2s; }
.diretti-switch input:checked ~ .switch-track { background:var(--sea); }
.diretti-switch input:checked ~ .switch-track .switch-thumb { transform:translateX(18px); }
.diretti-switch input:focus-visible ~ .switch-track { outline:2px solid var(--sea-light); outline-offset:2px; }

.form-error { color:#9a3e12; font-size:13px; padding:8px 12px; background:var(--accent-light); border-radius:8px; margin-bottom:10px; border-left:3px solid var(--accent); }
.cascade-field.error { border-color:var(--accent); background:var(--accent-light); }
.cascade-field.error .cascade-input { color:#9a3e12; }
.lines-panel { border-bottom:1px solid var(--border); }
.lines-toggle { display:flex; align-items:center; justify-content:space-between; cursor:pointer; font-size:11px; font-weight:600; text-transform:uppercase; letter-spacing:0.07em; color:var(--text-muted); padding:12px 16px; user-select:none; transition:background 0.15s; }
.lines-toggle:hover { background:var(--sea-pale); }
.lines-toggle svg { transition:transform 0.2s; flex-shrink:0; }
.lines-grid { display:none; flex-wrap:wrap; gap:5px; padding:0 16px 12px; }
.lines-grid.open { display:flex; }
.line-chip { display:flex; align-items:center; gap:5px; padding:3px 9px; border-radius:20px; font-size:11px; font-weight:500; cursor:pointer; border:1.5px solid transparent; transition:all 0.15s; }
.line-chip:hover { transform:translateY(-1px); }
.line-chip.active { border-color:currentColor; }
.results-area { flex:1; overflow-y:auto; overflow-x:hidden; padding:14px 16px; }
.results-header { display:flex; align-items:center; justify-content:space-between; margin-bottom:10px; }
.results-title { margin:0; font-size:12px; font-weight:600; text-transform:uppercase; letter-spacing:0.07em; color:var(--text-muted); }
.results-count { font-size:11px; color:var(--text-muted); background:var(--sea-pale); padding:2px 8px; border-radius:10px; }
.route-card { background:var(--white); border:1.5px solid var(--border); border-radius:var(--radius); padding:14px 16px; margin-bottom:8px; cursor:pointer; transition:all 0.2s; position:relative; overflow:visible; }
.route-card::before { content:''; position:absolute; left:0; top:0; bottom:0; width:4px; background:var(--sea); border-radius:var(--radius) 0 0 var(--radius); }
.route-card.diretto::before { background:var(--card-accent, var(--green)); }
.route-card.con_cambio::before { background:var(--accent); }
.route-card:hover { border-color:var(--sea-light); transform:translateX(2px); box-shadow:var(--shadow); }
@media (pointer:coarse) { .route-card:hover { transform:none; } }
.route-card.active { border-color:var(--sea); background:var(--sea-pale); }
.route-header { display:flex; justify-content:space-between; align-items:center; gap:8px; margin-bottom:10px; min-height:22px; }
.route-tag { display:inline-flex; align-items:center; font-size:12px; font-weight:600; padding:3px 10px; border-radius:20px; white-space:nowrap; }
.route-tag.diretto { background:var(--green-light); color:var(--green); }
.route-tag.cambio { background:var(--accent-light); color:#9a3e12; }
.route-tag.oggi { background:#dcfce7; color:#15803d; }
/* PR 3: la pastiglia data. Stesso meccanismo di .oggi, colori del cartello:
   compare su OGNI scheda quando la lista si riferisce a un giorno diverso da
   quello cercato. Il cartello in cima si perde scorrendo, questa no. */
.route-tag.data { background:var(--sea-pale); color:var(--sea); border:1px solid var(--sea-light); }
.route-stimato { display:inline-flex; align-items:center; font-size:12px; font-weight:600; padding:3px 10px; border-radius:20px; white-space:nowrap; background:#fbe8d3; color:#92400e; }
/* MOSSA 1 — la riga di certezza della corsa. Sostituisce la pill «Orario non
   certo»: quella diceva «questo numero l'abbiamo calcolato noi» (caso ora
   impossibile), questa dice quanto l'orario del VETTORE è stato confrontato.
   Discreta di proposito: è un chiarimento, non un allarme — compare solo
   quando lo stato non è `verificata`. */
.route-certezza { margin:6px 0 0; font-size:12px; line-height:1.45; color:#92400e; background:#fdf5ec;
  border-left:3px solid #e0a85a; border-radius:4px; padding:6px 10px; }
.route-certezza a { color:#92400e; text-decoration:underline; white-space:nowrap; }
/* P26: lo stesso «↗» di `.meta-link-orario`, ma in riga col testo: il padding
   verticale di un elemento inline non sposta le righe, e porta l'area di
   tocco a ~25 px (15,5 + 2×5). */
.route-certezza a { padding:5px 0; }
.route-certezza-inline { font-size:11px; color:#92400e; }
.route-header-right { display:flex; align-items:center; justify-content:flex-end; gap:8px; flex-wrap:wrap; }
.route-times { display:flex; align-items:center; gap:12px; margin-bottom:10px; }
.time { font-family:'DM Serif Display','DM Serif Display Fallback',serif; font-size:28px; font-weight:500; color:var(--text); line-height:1; letter-spacing:-0.01em; }
.time-arrow { flex:1; position:relative; display:flex; align-items:center; justify-content:center; min-height:22px; }
.time-arrow::before { content:''; position:absolute; left:0; right:0; top:50%; height:1px; background:var(--border); }
.time-duration-pill { position:relative; background:white; border:1px solid var(--border); border-radius:20px; padding:2px 10px; font-size:11px; color:var(--text-muted); white-space:nowrap; z-index:1; }
/* PR A2 (GATE 2 forma A): il .route-tratto è la TIMELINE CORTA — stesse
   righe .vd-stop del dettaglio (grafia unica), salita·cambi·discesa. A scheda
   aperta (.active) si nasconde: al suo posto c'è l'itinerario completo. */
.route-tratto { font-size:13px; color:var(--text); margin-bottom:8px; line-height:1.45; }
.route-card.active .route-tratto { display:none; }
.tc { position:relative; }
.tc::before { content:''; position:absolute; left:63px; top:14px; bottom:14px; width:2px; background:var(--card-accent, var(--sea)); opacity:.3; }
.tc-dot { background:var(--card-accent, var(--sea)); box-shadow:0 0 0 1.5px var(--card-accent, var(--sea)); }
.vd-badge-cambio { background:#fde6da; color:#b8431a; }
.route-opts { display:inline-block; margin-left:4px; padding:1px 6px; border-radius:10px; background:var(--border); color:var(--text); font-size:11px; font-weight:600; vertical-align:middle; }
.route-opts-list { display:block; font-size:11px; color:var(--text-muted); margin-top:1px; }
/* ── Selettore fermata con più opzioni (dropdown inline) ── */
.opt-sel-wrap { position:relative; display:inline-block; vertical-align:middle; max-width:100%; }
.opt-trigger { display:inline-flex; align-items:center; gap:3px; background:none; border:1px solid var(--border); border-radius:12px; padding:1px 7px; font:inherit; font-size:inherit; cursor:pointer; color:var(--text); transition:border-color .15s,background .15s; white-space:nowrap; line-height:1.5; max-width:100%; overflow:hidden; }
.opt-trigger:hover,.opt-trigger:focus-visible { border-color:var(--sea); background:var(--sea-pale); }
.opt-nome { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.opt-trigger .opt-ora { flex:0 0 auto; font-size:11px; color:var(--text-muted); margin-left:2px; }
.opt-trigger svg { flex:0 0 auto; }
.opt-comune { font-weight:600; }
/* «non è il paese»: la fermata sta nel comune cercato ma fuori dal centro
   abitato. Discreta come .route-stimato — è un chiarimento, non un allarme:
   la corsa è confermata, cambia solo dove ti lascia. */
.opt-frazione { display:inline-block; margin-left:6px; padding:1px 6px; border-radius:6px; background:var(--sea-pale); color:var(--sea); font-size:11px; font-weight:600; white-space:nowrap; }
.opt-dropdown { display:none; position:absolute; z-index:910; top:calc(100% + 4px); left:0; min-width:175px; max-width:min(280px, calc(100vw - 32px)); background:white; border:1px solid var(--border); border-radius:10px; box-shadow:0 4px 20px rgba(0,0,0,0.13); overflow-y:auto; max-height:min(260px,45vh); }
.opt-dropdown.open { display:block; }
.opt-dropdown.up { top:auto; bottom:calc(100% + 4px); }
.opt-dropdown.left { left:auto; right:0; }
.opt-item { display:block; width:100%; text-align:left; padding:9px 14px; background:none; border:none; border-bottom:1px solid var(--border); font:inherit; font-size:13px; color:var(--text); cursor:pointer; white-space:normal; word-break:break-word; }
.opt-item:last-child { border-bottom:none; }
.opt-item:hover,.opt-item:focus-visible { background:var(--sea-pale); }
.opt-item.active { color:var(--sea); font-weight:600; }
.route-meta { display:flex; flex-direction:column; gap:4px; font-size:13px; color:var(--text-muted); }
/* A11y (Lighthouse color-contrast): opacity sopra un colore gia' "muted"
   dimezzava ulteriormente il contrasto reale (~2.15:1 su bianco, sotto il
   minimo 4.5:1 AA). --text-muted da solo e' gia' leggibile (~6:1), l'opacity
   era superflua e dannosa. */
.route-meta .meta-sep { color:var(--text-muted); }
.route-meta .meta-prezzo { color:var(--text); font-weight:500; }
.route-meta .meta-verifica { background:none; border:none; padding:0; cursor:pointer; color:#92400e; font:inherit; display:inline-flex; align-items:center; gap:4px; }
.route-meta .meta-verifica:hover { text-decoration:underline; }
.route-actions { display:flex; flex-wrap:wrap; gap:6px; margin-top:10px; }
.route-actions:empty { display:none; }
.cambio-info { margin-top:10px; padding:12px 14px; background:var(--sea-pale); border:1px solid rgba(10,79,110,0.15); border-radius:10px; font-size:13px; color:var(--text); display:none; }
.route-card.active .cambio-info { display:block; }
.cambio-info + .cambio-info { margin-top:8px; }

.cambio-header { display:flex; align-items:center; gap:10px; margin-bottom:10px; }
.cambio-header-icon { width:32px; height:32px; border-radius:50%; background:#0a4f6e; display:flex; align-items:center; justify-content:center; flex-shrink:0; box-shadow:0 1px 4px rgba(10,79,110,0.3); }
.cambio-header-title { font-size:14px; font-weight:500; color:var(--sea); line-height:1.2; }

.cambio-strip { display:flex; align-items:stretch; gap:6px; margin-bottom:10px; }
.cambio-pill { flex:1; min-width:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:2px; padding:8px 6px; border-radius:8px; font-family:'DM Sans','DM Sans Fallback',sans-serif; }
.cambio-pill .lbl { font-size:10px; font-weight:600; text-transform:uppercase; letter-spacing:0.05em; opacity:0.85; }
.cambio-pill .val { font-size:14px; font-weight:600; line-height:1; }
.cambio-pill svg { opacity:0.9; flex-shrink:0; }

.cambio-pill-scendi { background:#fee2e2; color:#b91c1c; }
.cambio-pill-sali   { background:#dcfce7; color:#15803d; }
.cambio-pill-attesa { background:#fef3c7; color:#92400e; }
.cambio-pill-attesa-long { background:#fef3c7; color:#b91c1c; border:1.5px solid #dc2626; }

.cambio-walk-info { display:flex; align-items:center; gap:8px; font-size:12px; color:var(--text-muted); padding:6px 8px; background:rgba(245,158,11,0.08); border-left:3px solid #f59e0b; border-radius:0 6px 6px 0; margin-bottom:10px; line-height:1.4; }
.cambio-walk-info svg { flex-shrink:0; color:#92400e; }
.cambio-walk-info strong { color:var(--text); }
.cambio-altri { display:flex; align-items:flex-start; gap:7px; font-size:12px; color:var(--text-muted); padding:7px 9px; background:var(--sea-pale); border-radius:7px; margin-bottom:10px; line-height:1.45; }
.cambio-altri svg { flex-shrink:0; margin-top:1px; color:var(--sea); }
.cambio-altri strong { color:var(--text); font-weight:600; }

.cambio-next-toggle { display:flex; align-items:center; justify-content:space-between; gap:8px; width:100%; padding:7px 10px; background:none; border:1px solid rgba(10,79,110,0.15); border-radius:6px; font-family:inherit; font-size:12px; color:var(--text-muted); cursor:pointer; opacity:0.85; }
.cambio-next-toggle:hover, .cambio-next-toggle:focus-visible { background:white; color:var(--sea); opacity:1; }
.cambio-next-toggle svg { transition:transform 0.2s; flex-shrink:0; }
.cambio-next-toggle.open svg { transform:rotate(180deg); }
.cambio-next-list { display:none; margin-top:8px; padding:8px 10px; background:white; border-radius:6px; font-size:11px; color:var(--text-muted); }
.cambio-next-list.open { display:block; }

/* ── Dettaglio viaggio (timeline a gambe) ──
   PR A2 (forma A): un livello solo — l'itinerario completo si apre col tocco
   sulla scheda (l'apertura È la selezione .active), il toggle «Dettaglio
   percorso» non esiste più. */
.viaggio-dettaglio { display:none; margin-top:10px; padding:12px 10px; background:var(--sea-pale); border:1px solid rgba(10,79,110,0.15); border-radius:10px; }
.route-card.active .viaggio-dettaglio { display:block; }
.vd-leg-head { display:flex; align-items:center; gap:8px; margin-bottom:4px; }
.vd-leg-head:not(:first-child) { margin-top:12px; }
.vd-line-badge { font-size:11px; font-weight:600; padding:2px 9px; border-radius:20px; font-family:'DM Sans','DM Sans Fallback',sans-serif; white-space:nowrap; flex-shrink:0; }
.vd-leg-sub { font-size:11px; color:var(--text-muted); min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.vd-leg-sub.vd-leg-solo { font-size:12px; font-weight:600; color:var(--text); }
/* SAT_QUADRO_2B-1: nome della corsa nel quadro del vettore e nota di legenda. */
.vd-leg-corsa { font-size:11px; font-weight:600; color:var(--text-muted); white-space:nowrap; }
.vd-leg-nota { font-size:11px; color:var(--text-muted); margin:-2px 0 6px; }
/* PR A2 — GRAFIA UNICA della riga fermata (timeline corta E dettaglio):
   orario in colonna fissa a sinistra (tabulare, colore pieno — era il dato
   più importante ed era il più sbiadito), nome 15–16px, comune SOTTO il nome
   (a 375px la terza colonna non entra: il nome lungo andava a capo col
   comune schiacciato a destra). */
.vd-line { position:relative; }
.vd-line::before { content:''; position:absolute; left:63px; top:14px; bottom:14px; width:2px; background:var(--leg,#0a4f6e); opacity:0.35; }
.vd-stop { display:grid; grid-template-columns:48px 16px 1fr; column-gap:8px; align-items:start; padding:4px 0; }
.vd-stop[role=button] { cursor:pointer; border-radius:7px; transition:background 0.12s; }
.vd-stop[role=button]:hover { background:var(--sea-pale); }
.vd-dotcol { grid-column:2; display:flex; justify-content:center; padding-top:5px; }
.vd-dot { width:7px; height:7px; border-radius:50%; opacity:0.6; }
.vd-dot-end { width:12px; height:12px; border:2px solid var(--sea-pale); opacity:1; }
.vd-name { grid-column:3; min-width:0; font-size:15.5px; color:var(--text); line-height:1.3; word-break:break-word; }
.vd-stop-end .vd-name { font-weight:700; }
.vd-comune { display:block; font-size:12.5px; font-weight:400; color:var(--text-muted); margin-top:1px; white-space:normal; }
.vd-time { grid-column:1; grid-row:1; font-size:15px; font-weight:600; color:var(--text); font-variant-numeric:tabular-nums; font-family:'DM Sans','DM Sans Fallback',sans-serif; padding-top:1px; }
.vd-stop-opt .vd-name { font-weight:700; }
.vd-stop-salta .vd-name, .vd-stop-salta .vd-comune { color:var(--text-muted); opacity:.65; }
/* riga inline UX5: il dubbio sulla POSIZIONE si dichiara sotto la fermata */
.vd-incerta { display:block; font-size:11.5px; color:#92400e; margin-top:1px; }
.vd-incerta-link { font-weight:700; text-decoration:underline; cursor:pointer; }
.vd-nonferma { font-size:11px; font-style:italic; color:var(--text-muted); opacity:.8; }
/* LOTTO CELLA ONESTA (2026-09-02): il vettore NON ha pubblicato l'orario di
   questa cella. Non è «non ferma» — il pallino resta vuoto come lì, ma il testo
   dichiara il dubbio e offre il quadro ufficiale. La riga va a capo perché la
   frase è lunga: comprimerla in una sigla la renderebbe illeggibile proprio
   nel caso in cui serve. */
/* celle senza orario («non ferma», «orario non pubblicato…», «non
   riportato…»): la frase — invariata nelle parole — si ricolloca sotto il
   nome, dove c'è spazio per leggerla; la colonna orario resta vuota. */
.vd-stop-salta .vd-time { grid-column:3; grid-row:2; font-weight:400; font-size:12px; padding-top:0; }
/* «orario non pubblicato»: il dubbio è DICHIARATO, non un «non ferma» — la
   riga non si sbiadisce come le saltate (il bus lì probabilmente passa). */
.vd-stop-nonpub .vd-name, .vd-stop-nonpub .vd-comune { opacity:1; }
.vd-nonpub { font-size:11px; font-style:italic; color:var(--text-muted); opacity:.9; }
.vd-nonpub a { color:var(--sea); font-weight:600; font-style:normal; white-space:nowrap; }
.vd-opt-badge { display:inline-block; margin-left:6px; padding:0 6px; border-radius:9px; font-size:10px; font-weight:600; vertical-align:middle; }
.vd-opt-discesa { background:#fde6da; color:#b8431a; }
.vd-opt-salita { background:#dcefe2; color:#1d6b3f; }
.vd-stop-end .vd-time { color:var(--text); }
/* FASE 6c: percorso scheletro (2 cambi / AirLink) — nota onesta in testa */
.vd-indicativo { font-size:12px; font-style:italic; color:var(--text-muted); padding:6px 10px; background:var(--sea-pale); border-radius:8px; margin-bottom:6px; }
/* FASE 6b: gamba senza orari pubblicati — dicitura al posto della lista con ~ */
.vd-nondett { display:grid; grid-template-columns:48px 16px 1fr; column-gap:8px; padding:2px 0; }
.vd-nondett .vd-dotcol { grid-column:2; }
.vd-nondett .vd-nondett-txt { grid-column:3; }
.vd-nondett-txt { flex:1; font-size:12px; font-style:italic; color:var(--text-muted); }
.vd-nondett-txt a { color:var(--sea); font-weight:600; font-style:normal; }
.vd-more { display:grid; grid-template-columns:48px 16px 1fr; column-gap:8px; align-items:center; padding:2px 0; }
.vd-more .vd-dotcol { grid-column:2; }
.vd-more .vd-more-btn, .vd-more .vd-altri-btn { grid-column:3; }
.vd-more-btn { text-align:left; background:none; border:none; font-family:inherit; font-size:12px; color:var(--leg,var(--sea)); font-weight:500; cursor:pointer; display:flex; align-items:center; gap:5px; padding:0; }
/* P26 (WCAG 2.5.8): bersaglio alto 24 px, ma la riga della timeline resta
   quella di prima: il margine negativo restituisce la differenza fra 24 px e
   l'altezza della riga di testo (`1lh`; 15,5 px a 12 px, il ripiego). */
.vd-more-btn, .vd-altri-btn { min-height:24px; margin:-4.25px 0; margin:calc((1lh - 24px) / 2) 0; }
.vd-more-btn:hover, .vd-more-btn:focus-visible { text-decoration:underline; }
.vd-more-btn svg { transition:transform 0.2s; flex-shrink:0; }
.vd-more-btn.open svg { transform:rotate(180deg); }
.vd-mid { display:none; }
.vd-mid.open { display:block; }
/* Sub-gruppo collassabile "altri punti di salita/discesa" nel dettaglio */
.vd-altri-btn { text-align:left; background:none; border:none; font-family:inherit; font-size:12px; color:var(--text-muted); font-weight:500; cursor:pointer; display:flex; align-items:center; gap:5px; padding:0; }
.vd-altri-btn:hover,.vd-altri-btn:focus-visible { text-decoration:underline; }
.vd-altri-btn svg { transition:transform .2s; flex-shrink:0; }
.vd-altri-btn.open svg { transform:rotate(180deg); }
.vd-altri-mid { display:none; }
.vd-altri-mid.open { display:block; }
/* fascia cambio compatta (Opzione 1: scendi · attesa · sali in linea) */
.vd-cambio { display:flex; align-items:flex-start; gap:8px; background:#fef3c7; border:1px solid #f0b429; border-radius:8px; padding:8px 10px; margin:8px 0 4px; }
.vd-cambio.long { border-color:#dc2626; }
.vd-cambio-ico { color:#92400e; flex-shrink:0; display:flex; margin-top:1px; }
.vd-cambio-body { flex:1; min-width:0; }
.vd-cambio-title { font-size:13px; font-weight:500; color:#633806; }
.vd-cambio-comune { font-weight:400; opacity:0.85; }
.vd-cambio-times { font-size:12px; color:#854f0b; margin-top:1px; }
.vd-cambio-times .sc { color:#b91c1c; font-weight:500; }
.vd-cambio-times .sa { color:#15803d; font-weight:500; }
.vd-cambio-times .at.long { color:#b91c1c; font-weight:600; }
.vd-cambio-walk { font-size:11px; color:#854f0b; margin-top:5px; line-height:1.4; }
.vd-cambio-walk strong { color:var(--text); }
.viaggio-dettaglio .cambio-next-toggle { margin-bottom:8px; }
.modal-stop-num { font-size:11px; font-weight:700; color:var(--text-muted); min-width:22px; text-align:center; flex-shrink:0; }
.modal-stop.entry .modal-stop-num { color:var(--sea); }
.modal-stop.exit  .modal-stop-num { color:var(--green); }
/* GATE B · 1a: il tasto ⇅ vive sulla riga dell'etichetta dell'arrivo — la
   sua riga da 36px (.search-connector) non esiste piu'. */
.swap-btn { display:flex; align-items:center; justify-content:center; width:34px; height:34px; border-radius:50%; border:1.5px solid var(--border); background:white; cursor:pointer; color:var(--sea); transition:all 0.15s; box-shadow:var(--shadow); flex-shrink:0; }
.swap-btn:hover { background:var(--sea-pale); border-color:var(--sea); }
.andata-ritorno-tabs { display:none; gap:0; border-bottom:2px solid var(--border); background:white; }
.andata-ritorno-tabs.visible { display:flex; }
.ar-tab { flex:1; padding:10px 0; border:none; background:transparent; font-family:'DM Sans','DM Sans Fallback',sans-serif; font-size:13px; font-weight:600; color:var(--text-muted); cursor:pointer; border-bottom:2px solid transparent; margin-bottom:-2px; transition:all 0.15s; }
.ar-tab.active { color:var(--sea); border-bottom-color:var(--sea); }
.ritorno-ora-row { padding:10px 16px; background:var(--sea-pale); border-bottom:1px solid var(--border); display:none; gap:8px; align-items:center; flex-wrap:wrap; }
.ritorno-ora-row.visible { display:flex; }
.no-results { text-align:center; padding:40px 20px; color:var(--text-muted); }
.no-results-icon { font-size:32px; margin-bottom:12px; }
.no-results h3 { font-size:15px; margin-bottom:4px; color:var(--text); }
.no-results p { font-size:13px; }

/* No-results v2: azioni contestuali */
.no-results-v2 { padding:28px 14px 24px; text-align:center; }
.no-results-icon-v2 {
  display:inline-flex; align-items:center; justify-content:center;
  width:52px; height:52px; border-radius:50%;
  background:var(--sea-pale); color:var(--sea);
  margin-bottom:14px;
}
.no-results-v2 h3 { font-size:16px; color:var(--text); margin-bottom:4px; font-weight:600; }
.no-results-v2 p { font-size:13px; color:var(--text-muted); margin-bottom:16px; }
.no-results-actions { display:flex; flex-direction:column; gap:8px; max-width:300px; margin:0 auto; }
.no-results-btn {
  display:flex; align-items:center; gap:10px;
  padding:11px 14px; border:1.5px solid var(--border); border-radius:8px;
  background:white; color:var(--sea);
  font:500 14px 'DM Sans','DM Sans Fallback',sans-serif;
  cursor:pointer; text-align:left; min-height:44px; width:100%;
}
.no-results-btn:hover { background:var(--sea-pale); border-color:var(--sea); }
.no-results-btn svg { flex-shrink:0; opacity:0.7; }
.no-results-btn .lbl { flex:1; }
/* PR 3: "Segnala una mancanza" e' un link vero (naviga a /segnala/), non un
   bottone: stessa veste, ma va tolta la sottolineatura del browser. */
a.no-results-btn { text-decoration:none; }

/* #7: tasti "Corse precedenti / successive" */
.load-more-btn {
  display:flex; align-items:center; justify-content:center; gap:8px;
  width:100%; margin:8px 0; padding:11px 14px;
  border:1.5px dashed var(--border); border-radius:12px;
  background:white; color:var(--sea); font-family:'DM Sans','DM Sans Fallback',sans-serif;
  font-size:13px; font-weight:600; cursor:pointer; transition:all 0.15s;
}
.load-more-btn:hover { background:var(--sea-pale); border-color:var(--sea); }
.load-more-btn:disabled { opacity:0.55; cursor:default; color:var(--text-muted); border-style:solid; }
.load-more-btn svg { flex-shrink:0; opacity:0.8; }
.load-more-btn.loading { opacity:0.7; cursor:progress; }

/* PR 3 «mai senza risposta» — il cartello sopra la lista.
   Stessa impalcatura di .alt-banner, ma nei colori del mare invece che del
   verde: e' INFORMATIVO, non un allarme e nemmeno una conferma. Nessuna icona
   di errore, nessun rosso: il viaggio sotto e' vero, sta solo in un altro
   giorno o con un vincolo in meno. */
.slip-banner {
  display:flex; align-items:flex-start; gap:10px; flex-wrap:wrap;
  background:var(--sea-pale); border:1.5px solid var(--sea-light);
  border-radius:8px; padding:11px 14px; margin-bottom:12px;
  font-size:13px; color:var(--sea); line-height:1.45;
}
.slip-banner > svg { flex-shrink:0; margin-top:2px; opacity:0.85; }
/* min-width:0 + il testo che va a capo: un nome di fermata lungo non deve
   allargare il cartello e far scorrere l'area risultati in orizzontale. */
.slip-testo { flex:1 1 200px; min-width:0; overflow-wrap:anywhere; }
.slip-azioni { display:flex; flex-wrap:wrap; gap:8px; width:100%; }
.slip-azione {
  padding:7px 12px; border:1.5px solid var(--sea); border-radius:20px;
  background:var(--white); color:var(--sea);
  font:600 12.5px 'DM Sans','DM Sans Fallback',sans-serif;
  cursor:pointer; min-height:34px; white-space:nowrap;
}
.slip-azione:hover { background:var(--sea); color:var(--white); }

/* UX-C: la dichiarazione della fermata scelta sopra la lista risultati */
.ricerca-fermata-row {
  display:flex; align-items:center; gap:6px; flex-wrap:wrap;
  font-size:12.5px; color:var(--text-muted); line-height:1.4;
  padding:2px 2px 8px; overflow-wrap:anywhere;
}
.ricerca-fermata-row strong { color:var(--text); }
.ricerca-fermata-row .slip-azione { min-height:30px; padding:5px 10px; white-space:normal; }

/* Banner alternative (no emoji) */
.alt-banner {
  display:flex; align-items:flex-start; gap:10px;
  background:var(--green-light); border:1.5px solid var(--green);
  border-radius:8px; padding:10px 14px; margin-bottom:10px;
  font-size:13px; color:var(--green); line-height:1.45;
}
.alt-banner svg { flex-shrink:0; margin-top:2px; opacity:0.85; }
.alt-banner a { color:var(--green); text-decoration:underline; cursor:pointer; font-weight:600; }
.alt-banner a:hover { text-decoration:none; }

/* Avviso "Orari in verifica" (FASE 5: fonte del vettore cambiata) */
.avviso-verifica {
  display:flex; align-items:flex-start; gap:10px;
  background:#fff7ed; border:1.5px solid #ea8a3a;
  border-radius:8px; padding:10px 14px; margin-bottom:10px;
  font-size:13px; color:#9a4d10; line-height:1.45;
}
.avviso-verifica svg { flex-shrink:0; margin-top:2px; opacity:0.9; }
.avviso-verifica a { color:#9a4d10; text-decoration:underline; cursor:pointer; font-weight:600; }
.avviso-verifica a:hover { text-decoration:none; }

/* Skeleton card (loading) */
.skeleton-card {
  background:var(--white); border:1.5px solid var(--border); border-radius:var(--radius);
  padding:14px 16px; margin-bottom:8px; position:relative; overflow:hidden;
}
.skeleton-card::before {
  content:''; position:absolute; left:0; top:0; bottom:0; width:4px; background:var(--border);
}
.sk-line {
  background:var(--sea-pale); border-radius:6px; height:14px; margin-bottom:8px;
  position:relative; overflow:hidden;
}
.sk-line::after {
  content:''; position:absolute; inset:0;
  background:linear-gradient(90deg, transparent, rgba(255,255,255,.7), transparent);
  animation:sk-shimmer 1.4s linear infinite;
}
@keyframes sk-shimmer { 0% { transform:translateX(-100%); } 100% { transform:translateX(100%); } }
.sk-tag { width:70px; height:20px; border-radius:20px; margin-bottom:12px; }
.sk-times { display:flex; align-items:center; gap:12px; margin-bottom:10px; }
.sk-time { width:78px; height:26px; flex:none; }
.sk-pill { flex:1; height:10px; }
.sk-tratto { width:80%; margin-bottom:8px; }
.sk-meta { width:62%; height:11px; margin-bottom:0; }
.sk-actions { display:flex; gap:6px; margin-top:10px; }
.sk-actions .sk-line { width:78px; height:28px; border-radius:20px; margin-bottom:0; }

/* ── A11y: focus-visible globale per tasti, link, card interattive ── */
button:focus { outline:none; }
a:focus { outline:none; }
button:focus-visible,
a:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible,
.route-card:focus-visible,
.modal-stop:focus-visible,
.popup-fermata-item:focus-visible {
  outline:2px solid var(--sea-light);
  outline-offset:2px;
  border-radius:4px;
}
.cascade-fermata:focus-visible,
.cascade-comune:focus-visible,
.cascade-prov:focus-visible,
.cascade-back:focus-visible {
  outline:2px solid var(--sea-light);
  outline-offset:-2px;
}
.recent-search-item:focus-visible {
  outline:2px solid var(--sea-light);
  outline-offset:0;
}
/* Voce evidenziata da tastiera nell'autocomplete (aria-activedescendant) */
.cascade-dropdown .kb-active {
  background:var(--sea-pale);
  outline:2px solid var(--sea-light);
  outline-offset:-2px;
}
/* P26: l'anello dei controlli che hanno uno stile di hover. Le loro regole
   `X:hover, X:focus-visible` chiudevano con `outline:none` e spegnevano
   l'anello qui sopra: al Tab cambiava solo un colore di bordo. Lo stesso
   anello, non uno nuovo; per classe (0,2,0), perché `:where()` perderebbe
   contro `button:focus-visible`. Dentro un contenitore che taglia
   (`overflow`), l'anello va dentro il bordo. */
.btn-elenco:focus-visible,
.affina-link:focus-visible,
.day-chip:focus-visible,
.ora-preset:focus-visible,
.opt-trigger:focus-visible,
.cambio-next-toggle:focus-visible,
.vd-more-btn:focus-visible,
.vd-altri-btn:focus-visible,
.recent-chip:focus-visible,
.recent-chip-remove:focus-visible,
.btn-mappa-scheda:focus-visible {
  outline:2px solid var(--sea-light);
  outline-offset:2px;
}
.cascade-vedi-fermate:focus-visible,
.opt-item:focus-visible {
  outline:2px solid var(--sea-light);
  outline-offset:-2px;
}
/* …e ciascuno tiene la sua forma: il `border-radius:4px` dell'anello globale
   squadrava le pastiglie al focus. Gli stessi raggi delle regole base. */
.btn-elenco:focus-visible { border-radius:14px; }
.day-chip:focus-visible, .ora-preset:focus-visible, .recent-chip:focus-visible { border-radius:20px; }
.recent-chip-remove:focus-visible { border-radius:50%; }
.opt-trigger:focus-visible { border-radius:12px; }
.btn-mappa-scheda:focus-visible { border-radius:8px; }
.cambio-next-toggle:focus-visible { border-radius:6px; }
/* Screen-reader only utility */
.sr-only { position:absolute !important; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; }
/* Skip-link (WCAG 2.4.1): invisibile finché non riceve focus da tastiera */
.skip-link { position:absolute; left:-9999px; top:0; z-index:2000; background:var(--sea); color:#fff; padding:10px 18px; border-radius:0 0 10px 0; font-weight:600; font-size:14px; text-decoration:none; }
.skip-link:focus { left:0; }
/* A11y: touch target ≥44px sui dispositivi touch (persona anziana) */
@media (pointer:coarse) {
  .ora-chip, .ora-preset, .corr-chip, .line-chip { min-height:44px; }
  .modal-close { min-width:44px; min-height:44px; }
  .swap-btn { width:40px; height:40px; }
  .opt-trigger { padding:6px 10px; min-height:36px; }
}
.map-area { flex:1; position:relative; }
#map { width:100%; height:100%; }
/* #2: skeleton LCP-friendly. Un DIV con solo background-color/testo NON e'
   un candidato LCP valido, e in pratica nemmeno un background-image CSS lo
   e' in modo affidabile (verificato via trace Chrome: mai comparso tra i
   candidati anche con file same-origin precaricato). Un <img> vero invece
   e' un candidato LCP legittimo MA solo a dimensione fissa in px: sopra
   ~350x350px (soglia verificata via trace Chrome tra 122500px² funzionante
   e 160000px² che fallisce) un <img> position:absolute smette di essere
   preso in considerazione, indipendentemente da object-fit/inset/%/vw — un
   limite pratico di questa versione di Chrome, non risolvibile lato CSS.
   L'immagine resta quindi sotto soglia (vedi .map-skeleton-img) e il resto
   dell'area e' coperto dal solo background-color di .map-skeleton (non
   LCP-eligible da solo, ma comunque un colore pieno coerente col brand
   invece di uno sfondo bianco). Rimosso al primo tileload (initMap in
   02-mappa.js). */
.map-skeleton {
  position:absolute; inset:0; z-index:400; overflow:hidden;
  background:var(--sea-pale);
  display:flex; align-items:center; justify-content:center;
}
.map-skeleton-img { position:absolute; top:0; left:0; width:340px; height:340px; }
.map-skeleton.hidden { display:none; }
.popup-comune-title { font-weight:700; font-size:14px; color:var(--sea); margin-bottom:8px; padding-bottom:6px; border-bottom:1px solid var(--border); }
.popup-fermata-item { padding:7px 10px; border-radius:7px; cursor:pointer; font-size:13px; color:var(--text); transition:background 0.15s; margin-bottom:3px; }
.popup-fermata-item:last-child { margin-bottom:0; }
.popup-fermata-item:hover { background:var(--sea-pale); color:var(--sea); }
.popup-ruolo-row { display:flex; gap:6px; margin-top:8px; }
.popup-ruolo-btn { flex:1; padding:7px 0; border:none; border-radius:8px; cursor:pointer; font-size:12px; font-weight:600; font-family:'DM Sans','DM Sans Fallback',sans-serif; transition:opacity 0.15s; }
.popup-ruolo-btn:hover { opacity:0.85; }
.btn-torna-linea { position:absolute; top:14px; left:50%; transform:translateX(-50%); z-index:601; display:none; align-items:center; gap:7px; background:white; color:var(--sea); border:none; border-radius:22px; padding:9px 15px; font-family:'DM Sans','DM Sans Fallback',sans-serif; font-size:13px; font-weight:600; cursor:pointer; box-shadow:0 2px 10px rgba(10,79,110,0.22); transition:background 0.15s; white-space:nowrap; }
.btn-torna-linea.visible { display:flex; }
.btn-torna-linea:hover { background:var(--sea-pale); }
.btn-torna-linea svg { flex-shrink:0; }
/* UX2 blocco C: la legenda e' un pannello ad apertura/chiusura (chiuso di
   default, tasto #btn-legenda), sfondo semitrasparente coerente con
   .det-overlay-label. */
.map-legend { position:absolute; bottom:24px; right:16px; background:rgba(255,255,255,0.92); border-radius:var(--radius); padding:12px 14px; box-shadow:var(--shadow); z-index:500; font-size:12px; display:none; }
.map-legend.open { display:block; }
.legend-title { font-weight:600; color:var(--sea); margin-bottom:8px; font-size:11px; text-transform:uppercase; letter-spacing:0.05em; }
.legend-item { display:flex; align-items:center; gap:8px; margin-bottom:5px; color:var(--text-muted); }
.legend-line { width:24px; height:3px; border-radius:2px; }
.legend-marker { width:16px; height:16px; border-radius:50%; display:inline-flex; align-items:center; justify-content:center; flex-shrink:0; box-shadow:0 1px 3px rgba(0,0,0,0.25); }
.legend-marker-lg { width:18px; height:18px; }
.legend-note { margin-top:6px; padding-top:6px; border-top:1px solid var(--border); font-size:10.5px; color:var(--text-muted); line-height:1.35; max-width:160px; }
.legend-dot { width:10px; height:10px; border-radius:50%; border:2px solid; }
/* Le voci "posizione non confermata / ricostruita" della legenda, e le tre
   dei nodi del viaggio, stanno in fondo a questo file col resto del sistema
   di simboli: devono restare visivamente uguali ai marker che spiegano, e
   quei marker li disegna 01b-marker.js. */

/* ── Fase 3: tasto Dettagli e pannello comuni; UX2 blocco C: tasto Legenda,
   stesso formato di #btn-dettagli.
   Stanno in ALTO a sinistra (richiesta del proprietario, 13/09/2026): in basso
   la barra del browser su telefono se li mangia, e il pollice ci arriva ma
   l'occhio no — in mappa si guarda la fascia alta, dov'è lo zoom. Sono
   impilati e non affiancati perché in `mappa.html` NON sono fratelli adiacenti
   (in mezzo c'è #map-legend, il pannello che #btn-legenda governa): affiancarli
   vorrebbe dire o spostare il markup — cambiando l'ordine di tabulazione — o
   fissare a mano la larghezza del primo. Compaiono solo a percorso disegnato
   (`_mostraLegendaBtn`), quindi non incontrano mai .map-rag-hint, che vive
   nella vista esplorativa. ── */
/* «Dettagli» resta un tasto a sé in alto a sinistra: compare solo con un
   percorso disegnato, e nella barra in basso sarebbe il quarto elemento —
   che romperebbe la regola dei tre. */
#btn-dettagli { position:absolute; top:60px; left:16px; z-index:501; display:none; align-items:center; gap:6px; background:white; color:var(--sea); border:1.5px solid var(--border); border-radius:20px; padding:8px 14px; font-family:'DM Sans','DM Sans Fallback',sans-serif; font-size:13px; font-weight:500; cursor:pointer; box-shadow:var(--shadow); white-space:nowrap; transition:background .15s,border-color .15s,color .15s; }
/* «Legenda» apre il pannello dei simboli del PERCORSO (salita, discesa,
   cambio, a piedi, posizioni incerte) e vive accanto a «Dettagli», come
   prima. Fuori dalla barra in basso: quella dice cosa fare adesso, questo
   spiega cosa c'è disegnato. */
#btn-legenda { position:absolute; top:60px; left:16px; z-index:501; display:none; align-items:center; gap:6px; background:white; color:var(--sea); border:1.5px solid var(--border); border-radius:20px; padding:8px 14px; font-family:'DM Sans','DM Sans Fallback',sans-serif; font-size:13px; font-weight:500; cursor:pointer; box-shadow:var(--shadow); white-space:nowrap; transition:background .15s,border-color .15s,color .15s; }
#btn-dettagli { top:102px; }
#btn-dettagli.visible, #btn-legenda.visible { display:flex; }

/* ── Il blocco +/− dentro la barra ────────────────────────────────────────
   Leaflet lo impila in verticale; qui i tre gruppi devono avere la STESSA
   altezza, quindi i due tasti vanno affiancati. */
.map-barra .leaflet-control-zoom {
  display:flex; margin:0 !important; border:none !important; box-shadow:none !important;
  border-radius:calc(var(--map-barra-h) / 2); overflow:hidden; flex:0 0 auto;
}
.map-barra .leaflet-control-zoom a {
  width:var(--map-barra-h); height:var(--map-barra-h); line-height:calc(var(--map-barra-h) - 3px);
  background:white; color:var(--sea); border:1.5px solid var(--border);
  font-size:20px; font-weight:600; box-sizing:border-box;
}
.map-barra .leaflet-control-zoom a:first-child { border-radius:calc(var(--map-barra-h) / 2) 0 0 calc(var(--map-barra-h) / 2); border-right-width:0.75px; }
.map-barra .leaflet-control-zoom a:last-child  { border-radius:0 calc(var(--map-barra-h) / 2) calc(var(--map-barra-h) / 2) 0; border-left-width:0.75px; }
.map-barra .leaflet-control-zoom { box-shadow:0 2px 10px rgba(14,47,61,0.18) !important; }
#btn-dettagli.active, #btn-legenda.active { background:var(--sea); color:white; border-color:var(--sea); }
#btn-dettagli:hover:not(.active), #btn-legenda:hover:not(.active) { background:var(--sea-pale); border-color:var(--sea-light); }
/* Etichette-comune overlay sulla mappa (fase 3 blocco 4) */
.det-overlay-label { background:rgba(255,255,255,0.92); border:1.5px solid rgba(10,79,110,0.25); border-radius:8px; padding:4px 9px; font-family:'DM Sans','DM Sans Fallback',sans-serif; font-size:12px; font-weight:600; color:var(--sea); white-space:nowrap; cursor:pointer; box-shadow:0 2px 8px rgba(0,0,0,0.14); transform:translateX(-50%); display:inline-block; text-align:center; line-height:1.3; transition:background .15s,border-color .15s; }
.det-overlay-label:hover { background:var(--sea-pale); border-color:var(--sea-light); }
.det-overlay-label.sel { background:var(--sea); color:white; border-color:var(--sea); }
.det-overlay-count { font-size:10px; font-weight:400; opacity:0.8; display:block; }
/* Anello pulsante sulle fermate del comune selezionato (F1) */
@keyframes pulsaAnello {
  0%   { transform:translate(-50%,-50%) scale(0.7); opacity:0.85; }
  75%  { transform:translate(-50%,-50%) scale(1.8); opacity:0; }
  100% { transform:translate(-50%,-50%) scale(0.7); opacity:0; }
}
.leaflet-marker-icon.marker-pulse::after { content:''; position:absolute; top:50%; left:50%; width:100%; height:100%; border-radius:50%; border:2.5px solid var(--sea); animation:pulsaAnello 1.5s ease-out infinite; pointer-events:none; }
/* Targhette "Sali qui"/"Scendi qui" e attenuazione contestuale: in fondo a
   questo file, col sistema di simboli. */
@media (max-width:768px) {
  /* #5 (TODO_MOBILE_PWA): prima stava in top:64px;left:10px — l'angolo
     peggiore per il pollice su schermi 6"+. Spostato in basso, coerente col
     posizionamento desktop (bottom:24px;left:16px), ma piu' in alto per non
     sovrapporsi al grabber dello sheet risultati quando e' a "peek" (collassa
     all'altezza del solo .m-sheet-grabber, ~36px: vedi collapsed in
     01-core.js). .map-legend resta sulla destra (bottom:24px;right:16px) e si
     apre solo al clic di #btn-legenda, quindi non serve piu' evitarne la
     sovrapposizione con #btn-dettagli — restano entrambi a sinistra,
     #btn-legenda sopra #btn-dettagli. */
  #btn-legenda { top:48px; left:10px; padding:7px 11px; font-size:12px; }
  #btn-dettagli { top:88px; left:10px; padding:7px 11px; font-size:12px; }
}
.leaflet-popup-content-wrapper { border-radius:10px!important; box-shadow:0 4px 20px rgba(0,0,0,0.15)!important; }
.leaflet-popup-content { margin:12px 14px!important; font-family:'DM Sans','DM Sans Fallback',sans-serif!important; }
.popup-name { font-weight:600; font-size:15px; color:var(--sea); margin-bottom:3px; line-height:1.2; }
.popup-sub { font-size:12px; color:var(--text-muted); margin-bottom:0; display:flex; align-items:center; gap:5px; }
.popup-sub svg { color:var(--sea-light); flex-shrink:0; }
.popup-tags { display:flex; gap:4px; flex-wrap:wrap; }
.popup-tag { font-size:11px; padding:2px 7px; border-radius:10px; background:var(--sea-pale); color:var(--sea); }
.popup-chip { display:inline-flex; align-items:center; gap:5px; background:var(--sea-pale); color:var(--sea); font-size:11px; font-weight:500; padding:3px 10px; border-radius:20px; }
.popup-chip svg { flex-shrink:0; }
/* Stato verifica coordinate — box colorato coerente coi badge salita/discesa */
.coord-status { display:flex; align-items:center; gap:7px; margin-top:9px; padding:7px 10px; border-radius:8px; font-size:11.5px; font-weight:500; line-height:1.3; text-decoration:none; }
.coord-status svg { flex-shrink:0; }
.coord-ok { background:#e8f5ee; border:1px solid rgba(45,122,79,0.25); color:#1f5536; }
.coord-no { background:#fffbeb; border:1px solid rgba(245,158,11,0.35); color:#92400e; cursor:pointer; }
.coord-no:hover { background:#fef3c7; }
/* PROMPT V13 §7: 'ricostruita' è il caso DOMINANTE dopo il gradino 4 — tono
   neutro/informativo, non un allarme (è la condizione normale, non un'
   eccezione). 'incerta' è invece il caso che va corretto: stesso tono
   ambra di .coord-no ma leggermente più marcato. */
.coord-rebuilt { background:#eef2f6; border:1px solid rgba(107,114,128,0.30); color:#374151; }
.coord-unknown { background:#fef3c7; border:1px solid rgba(217,119,6,0.45); color:#92400e; }
/* Popup fermata: orario di passaggio */
.popup-orario-passaggio { display:flex; align-items:center; gap:6px; margin-top:9px; padding:7px 10px; background:var(--sea-pale); border-radius:8px; font-size:13px; font-weight:600; color:var(--sea); }
/* CTA fumetto fermata: "Apri su Maps" resta sempre secondaria (outline);
   "Correggi/Conferma posizione" usa .popup-cta-primary (piena, colore brand)
   per ricostruita/incerta — PROMPT V13 §7, il pulsante deve farsi notare
   proprio dove la posizione non è affidabile — e .popup-cta-secondary
   altrimenti. */
.popup-cta-primary { width:100%; margin-top:11px; display:flex; align-items:center; justify-content:center; gap:8px; background:var(--sea); color:#fff; border:none; border-radius:9px; padding:11px; font-size:13.5px; font-weight:600; font-family:'DM Sans','DM Sans Fallback',sans-serif; cursor:pointer; transition:background 0.15s; }
.popup-cta-primary:hover { background:#0c5f86; }
.popup-cta-secondary { width:100%; margin-top:8px; display:flex; align-items:center; justify-content:center; gap:7px; background:#fff; color:var(--text-muted); border:1.5px solid var(--border); border-radius:9px; padding:9px; font-size:12.5px; font-weight:500; font-family:'DM Sans','DM Sans Fallback',sans-serif; cursor:pointer; transition:all 0.15s; }
.popup-cta-secondary:hover { background:var(--sea-pale); border-color:var(--sea); color:var(--sea); }
/* P40-bis: «Apri su Maps» è un <a> vero; senza questa regola Leaflet
   (`.leaflet-container a`, più specifica) lo colorerebbe e sottolineerebbe. */
.leaflet-container a.popup-cta-link { color:var(--text-muted); text-decoration:none; }
.leaflet-container a.popup-cta-link:hover { color:var(--sea); }
.popup-actions { display:flex; gap:6px; margin-top:8px; }
.popup-action-btn { flex:1; padding:5px 0; border:1.5px solid var(--border); background:white; border-radius:7px; cursor:pointer; font-size:11px; font-weight:600; font-family:'DM Sans','DM Sans Fallback',sans-serif; color:var(--text-muted); transition:all 0.15s; white-space:nowrap; }
.popup-action-btn:hover { background:var(--sea-pale); border-color:var(--sea); color:var(--sea); }
.popup-corr-form { margin-top:8px; }
.popup-corr-select { width:100%; padding:5px 7px; border:1.5px solid var(--border); border-radius:7px; font-size:12px; font-family:'DM Sans','DM Sans Fallback',sans-serif; color:var(--text); background:white; margin-bottom:6px; }
.popup-corr-textarea { width:100%; box-sizing:border-box; padding:6px 8px; border:1.5px solid var(--border); border-radius:7px; font-size:12px; font-family:'DM Sans','DM Sans Fallback',sans-serif; color:var(--text); resize:vertical; min-height:60px; }
.popup-corr-email { width:100%; box-sizing:border-box; padding:5px 8px; border:1.5px solid var(--border); border-radius:7px; font-size:12px; font-family:'DM Sans','DM Sans Fallback',sans-serif; color:var(--text); margin-top:5px; }
.popup-corr-submit { width:100%; margin-top:6px; padding:6px 0; background:var(--sea); color:white; border:none; border-radius:7px; cursor:pointer; font-size:12px; font-weight:600; font-family:'DM Sans','DM Sans Fallback',sans-serif; }
.popup-corr-submit:disabled { opacity:0.5; cursor:default; }

/* ── #2: form "Segnala un problema" (modale/bottom-sheet) ── */
.corr-body { display:flex; flex-direction:column; overflow-y:auto; flex:1; min-height:0; }
.corr-label { display:block; font-size:12px; font-weight:600; color:var(--text); margin:12px 0 6px; }
.corr-opt { font-weight:400; color:var(--text-muted); }
.corr-chips { display:flex; flex-wrap:wrap; gap:6px; }
.corr-chip {
  padding:7px 13px; border-radius:20px; border:1.5px solid var(--border-input);
  background:white; color:var(--text-muted); cursor:pointer; transition:all 0.15s;
  font-family:'DM Sans','DM Sans Fallback',sans-serif; font-size:13px; font-weight:500;
}
.corr-chip:hover { border-color:var(--sea-light); color:var(--sea); }
.corr-chip.active { background:var(--sea); color:white; border-color:var(--sea); }
.corr-input {
  width:100%; box-sizing:border-box; padding:10px 12px;
  border:1.5px solid var(--border-input); border-radius:10px;
  font-family:'DM Sans','DM Sans Fallback',sans-serif; font-size:14px; color:var(--text);
  background:white; transition:border-color 0.15s;
}
.corr-input:focus { border-color:var(--sea); }
.corr-textarea { resize:vertical; min-height:76px; }
.corr-hint { font-size:11.5px; color:var(--text-muted); margin-top:5px; line-height:1.4; }
.corr-recaptcha { margin-top:16px; }
.corr-error { display:none; font-size:12px; color:#dc2626; margin-top:5px; }
.corr-error.visible { display:block; }
/* UX6: checkbox accettazione informativa privacy (form segnalazione + pannello posizione) */
.privacy-check { display:flex; align-items:flex-start; gap:7px; margin:14px 0 2px; font-size:12.5px; color:var(--text); cursor:pointer; line-height:1.4; }
.privacy-check input[type="checkbox"] { margin:1px 0 0; flex:none; width:15px; height:15px; accent-color:var(--sea); cursor:pointer; }
.privacy-check a { color:inherit; text-decoration:underline; }
#pp-panel .privacy-check { font-size:11px; margin:8px 0 2px; }
#corr-coords-wrap { border-radius:12px; transition:background 0.2s, box-shadow 0.2s; }
#corr-coords-wrap.corr-highlight {
  background:var(--sea-pale); box-shadow:0 0 0 8px var(--sea-pale);
}
.corr-submit {
  width:100%; margin-top:18px; padding:13px 0;
  background:var(--sea); color:white; border:none; border-radius:12px;
  cursor:pointer; font-family:'DM Sans','DM Sans Fallback',sans-serif; font-size:15px; font-weight:600;
  transition:opacity 0.15s, background 0.15s;
}
.corr-submit:hover { background:var(--sea-dark, #083a52); }
.corr-submit:disabled { opacity:0.55; cursor:default; }
.corr-success { text-align:center; padding:24px 8px 8px; }
.corr-success-icon {
  width:56px; height:56px; margin:0 auto 14px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  background:#e8f5ee; color:#2d7a4f;
}
.corr-success h3 { font-size:18px; color:var(--text); margin-bottom:6px; }
.corr-success p { font-size:13.5px; color:var(--text-muted); line-height:1.5; max-width:280px; margin:0 auto; }
::-webkit-scrollbar { width:4px; }
::-webkit-scrollbar-track { background:transparent; }
::-webkit-scrollbar-thumb { background:rgba(10,79,110,0.20); border-radius:2px; }
/* P21: `.tb-btn-edit-mode` in tb.css (l'id `btn-edit-mode` non cambia:
   lo cerca `toggleEditMode`). */
.edit-toast { position:absolute; bottom:80px; left:50%; transform:translateX(-50%); background:var(--sea); color:white; padding:8px 16px; border-radius:20px; font-size:13px; z-index:600; pointer-events:none; box-shadow:var(--shadow); white-space:nowrap; }
.edit-banner { position:absolute; top:16px; right:16px; background:var(--accent); color:white; padding:8px 14px; border-radius:var(--radius); font-size:12px; font-weight:500; z-index:600; box-shadow:var(--shadow); display:none; }
.tratta-badge { display:inline-flex; align-items:center; padding:4px 10px; border-radius:20px; font-size:12px; font-weight:600; cursor:pointer; border:none; font-family:'DM Sans','DM Sans Fallback',sans-serif; transition:filter 0.15s, transform 0.15s; }
.tratta-badge:hover { filter:brightness(0.88); transform:translateY(-1px); }
.modal-overlay { position:fixed; inset:0; background:rgba(0,0,0,0.45); z-index:9000; display:flex; align-items:center; justify-content:center; }
.modal-box { background:white; border-radius:var(--radius); padding:20px; width:340px; max-width:90vw; max-height:80vh; display:flex; flex-direction:column; box-shadow:0 8px 40px rgba(0,0,0,0.25); }
.modal-header { display:flex; align-items:flex-start; justify-content:space-between; margin-bottom:14px; }
.modal-title { font-size:16px; font-weight:700; color:var(--sea); }
.modal-sub { font-size:12px; color:var(--text-muted); margin-top:2px; }
.modal-close { background:none; border:none; cursor:pointer; color:var(--text-muted); font-size:20px; line-height:1; padding:0 0 0 8px; flex-shrink:0; }
.modal-pdf-link { display:inline-block; margin-top:4px; font-size:11px; font-weight:600; color:var(--sea); text-decoration:none; opacity:0.8; }
.modal-pdf-link:hover { opacity:1; text-decoration:underline; }
.modal-ext-links { display:flex; flex-wrap:wrap; gap:12px; }
.modal-nota-orario { margin-top:6px; font-size:11px; color:#92400e; background:#fffbeb; border:1px solid #f59e0b; border-radius:6px; padding:6px 8px; line-height:1.4; }
.badge-verifica { background:#fffbeb; color:#92400e; font-size:10px; font-weight:600; padding:2px 8px; border-radius:20px; white-space:nowrap; border:1px solid #f59e0b; cursor:pointer; }
.modal-close:hover { color:var(--text); }
.modal-header-info { flex:1; min-width:0; }
.modal-fermate { overflow-y:auto; flex:1; }
.modal-stop { display:flex; align-items:center; gap:10px; padding:8px 6px; font-size:13px; color:var(--text); border-bottom:1px solid var(--border); cursor:pointer; transition:background 0.1s; }
.modal-stop:hover { background:var(--sea-pale); }
.modal-stop:last-child { border-bottom:none; }
.modal-stop-dot { width:9px; height:9px; border-radius:50%; flex-shrink:0; box-shadow:0 0 0 2px white; position:relative; z-index:1; }
.modal-stop-name { flex:1; min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.modal-stop-comune { font-size:11px; color:var(--text-muted); margin-left:auto; padding-left:8px; flex-shrink:0; white-space:nowrap; }
.modal-stop-tag { font-size:9px; font-weight:700; letter-spacing:0.06em; padding:2px 7px; border-radius:10px; color:white; flex-shrink:0; }
.modal-stop.entry { background:rgba(10,79,110,0.06); }
.modal-stop.entry .modal-stop-tag { background:var(--sea); }
.modal-stop.entry .modal-stop-name strong { color:var(--sea); font-weight:700; }
.modal-stop.exit { background:rgba(45,122,79,0.08); }
.modal-stop.exit .modal-stop-tag { background:var(--green); }
.modal-stop.exit .modal-stop-name strong { color:var(--green); font-weight:700; }
.modal-stop-time { font-family:'DM Sans','DM Sans Fallback',sans-serif; font-weight:600; font-size:13px; color:var(--text); white-space:nowrap; flex-shrink:0; }
/* FASE 6b: gamba senza orari pubblicati — dicitura al posto della lista con ~ */
.modal-nondett { font-size:12px; color:var(--text-muted); padding:8px 12px; background:var(--sea-pale); border-radius:8px; margin:8px 0; }
.modal-nondett a { color:var(--sea); font-weight:600; }
.modal-corsa-strip { display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-top:10px; padding:8px 12px; background:var(--sea-pale); border-radius:8px; font-size:13px; color:var(--text); }
.modal-corsa-lbl { font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:0.06em; color:var(--sea); }
.modal-corsa-strip strong { font-family:'DM Serif Display','DM Serif Display Fallback',serif; font-size:19px; font-weight:500; letter-spacing:-0.01em; }
.modal-corsa-strip .route-stimato { font-size:11px; color:#92400e; }
.modal-segment-active { position:relative; padding:2px 0; }
.modal-segment-active::before { content:''; position:absolute; left:10px; top:18px; bottom:18px; width:2px; background:var(--seg-color,var(--sea)); border-radius:1px; opacity:0.35; }
.modal-segment-extra { padding-left:8px; border-left:2px dotted var(--border); margin-left:6px; }
.modal-segment-extra .modal-stop { color:var(--text-muted); }
.modal-segment-extra .modal-stop-dot { opacity:0.5; }
.modal-segment-extra .modal-stop-time { opacity:0.6; }
/* ── STATI APP ── */
body { --header-h:80px; }
#hero { flex:1; display:flex; flex-direction:column; justify-content:safe center; align-items:center; padding:40px 16px; background:var(--sand); overflow-y:auto; }
.hero-inner { width:100%; max-width:480px; }
.hero-title { font-family:'Fredoka','Fredoka Fallback','DM Sans','DM Sans Fallback',sans-serif; font-weight:600; font-size:30px; color:var(--sea); margin-bottom:44px; }
.hero-sub { font-size:14px; color:var(--text-muted); margin-bottom:28px; }
.hero-form { background:white; border-radius:var(--radius); box-shadow:var(--shadow); padding:20px; }
.hero-form .search-label { display:none; }
.app { flex:1; display:none; }
/* Stato search: hero visibile, app nascosto */
body.s-search #hero { display:flex; }
body.s-search .app  { display:none; }
/* Stato results (SCHEDA-FIRST): la scheda di viaggio e' l'output, e prende
   tutto lo spazio. La mappa non c'e' — ne' sotto (desktop) ne' dietro lo sheet
   (mobile): si apre da un controllo esplicito, che porta in `s-map`. */
body.s-results #hero     { display:none; }
body.s-results .app      { display:flex; justify-content:center; background:var(--sand); }
body.s-results .map-area { display:none!important; }
/* Colonna centrata a larghezza leggibile: la sidebar da 380px lasciava due
   terzi di schermo vuoti, perche' nata come spalla di una mappa che non c'e'
   piu'. `flex-shrink` va riportato a 1 o su schermi stretti non si adatta. */
body.s-results .sidebar {
  width:min(760px, 100%); flex-shrink:1;
  border-right:none; border-left:1px solid var(--border);
  box-shadow:0 0 24px rgba(10,79,110,0.06);
}
/* Stato map: app visibile, mappa visibile */
body.s-map #hero     { display:none; }
body.s-map .app      { display:flex; }
body.s-map .map-area { display:flex!important; flex:1; }
/* Mobile stato map: nascondi sidebar */
@media (max-width:768px) {
  body.s-map .sidebar { display:none; }
  #hero { justify-content:flex-start; padding-top:24px; }

  /* SCHEDA-FIRST: qui c'era il bottom sheet — la sidebar in `position:fixed`
     sopra la mappa, col grabber, la freccia di espansione, lo scrim e la
     topbar usata come superficie di trascinamento (`touch-action:none`).
     Esisteva per una sola ragione: sotto c'era la mappa. Ora sotto non c'e'
     niente, la scheda e' la pagina, e la sidebar resta il flusso normale.
     `touch-action:none` sulla topbar era la sola vera zona morta al tocco:
     se ne va con il resto. `.m-scrim` vive dentro `.map-area`, che in
     `s-results` e' `display:none`, quindi sparisce da se'.
     `.btn-sheet-toggle` e `.m-sheet-grabber` tornano al loro `display:none`
     di base, dichiarato piu' sotto: non c'e' piu' nessuno stato che li
     mostri. */
}

/* Grabber visibile solo su mobile ≤768px */
.m-sheet-grabber { display:none; }
/* Grabber modale visibile solo su mobile ≤600px (default desktop nascosto) */
.modal-grabber { display:none; }
/* Topbar risultati */
.results-topbar { display:flex; align-items:center; gap:10px; padding:10px 14px; border-bottom:1px solid var(--border); background:white; flex-shrink:0; }
.btn-modifica { background:none; border:1.5px solid var(--border); border-radius:20px; padding:5px 12px; font-size:12px; font-weight:500; color:var(--sea); cursor:pointer; font-family:'DM Sans','DM Sans Fallback',sans-serif; white-space:nowrap; display:flex; align-items:center; gap:5px; }
.btn-modifica:hover { background:var(--sea-pale); }
.topbar-riepilogo { flex:1; font-size:12px; color:var(--text-muted); min-width:0; line-height:1.35; word-break:break-word; }
.topbar-riepilogo strong { color:var(--sea); }
/* PR 3: la data effettiva accanto alla relazione, quando i risultati non sono
   del giorno cercato. Resta visibile mentre si scorre la lista. */
.topbar-quando { color:var(--sea); font-weight:600; white-space:nowrap; }
/* Back button mappa */
#field-from.filled { padding-right:36px; }
.recent-searches { margin-top:14px; }
.recent-searches-header { display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:8px; }
.recent-searches-title { font-size:11px; font-weight:600; color:var(--text-muted); text-transform:uppercase; letter-spacing:0.05em; }
.recent-clear-all { background:none; border:none; padding:2px 6px; font-size:12px; color:var(--sea); cursor:pointer; font-family:inherit; border-radius:6px; }
.recent-clear-all:hover { background:var(--sea-pale); text-decoration:underline; }
.recent-chips { display:flex; flex-wrap:wrap; gap:10px; }
.recent-chip { display:inline-flex; align-items:center; gap:6px; padding:6px 4px 6px 11px; border-radius:20px; font-size:13px; font-weight:500; border:1.5px solid var(--border); background:white; color:var(--text); cursor:pointer; font-family:'DM Sans','DM Sans Fallback',sans-serif; min-height:34px; max-width:100%; transition:all 0.12s; }
.recent-chip:hover, .recent-chip:focus-visible { background:var(--sea-pale); border-color:var(--sea-light); color:var(--sea); }
.recent-chip-icon { flex-shrink:0; opacity:0.65; }
.recent-chip-label { min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:calc(100% - 28px); }
/* A11y (Lighthouse color-contrast): opacity:0.55 sul testo " → " ereditato
   da --text scendeva a ~3.86:1 su sfondo bianco (sotto 4.5:1 AA). Colore
   diretto invece di opacity: stesso effetto "attenuato" visivamente, ma
   resta a ~6:1, conforme. */
.recent-chip-arrow { color:var(--text-muted); margin:0 1px; }
/* A11y (Lighthouse target-size): 20x20 era sotto il minimo WCAG 2.5.8 (24x24
   CSS px) — ora 24x24 col padding attorno, e gap fra chip alzato a 10px cosi'
   il target vicino (la chip stessa, cliccabile a sua volta) ha piu' respiro. */
.recent-chip-remove { display:inline-flex; align-items:center; justify-content:center; width:24px; height:24px; border-radius:50%; background:transparent; border:none; cursor:pointer; color:var(--text-muted); padding:0; flex-shrink:0; transition:background 0.12s, color 0.12s; }
.recent-chip-remove:hover, .recent-chip-remove:focus-visible { background:rgba(10,79,110,0.1); color:var(--accent); }
/* Stato vuoto storico non mostrato */
.recent-searches:empty { display:none; }

/* ── Navigazione header ─────────────────────────────────────────────────── */
/* P21: le regole `.m-*` della nav e del cassetto sono sparite —
   erano una seconda copia di `.tb-nav*` / `.tb-nav-drawer*`, quasi
   identica e percio' capace di divergere senza che si vedesse. */

/* P21: l'header compatto (nav via, hamburger, badge e tasto staff via) e'
   in tb.css, a 768px per TUTTO il sito. Era 768 qui e 640 la': fra i 641
   e i 768 px le due meta' del sito si comportavano diversamente. */

/* ── MOBILE-FIRST ≤ 600px ─────────────────────────────────────────────── */
@media (max-width:600px) {
  /* Previene zoom automatico iOS sul focus degli input */
  .cascade-input { font-size:16px!important; }

  /* Header semplificato */
  /* P21: padding e altezza dell'header stretto stanno in tb.css (a 640px,
     non 600: un valore solo per tutto il sito). */

  /* Hero form (GATE B: -8px hero, -8px titolo, -4px form = ~20px per far
     stare «Cerca percorsi» sopra la piega anche a 667 con le etichette) */
  #hero { padding:8px 12px; }
  .hero-inner { max-width:100%; }
  .hero-title { font-size:26px; margin-bottom:12px; }
  .hero-form { padding:14px 16px; }
  .btn-elenco .btn-elenco-lbl { font-size:11px; }

  /* Cascade: touch target ≥ 48px */
  .cascade-field { min-height:48px; }
  .cascade-fermata { padding:13px 14px; font-size:14px; }
  .cascade-fermata-nome { white-space:normal; }
  /* UX-C (8/09): a 375 px la riga vale ~283 px di contenuto e il badge
     «posizione non confermata» ne prende 139 — inline lascerebbe al nome una
     colonna di 129 px, cioè 2-3 righe per un nome lungo. Sotto i 600 px il
     badge va a capo da solo (come fa già `.vd-incerta` nella timeline, che è
     display:block): il nome riprende tutta la larghezza. Costo misurato sul
     comune peggiore (Diamante, 18 fermate incerte su 33): 1.650 → 1.952 px di
     lista. Solo le righe COL badge: `:has()` non supportato ⇒ si resta
     all'inline di prima, che è leggibile lo stesso. */
  .cascade-fermata:has(.cascade-badge-incerta) { flex-wrap:wrap; }
  .cascade-fermata:has(.cascade-badge-incerta) .cascade-fermata-nome { flex:1 1 100%; }
  .cascade-comune { padding:14px 14px 14px 20px; font-size:14px; }
  .cascade-prov { padding:14px; font-size:15px; }
  .cascade-back { padding:11px 14px; font-size:13px; }
  .cascade-dropdown { max-height:55vh; overscroll-behavior:contain; }

  /* Ora chips (ritorno) */
  .ora-chip { padding:8px 14px; font-size:14px; }

  /* Form "quando" v2 */
  .day-chip { min-height:42px; font-size:14px; padding:9px 14px; }
  .ora-preset { padding:9px 14px; font-size:14px; min-height:40px; }
  .diretti-switch { font-size:15px; padding:12px 2px; }

  /* Search button */
  .btn-search { padding:14px; font-size:15px; min-height:48px; }

  /* Results topbar */
  .results-topbar { padding:8px 12px; }
  .topbar-riepilogo { font-size:13px; }

  /* Route cards */
  .results-area { padding:10px 12px; }
  .route-card { padding:14px 16px; margin-bottom:10px; }
  .route-tag { font-size:13px; }
  .time { font-size:26px; }
  .time-duration-pill { font-size:12px; }
  .route-tratto { font-size:14px; }
  .route-meta { font-size:13px; gap:4px 12px; }

  /* Nomi fermata lunghi: su telefono si leggono per intero, niente troncamento */
  .opt-nome { white-space:normal; }
  .opt-trigger { align-items:flex-start; }

  /* Tratta badge: touch target ≥ 36px */
  .tratta-badge { padding:8px 14px; font-size:13px; min-height:36px; }

  /* Modal → bottom sheet trascinabile */
  .modal-overlay { align-items:flex-end; }
  .modal-box {
    width:100%; max-width:100%; height:88vh; max-height:88vh;
    border-radius:16px 16px 0 0; padding:0 20px 40px;
    transform:translateY(0); transition:transform 0.3s cubic-bezier(.4,0,.2,1);
    touch-action:pan-y;
  }
  .modal-box.dragging { transition:none; }
  .modal-box.snap-peek { transform:translateY(calc(88vh - 200px)); }
  .modal-box.snap-half { transform:translateY(calc(88vh - 55vh)); }
  .modal-box.snap-full { transform:translateY(0); }
  .modal-box::before { display:none; }
  .modal-grabber {
    width:100%; min-height:44px; display:flex; align-items:center; justify-content:center;
    cursor:grab; touch-action:none; user-select:none; padding:10px 0 4px;
    margin-bottom:6px;
  }
  .modal-grabber::before {
    content:''; width:44px; height:5px;
    background:rgba(10,79,110,0.25); border-radius:3px;
  }
  .modal-grabber:active { cursor:grabbing; }
  .modal-title { font-size:17px; }
  .modal-stop { padding:10px 6px; font-size:14px; }
  .modal-corsa-strip strong { font-size:20px; }

  /* Map legend compatta */
  .map-legend { bottom:12px; right:8px; padding:8px 10px; font-size:11px; }
  .legend-title { font-size:10px; }
}

/* ── MOBILE ≤ 380px (telefoni molto piccoli) ─────────────────────────── */
@media (max-width:380px) {
  .hero-title { font-size:22px; }
  .route-times { gap:8px; }
  .time { font-size:22px; }
  .route-tratto { font-size:13px; }
  .route-meta { font-size:12px; }
  .tratta-badge { padding:8px 12px; font-size:12px; }
}

/* ── Data chips ── */
.data-row { margin-bottom:10px; }
.data-chips { display:flex; gap:5px; flex-wrap:wrap; margin-top:6px; }
.data-chip { padding:6px 14px; border-radius:20px; font-size:13px; font-family:'DM Sans','DM Sans Fallback',sans-serif; font-weight:500; border:1.5px solid var(--border); cursor:pointer; background:white; color:var(--text-muted); transition:all 0.15s; }
.data-chip:hover { border-color:var(--sea-light); color:var(--sea); }
.data-chip.active { background:var(--sea); color:white; border-color:var(--sea); }
.data-custom-input { border:1.5px solid var(--border); border-radius:20px; padding:5px 12px; font-size:13px; font-family:'DM Sans','DM Sans Fallback',sans-serif; background:white; color:var(--text); outline:none; margin-top:6px; display:none; width:100%; }
.data-custom-input.visible { display:block; }

/* ── Filter tabs ── */
.filter-tabs { display:none; border-bottom:1px solid var(--border); background:var(--sea-pale); flex-shrink:0; }
.filter-tabs.visible { display:flex; }
.filter-tab { flex:1; padding:9px 0; text-align:center; font-size:12px; font-weight:600; color:var(--text-muted); cursor:pointer; border-bottom:2.5px solid transparent; background:none; border-top:none; border-left:none; border-right:none; font-family:'DM Sans','DM Sans Fallback',sans-serif; transition:color 0.15s,border-color 0.15s; }
.filter-tab:hover { color:var(--sea); }
.filter-tab.active { color:var(--sea); border-bottom-color:var(--sea); }
.filter-tab:disabled { opacity:0.4; cursor:default; }
.tab-count { font-size:10px; opacity:0.65; margin-left:3px; }

/* ── Share button ── */
.btn-share { background:none; border:1.5px solid var(--border); border-radius:20px; padding:5px 10px; font-size:12px; color:var(--sea); cursor:pointer; font-family:'DM Sans','DM Sans Fallback',sans-serif; display:none; align-items:center; gap:4px; white-space:nowrap; flex-shrink:0; }
.btn-share.visible { display:flex; }
.btn-share:hover { background:var(--sea-pale); }
/* Toggle comprimi/espandi sheet risultati (mobile only) */
.btn-sheet-toggle {
  display:none; align-items:center; justify-content:center;
  width:32px; height:32px; flex-shrink:0; padding:0;
  background:none; border:1.5px solid var(--border); border-radius:50%;
  color:var(--sea); cursor:pointer;
}
.btn-sheet-toggle:hover { background:var(--sea-pale); }
.btn-sheet-toggle svg { transition:transform 0.2s; }
body.s-sheet-peek #btn-sheet-toggle svg { transform:rotate(180deg); }

/* ── Oggi attivo badge ── */
.badge-oggi { background:#e8f5ee; color:#2d7a4f; }
.badge-oggi-no { background:#fdf0eb; color:#e8622a; }

.badge-coord-ok { background:#e8f5ee; color:#2d7a4f; font-size:10px; font-weight:600; padding:2px 8px; border-radius:20px; white-space:nowrap; border:1px solid #86efac; }
.badge-coord-no { background:#fff8e1; color:#92400e; font-size:10px; font-weight:600; padding:2px 8px; border-radius:20px; white-space:nowrap; border:1px solid #f59e0b; text-decoration:none; display:inline-block; }
/* ── Pannello ologramma proposta posizione ── */
#pp-panel { position:fixed; bottom:20px; left:50%; transform:translateX(-50%); z-index:10000; background:white; border-radius:12px; box-shadow:0 4px 24px rgba(0,0,0,0.18); padding:14px 18px; width:300px; max-width:calc(100vw - 32px); display:none; font-family:'DM Sans','DM Sans Fallback',sans-serif; }
#pp-panel .pp-title { font-weight:700; font-size:13px; color:var(--sea); margin-bottom:4px; }
#pp-panel .pp-hint  { font-size:11px; color:var(--text-muted); margin-bottom:10px; }
#pp-panel input[type=email] { width:100%; box-sizing:border-box; padding:6px 9px; border:1.5px solid var(--border); border-radius:7px; font-size:12px; font-family:'DM Sans','DM Sans Fallback',sans-serif; margin-bottom:6px; }
#pp-panel input[type=email]:focus { border-color:var(--sea); }
#pp-panel .pp-actions { display:flex; gap:8px; margin-top:4px; }
#pp-panel .pp-btn-ok  { flex:1; padding:7px 0; background:var(--sea); color:white; border:none; border-radius:7px; cursor:pointer; font-size:12px; font-weight:600; font-family:'DM Sans','DM Sans Fallback',sans-serif; }
#pp-panel .pp-btn-ok:disabled { opacity:0.5; cursor:default; }
#pp-panel .pp-btn-no  { flex:1; padding:7px 0; background:white; color:var(--text-muted); border:1.5px solid var(--border); border-radius:7px; cursor:pointer; font-size:12px; font-weight:600; font-family:'DM Sans','DM Sans Fallback',sans-serif; }
#pp-panel .pp-err     { font-size:11px; color:#dc2626; margin-top:2px; display:none; }
#pp-panel .pp-privacy { font-size:10px; color:var(--text-muted); margin-bottom:6px; }
#pp-panel .pp-privacy a { color:var(--text-muted); text-decoration:underline; }
#pp-panel .pp-recaptcha { margin-bottom:8px; }
#pp-panel .pp-label { display:block; font-size:11px; font-weight:600; color:var(--text); margin-bottom:4px; }
#pp-panel .pp-opt     { font-weight:400; color:var(--text-muted); }
#pp-panel .pp-notes   { width:100%; box-sizing:border-box; padding:6px 9px; border:1.5px solid var(--border); border-radius:7px; font-size:12px; font-family:'DM Sans','DM Sans Fallback',sans-serif; resize:vertical; min-height:52px; margin-bottom:6px; }
#pp-panel .pp-notes:focus { border-color:var(--sea); }

/* ── Attesa lunga al cambio ── */
/* B — «coincidenza non garantita»: una dichiarazione, non un allarme. Tono
   più tenue della riga di certezza (che parla di un dubbio sui DATI): qui il
   dato è giusto, è la garanzia a non esserci. */
.route-coincidenza { margin:6px 0 0; font-size:11.5px; line-height:1.45; color:#5b6472; }
.route-coincidenza::before { content:'⟳ '; }
/* H — l'avviso L2b in chiaro sulla scheda: stesso peso della riga di certezza
   (parla dei dati che l'utente ha davanti), non del bottone generico. */
.route-quadro-nuovo { margin:6px 0 0; font-size:12px; line-height:1.45; color:#92400e; background:#fdf5ec;
  border-left:3px solid #d97706; border-radius:4px; padding:6px 8px; }
.route-quadro-nuovo a { color:#92400e; text-decoration:underline; white-space:nowrap; }
.route-attesa-lunga { font-size:11px; color:#92400e; white-space:nowrap; }
.route-attesa-lunga::before { content:'⏱ '; }

/* ── Chip meta card (Viaggia / Effettuato da / Prezzo) ── */
.meta-row-viaggia { display:flex; align-items:center; justify-content:space-between; gap:10px; }
.meta-chip-viaggia { display:flex; align-items:center; gap:5px; white-space:nowrap; overflow:hidden; }
.meta-link-orario { font-weight:600; color:var(--sea); text-decoration:none; white-space:nowrap; flex-shrink:0; }
/* P26 (WCAG 2.5.8): 24 px di bersaglio senza alzare la riga. È il link a
   dare l'altezza alla riga, e la «↗» viene da un font di ripiego più alto
   (19,5 px contro 17 di `1lh`): padding e margine negativo uguali lasciano
   alla riga l'altezza del contenuto, qualunque font arrivi. */
.meta-link-orario { box-sizing:border-box; min-height:24px; padding:4px 0; margin:-4px 0; }
.meta-link-orario:hover { text-decoration:underline; }
.meta-chip-dot { width:8px; height:8px; border-radius:50%; flex-shrink:0; }
.meta-chip-vettore { display:flex; align-items:center; gap:5px; max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; padding-right:8px; box-sizing:border-box; }
.meta-chip-vettore svg, .meta-chip-viaggia svg, .meta-chip-prezzo svg { flex-shrink:0; }
.meta-chip-prezzo { display:flex; align-items:center; gap:5px; max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; box-sizing:border-box; }
.meta-chip-prezzo strong { font-weight:600; color:var(--text); }

/* ── La barra dei controlli della mappa ───────────────────────────────────
   Tre gruppi su una riga sola: «Risultati», «Legenda», il blocco +/−.
   Richiesta del proprietario (13/09/2026): stessa altezza, stessa distanza
   fra loro e dai bordi, e la stessa distanza dal basso che la pillola della
   guida ha dall'alto.

   ⚠️ È un FLEX e non tre elementi posizionati a mano, ed è l'unico modo che
   regge: con `left`/`right` la distanza fra due elementi dipende dalle loro
   larghezze, che qui sono diverse e cambiano col testo. Qui invece il gap e
   il padding laterale sono LO STESSO numero e i due tasti di testo si
   allargano a riempire — la regolarità è una conseguenza della regola, non
   una misura da tenere allineata a mano.

   ⚠️ La distanza dal basso NON è misurata dal bordo della mappa ma dal
   PAVIMENTO UTILE, cioè sopra la riga di attribuzione di Leaflet: i link di
   OpenFreeMap devono restare visibili e toccabili (richiesta precedente
   dello stesso collaudo), quindi la simmetria con la pillola in alto si
   legge rispetto allo spazio in cui la mappa si guarda. */
/* La COLONNA: barra sopra, riga dei colori sotto. Ancorata in basso, quindi
   quando la riga compare la barra sale da sé e quando sparisce torna giù —
   richiesta del proprietario, 13/09/2026. Con due `bottom` fissi servirebbero
   due numeri da tenere d'accordo a mano; qui è una conseguenza del flex. */
.map-fondo {
  position:absolute; left:0; right:0; z-index:700;
  bottom:calc(var(--map-gap) + var(--map-attrib-h) + env(safe-area-inset-bottom, 0px));
  display:flex; flex-direction:column; gap:var(--map-gap); align-items:stretch;
  padding:0 var(--map-gap); box-sizing:border-box;
  pointer-events:none;                 /* la mappa resta trascinabile intorno */
}
.map-fondo > * { pointer-events:auto; }

.map-barra {
  display:flex; align-items:stretch; gap:var(--map-gap);
  pointer-events:none;
}
.map-barra > * { pointer-events:auto; }
:root { --map-gap:10px; --map-attrib-h:18px; --map-barra-h:44px; --map-striscia-h:0px; }

/* I due tasti di testo si allargano; il blocco +/− tiene la sua larghezza. */
.map-barra .btn-back-map { flex:1 1 0; min-width:0; }

.btn-back-map {
  height:var(--map-barra-h); background:white; border:1.5px solid var(--border);
  border-radius:calc(var(--map-barra-h) / 2); cursor:pointer;
  font-size:14px; font-weight:600; font-family:'DM Sans','DM Sans Fallback',sans-serif;
  display:flex; align-items:center; justify-content:center; gap:6px;
  box-shadow:0 2px 10px rgba(14,47,61,0.18); color:var(--text);
  white-space:nowrap; overflow:hidden;
}
.btn-back-map:hover { background:var(--sea-pale); }
/* L'anello di `:focus-visible` (tb.css) non si disegna per il focus che
   mettiamo NOI all'apertura della mappa: sul telefono il tasto compariva col
   bordo blu e tornava normale al primo tocco altrove, e si leggeva come un
   difetto. La classe la toglie il primo `keydown` — vedi apriVistaMappa: per
   chi naviga da tastiera l'anello serve, e torna appena tocca un tasto. */
.btn-back-map.focus-da-script:focus-visible { outline:none; }

/* SCHEDA-FIRST: il bottone "Risultati" e' la via di ritorno dalla vista mappa,
   e serve su desktop quanto su telefono — prima era nascosto la' perche' la
   sidebar restava sempre a fianco e non c'era una vista da "chiudere". Fuori
   da `s-map` resta nascosto: non c'e' mappa da cui tornare. */
.btn-back-map { display:none; }
body.s-map .btn-back-map { display:flex; }


/* ── SCHEDA-FIRST (31/08/2026): i due accessi alla vista mappa ─────────────
   La mappa non e' piu' l'output del planner: e' una vista secondaria, e come
   tale si apre da un controllo che si vede e si dichiara. Due punti d'accesso,
   uno stabile e uno contestuale, entrambi `aria-expanded` sullo stesso
   `#map-area`. */
/* P21: `.tb-btn-mappa` in tb.css — lo stesso tasto vive ora anche nelle
   pagine pubbliche, dove e' un link a `/?vista=mappa` invece di un
   interruttore. L'id `btn-mappa` non cambia. */
/* La riga contestuale sopra la lista: compare solo quando c'e' un risultato
   da guardare sulla mappa (nessun risultato = niente da mostrare li'). */
.map-cta { display:none; padding:8px 14px; border-bottom:1px solid var(--border); background:var(--sea-pale); }
#sidebar-sheet.ha-risultati .map-cta { display:flex; }
/* Dentro la vista mappa il contestuale non serve: la via di uscita e' il
   bottone "Risultati", e un "Vedi sulla mappa" mentre la mappa e' aperta
   direbbe il contrario di quello che fa. */
body.s-map .map-cta { display:none!important; }
/* Mappa aperta dal form, senza una ricerca alle spalle: la colonna dei
   risultati sarebbe vuota, e su desktop occuperebbe 380px per non dire
   niente. Su telefono era gia' nascosta in `s-map`. */
body.s-map #sidebar-sheet:not(.ha-risultati) { display:none; }
.btn-mappa-risultati {
  background:white; border:1.5px solid var(--border); border-radius:20px;
  padding:7px 14px; cursor:pointer; width:100%;
  font-family:'DM Sans','DM Sans Fallback',sans-serif; font-size:13px; font-weight:600;
  color:var(--sea); display:flex; align-items:center; justify-content:center; gap:7px;
}
.btn-mappa-risultati:hover { background:var(--sea-pale); }
@media (pointer:coarse) { .btn-mappa, .btn-mappa-risultati { min-height:44px; } }
@media (max-width:768px) { .btn-mappa .btn-mappa-label { display:none; } }

/* ── SCHEDA-FIRST (PR A1): riga azioni della scheda + striscia in mappa ── */
/* La riga azioni: «Dettaglio percorso» (flessibile) + «Mappa» (fisso). Il
   margin-top che era del toggle passa alla riga; dentro la riga il toggle
   perde il width:100% (è il flex a dargli lo spazio). */
.route-azioni { display:flex; gap:8px; align-items:stretch; margin-top:10px; }
.btn-mappa-scheda {
  flex:1 1 auto; display:flex; align-items:center; justify-content:center; gap:6px; padding:9px 14px;
  background:white; border:1px solid rgba(10,79,110,0.2); border-radius:8px;
  font-family:inherit; font-size:13px; font-weight:600; color:var(--sea);
  cursor:pointer; transition:background 0.15s;
}
.btn-mappa-scheda:hover, .btn-mappa-scheda:focus-visible { background:var(--sea-pale); }
@media (pointer:coarse) { .btn-mappa-scheda { min-height:44px; } }

/* La striscia: fissa in fondo alla .map-area, ~56px, SOLO quando un percorso
   è disegnato (attributo hidden governato da _aggiornaStrisciaMappa). Non è
   il vecchio bottom sheet: niente drag, niente s-sheet-*. */
.map-striscia {
  position:absolute; left:0; right:0; bottom:0; z-index:650; min-height:56px;
  background:white; border-top:1px solid var(--border);
  box-shadow:0 -2px 10px rgba(0,0,0,0.08);
  display:flex; align-items:center; gap:8px; padding:6px 10px;
  padding-bottom:calc(6px + env(safe-area-inset-bottom, 0px));
}
.map-striscia[hidden] { display:none; }
.map-striscia-info {
  flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap; font-size:13px; color:var(--text);
  font-family:'DM Sans','DM Sans Fallback',sans-serif;
}
.map-striscia-info strong { font-size:15px; font-variant-numeric:tabular-nums; }
.map-striscia-nav {
  flex:0 0 auto; width:36px; height:36px; border-radius:50%;
  border:1.5px solid var(--border); background:white; color:var(--sea);
  font-size:18px; line-height:1; cursor:pointer; padding:0;
}
.map-striscia-nav:hover:not(:disabled) { background:var(--sea-pale); }
.map-striscia-nav:disabled { opacity:0.35; cursor:default; }
.map-striscia-btn {
  flex:0 0 auto; display:flex; align-items:center; gap:5px;
  background:var(--sea); color:white; border:1.5px solid var(--sea);
  border-radius:20px; padding:8px 14px; font-size:13px; font-weight:600;
  font-family:'DM Sans','DM Sans Fallback',sans-serif; cursor:pointer;
}
.map-striscia-btn:hover { background:var(--sea-light); border-color:var(--sea-light); }
/* Con la striscia, i controlli ancorati in basso salgono del suo ingombro
   (56px): attribuzione Leaflet (deve restare leggibile), legenda e bottoni. */
/* ⚠️ Con la striscia l'ordine dal basso è: striscia, link, controlli. I link
   restano l'ultima cosa DELLA MAPPA — «sempre in basso come prima» — e la
   striscia è una barra di sistema che sta sotto tutto.
   L'altezza della striscia si MISURA (`_allineaBarraMappa`): 56px era un
   minimo, e la striscia cresce col testo e con l'incavo dell'iPhone. */
.map-area.con-striscia .leaflet-control-attribution { margin-bottom:var(--map-striscia-h, 56px); }
/* La colonna sale sopra la striscia. Qui NON si somma `env(safe-area-inset-
   bottom)`: la striscia ha già il suo `padding-bottom` col safe-area dentro,
   e la sua altezza misurata lo comprende — sommarlo di nuovo lo conterebbe
   due volte. */
.map-area.con-striscia .map-fondo {
  bottom:calc(var(--map-gap) + var(--map-attrib-h) + var(--map-striscia-h));
}
/* Col percorso disegnato il ritorno ce l'ha già la striscia
   (`.map-striscia-btn`), nello stesso angolo dello schermo: due «Risultati»
   uno sopra l'altro non sono una scelta. Resta il solo blocco +/−, che si
   tiene la sua destra. */
.map-area.con-striscia .map-barra .btn-back-map { display:none; }
.map-barra { justify-content:flex-end; }
.map-area.con-striscia .map-legend { bottom:calc(24px + 56px); }
/* ⚠️ #btn-dettagli/#btn-legenda NON salgono più con la striscia: da quando
   stanno in alto non sono più ancorati in basso, e una regola su `bottom`
   qui darebbe loro top E bottom insieme — cioè un tasto stirato per tutta
   l'altezza della mappa. */
@media (max-width:600px) {
  .map-area.con-striscia .map-legend { bottom:calc(12px + 56px); }
}

/* ── GATE 1 (PR A1, scelte del proprietario 7/09/2026): la cornice ── */
/* 2b · chip «dalle» in coda alla riga Andata/Ritorno + pannello a tendina
   con le file «Parti dopo le» di prima. La riga da 64,5px sparisce dal
   flusso; le fasce restano le stesse, aperte dal chip. */
.ar-row-wrap { position:relative; }
.andata-ritorno-tabs { align-items:center; }
.andata-ritorno-tabs .ar-tab { flex:1 1 0; min-width:0; }
.ar-fascia-chip {
  flex:0 0 auto; display:inline-flex; align-items:center; gap:3px;
  margin:0 8px; padding:5px 10px; border:1.5px solid var(--border);
  border-radius:999px; background:white; color:var(--sea);
  font-family:'DM Sans','DM Sans Fallback',sans-serif; font-size:12px;
  font-weight:600; cursor:pointer; white-space:nowrap;
}
.ar-fascia-chip:hover { background:var(--sea-pale); }
.ar-fascia-chip .chev { transition:transform 0.2s; }
.ar-fascia-chip[aria-expanded="true"] .chev { transform:rotate(180deg); }
#fascia-panel {
  position:absolute; top:100%; left:0; right:0; z-index:700;
  background:white; border-bottom:1px solid var(--border);
  box-shadow:0 10px 18px rgba(0,0,0,0.12);
}
#fascia-panel[hidden] { display:none; }
/* 3a · i filtri Diretti/Con cambio compaiono solo se la lista ha entrambi i
   tipi: la regola vive in renderPercorsi, qui nessun cambio (resta .visible). */
/* 1a · header compatto negli stati risultati/mappa, SOLO su telefono: sulla
   home e su desktop il fumetto resta a piena taglia (è il brand). 44px
   guadagnati = 5,4% dello schermo a 812, 6,6% a 667. */
@media (max-width:600px) {
  /* UX-A: quando la scheda di viaggio (o la mappa) prende la scena,
     l'header si stringe per lasciarle spazio. NON e' «l'header che
     cambia da pagina a pagina» — e' lo stato della SPA, e per questo
     sopravvive a P21. Selettori aggiornati alle classi condivise. */
  body.s-results .tb-header, body.s-map .tb-header { height:64px; }
  body.s-results .tb-brand img, body.s-map .tb-brand img { height:58px; }
  /* 4a · via il «Vedi sulla mappa» sopra la lista: l'accesso contestuale è il
     bottone «Mappa» dentro ogni scheda; l'icona nell'header resta. Il bottone
     resta nell'HTML (guardia sui due accessi) e visibile su desktop. */
  #sidebar-sheet.ha-risultati .map-cta { display:none; }
}

/* GATE B: solo sotto i 350px il testo del tasto collassa nella freccia
   (l'aria-label resta); a 375 la scritta e' il modo in cui si scopre. */
@media (max-width:350px) {
  .btn-elenco .btn-elenco-lbl { display:none; }
  .cascade-field { padding-right:70px; }
}

/* ── P18: la mappa della scoperta ──────────────────────────────────────────
   I marker-comune (.mk-comune/.mk-dot/.mk-label) e i loro stati di
   raggiungibilità stanno in fondo a questo file, col sistema di simboli. */
/* La striscia-legenda della raggiungibilità: in basso al centro, discreta,
   solo quando i colori ci sono (JS: _aggiornaHintRaggiungibilita). */
/* Larga quanto la barra sopra, così i bordi laterali sono gli stessi.
   ⚠️ VA A CAPO, non scorre. Prima scorreva in orizzontale, e il risultato era
   che l'ultima voce restava fuori dallo schermo — tagliata, non nascosta:
   una legenda che non si legge tutta non è una legenda. Il timore che il
   capoverso facesse «saltare» i controlli era infondato: la riga vive nella
   colonna `.map-fondo`, che assorbe l'altezza spostando in su la barra —
   esattamente come fa quando la riga compare. */
.map-rag-hint {
  display:flex; align-items:center; justify-content:center;
  flex-wrap:wrap; column-gap:10px; row-gap:3px;
  background:rgba(255,255,255,0.96); border-radius:16px; padding:7px 12px;
  font-size:11.5px; font-weight:600; color:var(--text);
  box-shadow:0 2px 10px rgba(10,79,110,0.2);
  box-sizing:border-box;
}
.map-rag-hint[hidden] { display:none; }
.rag-hint-item { display:flex; align-items:center; gap:4px; white-space:nowrap; }
.rag-dot { width:10px; height:10px; border-radius:50%; display:inline-block; }
.rag-dot-partenza { background:var(--mk-verde); }
.rag-dot-destinazione { background:white; border:3px solid var(--mk-rosso); box-sizing:border-box; }
.rag-dot-diretto { background:var(--sea-light); }
.rag-dot-cambio { background:white; border:2.5px solid var(--sea-light); box-sizing:border-box; }
.rag-dot-non { background:#9aa5ab; opacity:0.6; }
/* Popup comune = mini-form: righe di chip compatte, scrollabili se serve. */
.popup-comune { min-width:206px; }
.popup-comune-stato { font-size:11.5px; font-weight:600; margin:-2px 0 8px; padding:3px 8px; border-radius:8px; }
.popup-comune-stato.stato-diretto { background:var(--sea-pale); color:var(--sea); }
.popup-comune-stato.stato-cambio { background:var(--sea-pale); color:var(--sea); }
.popup-comune-stato.stato-noncollegato { background:#f3f4f6; color:#6b7280; }
.popup-chip-row { display:flex; gap:5px; margin-bottom:6px; overflow-x:auto; scrollbar-width:none; }
.popup-chip-row::-webkit-scrollbar { display:none; }
.popup-chip { flex-shrink:0; border:1px solid var(--border); background:white; color:var(--text); border-radius:12px; padding:4px 9px; font-size:11.5px; font-weight:600; font-family:'DM Sans','DM Sans Fallback',sans-serif; cursor:pointer; }
.popup-chip.active { background:var(--sea); border-color:var(--sea); color:white; }
.popup-chip-altra-wrap { position:relative; flex-shrink:0; }
.popup-native-overlay { position:absolute; inset:0; opacity:0; cursor:pointer; width:100%; height:100%; }
.popup-sostituisci { font-size:12px; color:var(--text-muted); margin-bottom:8px; }
.popup-ruolo-btn:disabled { opacity:0.45; cursor:not-allowed; }
/* «Carico la mappa…» sopra lo skeleton esistente (P18 lavoro 6): sparisce
   con lui al primo paint del fondo (_nascondiSkeleton). */
.map-skeleton-msg { position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); background:rgba(255,255,255,0.92); color:var(--sea); font-size:13.5px; font-weight:600; padding:9px 16px; border-radius:20px; box-shadow:0 2px 10px rgba(10,79,110,0.2); animation:ragPulse 1.4s ease-in-out infinite; }
@keyframes ragPulse { 0%,100% { opacity:1; } 50% { opacity:0.55; } }
/* P18-bis: la guida di fase — un'istruzione sola, in alto, scritta da
   _aggiornaGuidaMappa. pointer-events:none: non è un controllo, non deve
   rubare tocchi alla mappa. */
.map-guida { position:absolute; top:14px; left:50%; transform:translateX(-50%); z-index:601; display:flex; align-items:center; gap:9px; background:var(--sea); color:white; border-radius:16px; padding:6px 12px; font-size:12.5px; font-weight:600; box-shadow:0 2px 10px rgba(10,79,110,0.3); white-space:nowrap; max-width:calc(100% - 24px); pointer-events:none; }
#map-guida-msg { overflow:hidden; text-overflow:ellipsis; }
/* Il bottone è l'unica parte cliccabile della guida (il resto non deve
   rubare tocchi alla mappa). */
#map-guida-cancella { pointer-events:auto; flex-shrink:0; border:none; background:rgba(255,255,255,0.2); color:white; border-radius:11px; padding:3px 9px; font-family:'DM Sans','DM Sans Fallback',sans-serif; font-size:11.5px; font-weight:600; cursor:pointer; }
#map-guida-cancella:hover { background:rgba(255,255,255,0.32); }
#map-guida-cancella[hidden] { display:none; }
.map-guida[hidden] { display:none; }
/* Sotto i 600px il centro-alto è conteso da «‹ Risultati» (a sinistra) e
   dallo zoom (a destra): la pillola si aggancia appena SOTTO quella riga,
   senza il vuoto che c'era a 64px. Su desktop lo spazio al centro c'è. */
@media (max-width:768px) {
  /* Al livello di + e − (richiesta del proprietario, 13/09/2026). Centrata
     non ci starebbe: a 390px la pillola larga arriverebbe SOTTO i tasti
     dello zoom. Si ancora quindi ai due bordi e si lascia 56px di colonna
     libera a destra per lo zoom; il testo accorcia da sé (#map-guida-msg ha
     già l'ellissi) invece di finire coperto. */
  /* `top` = --map-gap: la stessa distanza che la barra ha dal pavimento in
     basso. È la simmetria chiesta al collaudo, e vale finché i due numeri
     restano lo stesso numero. Niente più colonna riservata a destra: lo zoom
     è sceso nella barra. */
  .map-guida { top:var(--map-gap); left:var(--map-gap); right:var(--map-gap); transform:none; max-width:none; justify-content:center; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   SISTEMA DI SIMBOLI DELLA MAPPA
   Il gemello di tirreno_bus/static/js/spa/01b-marker.js: il JS decide le
   FORME, questo file i colori degli stati. Sostituisce, in questo stesso
   file, il blocco «P18: la mappa della scoperta», .tag-sali/.tag-scendi,
   .leaflet-marker-icon.marker-dim e le due voci di legenda incerta/
   ricostruita — dove ora restano solo i rimandi qui sotto.

   ⚠️ Lo stile attivo si sceglie in 01b-marker.js (const MARKER_STILE) e va
   rispecchiato con la stessa parola come classe sul <body> in mappa.html:
     <body class="mk-inchiostro ...">   |   mk-targhe   |   mk-velo
   Una riga in due posti: se divergono si vede subito, ed è voluto — meglio
   un disallineamento visibile di un default silenzioso. La classe la
   conserva `setAppState` in 01-core.js, che altrimenti la cancellerebbe al
   primo cambio di stato.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  --mk-ink: #0e2f3d;
  --mk-sea: #0a4f6e;
  --mk-sea-light: #1a7fa0;
  --mk-ambra: #f3a32b;
  --mk-arancio: #e8622a;
  --mk-spento: #8d9aa1;
  /* Partenza e destinazione: gli STESSI due colori dei marker A/B della
     scheda (MK_VERDE/MK_ROSSO in 01b-marker.js). Il colore non è mai l'unico
     segnale — partenza PIENA, destinazione ad ANELLO — perché verde e rosso
     sono la coppia che ~8% dei maschi non distingue. */
  --mk-verde: #1e7a4d;
  --mk-rosso: #c1272d;
  --mk-carta: #ffffff;
}

/* ── Comune: struttura comune a tutte le direzioni ────────────────────────
   Il riquadro dell'icona è 44px (area di tocco), il puntino ne occupa 22:
   il resto è trasparente. Prima il bersaglio era 16px. */
.mk-comune { position:relative; width:22px; height:22px; }
.mk-dot {
  display:block; width:22px; height:22px; border-radius:50%; box-sizing:border-box;
  /* Fondo di scorta: senza la classe di stile sul <body> il puntino resterebbe
     un riquadro trasparente. Ogni direzione lo sovrascrive. */
  background:var(--mk-sea-light); border:2.5px solid var(--mk-ink);
}
.mk-label { display:none;
  position:absolute; left:27px; top:50%; transform:translateY(-50%);
  white-space:nowrap; font-family:'DM Sans','DM Sans Fallback',sans-serif;
  font-size:14px; font-weight:700; pointer-events:auto;
}
.map-etichette-on .mk-comune:not(.mk-label-off) .mk-label { display:block; }
/* L'origine dice sempre il proprio nome, a qualunque zoom. */
/* Il nome di partenza e destinazione si legge sempre, a qualunque zoom. */
.mk-comune.mk-partenza .mk-label, .mk-comune.mk-destinazione .mk-label { display:block; }

/* ── A · Inchiostro ───────────────────────────────────────────────────────
   Contorno scuro al posto del bianco, nessuna ombra: l'anello fa da solo il
   lavoro di separazione, anche sopra una strada bianca. L'etichetta non ha
   pillola — ha un contorno di carta ottenuto con paint-order, che è più
   leggero di un fondo e non nasconde la mappa sotto. */
.mk-inchiostro .mk-dot { background:var(--mk-sea-light); border:2.5px solid var(--mk-ink); }
/* ⚠️ Il contorno di carta (-webkit-text-stroke) NON basta: staccava dalla
   TERRA, non dalle scritte che la basemap disegna già — «Domanico» nostro e
   «Vibo Valentia» di OpenFreeMap erano due testi scuri in grassetto sullo
   stesso fondo, e non si capiva quale dei due si potesse toccare. Il nome
   cliccabile porta quindi un fondo pieno: è la targhetta che dice «questo è
   un comando», non un'etichetta di mappa. */
.mk-inchiostro .mk-label {
  color:var(--mk-ink);
  background:rgba(255,255,255,0.95);
  border:1.5px solid rgba(14,47,61,0.22);
  border-radius:9px;
  padding:2px 7px;
  box-shadow:0 1px 3px rgba(14,47,61,0.18);
}
.mk-inchiostro .mk-partenza .mk-dot {
  background:var(--mk-verde); border-color:var(--mk-ink); border-width:3.5px;
  width:26px; height:26px; margin:-2px;
}
.mk-inchiostro .mk-destinazione .mk-dot {
  background:var(--mk-carta); border:7px solid var(--mk-rosso);
  width:26px; height:26px; margin:-2px;
}
.mk-inchiostro .mk-cambio .mk-dot { background:var(--mk-carta); border:5px solid var(--mk-sea-light); }
.mk-inchiostro .mk-noncollegato .mk-dot { background:var(--mk-spento); border-color:rgba(14,47,61,0.45); }
/* L'origine è una scelta già fatta: targhetta piena, come il suo puntino. */
.mk-inchiostro .mk-partenza .mk-label {
  background:var(--mk-verde); color:var(--mk-carta); border-color:var(--mk-ink);
}
.mk-inchiostro .mk-destinazione .mk-label {
  background:var(--mk-carta); color:var(--mk-rosso); border-color:var(--mk-rosso); border-width:2px;
}
.mk-inchiostro .mk-noncollegato .mk-label {
  color:#5b6771; background:rgba(255,255,255,0.82); border-color:rgba(14,47,61,0.12); box-shadow:none;
}

/* ── B · Targhe ───────────────────────────────────────────────────────────
   Il nome È il marker: il puntino resta solo come ancora minima sotto la
   soglia di zoom delle etichette. Il bordo tratteggiato dice «ci arrivi con
   un cambio» senza spendere un colore. */
.mk-targhe .mk-dot { background:var(--mk-sea-light); border:2px solid var(--mk-ink); width:14px; height:14px; }
.mk-targhe .mk-label {
  left:0; top:0; transform:none; position:relative;
  background:var(--mk-carta); border:1.5px solid rgba(14,47,61,0.55); border-radius:20px;
  padding:5px 11px; font-size:13.5px; color:var(--mk-ink);
  box-shadow:0 1px 4px rgba(14,47,61,0.16);
}
/* A etichette accese la targa sostituisce il puntino, non lo affianca. */
.mk-targhe .map-etichette-on .mk-comune:not(.mk-label-off) .mk-dot,
.map-etichette-on .mk-targhe .mk-comune:not(.mk-label-off) .mk-dot { display:none; }
.mk-targhe .mk-partenza .mk-label { border-width:2.5px; border-color:var(--mk-verde); }
.mk-targhe .mk-destinazione .mk-label { border-width:2.5px; border-color:var(--mk-rosso); }
.mk-targhe .mk-cambio .mk-label { border-style:dashed; }
.mk-targhe .mk-noncollegato .mk-label { color:#5b6771; border-color:rgba(14,47,61,0.25); }
.mk-targhe .mk-noncollegato .mk-dot { background:var(--mk-spento); border-color:rgba(14,47,61,0.3); }

/* ── C · Velo ─────────────────────────────────────────────────────────────
   Il contorno bianco resta, ma sotto c'è il velo (mkApplicaVelo in
   marker-mappa.js): a quel punto stacca davvero, e le ombre si vedono. */
.mk-velo .mk-dot {
  background:var(--mk-sea-light); border:3px solid var(--mk-carta);
  box-shadow:0 3px 9px rgba(14,47,61,0.4);
}
.mk-velo .mk-label {
  color:var(--mk-ink); background:var(--mk-carta); border-radius:6px; padding:3px 8px;
  font-size:13.5px; box-shadow:0 2px 7px rgba(14,47,61,0.22);
}
.mk-velo .mk-partenza .mk-dot { background:var(--mk-verde); width:28px; height:28px; margin:-3px; }
.mk-velo .mk-destinazione .mk-dot { background:var(--mk-carta); border:6px solid var(--mk-rosso); width:28px; height:28px; margin:-3px; }
.mk-velo .mk-cambio .mk-dot { background:var(--mk-carta); border:5px solid var(--mk-sea-light); }
.mk-velo .mk-noncollegato .mk-dot { background:var(--mk-spento); box-shadow:none; }
.mk-velo .mk-noncollegato .mk-label { color:#5b6771; }

/* ── Modalità modifica ────────────────────────────────────────────────────
   drawMarkersEdit disegna comuni e fermate TRASCINABILI: devono distinguersi
   da quelli normali, o il banner dice «trascina» sopra marker identici agli
   altri. Arancio del brand + matita, sopra qualunque direzione. */
.mk-comune.mk-edit .mk-dot {
  background:var(--mk-arancio); border-color:var(--mk-ink);
  display:flex; align-items:center; justify-content:center;
}
.mk-comune.mk-edit .mk-dot::after {
  content:'\270E'; font-size:12px; line-height:1; color:#fff;
}
.mk-velo .mk-comune.mk-edit .mk-dot { border-color:var(--mk-carta); }
.mk-targhe .mk-comune.mk-edit .mk-dot { display:flex !important; width:22px; height:22px; }
.mk-targhe .mk-comune.mk-edit .mk-label { border-color:var(--mk-arancio); }

/* ── Onestà della posizione ───────────────────────────────────────────────
   Il marker resta PIENO; il dubbio sta nel contorno. Vale per qualunque
   forma, perché agisce sul figlio diretto dell'icona. */
.leaflet-marker-icon.mk-ricostruita > div > div,
.leaflet-marker-icon.mk-ricostruita .mk-dot { border-style:dashed !important; }
.leaflet-marker-icon.mk-incerta { opacity:0.75; }

/* Attenuazione contestuale (dettaglio comune): 0.18 faceva sparire tutto su
   fondo chiaro. 0.4 arretra senza cancellare. */
.leaflet-marker-icon.marker-dim { opacity:0.4 !important; transition:opacity .25s; }

/* ── Targhette sali/scendi (tooltip permanenti Leaflet) ───────────────────
   Nella direzione B non servono: il testo è già dentro il marker. Si
   nascondono da CSS invece che da JS, così il codice che le crea resta uno. */
.tag-sali, .tag-scendi {
  background:var(--mk-ink) !important; color:#fff !important; border:none !important;
  border-radius:8px !important; padding:4px 10px !important;
  font:700 13px 'DM Sans','DM Sans Fallback',sans-serif !important;
  box-shadow:0 2px 6px rgba(14,47,61,0.3) !important; white-space:nowrap !important;
}
.tag-sali::before, .tag-scendi::before { display:none !important; }
.mk-targhe .tag-sali, .mk-targhe .tag-scendi { display:none !important; }

/* ── P17: targhette dei nodi del percorso ─────────────────────────────────
   `.rn-tip` è il tooltip permanente dei nodi che sopravvivono alla regola di
   densità: stessa grammatica della targhetta dei comuni (.mk-inchiostro
   .mk-label) — fondo pieno perché deve staccare anche dalle scritte, non
   solo dalla terra. La riga sotto (`.rn-sotto`) è il secondo pezzo del nome
   secondo la regola dei nomi (comune o toponimo); `.rn-ora` è l'orario del
   server. `.rn-tip-off` la spegne quando collide con una a priorità più
   alta: a sparire è il testo, il marker resta. */
.rn-tip {
  background:rgba(255,255,255,0.95) !important; color:var(--mk-ink) !important;
  border:1.5px solid rgba(14,47,61,0.22) !important; border-radius:9px !important;
  padding:2px 8px !important;
  font:600 12.5px 'DM Sans','DM Sans Fallback',sans-serif !important;
  box-shadow:0 1px 3px rgba(14,47,61,0.18) !important; white-space:nowrap !important;
}
.rn-tip::before { display:none !important; }
.rn-tip .rn-ora { font-variant-numeric:tabular-nums; }
.rn-sotto { display:block; font-weight:500; font-size:11px; opacity:0.75; }
/* Il troncamento è una faccenda di DISEGNO, non della regola dei nomi: la
   regola produce il nome pieno, qui lo si accorcia se non ci sta. 160px ≈
   metà di uno schermo da 375 meno il marker: la targhetta non esce mai
   dall'inquadratura per un nome lungo. Il nome intero resta nel popup. */
.rn-tip, .tag-sali, .tag-scendi { max-width:160px; }
.rn-tip, .rn-tip .rn-sotto, .tag-sali, .tag-scendi,
.tag-sali .rn-sotto, .tag-scendi .rn-sotto { overflow:hidden; text-overflow:ellipsis; }
.rn-tip-off { display:none !important; }
/* Le targhette di salita/discesa portano anche il nome del posto: la riga
   sotto eredita il fondo d'inchiostro, quindi resta bianca e arretra solo. */
.tag-sali .rn-sotto, .tag-scendi .rn-sotto { opacity:0.8; }

/* Le frecce del senso di marcia non sono bersagli: mai eventi, mai focus. */
.mk-freccia { pointer-events:none; }

/* ── Legenda: le voci devono restare identiche ai marker che spiegano ─────
   (stessa regola del file di oggi, aggiornata alle nuove forme) */
.legend-marker-incerta {
  width:20px; height:20px; border-radius:50%; border:2.5px dashed var(--mk-sea-light);
  background:rgba(26,127,160,0.28); box-sizing:border-box; flex-shrink:0;
}
.legend-marker-ricostruita {
  width:20px; height:20px; border-radius:50%; background:var(--mk-sea-light);
  border:2.5px dashed var(--mk-ink); box-sizing:border-box; flex-shrink:0;
}
.legend-marker-salita {
  width:20px; height:20px; border-radius:50%; background:var(--mk-sea);
  border:2.5px solid var(--mk-ink); box-sizing:border-box; flex-shrink:0;
}
.legend-marker-discesa {
  width:20px; height:20px; border-radius:50%; background:var(--mk-carta);
  border:4px solid var(--mk-sea); box-sizing:border-box; flex-shrink:0;
}
.legend-marker-cambio {
  width:16px; height:16px; background:var(--mk-ambra); border:2.5px solid var(--mk-ink);
  border-radius:3px; transform:rotate(45deg); box-sizing:border-box; flex-shrink:0; margin:2px;
}

/* ── Il velo ──────────────────────────────────────────────────────────────
   Il pannello lo crea mkApplicaVelo() e si chiama .mk-velo-STRATO: il nome
   non deve collidere con .mk-velo, che è lo stile sul <body>. Qui solo la
   transizione, perché accendere e spegnere il velo (es. un futuro tasto
   «mappa nitida») non deve essere uno scatto. */
.mk-velo-strato { transition:background .25s ease; }
