/* Archivo variabile, incluso nell'app: tutti i pesi usati dall'interfaccia,
   senza richieste a servizi esterni. Il font di sistema copre l'attesa. */
@font-face {
  font-family: "Archivo";
  src: url("/static/fonts/archivo-variable.woff?v=1") format("woff");
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
}
:root {
  --font-ui: "Archivo", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* Due temi: scuro (quello di sempre: lo schermo della Tesla è spesso in
   modalità scura) e chiaro, scelti in Impostazioni (Automatico segue il
   sistema; vedi theme.js, che mette data-theme su <html> prima del primo
   disegno). Il player (e lo schermo del guidatore), come lo schermo
   dell'ascolto (podcast e radio), resta sempre scuro: ha qui sotto i colori
   del tema scuro anche col tema chiaro.
   I controlli si usano col dito (almeno 44 px di altezza), ma restano
   compatti: con il browser a metà schermo (~630 px) lo spazio è poco. I
   comandi del player hanno misure loro, più grandi. */
:root, .player, .listen-screen {
  color-scheme: dark;
  --bg: #0e0f11;
  --surface: #1a1c20;
  --surface-2: #25282e;
  /* I pulsanti e gli avvisi, sopra le schede. */
  --raised: #25282e;
  --border: #30343b;
  /* Il bordo dei campi da scrivere: il campo si vede anche senza il
     segnaposto, di notte (3,9:1 sulla pagina, 3,5:1 sulle schede e nelle
     Impostazioni; prima 1,5 e 1,4). */
  --field-border: #6b727d;
  /* Il fondo sotto il dito o il mouse. */
  --hover: #30343b;
  --text: #eef0f3;
  /* Il testo secondario: margine per il riflesso del sole (8,6:1 sulle
     schede, 6,3:1 sul grigio sotto il dito; prima 6,5 e 4,8). */
  --muted: #b3b9c2;
  /* L'accento come segno: anelli del fuoco, bordi di una scelta, barre. */
  --accent: #1f6feb;
  /* L'accento pieno sotto il testo bianco (on-accent): pulsanti primari,
     schede e scelte fatte, play. Più scuro dell'accento: il bianco 5,5:1
     (su #1f6feb era 4,6), e il pieno resta a 3,1:1 sulle schede. */
  --accent-strong: #1c62db;
  /* Sotto il dito o il mouse il pieno di un pulsante si scurisce ancora (il
     bianco 6,6:1). */
  --accent-hover: #1756c4;
  /* Una scelta fatta sotto il dito o il mouse (la scheda in alto, In diretta
     / On demand, un giorno, un genere, un filtro) resta com'è: nell'auto
     (hover: hover) il tocco lascia :hover addosso fino al tocco dopo, e il
     pieno più scuro scenderebbe sotto 3:1 sulla pagina e sulle schede (2,9 e
     2,6; così resta 3,5 e 3,1). */
  --selected-hover: var(--accent-strong);
  --on-accent: #fff;
  /* Il testo secondario sul pieno (il nome di un filtro attivo): bianco
     tinto d'accento, 4,7:1 (5,7:1 nel tema chiaro). */
  --on-accent-soft: #e6edfb;
  /* L'accento come testo o segno su fondo scuro (6:1 su surface-2). */
  --accent-text: #6ea8ff;
  /* Il testo secondario su un fondo tinto d'accento (la qualità scelta nelle Impostazioni). */
  --tint-text: #c3d3ec;
  --danger: #e5484d;
  /* Il rosso come testo (errori, "Esci da tutti"): 5,6:1 su surface-2, 4,8:1
     sul grigio del pulsante sotto il dito. */
  --danger-text: #ff7479;
  --danger-hover: #b83236;
  /* LIVE: bianco sopra, 4,85:1. */
  --live: #cf3a3e;
  /* Un avviso che non è un errore: "Fino al 3 ott" su un contenuto che scade
     (8,9:1 sulle schede). */
  --warn-text: #f0b24a;
  /* La stella sulle miniature; star-ink sul fondo della pagina. */
  --star: #f5b82e;
  --star-ink: #f5b82e;
  /* I loghi dei canali e delle radio stanno su un riquadro blu, lo stesso nei
     due temi: blu profondo per quelli bianchi o a colori (il bianco 8,7:1,
     l'azzurro di HGTV 3,6:1, il verde di NOVE 4,7:1; le lettere trasparenti
     di "Rai" prendono il blu, come nel logo vero), azzurro per quelli scuri
     (Discovery 4,3:1, Deejay e m2o oltre 12:1), un po' spento di notte.
     logo-ink: il nome al posto di un logo che manca (8,7:1). */
  --logo-tile: #123f8c;
  --logo-ink: #eef0f3;
  --logo-light: #c6ddf6;
  /* La riga vuota di una barra (quanto è passato del programma). */
  --track: rgb(255 255 255 / .16);
  /* Il segno dell'app al posto di una miniatura o di una copertina che manca
     (mark.svg come maschera, al 50%): 2,5:1 sul grigio del riquadro. */
  --mark: #9aa1ab;
  --shadow-pop: 0 12px 40px rgb(0 0 0 / .5);
  --shadow-dialog: 0 24px 80px rgb(0 0 0 / .6);
  --backdrop: rgb(0 0 0 / .6);
  /* Gli angoli, a gradini: 6 i segni piccoli (loghi in piccolo, durate), 8
     i pulsanti senza bordo e i riquadri piccoli, 10, 12 (--radius) schede,
     pulsanti e campi, 14 le copertine grandi. Chi contiene un altro
     arrotondato (le scelte a interruttore) ha il suo più il margine. */
  --radius-xs: 6px;
  --radius-s: 8px;
  --radius-m: 10px;
  --radius: 12px;
  --radius-l: 14px;
  --tap: 48px;
  /* Grandezza delle schede (i pulsanti − +, vedi makeSizer in app.js): la
     larghezza minima di una colonna. A 1255 px 6, 5, 4, 3 o 2 colonne; a
     metà schermo 3, 2 o 1; sul telefono 2 o 1 (le più piccole: sempre due). */
  --card-min: 250px;
  --grid-gap: 16px;
  /* I colori dei profili (vedi profiles.COLORS e .avatar): gli stessi nei due
     temi, col bianco sopra almeno a 5:1 (blu 5,5, verde 5,4, viola 5,7, rosso
     5,4, arancio 5,05, acqua 5,6, rosa 6,0, grigio 6,3). */
  --profile-blu: #1c62db;
  --profile-verde: #1d7a3a;
  --profile-viola: #7c3aed;
  --profile-rosso: #c62f35;
  --profile-arancio: #b35309;
  --profile-acqua: #0d7377;
  --profile-rosa: #be185d;
  --profile-grigio: #556170;
}
/* La scala dei testi: un gradino per ruolo, in rem. La leva è la grandezza
   della radice (<html>): 16 px di serie, 18 sugli schermi touch larghi (qui
   sotto). I testi da leggere crescono di 2 px (meta 16, controlli 17, testo
   18, nomi 19: a 75 cm dallo schermo dell'auto sono loro a non leggersi), i
   titoli di 1 (sono già grandi): la gerarchia resta, e nel primo schermo
   resta quello che c'era.
   Restano in px, con misure loro: le schede in alto e le fonti di On demand
   (righe coi nomi misurati, vedi "barra in alto: le misure"), i loghi scritti
   dei canali (.tv-mark: disegni sui riquadri), il
   player e gli schermi del guidatore e dell'ascolto (sempre scuri, già
   grandi: 15-30 px, tarati sull'altezza della finestra), il <select>
   invisibile delle pillole (16: iOS non ingrandisce). Di quegli schermi
   seguono la leva solo i testi secondari (--fs-stage-meta): il tempo, lo
   stato della guida, «Mostra video», la velocità, «Podcast». */
:root {
  --fs-meta: calc(1rem - 2px);        /* 14 (16): orari, conteggi, autori, durate, suggerimenti */
  --fs-ui: calc(1rem - 1px);          /* 15 (17): pulsanti piccoli, pillole, scelte, avvisi */
  --fs-body: 1rem;                    /* 16 (18): il testo, i titoli delle schede, i pulsanti */
  --fs-lead: calc(1rem + 1px);        /* 17 (19): nomi dei canali, titoletti dei blocchi */
  --fs-subhead: calc(.5rem + 10px);   /* 18 (19): nomi dei gruppi, titoli di una sottopagina */
  --fs-heading: calc(.5rem + 11px);   /* 19 (20): titoli delle sezioni */
  --fs-title: calc(.5rem + 12px);     /* 20 (21): titoli dei dialoghi e degli stati vuoti */
  --fs-title-l: calc(.5rem + 14px);   /* 22 (23): "Chi guarda?" */
  --fs-display: calc(.5rem + 16px);   /* 24 (25): il titolo di un podcast, delle pagine */
  /* 15 (18): i testi secondari degli schermi del guidatore e dell'ascolto
     (tempo, stato della guida, pulsanti della barra, «Podcast»). Nell'auto
     sono quelli da leggere di sfuggita, a 75 cm: crescono di 3 px, non di 2. */
  --fs-stage-meta: calc(1.5rem - 9px);
}
/* L'auto (773×601 e 773×575, 1255×773, 627×773 a metà schermo) e i tablet:
   touch e larghi almeno 600 px. Il telefono in verticale resta a 16 (in
   orizzontale è largo come un tablet, e cresce anche lui). Nessuna condizione
   sull'altezza: se la tastiera dell'auto accorcia la finestra, il testo non
   deve cambiare mentre si scrive. Touch lo dice data-touch (theme.js, da
   navigator.maxTouchPoints), non (pointer: coarse): l'auto dal 2026.26
   risponde «pointer: fine» come un computer col mouse. */
@media (min-width: 600px) {
  :root[data-touch] { font-size: 112.5%; }
}
:root[data-cards="0"] { --card-min: min(170px, calc(50% - var(--grid-gap) / 2)); }
:root[data-cards="1"] { --card-min: 210px; }
:root[data-cards="3"] { --card-min: 330px; }
:root[data-cards="4"] { --card-min: 440px; }

/* Tema chiaro: fondo grigio chiarissimo, schede e pulsanti bianchi. Testi
   almeno 4,5:1 su tutti i fondi (muted 6,9:1 sul bianco, 5,5:1 sul grigio
   sotto il dito; accent-text 5,5:1 e tint-text 5,8:1 anche sui fondi tinti),
   bordi dei campi 3,3:1 sul fondo, accento pieno 6,6:1 col bianco sopra (di
   giorno c'è il sole: più margine che nel tema scuro), l'accento come anello
   del fuoco 4,2:1 sul fondo. */
:root[data-theme="light"] {
  color-scheme: light;
  --bg: #f3f4f6;
  --surface: #ffffff;
  --surface-2: #e8ebef;
  --raised: #ffffff;
  --border: #ccd2da;
  --field-border: #808894;
  --hover: #e3e7ec;
  --text: #16191d;
  --muted: #535b67;
  --accent: #1f6feb;
  --accent-strong: #1557c0;
  --accent-hover: #1349a6;
  /* Sul chiaro più scuro vuol dire più contrasto (7,5:1 sulla pagina): la
     scelta fatta si scurisce anche lei sotto il dito. */
  --selected-hover: var(--accent-hover);
  --accent-text: #0b57c8;
  --tint-text: #1b4a95;
  --danger: #cf222e;
  --danger-text: #b91c27;
  --danger-hover: #a8282c;
  --live: #cf3a3e;
  --warn-text: #945600;
  --star: #f5b82e;
  --star-ink: #a16207;
  --logo-tile: #123f8c;
  --logo-ink: #eef0f3;
  --logo-light: #d3e7fd;
  --track: rgb(22 25 29 / .14);
  /* Il segno al posto della miniatura: sul chiaro più scuro, per la stessa
     distanza dal fondo che ha nel tema scuro (2,4:1; col grigio di prima 1,4). */
  --mark: #3d444e;
  --shadow-pop: 0 10px 30px rgb(22 25 29 / .16);
  --shadow-dialog: 0 24px 64px rgb(22 25 29 / .22);
  --backdrop: rgb(22 25 29 / .4);
}
/* Più contrasto, chiesto dal sistema: i bordi di schede e pulsanti si vedono
   da soli (almeno 3:1 sulla pagina e sulle schede), quelli dei campi di più,
   il testo secondario quasi come il testo. Anche nel player e nell'ascolto
   (sempre scuri: i loro colori sono quelli del tema scuro). */
@media (prefers-contrast: more) {
  :root, .player, .listen-screen {
    --border: #6b727d;
    --field-border: #8a919c;
    --muted: #c9ced6;
  }
  :root[data-theme="light"] {
    --border: #808894;
    --field-border: #5f6773;
    --muted: #3d444e;
  }
}
/* Le zone sempre scure (il player, lo schermo del guidatore, lo schermo
   dell'ascolto): i loro colori, gli stessi nei due temi. Lì dentro valgono
   anche i token del tema scuro qui sopra (testo, secondario, superfici,
   bordi, accento). Il nero del video e il quasi nero degli schermi quieti;
   l'inchiostro bianco, pieno o velato; i veli neri che scuriscono l'immagine
   sotto titoli, comandi e avvisi, a gradini. */
:root {
  --stage: #000;
  --stage-quiet: #0a0b0d;
  --stage-menu: rgb(22 24 28 / .97);   /* i menu della barra */
  --stage-toast: rgb(20 22 26 / .92);  /* gli avvisi sopra il video */
  --on-stage: #fff;
  --on-stage-muted: rgb(255 255 255 / .85);  /* le frasi sotto un titolo, i dati tecnici */
  --on-stage-soft: rgb(255 255 255 / .8);    /* la parte leggera di un nome ("· cambia", "480p") */
  --on-stage-faint: rgb(255 255 255 / .62);  /* titoletti e note dei menu */
  --on-stage-off: rgb(255 255 255 / .3);     /* una scelta spenta */
  /* Il titolo di un errore: rosso chiaro, 7:1 sul nero. */
  --stage-danger: #ff8589;
  /* Bordi di pulsanti, menu e avvisi; le righe vuote (caricamento, rotellina). */
  --stage-line: rgb(255 255 255 / .16);
  /* Una voce di menu sotto il mouse o scelta, la riga che separa. */
  --stage-veil: rgb(255 255 255 / .12);
  /* Il pallino spento di "Torna in diretta" (LIVE ce l'ha rosso). */
  --stage-dot: rgb(255 255 255 / .55);
  /* La parte ancora da vedere della barra del tempo (più tenue nell'ascolto). */
  --stage-seek: rgb(255 255 255 / .32);
  --scrim-light: rgb(0 0 0 / .45);
  --scrim-dim: rgb(0 0 0 / .5);      /* l'immagine sotto i comandi, i pulsanti tondi */
  --scrim: rgb(0 0 0 / .55);         /* i pulsanti della barra */
  --scrim-mid: rgb(0 0 0 / .6);
  --scrim-strong: rgb(0 0 0 / .75);  /* sotto il mouse, sotto i sottotitoli */
  --scrim-press: rgb(0 0 0 / .8);    /* sotto il dito */
  --scrim-deep: rgb(0 0 0 / .85);    /* dietro titolo e barra in basso */
}
.listen-screen { --stage-seek: rgb(255 255 255 / .22); }
/* Le zone sicure dell'iPhone: la tacca o la Dynamic Island ai lati col
   telefono in orizzontale, la barretta Home in basso (in alto la barra di
   stato è nera, fuori dalla pagina: 0). index.html chiede tutto lo schermo
   (viewport-fit=cover): i fondi arrivano ai bordi, e barra in alto, pagina,
   player, schermo dell'ascolto, barra in basso, avvisi e fogli tengono testi e
   pulsanti qui dentro, con max() sui loro margini o sommandole alle distanze
   dal bordo. Dove non ci sono (computer, auto, Android nel browser, le altre
   pagine) valgono 0 e non cambia niente. Registrate come lunghezze: app.js le
   legge in px (i sottotitoli, vedi subsPlace). */
@property --safe-top { syntax: "<length>"; inherits: true; initial-value: 0px; }
@property --safe-right { syntax: "<length>"; inherits: true; initial-value: 0px; }
@property --safe-bottom { syntax: "<length>"; inherits: true; initial-value: 0px; }
@property --safe-left { syntax: "<length>"; inherits: true; initial-value: 0px; }
:root {
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
}
/* Il logo è chiaro (#eef0f3): sul fondo chiaro diventa scuro. */
:root[data-theme="light"] :is(.home img, .login h1 img, .privacy h1 img) { filter: invert(.9) hue-rotate(180deg); }

::selection { background: color-mix(in srgb, var(--accent) 34%, transparent); }

* { box-sizing: border-box; }

html, body { margin: 0; }

body {
  background: var(--bg);
  color: var(--text);
  font: var(--fs-body)/1.4 var(--font-ui);
  -webkit-tap-highlight-color: transparent;
}

h1, h2 { margin: 0; font-weight: 650; letter-spacing: -.015em; }

[hidden] { display: none !important; }

/* --- pulsanti e campi --------------------------------------------------- */

.btn {
  min-height: var(--tap);
  padding: 0 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--raised);
  color: var(--text);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  white-space: nowrap;
}
.btn:disabled { opacity: .5; cursor: default; }
.btn-primary { background: var(--accent-strong); border-color: var(--accent-strong); color: var(--on-accent); }
.btn-danger { color: var(--danger-text); }
/* L'azione che non si annulla, nella sua conferma: piena (bianco 4,85:1). */
.btn-danger-solid { background: var(--live); border-color: var(--live); color: #fff; }
.btn-small { min-height: 44px; padding: 0 14px; font-size: var(--fs-ui); }
.btn:active:not(:disabled) { background: var(--hover); }
.btn-primary:active:not(:disabled) { background: var(--accent-hover); }
.btn-danger-solid:active:not(:disabled) { background: var(--danger-hover); }
/* Sotto il dito niente :hover (resterebbe acceso dopo il tocco): solo col mouse. */
@media (hover: hover) {
  .btn:hover:not(:disabled) { background: var(--hover); }
  .btn-primary:hover:not(:disabled) { background: var(--accent-hover); }
  .btn-danger-solid:hover:not(:disabled) { background: var(--danger-hover); }
}

input, select {
  min-height: var(--tap);
  padding: 0 14px;
  border: 1px solid var(--field-border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  width: 100%;
}
input:focus-visible, select:focus-visible, .btn:focus-visible, .home:focus-visible,
.view-tab:focus-visible, .player-btn:focus-visible, .who-choice:focus-visible, .notice-action:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}
/* Il segnaposto del browser (#757575) non arriva a 4,5:1 sul fondo dei campi. */
::placeholder { color: var(--muted); opacity: 1; }

/* --- login -------------------------------------------------------------- */

.login-body { min-height: 100vh; display: grid; place-items: center; padding: 16px; }
.login {
  width: min(420px, 100%);
  display: grid;
  gap: 20px;
  justify-items: center;
}
.login h1 { margin-bottom: 20px; }
.login form { width: 100%; display: grid; gap: 12px; }
.login label { color: var(--muted); font-size: var(--fs-body); }
.error { color: var(--danger-text); margin: 0; }
/* "Mostra password": sotto il campo, tutta la riga si tocca. */
.login-show { justify-self: start; }

/* --- pagina che non c'è (404, vedi not_found in app/main.py) ------------- */

.lost { text-align: center; }
.lost h1 { margin-bottom: 4px; }
.lost h2 { font-size: var(--fs-title); }
.lost p { margin: 0; color: var(--muted); max-width: 36ch; }
.lost .btn { text-decoration: none; }

/* --- informativa privacy ---------------------------------------------- */

.privacy { width: min(720px, 100%); line-height: 1.55; }
.privacy h1 { margin-bottom: 24px; }
.privacy h2 { font-size: var(--fs-display); margin-bottom: 8px; }
.privacy h3 { margin: 28px 0 8px; font-size: var(--fs-title); }
.privacy p, .privacy li { color: var(--text); }
.privacy a { color: var(--accent-text); }
.privacy code { font-size: var(--fs-ui); }

/* --- diagnostica (/static/diagnostica.html) ------------------------------ */

.diag-page { max-width: 900px; display: grid; gap: 20px; }
.diag-page h2 { font-size: var(--fs-display); }
.diag-page code { font-size: var(--fs-ui); }
.diag-back { margin-left: auto; }
.diag-where { display: grid; gap: 16px; margin: 0; padding: 0; border: 0; min-width: 0; }
.diag-geo { display: grid; gap: 16px; }
.diag-geo h2 { font-size: var(--fs-title); }
.diag-where legend { padding: 0; margin-bottom: 8px; font-weight: 650; }
.views.diag-choice {
  display: grid;
  /* 200px: "Parcheggiata" ci sta intera; al telefono una colonna sola. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
  margin: 0;
}
.diag-choice .view-tab { min-width: 0; min-height: 48px; padding: 8px 16px; line-height: 1.2; }
/* Piccolo: basta a vedere se il <video> del browser parte (in movimento non c'è). */
.diag-video { width: 128px; aspect-ratio: 16 / 9; background: var(--stage); border-radius: var(--radius-s); }
/* Il livello del microfono nella prova «Microfono e voce». */
.diag-level { width: min(100%, 360px); height: 20px; }
.diag-summary { display: grid; grid-template-columns: max-content 1fr; gap: 10px 20px; margin: 0; }
.diag-summary dt { color: var(--muted); }
.diag-summary dd { margin: 0; overflow-wrap: anywhere; }
.diag-raw pre { overflow: auto; max-height: 60vh; padding: 12px; background: var(--surface); border-radius: var(--radius); font-size: var(--fs-meta); }
/* Il fotogramma disegnato con Lanczos: grande come la finestra (il costo è
   quello a tutto schermo), ma sopra il bordo in alto, fuori dallo schermo. */
.diag-sink-stage {
  position: fixed;
  inset: 0;
  z-index: -1;
  transform: translateY(calc(-100% - 64px));
  pointer-events: none;
  background: var(--stage);
}

/* --- statistiche (/static/statistiche.html) ------------------------------ */
/* Tabelle semplici sulle schede (il numero allineato a destra, in colonna),
   la linea dei 14 giorni accanto a ogni misura e, per fonti, decoder ed
   errori, barre orizzontali. Pensata per 773 px: lì le tabelle stanno
   intere; più stretto (il telefono) scorrono di lato dentro il loro riquadro,
   con la prima colonna ferma. */
.stats-page { max-width: 980px; display: grid; gap: 28px; }
.stats-head { display: grid; gap: 8px; }
.stats-head h2 { font-size: var(--fs-display); }
.stats-head .settings-hint { max-width: 72ch; }
.status-row.stats-status-row { margin: -12px 0 0; }
.stats-block { display: grid; gap: 12px; min-width: 0; }
.stats-block > * { min-width: 0; }
.stats-title { margin: 0; font-size: var(--fs-heading); font-weight: 650; }
.stats-subtitle { margin: 0; font-size: var(--fs-subhead); font-weight: 650; }
.stats-block > .stats-subtitle { margin-top: 12px; }
.stats-block > .settings-hint { margin-top: -6px; }
.stats-detail-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; }
.views.stats-pick { margin: 0; min-width: 0; max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.stats-pick::-webkit-scrollbar { display: none; }
.stats-pick .view-tab { flex: none; padding: 0 16px; font-size: var(--fs-ui); white-space: nowrap; }
.stats-scroll {
  overflow-x: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.stats-table {
  width: 100%;
  /* Separate (a spazio 0), non collapse: i bordi sono delle celle, anche di
     quella ferma a sinistra quando la tabella scorre. */
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--fs-ui);
  font-variant-numeric: tabular-nums;
}
.stats-table :is(th, td) { padding: 10px 12px; text-align: left; vertical-align: middle; white-space: nowrap; }
.stats-table :is(th, td):first-child { padding-left: 14px; }
.stats-table :is(th, td):last-child { padding-right: 14px; }
/* I titoli delle colonne vanno a capo (Ripro-duzioni col trattino morbido):
   a 773 px le tabelle stanno intere, i numeri restano su una riga. */
.stats-table thead th {
  color: var(--muted);
  font-size: var(--fs-meta);
  font-weight: 600;
  line-height: 1.25;
  vertical-align: bottom;
  white-space: normal;
  border-bottom: 1px solid var(--border);
}
.stats-table tbody th { font-weight: 600; }
.stats-table tbody tr + tr :is(th, td) { border-top: 1px solid var(--border); }
.stats-table .num { text-align: right; }
.stats-table .is-none { color: var(--muted); }
.stats-table tr.is-total :is(th, td) { background: var(--surface-2); }
.th-note { display: block; color: var(--muted); font-size: var(--fs-meta); font-weight: 500; }
/* La prima colonna resta ferma quando la tabella scorre di lato. */
.stats-table :is(th, td):first-child { position: sticky; left: 0; z-index: 1; background: var(--surface); }
.stats-table tr.is-total :is(th, td):first-child { background: var(--surface-2); }
.stats-trend .spark-col { width: 1%; padding-block: 6px; }
.stats-trend thead .spark-col { padding-block: 10px; }
/* La linea dei 14 giorni: una serie sola, col colore del testo secondario;
   oggi in accento. */
.spark { display: block; overflow: visible; }
.spark-base { stroke: var(--border); stroke-width: 1; }
.spark-line { fill: none; stroke: var(--muted); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.spark-dot { fill: var(--muted); }
.spark-now { fill: var(--accent-text); stroke: var(--surface); stroke-width: 2; }
.spark-hit { fill: transparent; }
/* Un giorno della tabella: si tocca per vedere le sue fonti, i decoder e gli errori. */
.stats-day {
  min-height: 44px;
  padding: 0 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  background: var(--raised);
  color: var(--text);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.stats-day[aria-expanded="true"] { background: var(--accent-strong); border-color: var(--accent-strong); color: var(--on-accent); }
.stats-day:active { background: var(--hover); }
.stats-day[aria-expanded="true"]:active { background: var(--accent-hover); }
@media (hover: hover) {
  .stats-day:hover { background: var(--hover); }
  .stats-day[aria-expanded="true"]:hover { background: var(--selected-hover); }
}
.stats-day:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.stats-days tr.is-picked :is(th, td) { background: color-mix(in srgb, var(--accent) 12%, var(--surface)); }
.stats-days :is(th, td):first-child { padding-block: 6px; }
/* Sotto il giorno aperto le sue fonti, i decoder e gli errori: larghi quanto
   il riquadro (non quanto la tabella, che sul telefono scorre di lato). */
.stats-scroll { container-type: inline-size; }
.stats-days tr.stats-day-detail td { position: static; padding: 4px 14px 16px; white-space: normal; }
.stats-days tr.is-picked + tr.stats-day-detail td { border-top: 0; }
.stats-day-detail .stats-facts { position: sticky; left: 14px; width: calc(100cqw - 28px); }
.stats-days :is(th, td):not(:first-child, :last-child) { padding-inline: 10px; }
/* Fonti, decoder ed errori: il nome, la barra (rispetto al più grande), quante. */
.stats-breakdown { display: grid; gap: 12px; padding: 16px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.stats-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 14px 24px; margin: 0; }
.stats-facts dt { color: var(--muted); font-size: var(--fs-ui); padding-top: 2px; }
.stats-facts dd { margin: 0; min-width: 0; }
.stats-facts dd > .is-none { color: var(--muted); font-size: var(--fs-ui); }
.stats-bars { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.stats-bars li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(64px, 30%) 4ch;
  align-items: center;
  gap: 12px;
  font-size: var(--fs-ui);
}
.stats-bar-name { overflow-wrap: anywhere; }
.stats-bar { height: 8px; border-radius: 4px; background: var(--track); overflow: hidden; }
.stats-bar-fill { display: block; height: 100%; border-radius: 4px; background: var(--accent); }
.stats-bar-n { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* Il telefono: meno spazio dentro le celle, i nomi sopra le barre. */
@media (max-width: 600px) {
  .stats-table :is(th, td) { padding: 8px 10px; }
  .stats-pick .view-tab { padding: 0 12px; }
  .stats-breakdown { padding: 12px; }
  .stats-facts { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .stats-facts dd { margin-bottom: 10px; }
}
/* Sul telefono le tabelle larghe scorrono comunque: i titoli su una riga (più
   il loro secondo rigo), non spezzati in quattro. */
@media (max-width: 480px) {
  .stats-table:not(.stats-trend) thead th { white-space: nowrap; }
}

/* --- barra in alto ------------------------------------------------------ */
/* Una riga sola a tutta larghezza: logo, schede, ricerca, tema e menu. Più
   stretta (vedi in fondo) la ricerca va su una riga sua. Le misure a ogni
   larghezza sono in fondo ("barra in alto: le misure"): la barra è un
   contenitore, e gli spazi delle schede si calcolano sulla sua larghezza. */

.topbar {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 12px;
  /* Ai lati --bar-pad (più stretto sotto, vedi "barra in alto: le misure"),
     o la zona sicura se è di più (l'iPhone in orizzontale). */
  --bar-pad: 16px;
  padding: max(8px, var(--safe-top)) max(var(--bar-pad), var(--safe-right)) 8px max(var(--bar-pad), var(--safe-left));
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
  container-type: inline-size;
  /* Lo spazio fra le schede in alto (vedi "barra in alto: le misure"). */
  --tab-gap: 8px;
}
.topbar h1 { display: flex; flex: none; }
/* Il logo ricarica la pagina: si torna ai Preferiti, ricerca chiusa. */
.home { display: flex; align-items: center; min-height: 44px; border-radius: var(--radius-s); }
.home img, .login h1 img { display: block; }
.home img { width: 170px; height: auto; }
.add-form { flex: 1; display: flex; gap: 8px; max-width: 640px; margin-left: auto; }
/* La ricerca c'è solo nella sua scheda: altrove tema e menu vanno a destra. */
.add-form[hidden] + .top-actions { margin-left: auto; }
.add-form input { min-height: 44px; min-width: 0; }
.add-form .btn { min-height: 44px; padding: 0 16px; }
/* Preferiti / YouTube / TV / Ascolta: nella barra in alto, quindi sempre visibili.
   Schede a pillola (44 px, anche di larghezza: "TV" da solo è corto), quella
   scelta piena, staccate di 8 px (4 sul telefono). */
.views.top-views { margin: 0; flex: none; padding: 0; gap: var(--tab-gap); background: none; border: 0; border-radius: 0; }
.top-views .view-tab { min-height: 44px; min-width: 44px; padding: 0 14px; white-space: nowrap; font-size: 16px; }

/* Il tema e il menu, vicini. L'interruttore (vedi app.js) mostra il simbolo
   del tema a cui si passa: il sole sul tema scuro, la luna sul chiaro; con
   tanto spazio, e senza la ricerca nella barra, anche il nome ("Tema chiaro").
   Fino a 560 px lascia il posto alle schede e sta nel menu ⋯, col nome. */
.top-actions { flex: none; display: flex; align-items: center; gap: 4px; }
.top-actions > .theme-toggle { min-height: 44px; min-width: 44px; padding: 0 10px; }
.menu-panel .theme-toggle { display: none; }
.menu-panel .theme-toggle svg { width: 20px; height: 20px; }
.menu-panel .theme-label { display: inline; }
.theme-toggle svg { flex: none; width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.theme-label { display: none; }
.theme-toggle .icon-moon, :root[data-theme="light"] .theme-toggle .icon-sun,
:root[data-theme="light"] .theme-label .to-light, :root:not([data-theme="light"]) .theme-label .to-dark { display: none; }
:root[data-theme="light"] .theme-toggle .icon-moon { display: block; }
@media (min-width: 1001px) {
  .add-form[hidden] + .top-actions > .theme-toggle .theme-label { display: inline; }
  .add-form[hidden] + .top-actions > .theme-toggle { padding: 0 16px 0 13px; }
}
/* Toccato: il simbolo nuovo entra girando, e si ferma morbido. */
@keyframes theme-turn { from { opacity: 0; transform: rotate(-90deg) scale(.6); } }
.theme-toggle.is-turning svg { animation: theme-turn .45s cubic-bezier(.16, 1, .3, 1); }
@media (prefers-reduced-motion: reduce) {
  .theme-toggle.is-turning svg { animation: none; }
}

.menu { position: relative; flex: none; }
.menu summary { position: relative; list-style: none; min-height: 44px; min-width: 44px; padding: 0 10px; font-size: 22px; }
.menu summary::-webkit-details-marker { display: none; }
.menu-panel {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  display: grid;
  gap: 6px;
  padding: 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-pop);
}
/* Largo quanto il pulsante più largo, fino al massimo; una colonna che non
   va oltre il pannello: un pulsante lungo (il nome di un profilo) si
   accorcia coi puntini, non spinge fuori gli altri. */
.menu-panel { width: max-content; max-width: min(340px, calc(100vw - 24px)); grid-template-columns: minmax(0, 1fr); }
/* Più alto dello schermo (l'iPhone in orizzontale, 390 px; una conferma
   aperta) scorre dentro di sé: la barra in alto resta ferma, scorrere la
   pagina non lo porterebbe. Sopra la barra fin sotto il pulsante ⋯ (il suo
   margine in alto e 44), lo stacco di 6; sotto 12. */
.menu-panel {
  max-height: calc(100dvh - 62px - max(8px, var(--safe-top)) - var(--safe-bottom));
  overflow-y: auto;
  overscroll-behavior: contain;
}
.menu-panel .btn { min-height: 44px; font-size: var(--fs-ui); justify-content: flex-start; }

/* Conferma dentro la pagina (al posto di confirm()): la domanda, "Annulla" e
   l'azione, dove stava il pulsante (menu ⋯, "Scollega"). */
.confirm { display: grid; gap: 10px; }
.confirm-text { margin: 0; font-size: var(--fs-ui); line-height: 1.35; }
.confirm-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
.menu-panel:has(> .confirm:not([hidden])) { width: min(320px, calc(100vw - 24px)); }
.menu-panel .confirm { padding: 6px 4px 2px; }
.menu-panel .confirm .btn { justify-content: center; }

/* Avviso in basso, sopra la pagina (anche scorrendo); con "Annulla" se serve.
   Le distanze dal fondo (anche sopra la barra dell'ascolto) sono dalla zona
   sicura: sopra la barretta Home dell'iPhone. */
.notice {
  position: fixed;
  left: 50%;
  bottom: calc(16px + var(--safe-bottom));
  z-index: 6;
  transform: translateX(-50%);
  width: max-content;
  max-width: min(560px, calc(100vw - 24px - var(--safe-left) - var(--safe-right)));
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 8px 8px 8px 16px;
  min-height: 48px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--raised);
  box-shadow: var(--shadow-pop);
  font-size: var(--fs-ui);
}
.notice-text { flex: 1; padding: 4px 8px 4px 0; }
.notice-error { color: var(--danger-text); }
.notice-action {
  flex: none;
  min-height: 44px;
  padding: 0 12px;
  border: 0;
  border-radius: var(--radius-s);
  background: none;
  color: var(--accent-text);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}
.notice-action:active { background: var(--hover); }
@media (hover: hover) {
  .notice-action:hover { background: var(--hover); }
}

/* --- griglia ------------------------------------------------------------ */

/* Ai lati e in fondo almeno la zona sicura (l'iPhone in orizzontale, la
   barretta Home): l'ultima riga si porta sopra la barretta. */
main {
  --main-pad: 16px;
  padding: var(--main-pad) max(var(--main-pad), var(--safe-right)) max(var(--main-pad), var(--safe-bottom)) max(var(--main-pad), var(--safe-left));
}

/* Uno stato vuoto, uguale ovunque: il titolo (cosa manca), il perché o cosa
   fare, e la strada dopo se c'è (Preferiti, una cartella di On demand senza
   niente, i podcast Iscritti). Dentro un blocco è allineato a sinistra; da
   solo nella pagina (.is-page: Preferiti vuoti) sta al centro, col segno sopra
   (la stella), il titolo più grande e, sotto, una nota (il bot Telegram). */
.empty-state { display: grid; justify-items: start; gap: 6px; max-width: 60ch; color: var(--muted); }
.empty-state p { margin: 0; }
.empty-state .empty-state-title { color: var(--text); font-size: var(--fs-subhead); font-weight: 650; }
.empty-state-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 8px; }
.empty-state-actions:not(:has(> :not([hidden]))) { display: none; }
.empty-state.is-page { justify-items: center; gap: 8px; max-width: 44ch; margin: 8vh auto; text-align: center; }
.empty-state.is-page .empty-state-title { font-size: var(--fs-title); }
.empty-state.is-page .empty-state-actions { justify-content: center; margin-top: 14px; }
.empty-state .empty-state-note { margin-top: 18px; font-size: var(--fs-ui); }
.empty-star { width: 48px; height: 48px; margin-bottom: 4px; fill: none; stroke: var(--star-ink); stroke-width: 1.5; stroke-linejoin: round; }
/* Con «Continua a guardare» sopra, più vicino. */
.continue:not([hidden]) ~ .empty-state.is-page { margin-top: 24px; }

/* «Continua a guardare»: una riga che scorre di lato, con un pezzo della
   scheda dopo che si vede (c'è altro). Tante colonne quante la griglia sotto
   (--cols e --peek li mette app.js, vedi layoutContinue: dipendono dalla
   grandezza scelta delle schede), un quarto di colonna in meno per il pezzo
   in più; con una colonna sola una scheda e poco più. Il padding tiene dentro
   l'anello del fuoco, che lo scorrimento taglierebbe. */
.continue { margin-bottom: 20px; container-type: inline-size; }
.continue-row {
  --cols: 1;
  --peek: .15;
  --gap: var(--grid-gap);
  list-style: none;
  margin: -6px;
  padding: 6px 6px 12px;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: calc((100cqi - var(--cols) * var(--gap)) / (var(--cols) + var(--peek)));
  gap: var(--gap);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  overflow-anchor: none; /* una scheda nuova in cima si vede, non spinge le altre fuori */
  scroll-snap-type: x mandatory;
  scroll-padding: 6px;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
.continue-row > li { scroll-snap-align: start; }
.is-continue .resume { height: 5px; }
/* In fondo alla scheda: quanto manca e "Rimuovi". */
.card-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  column-gap: 8px;
  margin-top: auto;
  padding: 0 4px 4px 0;
}
/* Nelle schede strette (le più piccole) "Ancora 1 h 24 min" non si spezza
   parola per parola accanto a "Rimuovi": "Rimuovi" va sotto, a destra. */
.is-continue .card-foot .result-stats { flex: 0 1 auto; min-width: 0; margin: 0; padding-right: 0; line-height: 1.25; }
.card-remove {
  flex: none;
  margin-left: auto;
  min-height: 44px;
  padding: 0 10px;
  border: 0;
  border-radius: var(--radius-s);
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: var(--fs-ui);
  font-weight: 600;
  cursor: pointer;
}
.card-remove:active { background: var(--hover); color: var(--text); }
@media (hover: hover) {
  .card-remove:hover { background: var(--hover); color: var(--text); }
}
.card-remove:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }

/* Colonne larghe almeno --card-min (vedi in cima): di serie a tutta larghezza
   (1255 px nell'auto) quattro colonne, a metà schermo due, sul telefono una. */
.grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--card-min)), 1fr));
  gap: var(--grid-gap);
}

.card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* Miniatura e titolo: un pulsante solo, che fa partire il video (o apre la playlist). */
.card-open, .card-play {
  all: unset;
  display: grid;
  gap: 4px;
  cursor: pointer;
}
.card-open { padding-bottom: 10px; }
/* Il fuoco da tastiera: attorno a tutta la scheda (dentro, la miniatura
   coprirebbe l'anello). */
.card-open:focus-visible, .card-play:focus-visible { outline: none; }
.card:has(> .card-play:focus-visible, > .card-open:focus-visible) {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}
.card-play:active .thumb, .card-open:active .thumb { opacity: .8; }
@media (hover: hover) {
  .card-play:hover .thumb img, .card-open:hover .thumb img { filter: brightness(1.12); }
}

.thumb {
  position: relative;
  aspect-ratio: 16 / 9;
  background: var(--surface-2);
  display: block;
}
/* Fuori dal flusso: una miniatura 4:3 (hqdefault, con le bande nere) non deve
   allungare il riquadro 16:9; object-fit: cover taglia le bande. */
.thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.no-thumb .thumb img { visibility: hidden; }
/* Il segno dell'app: mark.svg come maschera, col colore del tema (--mark). */
.no-thumb .thumb::after, .pod-art.no-art::after, .ls-art.no-art::after, .mini-art.no-art::after,
.riprendi-art.no-art::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  background: var(--mark);
  -webkit-mask: url("/static/mark.svg?v=1") center / contain no-repeat;
  mask: url("/static/mark.svg?v=1") center / contain no-repeat;
  opacity: .5;
}
.no-thumb .thumb::after { width: 40px; height: 40px; }
.duration {
  position: absolute;
  right: 6px;
  bottom: 8px;
  padding: 1px 6px;
  border-radius: var(--radius-xs);
  background: rgb(0 0 0 / .78);
  color: #fff; /* sulla miniatura: uguale nei due temi */
  font-size: var(--fs-meta);
  font-variant-numeric: tabular-nums;
}
.duration:empty { display: none; }
/* Diretta: al posto della durata, un bollino rosso. */
.duration.is-live, .live-pill {
  background: var(--live);
  color: #fff;
  font-weight: 700;
  letter-spacing: .06em;
}
/* Punto di ripresa: quanto è già stato visto, in fondo alla miniatura (il
   blu chiaro in tutti e due i temi: sta sopra l'immagine). */
.resume { position: absolute; inset: auto 0 0; height: 4px; background: rgb(255 255 255 / .28); }
.resume-fill { display: block; height: 100%; width: 0; background: #6ea8ff; }

.card-title {
  padding: 6px 12px 0;
  font-weight: 600;
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.card-meta { padding: 0 12px; color: var(--muted); font-size: var(--fs-meta); }

/* Stella dei preferiti: in alto a destra sulla miniatura. Piccola da vedere
   (un cerchio da 34 px), ma il tocco vale su 48 px. */
.fav {
  position: absolute;
  top: 0;
  right: 0;
  z-index: 2;
  width: 48px;
  height: 48px;
  padding: 0;
  border: 0;
  background: none;
  color: #fff;
  display: grid;
  place-items: center;
  cursor: pointer;
}
.fav::before {
  content: "";
  position: absolute;
  inset: 7px;
  border-radius: 50%;
  background: rgb(0 0 0 / .58);
  border: 1px solid rgb(255 255 255 / .18);
  transition: background .12s;
}
.fav svg {
  position: relative;
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linejoin: round;
  transition: transform .12s;
}
.fav[aria-pressed="true"] { color: var(--star); }
.fav[aria-pressed="true"] svg { fill: currentColor; }
@media (hover: hover) {
  .fav:hover::before { background: rgb(0 0 0 / .8); }
}
.fav:active svg { transform: scale(.85); }
.fav:focus-visible { outline: none; }
.fav:focus-visible::before { outline: 3px solid var(--accent); outline-offset: 1px; }

/* --- ricerca su YouTube ------------------------------------------------- */

/* Scelte a interruttore (In diretta | On demand, Podcast | Radio, Tutti |
   Da ascoltare, gli elenchi di "Per te", il tema, «Dove sei?» della
   Diagnostica) e le − + della grandezza delle schede: lo stesso contenitore,
   alto 52 px con le scelte da 44. */
.views, .sizer {
  display: inline-flex;
  gap: 4px;
  padding: 3px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) + 3px);
}
.views { margin-bottom: 12px; }
.view-tab {
  min-height: 44px;
  min-width: 0;
  padding: 0 16px;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
/* Fatta coi radio (il tema, «Dove sei?»): il radio non si vede, tutta la
   scelta si tocca e le frecce passano dall'una all'altra. */
.view-tab:has(> input[type="radio"]) { position: relative; display: flex; align-items: center; justify-content: center; text-align: center; }
.view-tab > input[type="radio"] { position: absolute; opacity: 0; width: 1px; height: 1px; min-height: 0; margin: 0; padding: 0; pointer-events: none; }
.view-tab:has(> input:focus-visible) { outline: 3px solid var(--accent); outline-offset: 2px; }
/* La scelta fatta: piena, in tutti e due i modi. */
.view-tab:is([aria-pressed="true"], :has(> input:checked)) { background: var(--accent-strong); color: var(--on-accent); }
@media (hover: hover) {
  .view-tab:hover { color: var(--text); background: var(--surface-2); }
  .view-tab:is([aria-pressed="true"], :has(> input:checked)):hover { color: var(--on-accent); background: var(--selected-hover); }
}

.search { margin-bottom: 24px; }
.section-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}
.section-head h2 {
  flex: 1;
  font-size: var(--fs-heading);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Tornare indietro, ovunque (un canale, una playlist di "Per te", una
   cartella di On demand, un podcast, dalla Diagnostica): la freccia e dove si
   torna ("Indietro", "Playlist", il nome del livello di prima). */
.back-btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  max-width: min(100%, 36ch);
  min-height: 44px;
  padding: 0 14px 0 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--raised);
  color: var(--text);
  font: inherit;
  font-size: var(--fs-ui);
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}
.back-btn svg { width: 22px; height: 22px; flex: none; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.back-btn-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.back-btn:active { background: var(--hover); }
@media (hover: hover) {
  .back-btn:hover { background: var(--hover); }
}
.back-btn:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }

/* Grandezza delle schede: − e + accanto al titolo della scheda in alto (una
   copia per scheda, vedi makeSizer). Spenti alle due estremità; nascosti
   quando non ci sono schede da ingrandire. */
.sizer { flex: none; margin-left: auto; }
.sizer-btn {
  width: 44px;
  min-height: 44px;
  padding: 0;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: var(--radius);
  background: none;
  color: var(--text);
  cursor: pointer;
}
.sizer-btn svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; }
.sizer-btn:disabled { color: var(--muted); opacity: .45; cursor: default; }
.sizer-btn:active:not(:disabled) { background: var(--hover); }
@media (hover: hover) {
  .sizer-btn:hover:not(:disabled) { background: var(--surface-2); }
}
.sizer-btn:focus-visible { outline: 3px solid var(--accent); outline-offset: 1px; }
.search-status { color: var(--muted); margin: 0 0 12px; }
.search-status.notice-error { color: var(--danger-text); }
/* La riga di stato di un elenco (vedi makeStatus in app.js): la frase e, per
   un errore, il titolo in rosso chiaro, la frase leggibile e "Riprova". */
.status-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; margin-bottom: 14px; }
.status-row .search-status { margin: 0; }
.status-row.is-error .search-status { color: var(--text); max-width: 60ch; }
.status-title { color: var(--danger-text); font-weight: 650; }
.search-more {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  margin-top: 20px;
}
.search-more .search-status { margin: 0; text-align: center; }
.search-more:has(> #search-more[hidden]):has(> #search-more-status[hidden]) { display: none; }

.result .card-meta { margin-top: 2px; }
/* Nome del canale: apre i video del canale. Un bersaglio suo alto 44 px,
   sotto il titolo (che fa partire il video) e staccato da lui. */
.channel-link {
  all: unset;
  box-sizing: border-box;
  cursor: pointer;
  display: inline-block;
  vertical-align: top;
  /* Un po' di margine ai lati, per l'anello del fuoco (il testo resta
     allineato al titolo). */
  max-width: calc(100% + 8px);
  margin-left: -8px;
  padding: 0 8px;
  min-width: 44px;
  min-height: 44px;
  line-height: 44px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--muted);
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--muted) 45%, transparent);
  text-underline-offset: 3px;
}
.channel-link:active { color: var(--text); }
@media (hover: hover) {
  .channel-link:hover { color: var(--text); }
}
.channel-link:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; border-radius: var(--radius-xs); }
.result .result-stats { margin: 2px 0 10px; }
.result .card-meta:has(> .channel-link) { margin-top: 6px; }
.result .card-meta:has(> .channel-link) + .result-stats { margin-top: -6px; }
.result-stats:empty { display: none; }
.result .card-meta:has(+ .result-stats:empty) { margin-bottom: 10px; }
.sort { margin-bottom: 12px; }
.sort .view-tab { padding: 0 14px; font-size: var(--fs-ui); white-space: nowrap; }

/* Ordina e filtri: "pillole" col nome, la scelta e la freccia. Il <select>
   vero è trasparente e le copre tutte: si tocca ovunque e si aprono le
   scelte del sistema. Un filtro attivo è colorato. A metà schermo vanno a
   capo, sul telefono riempiono le righe. */
.list-tools { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.pick {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 0 36px 0 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: var(--fs-ui);
  white-space: nowrap;
  cursor: pointer;
}
.pick-name { color: var(--muted); }
.pick-value { font-weight: 650; }
.pick::after {
  content: "";
  position: absolute;
  right: 15px;
  top: 50%;
  width: 7px;
  height: 7px;
  border-right: 2px solid var(--muted);
  border-bottom: 2px solid var(--muted);
  transform: translateY(-70%) rotate(45deg);
  pointer-events: none;
}
.pick select {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  min-height: 0;
  margin: 0;
  padding: 0;
  border: 0;
  opacity: 0;
  font-size: 16px;
  cursor: pointer;
}
.pick select:disabled { cursor: default; }
.pick:has(select:disabled) { opacity: .45; }
.pick:has(select:focus-visible), .pick-toggle:focus-visible, .pick-reset:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}
/* Lo stato «scelto», uguale ovunque. Le scelte piccole (le schede in alto,
   i giorni e i generi, un filtro attivo) sono piene d'accento col testo
   bianco: si riconoscono al primo sguardo anche col sole, non da un bordo di
   1 px e un velo di colore. I riquadri grandi (un gruppo aperto, la qualità
   scelta) hanno il bordo d'accento di 2 px (un'ombra interna da 1 px sopra
   il bordo: niente cambia di misura) e un segno che non è colore (la freccia
   in su, il pallino). */
.pick.is-set, .pick-toggle[aria-pressed="true"] {
  border-color: var(--accent-strong);
  background: var(--accent-strong);
  color: var(--on-accent);
}
.pick.is-set .pick-name, .pick-toggle[aria-pressed="true"] .pick-count { color: var(--on-accent-soft); }
.pick.is-set::after { border-color: var(--on-accent); }
/* "Nascondi già visti": un interruttore con la casella, senza freccia. */
.pick-toggle { padding: 0 14px 0 11px; }
.pick-toggle::after, .pick-reset::after { content: none; }
.pick-toggle svg { width: 20px; height: 20px; flex: none; fill: none; stroke: var(--muted); stroke-width: 1.8; }
.pick-toggle .tick { stroke: #fff; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; opacity: 0; }
/* Acceso: la casella bianca con la spunta dell'accento, sul pieno. */
.pick-toggle[aria-pressed="true"] rect { fill: var(--on-accent); stroke: var(--on-accent); }
.pick-toggle[aria-pressed="true"] .tick { opacity: 1; stroke: var(--accent-strong); }
.pick-count { color: var(--muted); font-variant-numeric: tabular-nums; }
.pick-count:empty { display: none; }
/* "Togli i filtri": solo con un filtro attivo, più leggero delle pillole. */
.pick-reset { padding: 0 14px 0 10px; border-color: transparent; background: none; color: var(--muted); font-weight: 600; }
/* "Filtri" (solo sul telefono, vedi in fondo) e il suo pannello: più larga,
   il pannello non c'è e le sue pillole stanno in fila con le altre. */
.pick-filters { display: none; }
.filter-panel { display: contents; }
/* Anche fuori dal telefono, se le pillole in fila andrebbero a capo
   (.is-compact, vedi fitSearchTools in app.js) e nell'auto (finestra bassa,
   in fondo): «Ordina» e «Filtri» in una riga, i filtri nel pannello sotto,
   aperto dalla pillola. Una riga di pillole in meno sopra i risultati. Per
   misurare (.is-measuring) le pillole tornano in fila, «Togli i filtri»
   compreso. */
@media (min-width: 481px) {
  .search-tools.is-compact .pick-filters { display: inline-flex; }
  .search-tools.is-compact .filter-panel { display: none; }
  .search-tools.is-compact.is-open .filter-panel { display: flex; flex-wrap: wrap; flex-basis: 100%; gap: 8px; }
  .search-tools.is-compact .pick-filters[aria-expanded="true"]::after { transform: translateY(-25%) rotate(225deg); }
}
.search-tools.is-measuring .pick-filters { display: none !important; }
.search-tools.is-measuring .filter-panel { display: contents !important; }
.search-tools.is-measuring .pick-reset { display: inline-flex !important; }
.pick-reset svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; }
@media (hover: hover) {
  .pick:hover { background: var(--surface-2); }
  .pick.is-set:hover, .pick-toggle[aria-pressed="true"]:hover { border-color: var(--selected-hover); background: var(--selected-hover); }
  .pick:has(select:disabled):hover { background: var(--surface); }
  .pick-reset:hover { background: var(--surface); color: var(--text); }
}
.list-note { margin: -4px 0 12px; }

/* --- "Per te" (account YouTube) ---------------------------------------- */

.foryou-account { color: var(--muted); font-size: var(--fs-ui); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* --- YouTube come l'app (vedi «YouTube come l'app» in app.js) --------------- */
/* Le pillole come quelle di YouTube: la scelta chiara sul fondo scuro. */
.yt-chips { display: flex; gap: 8px; margin: 0 0 14px; overflow-x: auto; scrollbar-width: none; }
.yt-chips::-webkit-scrollbar { display: none; }
.yt-chip {
  flex: none;
  min-height: 40px;
  padding: 0 16px;
  border: 0;
  border-radius: 10px;
  background: var(--surface-2);
  color: var(--text);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.yt-chip[aria-pressed="true"] { background: var(--text); color: var(--bg); }
.yt-chip:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
/* I canali seguiti in fila: l'avatar tondo e il nome sotto. */
.yt-channels { display: flex; gap: 14px; margin: 0 0 18px; padding-bottom: 4px; overflow-x: auto; scrollbar-width: none; }
.yt-channels::-webkit-scrollbar { display: none; }
.yt-chan {
  flex: none;
  display: grid;
  justify-items: center;
  gap: 6px;
  width: 80px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text);
  font: inherit;
  cursor: pointer;
}
.yt-chan-pic {
  position: relative;
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--surface-2);
  color: var(--muted);
  font-size: 24px;
  font-weight: 700;
}
.yt-chan-pic img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.yt-chan:active .yt-chan-pic { filter: brightness(.8); }
.yt-chan-name { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); font-size: var(--fs-meta); }
.yt-home-connect { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin: 0 0 16px; color: var(--muted); }
/* «Iscriviti» sulla pagina di un canale: pieno da fare, spento fatto. */
.channel-follow { flex: none; }
.channel-follow[aria-pressed="false"] { border-color: transparent; background: var(--accent-strong); color: #fff; }

/* Le righe di Apple Music e Spotify. Col dock prendono le misure delle righe
   dei podcast (.pod-cat in carplay.css). */
.music-rows { display: grid; gap: 8px; margin: 0 0 16px; }
.yt-row { width: 100%; padding: 10px 12px 10px 16px; background: var(--surface-2); }
.yt-row .net-tab-chev { visibility: visible; }
.yt-row:active { background: var(--hover); }

/* --- Apple Music e Spotify: il lettore ufficiale (vedi «Musica» in app.js) -- */
.music-link { display: flex; gap: 8px; margin: 0 0 16px; }
.music-link input { min-width: 0; }
.music-link .btn { flex: none; padding: 0 18px; }
.music-status { margin: 0 0 12px; }
.music-note { margin: 16px 0 0; color: var(--muted); font-size: var(--fs-meta); }
/* Alto quanto lo schermo lascia: Spotify e Apple mostrano più brani. */
.music-frame { display: block; width: 100%; height: max(380px, calc(100dvh - 190px)); border: 0; border-radius: 12px; background: var(--surface-2); }
/* Quello di Apple Music è alto 450 e basta: sotto resterebbe bianco. */
#applemusic .music-frame { height: 450px; }
.foryou-connect { display: grid; gap: 12px; justify-items: start; max-width: 60ch; margin-bottom: 20px; }
.foryou-connect p { margin: 0; color: var(--muted); }
a.btn { text-decoration: none; }
.foryou-back-row { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.foryou-back-row h3 { margin: 0; font-size: var(--fs-subhead); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.playlist .card-title { padding-bottom: 2px; }

/* --- TV italiana (canali Rai in diretta) --------------------------------- */
/* Schede compatte, nella stessa griglia dei risultati: in alto logo, nome e
   LIVE; sotto il programma in onda (due righe al massimo, riservate anche se
   ne basta una: le schede di una riga restano allineate; non sul telefono, a
   una colonna), i suoi orari con la barra di quanto è passato, e in fondo il
   successivo. Tutta la scheda è un pulsante. */

/* Accanto al titolo la scelta "In diretta | Rivedi La7". "In diretta" ha il
   punto rosso: una volta sola per tutta la scheda, al posto di un LIVE su
   ogni canale (premuto, sul blu, con un anello bianco che lo stacca). */
.tv-head-row { flex-wrap: wrap; row-gap: 8px; column-gap: 16px; }
.tv-head-row h2 { flex: none; }
.views.tv-modes { margin: 0; }
.tv-modes .view-tab { display: inline-flex; align-items: center; gap: 8px; padding: 0 14px; font-size: var(--fs-ui); white-space: nowrap; }
.tv-dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--live); }
.tv-modes .view-tab[aria-pressed="true"] .tv-dot { box-shadow: 0 0 0 2px #fff; }
/* Reti e ricerca (vedi makeNets in app.js), in «In diretta» e nella Radio. Da
   600 px in su (l'auto, a metà schermo, il computer) due colonne: a sinistra
   la ricerca e le reti, ferme sotto la barra in alto mentre le schede
   scorrono (più alte della finestra, le reti scorrono dentro di sé); a
   destra le schede della rete scelta, come sempre. Le reti sono una scelta a
   interruttore in verticale (lo stesso contenitore di In diretta | On demand):
   righe da 48 px col nome (a capo se lungo: «Altre dirette»), quante sono e
   la freccia verso le schede; quella scelta piena d'accento, con la freccia.
   Sotto i 600 px (il telefono) vedi più in basso: una fila di pillole. */
.nets {
  --rail-w: clamp(184px, 30%, 200px);
  display: grid;
  grid-template-columns: var(--rail-w) minmax(0, 1fr);
  column-gap: 16px;
  align-items: start;
}
.nets-side {
  position: sticky;
  top: calc(var(--topbar-h, 61px) + 12px);
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
  max-height: calc(100dvh - var(--topbar-h, 61px) - 24px);
}
/* Con la barra in basso (l'ascolto, un altro dispositivo) le reti finiscono sopra di lei. */
body:is(.has-mini, .has-remote-bar) .nets-side { max-height: calc(100dvh - var(--topbar-h, 61px) - 24px - 96px - var(--safe-bottom)); }
.nets-find { position: relative; flex: none; margin: 0; }
/* Almeno 16 px: sotto, l'iPhone ingrandisce la pagina toccando il campo. */
.nets-find input { padding: 0 8px 0 36px; font-size: max(16px, var(--fs-ui)); }
.nets-find:has(.nets-find-clear:not([hidden])) input { padding-right: 48px; }
.nets-find input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; display: none; }
.nets-find-icon {
  position: absolute;
  left: 10px;
  top: 50%;
  width: 20px;
  height: 20px;
  transform: translateY(-50%);
  fill: none;
  stroke: var(--muted);
  stroke-width: 2.2;
  stroke-linecap: round;
  pointer-events: none;
}
/* La X: tutta l'altezza del campo, 48 px da toccare. */
.nets-find-clear {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 48px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: var(--radius);
  background: none;
  color: var(--muted);
  cursor: pointer;
}
.nets-find-clear svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }
.nets-find-clear:active { color: var(--text); background: var(--hover); }
.nets-find-clear:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }
@media (hover: hover) {
  .nets-find-clear:hover { color: var(--text); background: var(--hover); }
}
.nets-rail {
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 3px;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) + 3px);
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
.nets-rail:empty { display: none; }
.net-tab {
  flex: none;
  display: flex;
  align-items: center;
  gap: 4px;
  min-height: var(--tap);
  padding: 6px 6px 6px 10px;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: var(--fs-ui);
  font-weight: 650;
  line-height: 1.2;
  text-align: left;
  cursor: pointer;
}
.net-tab-text { flex: 1; min-width: 0; display: grid; gap: 2px; }
.net-tab-name { overflow: hidden; overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.net-tab-sub, .net-tab-count { color: var(--muted); font-size: var(--fs-meta); font-weight: 500; }
.net-tab-sub { overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.net-tab-count { flex: none; font-variant-numeric: tabular-nums; }
.net-tab svg { flex: none; width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; }
.net-tab-check { display: none; stroke-width: 2.6; }
/* La freccia c'è sempre (il nome non cambia riga scegliendo): si vede sulla scelta. */
.net-tab-chev { width: 16px; height: 16px; stroke-width: 2.6; visibility: hidden; }
.net-tab .net-tab-star { fill: var(--star-ink); stroke: none; }
.net-tab-on { color: var(--accent-text); stroke-width: 2.6; }
.net-tab[aria-selected="true"] { background: var(--accent-strong); color: var(--on-accent); }
.net-tab[aria-selected="true"] :is(.net-tab-sub, .net-tab-count) { color: var(--on-accent-soft); }
.net-tab[aria-selected="true"] .net-tab-chev { visibility: visible; }
.net-tab[aria-selected="true"] .net-tab-on { color: var(--on-accent); }
.net-tab[aria-selected="true"] .net-tab-star { fill: var(--star); }
/* «Risultati», cercando: staccato dalle reti sotto. */
.net-tab.is-results { margin-bottom: 5px; }
.net-tab:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }
.net-tab[aria-selected="true"]:focus-visible { outline-color: var(--on-accent); outline-offset: -5px; }
.net-tab:active { background: var(--hover); }
.net-tab[aria-selected="true"]:active { background: var(--accent-hover); }
@media (hover: hover) {
  .net-tab:hover { background: var(--surface-2); }
  .net-tab[aria-selected="true"]:hover { background: var(--selected-hover); }
}
.nets-pane { min-width: 0; }
.nets-pane:focus { outline: none; }
/* La riga di stato della ricerca: quanti risultati («3 canali per “rai”»);
   vuota fuori dalla ricerca, senza spazio. Senza risultati è il titolo dello
   stato vuoto. */
.nets-found { margin: 0 0 14px; color: var(--muted); font-size: var(--fs-ui); }
.nets-found:empty { margin: 0; }
.nets-found.is-empty { margin-bottom: 6px; color: var(--text); font-size: var(--fs-subhead); font-weight: 650; }
.nets-empty { margin-bottom: 16px; }
/* I risultati, rete per rete: il nome e quanti, le schede di sempre. Tanti
   («radio»: 140) il browser disegna solo quelli vicini allo schermo. */
.nets-hits { display: grid; gap: 24px; }
.nets-hit li.card { content-visibility: auto; contain-intrinsic-size: auto 132px; }
.nets-hit-head { display: flex; align-items: baseline; gap: 10px; margin: 0 0 10px; font-size: var(--fs-lead); font-weight: 650; }
/* Quanti (anche nei blocchi dei podcast). */
.tv-group-count, .nets-count { flex: none; color: var(--muted); font-size: var(--fs-meta); font-weight: 500; font-variant-numeric: tabular-nums; }
/* Una scheda col fuoco (tastiera) non finisce sotto la barra in alto. */
.nets-pane li { scroll-margin-top: calc(var(--topbar-h, 61px) + 12px); }
/* Le loro regioni, sotto il nome di una radio locale (nei risultati, o di
   un'altra regione), su due righe se serve («Sicilia · sede in Calabria»:
   cercando, quella cercata per prima, vedi radioWhereFound). */
.radio-where {
  max-width: 100%;
  color: var(--muted);
  font-size: var(--fs-meta);
  font-weight: 500;
  line-height: 1.3;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
/* Telefono: la ricerca a tutta riga, sotto una fila di pillole che scorre di
   lato (come le scelte di On demand) e resta ferma sotto la barra in alto,
   sul suo stesso fondo velato. La scelta piena, con la spunta. */
@media (max-width: 599px) {
  .nets { display: block; }
  .nets-side { display: contents; }
  .nets-find { margin-bottom: 4px; }
  .nets-rail {
    position: sticky;
    top: var(--topbar-h, 61px);
    z-index: 3;
    flex-direction: row;
    gap: 8px;
    margin: 0 calc(-1 * var(--main-pad)) 12px;
    padding: 8px var(--main-pad);
    overflow-x: auto;
    overflow-y: hidden;
    background: color-mix(in srgb, var(--bg) 92%, transparent);
    backdrop-filter: blur(8px);
    border: 0;
    border-bottom: 1px solid var(--border);
    border-radius: 0;
    scrollbar-width: none;
  }
  .nets-rail::-webkit-scrollbar { display: none; }
  .net-tab {
    min-height: 44px;
    gap: 6px;
    padding: 0 14px;
    border: 1px solid var(--border);
    background: var(--surface);
    white-space: nowrap;
  }
  .net-tab-text { display: block; }
  .net-tab-name { display: inline; }
  .net-tab-sub, .net-tab-chev { display: none; }
  .net-tab[aria-selected="true"] { border-color: var(--accent-strong); padding-left: 10px; }
  .net-tab[aria-selected="true"] .net-tab-check { display: block; }
  .net-tab.is-results { margin-bottom: 0; }
  .nets-pane li { scroll-margin-top: calc(var(--topbar-h, 61px) + 74px); }
}
.tv-play {
  all: unset;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 14px 12px 12px;
  cursor: pointer;
}
.tv-play:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: -3px;
  border-radius: var(--radius);
}
.tv-head { display: flex; align-items: center; gap: 12px; margin-bottom: 4px; }
/* I loghi di RaiPlay, Sky e Mediaset sono bianchi su trasparente: stanno su
   un blu profondo in tutti e due i temi (o sul colore del canale, se il server
   lo manda), e così il nome di un canale senza logo. Uno scuro (Discovery, blu
   notte: vedi fitTvLogo in app.js) sull'azzurro. Le radio usano le stesse
   schede (vedi #radio-template). */
.tv-logo {
  flex: none;
  position: relative;
  container-type: size; /* per .is-fitted qui sotto: misure in cqw/cqh */
  width: 88px;
  height: 52px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-s);
  background: var(--logo-tile);
  color: var(--logo-ink);
  overflow: hidden;
}
.tv-card.is-dark-logo .tv-logo { background: var(--logo-light); }
/* L'altezza in px: in percentuale (riga della griglia senza altezza propria)
   non conterrebbe un logo verticale come quello di TV8, che uscirebbe tagliato. */
.tv-logo img { display: block; max-width: calc(100% - 18px); max-height: 36px; object-fit: contain; }
/* Il logo che sta arrivando (loading="lazy", vedi logoLoad in app.js): nella
   pagina perché il browser lo carichi, ma invisibile e fuori dal flusso. */
.tv-logo img.is-wait { position: absolute; opacity: 0; }
/* Un logo con tanto margine trasparente (Mediaset: un quadrato col logo
   piccolo in mezzo): la parte disegnata (larga --bw dell'immagine, con
   rapporto --r e centro in --cx, --cy) riempie lo stesso spazio di un logo
   senza margine (18 px meno del riquadro in larghezza, 16 in altezza);
   l'immagine, più grande, esce dal riquadro solo col margine trasparente. */
.tv-logo img.is-fitted {
  position: absolute;
  left: 50%;
  top: 50%;
  max-width: none;
  max-height: none;
  width: calc(min(100cqw - 18px, (100cqh - 16px) * var(--r)) / var(--bw));
  height: auto;
  transform: translate(calc(-50% + (.5 - var(--cx)) * 100%), calc(-50% + (.5 - var(--cy)) * 100%));
}
/* Senza logo: il nome, in grande se è corto ("1", "4K"). */
.tv-mark {
  padding: 0 6px;
  font-size: 26px;
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -.01em;
  text-align: center;
}
.tv-mark.is-long { font-size: 15px; font-weight: 750; letter-spacing: 0; }
.tv-id { flex: 1; min-width: 0; display: grid; justify-items: start; }
.tv-name {
  max-width: 100%;
  font-size: var(--fs-lead);
  font-weight: 650;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tv-now {
  min-height: 2.6em;
  font-weight: 600;
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.tv-label { color: var(--muted); font-weight: 500; }
.tv-now.is-missing { color: var(--muted); font-weight: 500; }
.tv-now.is-missing .tv-label { display: none; }
.tv-time {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--muted);
  font-size: var(--fs-meta);
  font-variant-numeric: tabular-nums;
}
/* Quanto del programma è passato: sottile come il punto di ripresa. */
.tv-progress { flex: 1; height: 4px; border-radius: 2px; background: var(--track); overflow: hidden; }
.tv-progress-fill { display: block; height: 100%; width: 0; background: var(--accent-text); }
.tv-next {
  margin-top: auto;
  padding-top: 2px;
  color: var(--muted);
  font-size: var(--fs-meta);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tv-next .tv-label { font-weight: 650; }
/* Senza guida in tutto il gruppo (le dirette di Dailymotion): solo logo e
   nome; il nome, spesso lungo ("ClassCNBC - Digitale Terrestre"), su due righe. */
.tv-card.is-bare .tv-head { margin-bottom: 0; }
/* Miniatura (un fotogramma della diretta) al posto del logo: riempie il riquadro, in 16:9. */
.tv-card.is-thumb .tv-logo { width: 96px; height: 54px; }
.tv-card.is-thumb .tv-logo img { width: 100%; height: 100%; max-width: none; max-height: none; object-fit: cover; }
.tv-card.is-bare .tv-name {
  white-space: normal;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  line-height: 1.25;
}
/* Per le schede strette (le più piccole, vedi in fondo). */
.tv-card { container-type: inline-size; }
.tv-play:active .tv-logo { opacity: .8; }
@media (hover: hover) {
  .tv-play:hover { background: color-mix(in srgb, var(--surface-2) 55%, var(--surface)); }
  .tv-play:hover .tv-logo img { filter: brightness(1.12); }
}
/* Il palinsesto (i canali che ce l'hanno): una riga in fondo alla scheda,
   divisa da un filo, col «Poi:» a sinistra e «Palinsesto» a destra, come un
   pulsante a sé (non fa partire il canale). */
.tv-card.has-guide .tv-play { padding-bottom: 10px; }
.tv-guide {
  all: unset;
  box-sizing: border-box;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 12px;
  min-height: 46px;
  padding: 4px 14px 4px 12px;
  border-top: 1px solid var(--border);
  cursor: pointer;
}
.tv-guide .tv-next { flex: 1 1 8em; min-width: 0; margin: 0; padding: 0; }
.tv-guide-label {
  flex: none;
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--accent-text);
  font-size: var(--fs-ui);
  font-weight: 650;
}
.tv-guide-label svg { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.tv-guide:active { background: var(--hover); }
@media (hover: hover) {
  .tv-guide:hover { background: color-mix(in srgb, var(--surface-2) 55%, var(--surface)); }
}
.tv-guide:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: -3px;
  border-radius: 0 0 var(--radius) var(--radius);
}

/* --- On demand ------------------------------------------------------------- */
/* Sotto "In diretta | On demand" le fonti, come schede con la riga sotto
   quella scelta (più leggere della scelta piena in alto; "Cerca" in fondo a
   destra); poi la cartella aperta: "← quella di prima" e il titolo, la fila
   delle scelte (giorni, sport; le regioni in una pillola), gli interruttori,
   le schede (miniatura con durata, titolo, programma, quando) o le righe. Sul
   telefono le fonti vanno su due righe, tutte in vista. */
.od-tabs {
  display: flex;
  gap: 2px;
  margin: 0 0 16px;
  padding: 0 2px;
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
  scrollbar-width: none;
}
.od-tabs::-webkit-scrollbar { display: none; }
.od-tab {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 48px;
  padding: 0 14px;
  border: 0;
  border-radius: var(--radius-m) var(--radius-m) 0 0;
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: 16px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}
.od-tab::after {
  content: "";
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: -1px;
  height: 3px;
  border-radius: 3px 3px 0 0;
  background: transparent;
}
.od-tab[aria-pressed="true"] { color: var(--text); }
.od-tab[aria-pressed="true"]::after { background: var(--accent); }
.od-tab.is-off { opacity: .55; font-weight: 500; }
.od-tab svg { width: 19px; height: 19px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.od-tab-search { margin-left: auto; }
.od-tab:active { background: var(--surface-2); }
@media (hover: hover) {
  .od-tab:hover { color: var(--text); background: var(--surface); }
}
.od-tab:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }

/* La cartella aperta: "‹ …" (quella di prima, vedi .back-btn) e il titolo. */
.od-head { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin: 0 0 14px; }
.od-title {
  flex: 1 1 16ch;
  min-width: 0;
  margin: 0;
  font-size: var(--fs-heading);
  font-weight: 650;
  line-height: 1.25;
  overflow-wrap: break-word;
  text-wrap: balance;
}
.od-title:focus { outline: none; }
/* Aperta una cartella: il titolo accanto a "← …" (sotto, se non ci sta). */
.od-head.is-deep .od-title { flex-basis: 20ch; font-size: var(--fs-title); }

/* "Cerca": in tutte le fonti insieme. */
.od-search { display: flex; gap: 8px; max-width: 640px; margin: 0 0 16px; }
.od-search input { min-height: 44px; min-width: 0; }
.od-search .btn { min-height: 44px; padding: 0 16px; }

/* Un programma: la copertina e la descrizione, sopra le puntate. */
.od-intro { display: grid; grid-template-columns: minmax(0, 220px) minmax(0, 60ch); gap: 16px; align-items: start; margin: 0 0 18px; }
.od-intro img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-radius: var(--radius-m); background: var(--surface-2); display: block; }
.od-intro.no-cover { grid-template-columns: minmax(0, 60ch); }
.od-intro.no-cover img { display: none; }
.od-intro-text {
  margin: 0;
  color: var(--muted);
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 5;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Una riga sopra le schede: la fila delle scelte, gli interruttori e
   "Ultime uscite" (a destra), che vanno a capo solo se non ci stanno: in auto
   lo spazio in verticale è poco. */
.od-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; margin: 0 0 14px; }
.od-bar:not(:has(> :not([hidden]))) { display: none; }
.od-bar .list-tools { margin: 0; }
.od-latest { margin-left: auto; }
.od-latest svg { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }

/* Le scelte in fila (Oggi, Ieri, "Sab 26"; i canali; gli sport), quella
   scelta colorata come un filtro attivo. Se non ci stanno la fila scorre di
   lato (il padding tiene dentro l'anello del fuoco). Tante (le regioni): una
   pillola. */
.od-chips {
  position: relative;
  flex: 0 1 auto;
  min-width: 0;
  max-width: calc(100% + 8px);
  display: flex;
  gap: 8px;
  margin: -4px;
  padding: 4px;
  overflow-x: auto;
  scrollbar-width: none;
}
.od-chips::-webkit-scrollbar { display: none; }
.od-chips.is-pick { overflow: visible; }
/* Se la fila scorre di lato, i bordi sfumano dove c'è altro da vedere: a
   destra all'inizio, ai due lati in mezzo, a sinistra alla fine (la
   sfumatura segue lo scorrimento: animation-timeline). Senza altro da vedere
   la timeline non è attiva e i bordi restano netti; i browser che non la
   conoscono restano come prima. */
@property --fade-start { syntax: "<length>"; inherits: false; initial-value: 0px; }
@property --fade-end { syntax: "<length>"; inherits: false; initial-value: 0px; }
@keyframes row-fade {
  from { --fade-start: 0px; --fade-end: 40px; }
  8% { --fade-start: 40px; }
  92% { --fade-end: 40px; }
  to { --fade-start: 40px; --fade-end: 0px; }
}
@supports (animation-timeline: scroll()) {
  .od-chips:not(.is-pick) {
    -webkit-mask-image: linear-gradient(to right, transparent, #000 var(--fade-start), #000 calc(100% - var(--fade-end)), transparent);
    mask-image: linear-gradient(to right, transparent, #000 var(--fade-start), #000 calc(100% - var(--fade-end)), transparent);
    animation: row-fade linear both;
    animation-timeline: scroll(self inline);
  }
}
.od-pick { min-width: 240px; } /* la regione più lunga ci sta, e cambiandola non si allarga */
.chip {
  flex: none;
  min-height: 44px;
  min-width: 56px;
  padding: 0 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: var(--fs-ui);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}
/* Il giorno o il genere scelto: pieno, come la scheda in alto (vedi lo stato
   «scelto» sopra le pillole). */
.chip[aria-pressed="true"] { border-color: var(--accent-strong); background: var(--accent-strong); color: var(--on-accent); }
.chip:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.chip:active { background: var(--surface-2); }
.chip[aria-pressed="true"]:active { background: var(--accent-hover); }
@media (hover: hover) {
  .chip:hover { background: var(--surface-2); }
  .chip[aria-pressed="true"]:hover { border-color: var(--selected-hover); background: var(--selected-hover); }
}
.od-notice { margin: -2px 0 14px; color: var(--muted); max-width: 70ch; }

/* Niente da guardare (uno stato vuoto, vedi .empty-state): il perché e, se
   c'è, la scelta dopo ("Apri «Ieri»"). */
.od-empty { margin: 6px 0 20px; }

.od-body { display: grid; gap: var(--grid-gap); }
.od-body:empty { display: none; }

/* Scheda di un contenuto: come quelle dei video, con il programma e quando
   sotto il titolo. */
.od-card .card-play { flex: 1; align-content: start; padding-bottom: 12px; }
.od-card .card-meta { line-height: 1.35; }
.od-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.od-when { font-variant-numeric: tabular-nums; }
.od-expires { color: var(--warn-text); font-weight: 600; }
.od-card.is-continue .card-play { flex: 0 0 auto; padding-bottom: 4px; }

/* Scheda di una cartella: copertina, titolo e quante puntate, con la freccia. */
.od-folder .card-open { flex: 1; align-content: start; padding-bottom: 12px; }
.od-folder-text { display: grid; gap: 2px; padding-right: 30px; position: relative; }
.od-folder-text::after {
  content: "";
  position: absolute;
  right: 14px;
  top: 12px;
  width: 8px;
  height: 8px;
  border-right: 2px solid var(--muted);
  border-top: 2px solid var(--muted);
  transform: rotate(45deg);
}
.od-folder .card-meta { line-height: 1.35; }
/* Un canale: il logo intero su un riquadro, come nella griglia delle dirette. */
.od-folder.is-logo .thumb { background: var(--logo-tile); }
.od-folder.is-logo.is-dark-logo .thumb { background: var(--logo-light); }
.od-folder.is-logo .thumb img { inset: 18% 22%; width: 56%; height: 64%; object-fit: contain; }

/* Righe compatte: le edizioni dei TG, le stagioni, le cartelle senza
   immagini. Nella griglia delle schede (le − + valgono anche qui). */
.od-row { container-type: inline-size; }
.od-row-btn {
  all: unset;
  box-sizing: border-box;
  flex: 1;
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 64px;
  padding: 10px 12px;
  cursor: pointer;
}
.od-row-thumb { flex: none; width: 112px; border-radius: var(--radius-s); overflow: hidden; }
.od-row:not(.has-thumb) .od-row-thumb { display: none; }
.od-row-thumb .duration { right: 4px; bottom: 4px; font-size: var(--fs-meta); }
.od-row-text { flex: 1; min-width: 0; display: grid; gap: 2px; }
.od-row-title {
  font-weight: 600;
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.od-row .od-sub, .od-row .od-when { color: var(--muted); font-size: var(--fs-meta); line-height: 1.35; }
.od-row-icon { flex: none; width: 22px; height: 22px; fill: none; stroke: var(--muted); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.od-row.is-item .od-icon-open, .od-row.is-folder .od-icon-play { display: none; }
.od-row.is-item .od-icon-play { width: 28px; height: 28px; stroke-width: 1.6; }
/* Con la miniatura (che ha la durata) l'icona del play non serve: più posto al titolo. */
.od-row.is-item.has-thumb .od-icon-play { display: none; }
.od-row.is-item .od-icon-play path { fill: var(--muted); stroke: none; }
.od-row .resume { top: auto; }
.od-row-btn:focus-visible { outline: none; }
.card:has(> .od-row-btn:focus-visible) { outline: 3px solid var(--accent); outline-offset: 2px; }
.od-row-btn:active { background: var(--surface-2); }
@media (hover: hover) {
  .od-row-btn:hover { background: color-mix(in srgb, var(--surface-2) 55%, var(--surface)); }
  .od-row-btn:hover .od-row-icon { stroke: var(--text); }
  .od-row.is-item .od-row-btn:hover .od-icon-play path { fill: var(--text); }
}
/* Righe strette (le schede più piccole): la miniatura più piccola. */
@container (max-width: 250px) {
  .od-row-btn { gap: 10px; padding: 10px; }
  .od-row-thumb { width: 72px; }
  .od-row-thumb .duration { display: none; }
  .od-row-icon { display: none; }
}

/* "Cerca": un gruppo per fonte, come i gruppi delle dirette. */
.od-group { display: grid; gap: 12px; }
.od-group + .od-group { margin-top: 16px; }
.od-group-head { margin: 0; font-size: var(--fs-lead); font-weight: 650; }
.od-group-body { display: grid; gap: var(--grid-gap); }
.od-group-more { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; }
.od-group-more .search-status { margin: 0; }
#od-more-row:has(> #od-more[hidden]):has(> #od-more-status[hidden]) { display: none; }

/* --- palinsesto di un canale (vedi openGuide in app.js) -------------------- */
/* Un foglio alto quanto la finestra (meno un margine): in cima il canale, il
   giorno, «Guarda» e la X, sotto i giorni; scorre solo l'elenco dei
   programmi. Sul telefono tutto lo schermo. */
.guide {
  /* I fogli stanno al centro della zona sicura (vedi --safe-*). */
  inset: var(--safe-top) var(--safe-right) var(--safe-bottom) var(--safe-left);
  width: min(760px, calc(100vw - 24px - var(--safe-left) - var(--safe-right)));
  max-width: none;
  height: calc(100vh - 24px);
  height: calc(100dvh - 24px - var(--safe-top) - var(--safe-bottom));
  max-height: none;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-dialog);
  overflow: hidden;
}
.guide:focus { outline: none; }
.guide::backdrop { background: var(--backdrop, rgb(0 0 0 / .6)); }
@keyframes guide-in { from { opacity: 0; transform: translateY(14px) scale(.985); } }
.guide[open] { animation: guide-in .3s cubic-bezier(.16, 1, .3, 1); }
@media (prefers-reduced-motion: reduce) {
  .guide[open] { animation: none; }
}
:root[data-moving] .guide[open] { animation: none; } /* in movimento niente che attiri lo sguardo */
/* Il riquadro riempie il <dialog>: un tocco sul <dialog> stesso è sullo sfondo. */
.guide-box { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.guide-head { display: flex; align-items: center; gap: 12px; padding: 14px 14px 12px 16px; }
.guide-logo { width: 76px; height: 44px; }
.guide-logo img { max-width: calc(100% - 14px); max-height: 30px; }
.guide-logo .tv-mark { font-size: 21px; }
.guide-logo .tv-mark.is-long { font-size: 13px; }
.guide-head.is-dark-logo .guide-logo { background: var(--logo-light); }
.guide-id { flex: 1; min-width: 0; display: grid; gap: 1px; }
.guide-title {
  margin: 0;
  font-size: var(--fs-title);
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.guide-sub { margin: 0; color: var(--muted); font-size: var(--fs-meta); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.guide-watch { flex: none; min-height: 44px; padding: 0 18px 0 14px; }
.guide-watch svg { width: 18px; height: 18px; fill: currentColor; }
.guide-close { --size: 44px; }
/* I giorni: le scelte di On demand (.od-chips), in una fila che scorre. */
.guide-days-row { min-height: 60px; padding: 0 16px 12px; border-bottom: 1px solid var(--border); }
.guide-days { max-width: calc(100% + 8px); }
.guide-scroll {
  position: relative; /* il riferimento di offsetTop per scrollGuideTo in app.js */
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 10px 10px 18px;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
/* Scorrendo, in cima l'elenco sfuma sotto i giorni (la sfumatura segue lo
   scorrimento, come le file delle scelte; senza animation-timeline niente). */
@property --fade-top { syntax: "<length>"; inherits: false; initial-value: 0px; }
@keyframes list-fade { from { --fade-top: 0px; } 4% { --fade-top: 28px; } to { --fade-top: 28px; } }
@supports (animation-timeline: scroll()) {
  .guide-scroll {
    -webkit-mask-image: linear-gradient(to bottom, transparent, #000 var(--fade-top));
    mask-image: linear-gradient(to bottom, transparent, #000 var(--fade-top));
    animation: list-fade linear both;
    animation-timeline: scroll(self block);
  }
}
.guide-scroll > .status-row { margin: 8px 8px 0; }
.guide-empty { margin: 16px 8px; }
.guide-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
/* Un programma: l'ora in una colonna (cifre a larghezza fissa), accanto il
   titolo, il sottotitolo e la descrizione in due righe. */
.guide-row {
  box-sizing: border-box;
  width: 100%;
  display: grid;
  grid-template-columns: 3.4em minmax(0, 1fr);
  column-gap: 14px;
  min-height: 44px;
  margin: 0;
  padding: 10px 12px;
  border: 0;
  border-radius: var(--radius-m);
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
}
button.guide-row { cursor: pointer; }
button.guide-row:active { background: var(--hover); }
@media (hover: hover) {
  button.guide-row:hover { background: color-mix(in srgb, var(--surface-2) 55%, var(--surface)); }
}
button.guide-row:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }
.guide-time { font-weight: 650; font-variant-numeric: tabular-nums; line-height: 1.35; }
.guide-time small { display: block; color: var(--muted); font-size: var(--fs-meta); font-weight: 500; }
.guide-main { display: grid; gap: 2px; min-width: 0; line-height: 1.35; }
.guide-name { font-weight: 650; overflow-wrap: anywhere; }
.guide-subtitle, .guide-desc { color: var(--muted); font-size: var(--fs-meta); }
.guide-desc {
  max-width: 70ch;
  margin-top: 1px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.guide-row[aria-expanded="true"] .guide-desc { display: block; }
/* Finiti: spenti (il testo secondario, non trasparente: si legge ancora). */
.guide-item.is-past :is(.guide-time, .guide-name) { color: var(--muted); font-weight: 600; }
/* In onda: il fondo tinto d'accento, «In onda», gli orari e la barra. */
.guide-item.is-now .guide-row {
  background: color-mix(in srgb, var(--accent) 15%, var(--surface));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 40%, transparent);
}
.guide-item.is-now :is(.guide-subtitle, .guide-desc, .guide-range) { color: var(--tint-text); }
.guide-now {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 10px;
  margin-bottom: 4px;
  font-size: var(--fs-meta);
  font-variant-numeric: tabular-nums;
}
.guide-badge {
  padding: 1px 9px;
  border-radius: 999px;
  background: var(--accent-strong);
  color: var(--on-accent);
  font-weight: 650;
}
.guide-progress { flex: 1 1 80px; max-width: 240px; height: 4px; border-radius: 2px; background: var(--track); overflow: hidden; }
.guide-progress-fill { display: block; height: 100%; width: 0; background: var(--accent-text); }

/* --- impostazioni ------------------------------------------------------- */

.settings {
  inset: var(--safe-top) var(--safe-right) var(--safe-bottom) var(--safe-left); /* al centro della zona sicura */
  width: min(560px, calc(100vw - 24px - var(--safe-left) - var(--safe-right)));
  max-height: calc(100vh - 24px);
  max-height: calc(100dvh - 24px - var(--safe-top) - var(--safe-bottom)); /* sui telefoni 100vh include le barre del browser */
  overflow: auto;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-dialog);
}
/* Il fondo del tema (dove ::backdrop non eredita le variabili, quello scuro). */
.settings::backdrop { background: var(--backdrop, rgb(0 0 0 / .6)); }
/* Il contenuto scorre; "Annulla" e "Salva" restano in fondo alla finestra. */
.settings-body { display: grid; gap: 18px; padding: 20px 20px 16px; }
.settings-form h2 { font-size: var(--fs-title); }
.settings-footer {
  position: sticky;
  bottom: 0;
  z-index: 1;
  display: grid;
  gap: 8px;
  padding: 12px 20px 16px;
  border-top: 1px solid var(--border);
  background: var(--surface);
}
.settings-footer .settings-actions { justify-content: flex-end; }
.settings fieldset { display: grid; gap: 12px; margin: 0; padding: 0; border: 0; min-width: 0; }
.settings legend { padding: 0; margin-bottom: 2px; font-weight: 650; }
.settings-hint { margin: 0; color: var(--muted); font-size: var(--fs-meta); }
.field { display: grid; gap: 4px; }
.field > span { font-weight: 600; font-size: var(--fs-ui); }
.field small { display: block; color: var(--muted); font-size: var(--fs-meta); font-weight: 400; }
/* "Qualità immagine": tre scelte grandi (tutta la riga si tocca), poi "Avanzate". */
.preset-list { display: grid; gap: 8px; }
.preset {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  column-gap: 12px;
  min-height: 56px;
  padding: 8px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
}
.preset input { grid-row: span 2; width: 22px; height: 22px; min-height: 0; margin: 0; padding: 0; accent-color: var(--accent); }
.preset-name { font-weight: 650; }
.preset-hint { grid-column: 2; color: var(--muted); font-size: var(--fs-meta); }
/* La scelta fatta: il bordo d'accento di 2 px, un velo e il pallino pieno. */
.preset:has(input:checked) {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 16%, var(--surface));
  box-shadow: inset 0 0 0 1px var(--accent);
}
.preset:has(input:checked) .preset-hint { color: var(--tint-text); }
.preset:has(input:focus-visible) { outline: 3px solid var(--accent); outline-offset: 2px; }
@media (hover: hover) {
  .preset:hover:not(:has(input:checked)) { background: var(--surface-2); }
}
.advanced { margin-top: 4px; }
.advanced summary {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding-right: 8px;
  border-radius: var(--radius-s);
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}
.advanced summary::-webkit-details-marker { display: none; }
.advanced summary::before {
  content: "";
  width: 7px;
  height: 7px;
  margin: 0 4px 0 6px;
  border-right: 2px solid var(--muted);
  border-bottom: 2px solid var(--muted);
  transform: rotate(-45deg);
  transition: transform .15s;
}
.advanced[open] summary::before { transform: rotate(45deg); }
.advanced summary:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.advanced-body { display: grid; gap: 14px; padding: 4px 0 2px; }
.settings select { min-height: 44px; }
.settings .btn { min-height: 44px; }
.settings-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.check { display: flex; align-items: center; gap: 12px; min-height: 44px; cursor: pointer; font-size: var(--fs-ui); }
.check input { width: 22px; height: 22px; min-height: 0; margin: 0; padding: 0; flex: none; accent-color: var(--accent); }
/* Le note fra parentesi: come i suggerimenti (non più "smaller", 12,5 px). */
.check small { color: var(--muted); font-size: var(--fs-meta); }
/* La modalità (guida attiva, non attiva, Tesla): tre scelte come quelle della
   qualità, la frase sotto e lo stato del GPS di adesso (cambia da solo: cifre
   a larghezza fissa). */
.settings .guida-field { gap: 8px; }
.guida-field legend { margin-bottom: 8px; font-size: var(--fs-ui); font-weight: 600; }
.check-hint { margin: 0; padding-left: 34px; }
.guida-now { margin: 0; color: var(--text); font-size: var(--fs-meta); font-weight: 600; font-variant-numeric: tabular-nums; }
/* La qualità arriva dal server (vedi loadServerSettings in app.js): intanto,
   o se non arriva, le scelte sono spente e sopra c'è la riga di stato. */
.settings .status-row { margin: 0; }
.presets.is-waiting :is(.preset-list, .advanced) { opacity: .5; }
.presets.is-waiting .preset { cursor: default; }
.settings-ceiling { display: flex; align-items: center; gap: 12px; }
.settings-ceiling .settings-hint { flex: 1; }
/* Tema: tre scelte in fila, quella fatta piena (il pallino del radio non si
   vede: tutta la scelta si tocca, le frecce passano dall'una all'altra). */
.settings .theme-field { gap: 8px; }
.theme-field legend { margin-bottom: 8px; font-size: var(--fs-ui); font-weight: 600; }
/* I podcast scaricati: tre scelte e, sotto, quanti e quanto spazio adesso. */
.settings .dl-field { gap: 10px; }
.dl-field legend { margin-bottom: 4px; font-size: var(--fs-ui); font-weight: 600; }
.dl-now { margin: 0; font-size: var(--fs-meta); font-weight: 600; font-variant-numeric: tabular-nums; }
/* Com'è adesso: «Automatico», il tema toccato col sole o la luna, o fisso. */
.theme-now { margin: 0; font-size: var(--fs-meta); font-weight: 600; }
/* Larghe uguali dove c'è posto; a 320 px «Automatico» si prende quello che gli serve. */
.views.theme-choice { display: grid; grid-template-columns: repeat(3, minmax(max-content, 1fr)); margin: 0; }
.theme-choice .view-tab { padding: 0 8px; font-size: var(--fs-ui); white-space: nowrap; }
/* «Risposte a voce»: come il tema; la prima scelta è lunga e, stretta, va a capo dentro di sé. */
.settings .speak-field { gap: 8px; }
.speak-field legend { margin-bottom: 8px; font-size: var(--fs-ui); font-weight: 600; }
.views.speak-choice { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr); margin: 0; }
.speak-choice .view-tab { padding: 4px 8px; font-size: var(--fs-ui); line-height: 1.2; }
/* Ricerca vocale: DeepSeek (vedi app.js). Com'è adesso (la chiave e, sotto,
   la pausa o lo spegnimento), il campo, i tre pulsanti (con la conferma di
   «Rimuovi» al loro posto) e l'esito dell'ultima azione. */
.settings .ds-field { gap: 10px; }
.ds-now { display: grid; gap: 2px; }
.ds-now-key { margin: 0; font-size: var(--fs-ui); font-weight: 600; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.ds-now-note { margin: 0; color: var(--warn-text); font-size: var(--fs-meta); font-weight: 600; }
.ds-dots { letter-spacing: .08em; }
.ds-key-field input:disabled { opacity: .5; cursor: default; }
.ds-field:has(> .confirm:not([hidden])) > .ds-actions { display: none; }
.ds-result { margin: 0; font-size: var(--fs-meta); font-weight: 600; overflow-wrap: anywhere; }
.ds-result[data-esito="attesa"] { color: var(--muted); font-weight: 400; }
.ds-result[data-esito="errore"] { color: var(--danger-text); }

/* --- player ------------------------------------------------------------- */

/* Il video occupa tutta la pagina; titolo, X e comandi gli stanno sopra e
   compaiono al tocco (.chrome-hidden li nasconde). Sempre scuro, anche col
   tema chiaro (i colori del tema scuro gli arrivano da :root, .player in cima). */
.player {
  width: 100%; /* 100vw finirebbe sotto la barra di scorrimento della pagina */
  height: 100vh;
  height: 100dvh; /* sui telefoni 100vh include le barre del browser */
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  overflow: hidden;
  background: var(--stage);
  color: var(--on-stage);
}
.player:focus { outline: none; }
/* (::backdrop non eredita le variabili nei browser vecchi.) */
.player::backdrop { background: var(--stage, #000); }
/* Il centro dei comandi (play e rotellina): a metà, un po' più sotto col solo
   audio, dove sopra stanno copertina, titolo e canale. */
.player { --mid: 50%; }
.player.is-audio-only { --mid: 57%; }
/* Col video aperto la lista dietro non scorre: chiudendo si torna dov'eri. */
html:has(#player[open]) { overflow: hidden; }
.player[open]::backdrop { animation: player-fade .28s ease-out; }
@keyframes player-fade { from { opacity: 0; } }

/* Tutto il player sta qui dentro: è questo che va a schermo intero (il
   <dialog> non può), con comandi, menu e avvisi. */
.player-frame { position: absolute; inset: 0; }
.player-frame:fullscreen { background: var(--stage); }
/* Col video, mentre si vedono i comandi, l'immagine si scurisce della metà:
   pausa e ±15 si vedono su qualunque immagine. Compare e sparisce coi comandi
   (stessi tempi); sotto i sottotitoli, che restano leggibili. Non col solo
   audio (è già scuro), né in caricamento, in pausa, dopo un errore o alla
   fine: lì c'è già lo strato del caricamento, scurito. */
.player-frame::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: var(--scrim-dim);
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s;
}
.player:not(.chrome-hidden, .is-audio-only, .is-loading, .is-paused, .has-error, .is-finished) .player-frame::before { opacity: 1; }

.player-stage { position: absolute; inset: 0; background: var(--stage); }
/* Modalità Tesla: il <video> vero (car-player-native.js), a tutto il palco
   come il disegno di ogv.js. */
.native-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; background: transparent; }

.player-overlay {
  position: absolute;
  inset: 0;
  z-index: 3;
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
}
.player.chrome-hidden .player-overlay { cursor: none; }
/* Compaiono subito (anche al Tab) e spariscono in dissolvenza. Mentre carica
   ci sono solo la rotellina e la X: i comandi arrivano dopo. */
.player-top, .player-center, .player-bottom { transition: opacity .2s, visibility 0s; }
.player.chrome-hidden :is(.player-top, .player-center, .player-bottom),
.player.is-loading:not(.is-slow) .player-center,
.player.is-loading .player-bottom {
  opacity: 0;
  visibility: hidden;
  transition: opacity .2s, visibility 0s .2s;
}

.player-top {
  position: absolute;
  inset: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 16px;
  /* Le sfumature arrivano ai bordi; titolo e X dentro le zone sicure. */
  padding: max(16px, var(--safe-top)) max(16px, var(--safe-right)) 48px max(24px, var(--safe-left));
  /* Più scuro dove sta il titolo: si legge anche sopra un video bianco. */
  background: linear-gradient(var(--scrim-deep), var(--scrim-mid) 55%, transparent);
}
.player-top h2 {
  flex: 1;
  min-width: 0;
  font-size: 20px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-shadow: 0 1px 3px var(--scrim-press);
}
/* "Passeggero · cambia": piccolo, accanto alla X. */
.player-top .player-who { flex: none; gap: 0; padding: 0 16px; font-size: 15px; font-weight: 600; }
.player-who-change { color: var(--on-stage-soft); font-weight: 500; white-space: pre; }
/* Modalità guida: lo stato del GPS accanto alla X. Da leggere, non da
   toccare: niente bordo né forma da pulsante (come LIVE); il volante giallo
   quando il GPS non c'è. */
.player-guida {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 36px;
  margin: 0;
  padding: 0 12px 0 10px;
  border-radius: var(--radius-s);
  background: var(--scrim);
  color: var(--on-stage);
  font-size: 15px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.player-guida[hidden] { display: none; }
.player-guida svg { width: 20px; height: 20px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.player-guida[data-gps="none"] svg { color: var(--warn-text); }
/* Sullo schermo del guidatore: a sinistra in alto, quieto come il canale. */
.player.is-audio-only .player-guida { padding-left: 0; background: none; color: var(--muted); }
/* Modalità Tesla: il volante resta bianco (la velocità non decide niente);
   col video fermato dall'auto, giallo come senza GPS. */
.player-guida[data-gps="blocked"] svg { color: var(--warn-text); }

/* I pulsanti tondi: sopra il video un velo nero; i colori li dà il contesto
   (--ctl-*: gli schermi quieti, "Chi guarda?"), non un selettore più forte. */
.player-btn {
  --size: 56px;
  flex: none;
  width: var(--size);
  height: var(--size);
  padding: 0;
  display: grid;
  place-items: center;
  border: 1px solid var(--ctl-line, var(--stage-line));
  border-radius: 50%;
  background: var(--ctl-bg, var(--scrim-dim));
  color: var(--on-stage);
  cursor: pointer;
  transition: transform .12s, background .12s;
}
@media (hover: hover) {
  .player-btn:hover { background: var(--ctl-hover, var(--scrim-strong)); }
}
.player-btn:active { transform: scale(.92); background: var(--ctl-press, var(--scrim-press)); }
.player-btn svg { width: 50%; height: 50%; display: block; overflow: visible; }
.player-close svg { width: 40%; height: 40%; fill: none; stroke: currentColor; stroke-width: 2.5; stroke-linecap: round; }

/* Al centro esatto dello schermo, dove sta anche la rotellina di caricamento. */
.player-center {
  position: absolute;
  top: var(--mid);
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  gap: 48px;
}
.player-toggle { --size: 96px; }
.player-toggle svg { width: 44%; height: 44%; fill: currentColor; }
.player-toggle .icon-pause, .player-toggle.is-playing .icon-play { display: none; }
.player-toggle.is-playing .icon-pause { display: block; }
.player-skip { --size: 72px; }
.player-skip svg { width: 60%; height: 60%; }
.skip-arc { fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
.skip-head { fill: currentColor; }
.player-skip text {
  fill: currentColor;
  font: 700 6.5px var(--font-ui);
  text-anchor: middle;
  dominant-baseline: middle;
}

.player-bottom {
  position: absolute;
  inset: auto 0 0;
  padding: 48px max(24px, var(--safe-right)) max(12px, var(--safe-bottom)) max(24px, var(--safe-left));
  /* Più scuro dove stanno tempo e pulsanti: si leggono anche sopra un video bianco. */
  background: linear-gradient(transparent, var(--scrim-mid) 45%, var(--scrim-deep));
  /* La sfumatura sopra la barra non prende i tocchi: col telefono in
     orizzontale sta sopra la parte bassa del play e dei ±15. */
  pointer-events: none;
}
.player-bottom > * { pointer-events: auto; }
.player-controls { display: grid; grid-template-columns: minmax(0, 1fr); }
/* La barra del tempo: 44 px da toccare, una riga di 6 px con la parte vista
   piena (--seek, da app.js) e un pallino da 22 px da trascinare col dito. */
.player-controls input[type="range"] {
  --seek: 0%;
  width: 100%;
  min-height: 44px;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.player-controls input[type="range"]::-webkit-slider-runnable-track {
  height: 6px;
  border-radius: 3px;
  background: linear-gradient(to right, var(--accent-text) var(--seek), var(--stage-seek) var(--seek));
}
.player-controls input[type="range"]::-moz-range-track { height: 6px; border-radius: 3px; background: var(--stage-seek); }
.player-controls input[type="range"]::-moz-range-progress { height: 6px; border-radius: 3px; background: var(--accent-text); }
.player-controls input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 22px;
  height: 22px;
  margin-top: -8px;
  border: 0;
  border-radius: 50%;
  background: var(--on-stage);
  box-shadow: 0 1px 4px var(--scrim-dim);
}
.player-controls input[type="range"]::-moz-range-thumb {
  width: 22px;
  height: 22px;
  border: 0;
  border-radius: 50%;
  background: var(--on-stage);
  box-shadow: 0 1px 4px var(--scrim-dim);
}
.player-controls input[type="range"]:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; border-radius: var(--radius-s); }
.player-time {
  color: var(--on-stage);
  font-size: 15px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  text-shadow: 0 1px 3px var(--scrim-press);
}
/* In diretta niente barra del tempo: al suo posto la scritta LIVE. I ±15 ci
   sono se il server tiene un pezzo di diretta da rivedere (.can-shift, vedi
   updateLiveShift in app.js); spenti al limite (aria-disabled: toccandoli si
   legge il perché). Rivista più indietro (.is-behind), al posto di LIVE quanto
   indietro, e il tocco torna in diretta. */
.player-live, #player-behind { display: none; }
.player.is-live :is(#player-seek, #player-time), .player.is-live:not(.can-shift) .player-skip { display: none; }
.player.is-live:not(.is-behind) .player-live { display: inline-flex; }
.player.is-live.is-behind #player-behind { display: inline-flex; }
.player-skip[aria-disabled="true"] { opacity: .4; cursor: default; }
.player-skip[aria-disabled="true"]:active { transform: none; }
/* (Per id: vale sopra .bar-btn, più sotto.) */
#player-behind { gap: 0; padding: 0 16px 0 14px; font-variant-numeric: tabular-nums; }
/* Un pallino spento: non è il punto più recente (LIVE ce l'ha rosso). */
#player-behind::before {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  margin-right: 8px;
  border-radius: 50%;
  background: var(--stage-dot);
}
.behind-go { font-weight: 600; white-space: pre; }

/* Barra in basso: il tempo (o LIVE) a sinistra, a destra video o solo audio,
   velocità e risoluzione; i menu si aprono sopra il pulsante. */
/* Se non ci sta (telefono stretto, video di ore) i pulsanti vanno a capo, a destra. */
.player-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; min-height: 48px; }
/* Anche i pulsanti vanno a capo, piuttosto che uscire dallo schermo. */
.bar-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 6px 8px; margin-left: auto; }
.bar-btn {
  flex: none;
  min-width: 44px;
  min-height: 44px;
  padding: 0 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 1px solid var(--bar-line, var(--stage-line));
  border-radius: 22px;
  background: var(--bar-bg, var(--scrim));
  color: var(--on-stage);
  font: inherit;
  font-size: 15px;
  font-weight: 650;
  white-space: nowrap;
  cursor: pointer;
  transition: transform .12s, background .12s;
}
.bar-btn svg {
  width: 20px;
  height: 20px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.bar-btn svg .fill { fill: currentColor; stroke: none; }
.bar-btn:active { transform: scale(.95); background: var(--bar-press, var(--scrim-press)); }
.bar-btn-value { min-width: 64px; padding: 0 14px; font-variant-numeric: tabular-nums; }
.bar-btn[aria-expanded="true"] { background: var(--on-stage); border-color: var(--on-stage); color: var(--stage); }
.bar-btn-primary { background: var(--accent-strong); border-color: var(--accent-strong); color: var(--on-accent); }
.bar-btn-primary:active { background: var(--accent-strong); }
.bar-btn-icon { width: 44px; padding: 0; }
/* Risoluzione: "Auto" col numero di adesso, più leggero; a mano solo il numero. */
.res-now { margin-left: 6px; color: var(--on-stage-soft); font-weight: 500; }
.res-now:empty { display: none; }
#bar-res[aria-expanded="true"] .res-now { color: color-mix(in srgb, var(--stage) 70%, transparent); }
.bar-btn:focus-visible, .bar-menu button:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
@media (hover: hover) {
  .bar-btn:hover { background: var(--bar-hover, var(--scrim-strong)); }
  .bar-btn[aria-expanded="true"]:hover { background: var(--on-stage); }
  .bar-btn-primary:hover { background: var(--accent-hover); }
}
/* L'icona dice cosa succede toccando: cuffie → solo audio, schermo → video. */
#bar-mode .icon-video, .player.is-audio-only #bar-mode .icon-audio { display: none; }
.player.is-audio-only #bar-mode .icon-video { display: block; }
/* Modalità guida, video non permesso: spento, come i ±15 al limite (il tocco dice perché). */
#bar-mode[aria-disabled="true"] { opacity: .45; cursor: default; }
#bar-mode[aria-disabled="true"]:active { transform: none; }
/* Schermo intero: angoli verso fuori per entrare, verso dentro per uscire. */
#bar-fullscreen svg { width: 22px; height: 22px; stroke-width: 2.2; }
#bar-fullscreen .icon-collapse, .player.is-fullscreen #bar-fullscreen .icon-expand { display: none; }
.player.is-fullscreen #bar-fullscreen .icon-collapse { display: block; }

.bar-pop { position: relative; }
/* Sopra l'ombra del suo menu. */
.bar-pop > .bar-btn { position: relative; z-index: 2; }
.bar-menu {
  position: absolute;
  right: 0;
  bottom: calc(100% + 10px);
  z-index: 1;
  min-width: 200px;
  max-height: calc(100vh - 150px);
  max-height: calc(100dvh - 150px);
  overflow: auto;
  overscroll-behavior: contain;
  display: grid;
  gap: 2px;
  padding: 6px;
  border: 1px solid var(--stage-line);
  border-radius: var(--radius);
  background: var(--stage-menu);
  box-shadow: 0 12px 36px var(--scrim);
}
.bar-menu-title { margin: 6px 12px 4px; color: var(--on-stage-faint); font-size: 15px; font-weight: 600; }
.bar-menu-note { margin: 4px 12px 6px; max-width: 22ch; color: var(--on-stage-faint); font-size: 15px; }
.bar-menu button {
  position: relative;
  min-height: 44px;
  padding: 0 18px 0 42px;
  border: 0;
  border-radius: var(--radius-s);
  background: none;
  color: var(--on-stage);
  font: inherit;
  font-size: 16px;
  font-variant-numeric: tabular-nums;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}
/* La scelta attuale: in grassetto, con la spunta. */
.bar-menu button[aria-checked="true"] { font-weight: 700; }
.bar-menu button[aria-checked="true"]::before {
  content: "";
  position: absolute;
  left: 17px;
  top: 50%;
  width: 12px;
  height: 6px;
  border-left: 2.5px solid var(--accent-text);
  border-bottom: 2.5px solid var(--accent-text);
  transform: translateY(-75%) rotate(-45deg);
}
.bar-menu button:disabled { color: var(--on-stage-off); cursor: default; }
.bar-menu button:not(:disabled):active { background: var(--stage-line); }
@media (hover: hover) {
  .bar-menu button:not(:disabled):hover { background: var(--stage-veil); }
}

/* Sottotitoli: il pulsante CC, pieno quando sono accesi. Il menu ha i
   sottotitoli del video (nomi lunghi: vanno a capo) e, sotto, le dimensioni
   una accanto all'altra. */
#bar-subs svg { width: 24px; height: 24px; stroke-width: 1.9; }
#bar-subs.is-on svg rect { fill: currentColor; }
#bar-subs.is-on svg path { stroke: var(--stage); }
#bar-subs.is-on[aria-expanded="true"] svg path { stroke: var(--on-stage); }
.bar-menu-subs { min-width: 272px; max-width: calc(100vw - 24px); }
.bar-menu-subs > button { padding-top: 8px; padding-bottom: 8px; line-height: 1.25; white-space: normal; }
.bar-menu-hint { color: var(--on-stage-faint); font-weight: 400; }
.bar-menu-sep { height: 1px; margin: 4px 8px; background: var(--stage-veil); }
.bar-menu-sizes { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; }
.bar-menu .bar-menu-sizes button { padding: 0 6px; text-align: center; }
.bar-menu .bar-menu-sizes button[aria-checked="true"] {
  background: var(--stage-veil);
  box-shadow: inset 0 0 0 2px var(--accent-text);
}
.bar-menu .bar-menu-sizes button[aria-checked="true"]::before { content: none; }

/* "Mostra video" dal solo audio: la barra diventa la conferma. */
.player-bar.is-confirming > :not(.bar-confirm) { display: none !important; }
.bar-confirm {
  flex: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 8px 12px;
}
.bar-confirm-text { margin: 0; font-size: 16px; font-weight: 600; text-shadow: 0 1px 4px var(--scrim-mid); }
.live-pill {
  align-items: center;
  gap: 8px;
  min-height: 32px;
  padding: 0 12px;
  border-radius: var(--radius-s);
  font-size: 15px;
}
.live-pill::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
}
/* Dati tecnici: in alto a sinistra, sotto il titolo; restano anche quando
   i comandi spariscono (sono per chi prova il player). */
.player-diag {
  position: absolute;
  top: 88px;
  left: max(24px, var(--safe-left));
  z-index: 4;
  max-width: calc(100% - 48px - var(--safe-left) - var(--safe-right));
  padding: 6px 10px;
  border-radius: var(--radius-s);
  background: var(--scrim-mid);
  color: var(--on-stage-muted);
  font: 14px/1.35 ui-monospace, monospace;
  white-space: pre-wrap;
  pointer-events: none;
}
/* Avviso sopra il video (la notifica della pagina starebbe sotto il player). */
.player-toast {
  position: absolute;
  top: 88px;
  left: 50%;
  z-index: 4;
  transform: translateX(-50%);
  width: max-content;
  max-width: min(640px, calc(100% - 32px));
  margin: 0;
  padding: 12px 18px;
  border-radius: var(--radius);
  background: var(--stage-toast);
  border: 1px solid var(--stage-line);
  box-shadow: 0 8px 30px var(--scrim-dim);
  font-size: 17px;
  text-align: center;
  pointer-events: none;
}
.player-diag:not([hidden]) ~ .player-toast { top: 150px; }

/* Sottotitoli sopra il video: bianchi su una fascia scura riga per riga (si
   leggono su qualunque immagine), in proporzione all'altezza del player (tutta
   la pagina, o tutto lo schermo), senza che una riga di 42 caratteri vada a
   capo (in Media e Piccola; Grande in una finestra stretta sì). Dove stanno lo
   decide app.js (subsPlace): in basso al centro, sollevati sopra i comandi
   quando si vedono (--subs-lift), o subito sotto l'immagine quando sotto c'è
   una banda nera che li contiene (.is-below, --subs-top). Mai col solo audio. */
.player-subs {
  --subs-scale: 1;
  position: absolute;
  inset: auto 0 0;
  z-index: 2;
  padding: 0 max(4%, var(--safe-right)) 0 max(4%, var(--safe-left));
  text-align: center;
  pointer-events: none;
  transform: translateY(var(--subs-lift, calc(-1 * max(14px, 4vh) - var(--safe-bottom))));
  transition: transform .2s ease;
}
.player-subs.is-below { top: var(--subs-top); bottom: auto; transform: none; }
.player-subs.no-anim { transition: none; }
.player-subs[data-size="s"] { --subs-scale: .8; }
.player-subs[data-size="l"] { --subs-scale: 1.25; }
.player.is-audio-only .player-subs { display: none; }
.player-subs-text {
  padding: .06em .4em;
  border-radius: 4px;
  background: var(--scrim-strong);
  color: var(--on-stage);
  /* 4,2% dell'altezza; al massimo 3,6% della larghezza: la riga più larga dei
     sottotitoli veri (42 caratteri, ~24 em con un font largo) sta nel 92%. */
  font-size: calc(var(--subs-scale) * clamp(14px, min(4.2vh, 3.6vw), 56px));
  font-size: calc(var(--subs-scale) * clamp(14px, min(4.2dvh, 3.6vw), 56px));
  font-weight: 500;
  line-height: 1.42;
  white-space: pre-line;
  overflow-wrap: break-word;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  text-shadow: 0 0 3px var(--scrim-strong);
}

/* Il canvas del disegno nitido riempie il palco. */
.car-sink {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: var(--stage);
}

/* Caricamento: la miniatura, e sopra rotellina, frase e barra delle fasi.
   Lo stesso strato mostra l'errore se il video non parte. */
.player-loading {
  position: absolute;
  inset: 0;
  z-index: 1;
  opacity: 0;
  visibility: hidden;
  transition: opacity .35s, visibility .35s;
}
.player.is-loading .player-loading, .player.has-error .player-loading { opacity: 1; visibility: visible; }
.player-poster { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.player-loading::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 55%, var(--scrim-strong), var(--scrim-light) 70%);
}
.loading-text {
  position: absolute;
  top: calc(var(--mid) + 80px);
  left: 16px;
  right: 16px;
  z-index: 1;
  display: grid;
  justify-items: center;
  gap: 6px;
  text-align: center;
  text-shadow: 0 1px 4px var(--scrim-mid);
}
.loading-title { margin: 0; font-size: 22px; font-weight: 650; }
.loading-step { margin: 0; color: var(--on-stage-muted); font-size: 16px; }
.loading-bar {
  width: min(240px, 60vw);
  height: 4px;
  margin-top: 10px;
  border-radius: 2px;
  background: var(--stage-line);
  overflow: hidden;
}
.loading-fill {
  display: block;
  height: 100%;
  width: 100%;
  border-radius: inherit;
  background: var(--accent);
  /* Cresce con transform (vedi showLoadingStep): niente ricalcolo del layout. */
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .6s ease-out;
}
/* Errore o fine del video: la frase sta nel blocco del messaggio (sopra i
   comandi, con i pulsanti); di questo strato resta l'immagine scurita. */
.player:is(.has-error, .is-finished) .loading-text { display: none; }
.player.is-finished .player-loading { opacity: 1; visibility: visible; }
/* Diretta in pausa: la sessione è chiusa, restano miniatura, frase e play. */
.player.is-paused .player-loading { opacity: 1; visibility: visible; }
.player.is-paused .loading-bar { display: none; }

/* Canale TV: al posto della miniatura il logo, piccolo e intero, sopra il
   play (e la rotellina), fuori dalla sfumatura scura. */
.player.is-tv .player-poster {
  z-index: 1;
  inset: auto auto calc(100% - var(--mid) + 84px) 50%;
  width: auto;
  height: auto;
  max-width: min(220px, 50%);
  max-height: min(120px, calc(var(--mid) - 84px - 88px));
  transform: translateX(-50%);
}

/* --- errore, diretta finita, fine del video -------------------------------- */
/* Al centro, sopra l'immagine scurita: titolo (per causa), frase, la scelta
   principale e "Chiudi" (bersagli da 52 px). Alla fine del video una riga
   sottile si svuota fino alla chiusura. */
.player-message {
  position: absolute;
  top: 50%;
  left: max(16px, var(--safe-left));
  right: max(16px, var(--safe-right));
  z-index: 2;
  transform: translateY(-50%);
  display: grid;
  justify-items: center;
  gap: 8px;
  text-align: center;
  text-shadow: 0 1px 4px var(--scrim-mid);
}
.message-title { margin: 0; font-size: 24px; font-weight: 650; text-wrap: balance; }
/* Un errore in rosso chiaro (7:1 sul nero); fine del video e diretta finita no. */
.player.has-error:not(.is-ended) .message-title { color: var(--stage-danger); }
.message-text {
  margin: 0;
  max-width: 46ch;
  color: var(--on-stage-muted);
  font-size: 17px;
  line-height: 1.4;
  text-wrap: pretty;
}
.player.is-finished .message-text {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.message-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: 14px; }
.message-btn { min-height: 52px; padding: 0 22px; border-radius: 26px; font-size: 17px; }
.message-btn svg { width: 22px; height: 22px; }
#message-primary .icon-replay, #message-primary[data-icon="replay"] .icon-retry { display: none; }
#message-primary[data-icon="replay"] .icon-replay { display: block; }
.message-countdown {
  width: min(200px, 50vw);
  height: 4px;
  margin-top: 14px;
  border-radius: 2px;
  background: var(--stage-line);
  overflow: hidden;
}
.message-countdown > span {
  display: block;
  height: 100%;
  background: color-mix(in srgb, var(--on-stage) 70%, transparent);
  transform-origin: left;
  animation: message-countdown var(--countdown, 10s) linear forwards;
}
@keyframes message-countdown { to { transform: scaleX(0); } }

/* --- solo audio (chi guida) ------------------------------------------------ */
/* Lo schermo più quieto dell'app: fondo quasi nero, nessuna immagine grande
   (di notte abbaglierebbe, e attira lo sguardo), la copertina piccola e
   scura, titolo e canale grandi, "Solo audio" scritto in chiaro (non un
   pulsante: quello, in basso, dice "Mostra video"). I comandi sono grandi
   (play 128 px, salti 88) e non spariscono mai (vedi canHideChrome); stanno
   un po' sotto la metà, sopra c'è il titolo. */
.player-now { display: none; }
.player.is-audio-only { --toggle: 128px; background: var(--stage-quiet); }
.player.is-audio-only :is(.player-stage, .player-loading) { background: var(--stage-quiet); }
/* Modalità guida in movimento: il video continua sotto questo schermo (vedi
   guidaHide in app.js), e del palco non si vede niente, nemmeno l'ultimo
   fotogramma di un salto. opacity anche per un figlio con visibility:
   visible; !important contro gli stili in linea di ogv.js. */
.player.is-audio-only .player-stage > :not(.native-video) { visibility: hidden !important; opacity: 0 !important; }
/* Modalità Tesla col video fermato dall'auto: il <video> resta com'è (lo
   stile non lo tocca mai: se l'auto lo nasconde, resta nascosto, e le prove
   del player guardano proprio questo), sotto uno strato quieto come il fondo
   di questo schermo. */
.player.is-tesla-blocked .player-stage::after { content: ""; position: absolute; inset: 0; background: var(--stage-quiet); }
.player.is-audio-only .player-poster { display: none; }
.player.is-audio-only .player-loading::after { content: none; }
.player.is-audio-only :is(.player-top, .player-bottom) { background: none; }
/* Il titolo grande è qui sotto: quello in alto resta per i lettori di schermo. */
.player.is-audio-only .player-top h2 {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}
/* La X (ferma e chiude) si tocca anche in movimento: 64 px, come la barra
   in basso (60). */
.player.is-audio-only .player-close { --size: 64px; margin-left: 0; }
.player.is-audio-only .player-bar { min-height: 60px; }
.player.is-audio-only .bar-btn { min-height: 60px; border-radius: 30px; }
.player.is-audio-only .bar-btn-icon { width: 60px; }
/* Velocità ("1×"): tonda anche stretta, come le altre da 60. */
:is(.player.is-audio-only, .listen-screen) .bar-btn-value { min-width: 64px; }
.player.is-audio-only .player-now {
  position: absolute;
  top: 84px;
  left: max(24px, var(--safe-left));
  right: max(24px, var(--safe-right));
  bottom: calc(100% - var(--mid) + var(--toggle) / 2 + 28px);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
  overflow: hidden;
  text-align: center;
  pointer-events: none;
}
.player.is-audio-only:is(.has-error, .is-finished) .player-now { visibility: hidden; }
/* Un contenitore (alto quanto lo spazio sopra i comandi): col titolo su due
   righe (72), il canale (28), lo stato (30) e gli spazi (18), sotto i 200 px
   la copertina resterebbe sotto i 40 px (a 773×601 una striscia di 7 px):
   niente copertina, come nell'ascolto (vedi @container ls-now). */
.player.is-audio-only .player-now { container: player-now / size; }
@container player-now (max-height: 199px) {
  .player-now .player-art { display: none; }
}
/* Poco spazio: si stringe la copertina, mai le righe di testo. */
.player-now > p { flex: none; }
.player-now .player-art {
  flex: 0 1 auto;
  min-height: 0;
  width: auto;
  height: auto;
  max-width: min(200px, 40vw);
  max-height: 112px;
  margin-bottom: 12px;
  border-radius: var(--radius-m);
  object-fit: contain;
  filter: brightness(.55) saturate(.6);
}
/* Il logo di un canale TV: intero, appena scurito. */
.player.is-tv .player-now .player-art { max-height: 64px; border-radius: 0; filter: brightness(.85); }
/* Un logo scuro (Discovery): sul fondo chiaro, come nella sua scheda. */
.player.is-tv.is-dark-logo :is(.player-poster, .player-now .player-art) {
  padding: 8px 12px;
  border-radius: var(--radius-s);
  background: var(--logo-light);
  filter: none;
}
/* Un logo con tanto margine trasparente, ritagliato sulla parte disegnata
   (cropTvLogo in app.js): alto come gli altri, non piccolo com'è nell'immagine. */
@supports (object-view-box: inset(0)) {
  .player.is-tv.is-cropped-logo .player-poster { height: min(80px, calc(var(--mid) - 84px - 88px)); }
  .player.is-tv.is-cropped-logo .player-now .player-art { height: 56px; }
}
.now-title {
  margin: 0;
  max-width: 32ch;
  color: var(--text);
  font-size: 30px;
  font-weight: 650;
  line-height: 1.2;
  text-wrap: balance;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.now-channel {
  max-width: 100%;
  margin: 0;
  color: var(--muted);
  font-size: 20px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.now-status {
  margin: 6px 0 0;
  display: flex;
  align-items: center;
  gap: 14px;
  color: var(--muted);
  font-size: 17px;
  font-weight: 600;
}
.now-mode { min-width: 0; text-wrap: balance; }
/* «Video fermato dall'auto in marcia · l'audio continua»: una riga nell'auto
   (col LIVE accanto), due al centro sul telefono. */
.player.is-tesla-blocked .now-status { flex-wrap: wrap; justify-content: center; row-gap: 4px; }
.now-live { display: none; align-items: center; gap: 7px; color: var(--text); font-weight: 700; letter-spacing: .06em; }
.now-live::before { content: ""; width: 10px; height: 10px; border-radius: 50%; background: var(--live); }
.player.is-live:not(.is-behind) .now-live { display: inline-flex; }
/* Rivista più indietro: quanto, al posto di LIVE ("Torna in diretta" è in basso). */
.now-behind { display: none; color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Stretto (320 px): "−0:15 dalla diretta" va a capo intero, sotto "Solo audio". */
.player.is-live.is-behind .now-status { flex-wrap: wrap; justify-content: center; row-gap: 2px; }
.player.is-live.is-behind .now-behind { display: inline; }
/* LIVE c'è già sotto il titolo: non anche in basso. */
.player.is-audio-only.is-live .player-live { display: none; }
.player.is-audio-only .player-center { gap: 44px; }
.player.is-audio-only .player-toggle { --size: var(--toggle); }
.player.is-audio-only .player-skip { --size: 88px; }
/* Pulsanti pieni, grigi: sul nero si vedono senza accendere lo schermo. Lo
   stesso nello schermo dell'ascolto: i colori dei pulsanti tondi (vedi
   .player-btn) li dà questo contesto, il play un gradino più chiaro. */
.player.is-audio-only, .listen-screen { --ctl-bg: var(--surface); --ctl-line: var(--border); --ctl-hover: var(--surface-2); --ctl-press: var(--border); }
:is(.player.is-audio-only, .listen-screen) .player-toggle { --ctl-bg: var(--surface-2); --ctl-hover: var(--border); }
/* La rotellina gira attorno al play, più grande. */
.player.is-audio-only .player-spinner {
  --spin: calc(var(--toggle) + 28px);
  width: var(--spin);
  height: var(--spin);
  margin: calc(var(--spin) / -2) 0 0 calc(var(--spin) / -2);
}
.player.is-audio-only .loading-text { top: calc(var(--mid) + var(--toggle) / 2 + 36px); }
/* I testi secondari (il tempo, "Guida attiva · 46 km/h", «Mostra video», «1×»),
   come quelli dello schermo dell'ascolto: 18 px nell'auto (vedi
   --fs-stage-meta). Non «Riprova» e «Chiudi» dell'errore: hanno i loro 17. */
.player.is-audio-only :is(.player-time, .player-guida, .bar-btn:not(.message-btn)),
.listen-screen :is(.ls-kind, .ls-time, .bar-btn:not(.message-btn)) { font-size: var(--fs-stage-meta); }

/* --- "Chi guarda?" ------------------------------------------------------ */

.who {
  inset: var(--safe-top) var(--safe-right) var(--safe-bottom) var(--safe-left); /* al centro della zona sicura */
  width: min(560px, calc(100vw - 24px - var(--safe-left) - var(--safe-right)));
  max-height: calc(100vh - 24px);
  max-height: calc(100dvh - 24px - var(--safe-top) - var(--safe-bottom));
  overflow: auto;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-dialog);
}
/* Il margine interno sta qui: un tocco sul <dialog> stesso è fuori dal riquadro. */
.who-box { padding: 20px; }
.who::backdrop { background: rgb(0 0 0 / .7); }
.who-head { display: flex; align-items: center; gap: 12px; }
.who-head h2 { flex: 1; font-size: var(--fs-title-l); }
/* La X è un pulsante tondo del player, coi colori del tema. */
.who-close { --size: 44px; --ctl-bg: var(--raised); --ctl-line: var(--border); --ctl-hover: var(--hover); --ctl-press: var(--hover); color: var(--text); }
@media (hover: hover) {
  .who-choice:hover { background: var(--hover); }
}
.who-close svg { width: 40%; height: 40%; fill: none; stroke: currentColor; stroke-width: 2.5; stroke-linecap: round; }
.who-video {
  margin: 4px 0 0;
  color: var(--muted);
  font-size: var(--fs-ui);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.who-text { margin: 12px 0 16px; font-size: var(--fs-ui); }
.who-choices { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.who-choice {
  min-height: 128px;
  padding: 14px 10px;
  display: grid;
  justify-items: center;
  align-content: center;
  gap: 4px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--raised);
  color: var(--text);
  font: inherit;
  cursor: pointer;
  transition: transform .12s, background .12s;
}
.who-choice:active { transform: scale(.97); background: var(--hover); }
.who-choice svg {
  width: 44px;
  height: 44px;
  margin-bottom: 4px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.who-choice svg .fill { fill: currentColor; stroke: none; }
.who-choice-name { font-size: var(--fs-title); font-weight: 650; }
.who-choice-hint { color: var(--muted); font-size: var(--fs-ui); }

/* --- profili: il riquadro, «Chi sei?», il menu, Impostazioni → Profili ------- */
/* Un profilo è l'iniziale sul suo colore, in un cerchio (vedi profileAvatar in
   app.js): grande in «Chi sei?» (64 px), 32-48 nel menu e nelle Impostazioni,
   20 sull'angolo del pulsante ⋯ (con più profili, per sapere di chi è quello
   che si vede). Bianco sopra, sempre almeno 5:1. */
.avatar {
  --avatar: var(--profile-blu);
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--avatar);
  color: #fff;
  font-size: 17px;
  font-weight: 750;
  line-height: 1;
  text-transform: uppercase;
  user-select: none;
}
.avatar[data-color="verde"] { --avatar: var(--profile-verde); }
.avatar[data-color="viola"] { --avatar: var(--profile-viola); }
.avatar[data-color="rosso"] { --avatar: var(--profile-rosso); }
.avatar[data-color="arancio"] { --avatar: var(--profile-arancio); }
.avatar[data-color="acqua"] { --avatar: var(--profile-acqua); }
.avatar[data-color="rosa"] { --avatar: var(--profile-rosa); }
.avatar[data-color="grigio"] { --avatar: var(--profile-grigio); }
/* Sull'angolo del pulsante ⋯, fuori dal suo bordo: il segno del menu resta intero. */
.menu-avatar {
  position: absolute;
  top: -6px;
  right: -4px;
  width: 20px;
  height: 20px;
  font-size: 12px;
  box-shadow: 0 0 0 2px var(--bg);
  pointer-events: none;
}
/* Nel menu ⋯, in cima: «Profilo: Marco» e, a destra, «Cambia» (un nome lungo
   si accorcia coi puntini, «Cambia» resta). */
.menu-panel .menu-profile { min-width: 0; gap: 10px; min-height: 52px; padding: 6px 14px 6px 8px; }
.menu-profile .avatar { width: 32px; height: 32px; font-size: 15px; }
.menu-profile-text { flex: 1; min-width: 0; display: flex; font-weight: 500; }
.menu-profile-text strong { min-width: 0; overflow: hidden; text-overflow: ellipsis; font-weight: 700; }
.menu-profile-change { flex: none; margin-left: 6px; color: var(--accent-text); font-weight: 650; }

/* «Chi sei?»: il foglio di «Chi guarda?», largo quanto servono i riquadri
   (data-n: quanti per riga, al massimo 4; sul telefono 2, a metà schermo 3).
   Un riquadro è tutto un pulsante (nell'auto 160 × 140 px), quello di qui col
   bordo d'accento e «In uso qui». */
.profile-pick { width: min(400px, calc(100vw - 24px - var(--safe-left) - var(--safe-right))); }
.profile-pick:focus { outline: none; } /* il foglio stesso, col fuoco dopo il login */
.profile-pick[data-n="3"] { width: min(560px, calc(100vw - 24px - var(--safe-left) - var(--safe-right))); }
.profile-pick[data-n="4"] { width: min(740px, calc(100vw - 24px - var(--safe-left) - var(--safe-right))); }
.chi-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin: 0; padding: 0; list-style: none; }
.profile-pick[data-n="3"] .chi-list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.profile-pick[data-n="4"] .chi-list { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.chi-tile {
  width: 100%;
  height: 100%;
  min-height: 140px;
  padding: 16px 10px 14px;
  display: grid;
  justify-items: center;
  align-content: center;
  gap: 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--raised);
  color: var(--text);
  font: inherit;
  cursor: pointer;
  transition: transform .12s, background .12s;
}
.avatar-chi { width: 64px; height: 64px; font-size: 30px; }
.chi-name { max-width: 100%; font-size: var(--fs-lead); font-weight: 650; line-height: 1.25; text-align: center; overflow-wrap: anywhere; }
/* «In uso qui» c'è in ogni riquadro (negli altri non si vede): i cerchi alla stessa altezza. */
.chi-here { color: var(--accent-text); font-size: var(--fs-meta); font-weight: 650; }
.chi-tile[aria-pressed="false"] .chi-here { visibility: hidden; }
/* Nessuno è di qui (dopo il login): niente riga da tenere. */
.chi-list:not(:has(.chi-tile[aria-pressed="true"])) .chi-here { display: none; }
.chi-tile[aria-pressed="true"] {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, var(--raised));
}
.chi-tile:active { transform: scale(.97); background: var(--hover); }
.chi-tile:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
@media (hover: hover) {
  .chi-tile:hover { background: var(--hover); }
}
.chi-tile.is-pending { opacity: .6; cursor: progress; }
.chi-list.is-busy .chi-tile { cursor: progress; }
.chi-error { margin: 14px 0 0; font-size: var(--fs-ui); }
.chi-manage { width: 100%; margin-top: 16px; }

/* Impostazioni → Profili: una riga per profilo (il riquadro, il nome,
   «Modifica»; appena creato anche «Usalo qui»); l'editor sotto la riga del
   profilo che si cambia, col bordo d'accento: nome e iniziale accanto
   all'anteprima, i colori in tondi da 48 px, «Elimina» a sinistra e
   «Annulla» «Salva profilo» a destra. */
.prof-list { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.prof-row {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 58px;
  padding: 6px 6px 6px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.prof-row-text { flex: 1; min-width: 0; display: grid; gap: 2px; }
.prof-row-name { font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prof-row-here { color: var(--accent-text); font-size: var(--fs-meta); font-weight: 600; }
.prof-edit-item { display: grid; }
.prof-editor {
  display: grid;
  gap: 14px;
  padding: 14px;
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--accent) 7%, var(--surface));
}
.prof-editor-title { margin: 0; font-weight: 650; overflow-wrap: anywhere; }
.prof-editor-row { display: grid; grid-template-columns: auto minmax(0, 1fr) 92px; align-items: end; gap: 12px; }
.avatar-edit { width: 48px; height: 48px; font-size: 22px; }
.prof-initial-field input { text-align: center; text-transform: uppercase; }
.settings .prof-colors-field { gap: 8px; }
.prof-colors-field legend { margin-bottom: 6px; font-size: var(--fs-ui); font-weight: 600; }
.prof-swatches { display: flex; flex-wrap: wrap; gap: 6px; }
.prof-swatch { position: relative; display: grid; place-items: center; width: 48px; height: 48px; border-radius: 50%; cursor: pointer; }
.prof-swatch input { position: absolute; inset: 0; width: 100%; height: 100%; min-height: 0; margin: 0; padding: 0; opacity: 0; cursor: pointer; }
.prof-swatch-dot { width: 34px; height: 34px; pointer-events: none; transition: box-shadow .12s; }
/* Quello scelto: un anello del colore del testo, staccato dal tondo. */
.prof-swatch:has(input:checked) .prof-swatch-dot { box-shadow: 0 0 0 3px var(--surface), 0 0 0 5px var(--text); }
.prof-swatch:has(input:focus-visible) { outline: 3px solid var(--accent); outline-offset: 1px; }
.prof-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
/* Mentre si conferma «Elimina», solo la conferma (un «Annulla» solo). */
.prof-editor:has(> .confirm:not([hidden])) > .prof-actions { display: none; }
.prof-actions-end { display: flex; gap: 8px; margin-left: auto; }
.prof-add { justify-self: start; }
@media (prefers-reduced-motion: reduce) {
  .chi-tile, .prof-swatch-dot { transition: none; }
}
@media (max-width: 700px) {
  .profile-pick[data-n="4"] { width: min(560px, calc(100vw - 24px - var(--safe-left) - var(--safe-right))); }
  .profile-pick[data-n="4"] .chi-list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 480px) {
  .profile-pick[data-n] { width: min(400px, calc(100vw - 24px - var(--safe-left) - var(--safe-right))); }
  .profile-pick[data-n] .chi-list { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .chi-tile { min-height: 124px; padding: 14px 8px 12px; }
  .avatar-chi { width: 56px; height: 56px; font-size: 26px; }
  .prof-editor { padding: 12px; }
  .prof-editor-row { grid-template-columns: auto minmax(0, 1fr) 72px; gap: 10px; }
  .prof-actions .btn { flex: 1; }
  .prof-actions-end { flex: 2; }
  /* «Usalo qui» sotto la riga, largo: il nome resta leggibile accanto a «Modifica». */
  .prof-row:has(.prof-use) { flex-wrap: wrap; row-gap: 8px; }
  .prof-use { order: 1; flex: 1 1 100%; }
}

/* Schermo intero su iPhone (#app-hint, vedi app.js): il foglio di «Chi
   guarda?», più stretto (righe di 40-45 caratteri). I tre passi col loro
   segno a sinistra, nel colore dei pulsanti di Safari; l'ultimo è l'icona di
   Videoteca, quella che si cerca sulla schermata Home. «Ho capito» in fondo,
   largo quanto il foglio. */
.app-hint { width: min(440px, calc(100vw - 24px - var(--safe-left) - var(--safe-right))); }
.app-hint-steps { display: grid; gap: 12px; margin: 0 0 20px; padding: 0; list-style: none; }
.app-hint-steps li { display: flex; align-items: center; gap: 14px; font-size: var(--fs-ui); line-height: 1.35; }
.app-hint-steps strong { font-weight: 650; }
.app-hint-mark { flex: none; display: grid; place-items: center; width: 44px; height: 44px; border-radius: var(--radius-m); }
span.app-hint-mark { background: var(--surface-2); color: var(--accent-text); }
.app-hint-mark svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.app-hint-ok { width: 100%; }

/* Rotellina: stessa posizione e stesso centro del pulsante play/pausa, che
   se compare le sta dentro. Serve anche quando il video si ferma a caricare. */
.player-spinner {
  position: absolute;
  top: var(--mid);
  left: 50%;
  z-index: 2;
  width: 120px;
  height: 120px;
  margin: -60px 0 0 -60px;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity .25s, visibility .25s;
  animation: spinner-turn 1.6s linear infinite;
}
.player:is(.is-loading, .is-buffering):not(.has-error, .is-finished) .player-spinner { opacity: 1; visibility: visible; }
.spinner-track { fill: none; stroke: var(--stage-line); stroke-width: 3; }
.spinner-arc {
  fill: none;
  stroke: var(--accent);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-dasharray: 1 140;
  animation: spinner-dash 1.6s ease-in-out infinite;
}
/* Ferma quando non si vede: altrimenti ricalcola lo stile a ogni fotogramma
   per tutta la visione, accanto a ogv.js che lavora sullo stesso thread. */
.player-spinner, .spinner-arc { animation-play-state: paused; }
.player:is(.is-loading, .is-buffering):not(.has-error, .is-finished) :is(.player-spinner, .spinner-arc) {
  animation-play-state: running;
}
@keyframes spinner-turn { to { transform: rotate(360deg); } }
@keyframes spinner-dash {
  0% { stroke-dasharray: 1 140; stroke-dashoffset: 0; }
  50% { stroke-dasharray: 90 140; stroke-dashoffset: -30; }
  100% { stroke-dasharray: 90 140; stroke-dashoffset: -137; }
}

@media (prefers-reduced-motion: reduce) {
  .player[open]::backdrop { animation: none; }
  .loading-fill, .player-btn, .bar-btn, .who-choice, .fav::before, .fav svg, .player-subs { transition: none; }
  /* La riga della fine del video resta piena: si chiude lo stesso da sola. */
  .message-countdown > span { animation: none; }
}

/* --- Ascolta: podcast e radio ------------------------------------------------ */
/* Sotto "Podcast | Radio" (la stessa scelta di "In diretta | On demand"), la
   ricerca e i blocchi della home, ognuno col suo titolo piccolo: «Continua ad
   ascoltare» (la riga che scorre, come «Continua a guardare»), «Iscritti» e
   «Popolari» (coi generi in fila). Le schede dei podcast sono come quelle dei
   canali TV: la copertina quadrata a sinistra (più grande nelle schede
   larghe), a destra titolo, autore e quanti episodi; nelle schede strette la
   copertina va sopra. */
.pod-block { margin-bottom: 28px; }
.pod-home > .pod-block:last-child { margin-bottom: 0; }
.pod-block-head { display: flex; align-items: baseline; gap: 10px; margin: 0 0 12px; }
.pod-block-head h3 { margin: 0; font-size: var(--fs-lead); font-weight: 650; }
/* Lo stato vuoto dentro un blocco (Iscritti): il titolo sotto il titoletto
   del blocco, grande come il testo (15 px sul telefono, dove sta su una riga
   anche a 320), distinto solo dal peso. */
.pod-block .empty-state .empty-state-title { font-size: inherit; }
.pod-genres { margin: -4px -4px 10px; }

.pod-card, .pod-cont { container-type: inline-size; }
.pod-open {
  all: unset;
  box-sizing: border-box;
  flex: 1;
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 12px;
  cursor: pointer;
}
.pod-open:focus-visible { outline: none; }
.card:has(> .pod-open:focus-visible) { outline: 3px solid var(--accent); outline-offset: 2px; }
.pod-open:active .pod-art { opacity: .8; }
@media (hover: hover) {
  .pod-open:hover { background: color-mix(in srgb, var(--surface-2) 55%, var(--surface)); }
  .pod-open:hover .pod-art img { filter: brightness(1.1); }
}
/* La copertina: quadrata, più grande nelle schede larghe. Senza (o se non
   arriva) il simbolo dell'app, come le miniature mancanti. */
.pod-art {
  position: relative;
  flex: none;
  display: block;
  width: clamp(64px, 30cqi, 112px);
  aspect-ratio: 1;
  border-radius: var(--radius-s);
  background: var(--surface-2);
}
.pod-art img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: inherit; display: block; }
.pod-art.no-art img, .ls-art.no-art img, .mini-art.no-art img { visibility: hidden; }
/* Il segno dell'app (vedi .no-thumb più in alto), al 40% del riquadro. */
.pod-art.no-art::after, .ls-art.no-art::after, .mini-art.no-art::after, .riprendi-art.no-art::after { width: 40%; height: 40%; }
/* I nuovi episodi di un iscritto: un numero sull'angolo della copertina. */
.pod-badge {
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 24px;
  height: 24px;
  padding: 0 7px;
  border-radius: 12px;
  background: var(--accent-strong);
  color: var(--on-accent);
  font-size: var(--fs-meta);
  font-weight: 700;
  line-height: 24px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  box-shadow: 0 0 0 2px var(--surface);
}
.pod-text { flex: 1; min-width: 0; display: grid; gap: 3px; align-content: start; padding-top: 1px; }
.pod-name {
  font-weight: 650;
  line-height: 1.3;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.pod-by { color: var(--muted); font-size: var(--fs-meta); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pod-info { color: var(--muted); font-size: var(--fs-meta); line-height: 1.35; font-variant-numeric: tabular-nums; }
.pod-part { white-space: nowrap; }
/* Un feed che non pubblica da mesi: "fermo dal 18 ott 2021". */
.pod-stale { color: var(--warn-text); font-weight: 600; }
/* Schede strette (le più piccole, due colonne sul telefono): la copertina sopra, larga. */
@container (max-width: 229px) {
  .pod-card .pod-open { flex-direction: column; gap: 10px; }
  .pod-card .pod-art { width: 100%; }
}

/* «Continua ad ascoltare»: copertina, episodio e podcast, la barra di quanto
   si è sentito, quanto manca e "Rimuovi". */
.pod-cont .pod-open { padding-bottom: 10px; }
.pod-cont .pod-art { width: clamp(56px, 24cqi, 88px); }
.pod-cont-bar { display: block; height: 4px; margin: 0 12px 4px; border-radius: 2px; background: var(--track); overflow: hidden; }
.pod-cont-bar .resume-fill, .pod-ep-bar .resume-fill, .mini-progress > span { background: var(--accent-text); }
.pod-cont.is-current, .pod-ep.is-current, .radio-card.is-current { border-color: color-mix(in srgb, var(--accent) 60%, var(--border)); }

/* La pagina di un podcast: copertina e, accanto, titolo, autore, genere,
   episodi e l'ultimo, "Riproduci" e "Iscriviti"; sotto la descrizione (poche
   righe, "Mostra tutto"), "Tutti | Da ascoltare" e gli episodi. */
.pod-hero { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 20px; align-items: start; margin: 0 0 18px; }
.pod-hero-art { width: clamp(112px, 20vw, 184px); border-radius: var(--radius); }
.pod-hero-text { display: grid; gap: 4px; align-content: start; min-width: 0; }
.pod-title { margin: 0; font-size: var(--fs-display); font-weight: 650; line-height: 1.2; text-wrap: balance; overflow-wrap: anywhere; }
.pod-title:focus { outline: none; }
.pod-author { margin: 0; color: var(--muted); font-size: var(--fs-body); }
.pod-meta { margin: 2px 0 0; color: var(--muted); font-size: var(--fs-meta); font-variant-numeric: tabular-nums; }
.pod-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 12px; }
.pod-actions:not(:has(> :not([hidden]))) { display: none; }
.pod-actions svg { width: 20px; height: 20px; flex: none; }
#pod-play svg { fill: currentColor; }
.pod-sub svg { fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.pod-sub .icon-check, .pod-sub[aria-pressed="true"] .icon-plus { display: none; }
/* «Scarica i nuovi episodi» acceso: su questo dispositivo, quanti. */
.pod-auto-note { margin: 8px 0 0; color: var(--muted); font-size: var(--fs-meta); }
/* Gli automatici fermi (lo spazio): il perché, come sotto «Scaricati». */
.pod-auto-stop { color: var(--warn-text); font-weight: 600; }
.pod-sub[aria-pressed="true"] .icon-check { display: block; }
.pod-sub[aria-pressed="true"] {
  border-color: color-mix(in srgb, var(--accent) 70%, var(--border));
  background: color-mix(in srgb, var(--accent) 16%, var(--raised));
}
@media (hover: hover) {
  .pod-sub[aria-pressed="true"]:hover:not(:disabled) { background: color-mix(in srgb, var(--accent) 26%, var(--raised)); }
}
.pod-about { max-width: 72ch; margin: 0 0 14px; }
.pod-desc {
  margin: 0;
  color: var(--muted);
  line-height: 1.5;
  white-space: pre-line;
  overflow-wrap: break-word;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.pod-about.is-open .pod-desc { display: block; overflow: visible; }
.pod-desc-more {
  min-height: 44px;
  margin-left: -8px;
  padding: 0 8px;
  border: 0;
  border-radius: var(--radius-s);
  background: none;
  color: var(--accent-text);
  font: inherit;
  font-size: var(--fs-ui);
  font-weight: 650;
  cursor: pointer;
}
.pod-desc-more:active { background: var(--hover); }
@media (hover: hover) {
  .pod-desc-more:hover { background: var(--hover); }
}
.pod-desc-more:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }
.views.pod-filter { margin: 0 0 14px; }
.pod-filter .view-tab { padding: 0 16px; font-size: var(--fs-ui); white-space: nowrap; }

/* Un episodio: il play tondo (lo schermo della TV per un video, le barre per
   quello in ascolto), titolo, quando e quanto dura, due righe della
   descrizione; a destra la spunta di "ascoltato"; in fondo quanto se ne è
   sentito. Tutta la riga (tranne la spunta) lo fa partire. */
/* Righe più larghe delle schede (CARD_WIDE in app.js): titolo e descrizione si leggono. */
.grid.pod-eps { grid-template-columns: repeat(auto-fill, minmax(min(100%, calc(var(--card-min) * 1.5)), 1fr)); }
.pod-ep { flex-direction: row; container-type: inline-size; }
.pod-ep-play {
  all: unset;
  box-sizing: border-box;
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 4px 14px 12px;
  cursor: pointer;
}
.pod-ep-play:focus-visible { outline: none; }
.card:has(> .pod-ep-play:focus-visible) { outline: 3px solid var(--accent); outline-offset: 2px; }
.pod-ep-icon {
  flex: none;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--text);
  transition: background .12s;
}
.pod-ep-icon svg { width: 22px; height: 22px; display: none; }
.pod-ep-icon .icon-play { display: block; fill: currentColor; }
.pod-ep-icon .icon-video { fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linejoin: round; }
.pod-ep-icon .icon-video .fill { fill: currentColor; stroke: none; }
.pod-ep-icon .icon-bars, .radio-on svg { fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; }
.pod-ep.is-video .pod-ep-icon .icon-play { display: none; }
.pod-ep.is-video .pod-ep-icon .icon-video { display: block; }
.pod-ep.is-current .pod-ep-icon { background: var(--accent-strong); color: var(--on-accent); }
.pod-ep.is-current .pod-ep-icon svg { display: none; }
.pod-ep.is-current .pod-ep-icon .icon-bars { display: block; }
.pod-ep-play:active .pod-ep-icon { background: var(--hover); }
@media (hover: hover) {
  .pod-ep:has(> .pod-ep-play:hover) { background: color-mix(in srgb, var(--surface-2) 55%, var(--surface)); }
  .pod-ep-play:hover .pod-ep-icon { background: var(--accent-strong); color: var(--on-accent); }
}
.pod-ep-text { flex: 1; min-width: 0; display: grid; gap: 3px; }
.pod-ep-title {
  font-weight: 600;
  line-height: 1.3;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.pod-ep-meta { color: var(--muted); font-size: var(--fs-meta); font-variant-numeric: tabular-nums; }
/* In «Scaricati»: il podcast, su una riga; niente descrizione. */
.pod-ep-by { color: var(--muted); font-size: var(--fs-meta); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.is-dl-row .pod-ep-desc { display: none; }
.pod-ep-desc {
  color: var(--muted);
  font-size: var(--fs-meta);
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Già ascoltato: il titolo più leggero; la spunta piena. */
.pod-ep.is-played .pod-ep-title { color: var(--muted); font-weight: 500; }
.pod-ep-mark {
  flex: none;
  align-self: flex-start;
  width: 48px;
  height: 48px;
  margin: 6px 4px 0 0;
  padding: 0;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: var(--radius);
  background: none;
  color: var(--muted);
  cursor: pointer;
}
.pod-ep-mark svg { width: 26px; height: 26px; fill: none; stroke: currentColor; stroke-width: 1.8; }
.pod-ep-mark .tick { stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.pod-ep-mark[aria-pressed="true"] { color: var(--accent-text); }
.pod-ep-mark[aria-pressed="true"] circle { fill: var(--accent-strong); stroke: var(--accent-strong); }
.pod-ep-mark[aria-pressed="true"] .tick { stroke: var(--on-accent); }
.pod-ep-mark:disabled { opacity: .5; cursor: default; }
.pod-ep-mark:active:not(:disabled) { background: var(--hover); }
@media (hover: hover) {
  .pod-ep-mark:hover:not(:disabled) { background: var(--surface-2); color: var(--text); }
  .pod-ep-mark[aria-pressed="true"]:hover:not(:disabled) { color: var(--accent-text); }
}
.pod-ep-mark:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }
.pod-ep-bar { position: absolute; inset: auto 0 0; height: 4px; background: var(--track); }
.pod-ep-bar .resume-fill { display: block; height: 100%; }
/* Scarica (la freccia nel vassoio), quanto manca (l'anello, col quadrato per
   fermare; vuoto in coda o in pausa) e Scaricato (il vassoio con la spunta,
   d'accento: è anche il segno che si ascolta senza rete). Vedi dlFillButton. */
.pod-ep-dl {
  flex: none;
  align-self: flex-start;
  width: 48px;
  height: 48px;
  margin-top: 6px;
  padding: 0;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: var(--radius);
  background: none;
  color: var(--muted);
  cursor: pointer;
}
.pod-ep-dl svg { width: 26px; height: 26px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.pod-ep-dl svg > * { display: none; }
.pod-ep-dl[data-dl="get"] .dl-get,
.pod-ep-dl[data-dl="done"] .dl-have,
.pod-ep-dl:is([data-dl="running"], [data-dl="waiting"]) :is(.dl-track, .dl-stop),
.pod-ep-dl[data-dl="running"] .dl-ring { display: inline; }
.pod-ep-dl[data-dl="done"] { color: var(--accent-text); }
.pod-ep-dl[data-dl="done"] svg { stroke-width: 2.1; }
.pod-ep-dl:is([data-dl="running"], [data-dl="waiting"]) { color: var(--text); }
.pod-ep-dl .dl-track { stroke: var(--track); stroke-width: 2.4; }
.pod-ep-dl .dl-ring {
  stroke: var(--accent-text);
  stroke-width: 2.4;
  stroke-linecap: butt;
  stroke-dasharray: 100;
  stroke-dashoffset: calc(100 - var(--dl, 0));
  transform: rotate(-90deg);
  transform-origin: 12px 12px;
  transition: stroke-dashoffset .5s cubic-bezier(.16, 1, .3, 1);
}
.pod-ep-dl .dl-stop { fill: currentColor; stroke: none; }
.pod-ep-dl:active { background: var(--hover); }
@media (hover: hover) {
  .pod-ep-dl:hover { background: var(--surface-2); color: var(--text); }
  .pod-ep-dl[data-dl="done"]:hover { color: var(--accent-text); }
}
.pod-ep-dl:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }
@media (prefers-reduced-motion: reduce) {
  .pod-ep-dl .dl-ring { transition: none; }
}
/* Righe strette: niente descrizione, il play più piccolo. */
@container (max-width: 260px) {
  .pod-ep-play { gap: 10px; padding-left: 10px; }
  .pod-ep-icon { width: 36px; height: 36px; }
  .pod-ep-icon svg { width: 18px; height: 18px; }
  .pod-ep-desc { display: none; }
  .pod-ep-mark { width: 44px; margin-right: 0; }
  .pod-ep-dl { width: 40px; }
}
/* Righe strette con tre pulsanti («Riproduci su…», Scarica, la spunta: il
   telefono col telecomando): la spunta resta in alto, «Riproduci su…» e
   Scarica scendono nell'angolo in basso (Scarica sotto la spunta). Il titolo
   resta largo; quando, la descrizione e il podcast lasciano loro il posto. */
@container (max-width: 419px) {
  :root[data-remote] .pod-ep:has(> .pod-ep-dl:not([hidden])) > .pod-ep-play { min-height: 112px; }
  :root[data-remote] .pod-ep:has(> .pod-ep-dl:not([hidden])) :is(.pod-ep-by, .pod-ep-meta, .pod-ep-desc) { margin-right: 56px; }
  :root[data-remote] .pod-ep:has(> .pod-ep-dl:not([hidden])) > :is(.cast-btn, .pod-ep-dl) { position: absolute; bottom: 6px; margin: 0; }
  :root[data-remote] .pod-ep:has(> .pod-ep-dl:not([hidden])) > .pod-ep-dl { right: 4px; }
  :root[data-remote] .pod-ep:has(> .pod-ep-dl:not([hidden])) > .cast-btn { right: 52px; }
}

/* «Scaricati»: quanto spazio (di quello scelto) e «Elimina tutti» sulla riga
   del titoletto; senza rete, sopra, la frase che lo dice. */
.pod-dl .pod-block-head { flex-wrap: wrap; align-items: center; row-gap: 6px; }
.pod-dl-space { color: var(--muted); font-size: var(--fs-meta); font-variant-numeric: tabular-nums; white-space: nowrap; }
.pod-dl-clear { margin-left: auto; align-self: center; }
.pod-dl-confirm { max-width: 560px; margin: 0 0 14px; }
.pod-dl-note { margin: -4px 0 12px; color: var(--warn-text); font-size: var(--fs-meta); font-weight: 600; max-width: 72ch; }
.pod-dl .empty-state { margin-bottom: 4px; }
.pod-dl-glyph svg { width: 1.2em; height: 1.2em; vertical-align: -.25em; fill: none; stroke: var(--text); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.pod-offline {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 16px;
  padding: 12px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
  color: var(--text);
  font-size: var(--fs-body);
  font-weight: 600;
  line-height: 1.35;
}
.pod-offline svg { width: 26px; height: 26px; flex: none; fill: none; stroke: var(--warn-text); stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }

/* In ascolto: le barre del play (e della radio) si muovono solo mentre suona,
   e solo per qualche secondo (cinque battute, 6 s) da quando parte, riparte o
   compare: dicono «suona», poi restano ferme (un movimento senza fine accanto
   al guidatore attira lo sguardo). In movimento (data-moving: la modalità
   guida non permette il video, vedi guidaMoving in app.js) non si muovono per
   niente. Cominciano e finiscono alte: niente scatti. */
@keyframes listen-bars { 0%, 100% { transform: scaleY(1); } 50% { transform: scaleY(.4); } }
:is(.pod-ep, .radio-card).is-playing :is(.icon-bars, .radio-on svg) path,
.net-tab.is-playing .net-tab-on path {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: listen-bars 1.2s ease-in-out 5;
}
:root[data-moving] :is(.pod-ep, .radio-card, .net-tab) :is(.icon-bars, .radio-on svg, .net-tab-on) path { animation: none; }

/* Radio: come i canali TV (logo e nome), col programma o il brano in onda
   (due righe riservate: le schede restano allineate); quella in ascolto col
   bordo e "In ascolto". */
.radio-card .tv-id { gap: 2px; }
/* Il nome intero, su due righe se serve ("Rai Radio Tutta Italiana"). */
.radio-card .tv-name {
  white-space: normal;
  line-height: 1.25;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.radio-on { display: inline-flex; align-items: center; gap: 6px; color: var(--accent-text); font-size: var(--fs-meta); font-weight: 650; }
.radio-on svg { width: 18px; height: 18px; }
.radio-now { display: grid; gap: 2px; min-height: 2.7em; align-content: start; }
.radio-title { font-weight: 600; line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.radio-sub { color: var(--muted); font-size: var(--fs-meta); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.radio-now.is-missing .radio-title { color: var(--muted); font-weight: 500; }

/* «Ultimi GR» (vedi radioGrCard in app.js): la rete della Radio e i suoi
   risultati della ricerca, schede basse (il simbolo della testata, il nome,
   l'ora e la durata), a capo quando non ci stanno (in auto due per riga
   accanto alle reti, sul telefono due). La scheda intera fa partire l'edizione. */
.radio-gr-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.radio-gr-card {
  position: relative;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.radio-gr-card.is-current { border-color: color-mix(in srgb, var(--accent) 60%, var(--border)); }
.radio-gr-play {
  all: unset;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 76px;
  padding: 10px 12px 10px 10px;
  cursor: pointer;
}
.radio-gr-play:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; border-radius: var(--radius); }
.radio-gr-art {
  flex: none;
  width: 54px;
  height: 54px;
  border-radius: var(--radius-s);
  background: var(--logo-tile);
  overflow: hidden;
}
.radio-gr-art img { display: block; width: 100%; height: 100%; object-fit: cover; }
.radio-gr-text { flex: 1 1 auto; display: grid; gap: 1px; min-width: 0; }
/* Il nome intero, su due righe se serve ("GR 1 Sport" nelle schede strette). */
.radio-gr-name { font-weight: 650; line-height: 1.25; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.radio-gr-when, .radio-gr-len { color: var(--muted); font-size: var(--fs-meta); line-height: 1.3; font-variant-numeric: tabular-nums;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.radio-gr-len:empty { display: none; }
.radio-gr-card .radio-on { margin-top: 2px; }
.radio-gr-card.is-playing .radio-on svg path {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: listen-bars 1.2s ease-in-out 5;
}
:root[data-moving] .radio-gr-card .radio-on svg path { animation: none; }
@media (hover: hover) {
  .radio-gr-card:hover { background: var(--surface-2); }
}
.radio-gr-card:active { background: var(--surface-2); }

/* Radio locali (vedi radioRenderLocal in app.js): la rete della Radio, col
   nome della regione scelta e «Cambia regione»; le schede come le altre
   radio, prima quelle con sede nella regione, poi «Si ascoltano anche qui».
   Finché la regione non c'è, la frase e le 20 regioni da toccare, a capo (non
   in fila: in auto si vedono tutte senza scorrere). */
.radio-local-head { align-items: center; flex-wrap: wrap; row-gap: 6px; }
.radio-region-change { margin-left: auto; }
.radio-region-pick { margin-bottom: 16px; }
.radio-region-text { max-width: 62ch; margin: 0 0 12px; color: var(--muted); }
.radio-region-text strong { color: var(--text); font-weight: 650; }
.radio-region-chips { flex-wrap: wrap; overflow: visible; max-width: none; }
.radio-region-chips.od-chips { -webkit-mask-image: none; mask-image: none; animation: none; }
.radio-local-also { margin: 18px 0 10px; color: var(--muted); font-size: var(--fs-ui); font-weight: 650; }

/* --- lo schermo dell'ascolto -------------------------------------------------- */
/* Quieto come quello del guidatore (fondo quasi nero, niente che abbagli):
   in alto "Riduci" e la X; la copertina (un po' scurita) o il logo della
   radio, titolo e sottotitolo grandi, lo stato; la barra del tempo (podcast);
   comandi grandi che non spariscono (play 128 px, salti 88); sotto la
   velocità (podcast) o "Torna in diretta" (radio rivista più indietro). Un
   errore prende il posto dei comandi. */
.listen-screen {
  width: 100%;
  height: 100vh;
  height: 100dvh;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  overflow: hidden;
  background: var(--stage-quiet);
  color: var(--text);
}
.listen-screen:focus { outline: none; }
.listen-screen::backdrop { background: var(--stage-quiet, #0a0b0d); }
.listen-screen[open]::backdrop { animation: player-fade .28s ease-out; }
/* La radio e i podcast solo audio (has-ambience, vedi lisAmbient in app.js):
   colori profondi dal logo o dalla copertina e sfumature mobili. Testi
   chiari ed equalizzatore luminoso mantengono il contrasto. */
#listen-screen.has-ambience {
  isolation: isolate;
  color-scheme: dark;
  --text: var(--radio-ink, #f3f5fa);
  --muted: var(--radio-muted, #ced6e5);
  --surface: rgb(255 255 255 / .08);
  --surface-2: rgb(255 255 255 / .16);
  --border: rgb(255 255 255 / .22);
  --on-stage: var(--text);
  --on-stage-muted: var(--muted);
  --on-stage-soft: var(--muted);
  --stage-danger: #ffafba;
  --stage-dot: var(--muted);
  --stage-line: var(--border);
  --logo-tile: var(--radio-light, #213457);
  --logo-light: var(--radio-logoLight, #dce5f1);
  --accent: var(--muted);
  background: var(--radio-background, #15243b);
}
/* Tre macchie di luce distinte; il movimento parte subito all'apertura,
   anche in pausa o durante il caricamento, indipendentemente da Web Audio.
   Si animano solo le trasformazioni, senza filtri su tutta la pagina. */
.ls-ambience {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.ls-aurora {
  position: absolute;
  width: 95%;
  height: 110%;
  border-radius: 50%;
  background: radial-gradient(ellipse, var(--aurora-color) 0%, transparent 66%);
  animation-play-state: paused;
}
.ls-aurora-main {
  --aurora-color: var(--radio-glow, #2347a0);
  left: -28%;
  top: -38%;
  animation: radio-colors-drift 12s ease-in-out infinite alternate;
  animation-delay: -4s;
  animation-play-state: paused;
}
.ls-aurora-drift {
  --aurora-color: var(--radio-drift, #873b62);
  left: 38%;
  top: 8%;
  animation: radio-light-drift 16s ease-in-out infinite alternate;
  animation-delay: -7s;
  animation-play-state: paused;
}
.ls-aurora-haze {
  --aurora-color: var(--radio-haze, #6331a9);
  left: -8%;
  top: 30%;
  opacity: .8;
  animation: radio-haze-drift 18s ease-in-out infinite alternate;
  animation-delay: -11s;
  animation-play-state: paused;
}
#listen-screen.has-ambience[open].has-radio-motion .ls-aurora {
  animation-play-state: running;
  will-change: transform;
}
#listen-screen.has-ambience .ls-frame { z-index: 1; }
@keyframes radio-colors-drift {
  0% { transform: translate3d(-12%, -8%, 0) scale(1); }
  50% { transform: translate3d(30%, 18%, 0) scale(1.16); }
  100% { transform: translate3d(12%, 40%, 0) scale(1.04); }
}
@keyframes radio-light-drift {
  0% { transform: translate3d(15%, 12%, 0) scale(1.08); }
  50% { transform: translate3d(-28%, -24%, 0) scale(.92); }
  100% { transform: translate3d(-40%, 12%, 0) scale(1.12); }
}
@keyframes radio-haze-drift {
  0% { transform: translate3d(-18%, 14%, 0) scale(.9); }
  50% { transform: translate3d(38%, -18%, 0) scale(1.1); }
  100% { transform: translate3d(15%, -45%, 0) scale(1); }
}
#listen-screen.is-radio .ls-art.is-logo { border: 1px solid rgb(255 255 255 / .18); }
#listen-screen.has-ambience .ls-controls .player-toggle {
  background: var(--text);
  color: var(--radio-background, #15243b);
  box-shadow: 0 8px 24px rgb(24 36 55 / .14);
}
#listen-screen.has-ambience .ls-controls .player-toggle:hover { background: var(--muted); }
#listen-screen.has-ambience .ls-toast { background: var(--radio-light, #213457); color: var(--text); }
html:has(#listen-screen[open]) { overflow: hidden; }
.ls-frame {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* I margini (più stretti sotto, vedi più in basso), o le zone sicure se
     sono di più (l'iPhone in orizzontale, la barretta Home). */
  --pad-top: 16px;
  --pad-side: 24px;
  --pad-bottom: 28px;
  padding: max(var(--pad-top), var(--safe-top)) max(var(--pad-side), var(--safe-right)) max(var(--pad-bottom), var(--safe-bottom)) max(var(--pad-side), var(--safe-left));
}
.ls-top { align-self: stretch; display: flex; align-items: center; gap: 16px; }
/* "Riduci" e la X: si toccano anche in movimento, 64 px. */
.ls-top .player-btn { --size: 64px; }
.ls-heading { flex: 1; min-width: 0; display: flex; align-items: center; gap: 12px; }
.ls-kind { flex: 1; min-width: 0; margin: 0; color: var(--muted); font-size: 15px; font-weight: 600; text-align: center; }
#listen-screen.has-ambience .ls-kind {
  font-family: var(--font-ui);
  font-size: var(--fs-stage-meta);
  font-weight: 650;
  letter-spacing: .02em;
  color: var(--radio-muted, var(--muted));
  text-align: right;
}
.ls-live-badge {
  display: none;
  flex: none;
  padding: 4px 10px;
  border: 2px solid #fff;
  border-radius: 999px;
  background: #be123c;
  color: #fff;
  font: 800 12px/1.2 var(--font-ui);
  letter-spacing: .08em;
}
#listen-screen.is-radio.is-live .ls-live-badge { display: inline-flex; }
#listen-screen.is-radio.is-live[open] .ls-live-badge { animation: radio-live-pulse 1.8s ease-in-out infinite; }
#listen-screen.is-radio .ls-status > .ls-live { display: none; }
@keyframes radio-live-pulse {
  0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 rgb(225 29 72 / .4); }
  50% { transform: scale(1.04); box-shadow: 0 0 0 7px rgb(225 29 72 / 0); }
}
.ls-min svg { width: 46%; height: 46%; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
/* Poco spazio in altezza: si stringe solo la copertina, mai le righe di
   testo (flex: none). È un contenitore: sotto l'altezza che servirebbe a un
   titolo su due righe con una copertina di almeno 40 px, la copertina sparisce
   (vedi @container ls-now più sotto). */
.ls-now {
  container: ls-now / size;
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  max-width: 760px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 0;
  text-align: center;
}
.ls-art {
  position: relative;
  flex: 0 1 auto;
  min-height: 0;
  height: min(232px, 32vh);
  height: min(232px, 32dvh);
  aspect-ratio: 1;
  margin-bottom: 14px;
  border-radius: var(--radius-l);
  overflow: hidden;
  background: var(--surface);
  box-shadow: 0 12px 40px var(--scrim-light);
}
/* Scurita un po': di notte una copertina a colori pieni abbaglia. */
.ls-art img { display: block; width: 100%; height: 100%; object-fit: cover; filter: brightness(.8) saturate(.85); }
/* Il logo di una radio: intero, sul suo riquadro scuro (chiaro per uno scuro). */
.ls-art.is-logo { aspect-ratio: 16 / 10; height: min(150px, 22vh); height: min(150px, 22dvh); padding: 18px 26px; background: var(--logo-tile); box-shadow: none; }
.ls-art.is-logo img { object-fit: contain; filter: none; }
.ls-art.is-logo.is-dark-logo { background: var(--logo-light); }
.ls-equalizer {
  position: relative;
  flex: 0 1 112px;
  min-height: 52px;
  width: min(520px, 100%);
  height: clamp(60px, 14vh, 112px);
  height: clamp(60px, 14dvh, 112px);
  margin: 0 0 12px;
  pointer-events: none;
}
.ls-equalizer canvas { display: block; width: 100%; height: 100%; }
.ls-ad-notice {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px 16px;
  padding: 8px 16px;
  margin-top: 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-l);
  background: var(--surface);
  color: var(--text);
  font-weight: 650;
}
.ls-ad-notice .bar-btn { min-height: 44px; }
#listen-screen.is-radio .ls-art { margin-bottom: 2px; }
.ls-title {
  flex: none;
  margin: 0;
  max-width: 30ch;
  font-size: 30px;
  font-weight: 650;
  line-height: 1.2;
  text-wrap: balance;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.ls-sub { flex: none; max-width: 100%; margin: 0; color: var(--muted); font-size: 20px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ls-status {
  flex: none;
  min-height: 26px;
  margin: 4px 0 0;
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--muted);
  font-size: 17px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.ls-live { display: none; align-items: center; gap: 7px; color: var(--text); font-weight: 700; letter-spacing: .06em; }
.ls-live::before { content: ""; width: 10px; height: 10px; border-radius: 50%; background: var(--live); }
.listen-screen.is-live .ls-live { display: inline-flex; }
/* La barra del tempo (podcast): come quella dei video, coi tempi sotto. */
.ls-seek { width: min(680px, 100%); display: grid; grid-template-columns: 1fr 1fr; align-items: center; margin-top: 8px; }
.listen-screen.is-radio .ls-seek { display: none; }
.ls-seek input[type="range"] {
  --seek: 0%;
  grid-column: 1 / -1;
  width: 100%;
  min-height: 44px;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.ls-seek input[type="range"]::-webkit-slider-runnable-track {
  height: 6px;
  border-radius: 3px;
  background: linear-gradient(to right, var(--accent-text) var(--seek), var(--stage-seek) var(--seek));
}
.ls-seek input[type="range"]::-moz-range-track { height: 6px; border-radius: 3px; background: var(--stage-seek); }
.ls-seek input[type="range"]::-moz-range-progress { height: 6px; border-radius: 3px; background: var(--accent-text); }
.ls-seek input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 22px;
  height: 22px;
  margin-top: -8px;
  border: 0;
  border-radius: 50%;
  background: var(--on-stage);
  box-shadow: 0 1px 4px var(--scrim-dim);
}
.ls-seek input[type="range"]::-moz-range-thumb { width: 22px; height: 22px; border: 0; border-radius: 50%; background: var(--on-stage); box-shadow: 0 1px 4px var(--scrim-dim); }
.ls-seek input[type="range"]:disabled { cursor: default; opacity: .5; }
.ls-seek input[type="range"]:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; border-radius: var(--radius-s); }
.ls-time { color: var(--muted); font-size: 15px; font-variant-numeric: tabular-nums; }
.ls-time-left { justify-self: end; }
.ls-controls { display: flex; align-items: center; justify-content: center; gap: 44px; margin: 14px 0 10px; }
.ls-controls .player-toggle { --size: 128px; }
.ls-controls .player-skip { --size: 88px; }
/* La rotellina gira attorno al play mentre l'audio arriva. */
.ls-toggle-box { position: relative; display: grid; place-items: center; }
.ls-spinner {
  position: absolute;
  inset: -14px;
  width: calc(100% + 28px);
  height: calc(100% + 28px);
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity .25s, visibility .25s;
  animation: spinner-turn 1.6s linear infinite;
  animation-play-state: paused;
}
.listen-screen.is-waiting:not(.has-error) .ls-spinner { opacity: 1; visibility: visible; }
.listen-screen.is-waiting:not(.has-error) :is(.ls-spinner, .ls-spinner .spinner-arc) { animation-play-state: running; }
.ls-bar { min-height: 60px; display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 10px; }
/* Come la barra del guidatore: 60 px, da toccare anche in movimento. Pieni e
   grigi come i pulsanti tondi di qui: i colori li dà il contesto (--bar-*,
   vedi .bar-btn), così le varianti restano sé stesse («Riprova» primario,
   una scelta aperta bianca). */
.listen-screen { --bar-bg: var(--surface); --bar-line: var(--border); --bar-hover: var(--surface-2); --bar-press: var(--border); }
.listen-screen .bar-btn { min-height: 60px; border-radius: 30px; }
.ls-live-btn { gap: 0; padding: 0 16px 0 14px; font-variant-numeric: tabular-nums; }
.ls-live-btn::before { content: ""; flex: none; width: 8px; height: 8px; margin-right: 8px; border-radius: 50%; background: var(--stage-dot); }
.ls-menu { right: 50%; transform: translateX(50%); }
/* Il volume dell'app abbassato dal telecomando (vedi remoteVolumeRender): come
   «Torna in diretta», quanto e il tocco che lo riporta al 100%. */
.app-volume { gap: 0; padding: 0 16px 0 12px; font-variant-numeric: tabular-nums; }
.app-volume svg { margin-right: 8px; }
/* Un errore: al posto della barra del tempo, dei comandi e della barra sotto. */
.listen-screen.has-error :is(.ls-seek, .ls-controls, .ls-bar) { display: none; }
.ls-message { display: grid; justify-items: center; gap: 8px; max-width: 46ch; margin: 18px 0 16px; text-align: center; }
.listen-screen .message-title { color: var(--stage-danger); }
.ls-toast { top: 92px; }

/* La barra in basso: mentre si ascolta con lo schermo chiuso. Galleggia sopra
   la pagina (che le lascia spazio in fondo; gli avvisi le stanno sopra).
   Pausa e stop si toccano anche in movimento: 64 px (48 sul telefono). */
.mini {
  position: fixed;
  left: 50%;
  bottom: calc(12px + var(--safe-bottom));
  z-index: 6;
  transform: translateX(-50%);
  width: min(680px, calc(100vw - 24px - var(--safe-left) - var(--safe-right)));
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px;
  border: 1px solid var(--border);
  border-radius: 18px;
  background: var(--raised);
  box-shadow: var(--shadow-pop);
  overflow: hidden;
}
body.has-mini main { padding-bottom: calc(104px + var(--safe-bottom)); }
body.has-mini .notice { bottom: calc(100px + var(--safe-bottom)); }
.mini-open {
  all: unset;
  box-sizing: border-box;
  flex: 1;
  min-width: 0;
  min-height: 64px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding-right: 8px;
  border-radius: var(--radius);
  cursor: pointer;
}
.mini-open:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }
@media (hover: hover) {
  .mini-open:hover .mini-title { text-decoration: underline; text-decoration-color: color-mix(in srgb, var(--text) 40%, transparent); text-underline-offset: 3px; }
}
.mini-art { position: relative; flex: none; width: 64px; height: 64px; border-radius: var(--radius); overflow: hidden; background: var(--surface-2); }
.mini-art img { display: block; width: 100%; height: 100%; object-fit: cover; }
.mini-art.is-logo { padding: 8px 6px; background: var(--logo-tile); }
.mini-art.is-logo img { object-fit: contain; }
.mini-art.is-logo.is-dark-logo { background: var(--logo-light); }
.mini-text { min-width: 0; display: grid; gap: 1px; }
.mini-title { font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mini-sub { color: var(--muted); font-size: var(--fs-meta); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mini.is-error .mini-sub { color: var(--danger-text); }
.mini-btn {
  flex: none;
  width: 64px;
  height: 64px;
  padding: 0;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--text);
  cursor: pointer;
}
.mini-btn svg { width: 26px; height: 26px; }
/* Play e pausa: il comando principale, pieno (si trova al primo sguardo). */
.mini-toggle { background: var(--accent-strong); color: var(--on-accent); }
.mini-toggle svg { fill: currentColor; }
.mini-toggle:active { background: var(--accent-hover); }
@media (hover: hover) {
  .mini-toggle:hover { background: var(--accent-hover); }
}
.mini-toggle .icon-pause, .mini-toggle.is-playing .icon-play { display: none; }
.mini-toggle.is-playing .icon-pause { display: block; }
.mini-close svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }
.mini-close:active { background: var(--hover); }
@media (hover: hover) {
  .mini-close:hover { background: var(--hover); }
}
.mini-btn:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.mini-progress { position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: var(--track); }
.mini-progress > span { display: block; height: 100%; width: 0; }
.mini.is-radio .mini-progress { display: none; }

/* Telefono: la copertina del podcast più piccola accanto al titolo; lo
   schermo dell'ascolto coi comandi un po' più piccoli (come il guidatore). */
@media (max-width: 480px) {
  .pod-hero { gap: 14px; }
  .pod-hero-art { width: 104px; }
  .pod-title { font-size: var(--fs-title); }
  .pod-author { font-size: var(--fs-ui); }
  .pod-actions { margin-top: 8px; }
  .pod-actions .btn { flex: 1 1 auto; }
  .pod-filter { display: flex; }
  .pod-filter .view-tab { flex: 1; padding: 0 8px; }
  .ls-frame { --pad-top: 12px; --pad-side: 16px; --pad-bottom: 20px; }
  .ls-controls { gap: 20px; }
  .ls-controls .player-toggle { --size: 112px; }
  .ls-controls .player-skip { --size: 76px; }
  .ls-title { font-size: 25px; }
  .ls-sub { font-size: 18px; }
  .mini { bottom: calc(8px + var(--safe-bottom)); width: calc(100vw - 16px); gap: 6px; border-radius: 16px; }
  .mini-btn { width: 48px; height: 48px; }
  .mini-toggle svg { width: 24px; height: 24px; }
  .mini-close svg { width: 20px; height: 20px; }
  .mini-art { width: 48px; height: 48px; border-radius: var(--radius-m); }
  .mini-open { min-height: 48px; gap: 10px; }
  body.has-mini main { padding-bottom: calc(84px + var(--safe-bottom)); }
  body.has-mini .notice { bottom: calc(80px + var(--safe-bottom)); }
}
@media (max-width: 360px) {
  .ls-controls { gap: 12px; }
  .ls-controls .player-toggle { --size: 100px; }
  .ls-controls .player-skip { --size: 68px; }
}
/* La finestra vera dell'auto (773×601, 773×575: telemetria): meno aria sopra,
   sotto e fra i blocchi, perché accanto a "Riduci", X e barra da 64/60 px
   restino copertina, titolo su due righe e comandi grandi. */
@media (max-height: 650px) {
  .ls-frame { --pad-top: 10px; --pad-bottom: 14px; }
  .ls-now { padding: 4px 0; }
  .ls-art { margin-bottom: 10px; }
  .ls-seek { margin-top: 4px; }
  .ls-controls { margin: 8px 0; }
  .ls-toast { top: 86px; }
}
/* Titolo su due righe (72), sottotitolo (28), stato (30), spazi (12): 142
   px dentro il padding; con la copertina almeno 40 px più 16 di margine. Sotto
   i 198 px niente copertina, come più in basso (vedi max-height: 560px). A
   773×575 la copertina è di 84 px col titolo su una riga, 48 su due. */
@container ls-now (max-height: 197px) {
  .ls-art { display: none; }
  .ls-equalizer { flex-basis: 40px; min-height: 28px; margin-bottom: 2px; }
}
/* Schermo basso (telefono in orizzontale): niente copertina, il titolo su una
   riga, comandi un po' più piccoli. */
@media (max-height: 560px) {
  /* Titolo e sottotitolo sempre interi (mai tagliati a metà riga): se non
     ci sta tutto, lo schermo scorre (alto quanto il suo contenuto, non più
     un contenitore). */
  .ls-frame { --pad-bottom: 12px; overflow-y: auto; }
  .ls-now { flex-shrink: 0; container-type: normal; }
  .ls-art { display: none; }
  .ls-equalizer { flex: none; height: 48px; min-height: 0; margin-bottom: 2px; }
  .ls-title { -webkit-line-clamp: 1; font-size: 22px; }
  .ls-sub { font-size: 17px; }
  .ls-controls { margin: 6px 0 4px; }
  .ls-controls .player-toggle { --size: 96px; }
  .ls-controls .player-skip { --size: 72px; }
}
/* Telefono in orizzontale (360-430 px di altezza): spazi e comandi più
   stretti, perché ci stia tutto senza scorrere. */
@media (max-height: 440px) {
  .ls-equalizer { height: 32px; }
  .ls-frame { --pad-top: 8px; }
  .ls-now { padding: 2px 0; gap: 2px; }
  .ls-seek { margin-top: 2px; }
  .ls-seek input[type="range"] { min-height: 36px; }
  .ls-controls { margin: 4px 0 2px; }
  .ls-controls .player-toggle { --size: 80px; }
  .ls-controls .player-skip { --size: 64px; }
  .ls-bar { min-height: 44px; }
  /* Solo sul telefono in orizzontale (l'auto non è mai così bassa): i
     pulsanti in alto e in basso come prima, perché ci stia tutto. */
  .ls-top .player-btn { --size: 56px; }
  .listen-screen .bar-btn { min-height: 44px; border-radius: 22px; }
}

@media (prefers-reduced-motion: reduce) {
  .listen-screen[open]::backdrop { animation: none; }
  #listen-screen.is-radio.is-live[open] .ls-live-badge { animation: none; }
  #listen-screen.has-ambience .ls-aurora,
  #listen-screen.has-ambience[open].has-radio-motion .ls-aurora { animation: none; will-change: auto; }
  :is(.pod-ep, .radio-card).is-playing :is(.icon-bars, .radio-on svg) path { animation: none; }
  .net-tab.is-playing .net-tab-on path { animation: none; }
  .pod-ep-icon { transition: none; }
}

/* --- telecomando (vedi Telecomando in app.js) --------------------------------- */

/* «Riproduci su…» sulle schede: lo schermo con le onde. Solo se c'è un altro
   dispositivo (data-remote su <html>): per chi usa l'app da un posto solo non
   c'è. Il tocco vale su 48 px, come la stella. */
.cast-btn {
  position: relative;
  flex: none;
  align-self: flex-start;
  width: 48px;
  height: 48px;
  padding: 0;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: var(--radius);
  background: none;
  color: var(--muted);
  cursor: pointer;
}
:root:not([data-remote]) .cast-btn { display: none; }
.cast-btn svg { position: relative; width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.cast-btn svg .fill, .remote-mini-icon .fill { fill: currentColor; stroke: none; }
.cast-btn:active { background: var(--hover); }
.cast-btn:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }
@media (hover: hover) {
  .cast-btn:hover { color: var(--text); background: var(--hover); }
}
/* Sulla miniatura (video e on demand): un cerchio scuro come la stella, a
   sinistra di lei nei video di YouTube. */
.cast-btn.on-thumb { position: absolute; top: 0; right: 0; z-index: 2; border-radius: 0; color: #fff; }
.result > .cast-btn.on-thumb { right: 44px; }
.cast-btn.on-thumb::before {
  content: "";
  position: absolute;
  inset: 7px;
  border-radius: 50%;
  background: rgb(0 0 0 / .58);
  border: 1px solid rgb(255 255 255 / .18);
  transition: background .12s;
}
.cast-btn.on-thumb svg { width: 20px; height: 20px; }
.cast-btn.on-thumb:active, .cast-btn.on-thumb:hover { background: none; color: #fff; }
.cast-btn.on-thumb:active::before { background: rgb(0 0 0 / .8); }
@media (hover: hover) {
  .cast-btn.on-thumb:hover::before { background: rgb(0 0 0 / .8); }
}
.cast-btn.on-thumb:focus-visible { outline: none; }
.cast-btn.on-thumb:focus-visible::before { outline: 3px solid var(--accent); outline-offset: 1px; }
/* Sulla scheda di un canale o di una radio: in alto a destra (il nome gli lascia il posto). */
.cast-btn.on-card { position: absolute; top: 4px; right: 4px; z-index: 1; }
:root[data-remote] .tv-card .tv-head { padding-right: 28px; }
/* Le righe on demand: il pulsante in fondo alla riga; le cartelle non partono. */
.od-row { flex-direction: row; }
.od-row > .cast-btn { align-self: center; margin-right: 4px; }
.od-row.is-folder > .cast-btn { display: none; }
.pod-ep > .cast-btn { margin-top: 6px; }

/* I segni dei dispositivi (auto, telefono, tablet, computer). */
.device-icon { fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.device-icon .dot { stroke-width: 2.8; }

/* La barra in basso quando un altro dispositivo riproduce: quella
   dell'ascolto, con «In riproduzione su Auto» sotto il titolo. */
.remote-mini-sub { display: flex; align-items: center; gap: 6px; }
.remote-mini-sub > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.remote-mini-icon { flex: none; width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
body.has-remote-bar main { padding-bottom: calc(104px + var(--safe-bottom)); }
body.has-remote-bar .notice { bottom: calc(100px + var(--safe-bottom)); }

/* Nel player: «Dal telefono: … · Mostra video» (un video partito da un altro
   dispositivo con la modalità guida spenta: solo audio). Come un avviso, ma da
   toccare, e in alto a sinistra nella riga della X (lì, col solo audio, non
   c'è altro): non copre il titolo. */
.player-remote {
  position: absolute;
  top: max(16px, var(--safe-top));
  left: max(24px, var(--safe-left));
  z-index: 4;
  width: max-content;
  max-width: calc(100% - max(24px, var(--safe-left)) - max(16px, var(--safe-right)) - 88px);
  min-height: 64px;
  display: flex;
  align-items: center;
  gap: 8px 10px;
  margin: 0;
  padding: 8px 8px 8px 18px;
  border: 1px solid var(--stage-line);
  border-radius: var(--radius);
  background: var(--stage-toast);
  box-shadow: 0 8px 30px var(--scrim-dim);
  color: var(--on-stage);
  font-size: 17px;
}
.player-remote-text { flex: 0 1 auto; min-width: 0; }
.player-remote .bar-btn { flex: none; }
.player-remote.is-confirming { border-color: var(--accent); }

/* Lo schermo del telecomando: quello dell'ascolto (sempre scuro, le stesse
   misure), col titolo a sinistra e, sotto, i dispositivi da scegliere. */
html:has(#remote[open]) { overflow: hidden; }
.rm-top { justify-content: space-between; }
.remote-screen .rm-heading { flex: 1; color: var(--text); font-size: 20px; font-weight: 650; text-align: left; }
.rm-devices {
  align-self: stretch;
  flex: none;
  display: flex;
  gap: 8px;
  margin: 10px calc(-1 * var(--pad-side)) 0;
  padding: 2px var(--pad-side) 6px;
  overflow-x: auto;
  scrollbar-width: none;
}
.rm-devices::-webkit-scrollbar { display: none; }
.rm-device {
  flex: none;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  column-gap: 10px;
  max-width: 260px;
  min-height: 60px;
  padding: 6px 18px 6px 14px;
  border: 1px solid var(--border);
  border-radius: 30px;
  background: var(--surface);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.rm-device .device-icon { grid-row: span 2; width: 28px; height: 28px; }
.rm-device-name { font-weight: 650; line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rm-device-sub { display: flex; align-items: center; gap: 6px; color: var(--muted); font-size: var(--fs-stage-meta); line-height: 1.2; white-space: nowrap; }
.rm-device:not(.is-offline) .rm-device-sub::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--accent-text); }
.rm-device[aria-pressed="true"] {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 24%, var(--surface));
  box-shadow: inset 0 0 0 1px var(--accent);
}
.rm-device[aria-pressed="true"] .rm-device-sub { color: var(--tint-text); }
/* Non in linea: spento (il bordo tratteggiato, il segno e il nome grigi), ma si può scegliere per vedere quando c'era. */
.rm-device.is-offline { border-style: dashed; color: var(--muted); }
.rm-device.is-offline .device-icon { opacity: .7; }
.rm-device:active { transform: scale(.97); }
.rm-device:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
@media (hover: hover) {
  .rm-device:hover:not([aria-pressed="true"]) { background: var(--surface-2); }
}
/* Niente da comandare: una frase al centro, al posto di tutto il resto. */
.rm-empty { flex: 1; display: grid; align-content: center; justify-items: center; gap: 8px; max-width: 46ch; padding: 16px 0; text-align: center; }
.remote-screen .rm-empty .message-title { color: var(--text); }
.rm-empty .message-text { color: var(--muted); }
.remote-screen.is-idle :is(.rm-now, .rm-seek, .rm-controls, .rm-bar) { display: none; }
/* Il tempo: solo da vedere (si salta coi ±15), la parte vista con transform. */
.remote-screen:not(.has-time) .rm-seek { display: none; }
.remote-screen.has-time .rm-seek { display: grid; }
.rm-track { grid-column: 1 / -1; height: 6px; margin: 19px 0 12px; border-radius: 3px; background: var(--stage-seek); overflow: hidden; }
.rm-fill { display: block; width: 100%; height: 100%; background: var(--accent-text); transform: scaleX(0); transform-origin: left center; }
.remote-screen.is-blocked #rm-state { color: var(--warn-text); }
/* Un video (YouTube, on demand): la miniatura 16:9, non quadrata. */
.remote-screen.is-wide .ls-art { aspect-ratio: 16 / 9; height: min(200px, 26vh); height: min(200px, 26dvh); }
.rm-controls .player-skip[aria-disabled="true"] { opacity: .4; cursor: default; }
.rm-controls .player-skip[aria-disabled="true"]:active { transform: none; }
/* Canale o radio prima e dopo: più piccoli dei ±15, il segno pieno. */
.rm-controls .rm-step { --size: 72px; }
.rm-step svg path { fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }
.rm-step svg path.fill { fill: currentColor; stroke: none; }
.rm-controls:has(.rm-step:not([hidden])) { gap: 28px; }
.rm-volume { display: flex; align-items: center; gap: 8px; }
.remote-screen .rm-volume .bar-btn-icon { width: 60px; }
.rm-vol { min-width: 7.2em; color: var(--text); font-size: var(--fs-stage-meta); font-weight: 600; font-variant-numeric: tabular-nums; text-align: center; }
.rm-volume .bar-btn[aria-disabled="true"] { opacity: .4; cursor: default; }
.rm-stop { padding: 0 22px 0 18px; }
.rm-stop svg .fill { fill: currentColor; stroke: none; }
/* Un comando partito, finché l'altro dispositivo non dice di averlo eseguito:
   un arco che gira attorno al pulsante tondo; gli altri un po' spenti. */
.remote-screen .player-btn { position: relative; }
.remote-screen .player-btn.is-pending::after {
  content: "";
  position: absolute;
  inset: -7px;
  border: 3px solid transparent;
  border-top-color: var(--accent-text);
  border-radius: 50%;
  animation: spinner-turn .9s linear infinite;
}
:is(.bar-btn, .mini-btn, .rm-device, .cast-device).is-pending { opacity: .6; cursor: progress; }

/* «Riproduci su…»: il foglio di «Chi guarda?», coi dispositivi in colonna. */
.cast { width: min(480px, calc(100vw - 24px - var(--safe-left) - var(--safe-right))); }
.cast-list { display: grid; gap: 8px; margin: 16px 0 0; padding: 0; list-style: none; }
.cast-device {
  width: 100%;
  min-height: 68px;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 16px 10px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--raised);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: transform .12s, background .12s;
}
.cast-device .device-icon { flex: none; width: 32px; height: 32px; color: var(--accent-text); }
.cast-device-text { min-width: 0; display: grid; gap: 2px; }
.cast-device-name { font-size: var(--fs-lead); font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cast-device-sub { color: var(--muted); font-size: var(--fs-meta); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cast-device:active:not(:disabled) { transform: scale(.98); background: var(--hover); }
.cast-device:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.cast-device:disabled { border-style: dashed; background: transparent; color: var(--muted); cursor: default; }
.cast-device:disabled .device-icon { color: var(--muted); opacity: .7; }
@media (hover: hover) {
  .cast-device:hover:not(:disabled) { background: var(--hover); }
}
.cast-note { margin: 14px 0 0; color: var(--muted); }
.cast-note.is-error { color: var(--danger-text); }

/* Telefono: i cinque comandi in una riga di 358 px; la barra in basso più bassa. */
@media (max-width: 480px) {
  body.has-remote-bar main { padding-bottom: calc(84px + var(--safe-bottom)); }
  body.has-remote-bar .notice { bottom: calc(80px + var(--safe-bottom)); }
  .rm-controls:has(.rm-step:not([hidden])) { gap: 8px; }
  .rm-controls:has(.rm-step:not([hidden])) .player-toggle { --size: 88px; }
  .rm-controls:has(.rm-step:not([hidden])) .player-skip { --size: 64px; }
  .rm-controls:has(.rm-step:not([hidden])) .rm-step { --size: 52px; }
  .rm-device { min-height: 56px; padding: 6px 14px 6px 12px; }
  .remote-screen .rm-heading { font-size: 18px; }
  .player-remote { left: max(12px, var(--safe-left)); flex-wrap: wrap; padding: 10px; font-size: 15px;
    max-width: calc(100% - max(12px, var(--safe-left)) - max(12px, var(--safe-right)) - 76px); }
  .player-remote-text { flex-basis: 100%; padding: 0 4px; }
}
@media (max-width: 360px) {
  .rm-controls:has(.rm-step:not([hidden])) { gap: 6px; }
  .rm-controls:has(.rm-step:not([hidden])) .player-toggle { --size: 80px; }
  .rm-controls:has(.rm-step:not([hidden])) .player-skip { --size: 58px; }
  .rm-controls:has(.rm-step:not([hidden])) .rm-step { --size: 48px; }
}
/* L'auto (773×601, 773×575): i dispositivi un po' più bassi, perché restino
   titolo, stato e comandi grandi. */
@media (max-height: 650px) {
  .rm-devices { margin-top: 6px; }
  .rm-device { min-height: 52px; }
  .rm-track { margin: 14px 0 8px; }
}
@media (prefers-reduced-motion: reduce) {
  .remote-screen .player-btn.is-pending::after { animation: none; border-color: var(--accent-text); opacity: .6; }
  .cast-device, .cast-btn.on-thumb::before { transition: none; }
}

/* Finestre medie: la ricerca va su una riga sua, sotto logo, schede, tema e
   menu, quando accanto a loro il campo resterebbe più stretto di 250 px (fino
   a 1100 px, con le quattro schede). */
@media (max-width: 1100px) {
  .topbar { flex-wrap: wrap; row-gap: 8px; }
  .top-actions { order: 3; margin-left: auto; }
  .add-form { order: 4; flex-basis: 100%; max-width: none; margin-left: 0; }
}

/* --- metà schermo dell'auto (~630 px) e telefoni ------------------------- */

@media (max-width: 700px) {
  :root { --grid-gap: 12px; }
  /* Il testo un gradino sotto (15 px sul telefono; 17 nell'auto a metà
     schermo, vedi la leva in cima). */
  body { font-size: var(--fs-ui); }
  main { --main-pad: 12px; }
  .card-title { padding: 6px 10px 0; }
  .card-meta { padding: 0 10px; }
  .result .result-stats { margin-bottom: 8px; }
  .result .card-meta:has(+ .result-stats:empty) { margin-bottom: 8px; }
  /* Su più righe; una parola più larga della riga va a capo, non si taglia. */
  .section-head h2 { white-space: normal; font-size: var(--fs-subhead); overflow-wrap: break-word; }
  .sort { display: flex; }
  .sort .view-tab { flex: 1; padding: 0 6px; }
  .empty-state.is-page { margin: 6vh auto; }
  .tv-logo { width: 80px; height: 48px; }
  .tv-logo img { max-height: 32px; }
  .tv-card.is-thumb .tv-logo { width: 85px; height: 48px; }
  .tv-name { font-size: var(--fs-body); }
  .tv-head-row { column-gap: 12px; }
  .nets { column-gap: 12px; }
  .chip { padding: 0 12px; }
  .od-tab { padding: 0 10px; font-size: 15px; }
  .od-intro { grid-template-columns: minmax(0, 160px) minmax(0, 1fr); gap: 12px; }
  .od-head.is-deep .od-title { font-size: var(--fs-heading); }
  .settings-body { padding: 16px 16px 14px; gap: 16px; }
  .settings-footer { padding: 10px 16px 12px; }
  .settings-actions .btn { flex: 1; }
  .who-box { padding: 16px; }
  .who-head h2 { font-size: var(--fs-title); }
  .who-text { margin: 10px 0 14px; }
  .who-choice { min-height: 112px; padding: 12px 8px; }
  .who-choice svg { width: 40px; height: 40px; }
  .who-choice-name { font-size: var(--fs-subhead); }
  .diag-summary { grid-template-columns: 1fr; gap: 2px; }
  .diag-summary dd { margin-bottom: 10px; }
  .btn { padding: 0 14px; }
}

/* Telefono (la barra in alto: vedi "barra in alto: le misure", più sotto). */
@media (max-width: 480px) {
  /* Una colonna sola (di serie): niente righe da allineare, niente spazio riservato. */
  :root:not([data-cards="0"]) .tv-now { min-height: 0; }
  /* Pagina di un canale: "← Indietro" e − + in una riga, il nome sotto, a
     tutta riga (fra i due resterebbe troppo stretto: parole tagliate). */
  .section-head:has(> #search-back:not([hidden])) { flex-wrap: wrap; row-gap: 8px; }
  .section-head:has(> #search-back:not([hidden])) h2 { order: 1; flex-basis: 100%; }
  /* "In diretta | On demand" a tutta riga sotto il titolo (e − +); le fonti
     su due righe, tutte in vista ("Cerca" in fondo); le scelte (i sette
     giorni, gli sport) quattro per riga. */
  .tv-head-row .sizer { order: 1; }
  /* Alta come − +: quando compaiono (il primo gruppo aperto) la riga non cresce. */
  .tv-head-row h2 { min-height: 52px; display: flex; align-items: center; }
  .tv-modes { order: 2; flex: 1 1 100%; }
  .tv-modes .view-tab { flex: 1; justify-content: center; padding: 0 10px; }
  .od-tabs { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); overflow: visible; padding: 0; column-gap: 0; }
  .od-tab { min-width: 0; padding: 0 4px; border-radius: var(--radius-m); }
  .od-tab::after { left: 8px; right: 8px; bottom: 2px; border-radius: 3px; }
  .od-tab-search { margin-left: 0; grid-column: -2; }
  /* Le scelte: nomi corti (i giorni) quattro per riga, tutti in vista; gli
     altri (canali, stagioni, sport) in una fila che scorre. */
  .od-chips { flex: 1 1 100%; }
  .od-chips.is-short { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); overflow: visible; -webkit-mask-image: none; mask-image: none; animation: none; }
  .od-chips.is-short .chip { min-width: 0; padding: 0 6px; overflow: hidden; text-overflow: ellipsis; }
  .od-chips.is-pick { display: flex; }
  .od-pick { flex: 1; min-width: 0; }
  /* Il palinsesto a tutto schermo, senza il logo; i giorni quattro per riga, come sopra. */
  .guide { inset: 0; width: 100vw; height: 100vh; height: 100dvh; border: 0; border-radius: 0; }
  .guide-head { gap: 10px; padding: max(10px, var(--safe-top)) 8px 10px 16px; }
  .guide-logo { display: none; } /* il nome basta: il posto va al giorno */
  .guide-sub { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; line-height: 1.3; }
  .guide-watch { padding: 0 12px 0 10px; }
  .guide-days-row { padding: 0 12px 10px; }
  .guide-scroll { padding: 6px 4px calc(16px + var(--safe-bottom)); }
  .guide-row { column-gap: 10px; padding: 10px 8px; }
  .od-bar .list-tools { display: flex; }
  .od-head.is-deep .od-title { flex-basis: 100%; font-size: var(--fs-heading); }
  /* La copertina piccola accanto alla descrizione: le puntate restano vicine. */
  .od-intro { grid-template-columns: minmax(0, 112px) minmax(0, 1fr); gap: 12px; }
  .od-intro-text { font-size: var(--fs-meta); -webkit-line-clamp: 6; }
  .od-search .btn { padding: 0 14px; }
  /* Pillole a due colonne, col nome sopra la scelta. */
  .list-tools { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pick {
    min-width: 0;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 0;
    min-height: 52px;
    padding: 5px 30px 5px 12px;
    line-height: 1.25;
  }
  .pick::after { right: 13px; }
  .pick-name { font-size: var(--fs-meta); }
  .pick-value { max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
  .pick-toggle, .pick-reset { flex-direction: row; align-items: center; gap: 8px; padding: 5px 10px; white-space: normal; text-align: left; }
  /* Cinque pillole nella ricerca: "Togli i filtri" nel posto libero accanto all'ultima. */
  .pick-reset { justify-self: start; min-height: 44px; }
  /* Ordina + "Nascondi già visti": più spazio all'ordinamento. */
  .list-tools:has(.pick-toggle) { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); }
  .pick-toggle { font-size: var(--fs-meta); }
  /* Ricerca: "Ordina" e "Filtri" in una riga; i filtri nel pannello sotto,
     aperto dalla pillola. */
  .search-tools .pick-filters { display: flex; }
  .search-tools .filter-panel { display: none; }
  .search-tools.is-open .filter-panel {
    display: grid;
    grid-column: 1 / -1;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
  }
  .pick-filters[aria-expanded="true"]::after { transform: translateY(-25%) rotate(225deg); }
}

/* Telefono stretto: il campo della ricerca un po' più largo dentro (il
   segnaposto ci sta intero). */
@media (max-width: 389px) {
  /* I giorni ("Mer 23") interi anche a 320 px, quattro per riga. */
  .od-chips.is-short .chip { padding: 0 2px; font-size: var(--fs-meta); }
  .od-tab { font-size: 14px; gap: 5px; }
  .od-tab svg { width: 17px; height: 17px; }
  .add-form { gap: 6px; }
  .add-form input { padding: 0 10px; }
  .add-form .btn { padding: 0 14px; }
}

/* --- l'auto: finestra bassa (773×601, 773×575) --------------------------- */
/* La finestra vera del browser dell'auto è bassa: sopra le schede ci sono già
   la barra in alto, "In diretta | On demand" (o "Podcast | Radio") e le fonti.
   Qui, fuori dal telefono, meno aria fra i blocchi e intestazioni più basse,
   perché nel primo schermo ci stia almeno una scheda (o un episodio) intera. */
@media (max-height: 650px) and (min-width: 481px) {
  .tv-head-row { margin-bottom: 8px; }
  .od-tabs { margin-bottom: 10px; }
  .od-head { margin-bottom: 10px; }
  /* La fila delle scelte si stringe (e scorre, vedi .od-chips) accanto agli
     interruttori e a "Ultime uscite": una riga sola, non due. */
  .od-bar { margin-bottom: 10px; }
  .od-bar > .od-chips:not(.is-pick) { flex: 1 1 320px; }
  /* Un programma (una cartella aperta, con "← …"): la descrizione su una
     riga, senza copertina (è quella della scheda appena toccata), e 8 px fra
     le righe. Le stagioni (la fila delle scelte) vanno sulla riga di "← …" e
     del titolo, a destra; il titolo ha fino al 62% della riga, poi va a capo
     accanto a "← …" (due righe da 19 px alte quanto "← …"), e le stagioni
     scorrono. Così nel primo schermo c'è una puntata intera anche a 773×575:
     196 + 44 + 8 + 23 + 8 = 279, più la scheda da 293. */
  .od-head.is-deep { margin-bottom: 8px; }
  .od-head.is-deep .od-title { font-size: var(--fs-heading); line-height: 1.2; }
  .od-intro, .od-intro.no-cover { grid-template-columns: minmax(0, 1fr); margin-bottom: 8px; }
  .od-intro img { display: none; }
  .od-intro-text { -webkit-line-clamp: 1; }
  .od:has(> .od-head.is-deep:not([hidden]) ~ .od-bar > .od-chips:not([hidden])) {
    display: grid;
    grid-template-columns: fit-content(62%) minmax(0, 1fr);
    column-gap: 16px;
  }
  .od:has(> .od-head.is-deep:not([hidden]) ~ .od-bar > .od-chips:not([hidden])) > * { grid-column: 1 / -1; order: 1; }
  .od:has(> .od-head.is-deep:not([hidden]) ~ .od-bar > .od-chips:not([hidden])) > :is(.od-tabs, .od-head, .od-bar) { order: 0; }
  .od:has(> .od-head.is-deep:not([hidden]) ~ .od-bar > .od-chips:not([hidden])) > .od-head { grid-column: 1; flex-wrap: nowrap; }
  .od:has(> .od-head.is-deep:not([hidden]) ~ .od-bar > .od-chips:not([hidden])) > .od-head .od-title { flex: 0 1 auto; }
  .od:has(> .od-head.is-deep:not([hidden]) ~ .od-bar > .od-chips:not([hidden])) > .od-bar { grid-column: 2; margin-bottom: 8px; }
  .od:has(> .od-head.is-deep:not([hidden]) ~ .od-bar > .od-chips:not([hidden])) > .od-bar > .od-chips { flex: 0 1 auto; margin-left: auto; }
  /* Un podcast: copertina più piccola, righe più vicine; la descrizione su
     due righe con "Mostra tutto" accanto, non sotto. "Riproduci" resta in
     vista. */
  .pod-hero { gap: 16px; margin-bottom: 12px; }
  .pod-hero-art { width: 128px; }
  .pod-hero-text { gap: 2px; }
  .pod-actions { margin-top: 8px; }
  .pod-about { margin-bottom: 10px; }
  .pod-about:has(> .pod-desc-more:not([hidden])) { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; column-gap: 12px; }
  .pod-desc { -webkit-line-clamp: 2; }
  .views.pod-filter { margin-bottom: 10px; }
}
/* La Ricerca nell'auto: «Ordina» e «Filtri» in una riga, i filtri a
   richiesta (come .is-compact, vedi in alto), e meno aria sopra i risultati:
   a 773×575 la prima scheda sta intera nel primo schermo. */
@media (max-height: 650px) and (min-width: 600px) {
  .search-tools .pick-filters { display: inline-flex; }
  .search-tools .filter-panel { display: none; }
  .search-tools.is-open .filter-panel { display: flex; flex-wrap: wrap; flex-basis: 100%; gap: 8px; }
  .search-tools .pick-filters[aria-expanded="true"]::after { transform: translateY(-25%) rotate(225deg); }
  /* Sotto la barra 10 px (non 16), 8 sotto il titolo, 10 sotto le pillole,
     e nelle schede (col testo della leva) 2 px fra miniatura, titolo e righe,
     come in On demand: la scheda comincia a 237 (112 + 10 + 52 + 8 + 44 + 10,
     più il bordo) e finisce, alta al più 336, a 573. */
  main[data-view="search"] { padding-top: 10px; }
  .search .section-head { margin-bottom: 8px; }
  .search-tools { margin-bottom: 10px; }
  :where(:root[data-touch]) .result .card-play { row-gap: 2px; }
}
/* Il testo della leva (18 px, meta 16: vedi in cima) con le righe di una
   riga sola (autore, meta) e le descrizioni un po' più strette, e pochi px
   in meno dentro una puntata e un episodio. Così nel primo schermo resta
   quello che c'era a 16 px: a 773×575 la puntata intera sotto il titolo del
   programma e il primo episodio sotto la testata del podcast. Solo dove il
   testo è cresciuto (la condizione della leva): con la finestra bassa di un
   computer il testo resta a 16 e le righe quelle di prima. :where() non
   aggiunge peso ai selettori: vincono le stesse regole di prima. */
@media (max-height: 650px) and (min-width: 600px) {
  :where(:root[data-touch]) .od-card .card-meta, :where(:root[data-touch]) .od-folder .card-meta { line-height: 1.3; }
  :where(:root[data-touch]) .od-card .card-play { row-gap: 2px; padding-bottom: 10px; }
  :where(:root[data-touch]) .od-intro-text { line-height: 1.3; }
  :where(:root[data-touch]) .pod-author, :where(:root[data-touch]) .pod-meta { line-height: 1.25; }
  :where(:root[data-touch]) .pod-desc { line-height: 1.35; }
  :where(:root[data-touch]) .pod-ep-play { padding-top: 10px; padding-bottom: 12px; }
  :where(:root[data-touch]) .pod-ep-meta { line-height: 1.25; }
  :where(:root[data-touch]) .pod-ep-desc { line-height: 1.3; }
}

/* --- barra in alto: le misure -------------------------------------------- */
/* Logo, le quattro schede, voce, tema e menu in una riga
   a ogni larghezza, alta uguale, coi nomi delle schede sempre interi. Fra le
   schede 8 px (--tab-gap; 4 sul telefono): un tocco un po' fuori non prende
   quella accanto. Stringendo si stringono gli spazi dentro le schede,
   calcolati sulla larghezza della barra (100cqw, senza i suoi margini): logo
   + nomi + spazi fra le schede + spazi fissi + voce, tema e menu (44 + 4 + 44
   + 4 + 44 = 140) vanno sottratti, e il resto diviso fra i due lati delle
   schede, con 4 px d'avanzo. I nomi sono misurati col font più largo che c'è
   (DejaVu Sans, semigrassetto), misurati con "Ricerca", "Per te" e "TV
   italiana" (YouTube è largo come Ricerca; TV da solo 22): 15 px 71 + 63 +
   52 + 91 + 63, 16 px 75 + 67 + 55 + 97 + 67; i conti sotto restano quelli,
   con un avanzo.
   "TV" da solo è largo almeno 44 px: vale il più piccolo dei due spazi, quello
   con "TV" a 44 px (22 in più, ma i suoi due lati non contano) e quello con
   "TV" largo quanto il nome e i lati.
   Poi il logo diventa il simbolo, e il tema va nel menu
   ⋯; sul telefono il logo lascia il posto alle schede, che si prendono la
   riga coi nomi un po' più piccoli. Si torna ai Preferiti dalla loro scheda.
   Misurato in Chromium da 320 a 1920 px: nomi interi da 340 px; a 320 si
   accorciano coi puntini. */
@media (max-width: 900px) {
  .topbar { --bar-pad: 12px; column-gap: 8px; }
  .home img { width: 150px; }
  /* Quattro schede con "TV italiana": 150 + 8 + 288 + 24 + 8 + 140 = 618
     (a 773 px, l'auto, restano 14 px per lato e 127 d'avanzo). */
  .top-views .view-tab { font-size: 15px; padding: 0 clamp(4px, (100cqw - 622px) / 8, 14px); }
}
/* Più stretto (a metà schermo, 627 px): il logo a
   128 px (128 + 8 + 219 + 24 + 8 + 140 = 527; con "TV" a 44 px 549). */
@media (max-width: 720px) {
  .home img { width: 128px; }
  .top-views .view-tab { padding: 0 clamp(4px, min((100cqw - 553px) / 6, (100cqw - 531px) / 8), 14px); }
}
/* Del logo resta il simbolo (30 + 8 + 219 + 24 + 8 + 140 = 429; 451). */
@media (max-width: 600px) {
  .home img { width: 30px; height: 30px; object-fit: cover; object-position: left center; }
  .top-views .view-tab { padding: 0 clamp(4px, min((100cqw - 455px) / 6, (100cqw - 433px) / 8), 14px); }
}
/* Il tema nel menu ⋯ (restano voce e menu, 44 + 4 + 44): quattro schede
   30 + 8 + 219 + 24 + 8 + 92 = 381 (403); cinque, coi nomi a 14 px,
   30 + 8 + 253 + 32 + 8 + 92 = 423 (445). */
@media (max-width: 560px) {
  .top-actions > .theme-toggle { display: none; }
  .menu-panel .theme-toggle { display: inline-flex; }
  .top-views .view-tab { padding: 0 clamp(4px, min((100cqw - 407px) / 6, (100cqw - 385px) / 8), 14px); }
}
/* Telefono: niente logo, le schede si prendono la riga (e lo spazio che
   avanza), larghe almeno 44 px (40 con cinque fino a 360), 4 px fra l'una e
   l'altra (2 con cinque sotto i 430 px); i nomi crescono con la barra fino a
   15 px (12 a 320), con cinque schede fino a 14 (11 a 320). Voce e menu, 40 e
   44, a 2 px: i 4 px in più del menu vengono dai margini della barra (6, 4
   fino a 360). */
@media (max-width: 480px) {
  .topbar { --tab-gap: 4px; --bar-pad: 6px; column-gap: 6px; }
  .topbar:has(.top-views) h1 { display: none; }
  .views.top-views { flex: 1; min-width: 0; display: flex; }
  .top-views .view-tab { flex: 1 1 auto; padding: 0 4px; font-size: clamp(12px, 3.95cqw, 15px); overflow: hidden; text-overflow: ellipsis; }
  .top-actions { gap: 2px; }
  .topbar > .top-voice { min-width: 40px; padding: 0 8px; }
  .menu summary { min-width: 44px; padding: 0 8px; }
}
@media (max-width: 360px) {
  .topbar { --bar-pad: 4px; column-gap: 4px; }
  .top-views .view-tab { padding: 0 2px; }
}

/* Schede TV strette (le più piccole, o due colonne sul telefono): il logo
   sopra il nome, largo quanto la scheda, e il nome su due righe. */
/* Schede TV non larghe (quattro per riga a tutto schermo, due a metà): il
   «Poi:» della riga del palinsesto su una riga sua, intera, «Palinsesto» sotto. */
@container (max-width: 329px) {
  .tv-guide { row-gap: 2px; padding-top: 7px; padding-bottom: 7px; }
  .tv-guide .tv-next { flex-basis: 100%; }
}
/* Due per riga accanto alle reti (l'auto: schede da 250-280 px): il logo un
   po' più piccolo, perché il nome ci stia intero su una riga («Rai News 24»,
   «Rai 3 TGR», «Rai Radio 1»). */
@container (min-width: 230px) and (max-width: 279px) {
  .tv-head { gap: 10px; }
  .tv-logo { width: 76px; height: 46px; }
  .tv-logo img { max-width: calc(100% - 14px); max-height: 30px; }
  .tv-card.is-thumb .tv-logo { width: 80px; height: 45px; }
}
@container (max-width: 229px) {
  .tv-head { flex-direction: column; align-items: stretch; gap: 8px; }
  .tv-logo, .tv-card.is-thumb .tv-logo { width: 100%; }
  /* Gli orari ai due lati, la barra sotto, larga. */
  .tv-time { flex-wrap: wrap; justify-content: space-between; row-gap: 6px; }
  .tv-progress { order: 1; flex-basis: 100%; }
  .tv-name {
    white-space: normal;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    line-height: 1.25;
  }
}

/* Player (misure sue, come prima): comandi un po' più piccoli sul telefono. */
@media (max-width: 720px) {
  .player-top { padding: max(12px, var(--safe-top)) max(12px, var(--safe-right)) 40px max(16px, var(--safe-left)); }
  .player-top h2 { font-size: 17px; }
  .player-center { gap: 28px; }
  .player-toggle { --size: 80px; }
  .player-skip { --size: 60px; }
  .player-bottom { padding: 40px max(16px, var(--safe-right)) max(8px, var(--safe-bottom)) max(16px, var(--safe-left)); }
  .player-bar { column-gap: 8px; }
  .bar-actions { gap: 6px; }
  .bar-btn { padding: 0 13px; }
  .bar-btn-value { min-width: 56px; padding: 0 10px; }
  .player-diag { top: 72px; left: max(12px, var(--safe-left)); max-width: calc(100% - 24px - var(--safe-left) - var(--safe-right)); }
  .player-toast { top: 72px; font-size: 15px; }
  .player-diag:not([hidden]) ~ .player-toast { top: 140px; }
  .player.is-audio-only .player-now { top: 80px; left: max(16px, var(--safe-left)); right: max(16px, var(--safe-right)); }
  /* Gli avvisi sotto la X da 64 px (finisce a 76). */
  .player.is-audio-only :is(.player-diag, .player-toast) { top: 84px; }
  .player.is-audio-only .player-diag:not([hidden]) ~ .player-toast { top: 152px; }
  /* Col video, accanto al titolo: il volante e la velocità, senza "Guida attiva" (resta per i lettori di schermo). */
  .player:not(.is-audio-only) .guida-lead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .now-title { font-size: 26px; }
  .now-channel { font-size: 18px; }
  .message-title { font-size: 22px; }
  .message-text { font-size: 16px; }
}

/* Telefono: la barra in basso ci sta in una riga in diretta; in un video, col
   tempo e la velocità, i pulsanti vanno sotto il tempo, a destra. */
@media (max-width: 480px) {
  .player-bottom { padding: 36px max(12px, var(--safe-right)) max(6px, var(--safe-bottom)) max(12px, var(--safe-left)); }
  .player-bar { column-gap: 6px; }
  .bar-btn { gap: 6px; padding: 0 12px; }
  .bar-btn-value { min-width: 50px; padding: 0 8px; }
  /* Solo "Auto": il numero è nel menu. */
  .res-now { display: none; }
  .player-diag { font-size: 12px; }
  /* Il titolo tiene la riga con la X; "Passeggero · cambia" va sotto, a
     sinistra, su una riga sua (ci sta intero anche a 320 px). */
  .player-top { flex-wrap: wrap; row-gap: 4px; }
  .player-top h2 { flex: 1 0 calc(100% - 72px); }
  .player-top .player-close { order: -1; }
  .player-top .player-who { order: 3; min-height: 44px; margin-top: -8px; }
  /* Lo stato della modalità guida anche lui sotto, col video; col solo audio
     (il titolo in alto non si vede) resta sulla riga della X, a sinistra. */
  .player-top .player-guida { order: 3; margin-top: -4px; }
  /* Qui ha una riga sua: di nuovo "Guida attiva". */
  .player:not(.is-audio-only) .guida-lead { position: static; width: auto; height: auto; overflow: visible; clip-path: none; }
  .player.is-audio-only .player-top .player-guida { order: 1; margin-top: 0; }
  /* Gli avvisi scendono sotto "Passeggero · cambia" o lo stato della guida, quando ci sono. */
  .player:is(:has(#player-who:not([hidden])), :not(.is-audio-only):has(#player-guida:not([hidden]))) :is(.player-diag, .player-toast) { top: 120px; }
  .player:is(:has(#player-who:not([hidden])), :not(.is-audio-only):has(#player-guida:not([hidden]))) .player-diag:not([hidden]) ~ .player-toast { top: 188px; }
  .player.is-audio-only .player-center { gap: 20px; }
  .now-title { font-size: 24px; }
}

/* 320-360 px: la barra ci sta tutta, sotto il tempo. "Solo audio" e "Mostra
   video" diventano solo l'icona (il nome resta per i lettori di schermo). */
@media (max-width: 360px) {
  #bar-mode { width: 44px; padding: 0; }
  .player.is-audio-only #bar-mode { width: 60px; }
  #bar-mode-text { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .player.is-audio-only { --toggle: 112px; }
  .player.is-audio-only .player-skip { --size: 76px; }
  .player.is-audio-only .player-center { gap: 14px; }
  .message-btn { padding: 0 18px; }
  /* La conferma di "Mostra video" qui va su due righe e sale fin sotto la
     frase della pausa: la frase le lascia il posto finché c'è. */
  .player:has(#bar-confirm:not([hidden])) .loading-step { visibility: hidden; }
  /* "Passeggero" intero anche a 320 px. */
  .who-choice { padding: 12px 4px; }
  .who-choice-name { font-size: var(--fs-body); }
}

/* Finestra bassa (l'auto: 773×601, 773×575; un telefono da 568): con la barra
   da 60 px la barra del tempo sale fin dove starebbe "Premi play per
   riprendere da 0:02.", e il pallino la coprirebbe. Il tempo è già nella
   barra: resta "In pausa". In diretta la barra del tempo non c'è e la frase
   dice da dove si riprende: resta. */
@media (max-height: 650px) {
  .player.is-audio-only.is-paused:not(.is-live) .loading-step { display: none; }
}
/* Schermo basso (telefono in orizzontale): col solo audio niente copertina,
   il titolo su una riga, comandi un po' più piccoli. Il play finisce sopra la
   barra del tempo (che comincia 116 px sopra il fondo, con la barra da 60),
   con 8 px di margine: un tocco sul suo bordo basso non sposta il video. */
@media (max-height: 560px) {
  .player.is-audio-only { --toggle: 104px; --mid: min(60%, calc(100% - 124px - var(--toggle) / 2)); }
  .player.is-audio-only .player-skip { --size: 76px; }
  .player-now .player-art { display: none; }
  /* Fino in cima, lasciando libera la X (64 px). */
  .player.is-audio-only .player-now { top: 12px; left: 88px; right: 88px; gap: 2px; }
  /* Lo stato della modalità guida sta nel margine a sinistra: solo il volante
     (giallo senza GPS; la frase resta per i lettori di schermo). */
  .player.is-audio-only .player-guida #player-guida-text { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .now-status { margin-top: 2px; }
  .now-title { display: block; max-width: 100%; font-size: 22px; line-height: 1.3; white-space: nowrap; text-overflow: ellipsis; }
  .now-channel { font-size: 16px; }
  /* In pausa la frase starebbe sopra la barra del tempo: bastano il play e
     il tempo nella barra. */
  .player.is-audio-only.is-paused .loading-text { display: none; }
}
/* Stretto e basso (solo un telefono, mai l'auto): la barra va su due righe
   sotto il play, coi pulsanti di prima (44). */
@media (max-height: 560px) and (max-width: 480px) {
  .player.is-audio-only .player-bar { min-height: 48px; }
  .player.is-audio-only .bar-btn { min-height: 44px; border-radius: 22px; }
  .player.is-audio-only .bar-btn-icon { width: 44px; }
  .player.is-audio-only .bar-btn-value { min-width: 50px; }
}
/* Ancora più basso (320 px): comandi un po' più piccoli, tra il titolo e la barra. */
@media (max-height: 340px) {
  .player.is-audio-only { --toggle: 92px; }
  .player.is-audio-only .player-skip { --size: 68px; }
}

/* Schermo basso (telefono in orizzontale): i due pulsanti del gate restano
   interi senza scorrere. */
@media (max-height: 480px) {
  .who-box { padding: 14px 18px; }
  .who-head h2 { font-size: var(--fs-title); }
  .who-text { margin: 8px 0 12px; }
  .app-hint-steps { gap: 8px; margin-bottom: 14px; }
  .app-hint-mark { width: 36px; height: 36px; }
  .app-hint-mark svg { width: 20px; height: 20px; }
  .who-choice { min-height: 88px; padding: 8px; gap: 2px; }
  .who-choice svg { width: 32px; height: 32px; margin-bottom: 2px; }
  .who-choice-name { font-size: var(--fs-subhead); }
}


/* --- «Riprendi» (vedi Riprendi in app.js) ------------------------------------ */
/* In cima ai Preferiti: una scheda larga, tutta da toccare (76 px d'altezza:
   nell'auto si trova al primo sguardo e si prende col dito), tinta d'accento
   come le cose scelte; la X a parte, a destra. La riga in fondo: quanto se ne
   è visto o ascoltato. */
.riprendi {
  position: relative;
  display: flex;
  align-items: center;
  margin-bottom: 22px;
  border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--border));
  border-radius: var(--radius-l);
  background: color-mix(in srgb, var(--accent) 9%, var(--surface));
  overflow: hidden;
}
.riprendi-play {
  all: unset;
  box-sizing: border-box;
  flex: 1;
  min-width: 0;
  min-height: 76px;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 10px 10px 10px;
  cursor: pointer;
}
.riprendi-play:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; border-radius: var(--radius-l); }
.riprendi-art {
  position: relative;
  flex: none;
  width: 104px;
  height: 58px;
  border-radius: var(--radius-s);
  overflow: hidden;
  background: var(--surface-2);
}
.riprendi-art img { display: block; width: 100%; height: 100%; object-fit: cover; }
.riprendi[data-kind="podcast"] .riprendi-art { width: 58px; }
/* Il logo di un canale o di una radio, sul riquadro blu delle loro schede. */
.riprendi-art.is-logo { width: 96px; padding: 9px 10px; background: var(--logo-tile); }
.riprendi-art.is-logo img { object-fit: contain; }
.riprendi-art.is-logo.is-dark-logo { background: var(--logo-light); }
.riprendi-text { flex: 1; min-width: 0; display: grid; gap: 3px; }
.riprendi-title {
  font-size: var(--fs-lead);
  font-weight: 650;
  line-height: 1.3;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.riprendi-verb { color: var(--accent-text); }
.riprendi-meta { color: var(--muted); font-size: var(--fs-meta); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.riprendi-go {
  flex: none;
  width: 52px;
  height: 52px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--accent-strong);
  color: var(--on-accent);
  transition: transform .12s;
}
.riprendi-go svg { width: 24px; height: 24px; fill: currentColor; }
.riprendi-play:active .riprendi-go { background: var(--accent-hover); transform: scale(.94); }
.riprendi-play:active .riprendi-art { opacity: .8; }
/* Mentre arriva quello che serve (l'elenco delle radio, l'episodio): il play pulsa. */
@keyframes riprendi-wait { 50% { opacity: .45; } }
.riprendi.is-busy .riprendi-go { animation: riprendi-wait 1s ease-in-out infinite; }
.riprendi-close {
  flex: none;
  width: 48px;
  height: 48px;
  margin-right: 8px;
  padding: 0;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: var(--radius);
  background: none;
  color: var(--muted);
  cursor: pointer;
}
.riprendi-close svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }
.riprendi-close:active { background: var(--hover); color: var(--text); }
.riprendi-close:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }
@media (hover: hover) {
  .riprendi-play:hover .riprendi-go { background: var(--accent-hover); }
  .riprendi-play:hover .riprendi-title #riprendi-name { text-decoration: underline; text-decoration-color: color-mix(in srgb, var(--text) 40%, transparent); text-underline-offset: 3px; }
  .riprendi-close:hover { background: var(--hover); color: var(--text); }
}
.riprendi-bar { position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: var(--track); }
.riprendi-bar > span { display: block; height: 100%; background: var(--accent-text); transform: scaleX(0); transform-origin: left; }
/* Telefono: la copertina più piccola, perché titolo e riga sotto restino leggibili. */
@media (max-width: 480px) {
  .riprendi-play { gap: 12px; padding: 8px 6px 8px 8px; min-height: 72px; }
  .riprendi-art { width: 72px; height: 40px; }
  .riprendi[data-kind="podcast"] .riprendi-art { width: 48px; height: 48px; }
  .riprendi-art.is-logo { width: 72px; height: 44px; padding: 7px 8px; }
  .riprendi-go { width: 44px; height: 44px; }
  .riprendi-go svg { width: 20px; height: 20px; }
  .riprendi-meta { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
  .riprendi-close { margin-right: 4px; }
}
@media (prefers-reduced-motion: reduce) {
  .riprendi.is-busy .riprendi-go { animation: none; opacity: .6; }
}

/* --- canali e radio preferiti (vedi toggleLiveFav in app.js) ------------------- */
/* La stella sulla scheda di un canale o di una radio: in alto a destra (con
   «Riproduci su…» alla sua sinistra, o sotto nelle schede fino a 379 px),
   48 px da toccare, fuori dal pulsante che fa partire. Accesa: piena, gialla
   (5:1 anche sul bianco). Il nome lascia il posto a quelli sulla sua riga. */
.live-fav {
  position: absolute;
  top: 4px;
  right: 4px;
  z-index: 1;
  width: 48px;
  height: 48px;
  padding: 0;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: var(--radius);
  background: none;
  color: var(--muted);
  cursor: pointer;
}
.live-fav svg { width: 23px; height: 23px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linejoin: round; transition: transform .12s; }
.live-fav[aria-pressed="true"] { color: var(--star-ink); }
.live-fav[aria-pressed="true"] svg { fill: currentColor; }
.live-fav:active { background: var(--hover); }
.live-fav:active svg { transform: scale(.85); }
.live-fav:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }
@media (hover: hover) {
  .live-fav:hover { background: var(--hover); color: var(--text); }
  .live-fav[aria-pressed="true"]:hover { color: var(--star-ink); }
}
.tv-card .cast-btn.on-card { right: 52px; }
.tv-card .tv-head { padding-right: 28px; }
:root[data-remote] .tv-card .tv-head { padding-right: 88px; }
/* Le schede fino a 379 px (a 2-4 colonne, l'auto, il telefono): stella e
   «Riproduci su…» una sopra l'altra a destra, e il nome tiene la larghezza
   che aveva con «Riproduci su…» da solo (con i due in fila, 88 px: «Rai News
   24» diventava «Rai N…»); la riga di quello in onda lascia il posto al
   secondo pulsante. Le schede col solo nome (senza guida) si alzano quanto
   i due pulsanti, col nome in mezzo. */
@container (min-width: 230px) and (max-width: 379px) {
  :root[data-remote] .tv-card .tv-head { padding-right: 28px; }
  :root[data-remote] .tv-card :is(.tv-now, .radio-now) { padding-right: 28px; }
  :root[data-remote] .tv-card.is-bare .tv-play { min-height: 80px; justify-content: center; } /* 104 col padding */
  .tv-card .cast-btn.on-card { top: 52px; right: 4px; }
}
/* Schede strette (il logo sopra il nome): stella e «Riproduci su…» una sopra
   l'altra a destra, il logo e il nome accanto. */
@container (max-width: 229px) {
  .tv-card .tv-head, :root[data-remote] .tv-card .tv-head { padding-right: 38px; }
  .tv-card .cast-btn.on-card { top: 52px; right: 4px; }
}
/* Nei Preferiti: «Canali» e «Radio», sopra i video. */
.fav-live { margin-bottom: 24px; }

/* Il numero dei promemoria in arrivo, nel menu ⋯. */
.menu-count {
  margin-left: 8px;
  min-width: 26px;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--accent-strong);
  color: var(--on-accent);
  font-size: var(--fs-meta);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: center;
}

/* --- promemoria del palinsesto (vedi Promemoria in app.js) ---------------------- */
/* Nel palinsesto, a destra di ogni programma che deve ancora iniziare:
   «Avvisami» (la campanella vuota, d'accento senza bordo, come «Palinsesto»
   sulle schede: una colonna di pulsanti col bordo pesava), messo «Avviso
   attivo» (piena, sul pieno d'accento: il segno sul programma). Stretto,
   solo la campanella. */
.guide-item { display: flex; align-items: center; gap: 6px; }
.guide-item > .guide-row { flex: 1; min-width: 0; }
.guide-bell {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-width: 48px;
  min-height: 44px;
  margin-right: 6px;
  padding: 0 14px 0 12px;
  border: 1px solid transparent;
  border-radius: 999px;
  background: none;
  color: var(--accent-text);
  font: inherit;
  font-size: var(--fs-ui);
  font-weight: 650;
  white-space: nowrap;
  cursor: pointer;
}
.guide-bell svg { flex: none; width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.guide-bell[aria-pressed="true"] { border-color: var(--accent-strong); background: var(--accent-strong); color: var(--on-accent); }
.guide-bell[aria-pressed="true"] svg { fill: currentColor; }
.guide-bell.is-pending { opacity: .7; }
.guide-bell:active { background: var(--hover); }
.guide-bell[aria-pressed="true"]:active { background: var(--accent-hover); }
.guide-bell:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
@media (hover: hover) {
  .guide-bell:hover { background: var(--hover); }
  .guide-bell[aria-pressed="true"]:hover { background: var(--accent-hover); }
}
@media (max-width: 560px) {
  .guide-bell { width: 48px; padding: 0; }
  .guide-bell-text { display: none; }
}
/* «Rivedi» (vedi playReplay in app.js): sui programmi finiti che si possono
   rivedere, al posto della campanella e come lei (d'accento senza bordo: su
   Rai Yoyo sono quasi tutte le righe, e una colonna di pulsanti pieni
   pesava). Stretto, solo il simbolo. */
.guide-replay {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-width: 48px;
  min-height: 44px;
  margin-right: 6px;
  padding: 0 14px 0 12px;
  border: 1px solid transparent;
  border-radius: 999px;
  background: none;
  color: var(--accent-text);
  font: inherit;
  font-size: var(--fs-ui);
  font-weight: 650;
  white-space: nowrap;
  cursor: pointer;
}
.guide-replay svg { flex: none; width: 21px; height: 21px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.guide-replay svg .fill { fill: currentColor; stroke: none; }
.guide-replay:active { background: var(--hover); }
.guide-replay:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
@media (hover: hover) {
  .guide-replay:hover { background: var(--hover); }
}
/* Nei giorni passati e tra quelli finiti di oggi le righe restano leggibili
   dove c'è da rivedere. */
.guide-item.is-past.has-replay .guide-name { color: var(--text); }
@media (max-width: 560px) {
  .guide-replay { width: 48px; padding: 0; }
  .guide-replay-text { display: none; }
}
/* Il «Rivedi» ancora in controllo: una pillola quieta in basso, sopra
   l'elenco e fuori dal suo flusso (comparendo e sparendo non sposta le
   righe sotto il dito); i tocchi passano alle righe sotto. */
.guide-box { position: relative; }
.guide-note {
  position: absolute;
  left: 50%;
  bottom: 14px;
  z-index: 1;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: calc(100% - 32px);
  margin: 0;
  padding: 9px 16px 9px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-2);
  box-shadow: var(--shadow-pop);
  color: var(--text);
  font-size: var(--fs-ui);
  white-space: nowrap;
  pointer-events: none;
}
.guide-note[hidden] { display: none; }
.guide-note-dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent-text);
  animation: guide-note-pulse 1.2s ease-in-out infinite alternate;
}
@keyframes guide-note-pulse { from { opacity: .25; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .guide-note-dot { animation: none; } }

/* ⋯ → Promemoria: il foglio del palinsesto, alto quanto serve; a giorni, le
   righe come quelle del palinsesto, con «Guarda» (in onda) e la X. */
.reminders { height: fit-content; max-height: calc(100dvh - 24px - var(--safe-top) - var(--safe-bottom)); }
.reminders .guide-box { height: auto; max-height: inherit; }
.reminders-icon {
  flex: none;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 16%, var(--surface));
  color: var(--accent-text);
}
.reminders-icon svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.reminders-scroll { border-top: 1px solid var(--border); }
.reminders-day + .reminders-day { margin-top: 12px; }
.reminders-day-title { margin: 6px 12px 6px; color: var(--muted); font-size: var(--fs-ui); font-weight: 650; }
.reminder-item .reminder-watch { flex: none; }
.reminder-delete {
  flex: none;
  width: 48px;
  height: 48px;
  padding: 0;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: var(--radius);
  background: none;
  color: var(--muted);
  cursor: pointer;
}
.reminder-delete svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }
.reminder-delete:active { background: var(--hover); color: var(--text); }
.reminder-delete:disabled { opacity: .4; cursor: default; }
.reminder-delete:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }
@media (hover: hover) {
  .reminder-delete:hover:not(:disabled) { background: var(--hover); color: var(--text); }
}

/* L'avviso di un promemoria: in basso nella pagina (sopra le barre in basso e
   sopra l'altro avviso, se c'è), in alto dentro il player, l'ascolto e il
   telecomando (sotto la riga del titolo, lontano dai comandi). La campanella,
   «Inizia ora:» d'accento, il programma e il canale, «Guarda» pieno e la X. */
.remind {
  position: fixed;
  left: 50%;
  bottom: calc(16px + var(--safe-bottom));
  z-index: 7;
  transform: translateX(-50%);
  width: max-content;
  max-width: min(660px, calc(100vw - 24px - var(--safe-left) - var(--safe-right)));
  min-height: 64px;
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  padding: 8px 8px 8px 12px;
  border: 1px solid color-mix(in srgb, var(--accent) 55%, var(--border));
  border-radius: var(--radius-l);
  background: var(--raised);
  box-shadow: var(--shadow-pop);
  color: var(--text);
  font-size: var(--fs-body);
}
@keyframes remind-in { from { opacity: 0; transform: translate(-50%, 12px); } }
.remind:not([hidden]) { animation: remind-in .32s cubic-bezier(.16, 1, .3, 1); }
:root[data-moving] .remind:not([hidden]) { animation: none; } /* in movimento niente che attiri lo sguardo */
.remind-icon {
  flex: none;
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 18%, var(--raised));
  color: var(--accent-text);
}
.remind-icon svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.remind-text { flex: 1 1 auto; min-width: 0; margin: 0; line-height: 1.35; overflow-wrap: anywhere; }
.remind-lead { color: var(--accent-text); font-weight: 700; }
.remind-go { flex: none; min-height: 48px; padding: 0 18px 0 14px; }
.remind-go svg { width: 18px; height: 18px; fill: currentColor; }
.remind-go.no-icon { padding: 0 18px; }
.remind-go.no-icon svg { display: none; }
.remind-close {
  flex: none;
  width: 48px;
  height: 48px;
  padding: 0;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: var(--radius);
  background: none;
  color: var(--muted);
  cursor: pointer;
}
.remind-close svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }
.remind-close:active { background: var(--hover); color: var(--text); }
.remind-close:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }
@media (hover: hover) {
  .remind-close:hover { background: var(--hover); color: var(--text); }
}
/* Una conferma o un errore (senza campanella). */
.remind.is-note { min-height: 56px; padding-left: 18px; border-color: var(--border); }
.remind.is-note .remind-icon { display: none; }
.remind.is-error { border-color: var(--danger); }
.remind.is-error .remind-text { color: var(--danger-text); }
body.has-mini > .remind, body.has-remote-bar > .remind { bottom: calc(100px + var(--safe-bottom)); }
#notice:not([hidden]) ~ .remind { bottom: calc(80px + var(--safe-bottom)); }
body:is(.has-mini, .has-remote-bar) > #notice:not([hidden]) ~ .remind { bottom: calc(164px + var(--safe-bottom)); }
.remind.in-stage { top: calc(max(16px, var(--safe-top)) + 76px); bottom: auto; font-size: 17px; }
@keyframes remind-in-top { from { opacity: 0; transform: translate(-50%, -12px); } }
.remind.in-stage:not([hidden]) { animation-name: remind-in-top; }
/* Nel player: nella riga della X, a sinistra (come «Dal telefono: …»): non
   copre il titolo né i comandi. */
.remind.in-player {
  top: max(16px, var(--safe-top));
  bottom: auto;
  font-size: 17px;
  left: max(24px, var(--safe-left));
  transform: none;
  max-width: calc(100% - max(24px, var(--safe-left)) - max(16px, var(--safe-right)) - 88px);
}
@keyframes remind-in-player { from { opacity: 0; transform: translateY(-12px); } }
.remind.in-player:not([hidden]) { animation-name: remind-in-player; }
/* Con lo stato della modalità guida («Guida attiva · 60 km/h», «GPS non
   disponibile») o «Passeggero · cambia» nella riga della X: sotto di loro,
   come gli avvisi brevi, non sopra. Lo stato della guida, finché c'è
   l'avviso, sale in cima alla riga (14 px) e il titolo col solo audio sta su
   una riga: a 773×575 l'avviso finisce 4 px sopra il titolo. */
.player:has(#player-guida:not([hidden])) .remind.in-player { top: calc(max(16px, var(--safe-top)) + 44px); }
.player:has(#player-who:not([hidden])) .remind.in-player { top: calc(max(16px, var(--safe-top)) + 58px); }
@media (min-width: 561px) {
  .player:has(.remind.in-player:not([hidden])) .player-top .player-guida { align-self: flex-start; }
}
.player.is-audio-only:has(.remind.in-player:not([hidden])) .now-title {
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Con l'avviso sopra, gli avvisi brevi del player e dell'ascolto scendono (non si coprono). */
.player-frame:has(> .remind:not([hidden])) .player-toast { top: 150px; }
.listen-screen:has(> .remind:not([hidden])) .ls-toast { top: 190px; }
/* Telefono: nella riga della X resterebbero 260 px (il testo a capo a metà
   parola, alto 200) e c'è lo stato della guida. A tutta larghezza, sotto le
   righe in alto (la X col solo audio, o lo stato della guida e «Passeggero»
   col video), come nella pagina; gli avvisi brevi sotto di lui. */
@media (max-width: 560px) {
  #player #player-frame > .remind.in-player {
    top: calc(max(12px, var(--safe-top)) + 112px);
    left: 50%;
    transform: translateX(-50%);
    max-width: calc(100vw - 24px - var(--safe-left) - var(--safe-right));
  }
  .remind.in-player:not([hidden]) { animation-name: remind-in-top; }
  .player #player-frame:has(> .remind:not([hidden])) .player-toast { top: calc(max(12px, var(--safe-top)) + 276px); }
}
@media (max-width: 480px) {
  .remind { gap: 8px; padding-left: 14px; }
  .remind-icon { display: none; }
  .remind-go { padding: 0 14px 0 12px; }
  body.has-mini > .remind, body.has-remote-bar > .remind { bottom: calc(80px + var(--safe-bottom)); }
}
@media (prefers-reduced-motion: reduce) {
  .remind:not([hidden]) { animation: none; }
}

/* --- «Rai 3 TGR» nel gruppo Rai (vedi TGR in app.js) ------------------------- */
/* L'immagine del TGR è una foto 16:9 (non un logo su trasparente): riempie il
   riquadro del logo, ingrandita sulla scritta «TGR», nella scheda, nel
   riquadro del gruppo chiuso e in cima al foglio. Finché non arriva (o se non
   arriva) la scritta, sul blu dei loghi. */
.tv-card.is-photo .tv-logo img,
.tgr-logo img {
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  object-fit: cover;
  transform: scale(1.6);
  transform-origin: 36% 50%;
}
.tgr-card .tv-mark, .tgr-logo .tv-mark { letter-spacing: .03em; }
/* Niente stella (non è un canale in diretta): «Riproduci su…», quando c'è,
   in alto a destra al suo posto. */
.tv-card.tgr-card .tv-head { padding-right: 0; }
:root[data-remote] .tv-card.tgr-card .tv-head { padding-right: 28px; }
.tv-card.tgr-card .cast-btn.on-card { top: 4px; right: 4px; }
@container (min-width: 230px) and (max-width: 379px) {
  :root[data-remote] .tv-card.tgr-card .tv-now { padding-right: 0; }
}
@container (max-width: 229px) {
  .tv-card.tgr-card .tv-head { padding-right: 0; }
  :root[data-remote] .tv-card.tgr-card .tv-head { padding-right: 38px; }
}
/* La riga in fondo: la regione a sinistra, «Edizioni» a destra (come «Poi:» e «Palinsesto»). */
.tgr-where:empty { display: none; }

/* Il foglio delle edizioni: come i promemoria, alto quanto serve (sul
   telefono a tutto schermo, come il palinsesto). Sotto la testa una riga con
   cosa c'è e «Cambia regione»; le regioni come quelle delle radio locali; le
   edizioni in righe come quelle di On demand, una per riga. */
@media (min-width: 481px) {
  .tgr-sheet { height: fit-content; max-height: calc(100dvh - 24px - var(--safe-top) - var(--safe-bottom)); }
  .tgr-sheet .guide-box { height: auto; max-height: inherit; }
}
.tgr-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  padding: 0 16px 12px;
  border-bottom: 1px solid var(--border);
}
.tgr-bar-text { flex: 1 1 16em; margin: 0; color: var(--muted); font-size: var(--fs-meta); line-height: 1.35; }
.tgr-bar .btn { flex: none; margin-left: auto; }
.tgr-bar[hidden] + .tgr-scroll { border-top: 1px solid var(--border); }
.tgr-region-pick { margin: 4px 6px 14px; }
.tgr-region-pick .radio-region-text { margin-bottom: 10px; }
/* Le due redazioni della regione delle radio locali (Trento e Alto Adige): bordate d'accento. */
.radio-region-chips .chip.is-suggested:not([aria-pressed="true"]) { border-color: var(--accent-strong); color: var(--accent-text); }
.tgr-list { grid-template-columns: minmax(0, 1fr); gap: 8px; }
@media (max-width: 480px) {
  .tgr-bar { padding: 0 12px 10px; }
  .tgr-bar-text { display: none; } /* sul telefono la riga è solo «Cambia regione»: la testa dice già la regione */
  .tgr-region-pick { margin: 4px 4px 12px; }
}

/* --- ricerca vocale --------------------------------------------------------- */
/* Il microfono nella barra in alto: come il tema, 44 × 44, il segno a tratto.
   Sugli schermi del guidatore e dell'ascolto un pulsante tondo nei colori
   del contesto, 64 px come «Riduci» e la X: lo si trova senza
   cercarlo. Nel player solo con lo schermo del guidatore (solo audio, o il
   video nascosto dalla guida): sopra un video non serve. */
.top-voice { min-height: 44px; min-width: 44px; padding: 0 10px; }
.top-voice svg, .stage-voice svg, .voice-orb svg, .voice-again svg {
  flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
.top-voice svg { width: 22px; height: 22px; }
.stage-voice { --size: 64px; --ctl-bg: var(--surface-2); --ctl-line: var(--border); --ctl-hover: var(--border); --ctl-press: var(--surface); color: var(--text); }
#listen-screen.has-ambience .stage-voice { --ctl-bg: var(--radio-voice, #94baff); --ctl-line: transparent; --ctl-hover: var(--radio-ink); --ctl-press: var(--radio-muted); color: var(--radio-background); }
.stage-voice svg { width: 44%; height: 44%; stroke-width: 2.2; }
.player-top .stage-voice { --size: 60px; margin-left: 0; }
.player:not(.is-audio-only) .stage-voice { display: none; }
.stage-voice:focus-visible { outline: 3px solid var(--on-stage); outline-offset: 3px; }

/* Il foglio: più largo di «Chi guarda?» (le proposte sono schede, tre per
   riga nell'auto), al centro, alto quanto serve e mai più dello schermo. */
.voice { width: min(720px, calc(100vw - 24px - var(--safe-left) - var(--safe-right))); }
.voice-box { display: grid; gap: 16px; }
.voice .who-head h2 { font-size: var(--fs-title); }

/* «Ti ascolto…»: il microfono grande col livello attorno (un anello che
   cresce con la voce), la frase e il tempo, «Fine» e «Annulla». */
.voice-listen { display: grid; justify-items: center; gap: 10px; padding: 0; text-align: center; }
.voice-orb {
  --level: 0;
  position: relative;
  width: 108px;
  height: 108px;
  margin-block: 16px; /* l'anello del livello cresce fin qui, senza toccare il titolo e la frase */
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--accent-strong);
  color: var(--on-accent);
  cursor: pointer;
  box-shadow: 0 6px 18px color-mix(in srgb, var(--accent-strong) 35%, transparent);
}
.voice-orb svg { position: relative; width: 46px; height: 46px; stroke-width: 2.1; }
.voice-level {
  position: absolute;
  inset: -8px;
  border-radius: 50%;
  border: 3px solid var(--accent);
  opacity: calc(.25 + var(--level) * .75);
  transform: scale(calc(.92 + var(--level) * .24));
  transition: transform 80ms linear, opacity 80ms linear;
}
.voice-orb:focus-visible { outline: 3px solid var(--accent); outline-offset: 16px; }
.voice-orb:active:not(:disabled) { background: var(--accent-hover); }
.voice-orb:disabled { cursor: default; }
/* Dopo «Fine»: l'anello gira finché non arriva la risposta. */
.voice[data-state="working"] .voice-level {
  transform: none;
  opacity: 1;
  border-color: color-mix(in srgb, var(--accent) 25%, transparent);
  border-top-color: var(--accent);
  animation: voice-spin .9s linear infinite;
}
@keyframes voice-spin { to { rotate: 1turn; } }
/* «Ci penso…» (il secondo livello): niente che gira; l'anello pieno respira
   piano (solo l'opacità: la fa il compositore, anche sull'auto) e sotto la
   frase capita. */
.voice[data-state="thinking"] .voice-level {
  transform: none;
  opacity: .9;
  animation: voice-breathe 1.4s ease-in-out infinite alternate;
}
@keyframes voice-breathe { from { opacity: .25; } to { opacity: .95; } }
.voice[data-state="thinking"] .voice-time { color: var(--text); font-size: var(--fs-ui); font-weight: 600; overflow-wrap: anywhere; }
.voice-listen-text { display: grid; gap: 2px; }
.voice-state { margin: 0; font-size: var(--fs-title); font-weight: 650; }
.voice-time { margin: 0; min-height: 1.4em; color: var(--muted); font-size: var(--fs-meta); font-variant-numeric: tabular-nums; }
.voice-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; }
.voice-actions .btn { min-width: 120px; }
/* Con la risposta (o senza microfono) il microfono grande lascia il posto:
   la frase resta per i lettori di schermo. */
.voice:is([data-state="result"], [data-state="nomic"]) :is(.voice-orb, .voice-time, .voice-actions) { display: none; }
.voice[data-state="result"] .voice-listen { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); padding: 0; }
.voice[data-state="nomic"] .voice-listen { justify-items: start; text-align: start; padding: 0; }
/* Di nuovo in ascolto per la domanda: in alto, su una riga, il microfono
   piccolo, «Ti ascolto…», «Fine» e «Annulla»; sotto restano la domanda e le
   sue risposte (o i pulsanti grandi), da toccare invece di dire. */
.voice[data-reply] .voice-listen { grid-template-columns: auto minmax(0, 1fr) auto; justify-items: start; align-items: center; column-gap: 16px; text-align: start; }
.voice[data-reply] .voice-orb { width: 64px; height: 64px; margin-block: 8px; }
.voice[data-reply] .voice-orb svg { width: 30px; height: 30px; }
.voice[data-reply] .voice-orb:focus-visible { outline-offset: 12px; }
.voice[data-reply] .voice-actions .btn { min-width: 96px; }
@media (max-width: 480px) {
  .voice[data-reply] .voice-listen { grid-template-columns: auto minmax(0, 1fr); row-gap: 6px; }
  .voice[data-reply] .voice-actions { grid-column: 1 / -1; justify-self: stretch; }
  .voice[data-reply] .voice-actions .btn { flex: 1; }
}
.voice-nomic { margin: -6px 0 0; color: var(--muted); max-width: 60ch; }

.voice-result { display: grid; gap: 6px; }
.voice-heard { margin: 0; font-size: var(--fs-lead); font-weight: 650; overflow-wrap: anywhere; }
.voice-say { margin: 0; color: var(--muted); }
.voice-say:empty { display: none; }
.voice-items { display: grid; gap: 18px; margin-top: 10px; }
.voice-items:empty { display: none; }
.voice-group { display: grid; gap: 10px; }
.voice-group-title { margin: 0; font-size: var(--fs-subhead); font-weight: 650; }
/* Le schede delle proposte: le stesse degli elenchi, un po' più strette (tre
   canali per riga nell'auto, due a metà schermo, una sul telefono). */
.voice .voice-list { --card-min: 200px; margin: 0; }
.voice .voice-list.radio-gr-list { display: grid; gap: 8px; padding: 0; list-style: none; }
.voice-hints { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.voice-hint { flex: 0 1 auto; white-space: normal; text-align: start; line-height: 1.3; padding: 8px 14px; }
/* La domanda del server, più forte della frase sopra, e le sue risposte
   (piene d'accento per distinguerle dagli esempi: valgono come dette). */
.voice-question { margin: 8px 0 0; font-size: var(--fs-lead); font-weight: 650; color: var(--text); overflow-wrap: anywhere; }
.voice-replies { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }
.voice-reply {
  flex: 0 1 auto;
  min-height: 48px;
  padding: 8px 18px;
  border-color: var(--accent-strong);
  background: var(--accent-strong);
  color: var(--on-accent);
  white-space: normal;
  text-align: start;
  line-height: 1.3;
  font-weight: 650;
}
.voice-reply:active { background: var(--accent-hover); }
@media (hover: hover) {
  .voice-reply:hover { background: var(--accent-hover); color: var(--on-accent); }
}
/* «Avvisami» su un programma che deve ancora iniziare: la riga in fondo alla
   scheda, come «Palinsesto»; messo, la campanella piena. */
.voice-remind .tv-guide-label svg { width: 20px; height: 20px; }
.voice-remind[aria-pressed="true"] .tv-guide-label svg { fill: currentColor; }
.voice-remind.is-pending { opacity: .7; }
.voice-prog .tv-now .tv-label { color: var(--accent-text); }

/* In movimento (modalità guida): tre pulsanti grandi, il nome e una riga. */
.voice-bigs { display: grid; gap: 10px; margin: 0; padding: 0; list-style: none; }
.voice-big {
  width: 100%;
  min-height: 80px;
  padding: 12px 18px;
  display: grid;
  align-content: center;
  gap: 2px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--raised);
  color: var(--text);
  font: inherit;
  text-align: start;
  cursor: pointer;
  transition: transform .12s, background .12s;
}
.voice-big:active { transform: scale(.98); background: var(--hover); }
.voice-big:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.voice-big-name { font-size: var(--fs-title); font-weight: 650; overflow-wrap: anywhere; }
.voice-big-sub { color: var(--muted); font-size: var(--fs-ui); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.voice-big-sub:empty { display: none; }
/* Un programma da avvisare: a destra, la campanella e «Avvisami» (piena,
   messo); alto come gli altri, «Parla di nuovo» resta in vista nell'auto. */
.voice-big[data-remind] { grid-template-columns: minmax(0, 1fr) auto; column-gap: 16px; }
.voice-big[data-remind] > :not(.voice-big-act) { grid-column: 1; }
.voice-big-act { grid-column: 2; grid-row: 1 / span 2; align-self: center; display: inline-flex; align-items: center; gap: 8px; color: var(--accent-text); font-size: var(--fs-ui); font-weight: 650; white-space: nowrap; }
.voice-big-act svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.voice-big[aria-pressed="true"] .voice-big-act svg { fill: currentColor; }
/* L'ora del programma non si taglia mai; sul telefono «Avvisami» va sotto. */
.voice-big[data-remind] .voice-big-sub { white-space: normal; }
@media (max-width: 480px) {
  .voice-big[data-remind] { grid-template-columns: minmax(0, 1fr); }
  .voice-big-act { grid-column: 1; grid-row: auto; margin-top: 4px; }
}
@media (hover: hover) {
  .voice-big:hover { background: var(--hover); }
}

/* «oppure scrivi»: il campo e «Cerca» su una riga. */
.voice-form { display: grid; gap: 6px; padding-top: 14px; border-top: 1px solid var(--border); }
.voice-or { color: var(--muted); font-size: var(--fs-meta); }
.voice-row { display: flex; gap: 8px; }
.voice-row input { min-width: 0; flex: 1; }
.voice-row .btn { flex: none; }
.voice-again { justify-self: start; }
.voice-again svg { width: 20px; height: 20px; }

/* «Avvio Rai 1 · Annulla»: in basso al centro, sopra lo schermo che si è
   aperto (dentro il player o l'ascolto), sempre scuro. */
.voice-toast {
  position: fixed;
  left: 50%;
  bottom: calc(24px + var(--safe-bottom));
  z-index: 7;
  transform: translateX(-50%);
  width: max-content;
  max-width: min(560px, calc(100vw - 24px - var(--safe-left) - var(--safe-right)));
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 8px 8px 8px 18px;
  min-height: 56px;
  border: 1px solid var(--stage-line);
  border-radius: var(--radius);
  background: var(--stage-toast);
  color: var(--on-stage);
  box-shadow: var(--shadow-pop);
  font-size: var(--fs-stage-meta);
  font-weight: 600;
}
/* Sopra gli schermi del player e dell'ascolto: in alto, sotto la riga della X
   (in basso coprirebbe i comandi). */
:is(.player-frame, .ls-frame) > .voice-toast { top: calc(96px + var(--safe-top)); bottom: auto; }
.voice-toast-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.voice-toast-undo {
  flex: none;
  min-height: 44px;
  padding: 0 16px;
  border: 0;
  border-radius: var(--radius-s);
  background: var(--accent-strong);
  color: var(--on-accent);
  font: inherit;
  cursor: pointer;
}
.voice-toast-undo:focus-visible { outline: 3px solid var(--on-stage); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
  .voice-level { transition: none; }
  .voice[data-state="working"] .voice-level { animation-duration: 3s; }
  .voice[data-state="thinking"] .voice-level { animation: none; }
}
@media (max-width: 480px) {
  .voice-box { gap: 14px; padding: 16px; }
  .voice-orb { width: 96px; height: 96px; }
  .voice .voice-list { --card-min: 100%; }
  /* Microfono e chiusura a sinistra; lo stato della guida può andare a capo
     dentro di sé senza spostare i pulsanti sulla riga degli avvisi. */
  .player.is-audio-only .player-top { flex-wrap: nowrap; }
  .player.is-audio-only .player-top .stage-voice { order: -1; }
  .player.is-audio-only .player-top .player-guida { flex: 0 1 auto; min-width: 0; white-space: normal; line-height: 1.2; }
  /* I comandi restano a sinistra; il nome occupa al massimo due righe. */
  .ls-top:has(> .stage-voice) { gap: 12px; }
  .ls-top:has(> .stage-voice) > .ls-min { margin-inline-end: 0; }
  .ls-top > .ls-heading { flex-direction: column; align-items: flex-end; gap: 6px; }
  .ls-top > .ls-heading .ls-kind { flex: none; width: 100%; }
  .ls-top:has(> .stage-voice) > .ls-heading .ls-kind {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    line-height: 1.2;
  }
}
