/* FlowSet · il portale — foglio di stile (B4.2, 21/08/2026)

   ⚠ QUI NON NASCONO TOKEN. Colori, caratteri, raggi, ombre e scale arrivano tutti
   da `/tokens.css`, che una macchina estrae da `web/style.css` — la fonte unica di
   FlowSet — e che il portale serve accanto a questo foglio, come fa `console.py`
   per la console (console.py:1084-1085). Un colore scritto a mano qui sarebbe una
   seconda verità: il gestionale mostrerebbe un valore e il portale un altro, e
   sarebbero due prodotti. Se serve un valore nuovo si aggiunge a `web/style.css` e
   si rigenera con `tools/v1/genera_tokens.py`; `tools/v1/z78_tokens.py` diventa
   rossa se i due si allontanano.

   ⭐ Le regole di base (`.testa`, `.btn`, `.chip`, `.foglio`, `.avviso`, `.accesso`,
   `.scheda`, `.campo`) sono ricalcate su `console_web/console.css`: è lo stesso
   mestiere — un secondo processo, con la sua origine e il suo segreto, che si veste
   con i token del gestionale — e due forme diverse per la stessa cosa farebbero due
   prodotti. Qui viaggiano REGOLE di layout; i VALORI restano uno solo, nei token.

   ⚠ La CSP di casa è severa (`style-src 'self'`): nessuno stile in linea nell'HTML,
   nessun attributo `style=""`. Tutto quello che si vede passa da una classe scritta
   qui — è la stessa lezione già annotata in console.css:151-154. */

*{box-sizing:border-box}
/* invariante anti-sbordo sulla radice e non su un elenco di selettori: un elenco
   protegge solo i componenti che c'erano quando è stato scritto (lezione O) */
body{margin:0;background:var(--bg);color:var(--t1);font-family:var(--ff-sans);
     font-size:var(--fs-md);line-height:1.45;overflow-wrap:anywhere}

/* ── TESTATA ──────────────────────────────────────────────────────────────── */
.testa{display:flex;align-items:center;gap:var(--sp-2);padding:var(--sp-3) var(--sp-4);
       background:var(--surface);border-bottom:1px solid var(--border);
       position:sticky;top:0;z-index:10}
/* i titoli prendono il carattere da titolo del tema (serif in «istituzionale»): è
   quello che si vede nel gestionale, e due caratteri diversi fanno due prodotti */
.testa h1{font-family:var(--ff-display);font-size:var(--fs-lg);margin:0;font-weight:600;
          letter-spacing:-.01em}
.testa .marchio{width:26px;height:26px;border-radius:var(--r-sm);background:var(--accent);
                display:grid;place-items:center;color:#fff;font-weight:700;
                font-size:var(--fs-sm)}
.testa .spazio{flex:1}
.testa .chi{color:var(--t2);font-size:var(--fs-base)}

/* ── COMANDI ──────────────────────────────────────────────────────────────── */
/* ⚠ `white-space:nowrap` non è estetica: l'invariante anti-sbordo del body è
   ereditata e prende anche i bottoni, che a 390px spezzavano l'etichetta a metà
   parola. Il testo dell'UTENTE cede ovunque perché è imprevedibile, l'ETICHETTA di
   un comando è testo nostro, corto e noto, e non si spezza mai (console.css:35-41).
   ⚠ `min-height:44px` è la misura del polpastrello (UI_SYSTEM §responsive). */
.btn{font:inherit;font-size:var(--fs-base);padding:var(--sp-1) var(--sp-3);
     border-radius:var(--r-pill);
     border:1px solid var(--border2);background:var(--surface);color:var(--t1);
     cursor:pointer;min-height:44px;white-space:nowrap;overflow-wrap:normal}
.btn:hover{border-color:var(--accent-bord);background:var(--accent-mute)}
.btn:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.btn-forte{background:var(--accent);border-color:var(--accent);color:#fff;font-weight:600}
.btn-forte:hover{background:var(--accent-deep);border-color:var(--accent-deep)}
/* ⭐ QUI SI GIOCA IL DIVIETO 8. Il tasto «Entra» di una produzione in cui non si può
   entrare NASCE spento, e deve SEMBRARLO: senza questa regola resterebbe pieno e
   nero accanto alla frase che spiega perché non funziona — premibile a vedersi,
   inerte a premerlo. È lo stesso difetto già corretto sulla console il 04/08
   (console.css:50-59). */
.btn:disabled,.btn-forte:disabled{opacity:.42;cursor:not-allowed;box-shadow:none}
.btn:disabled:hover,.btn-forte:disabled:hover{background:var(--accent);
                                              border-color:var(--accent)}
.btn:not(.btn-forte):disabled:hover{background:var(--surface);border-color:var(--border2)}

/* ── FOGLIO ───────────────────────────────────────────────────────────────── */
/* più stretto della console (1100px): qui c'è una colonna sola di carte, e una
   riga lunga quanto uno schermo da 27" non si legge, si scorre con gli occhi */
.foglio{max-width:820px;margin:0 auto;padding:var(--sp-4)}

.avviso{background:var(--c-crit-bg);color:var(--c-crit);border-radius:var(--r-sm);
        padding:var(--sp-2) var(--sp-3);margin-bottom:var(--sp-2);font-size:var(--fs-base)}
.avviso[hidden]{display:none}

/* ⭐ 27/08/2026 (Lotto 2) · LA SCATOLA SAPEVA DIRE SOLO «HAI SBAGLIATO».
   Fino a oggi `.avviso` aveva UNA sola veste, rossa, e `portale.js:217` ci stampava
   dentro anche il messaggio di SUCCESSO del ripristino. Emanuele, 26/08: «una volta
   messa l'email giusta non dà alcun avviso di aver inviato una mail alla tua casella
   e resta il messaggio di errore precedente in sovrimpressione». Non restava: era
   nuovo, ma era rosso e diceva una frase che somigliava alla precedente — da fuori
   indistinguibile. Un avviso che non sa dire «è andata bene» insegna a non credergli.

   ⚠ IL VERDE E' MISURATO, NON SCELTO A OCCHIO. Il token `--c-ok` (#1C8753) sullo
     sfondo di questa scatola dà 3,89:1, sotto la soglia di 4,5:1 — la stessa tinta
     scurita di un passo (#177046) dà 5,25:1. In casa c'è già un contrasto rimasto
     sotto soglia (lo stato «in invio», 2,78-3,87:1, che Emanuele ha deciso il 27/08
     di lasciare e far giudicare ad Andrea): non se ne aggiunge un secondo.
   ⚠ IL ROSSO RESTA A 3,82:1, e non è una svista: cambiarlo tocca OGNI avviso già in
     produzione, ed è una decisione di Emanuele, non un effetto collaterale di questa. */
.avviso.ok{background:var(--c-ok-bg);color:#177046}

/* 27/08/2026 (Lotto 2) · LA FRASE CHE DICE COME SI ENTRA.
   Da oggi l'etichetta dice «E-mail», ma chi ha un account nato prima — e gli account di
   servizio — entra ancora col nome utente (centrale.py:2379). Senza questa riga il campo
   direbbe una cosa sola e ne accetterebbe due: chi ha il nickname si troverebbe davanti
   un modulo che sembra dirgli che non puo' entrare piu'.
   ⚠ IL COLORE E' `--t1`, NON `--t3`. Misurato su fondo bianco: `--t3` da' 2,54:1 e `--t2`
     3,82:1, contro la soglia di 4,5:1 — un'ISTRUZIONE che serve a entrare non puo' essere
     un grigino. La gerarchia la fa la DIMENSIONE (`--fs-sm`), non un contrasto che si
     legge male. In casa c'e' gia' un caso rimasto sotto soglia (lo stato «in invio»,
     2,78-3,87:1): non se ne aggiunge un altro. */
.aiuto-campo{color:var(--t1);font-size:var(--fs-sm);line-height:1.45;
             margin:var(--sp-1) 0 0;opacity:.85}


/* La riga della password temporanea: è un'INFORMAZIONE, non un allarme, e prende il
   blu che in tutto FlowSet dice «info» (--c-info). Rosso qui direbbe «hai sbagliato
   qualcosa», che non è vero: la password temporanea è come nasce ogni account. */
.nota-pw{background:var(--c-info-bg);color:var(--c-info);border-radius:var(--r-sm);
         padding:var(--sp-2) var(--sp-3);margin-bottom:var(--sp-3);font-size:var(--fs-base)}
.nota-pw[hidden]{display:none}

.conteggio{color:var(--t2);font-size:var(--fs-base);margin:0 0 var(--sp-2)}

/* ── L'ELENCO: CARTE, NON UNA TABELLA ─────────────────────────────────────────
   La console è una tabella perché un fondatore confronta decine di clienti su
   quattro colonne. Qui le righe sono una, due, forse tre, e ognuna porta con sé una
   FRASE (perché non si entra · l'invito da accettare) che in una cella di tabella
   andrebbe a capo tre volte. Il portale si apre da un link in una email, cioè quasi
   sempre da un telefono: la carta è la forma che regge quel formato. */
.prod-elenco{display:grid;gap:var(--sp-3)}
.prod{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);
      box-shadow:var(--sh-1);padding:var(--sp-3) var(--sp-4);
      display:flex;flex-wrap:wrap;gap:var(--sp-3);align-items:center}
.prod-corpo{flex:1 1 260px;min-width:0}
.prod-nome{font-family:var(--ff-display);font-size:var(--fs-lg);font-weight:600;
           letter-spacing:-.01em;line-height:1.2}
/* il codice della produzione: stesso trattamento della console (td .codice) */
.codice{font-family:var(--ff-mono);font-size:var(--fs-sm);color:var(--t3);margin-top:2px}
.prod-riga{display:flex;flex-wrap:wrap;gap:var(--sp-1);align-items:center;margin-top:8px}
.prod-ruolo{color:var(--t2);font-size:var(--fs-base)}
/* le due frasi che tengono in piedi il divieto 8: perché il tasto è spento, e che
   l'invito è ancora da accettare. Non sono decorazione, sono il contenuto. */
.prod-perche{margin:8px 0 0;color:var(--t2);font-size:var(--fs-base);line-height:1.4}
.prod-invito{margin:8px 0 0;color:var(--c-info);font-size:var(--fs-base);line-height:1.4;
             font-weight:600}
.prod-errore{margin:8px 0 0;color:var(--c-crit);background:var(--c-crit-bg);
             border-radius:var(--r-sm);padding:var(--sp-2) var(--sp-2);
             font-size:var(--fs-base)}
.prod-errore[hidden]{display:none}
.prod-azione{flex:0 0 auto}

.chip{display:inline-block;padding:3px 10px;border-radius:var(--r-pill);
      font-size:var(--fs-sm);font-weight:600;white-space:nowrap;overflow-wrap:normal}
.chip-ok{background:var(--c-ok-bg);color:var(--c-ok)}
.chip-warn{background:var(--c-warn-bg);color:var(--c-warn)}
.chip-crit{background:var(--c-crit-bg);color:var(--c-crit)}
.chip-info{background:var(--c-info-bg);color:var(--c-info)}
.chip-neutro{background:var(--s3);color:var(--t2)}

/* ── LO STATO DELLA PAGINA ────────────────────────────────────────────────────
   Tre schermate diverse per tre fatti diversi, e non si sostituiscono a vicenda:
   «sto leggendo», «non sei in nessuna produzione», «il portale non risponde». Dire
   la seconda al posto della terza fa credere a qualcuno di aver perso il lavoro —
   è la lezione già scritta in console.js:213-217. */
.attesa{padding:34px var(--sp-4);text-align:center;color:var(--t2)}
.attesa[hidden]{display:none}
.niente{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);
        box-shadow:var(--sh-1);padding:var(--sp-6) var(--sp-4);text-align:center}
.niente[hidden]{display:none}
.niente h2{font-family:var(--ff-display);font-size:var(--fs-xl);font-weight:600;
           margin:0 0 var(--sp-3)}
.niente p{margin:0 auto var(--sp-2);color:var(--t2);font-size:var(--fs-base);
          max-width:46ch;line-height:1.5}
.niente p:last-child{margin-bottom:0}

/* ── ACCESSO (login.html) ─────────────────────────────────────────────────────
   Stessa forma della porta della console (console.css:164-180): una scheda sola,
   centrata, larga al massimo 380px. */
.accesso{min-height:100dvh;display:grid;place-items:center;padding:var(--sp-5)}
.scheda{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);
        box-shadow:var(--sh-2);padding:var(--sp-6);width:min(380px,100%)}
.scheda h1{font-family:var(--ff-display);font-size:var(--fs-xl);font-weight:600;
           margin:0 0 var(--sp-4)}
.campo{margin-bottom:var(--sp-2);min-width:0}
.campo label{display:block;font-size:var(--fs-base);color:var(--t2);margin-bottom:5px}
/* ⚠ 16px REALI e non un token elastico: sotto i 16px iOS ingrandisce la pagina da
   solo quando il campo prende il fuoco, e chi entra si ritrova il portale zoomato.
   È la stessa eccezione dichiarata nella scala tipografica del gestionale. */
.campo input{width:100%;font:inherit;font-size:16px;padding:var(--sp-2) var(--sp-2);
             border-radius:var(--r-sm);background:var(--surface);color:var(--t1);
             border:1px solid var(--border2);min-height:44px}
.campo input:focus-visible{outline:2px solid var(--accent);outline-offset:1px;
                           border-color:var(--accent)}
.scheda .btn-forte{width:100%;margin-top:6px}

/* ── SCHERMI STRETTI ──────────────────────────────────────────────────────────
   Sotto i 560px la carta si impila e il tasto prende tutta la riga: un bottone
   spinto a destra di una carta stretta è un bersaglio da 90px accanto al bordo
   dello schermo, cioè il posto sbagliato dove sbagliare mira. */
@media (max-width:560px){
  .prod{flex-direction:column;align-items:stretch}
  /* ⚠ `flex:1 1 260px` in colonna NON è più una larghezza minima: quel 260px
     diventa un'ALTEZZA di partenza, e la carta si apriva con un buco bianco di
     due dita fra la produzione e il suo tasto. Visto GUARDANDO lo scatto a 390px
     col collaudo già tutto verde — la stessa strada per cui sono uscite le altre
     misure sbagliate di casa (console.css:68-75). */
  .prod-corpo{flex:1 1 auto}
  .prod-azione{width:100%}
  .prod-azione .btn{width:100%}
  .testa h1{font-size:var(--fs-md)}
}

/* ══ L10.6 (25/08/2026) · LE DUE VISTE DELLA CHIAVE ═══════════════════════════
   «Ho dimenticato la password» e «scegli la password nuova». Stessa scheda
   dell'accesso, perché sono la stessa porta in tre momenti: cambiare il vestito
   fra un passo e l'altro fa credere di essere finiti da un'altra parte. */

/* ⚠ Le tre viste stanno nella STESSA pagina e se ne mostra una per volta. Non è
   una scelta estetica: il link del ripristino arriva con la chiave DOPO IL
   CANCELLETTO (`#k=…`), e quel pezzo dell'indirizzo il browser non lo manda mai
   al server. Cambiare pagina — anche solo un rimando — la butterebbe via, e un
   link che vale una volta sola sarebbe già speso. */
.nascosto{display:none}

.sotto{color:var(--t2);font-size:var(--fs-base);margin:0 0 var(--sp-3);line-height:1.45}
.aiuto{color:var(--t3);font-size:var(--fs-sm);margin:var(--sp-2) 0 0;text-align:center}

/* Il tasto che sembra un collegamento. È un <button> e non una <a> perché non
   porta da nessuna parte: cambia quello che c'è in questa pagina. Una <a href="#">
   direbbe a chi usa un lettore di schermo «collegamento», e non lo è. */
.link-testo{font:inherit;font-size:var(--fs-sm);color:var(--t2);background:none;
  border:0;padding:0;cursor:pointer;text-decoration:underline;text-underline-offset:3px}
.link-testo:hover{color:var(--accent)}
.link-testo:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:2px}

/* ⛔ IL TASTO NASCE INVISIBILE, E LO ACCENDE IL SERVER. Se questo portale non sa
   spedire (posta spenta, `url_pubblico` non dichiarato), il tasto non compare:
   offrirlo vorrebbe dire mandare una persona chiusa fuori ad aspettare un'email
   che non arriverà mai. Meglio nessun tasto e una telefonata.
   Chi lo accende: portale.js scrive `<body data-ripristino="1">` con la risposta
   di /api/accesso-info. Stessa forma del gestionale (web/login.html:53). */
[data-acc-chiave]{display:none}
body[data-ripristino="1"] [data-acc-chiave]{display:inline}

/* ⭐ 3M (03/09/2026) · «Lavorerai al Trucco.» sotto il nome della produzione.
   ⚠ Smorzata come il resto delle righe di contorno, non in evidenza: è
     un'informazione che serve, non un avviso. L'avviso è l'invito da accettare,
     e due cose in grassetto una sotto l'altra non ne fanno risaltare nessuna. */
.prod-reparti { color: var(--t3, #666); font-size: 13px; margin: 2px 0 0; }
