/* ============================================================
   ESTATE 2027 — Registro di rotta
   IL SISTEMA DI MACROFACTOR.

   Rifatta il 3/9/2026 su mandato esplicito: l'estetica diventa quella di
   MacroFactor (iOS), «identica in ogni singolo dettaglio», su TUTTA l'app e non
   solo sulla nutrizione. Il sistema "Gentler" e' REVOCATO, come lo era stato il
   quadro di bordo su carta prima di lui. Chi rimette #F2F2F7, i colori di
   famiglia come stato, i raggi da 22, i gradienti o gli aloni sta tornando a un
   sistema sostituito, non correggendo un errore.

   🔴 OGNI NUMERO QUI DENTRO E' MISURATO su 335 schermate, e sta in
   RIFERIMENTO-MACROFACTOR.md con la schermata da cui viene. Non si aggiunge un
   valore che non sia passato di la'. Il vocabolario nudo, senza l'app attorno,
   sta in kit.css e si guarda in kit.html.

   L'idea, in una frase: la pagina e' un FOGLIO GRIGIO NEUTRO su cui poggiano
   TESSERE BIANCHE, e il colore e' un DATO, mai uno stato.

   1. Due superfici sole: la pagina (#F6F6F6, grigio neutro, non azzurrato) e la
      tessera (#FFFFFF). Nessun bordo: la separazione la fa il contrasto.
      L'ombra e' una riga sola (#F5F5F5) e sul grigio non si vede quasi.
   2. 🔴 NON ESISTE UN ACCENTO PRIMARIO. Selezione, segmento attivo, interruttore
      acceso, azione primaria e collegamento sono tutti NERI. Il colore compare
      solo dove disegna una misura: una barra, un tratto, un punto.
   3. Le misure sono la cosa piu' grande della pagina, e il gradino massimo del
      riferimento e' 36 pt: non esiste testo piu' grande di cosi'.
   4. I raggi non sono uno: 12 la tessera e la riga di alimento, 8 il riquadro e
      il bottone e il campo, 6 la pastiglia del segmento, 16 il foglio (solo in
      alto) e il dialogo (quattro angoli), capsula le pillole.
   5. Due luci, misurate a COPPIE e non a campione: sei schermate scure vere e le
      loro gemelle chiare. #363636 non esiste: era il velo delle modali.
   6. Zero emoji, zero gradienti, zero aloni. I segni restano tipografici.
   7. Solo `transform` e `opacity` in movimento, `prefers-reduced-motion`
      rispettato, e l'ingresso a scalare solo al cambio vista.

   I NOMI DEI TOKEN NON CAMBIANO. `--testo`, `--carta`, `--filo`, `--palestra`,
   `--t-peso`, `Grotesk`, `Inciso`… vivono dentro gli attributi `style` e negli
   SVG di app.js: cambiarli qui significa rompere trentacinque punti la' dentro
   senza che nessun test se ne accorga. Cambiano i VALORI e i componenti.
   ============================================================ */

/* ---------- Il carattere ----------
   Misurato alla fonte: il testo di lettura di MacroFactor E' DM Sans (la g a
   doppia pancia da' 0,875 contro lo 0,533 della g di SF Pro). I titoli grandi
   NON lo sono — sovrapposizione 0,44-0,66 contro un controllo positivo a
   0,957-1,000, glifi x1,39 piu' LARGHI e non piu' stretti, e lo zero barrato di
   «JUNE 30» che DM Sans non ha — ma quella faccia display non e' stata
   identificata, quindi qui girano tutti su DM Sans e si ancorano all'ALTEZZA
   DELLE MAIUSCOLE misurata: cap/em 0,700, letto dal file. */
@font-face { font-family: 'DM Sans'; src: url('fonts/dm-var.woff2') format('woff2'); font-weight: 100 1000; font-display: swap; unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: 'DM Sans'; src: url('fonts/dm-var-ext.woff2') format('woff2'); font-weight: 100 1000; font-display: swap; unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
/* Gli alias 'Grotesk' e 'Inciso' restano perche' app.js li nomina dentro gli SVG
   (`font-family="Grotesk"`): puntano tutti e due a DM Sans, che nel riferimento
   e' il carattere unico del testo di lettura. */
@font-face { font-family: 'Grotesk'; src: url('fonts/dm-var.woff2') format('woff2'); font-weight: 100 1000; font-display: swap; }
@font-face { font-family: 'Inciso'; src: url('fonts/dm-var.woff2') format('woff2'); font-weight: 100 1000; font-display: swap; }

:root {
  /* ---- IL CAMMINO ----
     Lo scrive il JS a ogni render: giorni percorsi / 274. Comanda una cosa
     sola, la tinta dell'alone in cima. */
  --cammino: 0.16;

  /* ---- I COLORI-DATO ----
     🔴 Non sono piu' "colori di famiglia": nel sistema di MacroFactor il colore
     e' un DATO, non un dominio. Ogni stato attivo — selezione, segmento, tasto
     acceso, azione primaria, collegamento — e' NERO, misurato su 335 schermate.
     Questi cinque restano solo dove disegnano una misura: una barra, un tratto
     di grafico, un punto. I valori sono quelli misurati sul riferimento, e la
     corrispondenza segue il mestiere, non l'abitudine:
       palestra  = il blu delle calorie          rotta = il corallo delle proteine
       piatto = il verde dei carboidrati      piano = l'ambra dei grassi
       peso   = il viola della linea di tendenza del peso, che e' il nostro dominio */
  --palestra:  #5B95FA;
  --piatto: #4DB179;
  --peso:   #8F80DD;
  --rotta:  #FF8760;
  --piano:  #FFC446;
  --danger: #CC2F3B;   /* il rosso del cestino di scorrimento, misurato su 121 */
  --warn:   #FFC446;
  --ok:     #4DB179;

  /* Le stesse tinte in luce scura, misurate a coppie sulle sei schermate scure
     vere. Non sono schiarimenti a occhio: sono letture. */
  --palestra-viva:  #669EF9;
  --piatto-viva: #5CBB86;
  --peso-viva:   #A79AE6;
  --rotta-viva:  #FF8760;   /* di notte pieno e tinta tenue collassano: misurato */
  --piano-viva:  #FED15F;
  --danger-viva: #E4526A;

  /* ---- LE SUPERFICI TENUI ----
     I gradienti sono revocati con il sistema che li conteneva: su 335 schermate
     di MacroFactor non ce n'e' uno. Al loro posto la tinta TENUE misurata, che
     e' il colore diluito nel bianco e porta l'inchiostro scuro sopra. I nomi
     restano `--g-*` perche' app.js li nomina in undici punti. */
  --g-piatto: #9FD9B8;
  --g-palestra:  #AAC7FF;
  --g-rotta:  #FFB59E;
  --g-piano:  #FFDF98;
  --g-danger: #FFDAD0;
  --g-peso:   #ECDDFF;

  /* ---- Scala tipografica ----
     Ogni gradino e' l'altezza delle maiuscole misurata su MacroFactor, divisa
     per il cap/em di DM Sans (0,700, letto dal file e non stimato). Chi ne
     aggiunge uno nono cablato dentro uno `style=""` riporta la nuvola di prima. */
  --t-rom: 36px;   /* la misura piu' grande che esista nel riferimento */
  --t-xl: 30px;    /* il titolo di schermata: cap 21,0 pt */
  --t-t1: 28px;    /* la misura secondaria */
  --t-t2: 22px;    /* il numero di riga */
  --t-t3: 20px;    /* il titolo di sezione */
  --t-lg: 18px;    /* il titolo di tessera, e il bottone */
  --t-md: 16px;    /* la prosa */
  --t-rg: 16px;    /* la voce di lista */
  --t-sm: 14px;    /* etichetta, didascalia, nome di alimento */
  --t-xs: 14px;    /* 🔴 nel riferimento NON esiste testo di contenuto sotto i
                      14 pt: gli 11 pt sono solo l'etichetta della barra delle
                      schede. Un gradino piu' piccolo qui riporta la nostra
                      scala a partire da 6-7 pt, che e' lo scarto piu' grosso
                      che il banco della Fase 1 ha misurato. */
  --t-lbl-xs: 14px;   /* nel riferimento non esiste contenuto sotto i 14 pt */
  --t-nav: 11px;      /* l'etichetta della barra delle schede, e nient'altro */
  --t-lbl: 14px;
  --t-lbl-md: 14px;
  --t-lbl-lg: 14px;

  /* ---- Spazio ---- */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px;
  --gut: 16px;      /* margine di pagina: 16 e' il default delle tre famiglie */
  --gap: 16px;      /* respiro fra le tessere */

  /* ---- Raggi: uno per tipo, misurato ---- */
  --r-card: 12px;   /* la tessera grande, e la riga di alimento */
  --r-tile: 12px;
  --r-box: 8px;     /* il riquadro dentro una tessera, il bottone, il campo */
  --r-chip: 8px;
  --r-seg: 6px;     /* la pastiglia dentro la traccia del segmento */
  --r-foglio: 16px; /* il foglio che sale dal basso, solo in alto */
  --r-pill: 999px;

  /* ---- Movimento ---- */
  --ease: cubic-bezier(0.32, 0.72, 0.24, 1);
  --spring: cubic-bezier(0.34, 1.42, 0.56, 1);

  /* La barra delle schede di MacroFactor non galleggia e non ha pillola: e'
     una barra piena alta 56, appoggiata al fondo, con 34 di area sicura sotto.
     Misurata: 90 pt in tutto. */
  --nav-gap: 0px;
  --nav-pill: 56px;
  --nav-h: calc(var(--nav-pill) + env(safe-area-inset-bottom, 34px));
  --sans: 'DM Sans', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --grot: 'DM Sans', -apple-system, system-ui, sans-serif;
  --inciso: 'DM Sans', -apple-system, system-ui, sans-serif;
  --serif: 'DM Sans', -apple-system, system-ui, sans-serif;
  /* I segni del registro (⚓︎ ✦ ✪ ▲ ≡ ⚖︎ ☀︎) non stanno nella famiglia nuova:
     hanno la loro pila, e restano quelli di sempre. */
  --segni: 'Apple Symbols', 'Segoe UI Symbol', 'Noto Sans Symbols 2', system-ui, sans-serif;

  /* ---------- Gli alias del kit ----------
     `componenti.css` e' scritto sui nomi `--mf-*` perche' vive anche nella
     pagina del kit, dove l'app non c'e'. Qui si mappano sui token dell'app, e
     cosi' i tre componenti condivisi esistono in un posto solo: due copie che
     divergono sono il modo tipico in cui un sistema di design smette di essere
     un sistema. */
  --mf-font: var(--sans);
  --mf-testo: var(--testo);
  --mf-testo-2: var(--testo-2);
  --mf-testo-3: var(--testo-3);
  --mf-testo-4: var(--testo-4);
  --mf-tessera: var(--carta);
  --mf-pastiglia: var(--pastiglia);
  --mf-riempimento: var(--bordo);
  --mf-grot: var(--grot);
  --mf-traccia: var(--carta-2);
  --mf-traccia-macro: var(--traccia-fondo);
  --mf-calorie: var(--palestra);
  --mf-calorie-tenue: var(--g-palestra);
  --mf-ease: var(--ease);
}

/* ============================================================
   LE DUE LUCI
   Stessa struttura, versi invertiti. Di giorno il foglio è grigio e le tessere
   sono bianche; di notte il foglio è quasi nero e le tessere sono carbone.
   I gradini di grigio sono MISURATI, non scelti a occhio: `--testo-2` sta a
   5,20 sul bianco perché lì sotto ci vive la prosa secondaria, che è testo
   piccolo e deve stare sopra 4,5. Il grigio che l'app vera usa lì (#8E8E93)
   dà 3,25 e non passa: è l'unico punto in cui la copia si ferma.
   ============================================================ */
html[data-luce='chiara'] {
  /* Tutti valori MISURATI sul riferimento, non scelti a occhio. La pagina non e'
     una sola: grigia sulle viste a tessere, bianca sui moduli e sui fogli. */
  --fondo: #F6F6F6;
  --fondo-modulo: #FFFFFF;
  --carta: #FFFFFF;
  --carta-2: #F6F6F6;            /* il riquadro dentro la tessera */
  --medaglia: #F6F6F6;           /* la casella spenta */
  --medaglia-got: #FFFFFF;       /* quella conquistata: si ALZA, non cambia tinta */
  --testo: #000000;
  --testo-2: #666666;            /* l'inchiostro delle liste */
  /* 🔴 Qui la copia si ferma, e per un motivo misurato. Il grigio delle
     didascalie di MacroFactor e' #767676, che sul BIANCO da' 4,54 e passa: loro
     lo usano sulle tessere. Sulla pagina grigia #F6F6F6 lo stesso grigio da'
     4,20 e non passa, e la nostra app di testo sulla pagina ne ha molto piu' di
     loro. Quindi qui vive #666666, che e' l'altro grigio misurato del
     riferimento (l'inchiostro delle liste) e sulla pagina da' 5,31.
     Non e' un colore inventato per far passare un test: e' quello giusto dei
     due, usato nel posto giusto. */
  --testo-3: #666666;            /* didascalie ed etichette */
  --testo-3-tessera: #767676;    /* il valore del riferimento, dove il fondo e' bianco */
  --testo-4: #A8A8A8;            /* le freccette */
  --bordo:  #E9E9E9;
  --filo:   #E9E9E9;             /* 2 px @3x = 0,67 pt, e rientra da sinistra */
  --filo-2: #EFEFEF;
  --traccia-fondo: #EFEFEF;      /* la pista sotto una barra dei macro */
  --pastiglia: #E9E9E9;
  --avviso: #FFDAD0;             /* il riquadro d'avviso, misurato */
  /* 🔴 LA SUPERFICIE TENUE NON CAMBIA CON LA LUCE, e qui sta la ragione.
     `.alertbox` e `.session-note` prendono l'inchiostro NERO da una regola piu'
     su, perche' sono «il colore diluito nel bianco». Di notte pero' `--avviso`
     diventa #4A2A22, e nero su quel marrone misura 1,65:1 — illeggibile. Il
     caso peggiore e' proprio quello che serve: «in sala adesso e' il picco»
     compare la sera, quando la luce e' gia' girata.
     Non si schiarisce `--avviso`, che tre altre superfici usano con inchiostro
     CHIARO e a 12,76:1; e non si toglie la regola dell'inchiostro nero, che le
     varianti .warn, .ok e .danger prendono da li'. Si separa la superficie. */
  --avviso-tenue: #FFDAD0;
  /* 🔴 L'azione primaria e' NERA. Non esiste un accento primario di sistema:
     selezione, segmento attivo, interruttore acceso e collegamento sono tutti
     #000000, misurati su 335 schermate. E' il fatto di progetto piu' importante
     di tutta la specifica, ed e' l'opposto di quello che faceva il sistema di
     prima, che colorava d'arancione ogni stato. */
  --pieno: #000000;
  --su-pieno: #FFFFFF;
  --su-figura: #000000;
  /* L'ombra e' una riga sola, e sul grigio non si vede quasi: e' il punto.
     La profondita' la fa il bianco contro il grigio, mai un filo. */
  --ombra: 0 1px 0 #F5F5F5;
  --ombra-alta: 0 1px 0 #F5F5F5;
  /* Il colore-segnale DENTRO il testo resta una scala a parte: le tinte del
     dato sono troppo chiare per portare parole. Verificate da contrasto.js. */
  --t-warn:   #8A5600;
  --t-danger: #A81D33;
  --t-ok:     #0C6E4A;
  --t-peso:   #4A3E8F;
  --t-palestra:  #26509E;
  --t-piatto: #0C6E4A;
  --t-rotta:  #A9350B;
  --t-piano:  #8A5600;
  --alone: 0;                    /* nel riferimento non esistono aloni */
  color-scheme: light;
}
html[data-luce='scura'] {
  /* Misurati a COPPIE sulle sei schermate scure vere (309-314) e sulle loro
     gemelle chiare. #363636 non c'e': era il velo delle modali contato come
     superficie, e per lo stesso motivo le schermate scure sono 6 e non 16. */
  --fondo: #141414;
  --fondo-modulo: #141414;
  --carta: #1F1F1F;
  --carta-2: #333333;
  --medaglia: #333333;
  --medaglia-got: #383838;
  --testo: #FFFFFF;
  --testo-2: #A5A5A5;
  --testo-3: #A5A5A5;
  --testo-4: #525252;
  --bordo:  #4B4B4B;
  --filo:   #4B4B4B;
  --filo-2: #333333;
  --traccia-fondo: #333333;
  --pastiglia: #333333;
  --avviso: #4A2A22;             /* la stessa tinta portata di notte */
  --pieno: #FFFFFF;
  --su-pieno: #000000;
  --su-figura: #FFFFFF;
  --ombra: none;
  --ombra-alta: none;
  --t-warn:   #FED15F;
  --t-danger: #FF8496;
  --t-ok:     #5CBB86;
  --t-peso:   #A79AE6;
  --t-palestra:  #669EF9;
  --t-piatto: #5CBB86;
  --t-rotta:  #FF8760;
  --t-piano:  #FED15F;
  --alone: 0;
  color-scheme: dark;
}

/* 🔴 Le superfici che INVERTONO il verso del contrasto, riscritte per il sistema
   nuovo. Nel sistema di prima erano le tessere SATURE; qui le tessere sature non
   esistono piu', e le uniche superfici che portano inchiostro chiaro sono quelle
   NERE, cioe' gli stati scelti e l'azione primaria. Chi rimette `.campo` o
   `.alertbox` in questo elenco si ritrova il bianco su una tinta tenue, che e'
   1,3:1 e non si legge: e' successo, e contrasto.js l'ha visto. */
.btn:not(.ghost):not(.subtle), .tl-item .now-tag, .seg7 button.sel,
.zona.on, .cenacard.sel, .setchip.pr {
  --t-warn: #FFDC8A; --t-danger: #FFC5CD; --t-ok: #B6F2D5; --t-peso: #DCD1FF;
  --t-palestra: #CBDDFF; --t-piatto: #B6F2D5; --t-rotta: #FFD2BE; --t-piano: #FFDC8A;
  --testo: var(--su-pieno); --testo-2: var(--su-pieno); --testo-3: var(--su-pieno);
  --filo: rgba(255, 255, 255, 0.22); --filo-2: rgba(255, 255, 255, 0.14);
  --traccia-fondo: rgba(255, 255, 255, 0.24);
}
/* Le superfici TENUE (avviso, nota, foglio, medaglia conquistata) portano invece
   l'inchiostro scuro, sempre: sono il colore diluito nel bianco, e nel
   riferimento il riquadro d'avviso #FFDAD0 ha il testo nero sopra. */
.sheet-in, #toast, .session-note:not(.plain), .alertbox:not(.plain), .guide-rest,
.rotta-nota, .streak-head .n {
  --testo: #000000; --testo-2: #3A3A3A; --testo-3: #4A4A4A;
  --filo: rgba(0, 0, 0, 0.12); --filo-2: rgba(0, 0, 0, 0.07);
  --traccia-fondo: rgba(0, 0, 0, 0.10);
}
/* 🔴 L'eccezione dell'ambra non serve piu', e va tolta invece che lasciata a
   dormire. Esisteva perche' il sistema di prima riempiva le tessere di ambra e
   il bianco sopra dava 1,7:1: la cura era un inchiostro bruno. Qui le tessere
   ambra non esistono, gli stati scelti sono neri col bianco sopra, e le
   superfici tenui portano gia' l'inchiostro scuro dal blocco qui sopra. Lasciata
   in piedi, questa regola tingeva di bruno la tessera del peso, che ormai e'
   bianca: misurato rgb(58,36,0) su rgb(255,255,255), cioe' un marrone su bianco
   dove doveva esserci il nero. */
.exrow.done .st, .setchip.pr {
  --su-figura: var(--su-pieno);
}

* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html {
  font-size: 16px; background: var(--fondo); max-width: 100%; overflow-x: hidden;
  /* iOS ingrandisce il testo da sé quando il telefono ruota: qui la scala è
     misurata, e una gonfiata di Safari la sfascia. */
  -webkit-text-size-adjust: 100%; text-size-adjust: 100%;
}
body {
  font-family: var(--sans);
  background: var(--fondo);
  color: var(--testo);
  font-size: var(--t-md);
  line-height: 1.45;
  letter-spacing: 0;
  min-height: 100dvh;
  max-width: 100%;
  overflow-x: hidden;
  overscroll-behavior-y: none;
  /* Il corpo fermo mentre uno strato copre lo schermo. `position: fixed` e non
     `overflow: hidden`: su iOS il secondo non basta, la pagina scorre lo
     stesso. Il `top` negativo lo mette il JS, ed e' quello che al rilascio
     riporta esattamente dov'era invece di sbattere in cima. */
  &.fermo { position: fixed; left: 0; right: 0; width: 100%; }
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  user-select: none;
  /* Il dito che resta premuto su un tasto apriva il menù di iOS ("Copia",
     "Condividi") sopra l'app: in palestra è il gesto che si fa per sbaglio. */
  -webkit-touch-callout: none;
}
input, textarea { user-select: text; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
/* `manipulation` su TUTTO, non solo sui bottoni: toglie il doppio tocco per
   ingrandire, che e' il modo in cui piu' spesso si finisce ingranditi senza
   volerlo — un tocco un po' lento su una riga di testo, e la pagina salta.
   Resta lo scorrimento, resta il tocco: sparisce solo l'ingrandimento. */
html, body, #app, button, a, input, label { touch-action: manipulation; }
/* Il testo non si ridimensiona da solo quando iOS gira lo schermo: senza,
   in orizzontale i corpi crescono e la gerarchia che abbiamo misurato salta. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

/* La misura. È la voce che l'app copiata usa per ogni numero: tondo, pesante,
   cifre di larghezza fissa perché un contatore che cambia non deve saltare. */
.num {
  font-family: var(--grot); font-weight: 800; letter-spacing: 0;
  font-variant-numeric: tabular-nums lining-nums; font-feature-settings: 'tnum' 1;
}
/* L'etichetta: maiuscoletto largo, grigio. */
.sect-t, .rule-cap { font-family: var(--inciso); }
.segno { font-family: var(--segni); }

/* L'ALONE. Nell'app vera la schermata dei passi ha una macchia radiale calda
   dietro il numero, ed è l'unico elemento non piatto di tutto il disegno.
   Qui è in cima alla pagina, e la sua tinta la comanda `--cammino`: fredda a
   ottobre, calda a giugno. Il vecchio reticolo nautico non è più qui: era il
   fondo di un altro sistema. */
/* 🔴 L'alone in cima alla pagina e' revocato: su 335 schermate di MacroFactor
   non c'e' un gradiente, non c'e' un alone, non c'e' una tinta di fondo che
   cambia con la stagione. La pagina e' #F6F6F6 e basta, dal primo pixel
   all'ultimo. `--cammino` resta perche' app.js lo scrive a ogni render, ma qui
   non comanda piu' niente. */
body::before { content: none; }
/* Resta come gancio: il reticolo è stato tolto da index.html, e qui non deve
   più disegnare niente. Ridarle un contenuto significa rimettere la carta. */
.filigrana { display: none; }

#app, nav, .compact-bar, .sheet, .guide, .runmode, #toast, .burst { position: relative; z-index: 1; }
/* `viewport-fit=cover` porta la pagina sotto il notch: in orizzontale, senza
   gli inset laterali, la prima colonna finisce dietro la tacca. Sono zero in
   verticale, quindi non costano niente dove non servono. */
#app {
  max-width: 470px; margin: 0 auto;
  padding: 0 calc(var(--gut) + env(safe-area-inset-right, 0px)) calc(var(--nav-h) + 34px) calc(var(--gut) + env(safe-area-inset-left, 0px));
}

/* ============================================================
   LA TESTATA
   ============================================================ */
.hdr { padding: calc(14px + env(safe-area-inset-top, 0px) * 0.5) 0 0; }
/* 🔴 Niente `overflow: hidden` qui. I tre bottoni della testata allargano il
   bersaglio con un `::after` che sborda di 7 px per arrivare a 48: questa riga
   lo tagliava a 34, e il bottone del tornello e' proprio quello che si preme
   col borsone in mano. Verificato che togliendolo non cambia nulla d'altro:
   larghezza del marchio, altezza della riga, chip e scrollWidth restano
   identici al pixel a 320, 375, 390 e 430. */
.hdr-top { display: flex; align-items: center; gap: var(--s2); min-height: 34px; }
.hdr-mark { display: flex; align-items: center; gap: 7px; min-width: 0; }
/* Il marchio in testata: nero come ogni altro segno del sistema. Il colore, qui
   dentro, e' un dato — e un marchio non e' un dato. */
/* 20 px, non 18: il kit del marchio fissa la soglia — «croce visibile da 20 px
   in su, sotto serve il favicon a quadrato pieno». A 18 la croce di Amalfi
   comincia a chiudersi e la rosa torna una stella qualunque, cioe' si perde
   proprio la cosa che rende quel marchio il suo. */
.hdr-mark svg { width: 20px; height: 20px; color: var(--testo); flex-shrink: 0; display: block; }
/* La croce di Amalfi e' RICAVATA: prende il colore del fondo, non un bianco
   fisso. Cosi' la regola d'inversione del marchio vale da sola — di giorno
   stella scura e croce chiara, di notte stella chiara e croce scura — senza due
   file e senza un secondo `fill` da tenere allineato a mano. */
/* 🔴 La croce di Amalfi del marchio prende il colore del FONDO, ed e' quello
   che la fa esistere: senza, i quattro petali restano dell'inchiostro della
   stella e il marchio torna a essere la rosa piena a otto punte, cioe' quella
   che NON e' la sua. La regola stava sotto `.hdr-mark`, quindi valeva solo in
   testata; la schermata d'accesso, che il marchio se lo copia da li' con
   `innerHTML`, lo mostrava senza croce. Sta in piedi da sola apposta: vale
   ovunque il marchio compaia, oggi la testata e l'accesso, domani altrove. */
.rdv-croce { fill: var(--fondo); }
.hdr-mark .k {
  font-family: var(--inciso); font-weight: 700; font-size: var(--t-lbl-xs);
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--testo-2); white-space: nowrap;
  /* Col terzo bottone la riga e' piena e il chip finiva SOPRA la scritta,
     tagliandola a «ESTATE 20». Fra le due cose che possono cedere, cede questa:
     un marchio non si legge a meta', mentre la rosa da sola resta il marchio.
     Sotto i 380 px la scritta esce di scena e torna appena c'e' spazio. */
  overflow: hidden; text-overflow: clip; min-width: 0;
}
/* La soglia e' 380, non 360: sull'iPhone SE (375) il rilevatore di testo
   tagliato di `iphone.js` ha segnalato «Estate 2027» clippato su tutte e cinque
   le viste, e aveva ragione. La mia prima misura diceva «intero» perche'
   confrontava la larghezza del box con quella voluta: con `overflow: hidden`
   il box resta largo e a tagliare e' il GENITORE. Il box non e' il testo.
   Sotto la soglia esce la scritta e resta la rosa, che e' il marchio vero. */
@media (max-width: 380px) { .hdr-mark .k { display: none; } }
.hdr-tools { display: flex; align-items: center; gap: 7px; margin-left: auto; flex-shrink: 0; }
/* La pillola della fase: grigio tenue, testo scuro, angoli tondi. Nell'app
   vera è la forma di ogni marca secondaria — i "Splits", i chip delle zone. */
.hdr-chip {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--carta); color: var(--testo-2);
  box-shadow: var(--ombra);
  padding: 6px 12px; border-radius: var(--r-pill);
  font-family: var(--inciso); font-weight: 700; font-size: var(--t-lbl-xs);
  letter-spacing: 0.03em; white-space: nowrap;
  --testo-2: inherit;
  /* Con tre bottoni accanto (tornello, musica, luce) la riga di testata e'
     piena: il chip cede lo spazio per primo, perche' e' l'unica cosa qui dentro
     che non si tocca. Prima di sparire si accorcia con i puntini, e su 393 px
     «Blocco 2 · S5» ci sta ancora intero — misurato. Se un giorno un nome di
     blocco piu' lungo non ci stara', a perderci sara' la coda del testo, non un
     bottone che serve davanti a un tornello. */
  min-width: 0; overflow: hidden; text-overflow: ellipsis;
}
.hdr-chip .dot { flex-shrink: 0; }
.hdr-chip > span:last-child { overflow: hidden; text-overflow: ellipsis; }
.hdr-chip .dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--rotta); }
.lucebtn {
  width: 34px; height: 34px; flex-shrink: 0; position: relative; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; color: var(--testo-2);
  background: var(--carta); box-shadow: var(--ombra);
  transition: transform 0.24s var(--spring);
}
.lucebtn::after { content: ''; position: absolute; inset: -7px; }
.lucebtn:active { transform: scale(0.88); }
.lucebtn svg { display: block; width: 15px; height: 15px; }
/* Il filetto era la riga stampata sotto la testata. Nel sistema nuovo non
   esistono righe: la separazione la fa lo spazio. */
.filetto { height: 0; margin: 0; background: none; }

.hdr h1 {
  font-family: var(--sans); font-weight: 800; font-size: var(--t-xl);
  letter-spacing: 0; line-height: 1.06; margin-top: var(--s4); color: var(--testo);
  transition: transform 0.28s var(--ease), opacity 0.28s var(--ease);
}
.hdr h1 .sub {
  display: block; font-family: var(--sans); font-weight: 500; font-size: var(--t-md);
  letter-spacing: 0; color: var(--testo-2); margin-top: 6px; line-height: 1.4;
}
/* Su Oggi il titolo cede il passo al numero del giorno e si fa sopratitolo. */
body.v-oggi .hdr h1 {
  font-family: var(--sans); font-weight: 700; font-size: var(--t-sm);
  letter-spacing: 0.02em; line-height: 1.3; margin-top: var(--s4); color: var(--testo-2);
}
body.v-oggi .hdr h1 .sub {
  font-size: var(--t-lbl); font-weight: 600; letter-spacing: 0.02em;
  /* Sull'alone della testata il terzo gradino misurava 4,50 esatti: sotto la
     soglia di un pelo, ed è testo, non decorazione. Qui va il secondo. */
  color: var(--testo-2); margin-top: 3px;
}
body.scrolled .hdr h1 { transform: scale(0.7) translateY(-8px); opacity: 0; pointer-events: none; height: 0; margin: 0; overflow: hidden; }
.rule { margin-top: var(--s3); }
body.scrolled .rule { display: none; }

/* Il giorno: la misura più grande della pagina, e nel sistema nuovo è un
   numero tondo, non un numero romano in grazie. Il romano era il display del
   quadro di bordo; qui il display è la cifra, come su ogni schermata dell'app
   copiata (11.175 passi, 290.84 mi, 8h 19m). */
.giorno { display: flex; align-items: flex-end; gap: 12px; }
.giorno .rom {
  font-family: var(--grot); font-weight: 800; font-size: var(--t-rom);
  line-height: 0.9; letter-spacing: 0; color: var(--testo);
  font-variant-numeric: tabular-nums;
}
.giorno .di { padding-bottom: 8px; min-width: 0; }
.giorno .di b, .giorno .di i {
  display: block; font-family: var(--sans); font-style: normal; font-size: var(--t-sm);
  letter-spacing: 0; line-height: 1.35;
}
.giorno .di b { font-weight: 700; color: var(--testo); }
.giorno .di i { font-weight: 500; color: var(--testo-2); }

/* Il regolo. Era una scala graduata a tacche, incisa. Adesso è la pista
   arrotondata dell'app copiata: pista tenue, tratto pieno, e sulla punta il
   pallino con l'anello bianco — lo stesso segno che là marca il giorno di
   oggi in fondo all'onda. Le tacche non esistono più. */
.regolo { position: relative; height: 12px; margin-top: var(--s4); }
.regolo i { position: absolute; left: 0; right: 0; bottom: 0; display: block; }
.regolo .minori, .regolo .maggiori { display: none; }
.regolo .base { height: 12px; border-radius: var(--r-pill); background: var(--traccia-fondo); }
.regolo .fatto {
  right: auto; height: 12px; border-radius: var(--r-pill);
  background: var(--rotta);
  transform-origin: left;
}
.regolo .bandiera {
  left: 0; right: auto; bottom: -3px; width: 18px; height: 18px; margin-left: -9px;
  border-radius: 50%; background: var(--rotta);
  box-shadow: 0 0 0 3.5px var(--fondo), var(--ombra);
}
.regolo .bandiera::after { content: none; }
.rule-cap {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s2);
  margin-top: 10px; font-size: var(--t-xs); font-weight: 600; color: var(--testo-3);
}
.rule-cap b { color: var(--testo); font-weight: 800; font-family: var(--grot); }

/* La barra compatta: vetro chiaro con un filo sotto, come la navigation bar
   di iOS quando il contenuto le passa dietro. */
.compact-bar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 45;
  padding: calc(env(safe-area-inset-top, 0px) + 10px) calc(var(--gut) + env(safe-area-inset-right, 0px)) 11px calc(var(--gut) + env(safe-area-inset-left, 0px));
  background: color-mix(in oklab, var(--fondo), transparent 22%);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--filo);
  transform: translateY(-102%); transition: transform 0.3s var(--ease);
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
body.scrolled .compact-bar { transform: none; }
.compact-bar .t { font-family: var(--sans); font-weight: 800; font-size: var(--t-lg); letter-spacing: 0; color: var(--testo); }
.compact-bar .r { font-family: var(--sans); font-weight: 600; font-size: var(--t-sm); color: var(--testo-2); }

/* ============================================================
   VISTE E SEZIONI
   ============================================================ */
.view { display: none; }
.view.on { display: block; }
@keyframes sectIn { from { opacity: 0; transform: translate3d(0, 12px, 0); } to { opacity: 1; transform: none; } }
/* Il cartello di famiglia entra come le sezioni: lasciato fuori, restava fermo
   mentre tutto il resto della vista scivolava su, e sembrava incollato. */
.view.enter > .sect, .view.enter > .famiglia { animation: sectIn 0.5s var(--ease) both; }
.view.enter > .sect:nth-child(1) { animation-delay: 0.02s; }
.view.enter > .sect:nth-child(2) { animation-delay: 0.06s; }
.view.enter > .sect:nth-child(3) { animation-delay: 0.10s; }
.view.enter > .sect:nth-child(4) { animation-delay: 0.14s; }
.view.enter > .sect:nth-child(5) { animation-delay: 0.18s; }
.view.enter > .sect:nth-child(6) { animation-delay: 0.21s; }
.view.enter > .sect:nth-child(n+7) { animation-delay: 0.24s; }
.view.enter > a, .view.enter > .colophon { animation: sectIn 0.5s var(--ease) 0.26s both; }
.sect { margin-top: var(--s5); }
/* Il titolo di sezione era un'etichetta incisa con un filo che correva fino al
   margine. Nell'app copiata è grassetto scuro grande e basta ("Body Metrics",
   "Health", "Today's Activities"): il filo non c'è, e senza filo la sezione
   respira invece di essere incasellata. */
.sect-t {
  display: flex; align-items: baseline; gap: 10px;
  font-family: var(--sans); font-weight: 800; font-size: var(--t-t3);
  letter-spacing: 0; text-transform: none; line-height: 1.25;
  color: var(--testo); margin: 0 2px 11px; padding: 0;
}
.sect-t > span:first-of-type { min-width: 0; }
.sect-t::after { content: none; }
.sect-t .aux {
  margin-left: auto; font-weight: 600; font-size: var(--t-sm); letter-spacing: 0;
  color: var(--testo-3); flex-shrink: 0; text-transform: none;
}

/* ============================================================
   LA TESSERA
   Bianca, raggio 22, ombra bassissima, ZERO bordi. Il bordo su una tessera
   bianca è il segno che qualcuno ha copiato il vecchio sistema qui dentro.
   ============================================================ */
.shell { background: none; border: none; border-radius: 0; padding: 0; }
.core {
  position: relative; isolation: isolate;
  background: var(--carta); color: var(--testo);
  border-radius: var(--r-card); padding: var(--s4);
  box-shadow: var(--ombra);
  transition: transform 0.3s var(--ease);
}
.core.alto { box-shadow: var(--ombra); }
/* `.fuoco` è la tessera di ADESSO. Nell'app copiata la scheda del consiglio del
   giorno NON è satura: è bianca, con sopra la fascia illustrata, il titolo
   nero e la prosa grigia. Il colore ci sta come alone in cima, non come
   campitura sotto le parole. */
.core.fuoco {
  background: var(--carta); color: var(--testo);
  box-shadow: var(--ombra-alta);
  overflow: hidden;
}
/* L'aureola sotto la tessera del gesto e' revocata con lo stesso ragionamento:
   nel riferimento una tessera e' bianca, e la sua importanza la fa il contenuto,
   non un fondo che si accende. */
.core.fuoco::before { content: none; }
.core.fuoco .sect-t { color: var(--testo); }
.core .core { background: none; border: none; border-radius: 0; padding: 0; box-shadow: none; }
/* 🔴 `:not(.core)` non e' prudenza, e' la stessa trappola di `.core.rows`:
   `.core-pad` e' un blocco INTERNO che mette aria sopra e sotto, ma in due
   punti sta sullo STESSO elemento della tessera (`class="core core-pad aff"`,
   la scheda «Quando andare»). Due classi sullo stesso elemento hanno la stessa
   specificita', quindi vinceva quella scritta dopo: la tessera si ritrovava
   `padding: 16px 0` e perdeva i suoi bordi laterali. Misurato sul vivo: la
   striscia delle ore arrivava a filo dei due fianchi della carta. */
.core-pad:not(.core) { padding: var(--s4) 0; }
/* ---------- L'ARIA, TUTTA E QUATTRO I LATI ----------
   🔴 «Deve essere tutto bello centrato, con gli stessi bordi: sopra e sotto ci
   sono bordi diversi, sopra più stretto e sotto più largo, e tutto è attaccato
   alla carta». È la stessa regola che aveva già dato il 4 settembre — «quanto
   c'è aria a destra o a sinistra deve esserci aria anche sotto» — solo che era
   applicata a pezzi: la tessera metteva i 16 px ai soli fianchi e l'aria
   verticale la lasciava ai figli, che ognuno la metteva a modo suo. Misurato
   prima: tredici valori diversi sopra (da 12 a 46) e otto sotto (da 9 a 31) su
   44 tessere.
   Adesso li mette la TESSERA, una volta sola, su tutti e quattro i lati; e chi
   capita al primo o all'ultimo posto — anche dentro una porta o dentro una
   lista — non li raddoppia. Un valore solo, un posto solo. */
.core > :first-child,
.core > :first-child > :first-child:not(summary) { padding-top: 0; margin-top: 0; }
.core > :last-child,
.core > :last-child > :last-child:not(summary),
.core > :last-child > :last-child > :last-child:not(summary) { padding-bottom: 0; margin-bottom: 0; }
/* 🔴 Il cartello di una porta fa eccezione, per due motivi che si sommano.
   Primo: una porta chiusa non finisce col suo contenuto, finisce col CARTELLO,
   e il cartello non e' `:last-child` — il contenuto gli resta dietro nel
   documento anche da chiusa. Senza questa riga sedici tessere su quarantaquattro
   restavano a 33 px dal fondo invece che a 16.
   Secondo, e piu' importante: qui si toglie il MARGINE, non il padding. La
   prima versione azzerava il padding del cartello e il bersaglio crollava a
   23 px, sotto i 44 minimi — `node iphone.js` ne contava 36. Cosi' invece
   l'inchiostro sta a 16 dal bordo come tutto il resto e il bersaglio arriva
   fino al bordo della carta, dove il dito lo cerca. */
.core > details:first-child > summary,
.core > :first-child > details:first-child > summary { margin-top: calc(-1 * var(--s4)); }
.core > details:last-child:not([open]) > summary,
.core > :last-child > details:last-child:not([open]) > summary,
.core > :last-child > :last-child > details:last-child:not([open]) > summary { margin-bottom: calc(-1 * var(--s4)); }
/* Le righe dentro una tessera: il filo le divide e resta DENTRO l'incasso.
   Prima uscivano coi margini negativi fino ai fianchi della carta — era una
   delle due cose «attaccate a destra e a sinistra» — e si ripagavano il
   rientro con un padding uguale e contrario. Tolti tutti e due non resta
   niente da dichiarare: una lista e' un blocco come gli altri.
   🔴 E non si rimette un `.rows { padding: 0 }` "per pulizia": `.core.rows`
   sono le due classi sullo STESSO elemento, stessa specificita', quindi lo
   zero vincerebbe sul padding della tessera e la lista perderebbe i suoi 16 px
   su tutti e quattro i lati. Misurato: l'ultima riga finiva a 2 px dal fondo. */
.rows > * { border-top: 1px solid var(--filo); }
.rows > *:first-child { border-top: none; }
.core > .rows:last-child > *:last-child { border-bottom: none; }

/* ============================================================
   IL BOTTONE
   Pieno, raggio 16, bianco sopra, altezza 52. È il "Start" verde dell'app
   copiata, con l'arancio del marchio al posto del verde.
   ============================================================ */
/* Misurato: 361,2 x 56 pt, raggio 8, nero pieno, testo 18/600. Nessun
   gradiente e nessuna ombra colorata: nel riferimento non esistono. */
.btn {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; min-height: 56px; padding: 0 20px; border-radius: var(--r-box);
  background: var(--pieno);
  color: var(--su-pieno);
  font-family: var(--sans); font-weight: 600; font-size: var(--t-lg); letter-spacing: 0;
  box-shadow: none;
  transition: opacity 0.2s var(--ease);
}
.core.fuoco .btn { background: var(--pieno); color: var(--su-pieno); }
.btn:active { opacity: 0.82; }
.btn.ghost {
  background: var(--pastiglia);
  color: var(--testo);
  box-shadow: none; min-height: 48px; font-size: var(--t-rg);
}
.core.fuoco .btn.ghost { background: var(--pastiglia); color: var(--testo); box-shadow: none; }
.btn.subtle { background: var(--pastiglia); color: var(--testo); box-shadow: none; font-weight: 600; }
/* Il bottone che chiude un campo (« Salva ») e' l'azione primaria di quella
   riga, e nel riferimento l'azione primaria e' nera. */
.winput .btn:not(.ghost):not(.subtle), .formrow .btn:not(.ghost):not(.subtle) {
  background: var(--pieno); color: var(--su-pieno);
}
/* 🔴 `.core.fuoco .btn` sono tre classi e `.btn.subtle` due: dentro la tessera
   d'oro di ADESSO il sobrio perdeva e veniva ridipinto pieno, cioè due ori
   nella stessa schermata — la regola visiva che il progetto rompe più
   facilmente. Vale per chiunque, non solo per chi l'ha scoperto: 93% invece
   dell'87% del ghost, così la gerarchia fra i due secondari resta leggibile. */
.core.fuoco .btn.subtle { background: var(--carta-2); color: var(--testo-2); box-shadow: none; }
.btn.royal { background: var(--pieno); color: var(--su-pieno); box-shadow: none; }
.btn.danger { background: var(--danger); color: #FFFFFF; box-shadow: none; }
/* 46, non 44. Il minimo di Apple e' 44 e a 44 il bottone lo rispetta — ma
   esattamente, e una misura sul filo oscilla: `iphone.js` lo segnalava a
   intermittenza, uno scatto su quattro, perche' un'oscillazione sub-pixel
   durante l'animazione d'ingresso lo portava sotto. Due pixel tolgono
   l'intermittenza dal banco e allargano il bersaglio: nessuno dei due e' un
   costo. */
.btn.sm { width: auto; min-height: 46px; padding: 0 18px; font-size: var(--t-sm); }
.btn[disabled] { opacity: 0.36; pointer-events: none; box-shadow: none; }
.btn .ico { display: flex; align-items: center; justify-content: center; width: 20px; height: 20px; margin: 0; transition: transform 0.28s var(--ease); }
.btn:active .ico { transform: translateX(3px); }

/* ============================================================
   ADESSO — la scheda del consiglio
   ============================================================ */
.now { padding: var(--s4) 0 var(--s5); }
.now-k { display: flex; align-items: baseline; gap: 7px; }
.now-k .ora {
  font-family: var(--grot); font-weight: 800; font-size: var(--t-lbl-md);
  letter-spacing: 0; color: var(--testo-3);
}
.now-k .fascia {
  font-family: var(--sans); font-weight: 700; font-size: var(--t-lbl-md);
  letter-spacing: 0.02em; text-transform: none; color: var(--testo-3); opacity: 1;
}
.now-k .fascia::before { content: '·'; margin-right: 7px; }
.now-t {
  font-family: var(--sans); font-weight: 800; font-size: var(--t-xl);
  letter-spacing: 0; line-height: 1.08; margin-top: 10px; color: var(--testo);
}
.now-d { font-size: var(--t-md); line-height: 1.5; margin-top: 9px; color: var(--testo-2); }
.now-g { margin-top: var(--s4); }
.now-g .now-meal { border-top: 1px solid var(--filo); padding-top: var(--s4); }

/* L'ONDA. 🔴 «Ora c'è una linea che segna vari giorni, nella prima card di
   Oggi, e anche quella è attaccata sia a destra che a sinistra.» Aveva ragione:
   l'onda usciva dall'incasso coi margini negativi e faceva da pavimento alla
   scheda, appiccicata ai tre lati. Adesso è un riquadro come la scintilla delle
   tessere di misura — stesso incasso di 16, stesso raggio da riquadro — e la
   fascia verde la taglia il suo `overflow`, non più gli angoli della carta. */
.onda { margin: var(--s5) 0 0; }
/* 🔴 `overflow: visible` come fa gia' la scintilla delle tessere di misura, e
   non e' un dettaglio: i pallini del primo e dell'ultimo giorno stanno
   ESATTAMENTE sul bordo del viewBox, quindi il riquadro dell'SVG li taglia a
   meta'. Finche' l'onda usciva fino ai fianchi della carta una mezzaluna
   sembrava un grafico che continua fuori schermo; dentro l'incasso, con sedici
   pixel di bianco accanto, sembra solo un disegno rotto. Per lo stesso motivo
   niente raggio: con l'overflow visibile non taglierebbe nulla, sarebbe una
   dichiarazione che non dipinge. */
.onda svg { display: block; width: 100%; height: auto; overflow: visible; }
.onda-x {
  display: flex; justify-content: space-between; gap: 8px;
  padding: 9px 0 0;
  font-family: var(--sans); font-weight: 600; font-size: var(--t-xs); color: var(--testo-3);
}
.onda-x .oggi { color: var(--testo); font-weight: 800; }
/* Sotto una misura l'app copiata mette un gettone tondo con la freccia e tre
   parole ("Above Typical Saturday"): il segno dice il verso, il testo dice la
   cosa. Qui c'era una frase di due righe che ripeteva a parole quello che la
   figura dice da sola. */
.onda-cap {
  display: flex; align-items: center; gap: 9px;
  padding: 11px var(--s4) var(--s4);
  font-size: var(--t-sm); font-weight: 600; color: var(--testo-2);
}
.onda-cap .verso {
  width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
}
.onda-cap .verso svg { width: 13px; height: 13px; display: block; }
.onda-cap .verso.ok  { background: color-mix(in oklab, var(--piatto-viva), transparent 82%); color: var(--t-ok); }
.onda-cap .verso.su  { background: var(--pastiglia); color: var(--testo); }
.onda-cap .verso.giu { background: color-mix(in oklab, var(--palestra-viva), transparent 82%); color: var(--t-palestra); }

/* ============================================================
   IL QUADRANTE — le tessere di misura
   Sono le "Body Metrics" dell'app copiata: tessera bianca, etichetta grigia in
   alto, numero grande, unità sotto, e in fondo una traccia su fondo tenue.
   ============================================================ */
.rings { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap); }
.mis {
  display: flex; flex-direction: column; justify-content: space-between;
  /* 16 ai lati come la tessera grande, non 15: due incassi che differiscono di
     un pixel non sono una scelta, sono una svista che si vede quando le due
     forme stanno una sopra l'altra nella stessa colonna. */
  min-height: 132px; padding: var(--s4); border-radius: var(--r-tile); min-width: 0;
  background: var(--carta); color: var(--testo); box-shadow: var(--ombra);
  --tinta: var(--testo-3);
}
.mis.palestra  { --tinta: var(--palestra); }
.mis.piatto { --tinta: var(--piatto); }
.mis.peso   { --tinta: var(--peso); grid-column: span 2; min-height: 0; }
.mis .lb {
  display: flex; align-items: center; gap: 6px;
  font-family: var(--sans); font-weight: 700; font-size: var(--t-lbl);
  letter-spacing: 0.01em; text-transform: none; color: var(--testo-2); line-height: 1.3;
}
.mis.palestra .lb::before, .mis.piatto .lb::before, .mis.peso .lb::before {
  content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--tinta); flex-shrink: 0;
}
.mis .vl {
  font-family: var(--grot); font-weight: 800; font-size: var(--t-rom);
  letter-spacing: 0; line-height: 0.98; margin-top: 10px; color: var(--testo);
  font-variant-numeric: tabular-nums;
}
.mis .vl small {
  font-family: var(--sans); font-weight: 700; font-size: var(--t-lbl-lg);
  letter-spacing: 0; margin-left: 2px; color: var(--testo-3);
}
.mis .un {
  font-family: var(--sans); font-weight: 600; font-size: var(--t-xs);
  letter-spacing: 0.01em; text-transform: none; color: var(--testo-3); margin-top: 7px; min-height: 13px;
}
.mis.stato .vl { font-family: var(--sans); font-size: var(--t-t3); line-height: 1.16; letter-spacing: 0; }

/* Il misuratore a tacche, arrotondato: segmenti su pista tenue. È la barra
   delle zone cardiache dell'app copiata, ridotta a n segmenti. */
.tacche { display: flex; align-items: center; gap: 3px; height: 10px; margin-top: 12px; }
.tacche i {
  flex: 1; min-width: 2px; height: 8px; display: block; border-radius: var(--r-pill);
  background: var(--traccia-fondo); transition: background 0.4s var(--ease);
}
.tacche i.on { background: var(--tinta); }
.tacche i.dieci { height: 10px; }
.tacche.larghe { gap: 5px; }
.tacche.larghe i { height: 9px; }
.tacche.larghe i.dieci { height: 11px; }

/* La scintilla: quattordici giorni su fondo tenue della tinta del dominio, col
   pallino sull'ultimo giorno. È la mini-traccia sotto ogni "Body Metric"
   dell'app copiata, e nella tessera risponde alla sola domanda che il numero
   grande non tocca: oggi è un caso o una tendenza?
   Il pallino è HTML, non un `<circle>`: l'SVG si stira in larghezza, e dentro
   un SVG stirato un cerchio diventa un'ellisse. */
.mis .spark {
  position: relative; display: block; height: 40px; margin: 12px 0 0;
  border-radius: var(--r-box); color: var(--tinta);
  background: color-mix(in oklab, var(--tinta), transparent 88%);
}
.mis .spark svg { display: block; width: 100%; height: 100%; overflow: visible; }
.mis .spark .dot {
  position: absolute; width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px;
  border-radius: 50%; background: var(--tinta); box-shadow: 0 0 0 2.5px var(--carta);
}

/* La bilancia: tessera larga, con le due misure di contorno e la traccia
   delle tre settimane su fondo tenue — che è esattamente la mini-traccia
   sotto ogni Body Metric dell'app copiata. */
/* La traccia è appoggiata al fondo della tessera con lo stesso incasso dei
   fianchi (16), e il contenuto le lascia 8 px sopra: 16 + 36 di traccia + 8. */
.mis.peso { flex-direction: row; align-items: flex-end; flex-wrap: wrap; gap: 12px var(--s4); position: relative; overflow: hidden; padding-bottom: calc(var(--s4) + 36px + var(--s2)); }
.mis.peso .cap { flex: 1 1 100%; }
.mis.peso .vl { margin-top: 8px; font-size: var(--t-rom); }
.mis.peso .cell { min-width: 0; padding-left: var(--s4); border-left: 1px solid var(--filo); }
.mis.peso .cell .v { font-family: var(--grot); font-weight: 800; font-size: var(--t-md); letter-spacing: 0; margin-top: 4px; color: var(--testo); }
.mis.peso .cell .lb { font-size: var(--t-xs); }
.mis.peso .cell .lb::before { content: none; }
.mis.peso::after {
  content: ''; position: absolute; left: var(--s4); right: var(--s4); bottom: var(--s4); height: 36px;
  border-radius: var(--r-box); background: color-mix(in oklab, var(--peso-viva), transparent 84%);
  pointer-events: none;
}
.traccia {
  position: absolute; left: calc(var(--s4) + 5px); bottom: calc(var(--s4) + 5px); height: 26px;
  width: calc(100% - (var(--s4) + 5px) * 2);
  display: block; color: var(--peso); opacity: 1; pointer-events: none;
  overflow: visible;
}
.mis.peso:not(:has(.traccia)) { padding-bottom: var(--s4); }
.mis.peso:not(:has(.traccia))::after { display: none; }
/* Senza pesata la casella non mente: resta vuota, senza il campo acceso. */
.mis.peso:not(.on) .vl { color: var(--testo-3); }

/* ============================================================
   IL CAMPO — la tessera satura
   È la scheda di confronto dell'app copiata: rettangolo tondo pieno di colore,
   testo bianco, etichetta a opacità ridotta. Poche per schermata.
   ============================================================ */
.campo {
  display: flex; gap: var(--s3); width: 100%; text-align: left; align-items: flex-start;
  padding: var(--s4); border-radius: var(--r-tile); color: var(--testo);
  box-shadow: var(--ombra);
  transition: transform 0.18s var(--ease);
}
/* 🔴 La tessera satura e' revocata insieme al sistema che la conteneva. Su 335
   schermate di MacroFactor non esiste una superficie grande di colore: le
   tessere sono bianche, sempre, e il colore vive DENTRO, nella misura. Un campo
   pieno di tinta e' il segno che qualcuno ha copiato il sistema di prima dentro
   questo. L'unica superficie tinta ammessa e' il riquadro d'avviso, che nel
   riferimento e' misurato #FFDAD0 e sta in `.alertbox`. */
.campo.piatto, .campo.palestra, .campo.rotta, .campo.piano, .campo.peso {
  background: var(--carta);
}
/* 🔴 Il numero grande resta NERO. Nel riferimento la misura e' sempre nera e il
   colore vive nella BARRA sotto: colorare anche la cifra e' il passo che
   riporta il colore a fare da dominio invece che da dato. */
.campo.piatto .barra { background: var(--piatto); }
.campo.palestra  .barra { background: var(--palestra); }
.campo.rotta  .barra { background: var(--rotta); }
.campo.piano  .barra { background: var(--piano); }
.campo.peso   .barra { background: var(--peso); }

.campo .lb {
  font-family: var(--sans); font-weight: 700; font-size: var(--t-lbl);
  letter-spacing: 0.01em; text-transform: none; line-height: 1.3; color: var(--testo-2);
}
.campo .un {
  font-family: var(--sans); font-weight: 600; font-size: var(--t-xs);
  letter-spacing: 0.01em; text-transform: none; line-height: 1.5; color: var(--testo-2);
}
/* 🔴 `.meal` (una classe) e `.campo` (una classe) hanno la stessa specificita', e
   `.meal` viene dopo nel foglio: il suo `padding: 14px 0` vinceva, e la tessera
   del prossimo pasto in Oggi restava con zero padding a sinistra. Il pallino
   toccava il bordo della card — misurato 0 px. Dentro una lista `.rows` il
   margine lo mette la lista; questa tessera e' sola e se lo mette da se'. */
.campo.meal { padding: var(--s4); }
.campo.meal .meal-h .t, .campo.meal .meal-h .kp { color: var(--testo-2); opacity: 1; }
.campo.meal .porz { color: var(--testo-2); opacity: 1; }
.campo.meal .meal-in { flex: 1; min-width: 0; }
.campo.meal .d { display: block; font-family: var(--sans); font-weight: 800; font-size: var(--t-t2); letter-spacing: 0; line-height: 1.16; margin-top: 6px; color: var(--testo); }
.campo.meal .mbox { box-shadow: inset 0 0 0 2px color-mix(in oklab, currentColor, transparent 46%); width: 24px; height: 24px; border-radius: 50%; margin-top: 2px; }
.campo.meal.eaten .mbox { background: var(--testo); box-shadow: none; }
.campo.meal.eaten .mbox svg { display: block; stroke: var(--su-pieno); }
.campo.meal .porz { margin-top: 8px; }
/* Il campo del CONTO: il soggetto della vista. Forma unica su tutte e cinque. */
/* Anche qui la barra sta a 16 dal fondo come dai fianchi, e il contenuto le
   lascia 8 px sopra: 16 + 5 di barra + 8. Prima era a 12 e il contenuto a 24,
   cioe' la tessera respirava piu' sotto che sopra. */
.campo.conto { flex-direction: column; gap: 0; position: relative; overflow: hidden; padding-bottom: calc(var(--s4) + 5px + var(--s2)); }
.campo.conto .vl { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.campo.conto .vl b { font-family: var(--grot); font-weight: 800; font-size: var(--t-rom); letter-spacing: 0; line-height: 0.94; font-variant-numeric: tabular-nums; }
.campo.conto .vl small { font-family: var(--sans); font-weight: 700; font-size: var(--t-lbl-lg); letter-spacing: 0; text-transform: none; color: var(--testo-2); }
.campo.conto .un { margin-top: 10px; }
.campo.conto .barra {
  position: absolute; left: var(--s4); right: var(--s4); bottom: var(--s4); height: 5px; display: block; z-index: 1;
  /* La barra del conto misura CALORIE, e nel riferimento le calorie sono blu.
     Il nero e' lo stato, non il dato. */
  border-radius: 0; background: var(--palestra); opacity: 1;
  transform-origin: left; transition: transform 0.7s var(--ease);
}
.campo.conto::after {
  content: ''; position: absolute; left: var(--s4); right: var(--s4); bottom: var(--s4); height: 5px;
  border-radius: 0; background: var(--traccia-fondo); z-index: 0;
}
.campo.conto:not(:has(.barra)) { padding-bottom: var(--s4); }
.campo.conto:not(:has(.barra))::after { content: none; }
body.entra .campo.conto .barra { animation: traccia 0.8s var(--ease) 0.15s both; }
/* Un campo acceso senza il suo dato è una bugia grafica: torna tessera bianca. */
.campo.spento { background: var(--carta); color: var(--testo); box-shadow: var(--ombra); }
.campo.fatto { flex-direction: column; gap: 0; }
.campo.fatto .vl { font-family: var(--grot); font-weight: 800; font-size: var(--t-rom); letter-spacing: 0; line-height: 0.96; margin-top: 9px; }
.campo.fatto .vl small { font-family: var(--sans); font-weight: 700; font-size: var(--t-lbl-lg); margin-left: 3px; color: var(--testo-2); }
.campo.fatto .un { margin-top: 9px; }
.coppia { display: grid; grid-template-columns: 1.35fr 1fr; gap: var(--gap); margin-top: var(--gap); }

/* La tessera-porta: stessa tessera bianca, con il gallone a destra. */
.mis.carta { position: relative; background: var(--carta); color: var(--testo); box-shadow: var(--ombra); min-height: 116px; text-align: left; }
button.mis.carta::after {
  content: ''; position: absolute; top: 20px; right: 16px;
  width: 8px; height: 8px; border-right: 2px solid var(--testo-3); border-top: 2px solid var(--testo-3);
  transform: rotate(45deg); transition: transform 0.2s var(--ease);
}
button.mis.carta:active::after { transform: rotate(45deg) translate(2px, -2px); }
.mis.carta .vl { font-size: var(--t-t1); }
.mis .vl i { font-style: normal; font-size: var(--t-sm); opacity: 1; color: var(--testo-3); margin-right: 1px; }
.mis.carta .vl small { font-family: var(--sans); font-weight: 700; font-size: var(--t-lbl); margin-left: 3px; text-transform: none; color: var(--testo-3); }
.mis.carta .un { color: var(--testo-3); }
button.mis.carta { transition: transform 0.18s var(--ease); }


/* La porta che sta da sola: riga tonda su tessera, senza il riquadro alto. */
/* Stessa geometria della tessera grande: 16 su tutti e quattro i lati messi
   dalla carta, e il cartello che non li raddoppia. L'altezza del bersaglio non
   cambia — sono gli stessi 16 di prima, spostati di un livello. */
details.fold.sola {
  border: none; background: var(--carta); border-radius: var(--r-tile);
  box-shadow: var(--ombra); padding: var(--s4);
}
details.fold.sola > summary { padding: var(--s4) 0; gap: var(--s3); margin-top: calc(-1 * var(--s4)); }
details.fold.sola:not([open]) > summary { margin-bottom: calc(-1 * var(--s4)); }
details.fold.sola > summary .k { font-family: var(--sans); font-weight: 700; font-size: var(--t-rg); letter-spacing: 0; text-transform: none; color: var(--testo); }
details.fold.sola > summary .v { margin-left: auto; font-family: var(--sans); font-weight: 600; font-size: var(--t-sm); text-transform: none; color: var(--testo-3); }
details.fold.sola .zonegrid { margin-bottom: 0; }

/* ============================================================
   ROTTA — grafici, striscia, onorificenze
   ============================================================ */
.rotta-chart { padding: var(--s4) 0 var(--s2); }
/* 🔴 Qui c'era `padding-bottom: 0`, che portava la nota a filo del fondo della
   tessera. Vincenzo, 4 settembre: «questa sezione qua andrebbe leggermente data
   un po' di aria, mi raccomando, perche' importante dare aria. Quanto c'e' aria
   a destra o a sinistra deve esserci aria anche sotto nelle card».
   Ha ragione ed e' la regola giusta per TUTTE le tessere: sotto si respira
   quanto ai lati, cioe' 16 px, che e' il margine misurato del riferimento. */
.rotta-chart:has(.rotta-nota:last-child) { padding-bottom: var(--s4); }
.rotta-chart svg { display: block; width: 100%; overflow: visible; }
.rotta-cap { font-size: var(--t-sm); color: var(--testo-2); line-height: 1.6; padding: 12px 0 4px; border-top: 1px solid var(--filo); margin-top: 12px; }
.rotta-cap b { font-family: var(--grot); font-weight: 800; font-size: var(--t-rg); letter-spacing: 0; color: var(--testo); }
.rotta-cap em { font-style: normal; font-weight: 700; color: var(--testo); }
/* La nota è un riquadro tenue dentro la tessera, non una fascia piena a filo
   dei bordi: nel sistema nuovo niente arriva a filo. */
.rotta-nota {
  margin: var(--s3) 0 0; padding: 12px 14px; border-radius: var(--r-box);
  background: var(--g-rotta); color: var(--testo);
  font-size: var(--t-sm); line-height: 1.5; font-weight: 500;
}
.rotta-nota + .rotta-nota { margin-top: 6px; }
.streak-head { display: flex; align-items: center; gap: 12px; padding: var(--s4) 0; }
.streak-head .n {
  font-family: var(--grot); font-weight: 800; font-size: var(--t-t1); letter-spacing: 0; line-height: 1;
  background: var(--g-rotta); color: var(--testo);
  padding: 10px 14px; border-radius: var(--r-box); min-width: 62px; text-align: center;
}
.streak-head .l { font-family: var(--sans); font-weight: 700; font-size: var(--t-rg); letter-spacing: 0; text-transform: none; color: var(--testo); max-width: 13em; line-height: 1.4; }
/* La striscia dei giorni: pastiglie tonde, come la griglia dei mesi dell'app
   copiata. Un quadrato qui è il vecchio registro. */
.grid-weeks { display: grid; grid-template-rows: repeat(7, 1fr); grid-auto-flow: column; grid-auto-columns: 1fr; gap: 4px; padding: var(--s2) 0 var(--s4); }
.gday { aspect-ratio: 1; border-radius: 50%; background: var(--traccia-fondo); transition: background 0.3s var(--ease); }
.gday.w { background: var(--palestra-viva); }
.gday.r { background: var(--peso-viva); }
.gday.p { background: color-mix(in oklab, var(--testo), transparent 62%); }
.gday.today { box-shadow: 0 0 0 2px var(--carta), 0 0 0 3.5px var(--pieno); }
.gday.future, .gday.void { background: color-mix(in oklab, var(--testo), transparent 93%); }
.gcap { display: flex; gap: 14px; padding: var(--s2) 0 var(--s1); font-family: var(--sans); font-weight: 600; font-size: var(--t-xs); letter-spacing: 0; color: var(--testo-2); text-transform: none; flex-wrap: wrap; }
.gcap span { display: inline-flex; align-items: center; gap: 6px; }
.gcap i { width: 9px; height: 9px; border-radius: 50%; aspect-ratio: auto; flex-shrink: 0; }
/* Le onorificenze: riquadri tondi su fondo tenue, non celle di una tabella. */
/* Le onorificenze. Erano venti marche tipografiche dello stesso grigio dentro
   venti caselle uguali, e quella conquistata diventava una campitura d'ambra:
   una parete di segni in cui non si distingueva niente, e un colore solo per
   dire vent'anni di cose diverse. Adesso il segno vive in un GETTONE TONDO, e
   il gettone porta il colore della sua famiglia — le sedute blu, il volume
   arancio, i giorni di fila verdi, la corsa viola, la bilancia ambra. La
   casella conquistata non cambia colore: si ALZA (bianca, con l'ombra), come
   una tessera che è passata da sfondo a oggetto. */
.medals { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s2); background: none; border: none; padding: var(--s1) 0 var(--s3); }
.medal {
  text-align: center; padding: 14px 8px 13px; background: var(--medaglia);
  border-radius: var(--r-box); transition: transform 0.24s var(--ease), background 0.24s var(--ease);
  --gettone: var(--traccia-fondo);
}
.medal.got { background: var(--medaglia-got); box-shadow: var(--ombra); }
.medal.palestra.got  { --gettone: var(--g-palestra); }
.medal.piatto.got { --gettone: var(--g-piatto); }
.medal.rotta.got  { --gettone: var(--g-rotta); }
.medal.piano.got  { --gettone: var(--g-piano); }
.medal.peso.got   { --gettone: var(--g-peso); }
.medal .mi {
  display: flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; margin: 0 auto 9px; border-radius: 50%;
  background: var(--gettone); color: var(--testo-2);
  /* Il segno NOMINA l'onorificenza: è testo, non decorazione, e col terzo
     gradino dava 4,29 di giorno e 3,87 di notte sul gettone spento. */
  font-size: var(--t-sm); font-weight: 700; letter-spacing: 0; line-height: 1;
}
.medal.got .mi { color: #000000; }
.medal.peso.got .mi { color: #000000; }
.medal .mn { font-size: var(--t-xs); line-height: 1.35; color: var(--testo-2); font-weight: 600; }
.medal.got .mn { color: var(--testo); font-weight: 700; }
.medal .md { font-family: var(--sans); font-weight: 600; font-size: var(--t-lbl-xs); letter-spacing: 0; color: var(--testo-3); margin-top: 5px; }
.voyage-bar { height: 10px; border-radius: var(--r-pill); background: var(--traccia-fondo); overflow: hidden; margin: var(--s4) 0 10px; }
.voyage-bar i { display: block; height: 100%; border-radius: var(--r-pill); background: var(--rotta); transform-origin: left; transition: transform 1s var(--ease); }
.voyage-legend { display: flex; justify-content: space-between; font-family: var(--sans); font-weight: 600; font-size: var(--t-xs); letter-spacing: 0; color: var(--testo-3); text-transform: none; }

/* ============================================================
   LA SEDUTA
   ============================================================ */
.session-head { padding: var(--s4) 0 var(--s2); }
.session-head .kind { font-family: var(--sans); font-weight: 700; font-size: var(--t-lbl-md); letter-spacing: 0.01em; text-transform: none; color: var(--testo-3); }
.session-head h2 { font-family: var(--sans); font-weight: 800; font-size: var(--t-t2); letter-spacing: 0; line-height: 1.1; margin-top: 6px; color: var(--testo); }
.session-head .meta { font-family: var(--sans); font-weight: 500; font-size: var(--t-sm); letter-spacing: 0; color: var(--testo-2); margin-top: 7px; line-height: 1.5; }
.session-head.eco { padding-bottom: var(--s3); }
.session-head.eco .meta { margin-top: 5px; }
.session-note {
  margin: var(--s3) 0; padding: 12px 14px; border-radius: var(--r-box);
  background: var(--avviso-tenue, #FFDAD0); color: var(--testo);
  font-size: var(--t-sm); line-height: 1.5; font-weight: 500;
}
.session-note.warn { background: var(--g-piano); }
.session-note.plain { background: var(--carta-2); color: var(--testo-2); border: none; }

/* ============================================================
   LA NOTA CHE SI APRE
   Il piede di una tessera, non un blocco: nessuno sfondo, nessuna cornice,
   una riga tenue con un gallone. Chiusa costa 36 pt di altezza al posto dei
   tre-cinque righi che il paragrafo occupava sempre.

   Il bersaglio e' l'intera riga e non le due parole del cartello: `summary` e'
   `display:flex` a tutta larghezza, alto 44 pt pieni.
   🔴 44, non 36 piu' il padding: qui dentro il `box-sizing` e' `border-box`,
   quindi il padding sta DENTRO il minimo e non lo allunga di un pixel. Con
   `min-height:36px` il banco misurava 36, non 44 — la stessa aritmetica
   sbagliata che aveva lasciato `.cs-p` e `.rec-p` a 41.
   ============================================================ */
details.nota { margin: var(--s3) 0 0; }
details.nota > summary {
  list-style: none; display: flex; align-items: center; gap: 7px;
  min-height: 44px; padding: 4px 2px; cursor: pointer;
  font-family: var(--sans); font-weight: 600; font-size: var(--t-xs);
  letter-spacing: 0.01em; color: var(--testo-3);
}
details.nota > summary::-webkit-details-marker { display: none; }
/* Lo stesso gallone di `details.fold`, in piccolo: due lati di un quadrato
   ruotato. Il glifo `▾` cambia forma con la famiglia e non si allinea mai. */
details.nota > summary .arr {
  width: 6px; height: 6px; flex-shrink: 0; margin: -3px 0 0;
  border-right: 1.8px solid var(--testo-3); border-bottom: 1.8px solid var(--testo-3);
  transform: rotate(45deg); transition: transform 0.24s var(--ease), margin 0.24s var(--ease);
}
details.nota[open] > summary .arr { transform: rotate(-135deg); margin-top: 2px; }
details.nota[open] > summary { color: var(--testo-2); }
.nota-c {
  padding: 2px 2px 6px; font-family: var(--sans); font-weight: 500;
  font-size: var(--t-sm); line-height: 1.55; color: var(--testo-2);
}
.nota-c strong { color: var(--testo); font-weight: 700; }
/* Dentro una tessera scura la nota prende i toni della tessera, come fanno
   gia' le altre righe di `.core.fuoco`. */
.core.fuoco details.nota > summary { color: var(--testo-3); opacity: 1; }
.core.fuoco .nota-c { color: var(--testo-2); opacity: 1; }
/* I <p> della nota: il primo non stacca dall'alto, gli altri si separano di
   mezza riga. Senza questa regola i paragrafi si toccavano. */
.nota-c > p { margin: 0; }
.nota-c > p + p { margin-top: 9px; }

/* ---------- Il cartello di famiglia ----------
   Divide la pila delle sezioni in gruppi. Non e' un titolo di sezione: sta
   sopra ai titoli, e per non litigare con loro e' piccolo, spaziato e tenue,
   con un filo che lo separa da quello che viene prima. */
.famiglia {
  margin: var(--s6) 2px var(--s4); padding-top: var(--s4);
  border-top: 1px solid var(--filo);
  font-family: var(--sans); font-weight: 700; font-size: var(--t-lbl);
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--testo-3);
}
/* Il primo cartello della vista non porta il filo: non c'e' niente, sopra, da
   cui separarsi, e la riga finirebbe appoggiata al regolo della testata. */
.view > .famiglia:first-child { border-top: none; margin-top: var(--s4); padding-top: 0; }
/* Una sezione che segue il cartello non riapre lo stacco: il cartello e' gia'
   la sua distanza. */
.famiglia + .sect { margin-top: 0; }
.exrow-btn { display: flex; align-items: center; gap: var(--s3); width: 100%; padding: 14px 0 10px; text-align: left; }
/* La misura della riga: la stessa figura delle barre dei macro, alta 5 pt e a
   spigolo, con la tacca del bersaglio dove cade il numero di serie di tabella. */
.exrow-barra {
  position: relative; height: 5px; margin: 0 0 12px;
  background: var(--traccia-fondo); overflow: hidden;
}
.exrow-pieno { position: absolute; inset: 0 auto 0 0; background: var(--palestra); transition: width 0.5s var(--ease); }
.exrow-tacca { position: absolute; right: 0; top: -2px; bottom: -2px; width: 2px; background: var(--testo-4); }
.exrow.done .exrow-pieno { background: var(--piatto); }
.st {
  width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0;
  background: var(--carta-2); box-shadow: none;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--grot); font-size: var(--t-xs); font-weight: 800; color: var(--testo-3);
  transition: background 0.26s var(--ease), color 0.26s var(--ease);
}
.exrow.done .st { background: var(--pieno); color: var(--su-pieno); }
.exrow.part .st { background: color-mix(in oklab, var(--peso-viva), transparent 76%); color: var(--t-peso); }
.exname { font-size: var(--t-rg); font-weight: 700; letter-spacing: 0; color: var(--testo); }
.extgt { font-size: var(--t-xs); color: var(--testo-2); margin-top: 3px; line-height: 1.45; }
.exlast { margin-left: auto; text-align: right; flex-shrink: 0; white-space: nowrap; align-self: center; font-family: var(--sans); font-weight: 600; font-size: var(--t-xs); color: var(--testo-3); }
.exlast .num { display: block; font-family: var(--grot); font-weight: 800; font-size: var(--t-rg); letter-spacing: 0; color: var(--testo); }
.exlast .up { color: var(--t-peso); }
.exlast .d { font-family: var(--sans); font-weight: 600; font-size: var(--t-lbl-xs); letter-spacing: 0; color: var(--testo-3); }
.exdetail { padding: var(--s1) 0 var(--s4); animation: sectIn 0.26s var(--ease); }
/* La spiegazione: riquadro tenue tondo, non una citazione con il filetto. */
.cuebox {
  font-size: var(--t-sm); color: var(--testo-2); line-height: 1.6;
  background: var(--carta-2); border-radius: var(--r-box); border: none;
  padding: 13px 15px; margin: var(--s4) 0 var(--s1);
}
.cuebox .cerr { display: block; margin-top: 8px; color: var(--t-warn); font-weight: 600; }
.cuebox .ctag { display: block; margin-top: 8px; color: var(--testo-3); font-family: var(--sans); font-size: var(--t-xs); font-weight: 600; letter-spacing: 0; text-transform: none; }
.setchips { display: flex; flex-wrap: wrap; gap: 6px; margin: 12px 0 var(--s1); min-height: 4px; }
.setchip::before { content: ''; position: absolute; inset: -4px; }
.setchip {
  position: relative;
  display: inline-flex; align-items: center; gap: 5px; min-height: 38px; padding: 6px 13px;
  border-radius: var(--r-pill); background: var(--carta-2); box-shadow: none;
  font-family: var(--grot); font-weight: 800; font-size: var(--t-sm); letter-spacing: 0;
  animation: chipIn 0.3s var(--spring); transition: transform 0.15s var(--ease);
}
.setchip:active { transform: scale(0.94); }
.setchip.pr { background: var(--pieno); color: var(--su-pieno); }
.setchip .x { font-family: var(--sans); font-size: var(--t-xs); opacity: 0.5; }
@keyframes chipIn { from { opacity: 0; transform: scale(0.86); } to { opacity: 1; transform: none; } }
/* Il selettore del carico: due riquadri tondi tenui, non due colonne incise. */
.steppers { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap); margin: var(--s1) 0 var(--s3); }
.stepper {
  background: var(--carta-2); border-radius: var(--r-box); border: none; padding: 4px;
  display: grid; grid-template-columns: 44px minmax(0, 1fr) 44px; column-gap: 4px; align-items: center;
}
.stepper .sbtn { height: 56px; min-width: 44px; border-radius: var(--r-chip); font-family: var(--grot); font-size: var(--t-t3); font-weight: 800; color: var(--testo-2); display: flex; align-items: center; justify-content: center; transition: color 0.18s var(--ease), transform 0.15s var(--spring); }
.stepper .sbtn:active { transform: scale(0.86); color: var(--testo); }
.stepper .sval { text-align: center; }
.stepper .sval input { width: 100%; min-width: 0; min-height: 44px; text-align: center; background: none; border: none; color: var(--testo); font-family: var(--grot); font-size: var(--t-t1); font-weight: 800; outline: none; letter-spacing: 0; }
.stepper .slab { display: block; text-align: center; font-family: var(--sans); font-weight: 600; font-size: var(--t-lbl-xs); letter-spacing: 0.02em; text-transform: none; color: var(--testo-3); margin-top: -4px; padding-bottom: 6px; }

/* ============================================================
   DOLORE E ZONE
   ============================================================ */
.dolrow { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); padding: 14px 0; }
.dolrow .dn { min-width: 0; }
.dolrow .z { display: block; font-size: var(--t-rg); font-weight: 700; letter-spacing: 0; }
.dolrow .q { display: block; font-family: var(--sans); font-weight: 600; font-size: var(--t-xs); letter-spacing: 0; text-transform: none; color: var(--testo-3); margin-top: 4px; }
.dolrow.gate .z, .dolrow.gate .q { color: var(--t-warn); }
.dolrow.grave .z, .dolrow.grave .q { color: var(--t-danger); }
.dolrow .pill { flex-shrink: 0; }
.zonegrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; background: none; margin-top: var(--s2); border: none; padding-bottom: var(--s2); }
.zona { background: var(--carta-2); border-radius: var(--r-box); padding: 14px 8px; font-size: var(--t-sm); font-weight: 600; color: var(--testo-2); line-height: 1.3; min-height: 54px; transition: background 0.2s var(--ease), color 0.2s var(--ease); }
.zona:active { background: var(--filo); }
.zona.on { background: var(--pieno); color: var(--su-pieno); font-weight: 700; }

/* ============================================================
   PIATTO
   ============================================================ */
.daytype { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; padding: var(--s4) 0; }
.daytype .l { font-family: var(--sans); font-weight: 800; font-size: var(--t-t3); letter-spacing: 0; }
.daytype .k { font-family: var(--sans); font-weight: 400; font-size: var(--t-sm); letter-spacing: 0; text-transform: none; color: var(--testo-3); white-space: nowrap; }
.core.fuoco .daytype .k { color: var(--testo-3); opacity: 1; }
.meal { display: flex; gap: var(--s3); padding: 14px 0; width: 100%; text-align: left; align-items: flex-start; }
.meal .mbox {
  width: 24px; height: 24px; border-radius: 50%; flex-shrink: 0; margin-top: 2px;
  box-shadow: inset 0 0 0 2px var(--bordo);
  display: flex; align-items: center; justify-content: center;
  transition: background 0.22s var(--ease), box-shadow 0.22s var(--ease);
}
.meal .mbox svg { display: none; }
.meal.eaten .mbox { background: var(--pieno); box-shadow: none; }
.meal.eaten .mbox svg { display: block; stroke: var(--su-pieno); }
.now-meal .mbox { box-shadow: inset 0 0 0 2px var(--bordo); }
/* L'icona dell'alimento. Nel riferimento e' 32 pt e **non ha nessun
   contenitore**: e' un'illustrazione appoggiata sul bianco, e il filo divisorio
   della riga rientra di 64 pt quando c'e'. Qui e' 32 pt come la' ma il rientro
   del filo resta quello della lista, perche' la nostra riga porta anche la
   casella della spunta e il filo partirebbe a meta' del testo. */
.ci { width: 32px; height: 32px; flex-shrink: 0; margin-top: 1px; }
.ci svg { display: block; width: 100%; height: 100%; }
/* Finche' il foglio non e' arrivato i simboli non esistono: senza questa riga
   la riga del pasto tiene 32 px di vuoto a sinistra del testo per una frazione
   di secondo, e si vede saltare. */
body:not(.con-icone) .ci { display: none; }
.meal.eaten .ci { opacity: 0.5; transition: opacity 0.34s var(--ease); }
.meal-in { flex: 1; min-width: 0; transition: opacity 0.22s var(--ease); }
.meal.eaten .meal .d, .meal.eaten .d { opacity: 0.62; }
.meal-h { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; width: 100%; }
.meal-h .t { font-family: var(--sans); font-weight: 700; font-size: var(--t-lbl); letter-spacing: 0.01em; text-transform: none; color: var(--testo-2); }
.meal-h .kp { font-family: var(--sans); font-weight: 600; font-size: var(--t-lbl); letter-spacing: 0; color: var(--testo-3); white-space: nowrap; }
.core.fuoco .meal-h .t { color: var(--testo-2); opacity: 1; }
.core.fuoco .meal-h .kp { color: var(--testo-3); opacity: 1; }
.meal .d { display: block; font-family: var(--sans); font-weight: 800; font-size: var(--t-lg); letter-spacing: 0; line-height: 1.2; color: var(--testo); margin-top: 5px; }
.core.fuoco .meal .d { color: var(--testo); }
.meal .porz { display: block; font-size: var(--t-xs); color: var(--testo-2); margin-top: 7px; line-height: 1.5; font-variant-numeric: tabular-nums; }
.core.fuoco .meal .porz { color: var(--testo-2); opacity: 1; }
.alts { padding: 0 0 12px 36px; }
.alts summary { list-style: none; cursor: pointer; display: flex; align-items: center; min-height: 44px; padding: 4px 0; font-family: var(--sans); font-weight: 600; font-size: var(--t-xs); letter-spacing: 0; text-transform: none; color: var(--testo-3); }
.alts summary::-webkit-details-marker { display: none; }
.alts summary::after {
  content: ''; width: 7px; height: 7px; margin: -3px 0 0 8px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg); transition: transform 0.24s var(--ease), margin 0.24s var(--ease);
}
.alts[open] summary::after { transform: rotate(-135deg); margin-top: 2px; }
.alts .alt { display: block; font-size: var(--t-sm); color: var(--testo-2); margin-top: 6px; padding: 10px 12px; border: none; border-radius: var(--r-chip); background: var(--carta-2); line-height: 1.5; }
.cenagrid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap); padding-bottom: var(--s2); }
.cenacard { display: block; text-align: left; background: var(--carta-2); border-radius: var(--r-box); box-shadow: none; padding: 14px; transition: transform 0.18s var(--ease), background 0.2s var(--ease); }
.cenacard:active { background: var(--filo-2); }
.cenacard.sel { background: var(--pieno); color: var(--su-pieno); }
.cenacard.sugg { box-shadow: inset 0 0 0 2px var(--pieno); }
.cenacard.last { opacity: 0.5; }
.cenacard .n { font-family: var(--sans); font-weight: 800; font-size: var(--t-rg); letter-spacing: 0; }
.cenacard .d { font-size: var(--t-xs); color: var(--testo-2); margin-top: 5px; line-height: 1.4; }
.cenacard.sel .d { color: var(--testo-2); }
.cenacard .tag { display: inline-block; font-family: var(--sans); font-weight: 700; font-size: var(--t-lbl-xs); letter-spacing: 0.02em; text-transform: uppercase; color: var(--t-warn); margin-top: 7px; }
.cenacard .tag.ok { color: var(--t-ok); }
.check-item { display: flex; align-items: center; gap: var(--s3); width: 100%; padding: 14px 0; text-align: left; }
.check-item .box { width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0; box-shadow: inset 0 0 0 2px var(--bordo); display: flex; align-items: center; justify-content: center; transition: background 0.22s var(--ease), box-shadow 0.22s var(--ease); }
.check-item .box svg { display: none; }
.check-item.on .box { background: var(--piatto); box-shadow: none; }
.check-item.on .box svg { display: block; stroke: #FFFFFF; }
.check-item .t { font-size: var(--t-rg); flex: 1; min-width: 0; transition: color 0.2s var(--ease); }
.check-item .q { font-family: var(--grot); font-weight: 800; font-size: var(--t-sm); color: var(--testo-2); flex-shrink: 0; margin-left: auto; padding-left: 10px; }
.check-item.on .t { color: var(--testo-3); text-decoration: line-through; }
.check-item.on .q { color: var(--testo-3); }
.spesa-g { padding: var(--s3) 0 var(--s1); }
.spesa-g .g { font-family: var(--sans); font-weight: 800; font-size: var(--t-rg); letter-spacing: 0; text-transform: none; color: var(--testo); padding: var(--s4) 0 var(--s1); }

/* ============================================================
   PESO
   ============================================================ */
.statgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; padding: var(--s3) 0; }
.statgrid > div { padding: 13px 10px; background: var(--carta-2); border-radius: var(--r-box); }
.statgrid > div + div { padding-left: 10px; border-left: none; }
.statgrid > div:last-child { padding-right: 10px; }
/* L'etichetta tiene due righe di altezza anche quando ne usa una: con tre
   caselle affiancate, una sola etichetta che va a capo abbassava il suo numero
   e sfalsava la fila. */
.statgrid .sl { font-family: var(--sans); font-weight: 600; font-size: var(--t-xs); letter-spacing: 0; text-transform: none; color: var(--testo-2); opacity: 1; min-height: 2.6em; }
.statgrid .sv { font-family: var(--grot); font-weight: 800; font-size: var(--t-t3); margin-top: 6px; letter-spacing: 0; font-variant-numeric: tabular-nums; color: var(--testo); }
.statgrid .sv small { font-family: var(--sans); font-weight: 700; font-size: var(--t-lbl-xs); color: var(--testo-3); margin-left: 2px; }
.wchart { padding: var(--s3) 0 var(--s1); }
.wchart svg { display: block; width: 100%; overflow: visible; }
/* Il campo di digitazione: riquadro tenue tondo, non una riga sottolineata. */
.winput { display: flex; gap: var(--gap); align-items: stretch; padding: var(--s3) 0; }
.winput input {
  flex: 1; min-width: 0; min-height: 56px; background: var(--pastiglia); border: none; border-radius: var(--r-box);
  padding: 10px 16px;
  color: var(--testo); font-family: var(--grot); font-size: var(--t-t3); font-weight: 800;
  outline: none; letter-spacing: 0; transition: box-shadow 0.24s var(--ease);
}
.winput input::placeholder { font-family: var(--sans); font-size: var(--t-md); font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--testo-3); }
.winput input:focus { box-shadow: inset 0 0 0 2px var(--pieno); }
.winput .btn { width: auto; padding: 0 20px; }
/* Gli avvisi: riquadri tondi pieni dentro la tessera. */
.alertbox {
  display: block; margin: var(--s3) 0 var(--s2); padding: 12px 14px; border-radius: var(--r-box);
  font-size: var(--t-sm); line-height: 1.5; font-weight: 500;
  /* Il riquadro d'avviso del riferimento e' misurato #FFDAD0: e' l'unica
     superficie grande di colore che esista in tutta l'app copiata. */
  background: var(--avviso-tenue, #FFDAD0); color: var(--testo);
}
.alertbox + .alertbox { margin-top: 6px; }
.alertbox.warn { background: var(--g-piano); }
.alertbox.danger { background: var(--g-danger); }
.alertbox.ok { background: var(--g-piatto); }
.alertbox.plain { background: var(--carta-2); color: var(--testo-2); border: none; }
/* `nowrap` non è prudenza: col bersaglio della ✕ portato a 44 px la riga
   andava a capo e il segno finiva SOTTO il peso, in una colonna sua. */
.histrow { display: flex; align-items: center; gap: var(--s3); flex-wrap: nowrap; padding: 16px 0; font-size: var(--t-rg); }
.histrow .d { min-width: 0; }
/* Il peso e la ✕ stanno dentro uno `<span>` senza classe. Finché la ✕ era un
   pulsante in linea reggeva; portata a `display:flex` per farne un bersaglio da
   44 px è diventata di blocco, e il segno è finito SOTTO il numero, in una
   colonna sua. Il contenitore diventa una riga: `:has()` è già una dipendenza
   di questo foglio (`.campo.conto:not(:has(.barra))`). */
.histrow > span:has(.del) { display: flex; align-items: center; gap: 4px; margin-left: auto; flex-shrink: 0; }
.histrow .num { white-space: nowrap; }
.histrow .d { font-family: var(--sans); font-weight: 600; font-size: var(--t-sm); letter-spacing: 0; text-transform: none; color: var(--testo-2); }
.histrow .num { font-family: var(--grot); font-weight: 800; font-size: var(--t-md); letter-spacing: 0; }
/* Era un riquadro con 16 px di fianchi e il glifo che sbordava (scrollWidth
   oltre clientWidth su tutti gli schermi). Adesso è un bersaglio quadrato da
   44, centrato: la misura di Apple, e il segno ci sta dentro. */
.histrow .del {
  position: relative; display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; padding: 0; margin: -10px -10px -10px 0;
  font-family: var(--sans); font-size: var(--t-lbl-lg); color: var(--testo-3); flex-shrink: 0;
}
.histrow .del::after { content: ''; position: absolute; inset: -4px; }
.formrow { padding: var(--s3) 0; }
.formrow .fl { font-size: var(--t-sm); color: var(--testo-2); margin-bottom: 9px; display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.formrow .fl .auto { font-family: var(--sans); font-weight: 600; font-size: var(--t-lbl-xs); letter-spacing: 0; text-transform: none; color: var(--testo-3); }
/* Il selettore a sette: pastiglie tonde su pista tenue. */
.seg7 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.seg7 button { min-height: 46px; border-radius: var(--r-box); background: var(--carta-2); box-shadow: none; font-family: var(--grot); font-weight: 800; font-size: var(--t-rg); color: var(--testo-2); transition: background 0.16s var(--ease), color 0.16s var(--ease); }
.seg7 button.sel { background: var(--pieno); color: var(--su-pieno); }
.formrow textarea, .formrow input[type='text'] {
  width: 100%; background: var(--carta-2); border: none; border-radius: var(--r-box);
  padding: 13px 15px; min-height: 46px; color: var(--testo); font-size: 16px; font-family: inherit;
  outline: none; resize: none; transition: box-shadow 0.24s var(--ease);
}
.formrow textarea:focus, .formrow input:focus { box-shadow: inset 0 0 0 2px var(--pieno); }
.rowout { margin-top: var(--s2); padding: 14px 15px; border: none; border-radius: var(--r-box); background: var(--carta-2); font-family: var(--sans); font-size: var(--t-sm); line-height: 1.7; color: var(--testo-2); word-break: break-word; user-select: text; }

/* ============================================================
   PIANO — la linea del tempo
   ============================================================ */
.tl { position: relative; padding-left: 24px; }
.tl::before { content: ''; position: absolute; left: 5px; top: 10px; bottom: 10px; width: 2px; border-radius: 1px; background: var(--filo); }
.tl-item { position: relative; padding: 0 0 var(--s5); }
.tl-item::before {
  content: ''; position: absolute; left: -24px; top: 4px; width: 12px; height: 12px; border-radius: 50%;
  background: var(--carta); box-shadow: 0 0 0 2px var(--bordo) inset; transition: background 0.3s var(--ease);
}
.tl-item.now::before { background: var(--pieno); box-shadow: none; }
.tl-item.past::before { background: var(--testo-3); box-shadow: none; }
.tl-item .tn { font-family: var(--sans); font-weight: 800; font-size: var(--t-lg); letter-spacing: 0; }
.tl-item .tp { font-family: var(--sans); font-weight: 600; font-size: var(--t-sm); letter-spacing: 0; text-transform: none; color: var(--testo-2); margin-top: 3px; }
.tl-item.now .tp { color: var(--testo-2); font-weight: 500; }
.tl-item .td { font-size: var(--t-sm); color: var(--testo-2); margin-top: 8px; line-height: 1.55; }
.tl-item .now-tag {
  display: inline-block; font-family: var(--sans); font-weight: 700; font-size: var(--t-lbl-xs);
  letter-spacing: 0.03em; text-transform: uppercase;
  background: var(--pieno); color: var(--su-pieno);
  border-radius: var(--r-pill); padding: 4px 9px; margin-left: 8px; vertical-align: 2px;
}
/* Il selettore a tre: la pista grigia con la pastiglia bianca sopra. È il
   segmented control dell'app copiata, quello di "Week · Month · Year". */
.seg {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px;
  background: var(--carta-2); border: none; border-radius: var(--r-box); padding: 4px;
  margin: var(--s3) 0;
}
.core .seg { margin-left: 0; margin-right: 0; }
.core .medals, .core .zonegrid { margin-left: 0; margin-right: 0; }
.seg button { padding: 11px 6px; border-radius: var(--r-chip); background: none; font-size: var(--t-xs); font-weight: 700; color: var(--testo-2); line-height: 1.35; transition: background 0.2s var(--ease), color 0.2s var(--ease), box-shadow 0.2s var(--ease); }
.seg button.sel { background: var(--carta); color: var(--testo); font-weight: 800; box-shadow: var(--ombra); }
.seg button small { display: block; font-family: var(--sans); font-size: var(--t-lbl-xs); font-weight: 600; letter-spacing: 0; margin-top: 4px; color: var(--testo-3); }
.seg button.sel small { color: var(--testo-3); }
.gaterow { display: flex; justify-content: space-between; gap: var(--s4); padding: var(--s3) 0; font-size: var(--t-sm); line-height: 1.5; }
.gaterow .s { color: var(--testo-2); }
.gaterow .a { font-family: var(--sans); font-weight: 800; color: var(--testo); text-align: right; flex-shrink: 0; max-width: 45%; letter-spacing: 0; }
details.fold { border-top: 1px solid var(--filo); }
details.fold summary { list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: var(--s4) 0; font-size: var(--t-rg); font-weight: 700; letter-spacing: 0; cursor: pointer; }
details.fold summary::-webkit-details-marker { display: none; }
/* Il gallone: due lati di un quadrato ruotato. Il glifo `▾` è un carattere di
   testo, cambia forma con la famiglia e non si allinea mai con niente. */
details.fold summary .arr {
  font-size: 0; width: 8px; height: 8px; flex-shrink: 0; margin: -4px 3px 0 0;
  border-right: 2px solid var(--testo-3); border-bottom: 2px solid var(--testo-3);
  transform: rotate(45deg); transition: transform 0.24s var(--ease), margin 0.24s var(--ease);
}
details.fold[open] summary .arr { transform: rotate(-135deg); margin-top: 3px; }
.volrow { display: flex; align-items: center; gap: var(--s3); padding: 11px 0; }
.volrow .vn { font-size: var(--t-sm); width: 96px; flex-shrink: 0; color: var(--testo-2); }
.volrow .vb { flex: 1; height: 10px; border-radius: var(--r-pill); background: var(--traccia-fondo); overflow: hidden; }
.volrow .vb i { display: block; height: 100%; border-radius: var(--r-pill); background: var(--palestra-viva); }
.volrow .vb i.hi { background: var(--peso-viva); }
.volrow .vb i.over { background: var(--danger-viva); }
.volrow .vv { font-family: var(--grot); font-weight: 800; font-size: var(--t-xs); color: var(--testo-2); width: 50px; text-align: right; flex-shrink: 0; }
/* L'interruttore di iOS, che è quello che l'app copiata usa. */
.tgl { position: relative; width: 51px; height: 31px; border-radius: var(--r-pill); background: var(--traccia-fondo); box-shadow: none; flex-shrink: 0; transition: background 0.26s var(--ease); }
.tgl::before { content: ''; position: absolute; inset: -9px; }
.tgl::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 27px; height: 27px; border-radius: 50%;
  background: #FFFFFF; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.22);
  transition: transform 0.26s var(--spring);
}
.tgl.on { background: var(--piatto-viva); }
.tgl.on::after { transform: translateX(20px); }
.tglrow { display: flex; align-items: center; justify-content: space-between; gap: var(--s4); padding: var(--s4) 0; }
.tglrow .t { font-size: var(--t-rg); font-weight: 700; letter-spacing: 0; }
.tglrow .d { font-size: var(--t-sm); color: var(--testo-2); margin-top: 4px; line-height: 1.45; }
.empty { text-align: center; padding: var(--s6) var(--s5); }
.empty .ei { width: 48px; height: 48px; margin: 0 auto var(--s3); border-radius: 50%; background: var(--carta-2); box-shadow: none; display: flex; align-items: center; justify-content: center; font-size: var(--t-md); color: var(--testo-3); }
.empty .et { font-family: var(--sans); font-weight: 800; font-size: var(--t-rg); letter-spacing: 0; }
.empty .ed { font-size: var(--t-sm); color: var(--testo-2); margin-top: 6px; line-height: 1.5; }

/* ============================================================
   IL TIMER DI RECUPERO
   ============================================================ */
.sheet {
  position: fixed; left: 0; right: 0; bottom: var(--nav-h); z-index: 40;
  transform: translateY(calc(100% + var(--nav-h) + 24px)); transition: transform 0.4s var(--ease);
  padding: 0 calc(var(--gut) + env(safe-area-inset-right, 0px)) 10px calc(var(--gut) + env(safe-area-inset-left, 0px)); pointer-events: none;
}
.sheet.on { transform: none; pointer-events: auto; }
.sheet-in {
  /* 🔴 `margin-left: auto` SEMPRE, non solo da ridotto. Con `margin: 0 auto` il
     foglio tornava centrato durante la riapertura e cresceva dai DUE lati: il
     bordo destro si spostava di 23 px a meta' transizione — misurato — ed e'
     quello che si legge come «esce dal centro». Ancorato a destra, esce e
     rientra dallo stesso angolo.
     Su un telefono non cambia nulla a foglio aperto: la larghezza disponibile
     e' sempre sotto i 438 px, quindi il foglio li riempie comunque. */
  max-width: 438px; margin-left: auto; margin-right: 0;
  background: #1C1C1E; color: #FFFFFF;
  border-radius: var(--r-card); padding: 12px 14px;
  box-shadow: var(--ombra-alta);
  display: flex; align-items: center; gap: var(--s3);
}
.ring { position: relative; width: 60px; height: 60px; flex-shrink: 0; }
.ring svg { transform: rotate(-90deg); width: 60px; height: 60px; }
.ring .rtxt { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-family: var(--grot); font-size: var(--t-md); font-weight: 800; letter-spacing: 0; }
.sheet-info { flex: 1; min-width: 0; }
.sheet-info .t { font-family: var(--sans); font-weight: 700; font-size: var(--t-lbl); letter-spacing: 0.01em; text-transform: none; color: var(--testo-2); }
.sheet-info .d { font-size: var(--t-rg); font-weight: 600; margin-top: 3px; line-height: 1.35; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.sheet-acts { display: flex; gap: 6px; flex-shrink: 0; }
.pill {
  min-height: 44px; min-width: 44px; padding: 0 14px; border-radius: var(--r-pill);
  background: color-mix(in oklab, currentColor, transparent 86%); box-shadow: none;
  font-family: var(--sans); font-weight: 700; font-size: var(--t-sm); color: inherit;
  transition: transform 0.15s var(--spring), background 0.2s var(--ease);
}
.pill:active { transform: scale(0.93); }
.pill.tondo { padding: 0; width: 44px; display: flex; align-items: center; justify-content: center; }

/* ---------- IL RECUPERO RIDOTTO ----------
   Ridotto, del foglio resta il solo cerchio col tempo, agganciato a destra
   sopra la barra: continua a correre, continua a suonare alla fine, e smette di
   coprire mezza schermata. Il tocco lo riapre.
   La transizione e' su `width` e `padding` invece che su `transform`, perche' il
   foglio deve davvero LIBERARE lo spazio, non solo sembrare piu' piccolo: con
   una scala il dito continuerebbe a trovare la tessera dove non si vede piu'. */
.sheet.min { pointer-events: none; }
.sheet.min .sheet-in {
  max-width: 76px; margin-left: auto; margin-right: 0;
  padding: 8px; gap: 0; pointer-events: auto;
}
/* 🔴 Vincenzo, 5 settembre: «l'animazione di quando chiudo e apro il timer:
   alla riapertura esce dal centro, invece dovrebbe uscire di nuovo da dove si
   è chiusa, in basso a destra».
   La causa: la transizione era su `max-width` con `margin-left: auto`, quindi
   il foglio si stringeva verso destra ma si RIAPRIVA crescendo da entrambi i
   lati — il centro visivo si spostava, e l'occhio lo legge come «viene dal
   centro». `transform-origin` sull'angolo in basso a destra ancora tutti e due
   i movimenti allo stesso punto: si ritira li' e da li' riesce. */
.sheet-in { transform-origin: 100% 100%; }
.sheet.min .sheet-info, .sheet.min .sheet-acts { display: none; }
/* Ridotto, «2:28» non ci sta dentro i 60 px dell'anello e usciva tagliato dal
   bordo della pastiglia. Il numero scende alla misura che ci entra: la si
   guarda da vicino, non da mezzo metro. */
.sheet.min .ring .rtxt { font-size: 17px; letter-spacing: -0.01em; }
.sheet-in {
  transition: max-width 0.36s var(--ease), padding 0.36s var(--ease);
  will-change: max-width;
}
/* Il bersaglio che riapre: copre tutta la pastiglia ridotta, e sotto il foglio
   aperto non esiste (`display:none`), cosi' non ruba i tocchi ai due bottoni. */
.sheet-riapri {
  position: absolute; right: calc(var(--gut) + env(safe-area-inset-right, 0px));
  bottom: 10px; width: 76px; height: 76px; z-index: 2;
  background: none; box-shadow: none; border-radius: var(--r-card);
  display: none;
}
.sheet.min .sheet-riapri { display: block; pointer-events: auto; }

/* ============================================================
   LA SEDUTA GUIDATA
   ============================================================ */
.guide { position: fixed; inset: 0; z-index: 70; background: var(--fondo); display: none; flex-direction: column; }
/* ---------- LA TESTA DELL'ESERCIZIO ----------
   Nome e «serie 2 di 4» sulla stessa riga: dove sono, e a che punto sono. E'
   la prima domanda che uno si fa alzando gli occhi dal bilanciere, e prima la
   risposta stava a meta' schermata dentro il piede. */
.guide-cap { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.guide-cap h2 { flex: 1; min-width: 0; }
.guide-quante {
  flex-shrink: 0; font-family: var(--sans); font-weight: 600; font-size: var(--t-sm);
  color: var(--testo-2); white-space: nowrap;
}
/* ---------- IL GRAFICO DEI PROGRESSI ----------
   Il top set nel tempo. Piccolo: qui dice una cosa sola — se la linea sale —
   e chi vuole i numeri li ha nella didascalia sotto. */
.exgraf { margin-top: 16px; }
.exgraf svg { display: block; width: 100%; height: 42px; color: var(--palestra); overflow: visible; }
.exgraf-cap {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  margin-top: 8px; font-family: var(--sans); font-size: var(--t-xs); color: var(--testo-3);
}
.exgraf-cap .v { font-variant-numeric: tabular-nums; color: var(--testo-2); font-weight: 600; }
.exgraf-cap .su { color: var(--t-ok); font-weight: 700; }
.exgraf-cap .giu { color: var(--t-danger); font-weight: 700; }
.exgraf-vuoto {
  margin-top: 16px; font-size: var(--t-xs); color: var(--testo-3); line-height: 1.5;
}
/* ---------- LA PROSA, RICHIUSA ----------
   Cinque blocchi di testo in fila diventavano il centro della schermata mentre
   il gesto stava in fondo. Qui stanno dietro una riga sola. */
.guide-piu { margin-top: 18px; border-top: 1px solid var(--filo); }
.guide-piu summary {
  list-style: none; cursor: pointer; display: flex; align-items: center;
  justify-content: space-between; gap: 10px; min-height: 48px;
  font-family: var(--sans); font-weight: 600; font-size: var(--t-sm); color: var(--testo-2);
}
.guide-piu summary::-webkit-details-marker { display: none; }
.guide-piu summary .arr { transition: transform 0.24s var(--ease); color: var(--testo-3); }
.guide-piu[open] summary .arr { transform: rotate(180deg); }
.guide-piu[open] summary { color: var(--testo); }
.guide-piu > *:last-child { padding-bottom: var(--s4); }
.guide.on { display: flex; animation: sectIn 0.3s var(--ease); }
.guide-top { padding: calc(env(safe-area-inset-top, 0px) + 14px) var(--gut) 10px; }
.guide-prog { display: flex; gap: 4px; margin-bottom: 14px; }
.guide-prog i { flex: 1; height: 5px; border-radius: var(--r-pill); background: var(--traccia-fondo); }
.guide-prog i.done { background: var(--peso-viva); }
.guide-prog i.cur { background: var(--pieno); }
.guide-meta { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); }
.guide-meta .k { font-family: var(--sans); font-weight: 700; font-size: var(--t-sm); letter-spacing: 0.01em; text-transform: none; color: var(--testo-2); }
.guide-close { position: relative; width: 34px; height: 34px; border-radius: 50%; background: var(--carta); box-shadow: var(--ombra); display: flex; align-items: center; justify-content: center; color: var(--testo-2); flex-shrink: 0; }
.guide-close::before { content: ''; position: absolute; inset: -8px; }
/* 🔴 `justify-content: safe center` centrava TUTTO in verticale. Sul
   riscaldamento va bene — c'e' poco, e il cronometro al centro si guarda da
   lontano. Sull'esercizio no: il nome galleggiava a meta' schermo con 370 px di
   vuoto sopra, e la prima cosa che si cerca alzando gli occhi dal bilanciere
   stava dove non la si cerca. Di regola si parte dall'alto; il centraggio resta
   dove serve, dietro una classe. */
.guide-body { flex: 1; overflow-y: auto; padding: var(--s3) var(--gut) var(--s2); -webkit-overflow-scrolling: touch; display: flex; flex-direction: column; justify-content: flex-start; overscroll-behavior: contain; }
.guide-body.centra { justify-content: safe center; }
.guide-body .cuebox { margin-top: var(--s5); }
.guide-body h2 { font-family: var(--sans); font-weight: 800; font-size: var(--t-rom); letter-spacing: 0; line-height: 1.04; margin-top: var(--s3); }
.guide-target { display: flex; align-items: baseline; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.guide-target .tg { font-family: var(--grot); font-weight: 800; font-size: var(--t-t3); letter-spacing: 0; color: var(--testo); }
.guide-target .tsub { font-size: var(--t-sm); color: var(--testo-2); }
.guide-prev { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s3); margin-top: var(--s4); padding: 13px 15px; border: none; border-radius: var(--r-box); background: var(--carta-2); }
.guide-prev .k { font-family: var(--sans); font-weight: 600; font-size: var(--t-sm); letter-spacing: 0; text-transform: none; color: var(--testo-2); }
.guide-prev .v { font-family: var(--grot); font-weight: 800; font-size: var(--t-t3); letter-spacing: 0; color: var(--testo); text-align: right; }
.setdots { display: flex; gap: var(--gap); margin: var(--s5) 0 var(--s1); }
.setdot {
  flex: 1; min-width: 0; padding: 10px 8px 11px; text-align: left; display: block; width: 100%;
  font: inherit; color: inherit; background: var(--pastiglia); border-radius: var(--r-chip);
  border-bottom: 3px solid transparent; transition: border-color 0.3s var(--ease), background 0.3s var(--ease);
}
.setdot .sn { font-family: var(--sans); font-weight: 600; font-size: var(--t-lbl-xs); letter-spacing: 0; color: var(--testo-3); }
.setdot .sn .x { margin-left: 5px; opacity: 0; transition: opacity 0.2s var(--ease); }
button.setdot:active .sn .x { opacity: 1; }
button.setdot:active { transform: scale(0.94); }
.setdot .sv { font-family: var(--grot); font-weight: 800; font-size: var(--t-md); margin-top: 4px; color: var(--testo-3); letter-spacing: 0; white-space: nowrap; }
.setdot .sv i { font-style: normal; opacity: 0.6; margin: 0 1px; }
.setdot.done { border-bottom-color: var(--pieno); background: var(--pastiglia); }
.setdot.done .sv { color: var(--testo); }
.setdot.cur { border-bottom-color: var(--pieno); }
.setdot.cur .sn { color: var(--testo); font-weight: 700; }
.guide-foot { padding: 12px var(--gut) calc(env(safe-area-inset-bottom, 0px) + 14px); border-top: 1px solid var(--filo); background: var(--fondo); }
.guide-foot .row { display: flex; gap: var(--gap); }
.guide-foot .row .btn { flex: 1; }
.guide-rest {
  display: flex; align-items: center; gap: var(--s3); padding: 13px 15px; border-radius: var(--r-box);
  background: var(--g-palestra); color: var(--testo);
  margin-bottom: 10px; animation: sectIn 0.3s var(--ease);
}
.guide-rest .rn { font-family: var(--grot); font-weight: 800; font-size: var(--t-t2); letter-spacing: 0; min-width: 66px; }
.guide-rest .rl { flex: 1; font-size: var(--t-sm); line-height: 1.4; color: var(--testo-2); }

/* ============================================================
   LA CELEBRAZIONE
   ============================================================ */
.burst { position: fixed; inset: 0; z-index: 90; pointer-events: none; display: flex; align-items: center; justify-content: center; opacity: 0; padding: var(--gut); }
.burst.on { animation: burstIn 1.5s var(--ease); }
.burst .bcard {
  text-align: center; padding: 26px 32px; border-radius: var(--r-card);
  background: var(--carta); color: var(--testo); box-shadow: var(--ombra-alta);
}
.burst .bi {
  display: flex; align-items: center; justify-content: center;
  width: 64px; height: 64px; margin: 0 auto; border-radius: 50%;
  background: var(--pastiglia); color: var(--testo);
  font-size: 22px; font-weight: 800; letter-spacing: 0; line-height: 1;
}
.burst .bt { font-family: var(--sans); font-weight: 800; font-size: var(--t-t3); letter-spacing: 0; margin-top: 10px; }
.burst .bd { font-size: var(--t-rg); margin-top: 6px; color: var(--testo-2); }
@keyframes burstIn {
  0% { opacity: 0; transform: scale(0.88); }
  14% { opacity: 1; transform: scale(1.02); }
  22% { transform: scale(1); }
  78% { opacity: 1; }
  100% { opacity: 0; transform: scale(0.98); }
}

/* Le due spunte del giorno: una riga, due pastiglie, dieci secondi. */
.spunta-riga { display: flex; align-items: center; gap: var(--s3); padding: 14px 0; }
.spunta-t { flex: 1; min-width: 0; }
.spunta-t .t { font-family: var(--sans); font-weight: 500; font-size: var(--t-rg); color: var(--testo); }
.spunta-t .d { font-size: var(--t-sm); color: var(--testo-3); line-height: 1.45; margin-top: 3px; }
.spunta-b { display: flex; gap: 6px; flex-shrink: 0; }
.spunta-b .pill {
  /* 46 e non 44: il minimo di Apple e' 44, ma un flex con l'altezza al minimo
     esatto misura 43,99 e il banco lo segnala. Sopra la riga, non sulla riga. */
  min-width: 52px; min-height: 46px; padding: 0 14px; border-radius: var(--r-pill);
  background: var(--pastiglia); color: var(--testo);
  font-family: var(--sans); font-weight: 500; font-size: var(--t-sm);
  display: flex; align-items: center; justify-content: center;
}
.spunta-b .pill.sel { background: var(--pieno); color: var(--su-pieno); font-weight: 600; }

/* Il riscaldamento guidato: il cronometro grande e le due righe della rampa. */
.warm-clock {
  font-family: var(--grot); font-weight: 800; font-size: var(--t-rom);
  letter-spacing: 0; line-height: 1; margin-top: 18px;
  font-variant-numeric: tabular-nums;
}
.warm-riga {
  display: flex; align-items: baseline; gap: 12px; padding: 14px 0;
  font-size: var(--t-sm); color: var(--testo-2);
}
.warm-riga .k { font-weight: 700; color: var(--testo); min-width: 62px; }
.warm-riga .v { font-family: var(--grot); font-weight: 800; font-size: var(--t-lg); color: var(--testo); }
.warm-riga .d { flex: 1; text-align: right; }

/* Il riferimento all'esecuzione. Tre stati, e li decide il registro: in evidenza
   finche' non l'ha fatto tre volte, poi un punto interrogativo, e di nuovo in
   evidenza se l'esercizio manca da piu' di sei settimane. */
.rif {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 10px;
  padding: 9px 13px; border-radius: var(--r-box);
  background: var(--pastiglia); color: var(--testo);
  font-family: var(--sans); font-weight: 500; font-size: var(--t-sm); text-decoration: none;
}
.rif.nuovo, .rif.dimenticato { background: var(--avviso, #FFDAD0); font-weight: 600; }
.rif-a { opacity: 0.55; }
.rif-min {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 50%; vertical-align: middle;
  background: var(--pastiglia); color: var(--testo-2); text-decoration: none;
  font-family: var(--sans); font-weight: 600; font-size: var(--t-sm);
  margin-left: 8px;
}

/* La frase della serie: calcolata dal suo registro, e assente quando non c'e'
   niente di vero da dire. Sta sopra il consiglio di carico perche' e' quello che
   si legge mentre si carica il bilanciere. */
.guide-frase {
  margin: 16px 0 0; padding: 12px 14px; border-radius: var(--r-box);
  background: var(--pastiglia); color: var(--testo);
  font-family: var(--sans); font-weight: 500; font-size: var(--t-md); line-height: 1.45;
}

/* ============================================================
   IL TORNELLO
   Il codice della palestra, grande quanto lo schermo. Fondo BIANCO e non della
   pagina: un lettore da tornello legge meglio su bianco pieno, e la luminanza
   massima si chiede al sistema mentre e' aperto. Nessuna decorazione: qui si
   viene per due secondi, col telefono in una mano e il borsone nell'altra.
   ============================================================ */
.tornello {
  position: fixed; inset: 0; z-index: 92; display: none;
  flex-direction: column; background: #FFFFFF; color: #000000;
  padding: max(env(safe-area-inset-top, 0px), 12px) 16px max(env(safe-area-inset-bottom, 0px), 16px);
}
.tornello.on { display: flex; }
.tor-top { display: flex; align-items: center; justify-content: space-between; min-height: 44px; }
.tor-top .k { font-family: var(--sans); font-weight: 500; font-size: var(--t-sm); color: #666666; }
.tor-close {
  width: 44px; height: 44px; border-radius: var(--r-pill); background: #E9E9E9; color: #000000;
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.tor-mid { flex: 1; display: flex; align-items: center; justify-content: center; min-height: 0; }
/* Il codice occupa il lato corto meno i margini, e non si stira mai: un QR
   deformato non si legge. */
/* Il codice prende tutto il lato corto meno i margini: davanti al lettore, piu'
   grande e' e meno tentativi servono. Il quadrato non si stira mai. */
.tor-mid svg { width: 100%; max-width: min(100%, 70vh); height: auto; display: block; margin: 0 auto; }
.tor-mid .vuoto { max-width: 320px; text-align: center; }
.tor-mid .vuoto h2 { font-family: var(--sans); font-weight: 700; font-size: var(--t-t3); margin-bottom: 10px; }
.tor-mid .vuoto p { font-size: var(--t-sm); color: #666666; line-height: 1.5; }
.tor-foot { padding-top: 14px; display: grid; gap: 10px; }

/* ---------- IL TORNELLO IN LUCE SCURA ----------
   Il pannello era cablato bianco anche di notte: aprirlo alle 22 era una
   frustata negli occhi, e Vincenzo l'ha chiesto scuro. Il pannello lo diventa;
   il CODICE no, e resta su una tessera chiara — la ragione sta nel commento di
   `torInverso` in app.js, e non e' estetica: e' che i lettori fissi da tornello
   vogliono moduli scuri su fondo chiaro. Chi vuole provare l'inverso ha il suo
   bottone, e torna indietro con lo stesso tocco. */
.tornello[data-luce='scura'] { background: #141414; color: #FFFFFF; }
.tornello[data-luce='scura'] .tor-top .k { color: #A5A5A5; }
.tornello[data-luce='scura'] .tor-close { background: #333333; color: #FFFFFF; }
.tornello[data-luce='scura'] .tor-mid .vuoto p,
.tornello[data-luce='scura'] .nota { color: #A5A5A5; }
/* La tessera sotto il codice. ⚠ Non serve alla zona di quiete: quella ce l'ha
   gia' l'SVG, che nasce con `bordo: 4` come vuole la norma. Serve perche' sul
   fondo scuro fa da ISOLA CHIARA e rende il simbolo trovabile — misurato
   rimpicciolendo lo screenshot finche' un lettore vero smette di leggere:
   scura con tessera 40 px di lato, chiara senza 45. Cinque pixel di margine in
   piu', che davanti a un tornello sono un tentativo in meno.
   Quando il codice e' invertito la tessera sparisce, altrimenti gli girerebbe
   attorno un bordo chiaro che il lettore scambia per la fine del dato. */
.tornello[data-luce='scura'] .tor-mid svg {
  background: #FFFFFF; border-radius: 12px; padding: 10px;
}
.tornello.inverso .tor-mid svg { background: transparent; padding: 0; }

/* La riga del codice in chiaro, sotto il QR. E' quella che permette di
   confrontarlo con qualunque altro lettore senza credere a me sulla parola. */
.tor-letto {
  display: grid; gap: 4px; text-align: center;
  padding: 12px 14px; border-radius: var(--r-box);
  background: #F6F6F6;
}
.tornello[data-luce='scura'] .tor-letto { background: #1F1F1F; }
.tor-letto b {
  font-family: var(--grot); font-weight: 800; line-height: 1.25;
  font-variant-numeric: tabular-nums; word-break: break-all;
  /* La spaziatura fra i caratteri serve a leggerlo UNO A UNO quando lo si
     confronta con un altro schermo, ed e' il motivo per cui questa riga esiste.
     Ma un codice lungo, spaziato, va a capo in mezzo a se stesso e diventa piu'
     difficile da confrontare, non piu' facile: oltre i 16 caratteri la
     spaziatura cede e il corpo scende, cosi' resta su una riga sola. */
  /* `pre-wrap`: senza, uno spazio in coda si disegna largo ESATTAMENTE quanto
     un codice senza — misurato 168,6 px in tutti e due i casi. Due codici
     diversi, indistinguibili sul vetro, proprio nella riga che serve a
     confrontarli. Non basta da solo (uno spazio resta bianco su bianco), ed e'
     per questo che la riga sopra li NOMINA. */
  white-space: pre-wrap;
  font-size: var(--corpo-codice, 22px);
  letter-spacing: var(--spazio-codice, 0.16em);
}
.tor-letto[data-lungo='1'] { --corpo-codice: 17px; --spazio-codice: 0.08em; }
.tor-letto[data-lungo='2'] { --corpo-codice: 14px; --spazio-codice: 0.04em; }
.tor-letto .e { font-family: var(--sans); font-size: 12px; font-weight: 500; color: #666666; line-height: 1.4; }
.tornello[data-luce='scura'] .tor-letto .e { color: #A5A5A5; }
/* Il guasto non si annuncia col colore soltanto: chi non lo distingue leggerebbe
   una riga qualunque. Il testo dice «non fidarti», e il bordo lo sottolinea. */
.tor-letto.guasto { background: var(--avviso, #FFDAD0); box-shadow: inset 0 0 0 2px #A81D33; }
/* L'avviso del codice invertito: giallo, non rosso. Il contenuto e' giusto —
   sbagliata e' la polarita' — e confonderlo con un guasto vero farebbe ignorare
   entrambi. Anche qui il segno non e' solo il colore: c'e' scritto. */
.tor-letto.avviso { background: var(--g-piano, #FFDF98); box-shadow: inset 0 0 0 2px #8A5600; color: #000000; }
.tor-letto.avviso .e { color: #8A5600; font-weight: 700; }
.tornello[data-luce='scura'] .tor-letto.avviso { background: #3A2A00; color: #FFFFFF; }
.tornello[data-luce='scura'] .tor-letto.avviso .e { color: #FED15F; }
/* Il campo di confronto: incolla e chiedi, senza toccare il codice salvato. */
/* ---------- IL PIEDE RIDOTTO ----------
   Vincenzo, 4 settembre: «volevo che si vedesse solamente il QR Code senza
   ulteriori dettagli. Magari sì, metti un pulsantino, ma un piccolino».
   Quindi qui non c'e' un `.btn`: c'e' un tasto piccolo, grigio, che non chiede
   attenzione. L'area sensibile resta da 44 px con l'espansore, perche' piccolo
   riguarda l'aspetto, non il bersaglio del dito. */
.tor-min { display: flex; justify-content: center; gap: 18px; padding-top: 4px; }
.tor-cambia {
  position: relative;
  font-family: var(--sans); font-weight: 500; font-size: var(--t-sm);
  color: #767676; background: none; box-shadow: none; padding: 6px 2px;
  transition: color 0.2s var(--ease);
}
.tor-cambia::after { content: ''; position: absolute; inset: -12px -10px; }
.tor-cambia:active { color: var(--testo); }
.tornello[data-luce='scura'] .tor-cambia { color: #A5A5A5; }
.tornello[data-luce='scura'] .tor-cambia:active { color: #FFFFFF; }
.tor-avviso {
  text-align: center; font-family: var(--sans); font-size: var(--t-xs);
  font-weight: 600; color: #8A5600; padding: 8px 12px;
  background: var(--g-piano, #FFDF98); border-radius: var(--r-box);
}
.tornello[data-luce='scura'] .tor-avviso { background: #3A2A00; color: #FED15F; }

.tor-confronto { display: grid; grid-template-columns: 1fr auto; gap: 8px; }
.tor-confronto input {
  min-height: 46px; padding: 0 14px; border-radius: var(--r-box); border: none;
  background: #F6F6F6; color: #000000;
  font-family: var(--sans); font-size: var(--t-sm);
  box-shadow: inset 0 0 0 1px #E9E9E9;
}
.tor-confronto input:focus { box-shadow: inset 0 0 0 2px #000000; outline: none; }
.tornello[data-luce='scura'] .tor-confronto input {
  background: #1F1F1F; color: #FFFFFF; box-shadow: inset 0 0 0 1px #4B4B4B;
}
.tornello[data-luce='scura'] .tor-confronto input:focus { box-shadow: inset 0 0 0 2px #FFFFFF; }
.tor-confronto .btn { width: auto; padding: 0 18px; }
.tor-letto.guasto .e { color: #A81D33; font-weight: 700; }
.tornello[data-luce='scura'] .tor-letto.guasto { background: #4A2A22; }
.tornello[data-luce='scura'] .tor-letto.guasto .e { color: #FF8496; }
.tor-azioni { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.tornello[data-luce='scura'] .btn.ghost { background: #333333; color: #FFFFFF; }

/* ============================================================
   L'ACCESSO — la porta, prima di tutto il resto
   Copre lo schermo intero e sta sopra ogni altro strato: finche' non si e'
   entrati non c'e' niente da vedere. Stessa grammatica del resto dell'app —
   fondo carta, tessera bianca, nero come unico stato attivo.
   ============================================================ */
.accesso {
  position: fixed; inset: 0; z-index: 99;
  display: flex; align-items: center; justify-content: center;
  padding: 24px calc(var(--gut) + env(safe-area-inset-right, 0px));
  background: var(--fondo);
  visibility: hidden; opacity: 0;
  transition: opacity 0.3s var(--ease), visibility 0s linear 0.3s;
}
.accesso.on { visibility: visible; opacity: 1; transition-delay: 0s; }
.acc-in { width: 100%; max-width: 340px; text-align: center; }
.acc-marchio { display: flex; justify-content: center; margin-bottom: 22px; }
.acc-marchio svg { width: 56px; height: 56px; display: block; }
.accesso h1 {
  font-family: var(--sans); font-weight: 800; font-size: var(--t-t2);
  letter-spacing: 0; line-height: 1.1; margin: 0;
}
.acc-d {
  margin: 10px 0 26px; font-size: var(--t-sm); line-height: 1.55; color: var(--testo-2);
}
.acc-corpo { display: grid; gap: 10px; }
.acc-corpo input {
  width: 100%; min-height: 56px; padding: 0 16px; border: none; border-radius: var(--r-box);
  background: var(--carta); color: var(--testo); text-align: center;
  font-family: var(--grot); font-weight: 800; font-size: var(--t-t3);
  letter-spacing: 0.22em; font-variant-numeric: tabular-nums;
  box-shadow: inset 0 0 0 1px var(--filo);
}
.acc-corpo input::placeholder { letter-spacing: 0.06em; font-size: var(--t-rg); font-weight: 500; color: var(--testo-3); }
.acc-corpo input:focus { outline: none; box-shadow: inset 0 0 0 2px var(--pieno); }
.acc-nota {
  margin-top: 18px; font-size: var(--t-xs); line-height: 1.5; color: var(--testo-3);
  min-height: 32px;
}
.acc-nota.male { color: var(--t-danger); font-weight: 600; }
.acc-nota.bene { color: var(--t-ok); font-weight: 600; }
.acc-altro {
  margin-top: 4px; background: none; box-shadow: none; min-height: 44px;
  font-family: var(--sans); font-weight: 500; font-size: var(--t-sm); color: var(--testo-3);
}

/* ============================================================
   IL DIALOGO DELL'APP — al posto del `confirm()` di iPhone
   La geometria e' quella misurata del dialogo del riferimento: raggio 16 su
   TUTTI E QUATTRO gli angoli (a differenza del foglio dal basso, che ce l'ha
   solo in alto), velo scuro, e le due azioni affiancate con la primaria a
   destra — dove sta il pollice.
   ============================================================ */
.dlg {
  position: fixed; inset: 0; z-index: 96;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background: rgba(0, 0, 0, 0.4);
  opacity: 0; pointer-events: none;
  /* 🔴 `visibility: hidden` oltre all'opacita' zero. Con la sola opacita' il
     dialogo chiuso resta nell'albero: il banco del contrasto ne misurava i
     bottoni contro la pagina sotto — «Va bene» nero su #1F1F1F, 1,27 — e un
     lettore di schermo lo avrebbe letto ad alta voce in mezzo alla schermata,
     su una domanda che nessuno ha fatto. Non era un falso positivo del banco:
     era un difetto vero, trovato guardando i pixel. */
  visibility: hidden;
  transition: opacity 0.24s var(--ease), visibility 0s linear 0.24s;
}
.dlg.on { opacity: 1; pointer-events: auto; visibility: visible; transition-delay: 0s; }
.dlg-in {
  width: 100%; max-width: 340px;
  background: var(--carta); color: var(--testo);
  border-radius: 16px; padding: 22px 20px 16px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.28);
  transform: scale(0.94); opacity: 0;
  transition: transform 0.28s var(--spring), opacity 0.2s var(--ease);
  max-height: 84vh; overflow-y: auto; overscroll-behavior: contain;
}
.dlg.on .dlg-in { transform: none; opacity: 1; }
.dlg-t {
  font-family: var(--sans); font-weight: 800; font-size: var(--t-t3);
  line-height: 1.25; letter-spacing: 0;
}
.dlg-d {
  margin-top: 8px; font-size: var(--t-sm); line-height: 1.55; color: var(--testo-2);
  white-space: pre-line;
}
.dlg-d:empty { display: none; }
.dlg-acts { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 20px; }
.dlg-acts .btn { width: 100%; min-height: 48px; font-size: var(--t-rg); }
/* La domanda che distrugge qualcosa non ha il tasto nero: ce l'ha rosso, e la
   differenza si vede prima di leggere. */
.dlg.pericolo .dlg-acts .btn:not(.ghost) { background: var(--danger); color: #FFFFFF; }
/* Un solo tasto quando non c'e' niente da annullare: e' un avviso, non una
   domanda, e due bottoni identici farebbero esitare su una scelta che non c'e'. */
.dlg.solo .dlg-acts { grid-template-columns: 1fr; }
.dlg.solo #dlg-no { display: none; }

/* Il dialogo con i campi: correggere una serie e' un gesto solo, quindi i due
   numeri stanno dentro la domanda invece che dietro un secondo passaggio. */
.dlg.campi .dlg-d { color: var(--testo); }
.dlg-campi { display: grid; gap: 10px; margin-top: 4px; }
.dlg-campo {
  display: flex; align-items: center; gap: 10px;
  background: var(--carta-2); border-radius: var(--r-box); padding: 0 14px;
  min-height: 52px;
}
.dlg-campo span { font-family: var(--sans); font-size: var(--t-sm); font-weight: 600; color: var(--testo-2); flex-shrink: 0; }
.dlg-campo i {
  font-style: normal; font-family: var(--sans); font-size: var(--t-sm);
  font-weight: 600; color: var(--testo-3); flex-shrink: 0;
}
.dlg-campo input {
  flex: 1; min-width: 0; border: none; background: none; text-align: right;
  font-family: var(--grot); font-weight: 800; font-size: var(--t-lg);
  color: var(--testo); font-variant-numeric: tabular-nums;
  min-height: 44px; padding: 0;
}
.dlg-campo input:focus { outline: none; }
.dlg-campo:focus-within { box-shadow: inset 0 0 0 2px var(--pieno); }
/* Eliminare e' l'azione rara e distruttiva: sta sotto, in rosso, e non compete
   coi due bottoni della riga — che sono «salva» e «lascia com'e'». */
.dlg-elimina {
  display: block; width: 100%; margin-top: 14px; min-height: 44px;
  font-family: var(--sans); font-size: var(--t-sm); font-weight: 600;
  color: var(--t-danger, #A81D33); background: none;
}
.dlg-elimina:active { opacity: 0.6; }

/* ============================================================
   LE DUE LISTE — foglio dal basso
   La geometria e' quella misurata del foglio modale: raggio 16 sui SOLI angoli
   alti, il resto squadrato contro il fondo dello schermo.
   ============================================================ */
.musicasheet {
  position: fixed; inset: 0; z-index: 92;
  display: flex; align-items: flex-end;
  background: rgba(0, 0, 0, 0.4);
  opacity: 0; pointer-events: none;
  visibility: hidden;                 /* stessa ragione del dialogo, qui sopra */
  transition: opacity 0.3s var(--ease), visibility 0s linear 0.3s;
}
.musicasheet.on { opacity: 1; pointer-events: auto; visibility: visible; transition-delay: 0s; }
.ms-in {
  width: 100%; max-width: 438px; margin: 0 auto;
  background: var(--carta); color: var(--testo);
  border-radius: 16px 16px 0 0;
  padding: 12px 16px max(env(safe-area-inset-bottom, 0px), 16px);
  transform: translateY(100%); transition: transform 0.36s var(--ease);
  max-height: 86vh; overflow-y: auto;
}
.musicasheet.on .ms-in { transform: none; }
/* Ogni strato contiene il PROPRIO scorrimento: senza, arrivato in fondo alla
   sua lista il gesto prosegue sulla pagina sotto, e sembra che l'app abbia due
   fondi. `contain` ferma la catena senza togliere lo scorrimento interno. */
.ms-in, .tor-foot, .guide-body, .dlg-in { overscroll-behavior: contain; }
.ms-top { display: flex; align-items: center; justify-content: space-between; min-height: 44px; }
.ms-top .k { font-family: var(--sans); font-weight: 500; font-size: var(--t-sm); color: var(--testo-2); }
.ms-body { padding-top: 6px; display: grid; gap: 10px; }
.ms-lista {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  background: var(--carta-2); border-radius: var(--r-box); padding: 14px;
  box-shadow: none; min-height: 64px;
  transition: background 0.26s var(--ease);
}
.ms-lista:active { background: var(--filo); transition-duration: 0.04s; }
.ms-lista .msi {
  width: 40px; height: 40px; border-radius: var(--r-box); flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--tinta, var(--pieno)); color: var(--su-pieno);
}
.ms-lista .mst { flex: 1; min-width: 0; }
.ms-lista .mst b { display: block; font-family: var(--sans); font-weight: 700; font-size: var(--t-rg); }
.ms-lista .mst span { display: block; font-size: var(--t-xs); color: var(--testo-2); margin-top: 3px; line-height: 1.4; }
.ms-nota { font-size: var(--t-xs); color: var(--testo-2); line-height: 1.5; padding: 2px 2px 4px; }
.ms-body input {
  width: 100%; min-height: 46px; padding: 0 14px; border-radius: var(--r-box);
  background: var(--carta-2); color: var(--testo);
  font-family: var(--sans); font-size: var(--t-sm); border: none;
  box-shadow: inset 0 0 0 1px var(--filo);
}
.ms-body input:focus { box-shadow: inset 0 0 0 2px var(--pieno); outline: none; }
.tor-foot .btn { background: #000000; color: #FFFFFF; }
.tor-foot .btn.ghost { background: #E9E9E9; color: #000000; }
.tor-foot input {
  width: 100%; min-height: 56px; border: none; border-radius: var(--r-box);
  background: #E9E9E9; color: #000000; padding: 0 14px;
  font-family: var(--sans); font-size: var(--t-lg); outline: none;
}
.tor-foot input:focus { box-shadow: inset 0 0 0 2px #000000; }
.tor-foot .nota { font-size: var(--t-sm); color: #666666; line-height: 1.5; }

/* ============================================================
   LA CORSA GUIDATA
   ============================================================ */
.runmode { position: fixed; inset: 0; z-index: 80; background: var(--fondo); display: none; flex-direction: column; padding: calc(18px + env(safe-area-inset-top, 0px)) var(--gut) calc(18px + env(safe-area-inset-bottom, 0px)); }
.runmode.on { display: flex; animation: sectIn 0.3s var(--ease); }
.runmode .rm-top { display: flex; justify-content: space-between; align-items: center; font-family: var(--sans); font-weight: 700; font-size: var(--t-sm); letter-spacing: 0.01em; text-transform: none; color: var(--testo-2); padding-bottom: 12px; border-bottom: 1px solid var(--filo); }
.runmode .rm-mid { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; }
.runmode .rm-phase { font-family: var(--sans); font-weight: 700; font-size: var(--t-lbl-md); letter-spacing: 0.06em; text-transform: uppercase; color: var(--testo-3); transition: color 0.3s var(--ease); }
.runmode.running .rm-phase { color: var(--t-rotta); }
.runmode .rm-clock { font-family: var(--grot); font-weight: 800; font-size: 72px; letter-spacing: 0; line-height: 1; }
.runmode .rm-sub { font-size: var(--t-rg); color: var(--testo-2); text-align: center; }
.runmode .rm-int { display: flex; gap: 5px; margin-top: var(--s4); flex-wrap: wrap; justify-content: center; max-width: 250px; }
.runmode .rm-int i { width: 16px; height: 6px; border-radius: var(--r-pill); background: var(--traccia-fondo); }
.runmode .rm-int i.done { background: var(--peso-viva); }
.runmode .rm-int i.cur { background: var(--pieno); }
.runmode .rm-acts { display: flex; gap: var(--gap); }
.runmode .rm-acts .btn { flex: 1; }

/* ============================================================
   IL MESSAGGIO
   ============================================================ */
#toast {
  position: fixed; left: 50%; bottom: calc(var(--nav-h) + 16px); z-index: 95;
  transform: translate(-50%, 22px); opacity: 0; pointer-events: none;
  background: #1C1C1E; color: #FFFFFF;
  font-size: var(--t-rg); font-weight: 700; padding: 13px 20px; border-radius: var(--r-pill);
  box-shadow: var(--ombra-alta);
  transition: opacity 0.3s var(--ease), transform 0.34s var(--spring);
  white-space: nowrap; max-width: 90vw; overflow: hidden; text-overflow: ellipsis;
}
#toast.on { opacity: 1; transform: translate(-50%, 0); }
body.in-guide #toast { bottom: calc(env(safe-area-inset-bottom, 0px) + 280px); }

/* ============================================================
   LA BARRA DELLE SCHEDE
   🔴 La pillola che galleggia e' revocata insieme al sistema che la conteneva.
   Nel riferimento la barra e' PIENA, appoggiata al fondo, alta 56 con 34 di area
   sicura sotto (90 in tutto, misurati), senza vetro, senza raggio e senza
   pastiglia che scorre. La voce scelta si distingue per l'INCHIOSTRO NERO, non
   per un fondo colorato: e' la stessa regola che vale in tutta l'app.
   E i due neri della scheda attiva sono DUE, misurati: l'etichetta e' #000000
   esatto (443 pixel contati sulla 174), l'icona e' #0D0D0D (zero pixel neri,
   minimo di canale 5). Chi li unifica ne sbaglia uno.
   ============================================================ */
nav {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
  background: var(--carta);
  padding: 0 env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
  border: none;
}
.nav-in {
  position: relative; max-width: 438px; margin: 0 auto;
  display: grid; grid-template-columns: repeat(5, 1fr);
  background: none; border-radius: 0; padding: 0;
  box-shadow: none;
}
/* La pastiglia che scorreva non esiste piu': resta l'elemento, spento, perche'
   app.js lo cerca e gli scrive dentro due variabili. */
#nav-mark { display: none; }
/* 🔴 Qui la copia si ferma una seconda volta, e per lo stesso motivo della
   prima. L'etichetta della scheda spenta nel riferimento e' #9E9E9E, che sul
   bianco da' 2,68 e non passa; l'icona e' #A7A7A7, 2,42. Sono valori misurati e
   sono inaccessibili. Qui vivono i due grigi misurati che passano: #666666 per
   l'etichetta (5,31) e #767676 per l'icona (4,54), che nel riferimento sono
   l'inchiostro delle liste e quello delle didascalie. La forma e' la loro, il
   contrasto e' il nostro. */
nav button {
  position: relative; z-index: 2;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  min-height: var(--nav-pill); color: var(--testo-3); border-radius: 0;
  font-family: var(--sans); font-weight: 500; font-size: var(--t-nav); letter-spacing: 0; text-transform: none;
  box-shadow: none; background: none;
}
nav button svg {
  width: 26px; height: 26px; color: var(--testo-3);
  transition: color 0.24s var(--ease), transform 0.34s var(--spring);
}
/* 🔴 QUI LA COPIA SI FERMA UNA TERZA VOLTA, ED È UNA SCELTA DI VINCENZO.
   Nel riferimento la scheda attiva e' NERA: non c'e' un accento primario in
   tutte e 335 le schermate. Il 3 settembre ha chiesto l'opposto — «quando è off
   sia di un grigino e quando ci clicco sopra diventi colorata, non bianca-nera».
   Quindi questa e' una deroga dichiarata, non una svista: la barra e' l'unico
   posto dell'app dove il colore fa da STATO invece che da dato. Dentro le
   schermate la regola nera regge, e chi la tocca la' sta sbagliando.
   Il colore non e' decorativo: e' quello del dominio, lo stesso che porta la
   barra della misura dentro la vista. Cosi' la scheda accesa dice due cose in
   un colpo — dove sei, e di che cosa parla il posto dove sei. */
nav button.on { color: var(--tinta-nav, var(--testo)); }
nav button.on svg { color: var(--tinta-nav, var(--testo)); transform: translateY(-1px); }
/* Le tinte sono le `--t-*`, non le `--palestra/--piatto/…` nude: l'etichetta e' un
   testo di 11 px, e le tinte nude su bianco stanno fra 1,59 (ambra) e 3,33
   (viola), cioe' tutte sotto la soglia. Le `--t-*` sono le stesse tinte gia'
   portate al contrasto, e valgono in tutte e due le luci — misurato: dieci
   accoppiate su dieci fra 6,14 e 11,38, con l'ambra nuda a 1,59 come
   controprova che il conto misura davvero qualcosa. */
nav button[data-nav=oggi]  { --tinta-nav: var(--t-peso); }
nav button[data-nav=dieta] { --tinta-nav: var(--t-piatto); }
nav button[data-nav=peso]  { --tinta-nav: var(--t-palestra); }
nav button[data-nav=rotta] { --tinta-nav: var(--t-rotta); }
nav button[data-nav=piano] { --tinta-nav: var(--t-piano); }
/* Il colore non puo' essere il SOLO segno di quale scheda e' accesa: chi non
   distingue quel verde da quel grigio resterebbe senza risposta. Il secondo
   canale e' il peso dell'etichetta, che non costa spazio — un pallino sopra
   l'icona, provato, in 56 px di altezza finiva addosso al glifo. */
nav button.on { font-weight: 700; }
nav button:active { opacity: 0.6; }
nav button:active svg { transform: scale(0.88); }

/* ============================================================
   IL PIEDE
   ============================================================ */
.sitelink {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  min-height: 52px; margin-top: var(--s5); text-decoration: none; border-radius: var(--r-box);
  background: var(--carta); box-shadow: var(--ombra); color: var(--testo-2);
  font-family: var(--sans); font-weight: 700; font-size: var(--t-rg);
  transition: transform 0.2s var(--ease);
}

.sitelink svg { width: 14px; height: 14px; }
.colophon { display: flex; align-items: center; justify-content: center; gap: 8px; text-align: center; margin-top: var(--s5); padding-top: var(--s3); border: none; font-family: var(--sans); font-weight: 600; font-size: var(--t-lbl-xs); letter-spacing: 0.02em; color: var(--testo-3); line-height: 1.9; text-transform: none; }
.prmark { font-family: var(--segni); color: var(--t-peso); font-size: var(--t-sm); vertical-align: 1px; }
.medal .mi, .burst .bi, .empty .ei { font-family: var(--segni); }

/* ============================================================
   MOVIMENTO
   ============================================================ */
@keyframes traccia { from { transform: scaleX(0); } }
@keyframes pianta { from { opacity: 0; transform: scale(0.4); } to { opacity: 1; transform: none; } }
@keyframes accendi { from { opacity: 0.2; transform: scaleX(0.2); } to { opacity: 1; transform: none; } }
@keyframes sale { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
body.entra .regolo .fatto { animation: traccia 0.62s var(--ease) 0.06s both; transform-origin: left center; }
body.entra .regolo .bandiera { animation: pianta 0.34s var(--spring) 0.62s both; }
body.entra .giorno .rom { animation: sale 0.5s var(--ease) both; }
body.entra .tacche i.on {
  transform-origin: left center;
  animation: accendi 0.34s var(--spring) both;
  animation-delay: calc(0.30s + min(var(--k, 0) * 26ms, 420ms));
}
@keyframes daSotto { from { transform: translateY(6px); } to { transform: none; } }
body.entra .traccia { animation: daSotto 0.6s var(--ease) 0.3s both; }
/* ---------- IL TOCCO ----------
   🔴 Lo «scatto» che dava fastidio a Vincenzo era questo: ogni superficie grande
   si rimpiccioliva sotto il dito (`scale`), e su una tessera larga quanto lo
   schermo un rimpicciolimento e' un sussulto di tutta la pagina, non un
   riscontro. Nel riferimento le righe e le tessere **non si muovono**: si
   TINGONO, e basta. Il movimento resta solo dove l'elemento e' piccolo e tondo
   (i bottoncini), perche' li' un salto di due pixel si legge come un click e non
   come un tremolio.
   Il riscontro deve essere IMMEDIATO alla pressione e LENTO al rilascio: cosi'
   il dito sente subito, e l'occhio non vede uno sfarfallio quando si stacca. */
.exrow-btn, .meal, .check-item, .medal, .zona, .cenacard, .setchip, .histrow,
.campo, button.mis.carta, .sitelink, .core-row, .qrow {
  transition: background 0.26s var(--ease), box-shadow 0.26s var(--ease);
}
.exrow-btn:active, .meal:active, .check-item:active, .histrow:active,
.campo:active, button.mis.carta:active, .sitelink:active {
  background: var(--filo-2);
  transition-duration: 0.04s;
}
.mis { transition: background 0.26s var(--ease); }

/* Il lampo: il riscontro visivo dove quello tattile non esiste. Su iOS
   `navigator.vibrate` non c'e', quindi un tocco andato a segno e uno mancato
   sarebbero indistinguibili. Solo `opacity` e `transform`: non costa layout. */
@keyframes lampoOk {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--pieno) 55%, transparent); }
  100% { box-shadow: 0 0 0 14px color-mix(in srgb, var(--pieno) 0%, transparent); }
}
.lampo { animation: lampoOk 0.4s var(--ease); }

/* ---------- LA SPUNTA ----------
   E' il gesto piu' ripetuto dell'app: sei pasti al giorno, piu' le serie. Se
   non da' un riscontro suo, spuntare e non spuntare si somigliano, e a fine
   giornata non si sa piu' cosa si e' toccato. Il pallino fa uno scatto in
   dentro e torna, e il segno di spunta si disegna dopo: prima la superficie
   dice «preso», poi il segno dice «cosa». */
@keyframes spuntaPop {
  0%   { transform: scale(1); }
  38%  { transform: scale(0.82); }
  100% { transform: scale(1); }
}
@keyframes spuntaSegno {
  from { opacity: 0; transform: scale(0.5); }
  to   { opacity: 1; transform: none; }
}
.meal.eaten .mbox, .campo.meal.eaten .mbox { animation: spuntaPop 0.42s var(--spring); }
.meal.eaten .mbox svg, .campo.meal.eaten .mbox svg { animation: spuntaSegno 0.3s var(--spring) 0.08s both; }
/* Il testo del pasto preso si spegne con calma invece di saltare all'opacita'
   ridotta: e' l'unico modo per capire, guardando, QUALE riga si e' spuntata
   quando se ne spuntano due di fila. */
.meal .d, .meal .meal-in { transition: opacity 0.34s var(--ease); }

/* ---------- I BOTTONI ----------
   Il bottone pieno e' l'unico posto dove resta un movimento, perche' e' l'unico
   elemento che si tocca aspettandosi che «parta» qualcosa. Due pixel, non otto:
   il riscontro deve essere sentito, non visto. */
.btn { transition: opacity 0.2s var(--ease), transform 0.16s var(--spring); }
.btn:active { opacity: 0.82; transform: translateY(2px); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001s !important; transition-duration: 0.001s !important; animation-delay: 0s !important; transition-delay: 0s !important; }
  .burst.on { opacity: 1; animation: none; }
}

/* ============================================================
   I TELEFONI STRETTI
   ============================================================ */
@media (max-width: 359px) {
  .rings { gap: 8px; }
  .mis .vl { font-size: var(--t-t2); }
  .mis.peso { flex-direction: column; align-items: stretch; padding-bottom: var(--s4); }
  .mis.peso .traccia, .mis.peso::after { display: none; }
  .mis.peso .cap { flex: none; }
  .mis.peso .cell { padding-left: 0; border-left: none; border-top: 1px solid var(--filo); padding-top: 8px; margin-top: 8px; }
  .statgrid { grid-template-columns: 1fr 1fr; }
  .statgrid > div:nth-child(3) { grid-column: span 2; }
}
@media (max-width: 340px) {
  :root { --gut: 12px; --gap: 8px; --s4: 15px; }
  .steppers { grid-template-columns: 1fr; }
  .medals { grid-template-columns: repeat(2, 1fr); }
  .zonegrid { grid-template-columns: repeat(2, 1fr); }
  .exname { font-size: var(--t-sm); }
  nav button { font-size: var(--t-nav); gap: 3px; }
  .volrow .vn { width: 80px; font-size: var(--t-xs); }
}

/* ---------- QUANDO ANDARE ----------
   La striscia delle ore. Le barre non sono un grafico da leggere con
   precisione: sono un colpo d'occhio, e infatti l'unica informazione precisa
   è nelle due pastiglie sotto. Il colore fa tutto il lavoro — verde dove
   conviene andare, rosso nel picco, grigio nel mezzo — e resta lo stesso di
   giorno e di notte, come tutti gli altri campi di colore dell'app. */
.aff-top { display: flex; align-items: baseline; gap: var(--s2); margin-bottom: 13px; }
.aff-ora {
  font-family: var(--sans); font-size: var(--t-lbl); font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase; color: var(--testo-3);
}
.aff-giudizio { font-family: var(--grot); font-weight: 800; font-size: var(--t-t3); color: var(--testo); line-height: 1.2; }
.aff-giudizio.vuota, .aff-giudizio.calma { color: var(--t-ok); }
.aff-giudizio.piena { color: var(--danger-viva); }
.aff-giudizio.chiusa { color: var(--testo-3); }

.aff-strip { display: flex; align-items: stretch; gap: 3px; height: 54px; }
/* Una barra sola per ora: la pista intera più il riempimento, in un gradiente
   con lo stop netto. Due elementi annidati darebbero la stessa figura con il
   doppio del DOM per quindici ore. */
.aff-strip i {
  flex: 1; min-width: 0; border-radius: 3px; position: relative;
  background: linear-gradient(to top, var(--aff-c, var(--pastiglia)) var(--h, 6%), var(--traccia-fondo) var(--h, 6%));
}
.aff-strip i.buona { --aff-c: var(--piatto-viva); }
.aff-strip i.picco { --aff-c: var(--danger-viva); }
.aff-strip i.vuoto { background: var(--traccia-fondo); }
/* L'ora corrente è un punto sotto la barra, non un bordo attorno: un bordo su
   una barra alta 4 px la fa sparire. */
.aff-strip i.ora::after {
  content: ''; position: absolute; left: 50%; bottom: -7px;
  width: 4px; height: 4px; margin-left: -2px; border-radius: 50%; background: var(--testo);
}

.aff-x { display: flex; gap: 3px; margin-top: 11px; }
.aff-x span {
  flex: 1; min-width: 0; text-align: center;
  font-family: var(--grot); font-weight: 600; font-size: var(--t-lbl); color: var(--testo-3);
}

.aff-cons { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; margin-top: 15px; }
.aff-pill {
  font-family: var(--grot); font-weight: 800; font-size: var(--t-sm);
  padding: 6px 13px; border-radius: var(--r-pill);
  background: color-mix(in oklab, var(--piatto-viva), transparent 82%); color: var(--t-ok);
}
.aff-evita { font-size: var(--t-sm); color: var(--testo-3); }
.aff-scaduta { margin-top: 14px; font-size: var(--t-sm); line-height: 1.5; color: var(--testo-2); }
.aff-nota { margin-top: 13px; font-size: var(--t-lbl); line-height: 1.5; color: var(--testo-3); }

/* ---------- IL CIBO LIBERO ----------
   La riga di una cosa mangiata fuori dal menù. Stessa grammatica della riga di
   alimento del menù — nome sopra, dettaglio sotto, numeri a destra — perché è
   la stessa cosa vista da un'altra porta, e due grammatiche per lo stesso
   oggetto sono il modo in cui una schermata smette di essere una schermata. */
.cibrow {
  display: flex; align-items: center; gap: var(--s3);
  padding: 12px 0; border-bottom: 1px solid var(--linea-tenue, var(--traccia-fondo));
}
.cibrow:last-of-type { border-bottom: none; }
.cibrow .cd { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cibrow .cn { font-size: var(--t-rg); font-weight: 600; line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cibrow .cm { font-size: var(--t-lbl); color: var(--testo-3); }
.cibrow .cv, .cibrow .cp { font-family: var(--grot); font-weight: 800; font-size: var(--t-sm); flex-shrink: 0; text-align: right; }
.cibrow .cv { min-width: 62px; }
.cibrow .cp { min-width: 40px; color: var(--testo-2); }
.cibrow small { font-weight: 600; font-size: 11px; color: var(--testo-3); margin-left: 2px; }
/* 44 px di bersaglio anche se il segno ne disegna 14: è il minimo tattile, e la
   ✕ di una riga sbagliata va colpita al primo tentativo. */
.cibrow .cx {
  flex-shrink: 0; width: 44px; height: 44px; margin-right: -12px;
  display: flex; align-items: center; justify-content: center;
  background: none; color: var(--testo-3);
}

.cibo-q {
  width: 100%; margin-top: 10px; padding: 13px 14px;
  background: var(--carta-2); border: none; border-radius: var(--r-box);
  font-family: var(--sans); font-size: var(--t-rg); color: var(--testo);
}
.cibo-q::placeholder { color: var(--testo-3); }

.cibo-e {
  display: grid; grid-template-columns: 1fr auto; grid-template-areas: "n k" "m k";
  align-items: center; gap: 0 12px; width: 100%; text-align: left;
  background: var(--carta-2); border-radius: var(--r-box); padding: 13px 14px;
  transition: background 0.26s var(--ease);
}
.cibo-e .ce-n { grid-area: n; font-size: var(--t-rg); font-weight: 600; line-height: 1.3; }
.cibo-e .ce-m { grid-area: m; font-size: var(--t-lbl); color: var(--testo-3); }
.cibo-e .ce-k { grid-area: k; font-family: var(--grot); font-weight: 800; font-size: var(--t-sm); text-align: right; }
.cibo-e .ce-k small { display: block; font-weight: 600; font-size: 11px; color: var(--testo-3); }

.cibo-scelto .cs-n { font-family: var(--sans); font-weight: 800; font-size: var(--t-t3); line-height: 1.25; }
.cibo-scelto .cs-m { font-size: var(--t-lbl); color: var(--testo-3); margin-top: 4px; }
.cibo-scelto .cs-g { display: flex; align-items: center; justify-content: center; gap: var(--s4); margin: 18px 0 12px; }
.cibo-scelto .cs-b { width: auto; padding: 0 20px; }
.cibo-scelto .cs-v { font-family: var(--grot); font-weight: 800; font-size: 34px; min-width: 110px; text-align: center; }
.cibo-scelto .cs-v small { font-size: 15px; color: var(--testo-3); margin-left: 3px; }
.cibo-scelto .cs-fila { display: flex; gap: 6px; margin-bottom: 16px; }
/* Cinque pastiglie in fila per i grammi. `padding: 10px 0` le lasciava a 41 px:
   `flex:1` divide la larghezza, quindi il minimo sull'altezza non stringe
   niente. */
.cibo-scelto .cs-p {
  flex: 1; min-height: 44px; padding: 10px 0; border-radius: var(--r-box); background: var(--carta-2);
  font-family: var(--grot); font-weight: 700; font-size: var(--t-sm); color: var(--testo-2);
}
.cibo-scelto .cs-p.sel { background: var(--testo); color: var(--carta); }
.cibo-scelto .cs-tot { font-size: var(--t-sm); color: var(--testo-2); line-height: 1.5; margin-bottom: 16px; }
.cibo-scelto .cs-tot b { font-family: var(--grot); font-weight: 800; color: var(--testo); }

.cibo-mano { display: grid; gap: 10px; }
.cibo-mano input {
  width: 100%; padding: 13px 14px; background: var(--carta-2); border: none;
  border-radius: var(--r-box); font-family: var(--sans); font-size: var(--t-rg); color: var(--testo);
}
.cibo-mano input::placeholder { color: var(--testo-3); }
.cm-fila { display: flex; gap: 10px; }
.cm-fila input { min-width: 0; }

/* ---------- LE SCHEDE SUE ---------- */
.sch-add { display: grid; gap: 10px; padding-top: 12px; }
.sch-sel, .sch-add input {
  width: 100%; padding: 12px 13px; background: var(--carta-2); border: none;
  border-radius: var(--r-box); font-family: var(--sans); font-size: var(--t-rg); color: var(--testo);
  -webkit-appearance: none; appearance: none;
}
/* La freccetta del menù nativo la disegna il sistema e su iOS sparisce con
   `appearance:none`: si ridisegna qui, una volta, invece di rinunciare al menù
   nativo che su un telefono è imbattibile. */
.sch-sel {
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23999' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center; background-size: 18px;
  padding-right: 38px;
}
.sch-add input::placeholder { color: var(--testo-3); }
.sch-fila { display: flex; gap: 8px; align-items: center; }
.sch-fila input { min-width: 0; }
.sch-fila .sch-n { max-width: 92px; flex: 0 0 92px; text-align: center; }
.sch-usi { display: flex; gap: 8px; flex-wrap: wrap; padding-top: 4px; }
.sch-usi .btn.sm { width: auto; padding: 0 16px; }
.exrow-btn .cx {
  flex-shrink: 0; width: 44px; height: 44px; margin-right: -10px;
  display: flex; align-items: center; justify-content: center;
  background: none; color: var(--testo-3);
}
.cibosheet.senza-cerca .cibo-q { display: none; }

/* ---------- IL RECUPERO DEI GIORNI SALTATI ---------- */
.rec-g { padding: 12px 0; border-bottom: 1px solid var(--traccia-fondo); }
.rec-g:last-of-type { border-bottom: none; }
.rec-t { font-family: var(--sans); font-weight: 700; font-size: var(--t-rg); margin-bottom: 9px; }
.rec-pasti { display: flex; gap: 6px; flex-wrap: wrap; }
/* 🔴 Erano 40 px, difesi cosi': «a 44 su un iPhone stretto la terza andava a
   capo da sola». L'argomento non regge, ed e' stato misurato invece che
   creduto (`misure/_bersagli-pastiglie.js`): il ritorno a capo dipende dalla
   LARGHEZZA, e `min-height` non tocca la larghezza. Portate a 60 px per prova,
   su 320, 375 e 402 di schermo, le pastiglie restavano larghe 56 e sulle
   stesse 21 e 14 righe. Quindi 44, che e' la soglia del dito. */
.rec-p {
  min-height: 44px; padding: 0 13px; border-radius: var(--r-pill);
  background: var(--carta-2); color: var(--testo-2);
  font-family: var(--sans); font-weight: 600; font-size: var(--t-sm);
  transition: background 0.2s var(--ease), color 0.2s var(--ease);
}
/* 🔴 Bianco su verde chiaro misurava 2,36:1, cioe' sotto ogni soglia: era anche
   irraggiungibile finche' il giorno spariva al primo tocco, quindi nessuno lo
   aveva mai visto. Adesso lo stato esiste, e prende l'inchiostro del sistema:
   ogni stato attivo di questa app e' nero, non colorato. */
.rec-p.sel { background: var(--piatto-viva); color: var(--testo-inv, #111); font-weight: 700; }

/* ============================================================
   MODO ETICHETTE — i cartellini con cui Vincenzo punta
   Non è grafica dell'app: è un attrezzo fra lui e me. Il rosso e il verde
   acido stanno FUORI dalla tavolozza apposta, così non si possono scambiare
   per una decisione di disegno, e tutto vive sotto `body.etichette`: tolta la
   classe, di questo blocco non resta un pixel.
   ============================================================ */
body.etichette .view.on > [data-e] { position: relative; }
body.etichette [data-e]::before {
  content: attr(data-e);
  position: absolute; z-index: 60; pointer-events: none;
  font-family: var(--grot); font-weight: 800; font-size: 10px; line-height: 1;
  letter-spacing: 0.04em; padding: 3px 5px; border-radius: 4px;
  background: #FF1F4B; color: #FFFFFF;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}
/* La sezione porta il cartellino a cavallo del suo spigolo in alto a sinistra;
   i pezzi dentro lo portano a destra, così i due non si coprono mai.
   🔴 Sulla sezione il cartellino porta anche il NOME, e non è ridondanza: se il
   giorno cambia, una sezione compare o sparisce e i numeri slittano tutti. Col
   nome accanto, «1.4 · recupero» resta lo stesso indirizzo anche domani. */
body.etichette .view.on > [data-e]::before {
  top: -7px; left: -3px;
  content: attr(data-e) ' · ' attr(data-e-nome);
}
body.etichette [data-e] [data-e] { position: relative; }
body.etichette [data-e] [data-e]::before {
  top: -6px; right: -3px; left: auto;
  background: #00C2A8; color: #06231F;
}
/* Livello 2 — ogni dettaglio. I cartellini sono molti, quindi si rimpiccioliscono
   e si appoggiano allo spigolo invece di sporgere: a questa densità il cartellino
   che sporge copre il vicino, e due cartellini sovrapposti non sono due
   indirizzi, sono zero. */
/* 🔴 Il cartellino sta SOPRA la cosa, non sopra il suo testo. Misurato alla
   prima prova: a 110 cartellini per schermata coprivano «Cena», «5 ott»,
   «oggi» e il numero grande dei pasti — e un'etichetta che nasconde quello che
   sta etichettando è peggio di nessuna etichetta, perché lui non può più
   leggere la cosa di cui vuole parlarmi. Il `translateY(-100%)` lo solleva
   nell'aria sopra il riquadro, che a questa densità è l'unico posto libero. */
body.etichette-fitte [data-e] [data-e]::before {
  font-size: 8px; padding: 2px 3px; border-radius: 3px;
  top: 0; right: 0; box-shadow: none;
  transform: translate(2px, -100%);
  opacity: 0.92;
}
body.etichette-fitte .view.on > [data-e]::before { font-size: 9px; }

/* ============================================================
   IL VELO D'AVVIO
   Il marchio su carta piena mentre l'app si disegna. Due sole cose si muovono,
   `transform` e `opacity`, e nessuna delle due ridisegna il layout: il marchio
   respira (una scala fra 0,94 e 1) e il velo svanisce alzandosi di un pelo.
   🔴 Il fondo è `--fondo`, la stessa variabile che lo script in testa a
   `index.html` ha già deciso PRIMA del primo pixel: così di notte il velo nasce
   già scuro, invece di sbattere mezzo secondo di carta bianca in faccia a uno
   che apre l'app alle sei del mattino.
   ============================================================ */
.velo {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  background: var(--fondo); color: var(--testo);
  transition: opacity 0.42s var(--ease), transform 0.42s var(--ease), visibility 0s linear 0.42s;
}
.velo-marchio svg { width: 68px; height: 68px; display: block; animation: veloRespiro 1.9s var(--ease) infinite; }
.velo.via { opacity: 0; transform: translateY(-6px); visibility: hidden; pointer-events: none; }
@keyframes veloRespiro {
  0%, 100% { transform: scale(0.94); opacity: 0.72; }
  50%      { transform: scale(1);    opacity: 1; }
}

/* ============================================================
   GLI ANELLI CHE SI RIEMPIONO
   «I pallini in alto, quando uno entra nell'app, si animano.» Le tre capsule
   partono vuote e si riempiono girando, una dopo l'altra. Non è decorazione: il
   perimetro che corre È la lettura del dato, e vederlo correre dice quanto
   manca meglio di quanto lo dica fermo.
   Si anima `stroke-dashoffset`, che è l'unica proprietà che quella figura ha;
   sono tre tracciati da 100 unità, e il costo misurato sta dentro il frame.
   ============================================================ */
body.entra .mf-caps__arco { animation: capsulaGira 0.9s var(--ease) both; }
body.entra .benzina > .mf-caps:nth-child(2) .mf-caps__arco { animation-delay: 0.09s; }
body.entra .benzina > .mf-caps:nth-child(3) .mf-caps__arco { animation-delay: 0.18s; }
@keyframes capsulaGira { from { stroke-dashoffset: 100; } }

/* L'ONDA si disegna da sinistra: è la figura firma dell'app, e vederla nascere
   è il momento in cui la schermata smette di essere una pagina. Il tratto è un
   `path` con `pathLength` normalizzato, quindi basta scoprire il trattino. */
body.entra .onda svg path[stroke] { animation: ondaScrive 1.05s var(--ease) 0.12s both; }
@keyframes ondaScrive {
  from { stroke-dasharray: 0 2000; }
  to   { stroke-dasharray: 2000 0; }
}

/* La pressione: un bottone che cede sotto il dito. Tre centesimi di scala, non
   di più — oltre diventa un giocattolo, e questa è l'app con cui si va in sala. */
.btn:active, .pill:active, .mis.carta:active { transform: scale(0.976); }
.btn, .pill, .mis.carta { transition: transform 0.16s var(--ease), opacity 0.2s var(--ease); }

/* 🔴 L'ARREDAMENTO FISSO (`0.x`) vuole i cartellini SOPRA il blocco, non sul
   blocco. Dentro una vista le tessere hanno 24 px d'aria sopra e il cartellino
   ci sta comodo; in testata i blocchi sono impilati senza aria, e misurato alla
   prima prova il cartellino copriva il marchio, la data e il numero del giorno.
   Quindi qui si solleva di tutta la sua altezza — e la testata prende 18 px di
   respiro in cima SOLO col modo acceso, perche' al primo blocco l'aria sopra
   non esiste proprio. È un attrezzo, non il disegno: si vede solo mentre lui
   punta, e sparisce con lui. */
body.etichette .hdr { padding-top: calc(14px + env(safe-area-inset-top, 0px) * 0.5 + 18px); }
body.etichette .hdr > [data-e]::before,
body.etichette nav[data-e]::before {
  left: auto; right: 2px;
  transform: translateY(-100%);
}
