/* ============================================================================
 * Pedieta — foglio di stile
 * ----------------------------------------------------------------------------
 * Scritto per un telefono, e in particolare per il telefono su cui girera':
 * Poco X4 Pro 5G, AMOLED da 6.67", 1080x2400 a 120 Hz, foro della fotocamera
 * in alto al centro, HyperOS con la navigazione a gesti.
 *
 * Cosa cambia davvero, rispetto a un CSS "responsive" generico:
 *
 *  - IL NERO E' NERO. Su un AMOLED un pixel nero e' un pixel spento: il tema
 *    scuro qui usa #000 vero e non il solito grigio scurissimo, perche' e'
 *    l'unico che fa consumare meno e che rende invisibile il bordo dello
 *    schermo al buio.
 *
 *  - LE ZONE SICURE. La barra dei gesti sta SOPRA la pagina, e il foro della
 *    fotocamera si mangia la cima. Ogni margine esterno passa da env(), mai
 *    da un numero fisso.
 *
 *  - 120 Hz. Si animano solo transform e opacity, le due proprieta' che il
 *    telefono sa muovere senza ridisegnare il contenuto. Un'animazione su
 *    height o su box-shadow, a 120 fotogrammi al secondo, si vede scattare.
 *
 *  - IL POLLICE. Niente sotto i 48 punti: e' la misura minima di Android per
 *    qualcosa che si preme, ed e' misurata sul dito medio di un adulto.
 *
 *  - I CAMPI A 16px. Sotto quella misura il browser ingrandisce da solo la
 *    pagina quando si tocca un campo, e non torna piu' indietro.
 * ========================================================================== */

:root {
    color-scheme: light dark;

    --verde:        #2FBF71;
    --verde-cupo:   #1F8F55;
    --ambra:        #D89B1C;
    --rosso:        #DC4C4C;

    --fondo:        #F5F6F4;
    --carta:        #FFFFFF;
    --carta-2:      #EFF1EE;
    --inchiostro:   #14181B;
    --fumo:         #626B70;
    --linea:        rgba(20, 24, 27, .10);

    --raggio:       18px;
    --raggio-p:     12px;

    /* Una curva sola per tutto: il movimento dell'app deve sembrare una
       cosa sola, non sei effetti diversi messi vicini. */
    --molla: cubic-bezier(.22, .61, .36, 1);

    /* I margini esterni: il maggiore fra un valore minimo e la zona sicura.
       Su un telefono senza notch l'inset vale zero, e senza il max() il
       contenuto finirebbe appiccicato al bordo. */
    --su:  max(.75rem, env(safe-area-inset-top));
    --giu: max(.75rem, env(safe-area-inset-bottom));
    --sx:  max(1rem, env(safe-area-inset-left));
    --dx:  max(1rem, env(safe-area-inset-right));
}

@media (prefers-color-scheme: dark) {
    :root {
        --fondo:      #000000;
        --carta:      #0D0F10;
        --carta-2:    #16191B;
        --inchiostro: #ECEFF1;
        --fumo:       #8A9299;
        --linea:      rgba(255, 255, 255, .12);
        --verde:      #3ED17F;
        --ambra:      #E5AC33;
        --rosso:      #F26A6A;
    }
}

* { margin: 0; padding: 0; box-sizing: border-box; }
[hidden] { display: none !important; }

html {
    /* Niente rimbalzo elastico oltre il contenuto: dentro un'app installata
       fa sembrare la pagina staccata dalla cornice. */
    overscroll-behavior-y: none;
    -webkit-text-size-adjust: 100%;
}

body {
    min-height: 100dvh;
    background: var(--fondo);
    color: var(--inchiostro);
    font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    /*
     | Diciassette e non sedici. Sedici e' il minimo tecnico — sotto, il
     | browser ingrandisce la pagina da solo quando si tocca un campo — ma un
     | minimo non e' una buona misura: questa e' un'app che si guarda di
     | sfuggita, in cucina, spesso con il telefono appoggiato lontano dagli
     | occhi. Le voci secondarie sono salite di conseguenza, perche' alzare
     | solo la base avrebbe allargato la distanza fra il testo grande e quello
     | piccolo invece di rendere leggibile tutto.
     */
    font-size: 17px;
    line-height: 1.45;
    /* Il tocco non deve lasciare il rettangolo grigio di Android. */
    -webkit-tap-highlight-color: transparent;
    /*
     | manipulation spegne il doppio tocco che ingrandisce.
     |
     | Il meta viewport da solo non basta: toglie il pizzico, ma il doppio
     | tocco su alcune versioni di Chrome continua a funzionare. In cambio
     | sparisce anche l'attesa di 300 ms con cui il browser aspettava di
     | capire se il tocco fosse doppio — quindi ogni pulsante risponde prima.
     */
    touch-action: manipulation;
}

button, input { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }

/* Chi non puo' vedere l'animazione non deve subirla. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .001ms !important;
        transition-duration: .001ms !important;
    }
}

.niente-js {
    padding: 2rem 1.25rem; text-align: center; color: var(--fumo);
}

/* ============================================================== accesso == */

.porta {
    min-height: 100dvh;
    display: grid; place-items: center;
    padding: var(--su) var(--dx) var(--giu) var(--sx);
}
.porta__dentro { width: 100%; max-width: 22rem; text-align: center; }

/* Col tema scuro il fondo nero dell'icona si confonde con la pagina e resta
   solo l'anello; col tema chiaro si vede il quadrato, come sul telefono. */
.porta__logo { display: block; width: 5.5rem; height: 5.5rem; margin: 0 auto 1.1rem; }

.marchio {
    font-size: 2.1rem; font-weight: 800; letter-spacing: -.03em;
    color: var(--verde);
}
.porta__detto { margin: .4rem 0 2rem; color: var(--fumo); font-size: 1.05rem; }
.porta__blocco { display: grid; gap: .7rem; }
.porta__nota { font-size: .92rem; color: var(--fumo); margin-top: -.2rem; }
.porta__errore {
    margin-top: 1rem; padding: .7rem .9rem;
    background: color-mix(in srgb, var(--rosso) 14%, transparent);
    color: var(--rosso); border-radius: var(--raggio-p);
    font-size: .95rem; text-align: left;
}

/* ============================================================== bottoni == */

.bottone {
    display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
    min-height: 52px; padding: 0 1.4rem;
    border-radius: 999px;
    font-size: 1rem; font-weight: 650;
    /* Solo transform: a 120 Hz e' l'unica cosa che si muove senza scatti. */
    transition: transform .12s var(--molla), background-color .15s ease;
}
.bottone:active { transform: scale(.97); }
.bottone--pieno { background: var(--verde); color: #04120A; }
.bottone--nudo  { color: var(--fumo); min-height: 48px; }
.bottone--filo  { border: 1.5px solid var(--linea); }
.bottone[disabled] { opacity: .5; pointer-events: none; }

/* =============================================================== campi === */

.campo { display: grid; gap: .35rem; text-align: left; }
.campo__voce { font-size: .92rem; color: var(--fumo); font-weight: 600; }
.campo input, .campo select {
    width: 100%; min-height: 52px;
    padding: 0 .9rem;
    background: var(--carta); color: var(--inchiostro);
    border: 1.5px solid var(--linea); border-radius: var(--raggio-p);
    font-size: 16px;   /* mai meno: sotto, il browser ingrandisce la pagina */
}
.campo input:focus-visible, .campo select:focus-visible {
    outline: none; border-color: var(--verde);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--verde) 28%, transparent);
}

/* ================================================================= app === */

.app {
    /* In fondo si lascia posto alla barra di navigazione, che e' fissa e
       coprirebbe l'ultima riga del diario: la sua altezza piu' la zona
       sicura del telefono. */
    padding: 0 var(--dx) calc(78px + env(safe-area-inset-bottom)) var(--sx);
    max-width: 34rem; margin-inline: auto;
}

/* ================================================================ testa == */
/*
 | La testa resta in alto e si rimpicciolisce.
 |
 | E' sticky e non fixed: un elemento fisso esce dal flusso e bisogna
 | ricalcolargli sotto uno spazio vuoto pari alla sua altezza — che qui
 | cambia, perche' si accorcia scorrendo. Con sticky lo spazio se lo tiene da
 | solo e non c'e' nessun numero magico da mantenere allineato.
 |
 | I margini negativi la portano da bordo a bordo: dentro il padding di .app
 | resterebbero due strisce laterali da un centimetro in cui si vedrebbe
 | passare il contenuto sotto il vetro.
 */
.testa {
    position: fixed; top: 0; left: 0; right: 0; z-index: 30;
    padding: var(--su) var(--dx) .5rem var(--sx);
    background: color-mix(in srgb, var(--fondo) 86%, transparent);
    -webkit-backdrop-filter: saturate(180%) blur(16px);
    backdrop-filter: saturate(180%) blur(16px);
    transition: box-shadow .25s ease;
}
/* Fissa va da bordo a bordo, ma il contenuto dentro deve restare incolonnato
   con quello sotto: stessa larghezza massima, stesso centro. */
.testa > .capo,
.testa > .conto { max-width: 34rem; margin-inline: auto; }

/*
 | Lo spazio che la testa occupa, tenuto da parte dal contenuto.
 |
 | E' il nodo di tutta la faccenda. Quando la testa stava NEL flusso,
 | accorciandosi accorciava la pagina: il browser riportava lo scorrimento
 | dentro il nuovo limite, la testa si riapriva, e partiva l'altalena che
 | impediva di arrivare in fondo. Il primo rimedio — non accorciarla se la
 | pagina e' corta — toglieva l'altalena ma lasciava l'intestazione grande a
 | mangiarsi lo schermo, che e' un difetto peggiore.
 |
 | Fuori dal flusso il problema sparisce alla radice: la pagina e' sempre
 | alta uguale, la testa puo' accorciarsi sempre, e lo spazio riservato qui
 | sotto corrisponde a quella aperta — che e' come sta quando lo scorrimento
 | e' a zero, cioe' l'unico momento in cui quello spazio si vede.
 |
 | Il valore vero lo misura lo script; questo e' quello che vale prima, e per
 | i browser senza JavaScript.
 */
#vistaOggi {
    padding-top: var(--testa-alta, 25rem);

    /*
     | Il min-height insieme al box-sizing: border-box e' quello che rende il
     | tutto stabile, e vale la pena spiegarlo perche' non si vede.
     |
     | Lo spazio riservato sopra segue l'altezza VERA della testa: quando la
     | testa si accorcia, il padding si accorcia con lei — altrimenti fra la
     | testa chiusa e il contenuto resterebbe una fascia vuota di
     | duecentocinquanta pixel, che e' il difetto che si vedeva premendo "+"
     | su un pasto.
     |
     | Ma un padding che si accorcia accorcerebbe la pagina, e la pagina che
     | si accorcia era l'altro difetto, quello dell'altalena. Qui non succede:
     | con border-box il min-height comprende il padding, quindi mentre il
     | padding cala il contenuto cresce e l'altezza totale resta identica.
     | Le due cose si compensano da sole, senza che nessuno tenga il conto.
     */
    min-height: 100dvh;
}
/* La riga di separazione compare solo quando c'e' qualcosa che le scorre
   sotto: prima sarebbe un bordo che divide il nulla dal nulla. */
.testa.is-compatta { box-shadow: 0 1px 0 var(--linea), 0 6px 18px rgba(0, 0, 0, .10); }

/* Spegne le animazioni per il tempo di una misura. Senza, misurare
   l'altezza chiusa mentre la testa si sta ancora chiudendo darebbe un
   valore a meta' strada. */
.testa.senza-moto,
.testa.senza-moto * { transition: none !important; }

.capo {
    display: flex; align-items: center; gap: .25rem;
    padding-block: .35rem;
}
.capo__giorno {
    width: 48px; height: 48px; flex: none;
    display: grid; place-items: center;
    font-size: 1.6rem; color: var(--fumo); border-radius: 50%;
    transition: transform .12s var(--molla);
}
.capo__giorno:active { transform: scale(.9); }
.capo__data { flex: 1; text-align: center; line-height: 1.15; }
.capo__quando { display: block; font-weight: 700; }
.capo__dataPiccola { display: block; font-size: .85rem; color: var(--fumo); }
.capo__menu {
    width: 48px; height: 48px; flex: none;
    display: grid; place-items: center; border-radius: 50%;
}
.capo__menu svg { width: 22px; height: 22px; fill: var(--fumo); }

/* --------------------------------------------------------------- conto -- */

/*
 | Il contatore, che scorrendo si accorcia.
 |
 | Tutto quello che si muove passa da una transizione su misure semplici di
 | un elemento solo — la larghezza dell'anello e il corpo del numero — e non
 | da una ricostruzione del blocco: il passaggio avviene una volta per gesto,
 | non a ogni fotogramma, quindi anche a 120 Hz non c'e' niente da recuperare.
 |
 | Da aperto e' una colonna: anello grande, numeri sotto. Da chiuso diventa
 | una riga: anello piccolo a sinistra, i due obiettivi accanto. Non sparisce
 | mai, perche' quel numero e' la ragione per cui l'app viene aperta.
 */
.conto {
    display: grid; justify-items: center; gap: .7rem;
    padding: .8rem 0 1rem;
    transition: gap .3s var(--molla), padding .3s var(--molla);
}
/*
 | L'anello e' piu' piccolo di prima.
 |
 | Sotto ci sono tre righe di numeri invece di una, e la testa aperta non puo'
 | prendersi mezzo schermo: quello che si guadagna mostrando tutto si perde
 | subito se per vedere la colazione bisogna scorrere. Undici rem sono ancora
 | abbastanza perche' il numero grande al centro si legga da lontano.
 */
.conto__anello {
    position: relative; width: min(40vw, 10.5rem); aspect-ratio: 1;
    transition: width .3s var(--molla);
}

/* --- da chiuso --- */
.testa.is-compatta .conto {
    grid-template-columns: auto 1fr;
    justify-items: stretch; align-items: center;
    gap: .8rem; padding: .2rem 0 .35rem;
}
.testa.is-compatta .conto__anello { width: 3.4rem; }
.testa.is-compatta .conto__kcal { font-size: 1rem; letter-spacing: -.02em; }
.testa.is-compatta .conto__etichetta { display: none; }
.conto__anello svg { width: 100%; height: 100%; transform: rotate(-90deg); }
/*
 | I due anelli.
 |
 | Le circonferenze sono scritte a mano nel dasharray perche' il raggio e'
 | fissato nel marcatore: 2 x pi greco x 52 fa 326.7 per quello esterno, x 38
 | fa 238.8 per quello interno. Cambiare un raggio vuol dire cambiare anche
 | il numero qui — sono gli unici due posti.
 */
.anello__fondo, .anello__pieno {
    fill: none; stroke-linecap: round;
}
.anello__fondo { stroke: var(--carta-2); stroke-width: 11; }
.anello__fondo--dentro { stroke-width: 8; }

.anello__pieno {
    stroke: var(--verde); stroke-width: 11;
    stroke-dasharray: 326.7;
    stroke-dashoffset: 326.7;
    transition: stroke-dashoffset .5s var(--molla), stroke .3s ease;
}
.anello__pieno--prot {
    stroke: #7C5CD6; stroke-width: 8;
    stroke-dasharray: 238.8;
    stroke-dashoffset: 238.8;
}
.conto.is-oltre .anello__pieno { stroke: var(--rosso); }
.conto.is-vicino .anello__pieno { stroke: var(--ambra); }
/* Il colore dell'anello delle proteine non cambia con quello delle calorie:
   sforare le calorie non dice niente sulle proteine. */
.conto.is-oltre .anello__pieno--prot,
.conto.is-vicino .anello__pieno--prot { stroke: #7C5CD6; }

.conto__numero {
    position: absolute; inset: 0;
    display: grid; place-content: center; text-align: center;
}
.conto__kcal {
    display: block;
    /* Ridotto insieme all'anello: quattro cifre devono stare dentro il
       cerchio interno, e con la misura di prima "1697" lo toccava da
       entrambi i lati. */
    font-size: clamp(1.9rem, 9.5vw, 2.6rem); font-weight: 800;
    letter-spacing: -.04em; line-height: 1;
    /* Le cifre in colonna non devono ballare mentre il numero cambia. */
    font-variant-numeric: tabular-nums;
}
.conto__etichetta { font-size: .9rem; color: var(--fumo); }

/*
 | Il riepilogo: tre righe uguali, una per calorie, proteine e idratazione.
 |
 | Le tre colonne sono di larghezza identica e i numeri incolonnati con le
 | cifre tabulari: leggendo in verticale si confrontano fra loro i "mangiate"
 | e i "rimanenti" delle tre cose, che e' il secondo modo in cui questa
 | tabella si guarda.
 |
 | Il numero rimanente e' l'unico in nero pieno. Gli altri due — quanto hai
 | preso, quanto te ne serve — sono il contesto che gli da' significato, e in
 | grigio restano leggibili senza contendergli lo sguardo.
 */
.riepilogo {
    width: 100%;
    display: grid; gap: .5rem;
    font-variant-numeric: tabular-nums;
}
.metro { display: grid; gap: .1rem; }
.metro__voce {
    display: flex; align-items: center; gap: .35rem;
    font-size: .72rem; font-weight: 700; letter-spacing: .07em;
    text-transform: uppercase; color: var(--fumo);
}
.metro__cifre { display: grid; grid-template-columns: repeat(3, 1fr); }
.metro__cella {
    display: grid; justify-items: center; align-content: start;
    line-height: 1.15;
}
.metro__cella b {
    font-size: 1.2rem; font-weight: 700; color: var(--fumo);
    letter-spacing: -.02em;
}
.metro__cella small { font-size: .68rem; color: var(--fumo); }
.metro__cella--resta b { color: var(--inchiostro); font-size: 1.35rem; }

/* L'unita' di misura vive nel titolo della riga finche' c'e' spazio; da
   chiusi il titolo sparisce e l'unita' si sposta accanto al numero, altrimenti
   tre numeri nudi in fila non direbbero di cosa parlano. */
.metro__unita { display: none; font-style: normal; }

/* --- il riepilogo da chiuso: solo i tre numeri che restano --- */
.testa.is-compatta .riepilogo {
    display: flex; gap: .9rem; justify-content: space-around; flex-wrap: wrap;
}
.testa.is-compatta .metro__voce span { display: none; }
.testa.is-compatta .metro { grid-auto-flow: column; align-items: center; gap: .35rem; }
.testa.is-compatta .metro__cifre { display: flex; }
.testa.is-compatta .metro__cella:not(.metro__cella--resta) { display: none; }
.testa.is-compatta .metro__cella--resta {
    display: flex; align-items: baseline; gap: .15rem;
}
.testa.is-compatta .metro__cella--resta b { font-size: 1rem; }
.testa.is-compatta .metro__cella small { display: none; }
.testa.is-compatta .metro__unita { display: inline; font-size: .78rem; color: var(--fumo); }

.pallino--kcal  { background: var(--verde); }
.pallino--prot  { background: #7C5CD6; }
.pallino--acqua { background: #3FA8E0; }
.conto.is-oltre .pallino--kcal { background: var(--rosso); }
.conto.is-vicino .pallino--kcal { background: var(--ambra); }

/* Sforare si vede anche nel numero, non solo nell'anello: e' il caso in cui
   quel numero va guardato. */
.metro__cella--resta.is-oltre b { color: var(--rosso); }

/* -------------------------------------------------------------- barre --- */

.barra__pista {
    height: 10px; border-radius: 999px;
    background: var(--carta-2); overflow: hidden;
}
.barra__pieno {
    height: 100%; width: 0;
    border-radius: 999px;
    background: var(--verde);
    /* Solo la larghezza in transizione: e' una proprieta' che costa, ma qui
       cambia una volta per gesto e mai durante lo scorrimento. */
    transition: width .45s var(--molla), background-color .3s ease;
}
.barra__pieno--acqua { background: #3FA8E0; }
.barra.is-pieno .barra__pieno { background: var(--verde-cupo); }

.acqua__tocchi { display: flex; gap: .4rem; margin-top: .6rem; flex-wrap: wrap; }
/* Il «+» della scheda dell'acqua e' azzurro come la sua barra, non verde come
   quello dei pasti: il colore dice a quale contatore va quello che si aggiunge. */
.scheda--acqua .scheda__piu { color: #3FA8E0; }
.scheda--acqua .scheda__piu:active { background: #3FA8E0; color: #04121A; }
/*
 | flex-basis auto e nessun min-width scritto a mano: cosi' ogni pillola
 | parte dalla larghezza del suo testo e puo' solo crescere, mai stringersi
 | sotto di essa. Quando non ci stanno tutte in riga, vanno a capo — che e'
 | quello che deve succedere su uno schermo stretto.
 */
.acqua__tocchi .scorciatoia { flex: 1 1 auto; }

/* -------------------------------------------------------------- cerca --- */

.cerca { position: relative; margin-top: .4rem; }
.cerca__chiudi { display: none; }

/* ======================================================== modo ricerca == */
/*
 | Toccando la barra si entra in una schermata di ricerca vera: la barra sale
 | in cima, i risultati riempiono lo spazio fino alla tastiera, il resto
 | sparisce.
 |
 | E' la terza soluzione al problema della tastiera che copriva il campo, e
 | la prima che non puo' fallire. Le prime due inseguivano la tastiera con lo
 | scorrimento: si misurava lo spazio rimasto e si scorreva di conseguenza —
 | ma il browser fa i suoi scorrimenti per conto suo, la tastiera cambia
 | altezza mentre si scrive, e bastava che una delle due cose arrivasse un
 | attimo dopo perche' il campo tornasse sotto.
 |
 | Qui non si misura e non si scorre: la barra sta in un punto fisso in alto,
 | dove la tastiera per definizione non arriva.
 */
body.is-cercando { overflow: hidden; }
body.is-cercando .testa,
body.is-cercando .diario,
body.is-cercando .scheda--acqua,
body.is-cercando .tabbar { display: none; }

/*
 | Il livello 38 non e' un numero a caso: deve stare SOPRA la barra di
 | navigazione (35) e la testa (30), ma SOTTO il velo (40) e il foglio (41).
 |
 | Con un valore piu' alto — c'era 45 — toccando un risultato il foglio della
 | quantita' si apriva dietro la schermata di ricerca: si apriva davvero,
 | semplicemente non lo vedeva nessuno, e sembrava che il tocco non avesse
 | fatto niente.
 */
body.is-cercando .cerca {
    position: fixed; inset: 0; z-index: 38;
    margin: 0; padding: var(--su) var(--dx) 0 var(--sx);
    background: var(--fondo);
    display: flex; flex-direction: column;
}
body.is-cercando .cerca__chiudi {
    display: block; flex: none;
    min-height: 44px; padding: 0 .2rem 0 .7rem;
    color: var(--verde); font-weight: 600; font-size: .95rem;
}
body.is-cercando .risultati {
    flex: 1; min-height: 0; overflow-y: auto;
    margin-top: .7rem; padding-bottom: 1rem;
    overscroll-behavior: contain;
}
.cerca__riga {
    display: flex; align-items: center; gap: .5rem;
    background: var(--carta);
    border: 1.5px solid var(--linea); border-radius: 999px;
    padding: 0 .5rem 0 .9rem;
}
.cerca__riga:focus-within {
    border-color: var(--verde);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--verde) 24%, transparent);
}
.cerca__lente {
    width: 20px; height: 20px; flex: none;
    fill: none; stroke: var(--fumo); stroke-width: 2; stroke-linecap: round;
}
.cerca input {
    flex: 1; min-width: 0; min-height: 52px;
    background: none; border: 0; outline: none;
    font-size: 16px;
}
.cerca input::-webkit-search-cancel-button { display: none; }
.cerca__pulisci {
    width: 40px; height: 40px; flex: none;
    display: grid; place-items: center;
    font-size: 1.5rem; color: var(--fumo); border-radius: 50%;
}
/* 44 punti come la matita delle righe: sta accanto alla ×, e fra le due ci
   deve essere spazio per il pollice. */
.cerca__scansiona {
    width: 44px; height: 44px; flex: none;
    display: grid; place-items: center; border-radius: 50%;
    transition: transform .12s var(--molla), background-color .15s ease;
}
.cerca__scansiona svg {
    width: 22px; height: 22px;
    fill: none; stroke: var(--fumo); stroke-width: 1.8;
    stroke-linecap: round; stroke-linejoin: round;
}
.cerca__scansiona:active { transform: scale(.88); background: var(--carta-2); }
.cerca__scansiona:active svg { stroke: var(--verde); }
.cerca__scansiona:focus-visible { outline: 3px solid var(--verde); outline-offset: 2px; }

/* ======================================================== la scansione == */
/*
 | La fotocamera a tutto schermo, con il mirino in mezzo.
 |
 | Nera in tutti e due i temi: e' un mirino, non una pagina. Il livello 39 la
 | mette sopra la ricerca (38) e sotto il velo (40), per la stessa ragione
 | scritta li': il foglio che si apre dopo la lettura deve stare davanti.
 */
.scanner {
    position: fixed; inset: 0; z-index: 39;
    background: #000; color: #fff;
}
.scanner__video {
    position: absolute; inset: 0;
    width: 100%; height: 100%; object-fit: cover;
}
/* Il mirino e' largo e basso, della forma di un codice a barre: dice senza
   parole come tenere il telefono. L'ombra enorme scurisce tutto il resto. */
.scanner__mirino {
    position: absolute; left: 50%; top: 42%;
    width: min(80vw, 22rem); aspect-ratio: 16 / 9;
    transform: translate(-50%, -50%);
    border: 3px solid var(--verde); border-radius: 18px;
    box-shadow: 0 0 0 100vmax rgba(0, 0, 0, .45);
}
.scanner__detto {
    position: absolute; left: 0; right: 0; top: calc(var(--su) + 1.2rem);
    padding: 0 var(--dx) 0 var(--sx);
    text-align: center; font-size: 1.05rem; font-weight: 600;
    text-shadow: 0 1px 4px rgba(0, 0, 0, .6);
}
.scanner__comandi {
    position: absolute; left: 0; right: 0; bottom: 0;
    display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem;
    padding: 1rem var(--dx) calc(var(--giu) + 1rem) var(--sx);
}
.scanner__tasto {
    min-height: 48px; padding: 0 1.2rem;
    border-radius: 999px;
    background: rgba(255, 255, 255, .18); color: #fff;
    font-size: .98rem; font-weight: 600;
    white-space: nowrap;
}
.scanner__tasto.is-accesa { background: #fff; color: #000; }
.scanner__tasto--chiudi { background: var(--verde); color: #04120A; }

.risultati { display: grid; gap: .4rem; margin-top: .6rem; }

.voce {
    display: flex; align-items: center; gap: .8rem;
    width: 100%; min-height: 56px;
    padding: .55rem .9rem;
    background: var(--carta); border-radius: var(--raggio-p);
    text-align: left;
    transition: transform .12s var(--molla);
}
.voce:active { transform: scale(.985); }
.voce__nome { flex: 1; min-width: 0; }
.voce__nome b { display: block; font-weight: 600; }
.voce__nome span { font-size: .87rem; color: var(--fumo); }
.voce__kcal {
    flex: none; font-weight: 700; font-variant-numeric: tabular-nums;
}
.voce__kcal small { font-weight: 500; color: var(--fumo); }

.vuoto {
    padding: 1.2rem .9rem; text-align: center;
    color: var(--fumo); font-size: .97rem;
}

/* I risultati che vengono da fuori sono marcati: chi sceglie deve sapere che
   quel dato viene da un'etichetta caricata da qualcun altro, non dalla
   tabella curata dell'app. */
.risultati__capo {
    padding: .8rem .3rem .3rem;
    font-size: .78rem; font-weight: 700; letter-spacing: .09em;
    text-transform: uppercase; color: var(--fumo);
}
.risultati__nota {
    padding: .7rem .3rem 0;
    font-size: .82rem; color: var(--fumo);
}
.voce--esterna { border: 1.5px dashed var(--linea); background: transparent; }
.voce--esterna:disabled { opacity: .5; }

/* ------------------------------------------------------------- diario --- */

.diario { display: grid; gap: .7rem; margin-top: 1.2rem; }

/*
 | La scheda di un pasto.
 |
 | Quattro contenitori fissi — colazione, pranzo, cena, spuntini — anche
 | quando sono vuoti: e' cosi' che si vede a colpo d'occhio cosa manca.
 | Ognuno ha il suo "+", che e' la differenza fra "cerco, scelgo e poi dico
 | dove metterlo" e "aggiungo alla cena".
 */
.scheda {
    padding: .7rem .7rem .6rem;
    background: var(--carta);
    border-radius: var(--raggio);
}
.scheda--acqua { margin-top: .7rem; }

.scheda__capo {
    display: flex; align-items: center; gap: .6rem;
    padding: 0 .2rem .5rem;
}
.scheda__nome {
    flex: 1;
    font-size: .85rem; font-weight: 700; letter-spacing: .08em;
    text-transform: uppercase; color: var(--fumo);
}
.scheda__somma {
    display: flex; flex-direction: column; align-items: flex-end;
    line-height: 1.15;
    font-size: .95rem; font-variant-numeric: tabular-nums;
    color: var(--inchiostro);
}
/* Le proteine del pasto: stessa colonna del totale, mezzo passo indietro. */
.scheda__somma small {
    font-size: .76rem; font-weight: 600;
    color: var(--fumo);
}
.scheda__copia {
    width: 40px; height: 40px; flex: none;
    display: grid; place-items: center;
    margin: -.35rem 0;
    border-radius: 50%;
    transition: transform .12s var(--molla), background-color .15s ease;
}
.scheda__copia svg {
    width: 19px; height: 19px;
    fill: none; stroke: var(--fumo); stroke-width: 1.8;
    stroke-linecap: round; stroke-linejoin: round;
}
.scheda__copia:active { transform: scale(.88); background: var(--carta-2); }
.scheda__copia:active svg { stroke: var(--verde); }

.scheda__piu {
    width: 40px; height: 40px; flex: none;
    display: grid; place-items: center;
    margin: -.35rem -.2rem -.35rem 0;
    border-radius: 50%;
    background: var(--carta-2); color: var(--verde);
    font-size: 1.45rem; font-weight: 600; line-height: 1;
    transition: transform .12s var(--molla), background-color .15s ease;
}
.scheda__piu:active { transform: scale(.88); background: var(--verde); color: #04120A; }

.pasto__voci { display: grid; gap: .3rem; }

/* Il pasto vuoto non e' uno spazio bianco: e' un invito, ed e' premibile
   tutto, non solo il "+" in alto a destra. */
.pasto__vuoto {
    width: 100%; min-height: 44px;
    padding: .5rem .9rem;
    border-radius: var(--raggio-p);
    background: var(--carta-2);
    color: var(--fumo); font-size: .92rem; text-align: left;
}
.pasto__vuoto:active { transform: scale(.985); }

/* Dentro una scheda le righe non hanno bisogno del loro fondo: sarebbero
   una scatola dentro una scatola. */
.scheda--pasto .riga,
.scheda--acqua .riga { background: var(--carta-2); }

/* L'elenco delle sorsate sta sotto le pillole: quelle restano dove sono —
   sono il gesto che si fa sempre — e la giornata cresce sotto di loro. */
.scheda--acqua .pasto__voci:not(:empty) { margin-top: .5rem; }

/* ========================================================= ingredienti == */
/*
 | I pesi di un piatto composto.
 |
 | Una riga per ingrediente, con il nome a sinistra e il peso a destra: il
 | nome puo' essere lungo quanto vuole e va a capo, il campo resta dov'e'.
 | Cosi' i campi sono incolonnati e si scende con il pollice senza rimirare
 | ogni volta dov'e' finito quello dopo.
 */
.ingredienti { display: grid; gap: .4rem; }

.ingrediente {
    display: flex; align-items: center; gap: .7rem;
    min-height: 52px; padding: .35rem .5rem .35rem .9rem;
    background: var(--carta-2); border-radius: var(--raggio-p);
}

.ingrediente__nome { flex: 1; min-width: 0; font-size: .95rem; }
.ingrediente__peso { flex: none; display: flex; align-items: center; gap: .3rem; }
.ingrediente__peso input {
    width: 5rem; min-height: 44px;
    padding: 0 .5rem;
    background: var(--carta); color: var(--inchiostro);
    border: 1.5px solid var(--linea); border-radius: 10px;
    font-size: 16px; text-align: center; font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.ingrediente__peso input:focus-visible {
    outline: none; border-color: var(--verde);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--verde) 28%, transparent);
}
.ingrediente__unita { font-size: .85rem; color: var(--fumo); }

/* --- il piatto scritto a mano ------------------------------------------- */

/* I due modi di rimediare a una ricerca a vuoto, uno accanto all'altro
   finché ci stanno e in colonna quando lo schermo è stretto. */
.vuoto__scelte {
    display: flex; flex-wrap: wrap; gap: .5rem;
    justify-content: center; margin-top: .8rem;
}

/* In fondo a ogni elenco di risultati, staccata da una riga: non è un
   risultato, è la via d'uscita per quando nessuno di quelli sopra è la cosa
   che si è mangiata. */
.coda {
    margin-top: .6rem; padding: .8rem .3rem .2rem;
    border-top: 1px solid var(--linea);
    text-align: center;
}
.coda__voce {
    margin: 0; font-size: .88rem; color: var(--fumo);
}
.vuoto__scelte .bottone { flex: 1 1 auto; }

/* Nel piatto che si sta scrivendo ogni ingrediente porta con sé i suoi
   numeri: senza, due righe con lo stesso nome e valori diversi — quello
   della tabella e quello scritto a mano — sarebbero indistinguibili. */
.ingrediente__dati {
    display: block; margin-top: .1rem;
    font-size: .8rem; color: var(--fumo);
    font-variant-numeric: tabular-nums;
}

.esiti { display: grid; gap: .3rem; }

.nuovo-ing {
    display: grid; gap: .5rem;
    padding: .8rem .7rem;
    background: var(--carta-2); border-radius: var(--raggio-p);
}
.nuovo-ing__capo {
    margin: 0; font-size: .9rem; font-weight: 600; color: var(--fumo);
}

.riga {
    display: flex; align-items: center; gap: .2rem;
    min-height: 52px; padding: .5rem .3rem .5rem .9rem;
    background: var(--carta); border-radius: var(--raggio-p);
}

/*
 | Il nome e le calorie sono un pulsante solo: toccarli apre la correzione
 | della quantita'. E' l'area piu' grande della riga, che e' giusto per
 | l'azione che si fa piu' spesso — dopo il cestino non si torna indietro,
 | dopo questa si'.
 */
.riga__apri {
    flex: 1; min-width: 0;
    display: flex; align-items: center; gap: .7rem;
    padding: .2rem 0; margin: -.2rem 0;
    text-align: left; color: inherit;
    border-radius: 10px;
    transition: transform .12s var(--molla);
}
.riga__apri:active { transform: scale(.985); }
.riga__nome { flex: 1; min-width: 0; }
.riga__nome b { display: block; font-weight: 550; }
.riga__nome span { font-size: .85rem; color: var(--fumo); }
.riga__kcal { font-weight: 700; font-variant-numeric: tabular-nums; }
.riga__kcal small { font-weight: 500; color: var(--fumo); font-size: .8rem; }

/*
 | La matita.
 |
 | Non e' un doppione del tocco sulla riga: e' la cosa che dice che la riga si
 | puo' toccare. Senza, l'unico modo di scoprirlo sarebbe provarci — e su una
 | riga che ha un cestino accanto, provarci non e' una cosa che si fa a cuor
 | leggero.
 |
 | Sta a 44 punti e non a 48 come il cestino: fra i due ci deve essere
 | abbastanza distanza perche' il pollice non prenda il cestino per sbaglio, e
 | in una riga larga come un telefono i quattro punti li vale.
 */
.riga__modifica {
    width: 44px; height: 44px; flex: none;
    display: grid; place-items: center;
    border-radius: 50%;
    transition: transform .12s var(--molla), background-color .15s ease;
}
.riga__modifica svg {
    width: 18px; height: 18px;
    fill: none; stroke: var(--fumo); stroke-width: 1.8;
    stroke-linecap: round; stroke-linejoin: round;
}
.riga__modifica:active { transform: scale(.88); background: var(--carta-2); }
.riga__modifica:active svg { stroke: var(--verde); }
.riga__modifica:focus-visible { outline: 3px solid var(--verde); outline-offset: 2px; }

/* Dentro una scheda le righe stanno su carta-2: il tocco deve schiarire, non
   confondersi con il fondo. */
.scheda--pasto .riga__modifica:active,
.scheda--pasto .riga__togli:active { background: var(--carta); }

/* Il cestino: 48 punti, la misura minima di Android per qualcosa che si
   preme, e un'area di tocco che arriva fino al bordo della riga. */
.riga__togli {
    width: 48px; height: 48px; flex: none;
    display: grid; place-items: center;
    border-radius: 50%;
    transition: transform .12s var(--molla), background-color .15s ease;
}
.riga__togli svg {
    width: 20px; height: 20px;
    fill: none; stroke: var(--fumo); stroke-width: 1.8;
    stroke-linecap: round; stroke-linejoin: round;
}
.riga__togli:active { transform: scale(.88); background: var(--carta-2); }
.riga__togli:active svg { stroke: var(--rosso); }
.riga__togli:focus-visible { outline: 3px solid var(--rosso); outline-offset: 2px; }
.riga__togli[disabled] { opacity: .4; }

.piedino {
    margin-top: 2.5rem; text-align: center;
    font-size: .82rem; color: var(--fumo);
}

/* =============================================== veli, fogli e messaggi == */

.velo {
    position: fixed; inset: 0; z-index: 40;
    background: rgba(0, 0, 0, .5);
    animation: entra .18s ease;
}
@keyframes entra { from { opacity: 0 } to { opacity: 1 } }

/*
 | Il foglio sale dal basso, come tutte le finestre di Android. Sale con una
 | translate e non cambiando l'altezza: e' l'unico modo di farlo a 120 fps.
 |
 | Il padding in fondo tiene conto della barra dei gesti: senza, l'ultimo
 | pulsante finirebbe sotto la riga bianca di HyperOS e non si potrebbe
 | premere.
 */
.foglio {
    position: fixed; z-index: 41;
    left: 0; right: 0; bottom: 0;
    max-height: 88dvh; overflow-y: auto;
    padding: .6rem var(--dx) calc(var(--giu) + 1rem) var(--sx);
    background: var(--carta);
    border-radius: 22px 22px 0 0;
    box-shadow: 0 -8px 40px rgba(0, 0, 0, .35);
    animation: sali .26s var(--molla);
    overscroll-behavior: contain;
}
@keyframes sali { from { transform: translateY(100%) } to { transform: none } }

.foglio__maniglia {
    width: 40px; height: 4px; margin: .2rem auto .9rem;
    background: var(--linea); border-radius: 2px;
}
.foglio__titolo { font-size: 1.15rem; margin-bottom: .9rem; }
.foglio__corpo { display: grid; gap: .9rem; padding-bottom: .4rem; }
.foglio__detto { color: var(--fumo); line-height: 1.45; }

.quantita {
    display: flex; align-items: center; gap: .6rem;
}
.quantita input { flex: 1; text-align: center; font-size: 1.3rem; font-weight: 700; }
.quantita button {
    width: 52px; height: 52px; flex: none;
    display: grid; place-items: center;
    background: var(--carta-2); border-radius: 50%;
    font-size: 1.5rem; font-weight: 600;
    transition: transform .12s var(--molla);
}
.quantita button:active { transform: scale(.9); }

.scorciatoie { display: flex; gap: .4rem; flex-wrap: wrap; }
.scorciatoia {
    min-height: 44px; padding: 0 .9rem;
    background: var(--carta-2); border-radius: 999px;
    font-size: .95rem; font-weight: 600;
    /* L'etichetta non va a capo e non si fa stringere: se non ci sta in
       riga, la riga va a capo. Senza, "+ bottiglietta" usciva dalla pillola
       perche' il flex la comprimeva sotto la larghezza del suo testo. */
    white-space: nowrap;
}
.scorciatoia.is-scelta { background: var(--verde); color: #04120A; }

.momenti { display: grid; grid-template-columns: repeat(4, 1fr); gap: .35rem; }
.momento {
    min-height: 48px; border-radius: var(--raggio-p);
    background: var(--carta-2); font-size: .9rem; font-weight: 600;
}
.momento.is-scelto { background: var(--verde); color: #04120A; }

.anteprima {
    text-align: center; font-size: 1rem; color: var(--fumo);
    min-height: 2.1rem;   /* il posto del numero grande resta anche quando non c'è */
}
.anteprima b { font-size: 1.7rem; color: var(--inchiostro); font-variant-numeric: tabular-nums; }
.anteprima__invito { display: inline-block; padding-top: .4rem; font-size: .95rem; }

.elenco-secco { display: grid; gap: .3rem; }
.elenco-secco > div {
    display: flex; align-items: center; justify-content: space-between; gap: .6rem;
    min-height: 52px; padding: .4rem .9rem;
    background: var(--carta-2); border-radius: var(--raggio-p);
    font-size: .98rem;
}

/* I miei alimenti: il nome apre la correzione e va a capo quando e' lungo —
   «gateau di patate confezione da 250 gr» su un telefono stretto non ci sta
   in una riga — mentre matita e cestino restano della loro misura. */
.elenco-secco--miei > div { gap: .2rem; padding-right: .3rem; }
.elenco-secco__nome {
    flex: 1; min-width: 0;
    padding: .2rem 0; text-align: left; border-radius: 10px;
}
.elenco-secco__nome b { display: block; font-weight: 550; overflow-wrap: anywhere; }
.elenco-secco__nome span { font-size: .85rem; color: var(--fumo); }
.elenco-secco__azioni { flex: none; display: flex; align-items: center; }
.elenco-secco--miei .riga__modifica:active,
.elenco-secco--miei .riga__togli:active { background: var(--carta); }

/*
 | Il messaggio breve. Sta in ALTO e non in basso, che e' l'unica scelta
 | discutibile di tutto il foglio: in basso finirebbe sotto la barra dei
 | gesti o sotto il foglio aperto, e la meta' delle volte non si vedrebbe.
 */
.brindisi {
    position: fixed; z-index: 60;
    top: calc(var(--su) + .4rem); left: 50%;
    transform: translateX(-50%);
    max-width: min(92vw, 26rem);
    padding: .7rem 1.1rem;
    background: var(--inchiostro); color: var(--fondo);
    border-radius: 999px;
    font-size: .97rem; font-weight: 600; text-align: center;
    box-shadow: 0 6px 24px rgba(0, 0, 0, .3);
    animation: scendi .22s var(--molla);
}
.brindisi.is-guaio { background: var(--rosso); color: #fff; }
@keyframes scendi {
    from { transform: translate(-50%, -140%); opacity: 0 }
    to   { transform: translate(-50%, 0);     opacity: 1 }
}

/* ============================================================== tabbar == */
/*
 | La barra di navigazione in basso.
 |
 | Sta in fondo perche' in fondo ci arriva il pollice: su uno schermo da
 | 6.67 pollici la cima e' fuori portata con una mano sola, ed e' il motivo
 | per cui ogni app di telefono tiene i comandi principali sotto e non sopra.
 |
 | Il margine inferiore passa da env(safe-area-inset-bottom): su HyperOS la
 | barra dei gesti sta SOPRA la pagina, e senza quel margine le tre voci
 | finirebbero sotto la riga bianca, dove il tocco lo prende il sistema e non
 | l'applicazione.
 */
.tabbar {
    position: fixed; z-index: 35;
    left: 0; right: 0; bottom: 0;
    display: grid; grid-template-columns: repeat(3, 1fr);
    padding: .3rem max(.5rem, env(safe-area-inset-right))
             max(.4rem, env(safe-area-inset-bottom)) max(.5rem, env(safe-area-inset-left));
    background: color-mix(in srgb, var(--fondo) 88%, transparent);
    -webkit-backdrop-filter: saturate(180%) blur(16px);
    backdrop-filter: saturate(180%) blur(16px);
    box-shadow: 0 -1px 0 var(--linea);
}

.tab {
    display: grid; justify-items: center; gap: .15rem;
    min-height: 52px; padding: .35rem .2rem;
    border-radius: 14px;
    color: var(--fumo);
    transition: color .2s ease, transform .12s var(--molla);
}
.tab svg {
    width: 24px; height: 24px;
    fill: none; stroke: currentColor; stroke-width: 1.9;
    stroke-linecap: round; stroke-linejoin: round;
}
.tab span { font-size: .74rem; font-weight: 600; }
.tab:active { transform: scale(.92); }
.tab.is-scelta { color: var(--verde); }
.tab.is-scelta svg { stroke-width: 2.3; }

/* ========================================================== calendario == */

.capo--vista { padding-block: .6rem .2rem; }

.settimana {
    display: grid; grid-template-columns: repeat(7, 1fr);
    gap: .3rem; margin: .6rem 0 .35rem;
    text-align: center;
    font-size: .74rem; font-weight: 700; letter-spacing: .08em;
    color: var(--fumo);
}

.calendario { display: grid; grid-template-columns: repeat(7, 1fr); gap: .3rem; }

/*
 | Una casella per giorno: il numero, le calorie e un pallino che dice com'e'
 | andata. Il pallino c'e' perche' scorrendo un mese si guardano i colori, non
 | i numeri: il numero serve quando ci si ferma su un giorno.
 */
.casella {
    position: relative;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: .1rem;
    min-height: 54px; padding: .3rem .1rem .55rem;
    background: var(--carta); border-radius: 12px;
    transition: transform .12s var(--molla), background-color .2s ease;
}
.casella:active { transform: scale(.93); }
.casella--vuota { background: none; }
.casella.is-futuro { opacity: .3; pointer-events: none; }
.casella.is-oggi { box-shadow: inset 0 0 0 2px var(--verde); }
.casella.is-scelto { background: var(--carta-2); }

.casella__giorno { font-size: .95rem; font-weight: 650; line-height: 1; }
.casella__kcal {
    font-size: .68rem; color: var(--fumo); line-height: 1;
    font-variant-numeric: tabular-nums;
}
.casella__kcal--niente { opacity: .45; }

.pallino { display: block; width: 6px; height: 6px; border-radius: 50%; background: var(--fumo); }
.casella .pallino { position: absolute; bottom: .3rem; }
.pallino--sotto  { background: #3FA8E0; }
.pallino--dentro { background: var(--verde); }
.pallino--oltre  { background: var(--rosso); }

.legenda {
    display: flex; flex-wrap: wrap; gap: .5rem 1.1rem;
    margin-top: 1.1rem; padding: 0 .2rem;
    font-size: .8rem; color: var(--fumo);
}
.legenda span { display: inline-flex; align-items: center; gap: .35rem; }

/* ================================================================== io == */

.io { display: grid; gap: .8rem; margin-top: .6rem; }
.separa { border: 0; border-top: 1px solid var(--linea); margin: .6rem 0 .2rem; }

.piedino__aggiorna {
    display: inline-flex; align-items: center; gap: .3rem;
    min-height: 44px; padding: 0 .7rem; margin-left: .3rem;
    border-radius: 999px; color: var(--verde);
    font-weight: 600; font-size: .84rem;
}
.piedino__aggiorna svg {
    width: 15px; height: 15px;
    fill: none; stroke: currentColor; stroke-width: 2;
    stroke-linecap: round; stroke-linejoin: round;
}
.piedino__aggiorna[disabled] { opacity: .5; }
.piedino__nuova { margin-top: -.5rem; color: var(--ambra); font-weight: 600; }

/* Il richiamo a installare l'app: compare solo se Android dice che si puo'. */
.installa {
    display: flex; align-items: center; gap: .7rem;
    margin-top: 1rem; padding: .8rem .9rem;
    background: var(--carta); border: 1.5px dashed var(--linea);
    border-radius: var(--raggio);
}
.installa p { flex: 1; font-size: .95rem; }
.installa button { flex: none; }
