/* fga/ui/static/css/app.css — foglio di stile UNICO di tutto il gestionale
   FGA (issue #39, rename 12/08/2026: si chiamava portale.css da quando
   copriva solo il pilota F3-UI del portale ristoratori, ma da tempo serve
   ANCHE le pagine agenzia — fga/ui/templates/agenzia/_layout.html lo carica
   allo stesso modo di fga/ui/templates/base.html; il nome vecchio non
   diceva piu' il vero). Nessun comportamento cambiato dal rename: stesso
   contenuto, stesso URL /static/css/app.css servito da StaticFiles.
   Registro visivo del gestionale (decisione di Giuseppe 24/08/2026 in
   chat, issue #268 — scioglie la divergenza #160): NEUTRO-BIANCO shadcn.
   Fondo pagina bianco #FFFFFF, testo Nero caldo #1C1714, grigi caldi
   "Notion" (scala slate/steel/stone + tinte calcolate color-mix qui
   sotto), hairline sottili, accento Rosso Scarlatto #D62828 RARO (mai
   testo-corpo, mai unico canale di significato — a11y: sempre glifo o
   testo accanto). L'Avorio caldo #FAF7F0 NON e' piu' un colore di
   superficie: sopravvive SOLO come tinta di testo/logo sulla navbar
   sempre nera (canone Home 21/07). Inter SOLO (self-hosted, niente Plus
   Jakarta Sans nel gestionale), tabular-nums su prezzi/quantita', mai un
   colore inventato fuori dai token. Niente oro. I token semantici dei
   componenti nuovi (#268) vivono in src/tokens.css e puntano a QUESTI
   valori: app.css resta la fonte dei colori. */

@font-face {
  font-family: "Inter";
  src: url("/static/fonts/Inter-Regular.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Inter";
  src: url("/static/fonts/Inter-SemiBold.ttf") format("truetype");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

/* Playfair Display Bold — SOLO per titoli-display (canone brand: display
   serif, solo tondo, mai corpo/testo di servizio). Estratta dal canone
   firmato 21/07 (vedi blocco token sotto): usata da .fg-titolo--display,
   NON dal .fg-titolo di base (quello resta Inter per tutti i titoli di
   pagina funzionali — "Ordini di agenzia", "Magazzino"...). */
@font-face {
  font-family: "Playfair Display";
  src: url("/static/fonts/PlayfairDisplay-Bold.ttf") format("truetype");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* Playfair Display SemiBold — il trattamento display CANONICO (sistema-
   tipografico.md §2/§5.1: peso 600, non il 700 di default) per i titoli di
   pagina della superficie portale (issue #36). Il Bold 700 qui sopra resta
   la firma del display del gestionale (canone Home 21/07). */
@font-face {
  font-family: "Playfair Display";
  src: url("/static/fonts/PlayfairDisplay-SemiBold.ttf") format("truetype");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

/* Plus Jakarta Sans — SOLO superficie portale (body.fg-portale piu' sotto):
   il sans funzionale brand FUORI dal gestionale (canone sistema-tipografico
   v3.0 §9, riga «Portale clienti HoReCa» rivista con firma 28/07 — issue
   #36). Vendorizzato come gli altri: TTF statici da Google Fonts, licenza
   SIL OFL in OFL-PlusJakartaSans.txt accanto ai file. Inter NON si carica
   in meno per questo: e' il font di tutto il resto dell'app. */
@font-face {
  font-family: "Plus Jakarta Sans";
  src: url("/static/fonts/PlusJakartaSans-Regular.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Plus Jakarta Sans";
  src: url("/static/fonts/PlusJakartaSans-SemiBold.ttf") format("truetype");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

:root {
  --fg-nero: #1c1714;
  --fg-avorio: #faf7f0;
  --fg-scarlatto: #d62828;
  --fg-raggio: 6px;
  /* color-scheme forzato a "light" (mandato M1-B, decisione Giuseppe via
     AUQ, 2026-07-20): il blocco @media (prefers-color-scheme: dark) qui
     sotto e' spento (vedi commento li'). Con color-scheme ancora "light
     dark" i controlli nativi del browser (scrollbar, checkbox, focus dei
     form nativi) si adatterebbero comunque al dark del sistema mentre i
     NOSTRI colori restano quelli chiari: un ibrido rotto, non un tema
     chiaro vero. "light" da solo tiene tutto coerente finche' il blocco
     sotto non si riaccende (un solo passo in piu', stessa istruzione). */
  color-scheme: light;

  /* — Canone Home + Statistiche, FIRMATO 21/07/2026 (fondazione grafica) —
     Token estratti 1:1 dalla variante DEFAULT dei due mockup giocabili:
     80-cantieri/fga-standalone/_lavorazione/mockup-goal-grafica-20260721/
     proposta-d-play.html (Home) + statistiche-play.html (Statistiche).
     Mai un hex inventato: ogni valore qui sotto e' copiato da li'. */
  --fg-bianco: #ffffff;           /* fondo pagina canone (era --fg-avorio) */
  --fg-canvas: var(--fg-bianco);  /* alias mockup: card/superfici bianche */
  --fg-surface: #f6f5f4;          /* sezioni sobrie (header/hover card) */
  --fg-surface-soft: #fafaf9;     /* sezioni ancora piu' leggere */
  --fg-slate: #5d5b54;            /* testo secondario Notion, 6.80:1 su bianco */
  --fg-steel: #787671;            /* testo terziario Notion, 4.54:1 su bianco */
  --fg-stone: #a4a097;            /* label mute, solo >=18px/grassetto */
  --fg-hairline: #e5e3df;
  --fg-hairline-soft: #ede9e4;
  --fg-hairline-strong: #c8c4be;
  --fg-radius-chip: 5px;
  /* control 8->6 e card 12->10 (#268 lotto 1, rubrica «raggi stretti»:
     un gestionale denso non porta i raggi delle superfici brand; deroga
     ai valori del mockup 21/07 coperta dalla licenza di Giuseppe 24/08
     «niente e' canonico al 100% per questa issue»). Il --radius 8px di
     src/tokens.css resta coerente: i controlli Basecoat usano
     radius-md = 8-2 = 6px, come qui. */
  --fg-radius-control: 6px;
  --fg-radius-card: 10px;
  --fg-shadow-hover: 0 1px 2px rgba(15, 15, 15, 0.04);
  /* Avorio a 72%: testo secondario sulla navbar nera (sempre nera, canone
     firmato) — 8,99:1 su #1C1714, ampio margine sopra il 4.5:1 AA. */
  --fg-avorio-72: color-mix(in srgb, var(--fg-avorio) 72%, transparent);

  /* Tag/pill semaforo stile Notion, gia' scuriti per AA (mockup, palette D). */
  --tag-verde-bg: #eef3ed;   --tag-verde-fg: #4d775c;
  --tag-giallo-bg: #faf3dd;  --tag-giallo-fg: #8c692d;
  --tag-blu-bg: #e9f3f7;     --tag-blu-fg: #427298;
  --tag-rosso-bg: #faecec;   --tag-rosso-fg: #bb463e;
  --tag-grigio-bg: #f1f1ef;  --tag-grigio-fg: #6e6d6b;
  --tag-brown-bg: #f3eeee;   --tag-brown-fg: #8b6450;
  --tag-purple-bg: #f6f3f8;  --tag-purple-fg: #8560a7;
  --tag-orange-bg: #f8ecdf;  --tag-orange-fg: #9d5c24;

  /* Famiglie-area per il filetto delle card (.fg-card[data-famiglia]) —
     stessa mappa dichiarata nel mockup Home, riusata da fga/ui/templates/
     home.html. Statistiche riusera' lo stesso set per le sue card KPI. */
  --fam-finanza: var(--tag-verde-fg);
  --fam-vendita: var(--tag-blu-fg);
  --fam-prodotto: var(--tag-brown-fg);
  --fam-anagrafiche: var(--tag-purple-fg);
  --fam-statistiche: var(--tag-blu-fg);
  --fam-archivio: var(--tag-grigio-fg);
  /* Fondi chiari delle STESSE famiglie (#268 lotto 2b, plancia Home):
     i -bg dei tag qui sopra, nessun colore nuovo inventato. */
  --fam-finanza-bg: var(--tag-verde-bg);
  --fam-vendita-bg: var(--tag-blu-bg);
  --fam-prodotto-bg: var(--tag-brown-bg);
  --fam-anagrafiche-bg: var(--tag-purple-bg);
  --fam-statistiche-bg: var(--tag-blu-bg);
  --fam-archivio-bg: var(--tag-grigio-bg);

  /* Tinte calcolate (non nuovi colori): nero a bassa opacita' sul fondo
     pagina. Base spostata da --fg-avorio a --fg-bianco (canone 21/07: fondo
     pagina bianco) — stessa formula/percentuali di prima, stesso principio
     "tinta calcolata, non colore nuovo", solo la base e' quella vera ora in
     pagina (scarto avorio/bianco impercettibile, ~1-2 unita' RGB). */
  --fg-bordo: color-mix(in srgb, var(--fg-nero) 22%, var(--fg-bianco));
  --fg-testo-secondario: color-mix(in srgb, var(--fg-nero) 62%, var(--fg-bianco));
  --fg-superficie: color-mix(in srgb, var(--fg-nero) 4%, var(--fg-bianco));

  /* Semaforo YoY a 7 classi (ramo Statistiche, canone firmato 21/07,
     statistiche-play.html): hex esatti dal mockup, un token per classe.
     Il grigio "nd" (nessun confronto possibile) riusa --fg-hairline-strong
     gia' esistente, nessun ottavo token per quello. */
  --sem-rosso: #cd212a;
  --sem-arancio-scuro: #ea580c;
  --sem-arancio: #f97316;
  --sem-giallo: #eab308;
  --sem-lime: #84cc16;
  --sem-verde-vivo: #22c55e;
  --sem-verde: #008c45;
}

/* Tema scuro cerimoniale — SPENTO (mandato M1-B, decisione Giuseppe via AUQ,
   2026-07-20): in due giri di collaudo sono stati fatti 34 screenshot e
   NESSUNO in tema scuro — un Mac in dark mode avrebbe mostrato domani a
   Peppino una versione dell'app mai revisionata. Commentato, non
   cancellato: le regole restano identiche e pronte, invariate dentro il
   blocco.
   PER RIACCENDERE (due passi — MAI scrivere qui sopra i simboli di apertura
   o chiusura di un commento CSS per esteso: spezzerebbero il parsing di
   questo stesso commento, esattamente il bug preso e corretto in questo
   giro): 1) cancella il delimitatore di apertura commento appena sopra la
   riga "@media (prefers-color-scheme: dark)" qui sotto, e il delimitatore
   di chiusura subito dopo la parentesi graffa finale dello stesso blocco;
   2) riporta color-scheme, qui sopra in :root, a "light dark". */
/*
@media (prefers-color-scheme: dark) {
  :root {
    --fg-nero: #faf7f0;
    --fg-avorio: #1c1714;
  }
}
*/

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

/* Fondo pagina BIANCO #FFFFFF (canone Home firmato 21/07, non piu' Avorio):
   testo nero caldo invariato. --fg-avorio resta un colore valido della
   palette (testo/pill sulla navbar sempre nera piu' sotto), solo non e'
   piu' il fondo su cui poggia il contenuto. */
body {
  font-family: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  background: var(--fg-bianco);
  color: var(--fg-nero);
  line-height: 1.5;
  /* OpenType di Inter (rubrica #268, lotto 1 — convergenza dei pareri
     esterni 24/08): character variants cv02/03/04/11 + numeri tabellari
     di default su tutto il gestionale, tracking leggermente negativo.
     tnum qui NON sostituisce .fg-tabnum (che resta il contratto esplicito
     dei prezzi/quantita'): e' il default della superficie. */
  font-feature-settings: "cv02", "cv03", "cv04", "cv11", "tnum";
  letter-spacing: -0.011em;
}

/* — SUPERFICIE PORTALE RISTORATORI (issue #36; decisione 20 del cantiere
   web-app-ristoratori, firma 28/07) — il portale e' superficie brand
   rivolta ai clienti: corpo e dati in Plus Jakarta Sans, titoli di pagina
   in Playfair Display tondo. Il gestionale resta Inter e i due sans NON si
   mescolano mai nella stessa composizione (canone sistema-tipografico.md
   §1/§9/§10.2): per questo la veste e' agganciata a body.fg-portale (block
   Jinja body_class: template portale/* + HOME quando l'utente e'
   ristoratore/sala) e mai a un selettore condiviso col gestionale.
   Il TOKEN DEL FONDO resta INVARIATO (--fg-bianco, decisione 24 del 30/07:
   la tonalita' chiara unica brand+FGA+portale e' un giro dedicato, palette
   L3 con firma di entrambi i fratelli — qui non si tocca).
   tabular-nums su prezzi/quantita': gia' garantiti da .fg-tabnum (regola
   brand piu' sotto), che vale qualunque sia il font della superficie. */
body.fg-portale {
  font-family: "Plus Jakarta Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  /* Le feature qui sopra sono le variants DI INTER: sulla superficie brand
     (PJS) non hanno senso e si azzerano (#268, lotto 1). */
  font-feature-settings: normal;
  letter-spacing: normal;
}

/* Titoli di pagina del portale («Carta Demo», «I tuoi ordini»): Playfair
   SOLO TONDO col trattamento canonico — peso 600, tracking -0.02em
   (sistema-tipografico.md §2). 1.75rem = 28px: la cautela tecnica §5.1
   (un Didone su schermo sotto ~28px assottiglia le hairline). I
   sottotitoli di sezione (.fg-sottotitolo) restano sans di proposito:
   il display e' dei titoli di pagina, non dei titoli funzionali
   (rilievo C2 del piano revisione 30/07, «dentro i limiti del canone»). */
body.fg-portale .fg-titolo {
  font-family: "Playfair Display", Georgia, serif;
  font-weight: 600;
  font-size: 1.75rem;
  letter-spacing: -0.02em;
}

/* Il display della HOME ristoratore (saluto col nome del locale) si
   allinea allo stesso trattamento 600/-0.02em: il 700/-0.01em di
   .fg-titolo--display resta la firma del canone Home del GESTIONALE
   (21/07), fuori da questa superficie. */
body.fg-portale .fg-titolo--display {
  font-weight: 600;
  letter-spacing: -0.02em;
}

/* Riga «Quando serve» delle card di Link utili (#462, portale/
   guide_link.html): il campo "quando" e' opzionale, quindi e' un TERZO <p>
   che compare solo per le voci che lo portano, subito sotto la descrizione.
   Il COLORE resta quello di .fg-testo-secondario, che sta gia' sullo stesso
   elemento; la DIMENSIONE e' quella ereditata dal corpo (16 px misurati) —
   quella classe il font-size non lo tocca, lo tocca .fg-testo-piccolo, che
   qui non c'e'. Questa regola fa SOLO spaziatura.
   Serve perche' in questo foglio non c'e' nessun reset di margine sui <p>
   (nessun selettore `p {`, e quattro discendenti — .fg-voce__inglese p,
   .fg-pop-cantina p, .fg-esito-magazzino p, .fg-modal-blocco p — nessuno
   dei quali colpisce i <p> della card), quindi ogni paragrafo prende il
   margine di default del browser, 1em.
   EFFETTO MISURATO, non supposto (Chrome headless sulla pagina vera resa
   dalla rotta, computed style + getBoundingClientRect, 08/09/2026): la
   regola toglie i 16 px di coda sotto l'ULTIMO <p> della card — spazio
   sotto la riga da 33 px a 17 px, altezza card da 154 px a 138 px.
   Lo stacco dalla descrizione NON cambia: 16 px con la regola e 16 px
   senza. Un margin-top piccolo qui sarebbe inerte, perche' i margini di due
   <p> fratelli collassano al maggiore e i 16 px di sotto della descrizione
   vincono sempre (misurato: con `margin-top: 0.35rem` il computed style
   diceva 5,6 px e il divario restava 16 px). Per riavvicinare davvero la
   riga bisognerebbe azzerare anche il margine del fratello sopra: e' una
   scelta sulla spaziatura delle card, non e' in questo perimetro.
   Scoped su body.fg-portale come le due regole qui sopra (la classe vive in
   un solo template, del portale): cosi' vince comunque su
   .fg-testo-secondario, 0,2,0 contro 0,1,0, che sta piu' giu' nel foglio e
   oggi non dichiara margini ma domani potrebbe. */
body.fg-portale .fg-link__quando {
  margin-bottom: 0;
}

/* Colore di default dei link (mandato C1, voce 2 del report 20/07,
   Lente-Fable, visibile in 03/06): senza una regola globale "a { color }"
   il browser applica il suo blu #0000EE di default — un ottavo colore
   fuori dai 7 della palette brand. I link nudi delle tabelle (es.
   agenzia/lista.html, carte_lista.html) non hanno classi dedicate, quindi
   ricadono qui. Nero-su-avorio (si inverte da solo in tema scuro, stessa
   variabile di .fg-header__nav a piu' sotto) + sottolineatura: il segnale
   "questo e' un link" resta la sottolineatura, non un colore fuori
   palette. Selettori piu' specifici (.fg-nav__link, .fg-home-card,
   a.fg-header__marchio...) vincono gia' su questo per specificita' e non
   sono toccati. */
a {
  color: var(--fg-nero);
  text-decoration: underline;
}

.fg-skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--fg-nero);
  color: var(--fg-avorio);
  padding: 0.5rem 1rem;
  z-index: 100;
}

.fg-skip:focus {
  left: 0.5rem;
  top: 0.5rem;
}

/* Navbar NERA #1C1714 (canone Home firmato 21/07: SEMPRE nera, nessuna
   variante — il playground del mockup provava anche "chiara"/"navy", la
   ricetta firmata di Giuseppe fissa "nera" come unico valore di produzione).
   Griglia a 3 colonne (fix F1, Loop 3 polish 20/08): logo/occhiello nella
   colonna centrale "auto", il cluster di destra (pill/azioni/uscita) nella
   colonna "1fr" a destra, una colonna "1fr" vuota a sinistra per bilanciare.
   PRIMA di questo giro il cluster di destra era in overlay
   (position:absolute, ancorato a destra) sopra il logo centrato: con due
   bottoni lunghi (es. scheda carta, "Fasce di markup della carta" +
   "Esporta per il cliente") il cluster si allargava verso sinistra fino a
   COPRIRE il logo — misurato su /agenzia/carte/{name} a 1280px, non solo
   sotto una soglia mobile. Una griglia non permette la sovrapposizione per
   costruzione (le colonne non si intersecano mai): con azioni molto larghe
   il logo puo' scostarsi leggermente dal centro esatto (le due colonne 1fr
   si dividono lo spazio residuo, non necessariamente in parti uguali se una
   ha piu' contenuto), ma non lo copre mai — l'esito accettato e' «quasi
   centrato», mai «sotto ai bottoni». */
.fg-header {
  position: relative;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  column-gap: 1rem;
  row-gap: 0.3rem;
  padding: 1rem 1.5rem;
  background: var(--fg-nero);
}

.fg-header__brand {
  grid-column: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
}

.fg-header__marchio {
  display: inline-flex;
}

.fg-logo {
  height: 24px;
  width: auto;
  display: block;
}

.fg-header__sotto {
  color: var(--fg-avorio-72);
  font-size: 0.85rem;
}

/* Cluster di destra (pill DATI DIMOSTRATIVI, azioni di pagina, Esci): colonna
   3 della griglia di .fg-header, incollato al bordo destro (justify-self:
   end) e con flex-wrap interno — un cluster con piu' bottoni (es. "Fasce
   markup" + "Nuova carta") va a capo su se stesso invece di allargarsi.
   Sotto la soglia qui sotto la griglia torna a una sola colonna: logo sopra,
   azioni sotto, entrambi centrati — mai in overlay, mai sullo stesso rigo se
   lo spazio manca.
   Soglia 1080px (Guardiano R2, Loop 3 polish 20/08 — misurato dal vivo su
   /agenzia/carte/{name}, cluster a 6 azioni): la soglia precedente (700px)
   era invertita rispetto al punto di rottura reale di QUESTA testata —
   a 701px l'header restava a griglia ma il cluster stretto in una sola
   colonna 1fr andava a capo su 5 righe (altezza ~335px), mentre a 700px
   la colonna singola piena larghezza ne bastavano 2 (altezza ~176px): la
   colonna singola era gia' la resa migliore ben prima dei 700px. 1080px
   e' il punto in cui la griglia due-colonne torna a valere il costo (a
   1024px, sotto soglia, singola colonna ~2 righe; a 1280px, sopra soglia,
   griglia a 3 righe — mai il caso peggiore da 5). Non tocca il 640px usato
   piu' sotto per la scheda mobile della carta vini: stesso principio di
   prima, un secondo blocco a quella soglia esatta avrebbe fatto match
   anche a una ricerca testuale che isola il blocco mobile della carta
   cercando la prima occorrenza esatta di quella soglia mobile
   (tests/api/test_frontend_m1_20260720.py), scambiando le regole di questo
   blocco per parte di quello — invariato, si tocca SOLO il valore qui
   sotto.
   R1 (stesso Guardiano): con la griglia 1fr auto 1fr la colonna 1fr di
   destra resta comunque stretta rispetto al totale del cluster (~1060px
   di bottoni non spezzati, anche a 1440px la colonna disponibile e' sotto
   quella soglia) — un minmax/fr diverso sulla terza colonna la
   allargherebbe SOLO spostando il logo fuori dal centro esatto (il
   vincolo di brand e' che le due colonne laterali restino identiche):
   scambio non pulito, quindi non fatto — sopra soglia resta wrap su piu'
   righe (3 a 1280px, 2 a 1440px), mai piu' le 5 del caso peggiore che la
   sola soglia gia' assorbe. Dichiarato, non risolto oltre questo. */
.fg-header__right {
  grid-column: 3;
  justify-self: end;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0.5rem;
}

@media (max-width: 1080px) {
  .fg-header {
    grid-template-columns: 1fr;
  }

  .fg-header__brand {
    grid-column: 1;
  }

  .fg-header__right {
    grid-column: 1;
    justify-self: center;
    justify-content: center;
    margin-top: 0.5rem;
  }
}

.fg-header__nav {
  display: flex;
  align-items: center;
  gap: 1rem;
}

/* :not(.fg-btn) (mandato C1, voce 3 del report 20/07, Lente-Fable, visibile
   in 03/06): senza l'esclusione, questa regola (specificita' 0-1-1) batteva
   ".fg-btn { text-decoration: none }" (0-1-0) — le CTA scarlatte "Nuovo
   ordine"/"Nuova carta" nella nav uscivano sottolineate, un bottone che
   sembra rotto. Niente !important, niente specificita' gonfiata a caso: si
   esclude .fg-btn dal selettore, cosi' i link VERI della nav restano
   leggibili (colore aggiornato qui sotto) e i bottoni restano governati
   solo dal contratto CTA piu' sotto (.fg-btn/.fg-btn--*).
   Colore avorio-72 (era nero): questo blocco vive SEMPRE dentro .fg-header,
   ora sempre a fondo nero — nero-su-nero sarebbe stato illeggibile. */
.fg-header__nav a:not(.fg-btn) {
  color: var(--fg-avorio-72);
  text-decoration: underline;
}

/* Bottoni/testo di servizio DENTRO l'header (sempre a fondo nero ora): le
   varianti .fg-btn--ghost/.fg-testo-secondario sono condivise con pagine a
   fondo bianco (corpo pagina) — qui uno scoping ".fg-header ..." le
   reinverte SOLO dentro l'header, senza toccare gli usi altrove nel sito
   (radar Kaizen: bottone ghost nero-su-nero, invisibile, era un rischio
   concreto appena la navbar e' diventata sempre scura). */
.fg-header .fg-btn--ghost {
  color: var(--fg-avorio);
  border-color: color-mix(in srgb, var(--fg-avorio) 35%, transparent);
}

.fg-header .fg-btn--ghost:hover {
  background: color-mix(in srgb, var(--fg-avorio) 8%, transparent);
  border-color: var(--fg-avorio);
}

.fg-header .fg-btn--secondario {
  background: var(--fg-avorio);
  color: var(--fg-nero);
}

.fg-header .fg-btn--secondario:hover {
  background: color-mix(in srgb, var(--fg-avorio) 85%, var(--fg-nero));
}

.fg-header .fg-testo-secondario {
  color: var(--fg-avorio-72);
}

/* Badge di ruolo (voce 18 del report 20/07): nel markup e' gia' uno <span>,
   mai un <a> (verificato in portale/pagina.html e fatture/pagina.html) —
   ma visivamente si confondeva coi link sottolineati e i bottoni bordati
   accanto in header. Ora ha un riempimento pieno (tinta calcolata
   --fg-bordo, gia' in uso altrove — non un colore nuovo) invece del solo
   contorno su sfondo header trasparente: si legge subito come un'etichetta
   di stato, non come qualcosa da cliccare. Peso 600 + testo pieno nero
   (contrasto alto sul riempimento) al posto del grigio-secondario tenue di
   prima. cursor:default e' difensivo, nel caso un domani il markup la
   renda per errore un elemento altrimenti interattivo. */
.fg-badge-ruolo {
  font-size: 0.85rem;
  font-weight: 600;
  padding: 0.2rem 0.6rem;
  border: 1px solid var(--fg-bordo);
  border-radius: 999px;
  background: var(--fg-bordo);
  color: var(--fg-nero);
  cursor: default;
}

/* --- Tag/pill stile Notion (canone Home firmato 21/07) -----------------
   Componente NUOVO, riusabile: puntino + testo, coppie bg/fg gia' scurite
   per AA (token --tag-*-bg/--tag-*-fg qui sopra). Distinto da .fg-badge
   (pill legacy gia' in uso su stati ordine/carta con glifo ::before): qui
   niente migrazione dei suoi 8 usi esistenti (fuori dal file-set di questo
   mandato, mai toccati alla cieca) — .fg-tag e' lo standard per i punti
   nuovi che seguono la ricetta Home/Statistiche (qui: la pill "DATI
   DIMOSTRATIVI" nell'header; i cruscotti che verranno lo riuseranno). */
.fg-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1;
  padding: 5px 9px;
  border-radius: var(--fg-radius-chip);
  white-space: nowrap;
}

.fg-tag__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}

.fg-tag--verde  { background: var(--tag-verde-bg);  color: var(--tag-verde-fg); }
.fg-tag--giallo { background: var(--tag-giallo-bg); color: var(--tag-giallo-fg); }
.fg-tag--blu    { background: var(--tag-blu-bg);    color: var(--tag-blu-fg); }
.fg-tag--rosso  { background: var(--tag-rosso-bg);  color: var(--tag-rosso-fg); }
.fg-tag--grigio { background: var(--tag-grigio-bg); color: var(--tag-grigio-fg); }
.fg-tag--brown  { background: var(--tag-brown-bg);  color: var(--tag-brown-fg); }
.fg-tag--purple { background: var(--tag-purple-bg); color: var(--tag-purple-fg); }
.fg-tag--orange { background: var(--tag-orange-bg); color: var(--tag-orange-fg); }

/* Anello di definizione sui tag DENTRO l'header (sempre a fondo nero ora):
   rifinitura, non correzione di contrasto — ogni .fg-tag ha gia' un fondo
   proprio opaco, gia' a norma AA per conto suo (stesso principio dichiarato
   nel mockup di provenienza). */
.fg-header .fg-tag {
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--fg-avorio) 16%, transparent);
}

/* Larghezza contenuto (mandato C1, voce 13 del report 20/07): a 1440px il
   contenuto restava incolonnato a sinistra con una fascia vuota a destra
   (il login "galleggiava" senza un fuoco visivo) — 72rem era gia' oltre il
   range 1000-1140px del mandato. 70rem (1120px) centrato, dentro il range,
   con lo stesso padding laterale di prima (1.5rem, gia' verificato via
   screenshot a 390px: nessun overflow sul mobile). */
.fg-main {
  max-width: 70rem;
  margin: 0 auto;
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 2rem;
}

/* overflow-x:auto (voce 13 del report 20/07, verificato dal vivo in
   browser): la tabella ordine agenzia ha 12 colonne e a 1120px (nuovo
   max-width di .fg-main qui sopra) supera comunque la larghezza
   disponibile — senza questa regola sarebbe la PAGINA a scorrere in
   orizzontale (WCAG 1.4.10 Reflow). fg-sezione e' l'unico contenitore
   comune a OGNI tabella del sito (verificato: ogni <table class="fg-tabella">
   in ogni template vive dentro una <section class="fg-sezione">), quindi
   qui e non su .fg-fieldset: provato dal vivo che .fg-fieldset NON
   contiene davvero l'overflow (i fieldset hanno un min-width intrinseco al
   contenuto, un quirk browser noto — con overflow-x:auto il fieldset
   continua a crescere oltre il contenitore invece di scrollare, mentre una
   <section> normale no). La scrollbar compare solo se il contenuto e'
   davvero piu' largo del contenitore, quindi nessun impatto sulle sezioni
   che oggi stanno larghe come .fg-main. Trade-off accettato e dichiarato:
   overflow-x diverso da 'visible' forza anche overflow-y ad 'auto' (regola
   CSS, non scelta nostra) — con fg-sezione senza altezza vincolata questo
   non taglia mai il contenuto normale, solo, in teoria, l'ultimo pixel di
   un anello di focus se un elemento focabile fosse incollato al bordo
   inferiore senza padding: rischio minimo, accettato al posto dello
   scroll orizzontale di pagina (peggiore per l'a11y). */
.fg-sezione {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  overflow-x: auto;
  /* Scroll-shadow (giro 12, piano 21/07, intervento #13 — DA COLLAUDO
     VISIVO, si ritira se il doppio gradiente stona sulle sezioni corte:
     vedi report ripianificazione 21/07 §C.5). Tecnica CSS pura via
     background-attachment local/scroll (zero JS, CSP-safe): le due
     sfumature "local" seguono lo scroll e coprono il bordo appena il
     contenuto scorre sotto, le due "scroll" restano fisse e danno il
     segnale di profondita' sul bordo. Tinte calcolate sui colori gia' in
     palette (fondo pagina pieno + nero a bassa opacita'), nessun colore
     nuovo. Le sfumature di copertura DEVONO essere del colore del fondo
     pagina: col canone 21/07 il fondo e' --fg-bianco (con l'avorio di
     prima apparivano come fasce sporche ai bordi, visto a collaudo).
     Sulle sezioni piu' strette del contenitore (nessun overflow)
     background-attachment:local le tiene invisibili da sole: zero impatto
     sulle sezioni che oggi non scrollano. */
  background:
    linear-gradient(to right, var(--fg-bianco) 30%, transparent),
    linear-gradient(to left, var(--fg-bianco) 30%, transparent) 100% 0,
    linear-gradient(to right, color-mix(in srgb, var(--fg-nero) 15%, transparent), transparent),
    linear-gradient(to left, color-mix(in srgb, var(--fg-nero) 15%, transparent), transparent) 100% 0;
  background-repeat: no-repeat;
  background-size: 2rem 100%, 2rem 100%, 1rem 100%, 1rem 100%;
  background-attachment: local, local, scroll, scroll;
}

/* Disciplina Scarlatto (giro 12, piano 21/07, intervento #9): applica qui
   la regola gia' scritta nel contratto CTA piu' sotto ("UN SOLO Scarlatto
   per vista", app.css:404) e la Carta di CORE §4 ("un solo accento
   per vista"). Titoli di pagina (.fg-titolo) e legende di sezione
   (.fg-sottotitolo) erano scarlatti OVUNQUE: una vista con piu' fieldset
   (es. Magazzino: "Giacenze"+"Registra movimento"+"Storico movimenti",
   tutte .fg-sottotitolo) mostrava fino a 5 elementi rossi sulla stessa
   schermata (Lente-Fable, giro 11) — l'accento perdeva il suo unico
   compito di indicare l'azione che chiude il task. Stesso nero gia' scelto
   per il summary GDO (commento piu' sopra, "per non moltiplicare l'accento
   su un controllo") e per gli avvisi/conferme (.fg-avviso/.fg-conferma-ok
   piu' sotto): l'unico Scarlatto di vista resta la CTA primaria
   (.fg-btn--primario) piu' gli avvisi critici esistenti (.fg-errore,
   .fg-tabnum--errore, .fg-cella--anomalia). */
.fg-titolo {
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--fg-nero);
  margin: 0;
  /* Rubrica #268 (lotto 1): titoli funzionali con tracking stretto e
     line-height compatta — il look "app 2026" senza cambiare corpo. */
  letter-spacing: -0.02em;
  line-height: 1.15;
}

/* Modificatore, NON un default: Playfair Display SOLO come titolo-display
   (canone brand, sistema-tipografico.md v3.0 — "solo tondo", mai testo di
   servizio). .fg-titolo di base resta Inter per ogni titolo funzionale di
   pagina ("Ordini di agenzia", "Magazzino"...): qui il saluto della HOME
   (mockup Home firmato 21/07, controllo "Carattere del titolo" = Playfair
   Display Bold di default). Deve stare DOPO .fg-titolo nel file per vincere
   a parita' di specificita' (0-1-0 su entrambe). */
.fg-titolo--display {
  font-family: "Playfair Display", Georgia, serif;
  font-weight: 700;
  font-size: 1.75rem;
  letter-spacing: -0.01em;
}

.fg-sottotitolo {
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--fg-nero);
  padding: 0;
  letter-spacing: -0.01em; /* rubrica #268, meta' del tracking dei titoli */
}

/* Filetto sotto i titoli di sezione del SOLO Magazzino (giro 12, piano
   21/07, intervento #6): verificato con grep che .fg-sottotitolo e'
   condiviso col portale ristoratori (legenda categoria vino + "Le cantine
   in carta"/"Vendite di fine serata"/"Nuovo ordine", portale/pagina.html)
   — toccare .fg-sottotitolo stesso avrebbe aggiunto il filetto anche li',
   effetto collaterale non richiesto. Classe dedicata, aggiunta SOLO in
   agenzia/magazzino.html accanto a .fg-sottotitolo (mai in sostituzione):
   stacco via bordo, stessa tinta calcolata --fg-bordo gia' in uso ovunque
   nel file. */
.fg-sottotitolo--sezione-magazzino {
  border-bottom: 1px solid var(--fg-bordo);
  padding-bottom: 0.35rem;
}

.fg-testo-secondario {
  color: var(--fg-testo-secondario);
}

.fg-testo-piccolo {
  font-size: 0.85rem;
}

/* --- Tab di sezione DENTRO una pagina (scheda cliente coi 4 tab,
   rifondazione IA ramo A — SPEC-FGA.md §4): ?tab=... in query string, MAI
   un tab JavaScript — ogni voce e' un <a> vero (fga/ui/templates/agenzia/
   clienti_dettaglio.html), la pagina resta un GET pieno navigabile senza
   JS, stesso principio dei link ?ricerca=/?salvato=1 gia' in uso altrove
   nell'app. Stesso linguaggio del contratto gia' scritto per la pagina
   corrente in .fg-nav__link[aria-current="page"] qui sopra: peso + filetto
   SUL NERO, MAI lo Scarlatto (riservato all'accento unico/CTA di vista —
   qui e' un indicatore di stato, non un'azione primaria). Vive dentro il
   contenuto della pagina (nero-su-bianco), non nella navbar sempre nera:
   colori invertiti rispetto a .fg-nav__link, stesso contratto semantico. */
.fg-tabs {
  border-bottom: 1px solid var(--fg-bordo);
}

/* Lotto 3 #268 (rubrica di stile, 25/08): niente wrap — con 8 tab a 375px
   la barra andava su TRE righe e i filetti attivi delle righe superiori
   galleggiavano staccati dall'hairline della barra. Pattern standard delle
   tab bar mobile: una riga sola che scrolla in orizzontale, scrollbar
   nascosta (i link restano raggiungibili da tastiera e il browser scrolla
   da se' la tab focalizzata dentro la vista). */
.fg-tabs__lista {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: nowrap;
  gap: 0 1.25rem;
  overflow-x: auto;
  scrollbar-width: none;
}

.fg-tabs__lista::-webkit-scrollbar {
  display: none;
}

.fg-tabs__link {
  display: inline-block;
  padding: 0.5rem 0;
  color: var(--fg-testo-secondario);
  text-decoration: none;
  white-space: nowrap;
  border-bottom: 2px solid transparent;
  transition: color 120ms ease, border-color 120ms ease;
}

.fg-tabs__link:hover {
  color: var(--fg-nero);
}

/* La lista e' uno scroll-container: l'anello di focus esterno (offset
   positivo, regola globale) verrebbe TAGLIATO dal clip di overflow —
   qui l'anello si disegna dentro il perimetro del link. */
.fg-tabs__link:focus-visible {
  outline: 2px solid var(--fg-nero);
  outline-offset: -2px;
}

.fg-tabs__link[aria-current="page"] {
  font-weight: 600;
  color: var(--fg-nero);
  border-bottom-color: var(--fg-nero);
}

/* Sotto prefers-reduced-motion la transizione dei tab si spegne NEL blocco
   condiviso del criterio #41 piu' sotto (quello del pannello carrello):
   un blocco @media nuovo QUI diventerebbe il primo del file e romperebbe
   il contratto di test_css_rispetta_prefers_reduced_motion, che pinna il
   carrello nel PRIMO blocco (misurato in CI, PR #412). */

.fg-fieldset {
  border: 1px solid var(--fg-bordo);
  border-radius: var(--fg-raggio);
  padding: 1rem;
  margin: 0;
}

/* Albero geografico nazione→regioni del filtro Catalogo (issue #92,
   criterio 3): le regioni annidate sotto la propria nazione, un rientro +
   un bordo sottile a sinistra — stesso linguaggio di .fg-fieldset (bordo
   var(--fg-bordo)), nessun colore nuovo introdotto. */
.fg-albero-regioni {
  margin-left: 1.5rem;
  padding-left: 0.75rem;
  border-left: 1px solid var(--fg-bordo);
}

/* --- Disclosure GDO (richiesta 2 di Giuseppe, 20/07: «un triangolino per
   ridurre» sul blocco GDO — per ora solo li', il resto della pagina si
   valuta a parte). <details>/<summary> nativi, ZERO JavaScript (la CSP di
   questo portale e' default-src 'none'/script-src 'self': niente inline,
   e comunque non serve, il disclosure e' gia' nativo del browser). I campi
   dentro un <details> CHIUSO restano nel DOM e vengono comunque inviati
   col form (l'attributo `open` governa solo il rendering visivo, non la
   partecipazione al form — verificato con un test vero end-to-end,
   tests/api/test_ordini_agenzia_ui.py): mai un dato perso in silenzio.

   Stesso bordo/raggio di .fg-fieldset qui sopra (stesso linguaggio visivo
   degli altri riquadri della pagina), padding portato dentro
   .fg-details__summary/.fg-details__corpo cosi' che da CHIUSO il
   triangolino non "galleggi" staccato dal bordo con mezzo rettangolo
   vuoto sotto.

   Il summary NON e' scarlatto come le altre legend decorative di questa
   pagina (Righe/Modifica/il titolo pagina, tutte .fg-titolo): ora e' un
   comando cliccabile che cambia stato, non un titolo passivo — l'accento
   Scarlatto "vero" di questa vista resta sulla CTA primaria
   (.fg-btn--primario, "Salva modifiche"/"Crea ordine"), qui nero (si
   inverte da solo in tema scuro) per non moltiplicare l'accento su un
   controllo. */
.fg-details {
  border: 1px solid var(--fg-bordo);
  border-radius: var(--fg-raggio);
  margin: 0;
}

.fg-details__summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--fg-nero);
  padding: 1rem;
}

/* Stesso anello di focus neutro del resto del portale (regola qui sopra su
   .fg-input/a/button): <summary> e' gia' focabile da tastiera per
   costruzione (contenuto interattivo nativo), qui solo la resa visiva. */
.fg-details__summary:focus-visible {
  outline: 2px solid var(--fg-nero);
  outline-offset: 2px;
}

.fg-details__corpo {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 0 1rem 1rem;
}

.fg-tabella {
  width: 100%;
  border-collapse: collapse;
}

.fg-tabella th,
.fg-tabella td {
  padding: 0.5rem 0.5rem;
  border-bottom: 1px solid var(--fg-bordo);
  text-align: left;
  vertical-align: middle;
}

.fg-tabella thead th {
  color: var(--fg-testo-secondario);
  font-weight: 600;
  font-size: 0.85rem;
}

/* Zebra + hover riga (giro 12, piano 21/07, intervento #4): tabelle con
   molte righe (storico movimenti, righe carta/ordine) erano un filetto
   1px ripetuto senza alcuno stacco fra riga e riga — a colpo d'occhio
   indistinguibili. Tinte calcolate (non nuovi colori): --fg-superficie
   per lo zebra pari (stessa variabile del fondo header/superfici),
   nero a bassa opacita' su avorio per l'hover (stessa formula di
   .fg-riga--anomalia piu' sotto). Esclude esplicitamente
   .fg-riga--anomalia: la riga fattura non risolta deve restare l'UNICO
   segnale della tabella, zebra/hover non la devono annacquare. */
.fg-tabella tbody tr:nth-child(even):not(.fg-riga--anomalia) {
  background: var(--fg-superficie);
}

.fg-tabella tbody tr:hover:not(.fg-riga--anomalia) {
  background: color-mix(in srgb, var(--fg-nero) 8%, var(--fg-avorio));
}

/* Riga selezionata nella lista ordini (issue #358, firma 22/08 sera —
   static/js/selezione-ordini.js): stessa famiglia di tinta calcolata dello
   hover qui sopra, un grado più scura, così la riga scelta resta leggibile
   anche sotto il mouse. Nessun colore nuovo. */
.fg-tabella tbody tr.fg-riga--selezionata,
.fg-tabella tbody tr.fg-riga--selezionata:hover {
  background: color-mix(in srgb, var(--fg-nero) 14%, var(--fg-avorio));
}

/* Riga-titolo del gruppo (issue #62, scadenzario a fasce di anzianita'): un
   <tbody> per fascia, e la PRIMA riga di ogni tbody dice quale fascia
   comincia. Senza stacco esce identica a una riga di dati — stesso <th> del
   nome fattura — e il raggruppamento si perde proprio dove deve leggersi.
   Nessun colore nuovo e nessun valore inventato: --fg-superficie e' lo
   stesso fondo dello zebra qui sopra, e il filetto 2px --fg-nero e' quello
   che tfoot usa gia' qui sotto per staccare un totale dalle sue righe.
   DOPO zebra/hover di proposito. Quello che porta il peso e' il SECONDO
   selettore: .fg-tabella tbody tr.fg-riga-gruppo:hover pesa (0,3,2) —
   .fg-tabella + .fg-riga-gruppo + :hover, piu' tbody e tr — cioe' quanto la
   regola hover qui sopra: pari specificita', vince l'ordine, e la riga-titolo
   non si schiarisce al passaggio del mouse (non e' una riga cliccabile). Il
   primo selettore pesa meno (0,2,2: nessun :hover) e da solo perderebbe
   contro lo zebra (0,3,2), ma la questione non si pone — la riga-titolo e'
   sempre il PRIMO figlio del suo <tbody>, e :nth-child(even) non prende mai
   un primo figlio; e comunque lo zebra dipinge lo stesso --fg-superficie.
   Selettore scoped su .fg-riga-gruppo, che vive in un solo template
   (agenzia/amministrazione.html). */
.fg-tabella tbody tr.fg-riga-gruppo,
.fg-tabella tbody tr.fg-riga-gruppo:hover {
  background: var(--fg-superficie);
}

.fg-tabella tbody tr.fg-riga-gruppo th {
  border-top: 2px solid var(--fg-nero);
  font-weight: 600;
}

.fg-tabella tfoot th,
.fg-tabella tfoot td {
  border-top: 2px solid var(--fg-nero);
  border-bottom: none;
  font-weight: 600;
}

/* Registro denso (issue #268, lotto 4): modifier OPT-IN per le tabelle di
   amministrazione D48 (le 8 di agenzia/amministrazione.html, inclusa quella
   di _provvigioni_corpo.html, + quella di fatture_da_rivedere.html) —
   liste lunghe da scorrere a colpo d'occhio, non pagine di lettura.
   Promozione a default su tutte le tabelle = decisione di Giuseppe, non qui.
   14px e non i 13 della rubrica #268: il floor dati del canone tipografico
   (sistema-tipografico.md) e' 14 e il canone prevale sulla rubrica.
   Riga risultante ~34-35px (14px * lh 1.5 + 2*0.4rem + filetto 1px),
   dentro il target 32-36px della rubrica. tabular-nums e' gia' globale
   (lotto 1), niente da ripetere qui. */
.fg-tabella--densa {
  font-size: 0.875rem;
}

.fg-tabella--densa th,
.fg-tabella--densa td {
  padding: 0.4rem 0.5rem;
}

/* Testata sticky frosted. Due vincoli misurati al banco:
   - con border-collapse: collapse il border-bottom di un th sticky resta
     ancorato alla riga e NON viaggia col th appiccicato → il filetto si
     disegna con box-shadow (0 1px 0 = stessa geometria del bordo);
   - lo sticky si aggancia allo scroll-container piu' vicino, e
     .fg-sezione ha overflow-x: auto (WCAG 1.4.10, vedi sopra): MISURATO
     al banco (25/08, viewport 1280) che rispetto allo scroll di PAGINA lo
     sticky e' INERTE — limite CSS noto: sticky-su-pagina e overflow-x
     sullo stesso antenato si escludono. Ad accenderlo e' il CAP in coda
     a questo blocco (lotto 4b, decisione Giuseppe 25/08 in chat, opzione
     (a) mite): solo la sezione densa che SUPERA il cap scrolla in
     verticale al suo interno, e li' lo sticky vive; le sezioni corte
     restano identiche a prima, nessuna scrollbar in piu'. */
.fg-tabella--densa thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: color-mix(in srgb, var(--fg-bianco) 85%, transparent);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  border-bottom: none;
  box-shadow: 0 1px 0 var(--fg-bordo);
}

/* Hover e riga selezionata ribasati su --fg-bianco (potatura ①, registro
   FGA = neutro-bianco shadcn): le regole generali qui sopra mescolano
   ancora sull'avorio, che su un fondo bianco sporca invece di scurire.
   Stessa formula e stesse percentuali (8% / 14%), cambia solo la base.
   Pari specificita' delle regole generali (0,3,2) → vince l'ordine. */
.fg-tabella--densa tbody tr:hover:not(.fg-riga--anomalia) {
  background: color-mix(in srgb, var(--fg-nero) 8%, var(--fg-bianco));
}

.fg-tabella--densa tbody tr.fg-riga--selezionata,
.fg-tabella--densa tbody tr.fg-riga--selezionata:hover {
  background: color-mix(in srgb, var(--fg-nero) 14%, var(--fg-bianco));
}

/* Wrapper di scroll che accende lo sticky (lotto 4b). Tre tentativi
   misurati al banco prima di arrivare qui: cap su .fg-sezione → sticky
   morto (l'aggancio vero era .fg-card, gia' overflow:auto) e card compressa
   dal flex; cap su .fg-card → sticky VIVO ma con una riga che sconfinava
   cruda nella striscia dei 16px di padding sopra il th agganciato. La
   soluzione senza artefatti e' il pattern shadcn: un wrapper dedicato
   SENZA padding attorno alla sola tabella (nei template D48) — il th
   agganciato sta a filo del bordo di scroll e il frosted copre tutto; la
   card tiene il suo padding attorno al wrapper e le liste corte non
   cambiano di un pixel (il wrapper sotto il cap non scrolla). 70vh e' un
   parametro ingegneristico dichiarato, non un valore brand: generoso
   apposta, la scrollbar nasce solo dove la lista e' davvero lunga
   (scadenze, fatture da rivedere), l'unico posto dove lo sticky serve. */
.fg-tabella-scroll {
  max-height: 70vh;
  overflow: auto;
}

/* Bug reale trovato in verifica (voce 10 del report 20/07): .fg-num da solo
   ha specificita' (0,1,0), PIU' BASSA di ".fg-tabella th, .fg-tabella td"
   qui sopra (0,1,1) — quella regola vinceva sempre e le colonne numeriche
   restavano allineate a sinistra nonostante la classe fg-num sulle celle.
   Fix: qualificare con .fg-tabella per superare quella specificita'; il
   selettore nudo resta come fallback per un eventuale fg-num fuori tabella.
   Contratto per gli altri: fg-num su <th> allinea l'header a destra come la
   colonna sottostante — non serve una classe separata per l'intestazione,
   e' la stessa da riusare (gia' cosi' in tutti i template esistenti). */
.fg-num,
.fg-tabella .fg-num {
  text-align: right;
}

/* Regola brand: tabular-nums su prezzi/quantita'. */
.fg-tabnum {
  font-variant-numeric: tabular-nums;
}

.fg-vino {
  font-weight: 400;
}

.fg-nota {
  display: block;
  color: var(--fg-testo-secondario);
  font-size: 0.85rem;
  font-weight: 400;
}

/* Nota "Ultima modifica" contenuta nella cella, solo desktop (giro 12,
   piano 21/07, intervento #8): senza un vincolo di larghezza .fg-tabella
   non ha table-layout:fixed, quindi il layout automatico dimensiona la
   colonna Rettifica sulla riga di testo piu' larga (la nota e' una sola
   riga non spezzata, allineata a destra dal .fg-num del <td> padre) — le
   righe CON nota diventavano visibilmente piu' alte/larghe di quelle
   senza. white-space:normal fa andare a capo la nota DENTRO la cella
   invece di allargare la colonna. Scoping via attribute-selector
   (td[id^="rett-cella-"]) sullo STESSO nodo che gli swap HTMX bersagliano
   (_rettifica_cella.html/_giacenza_riga.html, hx-swap="outerHTML"): il fix
   si applica da solo anche dopo lo swap, senza toccare quei due partial.
   Solo desktop: sotto 640px la cella diventa gia' display:block a piena
   larghezza (@media piu' sotto), il problema non esiste li'. */
@media (min-width: 641px) {
  .fg-tabella--carta td[id^="rett-cella-"] > .fg-nota {
    display: block;
    max-width: 11rem;
    margin-inline-start: auto;
    white-space: normal;
    text-align: right;
  }
}

.fg-input,
.fg-textarea {
  font-family: inherit;
  border: 1px solid var(--fg-bordo);
  border-radius: var(--fg-raggio);
  padding: 0.35rem 0.5rem;
  background: var(--fg-superficie);
  color: var(--fg-nero);
}

.fg-input--num {
  width: 5rem;
  text-align: right;
}

/* Campi readonly (issue #233, Nota 4 review Opus): senza questa regola
   gli input "Dal mandato" (dettaglio.html: fg-sconto-testata/fg-listino;
   il terzo d'origine, fg-payment-terms, e' ritirato da D48/#388) restavano visivamente identici a un campo
   editabile — stesso sfondo, stesso bordo, stesso caret al focus — pur
   avendo l'attributo `readonly`. Sfondo leggermente diverso (stesso token
   di :disabled qui sotto, --fg-superficie e' gia' quello ereditato da
   .fg-input quindi si usa --fg-surface per un contrasto visibile) +
   cursore "default" invece del caret di editing: nessun colore nuovo, solo
   token gia' in uso nel foglio. NIENTE opacity (a differenza di
   :disabled): il valore resta pienamente leggibile/selezionabile/copiabile
   (readonly, non disabled — vedi commento Jinja sul blocco). */
.fg-input[readonly] {
  background-color: var(--fg-surface);
  color: var(--fg-testo-secondario);
  cursor: default;
}

.fg-textarea {
  width: 100%;
  resize: vertical;
}

/* Anello di focus (voce 20 del report 20/07): prima era scarlatto pieno e
   competeva con l'unico accento di vista delle CTA (contratto qui sopra).
   Ora e' nero/avorio (var(--fg-nero), si inverte da solo in tema scuro) —
   MAI il Grigio neutro della palette: su Avorio il Grigio #B2B9B8 non
   regge il contrasto minimo 3:1 richiesto da WCAG 2.2 (2.4.11 Focus
   Appearance) contro lo sfondo, oltre a essere gia' vietato come colore di
   dettaglio fine dalla Carta di CORE. Nero-su-avorio (o l'inverso in tema
   scuro) supera ampiamente quella soglia: contrasto e visibilita' non si
   sacrificano. 2px = spessore minimo AAA per l'area del focus indicator,
   "sottile" ma sempre visibile — le CTA restano scarlatte, cambia solo
   l'anello. */
.fg-input:focus,
.fg-textarea:focus,
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--fg-nero);
  outline-offset: 2px;
}

.fg-form-inline {
  display: inline-flex;
  gap: 0.35rem;
  align-items: center;
  /* Residuo dichiarato nel checkpoint FGA: sotto ~340px (schede impilate,
     .fg-tabella--carta, content area ridotta al 58% dalla colonna-etichetta
     ::before) l'input numerico (.fg-input--num, 5rem) + il bottone
     "Aggiorna"/"Modifica" non ci stavano piu' sulla stessa riga e il
     bottone usciva dalla scheda. flex-wrap:wrap li impila in verticale
     appena servono, invariato ovunque il form ci sta gia' su una riga
     (nessuna larghezza minima cambiata, solo la possibilita' di andare a
     capo). */
  flex-wrap: wrap;
}

/* --- Contratto CTA (mandato C1, voce 9 del report 20/07) ---------------
   Regola brand: UN SOLO Scarlatto per vista. Qui si dichiara il contratto,
   non si cambiano le classi nei template (lo fa la fase dopo: oggi alcune
   pagine hanno piu' bottoni scarlatti impilati, es. carta dettaglio
   "Salva dati carta" + "Modifica carta" — verra' corretto scegliendo quale
   dei due e' l'azione primaria di quella vista).

   .fg-btn--primario  = Scarlatto. UNO per vista, mai due. E' l'azione che
                         PORTA A TERMINE il compito della vista (conferma,
                         salva, crea) — se una vista ha piu' bottoni che
                         sembrano "primari", solo quello che chiude il
                         compito resta primario, gli altri scendono a
                         secondario o ghost.
   .fg-btn--secondario = Nero pieno. Azione di supporto: importante ma non
                         quella che chiude il compito (es. "Modifica carta"
                         quando "Salva dati carta" e' gia' il primario della
                         stessa vista).
   .fg-btn--ghost      = Trasparente/contorno. Azione di servizio: minore,
                         di contesto (es. "Modifica" su una singola riga).

   Il focus ring (piu' sotto) e' SEMPRE nero, mai scarlatto: cosi' l'unico
   accento di vista resta il riempimento del bottone primario, non anche il
   suo anello di focus. */
.fg-btn {
  font-family: inherit;
  font-weight: 600;
  border-radius: var(--fg-raggio);
  padding: 0.5rem 1rem;
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
}

/* Colore letterale, NON var(--fg-avorio) (radar Kaizen, calcolato sugli hex
   dichiarati): lo Scarlatto NON si inverte mai fra i due temi (e' fisso,
   var(--fg-scarlatto) sempre #d62828), ma --fg-avorio SI' inverte in tema
   scuro (diventa #1c1714, vedi @media prefers-color-scheme:dark piu' in
   alto) — quindi con la variabile il testo del bottone primario diventava
   nero-su-scarlatto in dark, ~3,55:1, sotto il 4,5:1 minimo WCAG AA per
   testo normale. #faf7f0 fisso qui sopra da' ~4,68:1 in ENTRAMBI i temi
   (lo sfondo scarlatto non cambia mai): contrasto stabile, nessuna
   rinomina di variabili ne' cambio di semantica dei token (canone brand
   intatto, si ripara solo il contrasto). */
.fg-btn--primario {
  background: var(--fg-scarlatto);
  color: #faf7f0;
}

.fg-btn--secondario {
  background: var(--fg-nero);
  color: var(--fg-avorio);
}

.fg-btn--ghost {
  background: transparent;
  border-color: var(--fg-bordo);
  color: var(--fg-nero);
  padding: 0.35rem 0.6rem;
  font-weight: 400;
}

/* Stati :hover (giro 12, piano 21/07, intervento #5): nessuno dei 3
   bottoni aveva un segnale al passaggio del mouse oltre cursor:pointer —
   zero feedback prima del click. Tinte calcolate via color-mix sugli
   stessi token del contratto CTA qui sopra (Scarlatto/Nero/bordo), non
   colori nuovi: 85% del colore proprio + 15% di nero scurisce leggermente
   il riempimento pieno (primario/secondario); il ghost, senza
   riempimento, prende il fondo neutro --fg-superficie + un bordo che si
   scurisce a nero. */
.fg-btn--primario:hover {
  background: color-mix(in srgb, var(--fg-scarlatto) 85%, var(--fg-nero));
}

.fg-btn--secondario:hover {
  background: color-mix(in srgb, var(--fg-nero) 85%, var(--fg-avorio));
}

.fg-btn--ghost:hover {
  background: var(--fg-superficie);
  border-color: var(--fg-nero);
}

.fg-btn[disabled] {
  opacity: 0.6;
  cursor: not-allowed;
}

.fg-cantine {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
  gap: 1rem;
}

/* Canone Home firmato 21/07: card BIANCA, filetto sottile, angoli 12px —
   componente riusabile, non solo per l'hub Home (.fg-card--errore/
   --conferma qui sotto ereditano lo stesso fondo/raggio, cambia solo lo
   spessore/colore del bordo, invariato). */
.fg-card {
  background: var(--fg-canvas);
  border: 1px solid var(--fg-hairline);
  border-radius: var(--fg-radius-card);
  padding: 1rem;
  transition: background-color 150ms ease, border-color 150ms ease, box-shadow 150ms ease;
  /* Residuo dichiarato nel checkpoint FGA: sotto ~340px una tabella
     .fg-tabella "piena" (senza il trattamento responsive --carta, es. le
     giacenze/lo storico movimenti di agenzia/magazzino.html) non ha dove
     restringersi — il bottone "Aggiorna" della cella saldo usciva dal
     bordo della card invece di restare dentro. auto invece di visible: la
     card diventa lei stessa lo scroll-container orizzontale quando serve,
     nessun effetto quando il contenuto ci sta gia' (caso di gran lunga
     piu' comune: card KPI/Home, testo che va a capo). */
  overflow-x: auto;
}

.fg-card:hover {
  background: var(--fg-surface);
  box-shadow: var(--fg-shadow-hover);
}

.fg-card__titolo {
  font-weight: 600;
  margin: 0 0 0.25rem;
}

.fg-card--errore {
  border-width: 2px;
  border-color: var(--fg-nero);
}

.fg-card--conferma {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  border-width: 2px;
  border-color: var(--fg-nero);
}

/* Filetto 2px colorato PER FAMIGLIA (mockup Home, mappa dichiarata in
   fga/ui/templates/home.html): attributo data-famiglia sulla card, mai una
   classe in piu' da tenere sincronizzata a mano. Riusabile da ogni card
   futura (es. KPI di Statistiche) che porti lo stesso attributo. */
.fg-card[data-famiglia] {
  border-width: 2px;
}
.fg-card[data-famiglia="finanza"]      { border-color: var(--fam-finanza); }
.fg-card[data-famiglia="vendita"]      { border-color: var(--fam-vendita); }
.fg-card[data-famiglia="prodotto"]     { border-color: var(--fam-prodotto); }
.fg-card[data-famiglia="anagrafiche"]  { border-color: var(--fam-anagrafiche); }
.fg-card[data-famiglia="statistiche"]  { border-color: var(--fam-statistiche); }
.fg-card[data-famiglia="archivio"]     { border-color: var(--fam-archivio); }

/* Avvisi/conferme: MAI scarlatto su testo-corpo (regola del compito). Il
   colore resta nero; il significato passa da grassetto + glifo + parole,
   mai dalla tinta da sola (a11y: chi non distingue i colori legge lo
   stesso messaggio). */
.fg-avviso {
  color: var(--fg-nero);
  font-weight: 600;
}

.fg-avviso::before {
  content: "⚠ ";
}

.fg-conferma-ok {
  color: var(--fg-nero);
  font-weight: 600;
}

.fg-conferma-ok::before {
  content: "✓ ";
}

.fg-carrello__totale {
  font-size: 1.1rem;
}

.fg-htmx-indicatore {
  display: none;
  color: var(--fg-testo-secondario);
}

.htmx-request .fg-htmx-indicatore,
.fg-htmx-indicatore.htmx-request {
  display: inline;
}

.fg-elenco-ordini {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

/* Badge a pillola (giro 12, piano 21/07, intervento #2 — voci 16/17 del
   report frontend 20/07): prima era testo grigio nudo, senza bordo/sfondo,
   quasi invisibile rispetto a .fg-badge-ruolo che nella stessa app ha gia'
   un trattamento a pillola pieno e leggibile — qui si riusa lo STESSO
   linguaggio (bordo+sfondo --fg-bordo, gia' in uso, nessun colore nuovo).
   margin-left risolve voce 17 (l'etichetta "manuale" incollata al prezzo
   in agenzia/_carta_riga.html, senza spazio ne' margine nel markup
   originale): un solo intervento CSS copre tutti gli 8 punti d'uso di
   .fg-badge in un colpo solo, nessun template toccato. */
.fg-badge {
  display: inline-block;
  font-size: 0.8rem;
  font-weight: 600;
  padding: 0.15rem 0.55rem;
  margin-left: 0.4rem;
  border: 1px solid var(--fg-bordo);
  border-radius: 999px;
  color: var(--fg-nero);
  background: var(--fg-superficie);
}

/* Secondo canale sugli stati ordine (giro 12, piano 21/07, intervento #3):
   "Stato" era sempre testo piatto, indistinguibile a colpo d'occhio dalle
   altre colonne — nessun colore nuovo, il canale in piu' e' un glifo
   generato via CSS da un attributo dato (data-stato), stesso principio
   "significato mai al solo colore" gia' applicato a .fg-avviso/
   .fg-conferma-ok/.fg-cella--anomalia in questo file. I 4 stati sono
   quelli reali del modello (fga/db/models/portale.py). */
.fg-badge[data-stato="Inviato"]::before { content: "→ "; }
.fg-badge[data-stato="Confermato"]::before { content: "✓ "; }
.fg-badge[data-stato="Consegnato"]::before { content: "✓ "; }
.fg-badge[data-stato="Annullato"]::before { content: "✕ "; }

.fg-tabnum--errore {
  color: var(--fg-nero);
  font-weight: 600;
}

.fg-tabnum--errore::before {
  content: "⚠ ";
}

/* Riga anteprima fattura con articolo non risolto: indicatore visivo a colpo
   d'occhio (finding UX). Sfondo tinta calcolata (non un colore nuovo) +
   glifo/peso sulla cella interessata — mai lo scarlatto su testo-corpo, mai
   il colore come unico canale di significato (a11y, stesso canone di
   fg-avviso/fg-tabnum--errore qui sopra). */
.fg-riga--anomalia {
  background: color-mix(in srgb, var(--fg-nero) 6%, var(--fg-superficie));
}

.fg-cella--anomalia {
  color: var(--fg-nero);
  font-weight: 600;
}

.fg-cella--anomalia::before {
  content: "⚠ ";
}

.fg-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* --- Login / logout (F-auth) ------------------------------------------- */
.fg-login {
  max-width: 24rem;
}
.fg-form-login {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  margin-top: 1rem;
}
.fg-campo {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
/* Alert d'errore: filetto scarlatto (unico accento), testo in nero leggibile
   (lo scarlatto non fa mai da testo-corpo, canone brand). */
.fg-errore {
  border-left: 3px solid var(--fg-scarlatto);
  padding: 0.5rem 0.75rem;
  background: var(--fg-superficie);
  color: var(--fg-nero);
  border-radius: var(--fg-raggio);
}
/* Stato nascosto di default (sostituisce style="display:none" inline: la CSP
   style-src 'self', senza 'unsafe-inline', blocca l'attributo style="" in
   markup — verificato a runtime con Chrome headless, screenshot alla mano.
   JS che tocca .style.display via CSSOM invece NON e' toccato dalla CSP
   (stessa verifica): upload-tetto.js continua a funzionare invariato). */
.fg-nascosto {
  display: none;
}
/* Errore di validazione INLINE accanto a un campo auto-save (issue #173,
   attrito-S, D26) — stesso linguaggio visivo di .fg-errore (filetto
   scarlatto, testo nero) ma compatto: sta accanto a UN campo dentro una
   riga/cella, non occupa una card intera come un errore a pagina. */
.fg-errore-inline {
  border-left: 3px solid var(--fg-scarlatto);
  padding: 0.2rem 0.5rem;
  margin: 0.3rem 0 0;
  font-size: 0.85rem;
  color: var(--fg-nero);
}
/* Il form di logout nella navbar non deve spezzare la riga dei link. */
.fg-logout {
  display: inline;
  margin: 0;
}

/* --- Nav comune + HOME hub (mandato R1, 20/07) -------------------------
   Il marchio "Fine Goods" nell'header e' ora un link alla HOME: stesso
   stile del testo fisso di prima (scarlatto, 600, ereditato da
   .fg-header__marchio piu' sopra), solo senza la sottolineatura di default
   di un <a>. Regola additiva: la dichiarazione esistente NON viene toccata,
   qui solo un override mirato sul comportamento da link. */
a.fg-header__marchio {
  text-decoration: none;
}

/* Nav condivisa (_nav.html, inclusa da base.html e agenzia/_layout.html):
   fascia SOTTO l'header, trattata come la stessa "fascia scura" dell'header
   (canone Home firmato 21/07: navbar sempre nera) — .fg-nav-wrap porta il
   fondo/bordo a piena larghezza, .fg-nav centra il contenuto sullo stesso
   max-width di .fg-main (70rem) cosi' testata e corpo pagina si allineano.
   flex-wrap su .fg-nav__lista regge il mobile 390px andando a capo invece
   di generare scroll orizzontale — nessun @media dedicato, stesso pattern
   gia' in uso da .fg-header. */
.fg-nav-wrap {
  background: var(--fg-nero);
  border-bottom: 1px solid color-mix(in srgb, var(--fg-avorio) 14%, transparent);
}

.fg-nav {
  max-width: 70rem;
  margin: 0 auto;
  padding: 0.5rem 1.5rem;
}

/* Menu <details> della testata F4 (#268 lotto 2): il summary-hamburger
   esiste SOLO sotto i 640px (breakpoint gemello di fga-nav.js — se cambia
   qui deve cambiare la'). Sopra: summary nascosto, il details resta open
   (markup + fga-nav.js) e la lista e' la barra orizzontale di sempre. */
.fg-nav__hamburger {
  display: none;
}

.fg-nav__lista {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.3rem 1.25rem;
}

@media (max-width: 40rem) {
  .fg-nav__hamburger {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    cursor: pointer;
    color: var(--fg-avorio-72);
    border: 1px solid color-mix(in srgb, var(--fg-avorio) 35%, transparent);
    border-radius: var(--fg-radius-control);
    padding: 0.45rem 0.8rem;
    font-weight: 600;
    user-select: none;
    /* niente triangolo di default del summary */
    list-style: none;
  }

  .fg-nav__hamburger::-webkit-details-marker {
    display: none;
  }

  .fg-nav__hamburger:hover,
  .fg-nav__menu[open] .fg-nav__hamburger {
    color: var(--fg-avorio);
    background: color-mix(in srgb, var(--fg-avorio) 8%, transparent);
    border-color: var(--fg-avorio);
  }

  .fg-nav__lista {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin-top: 0.5rem;
    border-top: 1px solid color-mix(in srgb, var(--fg-avorio) 14%, transparent);
    padding-top: 0.25rem;
  }

  /* Voci a tutta riga con area di tocco comoda (>=40px). */
  .fg-nav__lista .fg-nav__link {
    display: block;
    padding: 0.55rem 0.25rem;
    border-bottom: none;
  }

  .fg-nav__link[aria-current="page"] {
    border-left: 2px solid var(--fg-avorio);
    padding-left: 0.6rem;
  }
}

.fg-nav__link {
  display: inline-block;
  padding: 0.15rem 0;
  color: var(--fg-avorio-72);
  text-decoration: none;
  border-bottom: 2px solid transparent;
}

.fg-nav__link:hover {
  color: var(--fg-avorio);
}

/* Pagina corrente: peso + filetto, MAI lo scarlatto (riservato all'accento
   unico/CTA di vista — qui non e' un'azione primaria, e' un indicatore di
   stato). Stesso principio "significato mai al solo colore" del resto del
   foglio: il peso del font porta il significato quanto il filetto. */
.fg-nav__link[aria-current="page"] {
  font-weight: 600;
  color: var(--fg-avorio);
  border-bottom-color: var(--fg-avorio);
}

/* Casella «Cerca» unica in navbar (issue #102): sotto le voci, centrata sullo
   stesso asse, con un tetto di larghezza — a piena larghezza dentro una barra
   nera leggerebbe come un secondo header, non come un campo. Nessun colore
   nuovo: il campo resta .fg-input (stessa veste dei form di pagina) e il
   bottone .fg-btn--ghost, gia' pensato per fondo scuro. flex-wrap per la
   stessa ragione di .fg-nav__lista: a 390px va a capo invece di generare
   scroll orizzontale. */
.fg-nav__cerca {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0.5rem;
  margin: 0.5rem auto 0;
  max-width: 34rem;
}

.fg-nav__cerca .fg-input {
  flex: 1 1 14rem;
  min-width: 0;
}

/* Stessa reinversione di .fg-header .fg-btn--ghost: la casella vive in
   .fg-nav-wrap (fondo scuro) ma fuori da .fg-header, quindi il ghost
   restava nero-su-nero. */
.fg-nav__cerca .fg-btn--ghost {
  color: var(--fg-avorio);
  border-color: color-mix(in srgb, var(--fg-avorio) 35%, transparent);
}

.fg-nav__cerca .fg-btn--ghost:hover {
  background: color-mix(in srgb, var(--fg-avorio) 8%, transparent);
  border-color: var(--fg-avorio);
}

/* Griglia card HOME: stesso pattern a griglia responsiva di .fg-cantine
   piu' sopra (auto-fill, minmax), qui con una card cliccabile intera
   (titolo + descrizione) invece di un elenco testuale. */
/* max-width (giro 12, piano 21/07, intervento #7): auto-fill senza un
   tetto di larghezza distanzia le card su schermi larghi finche' l'ultima
   riga resta con una sola card sperduta accanto a colonne vuote (5 card
   staff -> 4+1 su desktop largo: la card orfana legge come un layout
   rotto, non intenzionale). 54rem tiene 3 colonne piene ovunque le card
   ci stiano (5 card -> 3+2, mai 4+1): stessa minmax(16rem,1fr) di prima,
   cambia solo il tetto del contenitore. */
.fg-home-griglia {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
  gap: 1rem;
  max-width: 54rem;
}

/* .fg-home-card si applica INSIEME a .fg-card (bordo/padding/raggio gia'
   definiti piu' sopra): qui solo cio' che serve per farne un link a blocco
   pulito (mai il blu/sottolineato di default di un <a>, il colore resta
   ereditato dal testo nero circostante). */
.fg-home-card {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  text-decoration: none;
  color: inherit;
}

.fg-home-card:hover,
.fg-home-card:focus-visible {
  border-color: var(--fg-nero);
}

.fg-home-card__titolo {
  font-weight: 600;
  color: var(--fg-nero);
}

.fg-home-card__descrizione {
  color: var(--fg-steel);
  font-size: 0.9rem;
}

/* --- Carta vini responsiva: schede impilate su mobile (mandato M1-A,
   decisione Giuseppe via AUQ, 2026-07-20) --------------------------------
   Il problema (eletto "la cosa sola" da due lenti critiche indipendenti,
   report frontend 20/07): a 390px la tabella della carta mostra Vino,
   Giacenza, Prezzo, Rettifica — "Vendute oggi" e soprattutto "Ordina"
   finiscono oltre il bordo del fieldset, con lo scroll orizzontale
   invisibile a riposo su iOS. "Ordina" e' il compito primario del
   ristoratore, sul suo dispositivo vero (in piedi, in sala, una mano sola).

   Soglia 640px, scelta nel range 600-720px indicato dal compito: copre con
   margine ogni telefono in verticale di oggi (iPhone 14/15 390px, i Pro Max
   430px, Android medi 360-428px) restando sotto un iPad in verticale
   (768px, che resta tabella) — la stessa soglia "sm" di molti design
   system, usata qui per la stessa ragione: separa "telefono in mano" da
   "tablet/desktop appoggiato".

   Scoping a .fg-tabella--carta (SOLO la tabella della carta vini in
   portale/pagina.html — stesso pattern di modificatore gia' in uso per
   .fg-tabella--carrello in _carrello.html): .fg-tabella nudo resta
   la tabella di agenzia-ordini/fatture (12 colonne, altro file-set, fuori
   da questo mandato) — zero effetti collaterali li'.

   La STRUTTURA resta table/thead/tbody/tr/th/td (obbligatorio: gli swap
   HTMX mirano a id precisi su questi stessi tag — vedi _giacenza_riga.html,
   _rettifica_cella.html, _qta_input.html, _magazzino_esito.html; cambiare tag
   romperebbe ogni hx-target). Cambia SOLO la presentazione via CSS in un
   file 'self' (CSP style-src invariata: nessuno style="" inline nel
   markup, content: attr()/stringa qui e' CSS puro).

   Etichette per cella via ::before posizionale (nth-of-type), non un
   attributo data-label sul markup: la cella "Rettifica" e' l'unico <td>
   emesso da un frammento fuori dal file-set di oggi (_rettifica_cella.html,
   altro proprietario) — i selettori posizionali qui la etichettano lo
   stesso senza toccare quel file. L'ordine colonne e' fisso e condiviso
   col <thead> (Vino, Giacenza, poi — solo per il titolare — Prezzo,
   Rettifica, Vendute oggi, Ordina): nth-of-type(1) e' sempre Giacenza,
   (2)-(5) le colonne extra del titolare, stesso ordine del <thead>.

   Le micro-etichette inline "Vendute"/"Ordina" (span.fg-nota
   aria-hidden="true" accanto ai due input gemelli, gia' in pagina.html)
   si spengono qui sotto SOLO in questa vista: servivano a distinguere due
   input identici affiancati nella stessa riga desktop, ridondanti ora che
   ogni campo ha la sua etichetta di cella su una riga propria. Erano gia'
   invisibili alla lettura assistita (aria-hidden), quindi il display:none
   qui non toglie nulla in piu' li'.

   Accessibilita': il <thead> si nasconde SOLO visivamente (stesso pattern
   clip di .fg-sr-only sopra, non display:none) — resta nell'albero di
   accessibilita' per chi naviga il documento per intestazioni. Il testo
   generato via ::before pero' non e' garantito in ogni combinazione
   browser/screen reader (limite noto della tecnica, non specifico di
   questo file): la rete di sicurezza reale per i controlli restano i
   <label for> e gli aria-label gia' presenti riga per riga (Rettifica,
   Vendute oggi, Ordina — invariati, vedi pagina.html), sempre
   nell'albero di accessibilita' a prescindere dal CSS. Per le celle senza
   controllo proprio (Giacenza, Prezzo, Rettifica in sola lettura)
   l'etichetta visibile e' l'unica compensazione disponibile in questo
   giro per la relazione intestazione/cella: dichiarato, non nascosto. */
@media (max-width: 640px) {
  .fg-tabella--carta thead {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }

  .fg-tabella--carta,
  .fg-tabella--carta tbody,
  .fg-tabella--carta tr,
  .fg-tabella--carta th,
  .fg-tabella--carta td {
    display: block;
    width: 100%;
  }

  .fg-tabella--carta tbody tr {
    padding: 0.75rem 0;
    border-bottom: 1px solid var(--fg-bordo);
  }

  .fg-tabella--carta tbody tr:last-child {
    border-bottom: none;
  }

  .fg-tabella--carta th[scope="row"] {
    font-size: 1rem;
    font-weight: 600;
    border-bottom: none;
    padding: 0 0 0.5rem;
  }

  .fg-tabella--carta tbody td {
    position: relative;
    border-bottom: none;
    padding: 0.35rem 0 0.35rem 42%;
    min-height: 1.5rem;
  }

  .fg-tabella--carta tbody td::before {
    position: absolute;
    left: 0;
    top: 0.35rem;
    width: 38%;
    font-weight: 600;
    font-size: 0.8rem;
    color: var(--fg-testo-secondario);
  }

  .fg-tabella--carta tbody td:nth-of-type(1)::before { content: "Giacenza"; }
  .fg-tabella--carta tbody td:nth-of-type(2)::before { content: "Prezzo"; }
  .fg-tabella--carta tbody td:nth-of-type(3)::before { content: "Rettifica"; }
  .fg-tabella--carta tbody td:nth-of-type(4)::before { content: "Vendute oggi"; }
  .fg-tabella--carta tbody td:nth-of-type(5)::before { content: "Ordina"; }

  .fg-tabella--carta tbody td span.fg-nota[aria-hidden="true"] {
    display: none;
  }

  /* Touch target "Modifica" (giro 12, piano 21/07, intervento #12): su
     mobile .fg-btn--ghost regge il minimo WCAG 2.5.8 AA (24px) ma resta
     sotto il target AAA consigliato (44px) — qui il bottone si ripete una
     volta per riga vino, su un dispositivo "in piedi, in sala, una mano
     sola" (stessa motivazione del breakpoint qui sopra). Scoping SOLO
     alla tabella carta (.fg-tabella--carta .fg-btn--ghost): non tocca gli
     altri usi di .fg-btn--ghost nel sito (card "Stampa" in storico
     ordini, "Annulla" in editing, bottoni di agenzia — altro file-set). */
  .fg-tabella--carta .fg-btn--ghost {
    padding: 0.55rem 0.9rem;
  }
}

/* --- Larghezze quantizzate per barre (mandato fondazione, 21/07) -------
   La CSP style-src 'self' vieta style="width:NN%" inline: il ramo
   Statistiche calcola una percentuale per barra (fatturato/andamento
   mensile, mockup statistiche-play.html) e la traduce in una di queste
   classi invece di un attributo style. Passo 2% (51 classi, 0-100):
   il chiamante arrotonda al passo piu' vicino, mai un valore fuori da
   questo set. Nessun colore qui dentro: solo width, il colore della
   barra (semaforo YoY) vive nelle classi .fg-barra-fill--* del ramo
   Statistiche (fuori da questo mandato). */
.fg-w-0 { width: 0%; }
.fg-w-2 { width: 2%; }
.fg-w-4 { width: 4%; }
.fg-w-6 { width: 6%; }
.fg-w-8 { width: 8%; }
.fg-w-10 { width: 10%; }
.fg-w-12 { width: 12%; }
.fg-w-14 { width: 14%; }
.fg-w-16 { width: 16%; }
.fg-w-18 { width: 18%; }
.fg-w-20 { width: 20%; }
.fg-w-22 { width: 22%; }
.fg-w-24 { width: 24%; }
.fg-w-26 { width: 26%; }
.fg-w-28 { width: 28%; }
.fg-w-30 { width: 30%; }
.fg-w-32 { width: 32%; }
.fg-w-34 { width: 34%; }
.fg-w-36 { width: 36%; }
.fg-w-38 { width: 38%; }
.fg-w-40 { width: 40%; }
.fg-w-42 { width: 42%; }
.fg-w-44 { width: 44%; }
.fg-w-46 { width: 46%; }
.fg-w-48 { width: 48%; }
.fg-w-50 { width: 50%; }
.fg-w-52 { width: 52%; }
.fg-w-54 { width: 54%; }
.fg-w-56 { width: 56%; }
.fg-w-58 { width: 58%; }
.fg-w-60 { width: 60%; }
.fg-w-62 { width: 62%; }
.fg-w-64 { width: 64%; }
.fg-w-66 { width: 66%; }
.fg-w-68 { width: 68%; }
.fg-w-70 { width: 70%; }
.fg-w-72 { width: 72%; }
.fg-w-74 { width: 74%; }
.fg-w-76 { width: 76%; }
.fg-w-78 { width: 78%; }
.fg-w-80 { width: 80%; }
.fg-w-82 { width: 82%; }
.fg-w-84 { width: 84%; }
.fg-w-86 { width: 86%; }
.fg-w-88 { width: 88%; }
.fg-w-90 { width: 90%; }
.fg-w-92 { width: 92%; }
.fg-w-94 { width: 94%; }
.fg-w-96 { width: 96%; }
.fg-w-98 { width: 98%; }
.fg-w-100 { width: 100%; }

/* --- Cruscotto Statistiche: KPI + barre mensili (mandato mixaggio, 21/07,
   canone firmato statistiche-play.html) — hex/valori copiati 1:1 dal
   mandato, nessun colore inventato. */
.fg-kpi-riga {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 320px));
  gap: 12px;
  margin-bottom: 8px;
}

.fg-kpi-etichetta {
  display: block;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--fg-steel);
  margin-bottom: 8px;
}

.fg-kpi-valore {
  display: block;
  font-size: 26px;
  font-weight: 600;
  color: var(--fg-nero);
  letter-spacing: -0.01em;
}

.fg-barre {
  display: flex;
  flex-direction: column;
  gap: 9px;
  background: var(--fg-canvas);
  border: 1px solid var(--fg-hairline-soft);
  border-radius: var(--fg-radius-control);
  padding: 20px 20px 18px;
}

/* Colonna mese allargata a 84px (era 44px nel mockup) per ospitare i mesi
   in italiano per esteso, es. "Settembre" — deviazione dichiarata dal
   mandato del mixaggio, stesso motivo del canone (leggibilita' del mese,
   non un capriccio grafico). */
.fg-barra-riga {
  display: grid;
  grid-template-columns: 84px 1fr 100px 76px;
  align-items: center;
  gap: 12px;
  font-size: 13px;
}

.fg-barra-mese {
  color: var(--fg-slate);
  font-weight: 600;
}

.fg-barra-traccia {
  background: var(--fg-surface);
  border-radius: 4px;
  height: 14px;
  overflow: hidden;
}

.fg-barra-fill {
  display: block;
  height: 100%;
  background: var(--fam-statistiche);
  border-radius: 4px 0 0 4px;
}

.fg-barra-fill[data-classe="-3"] { background: var(--sem-rosso); }
.fg-barra-fill[data-classe="-2"] { background: var(--sem-arancio-scuro); }
.fg-barra-fill[data-classe="-1"] { background: var(--sem-arancio); }
.fg-barra-fill[data-classe="0"]  { background: var(--sem-giallo); }
.fg-barra-fill[data-classe="1"]  { background: var(--sem-lime); }
.fg-barra-fill[data-classe="2"]  { background: var(--sem-verde-vivo); }
.fg-barra-fill[data-classe="3"]  { background: var(--sem-verde); }
.fg-barra-fill[data-classe="nd"] { background: var(--fg-hairline-strong); }

.fg-barra-valore {
  text-align: right;
  color: var(--fg-slate);
  font-size: 13px;
  white-space: nowrap;
}

.fg-barra-delta {
  text-align: right;
  font-size: 12px;
  color: var(--fg-slate);
  white-space: nowrap;
}

/* Mixaggio suite piena (giro completamento funzioni, 21/07 sera): 3 aggiunte
   richieste dai rami, token esistenti, nessun colore nuovo. */

/* a.fg-tag come link (pillola filtro attivo rimovibile in catalogo.html):
   .fg-tag non aveva mai fatto da <a>, la regola globale "a { text-decoration:
   underline }" rovinava l'aspetto a pillola. Solo estetico, nessun test rotto
   senza. */
a.fg-tag {
  text-decoration: none;
}

a.fg-tag:hover {
  filter: brightness(0.95);
}

/* Accento Scarlatto sul premio >=85/100 da testata-faro (Carta di CORE §4)
   in catalogo_scheda.html. Secondo canale già presente nel testo (glifo
   "★"), il filetto è rifinitura visiva, mai il colore da solo. */
.fg-cella--premio-evidenza {
  border-left: 3px solid var(--fg-scarlatto);
  font-weight: 600;
  padding-left: 0.5rem;
}

/* Slot allegato incasso (foto assegno/PDF contabile): input file nativo
   stilizzato a zona di rilascio, zero JS (CSP 'self'). Senza questa classe
   l'<input type="file"> resta comunque valido, solo senza lo stile a
   zona di rilascio. */
.fg-file-drop {
  display: block;
  width: 100%;
  padding: 1.1rem 0.75rem;
  border: 1px dashed var(--fg-hairline-strong);
  border-radius: var(--fg-radius-control);
  background: var(--fg-surface-soft);
  color: var(--fg-slate);
  font-family: inherit;
  font-size: 0.9rem;
  cursor: pointer;
}

.fg-file-drop:hover {
  border-color: var(--fg-steel);
}

.fg-file-drop:focus-visible {
  outline: 2px solid var(--fg-nero);
  outline-offset: 2px;
}

.fg-file-drop::file-selector-button {
  font-family: inherit;
  font-weight: 600;
  border: 1px solid var(--fg-bordo);
  border-radius: var(--fg-radius-chip);
  padding: 0.3rem 0.7rem;
  margin-inline-end: 0.6rem;
  background: var(--fg-bianco);
  color: var(--fg-nero);
  cursor: pointer;
}

.fg-file-drop::file-selector-button:hover {
  background: var(--fg-surface);
}

/* --- GRAFICA-2 «le tendine» (critica di Giuseppe 21/07: "puoi fare di
   meglio specialmente nei dettagli, ad esempio le tendine") — mandato
   mixaggio 22/07 -----------------------------------------------------------
   Prima di questo blocco <select class="fg-input"> ereditava SOLO le regole
   generiche di .fg-input (bordo/raggio/padding/sfondo): la freccina restava
   quella nativa del sistema operativo, mai disegnata da noi — l'unico
   dettaglio "grezzo" rimasto in un portale altrimenti rifinito.

   Freccia custom via file SVG statico (fga/ui/static/img/chevron-select.svg,
   vedi il commento in testa a quel file per il perche' NON e' un data: URI
   inline): la CSP di questo portale ha `img-src 'self'` senza `data:`
   (fga/api/__init__.py, blocco _CSP) — un background-image:url("data:...")
   sarebbe stato bloccato silenziosamente dal browser (nessuna eccezione
   JS, solo una freccia invisibile), verificato leggendo la direttiva prima
   di scegliere la tecnica. `appearance:none` toglie la resa nativa del
   browser (freccia + padding/bordo non uniformi fra Chrome/Firefox/Safari):
   da qui in poi altezza/padding tornano PIENAMENTE quelli di .fg-input,
   coerenti col resto del form, non un'imitazione approssimata.

   input[list] (i campi con <datalist>, bullet B1 del ramo "ordini di
   agenzia" — es. "Codice articolo" in agenzia/dettaglio.html/magazzino.html)
   ricevono la STESSA freccia: sono anch'essi un controllo "assistito da un
   elenco", la resa nativa del suggerimento (tutt'altro che uniforme fra
   browser: Firefox disegna una sua freccia, Chrome nessuna) diventava
   un'incoerenza visiva proprio accanto alle <select> appena rifinite.
   `::-webkit-calendar-picker-indicator{display:none}` toglie la SECONDA
   freccia nativa che Chrome/Edge disegnano di loro su un input con `list`
   (stesso pseudo-elemento di <input type="date">) — senza questa riga si
   sarebbero viste due frecce sovrapposte. */
select.fg-input,
input.fg-input[list] {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  background-color: var(--fg-superficie);
  background-image: url("/static/img/chevron-select.svg");
  background-repeat: no-repeat;
  background-position: right 0.6rem center;
  background-size: 12px 12px;
  padding-right: 2.1rem;
  cursor: pointer;
}

input.fg-input[list] {
  /* Un campo testo con suggerimenti resta un campo testo: si digita,
     non si "apre" come una select — cursor:text (non pointer) e' il
     segnale corretto, la freccia da sola basta a dire "c'e' un elenco". */
  cursor: text;
}

input.fg-input[list]::-webkit-calendar-picker-indicator {
  display: none;
}

/* Hover sobrio (stesso principio gia' dichiarato per .fg-btn--ghost/.fg-card
   piu' sopra: un segnale prima del click, tinta calcolata non un colore
   nuovo) + stato disabled leggibile: niente della resa "morta" di un
   controllo nativo disabilitato, lo stesso linguaggio di .fg-btn[disabled]. */
select.fg-input:hover:not(:disabled),
input.fg-input[list]:hover:not(:disabled) {
  border-color: var(--fg-nero);
}

select.fg-input:disabled,
input.fg-input[list]:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  background-color: var(--fg-superficie);
}

/* Option leggibili (mandato grafica-2): sfondo/testo espliciti invece di
   ereditare il default del sistema operativo — Firefox rispetta questa
   regola sul popup nativo, Chrome/Safari la rispettano parzialmente (limite
   noto della piattaforma, non di questo foglio: il popup nativo di una
   <select> non e' interamente stilizzabile via CSS senza un widget JS
   dedicato, fuori scope per un portale "zero JS custom fuori da HTMX"). */
select.fg-input option {
  color: var(--fg-nero);
  background: var(--fg-bianco);
}

/* Microdettaglio form (stessa cura richiesta dal mandato mixaggio):
   spaziatura/peso dell'etichetta dentro ogni .fg-campo, finora ereditati dal
   default del browser (peso normale, stesso nero del testo di corpo — poco
   distinguibile dal valore sottostante). Scoping a `.fg-campo label` (mai
   `label` nudo): .fg-campo e' gia' il wrapper standard di OGNI coppia
   etichetta+controllo del portale staff (verificato: 95 usi in
   fga/ui/templates/agenzia/*.html contro 91 <label> totali, praticamente
   tutte le etichette del sito passano di qui), quindi la rifinitura arriva
   ovunque senza toccare un solo template. */
.fg-campo label {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--fg-testo-secondario);
}

/* --- Carrello a scomparsa — issue #41 -----------------------------------
   Pattern C «Banco di servizio» (mockup firmato, decisione 27 del cantiere
   web-app-ristoratori). Due pezzi: la LEVA fissa, sempre a schermo col
   conteggio delle bottiglie, e il PANNELLO (<dialog> modale) che si apre
   solo quando serve — prima il carrello era una sezione in fondo alla
   pagina, cioe' fuori schermo esattamente mentre si compilavano le
   quantita'.

   Contrasti CALCOLATI (formula WCAG, non a occhio):
   - testo leva, avorio #FAF7F0 su nero #1C1714 = 16,6:1 (AAA);
   - pieno barra, nero su pista #E5E3DF = 13,86:1 (>= 3:1 per componenti);
   - pieno «completo», verde #4D775C su pista = 3,99:1.
   La pista contro il fondo bianco resta a 1,74:1 di proposito: il confine
   della pista non porta informazione (il dato sta nel testo sotto la barra,
   sempre presente, e nel contrasto pieno-vs-pista) — la barra e' un canale
   ridondante, mai l'unico.

   Un solo accento per vista (Carta §3): la leva e' NERA. Lo scarlatto resta
   al bottone «Conferma ordine», che vive dentro il pannello. */

.fg-leva-carrello {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  /* Su iPhone la home-bar mangia la fascia bassa: la leva sale di quanto
     serve, zero quando la safe-area non esiste (desktop). */
  bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
  z-index: 30;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.75rem 1.1rem;
  border: 0;
  border-radius: 999px;
  background: var(--fg-nero);
  color: var(--fg-avorio);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  /* Le ombre e gli scrim di questo file restano rgba(28,23,20,...) DI
     PROPOSITO: convertirli a var(--fg-nero) li farebbe diventare bagliori
     avorio dentro la veste Notturna, che inverte --fg-nero. Un eventuale
     token ombra dedicato e' una scelta di design, non una bonifica. */
  box-shadow: 0 2px 10px rgba(28, 23, 20, 0.22);
}

.fg-leva-carrello:hover {
  background: #2a231f;
}

.fg-leva-carrello__voce {
  font-size: 0.95rem;
}

.fg-leva-carrello__conteggio {
  min-width: 1.6rem;
  padding: 0.05rem 0.4rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--fg-avorio) 16%, transparent);
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.fg-leva-carrello__totale {
  padding-left: 0.6rem;
  border-left: 1px solid color-mix(in srgb, var(--fg-avorio) 28%, transparent);
  font-variant-numeric: tabular-nums;
}

/* Coda di pagina sotto la leva: uno spaziatore reso solo quando la leva
   esiste (portale/pagina.html, ristoratore) — niente :has() per non legare
   il layout al supporto del selettore su Safari datati. */
.fg-spazio-leva {
  height: calc(4.5rem + env(safe-area-inset-bottom, 0px));
}

/* Pannello: <dialog> nativo. showModal() porta Esc, fondo inerte e ritorno
   del focus alla leva senza una riga di JS nostro (static/js/carrello.js fa
   solo apri/chiudi/click-sul-fondale). Default = bottom-sheet (mobile
   first); da 641px diventa drawer laterale. */
.fg-pannello-carrello {
  width: 100%;
  max-width: 100%;
  max-height: 85vh;
  margin: auto auto 0;
  padding: 1.1rem 1.1rem calc(1.1rem + env(safe-area-inset-bottom, 0px));
  border: 0;
  border-radius: var(--fg-radius-card) var(--fg-radius-card) 0 0;
  background: var(--fg-bianco);
  color: var(--fg-nero);
  box-shadow: 0 -2px 24px rgba(28, 23, 20, 0.18);
  overflow-y: auto;
  animation: fg-sheet-su 0.18s ease-out;
}

.fg-pannello-carrello::backdrop {
  background: rgba(28, 23, 20, 0.45);
}

.fg-pannello-carrello__testata {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.25rem;
}

.fg-pannello-carrello__testata .fg-sottotitolo {
  margin: 0;
}

.fg-pannello-carrello__corpo {
  margin-top: 0.9rem;
}

@keyframes fg-sheet-su {
  from { transform: translateY(12px); opacity: 0; }
  to   { transform: translateY(0);    opacity: 1; }
}

@keyframes fg-drawer-lato {
  from { transform: translateX(16px); opacity: 0; }
  to   { transform: translateX(0);    opacity: 1; }
}

@media (min-width: 641px) {
  .fg-pannello-carrello {
    width: min(420px, 92vw);
    max-height: 100vh;
    height: 100%;
    margin: 0 0 0 auto;
    padding: 1.25rem;
    border-radius: var(--fg-radius-card) 0 0 var(--fg-radius-card);
    box-shadow: -2px 0 24px rgba(28, 23, 20, 0.18);
    animation-name: fg-drawer-lato;
  }
}

/* Barra di avanzamento verso il porto-franco. La larghezza arriva dalle
   classi .fg-w-N (passo 2, gia' in questo foglio): mai uno style inline,
   che la CSP style-src 'self' farebbe ignorare. */
.fg-avanzamento {
  margin: 0.9rem 0 0.75rem;
}

.fg-avanzamento__pista {
  height: 8px;
  border: 1px solid var(--fg-hairline-strong);
  border-radius: 999px;
  background: var(--fg-hairline);
  overflow: hidden;
}

.fg-avanzamento__pieno {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--fg-nero);
  transition: width 0.2s ease-out;
}

.fg-avanzamento__pieno--completo {
  background: var(--tag-verde-fg);
}

/* Criterio 4 della issue #41: chi ha chiesto meno animazioni non riceve ne'
   la scivolata del pannello ne' la barra che si allunga — lo stato finale
   e' identico, ci arriva solo senza transizione. */
@media (prefers-reduced-motion: reduce) {
  .fg-pannello-carrello {
    animation: none;
  }
  .fg-avanzamento__pieno {
    transition: none;
  }
  /* Tab bar della scheda cliente (lotto 3 #268): stessa filosofia, lo
     stato finale e' identico, ci si arriva senza transizione. */
  .fg-tabs__link {
    transition: none;
  }
  /* Lotto 5 #268: niente pressione animata sui bottoni e niente
     dissolvenza fra le pagine. Lo stato d'attesa (aria-busy /
     .htmx-request) resta pieno: e' informazione, non movimento. */
  .fg-btn {
    transition: none;
  }
  .fg-btn:active {
    transform: none;
  }
  @view-transition {
    navigation: none;
  }
}

/* ==========================================================================
   CARTA CONSULTIVA (issue #42, pattern C «Banco di servizio» — decisione 27)
   La carta non e' piu' una tabella da compilare ma una carta da consultare:
   si cerca, si apre il vino, si legge. Nessun colore nuovo: banco e chip
   riusano i token gia' in casa (criterio 4 della issue: la distinzione fra
   capitoli e' SOLO tipografica — i colori-categoria vino restano una open
   question del brand, 10-brand/visual-identity.md §2.2, e non si inventano).
   ========================================================================== */

/* Il banco resta a portata di pollice mentre si scorre: durante il servizio
   la ricerca serve alla terza voce come alla sessantesima. z-index 20 lo
   tiene sotto la leva del carrello (30), che deve restare sopra a tutto. */
.fg-banco {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.75rem 0;
  background: var(--fg-bianco);
  border-bottom: 1px solid var(--fg-hairline);
}

.fg-banco__cerca {
  width: 100%;
  font-size: 1rem; /* mai sotto 16px: iOS zooma sul focus di un campo piu' piccolo */
}

.fg-banco__capitoli {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

/* min-height 2.5rem: col solo padding i chip misuravano 33px, stretti per un
   pollice in sala (Apple ne raccomanda 44, WCAG 2.2 AA ne chiede almeno 24). */
.fg-chip {
  display: inline-flex;
  align-items: center;
  min-height: 2.5rem;
  gap: 0.35rem;
  padding: 0.3rem 0.8rem;
  border: 1px solid var(--fg-hairline-strong);
  border-radius: 999px;
  background: var(--fg-bianco);
  color: var(--fg-nero);
  font: inherit;
  font-size: 0.9rem;
  cursor: pointer;
}

.fg-chip__conta {
  color: var(--fg-steel);
  font-size: 0.85em;
}

/* Chip acceso: nero pieno come la leva del carrello, mai lo scarlatto — un
   solo accento per vista (Carta di CORE §3), e qui l'accento e' gia' del
   bottone «Conferma ordine» dentro il pannello. */
.fg-chip[aria-pressed="true"] {
  background: var(--fg-nero);
  border-color: var(--fg-nero);
  color: var(--fg-avorio);
}

.fg-chip[aria-pressed="true"] .fg-chip__conta {
  color: var(--fg-avorio-72);
}

/* --- capitoli e voci ------------------------------------------------------ */

.fg-capitolo {
  margin-top: 1.5rem;
}

/* Distinzione tipografica, non cromatica: maiuscoletto spaziato sopra un
   filetto sottile. */
.fg-capitolo__titolo {
  margin: 0 0 0.5rem;
  padding-bottom: 0.3rem;
  border-bottom: 1px solid var(--fg-hairline);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-slate);
}

/* [hidden] deve battere il display delle regole qui sotto: senza questa riga
   il filtro nasconderebbe le voci solo per lo screen reader, lasciandole a
   schermo (l'UA stylesheet perde per specificita' contro una classe). */
.fg-voce[hidden],
.fg-capitolo[hidden] {
  display: none;
}

.fg-voce {
  border-bottom: 1px solid var(--fg-hairline-soft);
}

.fg-voce__testa {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.7rem 0;
  cursor: pointer;
  list-style-position: inside;
}

.fg-voce__identita {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0; /* il nome lungo va a capo invece di spingere fuori il prezzo */
}

.fg-voce__nome {
  font-weight: 600;
}

.fg-voce__sotto {
  font-size: 0.9rem;
}

.fg-voce__prezzo {
  white-space: nowrap;
  font-weight: 600;
}

.fg-voce__dentro {
  padding: 0 0 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/* Dati di servizio: quel che serve col vino in mano, in riga sola. */
.fg-dati-servizio {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.25rem;
  margin: 0;
  font-size: 0.9rem;
}

.fg-dati-servizio dt {
  color: var(--fg-steel);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.fg-dati-servizio dd {
  margin: 0;
  font-weight: 600;
}

.fg-voce__prosa {
  margin: 0;
  max-width: 62ch; /* misura di lettura, come il resto dei testi lunghi */
}

/* Blocco «La cantina» nella scheda vino (issue #641): stessa misura di
   lettura della prosa qui sopra, piu' gli a capo. Chi scrive la
   presentazione dal form del mandante va a capo per separare i paragrafi:
   quegli a capo sono contenuto, non rumore — stessa scelta di
   .fg-nota-testo. */
.fg-scheda-cantina__prosa {
  margin: 0 0 0.6rem;
  max-width: 62ch;
  white-space: pre-wrap;
}

/* Il blocco inglese si stacca dalla prosa italiana con un filetto laterale:
   in servizio si deve trovare a colpo d'occhio senza leggere il titolo. */
.fg-voce__inglese {
  padding-left: 0.75rem;
  border-left: 2px solid var(--fg-hairline-strong);
}

.fg-voce__inglese-titolo {
  margin: 0 0 0.25rem;
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--fg-steel);
}

.fg-voce__inglese p {
  margin: 0;
  max-width: 62ch;
}

.fg-voce__cantina {
  align-self: flex-start;
}

.fg-voce__riordino {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* --- pop-up cantina ------------------------------------------------------- */

.fg-pop-cantina {
  width: min(34rem, 92vw);
  max-height: 80vh;
  overflow-y: auto;
  padding: 1.25rem;
  border: 1px solid var(--fg-hairline-strong);
  border-radius: var(--fg-radius-card);
  background: var(--fg-bianco);
  color: var(--fg-nero);
}

.fg-pop-cantina::backdrop {
  background: rgba(28, 23, 20, 0.45);
}

.fg-pop-cantina__testata {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.5rem;
}

.fg-pop-cantina p {
  max-width: 62ch;
}

/* --- immagini della mandante nel pop-up cantina (issue #541) --------------
   Griglia che si adatta da sola: una sola immagine non si stira a tutta
   larghezza (minmax col max a 10rem), tre stanno in riga su desktop e
   vanno a capo sul telefono. Nessun colore nuovo: il bordo e' la stessa
   hairline del pop-up che le contiene. */
.fg-scheda-cantina__immagini {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(7rem, 10rem));
  gap: 0.5rem;
  margin: 0.75rem 0 0;
  padding: 0;
  list-style: none;
}

.fg-scheda-cantina__immagini img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--fg-hairline-strong);
  border-radius: var(--fg-radius-card);
}

/* --- modal della scheda vino (issue #540) ---------------------------------
   STESSA forma del pop-up cantina (stessa larghezza, stesso fondale, stesso
   scorrimento interno): sono due pop-up della stessa carta e devono
   sembrare parenti, non due invenzioni diverse. Le regole si scrivono per
   esteso invece di aggiungere .fg-pop-vino al selettore di .fg-pop-cantina
   perche' quel blocco appartiene alla #42 e non si riscrive da qui. */
.fg-pop-vino {
  width: min(34rem, 92vw);
  max-height: 80vh;
  overflow-y: auto;
  padding: 1.25rem;
  border: 1px solid var(--fg-hairline-strong);
  border-radius: var(--fg-radius-card);
  background: var(--fg-bianco);
  color: var(--fg-nero);
}

.fg-pop-vino::backdrop {
  background: rgba(28, 23, 20, 0.45);
}

.fg-pop-vino__testata {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.5rem;
}

.fg-pop-vino p {
  max-width: 62ch;
}

/* La figura esiste SOLO quando il vino ha davvero una foto (il template non
   rende nemmeno il tag altrimenti): niente riquadro vuoto, niente segnaposto
   rotto, e la modal senza immagine resta una scheda di solo testo ben
   impaginata — il caso normale finche' la liberatoria non e' firmata. */
.fg-pop-vino__figura {
  margin: 0 0 0.75rem;
}

.fg-pop-vino__figura img {
  display: block;
  width: 100%;
  max-width: 18rem;
  height: auto;
  margin: 0 auto;
  border: 1px solid var(--fg-hairline-strong);
  border-radius: var(--fg-radius-card);
}

/* La live region del filtro resta vuota finche' non si cerca: senza questa
   regola i suoi margini lasciano un buco di ~30px fra il banco e il primo
   capitolo (misurato in collaudo su iPhone 390x844). Mai display:none, che
   la zittirebbe anche quando ha qualcosa da annunciare. */
.fg-esito-ricerca:empty {
  margin: 0;
}

.fg-voce__scheda-completa {
  align-self: flex-start;
}

/* ==========================================================================
   SCHEDA VINO COMPLETA (issue #90, firma D18-bis punto 1) — la vista dedicata
   e linkabile dalla micro descrizione dell'accordion. Nessun colore nuovo:
   stesse variabili --fg-* e stessi pattern (.fg-dati-servizio, .fg-tag,
   .fg-avanzamento__pista) gia' in uso sopra per la carta consultiva.
   ========================================================================== */

.fg-scheda-vino__testata {
  margin-bottom: 0.75rem;
}

.fg-scheda-vino .fg-sottotitolo {
  margin: 1.5rem 0 0.5rem;
}

.fg-lista-uvaggio {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  margin: 0;
  padding: 0;
  list-style: none;
  max-width: 28rem;
}

.fg-lista-uvaggio li {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding-bottom: 0.3rem;
  border-bottom: 1px solid var(--fg-hairline-soft);
}

.fg-lista-tag {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0.3rem 0 0.9rem;
  padding: 0;
  list-style: none;
}

/* Scala visiva corpo/dolcezza: stessa meccanica della barra porto-franco
   (.fg-avanzamento__pista/.fg-avanzamento__pieno, issue #41) — una pista con
   un pieno dimensionato via .fg-w-N (passo 2, gia' in questo foglio), mai
   uno style inline. E' un'illustrazione di una posizione FISSA (role="img"
   nel template), non un progressbar: nessuna animazione qui, il valore non
   avanza nel tempo. */
.fg-scala {
  max-width: 28rem;
  margin-bottom: 1rem;
}

.fg-scala__etichetta {
  margin: 0 0 0.3rem;
  font-size: 0.9rem;
}

.fg-scala__pista {
  height: 8px;
  border: 1px solid var(--fg-hairline-strong);
  border-radius: 999px;
  background: var(--fg-hairline);
  overflow: hidden;
}

.fg-scala__pieno {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--fg-nero);
}

.fg-scala__passi {
  display: flex;
  justify-content: space-between;
  margin: 0.3rem 0 0;
  padding: 0;
  list-style: none;
  font-size: 0.8rem;
  color: var(--fg-steel);
}

.fg-scala__passo--attivo {
  color: var(--fg-nero);
  font-weight: 600;
}

/* ==========================================================================
   MAGAZZINO «CASSA» (issue #43, pattern C firmato — decisione 27)
   Una riga per vino, un contatore per gesto. Nessun colore porta da solo
   un'informazione: la scorta bassa ha icona e parola nel testo.
   Palette e misure dal canone gia' in uso qui sopra (nessun valore nuovo:
   stesse variabili --fg-*, stessa altezza-pollice 2.5rem dei chip).
   ========================================================================== */

.fg-cassa {
  margin-top: 1rem;
  border-top: 1px solid var(--fg-hairline);
}

.fg-cassa-riga {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0.25rem 0.9rem;
  align-items: center;
  padding: 0.75rem 0.15rem;
  border-bottom: 1px solid var(--fg-hairline);
}

.fg-cassa-riga__nome {
  margin: 0;
  /* Nessun font-family qui: il nome del vino eredita il corpo del portale
     (Plus Jakarta Sans, decisione veste 28/07). Il mockup C lo mostrava in
     Playfair, ma quello e' un titolo-display per canone e questa e' una
     riga di lista: la scelta tipografica resta di Giuseppe, non la forza
     un foglio di stile. */
  font-weight: 600;
  font-size: 1.05rem;
}

.fg-cassa-riga__sotto {
  margin: 0;
  color: var(--fg-testo-secondario);
}

/* Il triangolo sta nel testo (non e' uno ::before decorativo): chi legge
   con lo screen reader deve sentire lo stesso segnale che si vede. */
.fg-scorta-bassa {
  font-weight: 600;
  color: var(--fg-scarlatto);
}

/* «Riordina» e' un bottone, non un link: agisce sulla pagina (aggiunge al
   carrello), non naviga. Resta della misura del testo che lo circonda. */
.fg-btn-riordina {
  min-height: 2.5rem;
  padding: 0 0.2rem;
  border: 0;
  background: none;
  color: var(--fg-nero);
  font: inherit;
  font-weight: 600;
  text-decoration: underline;
  cursor: pointer;
}

.fg-contatore {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
}

.fg-contatore__valore {
  min-width: 2.2ch;
  text-align: center;
  font-size: 1.15rem;
  font-weight: 600;
}

/* 2.75rem = 44px: la misura del pollice raccomandata da Apple, sopra il
   minimo WCAG 2.2 AA. Qui il gesto si ripete decine di volte a fine
   serata, col telefono in una mano sola. */
.fg-btn-tondo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border: 1px solid var(--fg-hairline-strong);
  border-radius: 999px;
  background: var(--fg-bianco);
  color: var(--fg-nero);
  font: inherit;
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
}

.fg-btn-tondo:disabled {
  color: var(--fg-steel);
  border-color: var(--fg-hairline);
  cursor: not-allowed;
}

/* L'esito resta sopra la lista e non spinge le righe quando compare: il
   posto e' riservato anche da vuoto (stessa lezione della live region
   della carta, che lasciava 75px di buco). */
.fg-esito-magazzino {
  min-height: 3rem;
  margin: 0.5rem 0 0;
}

.fg-esito-magazzino p {
  margin: 0 0 0.35rem;
}

/* Blocco «Note» delle schede documento (issue #98, firma D19 punto 2).
   Una lista, non una tabella: il contenuto e' prosa libera di lunghezza
   ignota, e una cella di tabella la spezzerebbe male. Le azioni stanno
   sotto ogni nota, non in una colonna: modifica e cancellazione sono
   libere (firma 2.2) e devono essere raggiungibili senza cercarle. */
.fg-lista-note {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  margin: 0.6rem 0 1.2rem;
  padding: 0;
  list-style: none;
}

.fg-nota-riga {
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--fg-hairline-soft);
}

.fg-nota-testo {
  margin: 0 0 0.25rem;
  /* Gli a capo scritti da chi annota sono contenuto, non rumore. */
  white-space: pre-wrap;
}

/* Checkbox «nota privata»: etichetta e casella sulla stessa riga, come il
   flag «Destinatario ordini» dell'anagrafica ditta (_mandanti_email_fieldset). */
.fg-campo-inline {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0 0 0.6rem;
}

/* Toast di riconciliazione (b)/(c) — issue #168, rilievo IMPORTANTE 7:
   posizionamento/spaziatura erano inline nel template (fatture/_esito.html),
   bloccati dalla CSP style-src 'self'. Stesse regole, spostate qui — servite
   da 'self' come ogni altro foglio del progetto. */
.fg-toast-stack {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-width: 24rem;
}

.fg-toast {
  /* #268 lotto 1: il toast e' superficie sovrapposta del registro
     neutro-bianco — fondo bianco, hairline, ombra vera (consentita solo
     qui e su modali/dropdown), raggio dei controlli. Prima era avorio
     con bordo currentColor. */
  background: var(--fg-bianco);
  border: 1px solid var(--fg-hairline-strong);
  border-radius: var(--fg-radius-control);
  /* Ombra da elemento sovrapposto (famiglia modali/dropdown della
     rubrica): il confine del toast su fondo bianco e' l'ombra, il bordo
     hairline e' solo il filetto. */
  box-shadow: 0 4px 16px rgba(28, 23, 20, 0.16);
  padding: 0.5rem 0.75rem;
}

/* Picker condiviso «Aggiungi articoli» (issue #325, criterio 3) — usato
   SIA da agenzia/dettaglio.html SIA da fatture/nuova.html
   (_picker_articoli.html/_picker_risultati.html). <details> nativo: zero
   JS per aprire/chiudere (CSP script-src 'self', niente inline). */
.fg-picker {
  margin: 1rem 0;
  border: 1px solid var(--fg-hairline);
  padding: 0.75rem 1rem;
}

.fg-picker__corpo {
  margin-top: 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.fg-picker__lista {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 16rem;
  overflow-y: auto;
  border: 1px solid var(--fg-hairline);
}

.fg-picker__lista li {
  padding: 0.4rem 0.6rem;
  border-bottom: 1px solid var(--fg-hairline);
}

.fg-picker__lista li:last-child {
  border-bottom: 0;
}

.fg-picker__risultati {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

/* Quadratino numerato di riordino (issue #375, firma Giuseppe 23/08: supera
   le frecce ▲▼ e la maniglia ⋮⋮ separata di #325/#359/#368) — prima colonna
   di ogni tabella di righe riordinabili (ordine agenzia, fattura manuale,
   carta vini): UNICO punto di presa, due gesti sullo stesso elemento.
   (a) drag nativo (JS in static/js/righe-articoli.js e carta-riordino.js
   sposta la riga (elemento tr) nel DOM, poi rinumera); (b) clic/Invio lo sostituisce
   con un input numerico (.fg-riga-quadratino--input) — Invio/blur
   applica la posizione nuova, Esc annulla. Niente colori nuovi: solo i
   token già in uso da .fg-input (bordo/superficie/testo) qui sopra. */
.fg-riga-quadratino {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.8rem;
  height: 1.8rem;
  padding: 0;
  border: 1px solid var(--fg-bordo);
  border-radius: var(--fg-raggio);
  background: var(--fg-superficie);
  color: var(--fg-nero);
  font-family: inherit;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
}

.fg-riga-quadratino:active {
  cursor: grabbing;
}

/* Stato "editing" (clic/Invio sul quadratino, righe-articoli.js/
   carta-riordino.js): stesso ingombro, ma un <input type="number"> vero —
   testo selezionabile/digitabile, mai il cursore "grab" del bottone. */
.fg-riga-quadratino--input {
  cursor: text;
  user-select: text;
  -webkit-user-select: text;
  text-align: center;
}

.fg-riga--trascinata {
  opacity: 0.45;
}

/* --- modal «blocco = avviso» (D46, issue #356 parte 2) -------------------
   <dialog> nativo del form ordine agenzia (agenzia/_modal_blocco.html):
   stessa famiglia del pop-up cantina qui sopra — stessi bordi, stesso
   fondale, nessun colore nuovo. Più largo (tabella a sei colonne). */
.fg-modal-blocco {
  width: min(46rem, 94vw);
  max-height: 85vh;
  overflow-y: auto;
  padding: 1.25rem;
  border: 1px solid var(--fg-hairline-strong);
  border-radius: var(--fg-radius-card);
  background: var(--fg-bianco);
  color: var(--fg-nero);
}

.fg-modal-blocco::backdrop {
  background: rgba(28, 23, 20, 0.45);
}

.fg-modal-blocco__testata {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.5rem;
}

.fg-modal-blocco__testata .fg-sottotitolo {
  margin: 0;
}

.fg-modal-blocco .fg-tabella {
  margin: 0.75rem 0;
}

.fg-modal-blocco p {
  max-width: 70ch;
}


/* — FLASH DI CONFERMA SUGLI SWAP HTMX (#268, lotto 1; dettaglio ad alto
   impatto dei pareri esterni 24/08) — il contenuto appena sostituito
   lampeggia dal 8% di Scarlatto a trasparente: feedback di stato senza
   toast. MISURATO al banco (25/08): la classe .htmx-settling vive solo
   ~20ms (settleDelay htmx) e tronca qualunque animazione CSS-only — per
   questo la classe .fg-flash la applica fga-flash.js su htmx:afterSettle
   e la toglie ad animationend. Sotto prefers-reduced-motion niente flash
   (il JS controlla anche lui, il CSS e' la seconda rete). */
@keyframes fg-flash-conferma {
  from {
    background-color: color-mix(in srgb, var(--fg-scarlatto) 8%, transparent);
  }
  to {
    background-color: transparent;
  }
}

.fg-flash {
  animation: fg-flash-conferma 400ms ease-out;
}

@media (prefers-reduced-motion: reduce) {
  .fg-flash {
    animation: none;
  }
}

/* ==========================================================================
   Plancia Home — variante C + restyle «Elettrica» (#268 lotto 2b, firma
   Giuseppe in chat 25/08/2026; mockup: vault CORE, mockup-2b-restyle-C.html,
   22 fix dalla review a tre del 25/08). Tutto SCOPED su .fg-plancia: il ramo
   non-staff di home.html e il resto dell'app non cambiano d'un pixel.
   ========================================================================== */

/* Tinta di famiglia come custom property locale: un solo posto per
   selettore-famiglia, i componenti sotto leggono var(--fam)/var(--fam-bg). */
.fg-plancia [data-famiglia="finanza"],     .fg-mese [data-famiglia="finanza"]     { --fam: var(--fam-finanza);     --fam-bg: var(--fam-finanza-bg); }
.fg-plancia [data-famiglia="vendita"],     .fg-mese [data-famiglia="vendita"]     { --fam: var(--fam-vendita);     --fam-bg: var(--fam-vendita-bg); }
.fg-plancia [data-famiglia="prodotto"],    .fg-mese [data-famiglia="prodotto"]    { --fam: var(--fam-prodotto);    --fam-bg: var(--fam-prodotto-bg); }
.fg-plancia [data-famiglia="anagrafiche"], .fg-mese [data-famiglia="anagrafiche"] { --fam: var(--fam-anagrafiche); --fam-bg: var(--fam-anagrafiche-bg); }
.fg-plancia [data-famiglia="statistiche"], .fg-mese [data-famiglia="statistiche"] { --fam: var(--fam-statistiche); --fam-bg: var(--fam-statistiche-bg); }
.fg-plancia [data-famiglia="archivio"],    .fg-mese [data-famiglia="archivio"]    { --fam: var(--fam-archivio);    --fam-bg: var(--fam-archivio-bg); }

.fg-plancia__data {
  margin: -0.4rem 0 1.4rem;
  color: var(--fg-testo-secondario);
}

/* --- Fila KPI: valore neutro NERO, tinta a sfondo (4%) ed etichetta —
   convergenza Qwen+Gemini della review 25/08 (un numerone colorato toglie
   peso al valore; la famiglia orienta, non urla). ----------------------- */
.fg-plancia__kpi {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
  margin-bottom: 1.4rem;
}

.fg-kpi {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  border: 1px solid var(--fg-hairline);
  border-radius: var(--fg-radius-card);
  padding: 0.95rem 1.1rem;
  background: color-mix(in srgb, var(--fam, var(--fg-nero)) 4%, var(--fg-bianco));
}

.fg-kpi__etichetta {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--fam, var(--fg-steel));
}

/* Stessi size/peso di .fg-kpi-valore (Statistiche): un solo registro
   tipografico per i numeroni del gestionale. */
.fg-kpi__valore {
  display: block;
  font-size: 26px;
  font-weight: 600;
  color: var(--fg-nero);
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}

.fg-kpi__contesto {
  font-size: 0.85rem;
  color: var(--fg-testo-secondario);
}

/* --- Corpo a due colonne: «Oggi» + calendario | «Le tue aree». -------- */
.fg-plancia__corpo {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 21rem;
  gap: 1.25rem;
  align-items: start;
}

.fg-plancia__oggi {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  min-width: 0;
}

/* Card della colonna «Oggi»: bordo neutro + filetto SINISTRO di famiglia
   (il bordo intero in tinta della .fg-card[data-famiglia] globale qui
   rientra: nel restyle il colore orienta dal fianco, review 25/08). */
.fg-plancia__oggi .fg-card[data-famiglia] {
  border: 1px solid var(--fg-hairline);
  border-left: 3px solid color-mix(in srgb, var(--fam) 55%, transparent);
}

a.fg-card--plancia {
  display: block;
  text-decoration: none;
  color: inherit;
}

a.fg-card--plancia:hover,
a.fg-card--plancia:focus-visible {
  border-left-color: var(--fam);
  background: color-mix(in srgb, var(--fam-bg, var(--fg-superficie)) 55%, var(--fg-bianco));
}

/* --- Calendario della settimana. -------------------------------------- */
.fg-calendario {
  border: 1px solid var(--fg-hairline);
  border-radius: var(--fg-radius-card);
  background: var(--fg-canvas);
  padding: 1rem;
}

.fg-calendario__titolo {
  margin: 0 0 0.75rem;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--fg-steel);
}

.fg-calendario__griglia {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  border: 1px solid var(--fg-hairline-soft);
  border-radius: var(--fg-raggio);
  overflow: hidden;
}

.fg-calendario__giorno {
  min-height: 6.5rem;
  padding: 0.45rem 0.4rem;
  border-right: 1px solid var(--fg-hairline-soft);
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.fg-calendario__giorno:last-child {
  border-right: 0;
}

.fg-calendario__nome {
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg-steel);
}

.fg-calendario__numero {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--fg-nero);
  width: 1.6rem;
  height: 1.6rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
}

/* «Oggi»: velo Scarlatto 5% sulla cella, numero pieno — l'unico punto
   Scarlatto della plancia (accento raro, canone; review 25/08). */
.fg-calendario__giorno--oggi {
  background: color-mix(in srgb, var(--fg-scarlatto) 5%, var(--fg-canvas));
}

.fg-calendario__giorno--oggi .fg-calendario__numero {
  background: var(--fg-scarlatto);
  color: var(--fg-bianco);
}

/* Pill evento: fondo-tag famiglia, testo in tinta, MAI troncata (va su
   piu' righe — review 25/08: mai ellipsis su un dato). */
.fg-calendario__evento {
  font-size: 0.68rem;
  font-weight: 600;
  line-height: 1.25;
  padding: 0.2rem 0.35rem;
  border-radius: 5px;
  background: var(--fam-bg, var(--fg-superficie));
  color: var(--fam, var(--fg-nero));
  overflow-wrap: anywhere;
}

/* --- «Le tue aree»: colonna di bottoni compatti, tocco >=48px, filetto
   famiglia 45% a riposo e pieno all'hover col fondo-tag (richieste
   Giuseppe 25/08: piu' spazio ai pulsanti, niente pallini; niente icone
   e niente gerarchia pesi, deciso 25/08 sera). ------------------------- */
.fg-plancia__aree {
  min-width: 0;
}

.fg-plancia__aree .fg-home-griglia {
  grid-template-columns: 1fr;
  gap: 0.45rem;
  max-width: none;
}

.fg-plancia__aree .fg-home-card {
  flex-direction: row;
  align-items: center;
  gap: 0.6rem;
  padding: 0.78rem 0.8rem;
  min-height: 48px;
  border: 1px solid var(--fg-hairline);
  border-left: 3px solid color-mix(in srgb, var(--fam, var(--fg-bordo)) 45%, transparent);
  transition: background-color 150ms ease, border-color 150ms ease, transform 150ms ease;
}

.fg-plancia__aree .fg-home-card__titolo {
  font-size: 0.92rem;
}

.fg-plancia__aree .fg-home-card__descrizione {
  margin-left: auto;
  font-size: 0.78rem;
  text-align: right;
}

.fg-plancia__aree .fg-home-card::after {
  content: "\203A"; /* › */
  color: var(--fg-steel);
  font-weight: 600;
}

.fg-plancia__aree .fg-home-card:hover,
.fg-plancia__aree .fg-home-card:focus-visible {
  border-color: var(--fg-hairline);
  border-left-color: var(--fam, var(--fg-nero));
  background: var(--fam-bg, var(--fg-superficie));
  transform: translateX(2px);
}

@media (prefers-reduced-motion: reduce) {
  .fg-plancia__aree .fg-home-card {
    transition: none;
  }
  .fg-plancia__aree .fg-home-card:hover {
    transform: none;
  }
}

/* --- Sotto ~64rem la plancia si impila: KPI a colonna, aree in fondo. -- */
@media (max-width: 64rem) {
  .fg-plancia__kpi {
    grid-template-columns: 1fr;
  }
  .fg-plancia__corpo {
    grid-template-columns: 1fr;
  }
  .fg-calendario__griglia {
    grid-template-columns: repeat(7, minmax(4.5rem, 1fr));
  }
  .fg-calendario {
    overflow-x: auto;
  }
}

/* --- Calendario: vista mese + form attivita' (issue #414) ---------------
   Griglia lun→dom completa; le pill riusano .fg-calendario__evento della
   plancia (stesso componente, fondo-tag famiglia, mai troncate) — il
   selettore-famiglia sopra copre anche .fg-mese. Niente animazioni nuove. */

/* Testata della settimana in plancia: titolo-link alla vista mese +
   bottone «+ Attivita'» (issue #414). */
.fg-calendario__testata {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.fg-calendario__titolo a {
  color: inherit;
  text-decoration: none;
}

.fg-calendario__titolo a:hover,
.fg-calendario__titolo a:focus-visible {
  text-decoration: underline;
}

/* Frecce settimana in plancia (issue #418): swap HTMX del solo blocco,
   URL mai toccato. Le frecce sono fg-btn--ghost compattati; l'etichetta
   range orienta chi scorre (testo terziario, come i nomi-giorno). */
.fg-calendario__nav {
  display: flex;
  gap: 0.25rem;
}

.fg-calendario__freccia {
  min-width: 2rem;
  padding-inline: 0.45rem;
  justify-content: center;
}

.fg-calendario__range {
  font-size: 0.8rem;
  color: var(--fg-steel);
  white-space: nowrap;
  margin-left: auto;
}
.fg-mese__testata {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.fg-mese__nav {
  display: flex;
  gap: 0.35rem;
}

/* Barra filtri della vista mese (issue #418): link GET a forma di chip,
   scadenze clienti OFF di default. Attivo = dot famiglia-neutro pieno e
   testo pieno; spento = tratteggio e testo terziario — lo stato parlato
   vive nell'aria-label, il chip e' solo rinforzo visivo. */
.fg-mese__filtri {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.75rem;
}

.fg-filtro {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.2rem 0.65rem;
  border: 1px solid var(--fg-hairline-strong);
  border-radius: 999px;
  font-size: 0.8rem;
  color: var(--fg-steel);
  text-decoration: none;
  background: var(--fg-canvas);
}

.fg-filtro:hover,
.fg-filtro:focus-visible {
  border-color: var(--fg-nero);
  color: var(--fg-nero);
}

.fg-filtro__dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 999px;
  border: 1px dashed var(--fg-hairline-strong);
}

.fg-filtro--attivo {
  color: var(--fg-nero);
  border-color: var(--fg-nero);
}

.fg-filtro--attivo .fg-filtro__dot {
  border-style: solid;
  border-color: var(--fg-nero);
  background: var(--fg-nero);
}

.fg-mese {
  margin-top: 1rem;
  overflow-x: auto;
}

.fg-mese__giorni-testata {
  display: grid;
  grid-template-columns: repeat(7, minmax(7.5rem, 1fr));
  gap: 0.35rem;
  padding-bottom: 0.35rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg-steel);
}

.fg-mese__settimana {
  display: grid;
  grid-template-columns: repeat(7, minmax(7.5rem, 1fr));
  gap: 0.35rem;
  margin-bottom: 0.35rem;
}

.fg-mese__giorno {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.25rem;
  min-height: 6rem;
  padding: 0.4rem;
  border: 1px solid var(--fg-hairline-soft);
  border-radius: 8px;
  background: var(--fg-bianco);
}

/* Giorni di contorno (mese prec./succ. nella griglia): presenti ma
   attenuati — il dato c'e', il mese e' un altro. Fondo --fg-surface, non
   --fg-canvas: nel registro neutro-bianco (#160) canvas == bianco e la
   distinzione sparirebbe (misurato al banco 26/08); --fg-surface e'
   ridefinito anche dalla veste Notturna, si adatta da solo. */
.fg-mese__giorno--fuori {
  background: var(--fg-surface);
}

.fg-mese__giorno--fuori .fg-mese__numero {
  color: var(--fg-stone);
}

/* «Oggi»: stesso velo Scarlatto 5% della plancia (accento raro, canone). */
.fg-mese__giorno--oggi {
  background: color-mix(in srgb, var(--fg-scarlatto) 5%, var(--fg-canvas));
}

.fg-mese__numero {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--fg-nero);
  width: 1.6rem;
  height: 1.6rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  text-decoration: none;
}

.fg-mese__numero:hover,
.fg-mese__numero:focus-visible {
  background: var(--fg-superficie);
}

.fg-mese__giorno--oggi .fg-mese__numero {
  background: var(--fg-scarlatto);
  color: var(--fg-bianco);
}

/* Pill-link (attivita'): stessa resa della pill statica, piu' l'hover. */
.fg-calendario__evento--link {
  text-decoration: none;
  display: block;
}

.fg-calendario__evento--link:hover,
.fg-calendario__evento--link:focus-visible {
  outline: 1px solid var(--fam, var(--fg-bordo));
  outline-offset: 1px;
}

/* Form attivita': campi a griglia 2 colonne sopra ~40rem, radio in fila. */
.fg-attivita-form {
  max-width: 46rem;
}

.fg-attivita-form__tipi {
  display: flex;
  gap: 1.25rem;
  flex-wrap: wrap;
}

.fg-attivita-form__radio {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.fg-attivita-form__griglia {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  column-gap: 1rem;
}

.fg-attivita-form__azioni {
  display: flex;
  gap: 0.6rem;
  align-items: center;
}

.fg-attivita-conferma {
  border-color: var(--fg-scarlatto);
  margin-bottom: 1.25rem;
}

.fg-attivita-conferma__azioni {
  display: flex;
  gap: 0.6rem;
  align-items: center;
}

/* --- Micro-interazioni: feedback di stato (#268 lotto 5) -----------------
   Tre famiglie, tutte sobrie, nessun colore nuovo:
   1. form classici in invio — guardia-doppio-submit.js (globale dal
      lotto 5) imposta aria-busy="true" sul form e disabilita i bottoni;
      qui solo la resa: cursore d'attesa + bottone attenuato.
      L'attenuazione al 60% e' uno stato DISATTIVO: esente dal minimo di
      contrasto WCAG 1.4.3 («part of an inactive user interface
      component»), dichiarato in PR.
   2. scambi HTMX in volo — htmx aggiunge da se' la classe .htmx-request
      all'elemento che ha lanciato la richiesta (form o bottone): stessa
      resa dei classici senza toccare i ~20 template HTMX; gli
      hx-indicator espliciti gia' esistenti (carrello, import) restano.
   3. pressione dei bottoni — scale(0.98) su :active: feedback quasi
      impercettibile (uso frequente, quindi 120 ms come le transizioni
      gia' in app.css: tab 120 ms, controlli 150 ms; press feedback
      100-160 ms da rubrica lotto 5). Un bottone disabled non riceve
      :active, quindi niente conflitto con lo stato d'attesa. */
form[aria-busy="true"],
form.htmx-request {
  cursor: progress;
}

form[aria-busy="true"] button[type="submit"],
form.htmx-request button[type="submit"],
.fg-btn.htmx-request {
  opacity: 0.6;
  cursor: progress;
}

.fg-btn {
  transition: transform 120ms ease-out;
}

.fg-btn:active {
  transform: scale(0.98);
}

/* View Transitions cross-documento [PROPOSTA #268 lotto 5, verdetto al
   banco nella PR]: dissolvenza breve fra le pagine del gestionale al
   posto del lampo bianco della navigazione classica. Progressive
   enhancement: dove non supportata (Firefox) non cambia nulla. 150 ms
   contro i ~250 ms di default UA: su un gestionale usato tutto il giorno
   la transizione non deve mai sembrare un'attesa. Sotto
   prefers-reduced-motion si spegne nel blocco condiviso del criterio #41
   piu' in alto (regola M26: mai un @media reduced-motion nuovo). */
@view-transition {
  navigation: auto;
}

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 150ms;
}

/* ==========================================================================
   VESTE NOTTURNA (#268, firma Giuseppe in chat 25/08/2026 sera:
   «E·Elettrica default + N·Notturna come opzione in impostazioni» — supera
   in parte il «niente dark mode» M1-B del 20/07, nota di propagazione
   datata sul canonico palette-gestionale.md).

   MECCANISMO: attributo data-veste="notturna" sull'<html>, scritto
   SERVER-SIDE dal context processor _nav_context (fga.ui.templating) solo
   per utenti STAFF con fg_veste="notturna" — mai da prefers-color-scheme
   (il blocco @media storico resta commentato, e resta valida la sua
   lezione: l'OS non decide la veste, la decide l'utente in Impostazioni).
   SCOPE: i token vivono su html[data-veste] (le derivate di :root —
   --fg-canvas, --fam-*... — si computano su html: un override sul body
   non le raggiunge, misurato al banco 25/08). Il portale ristoratori
   resta chiaro SEMPRE via guardia SERVER-SIDE: _nav_context non emette
   mai l'attributo sui path /portale/*, né per ruoli non-staff.

   COLORI: mai un hex nuovo. I due primitivi (#1c1714 nero caldo, #faf7f0
   avorio) sono quelli di :root; qui compaiono come LETTERALI di proposito:
   dentro questo blocco var(--fg-nero)/var(--fg-avorio) risolverebbero i
   valori GIA' INVERTITI (le custom property si leggono all'uso, non alla
   definizione) e le derivazioni uscirebbero al contrario. Le percentuali
   dei color-mix vengono dalla veste N del mockup 2b
   (_lavorazione/mockup-268-lotto2b-home/mockup-2b-restyle-C.html,
   collaudata al banco 25/08): pagina = nero 96%+black, superfici avorio
   7%/12%, secondario avorio 68%, bordi avorio 20%/12% su transparent,
   famiglie schiarite 55% white coi fondi al 18% sul nero.

   Le TINTE CALCOLATE di :root (--fg-bordo, --fg-testo-secondario,
   --fg-superficie, frosted della tabella densa, hover righe, velo dei KPI
   plancia) si ricalcolano DA SOLE sui primitivi invertiti: qui si
   ridefinisce solo cio' che in :root e' un hex fisso chiaro. */
html[data-veste="notturna"] {
  color-scheme: dark;

  /* Si inverte SOLO --fg-nero (l'inchiostro diventa avorio).
     --fg-avorio resta CHIARO di proposito: nell'app e' quasi ovunque il
     testo chiaro delle fasce scure (testata, nav, bottoni scuri), che
     restano scure anche in notturna — invertirlo avrebbe chiesto un
     ripristino per ognuno di quei punti (misurato al banco 25/08: fascia
     Cerca avorio in mezzo al buio). Gli usi di --fg-nero come FONDO
     scuro sono enumerati e trattati qui sotto (testata, fascia nav,
     bottone secondario, skip-link, hover tabella chiara). */
  --fg-nero: #faf7f0;   /* inchiostro: avorio */
  /* Fondo pagina: --pagina della veste N (nero caldo 96% + black). */
  --fg-bianco: color-mix(in srgb, #1c1714 96%, black);

  /* Superfici e testi fissi di :root, riportati sulle derivazioni N. */
  --fg-surface: color-mix(in srgb, #faf7f0 7%, #1c1714);
  --fg-surface-soft: color-mix(in srgb, #faf7f0 4%, #1c1714);
  --fg-slate: color-mix(in srgb, #faf7f0 68%, #1c1714);
  --fg-steel: color-mix(in srgb, #faf7f0 55%, #1c1714);
  --fg-stone: color-mix(in srgb, #faf7f0 40%, #1c1714);
  --fg-hairline: color-mix(in srgb, #faf7f0 20%, transparent);
  --fg-hairline-soft: color-mix(in srgb, #faf7f0 12%, transparent);
  --fg-hairline-strong: color-mix(in srgb, #faf7f0 32%, transparent);
  --fg-shadow-hover: 0 1px 2px rgba(0, 0, 0, 0.4);

  /* Tag/pill: testi schiariti (55% white) su fondi 18% sul nero caldo —
     le derivazioni dichiarate della veste N. I --fam-* di :root puntano a
     questi token e si aggiornano da soli. */
  --tag-verde-bg: color-mix(in srgb, #4d775c 18%, #1c1714);
  --tag-verde-fg: color-mix(in srgb, #4d775c 55%, white);
  --tag-giallo-bg: color-mix(in srgb, #8c692d 18%, #1c1714);
  --tag-giallo-fg: color-mix(in srgb, #8c692d 55%, white);
  --tag-blu-bg: color-mix(in srgb, #427298 18%, #1c1714);
  --tag-blu-fg: color-mix(in srgb, #427298 55%, white);
  --tag-rosso-bg: color-mix(in srgb, #bb463e 18%, #1c1714);
  --tag-rosso-fg: color-mix(in srgb, #bb463e 55%, white);
  --tag-grigio-bg: color-mix(in srgb, #6e6d6b 18%, #1c1714);
  --tag-grigio-fg: color-mix(in srgb, #6e6d6b 55%, white);
  --tag-brown-bg: color-mix(in srgb, #8b6450 18%, #1c1714);
  --tag-brown-fg: color-mix(in srgb, #8b6450 55%, white);
  --tag-purple-bg: color-mix(in srgb, #8560a7 18%, #1c1714);
  --tag-purple-fg: color-mix(in srgb, #8560a7 55%, white);
  --tag-orange-bg: color-mix(in srgb, #9d5c24 18%, #1c1714);
  --tag-orange-fg: color-mix(in srgb, #9d5c24 55%, white);
}

/* La testata resta NERA (canone firmato 21/07: navbar/nav scure, sempre).
   Coi primitivi invertiti il suo background: var(--fg-nero) diventerebbe
   avorio: qui si pinna al nero caldo canonico. Il testo sopra
   (--fg-avorio-72, ora color-mix dal token, stesso valore) resta giusto da solo. Il filetto
   sotto separa la testata dal fondo pagina, che in notturna le somiglia. */
html[data-veste="notturna"] .fg-header {
  background: #1c1714;
  box-shadow: 0 1px 0 color-mix(in srgb, #faf7f0 12%, transparent);
}

/* Fascia nav sotto la testata: stessa «fascia scura» del canone (background
   var(--fg-nero), che invertito diventerebbe avorio) — pinnata come sopra.
   I suoi testi usano --fg-avorio/rgba chiari fissi: giusti da soli. */
html[data-veste="notturna"] .fg-nav-wrap {
  background: #1c1714;
}

/* Gli «scuri pieni con testo avorio» condivisi si INVERTONO: il fondo
   var(--fg-nero) diventa avorio da solo, qui si scurisce il testo. */
html[data-veste="notturna"] .fg-skip,
html[data-veste="notturna"] .fg-btn--secondario {
  color: #1c1714;
}

html[data-veste="notturna"] .fg-btn--secondario:hover {
  background: color-mix(in srgb, #faf7f0 85%, #1c1714);
}

/* Hover/selezione delle tabelle NON dense: in chiaro sono tinte su base
   avorio (che qui resta chiara): si ricalcolano sulla base scura. */
html[data-veste="notturna"] .fg-tabella tbody tr:hover:not(.fg-riga--anomalia) {
  background: color-mix(in srgb, #faf7f0 8%, #1c1714);
}

html[data-veste="notturna"] .fg-tabella tbody tr.fg-riga--selezionata,
html[data-veste="notturna"] .fg-tabella tbody tr.fg-riga--selezionata:hover {
  background: color-mix(in srgb, #faf7f0 14%, #1c1714);
}

/* ==========================================================================
   Impostazioni → Aspetto (#268): scelta veste. Stile della scelta radio,
   valido in ENTRAMBE le vesti (token, mai colori diretti). */
.fg-veste-scelta {
  border: 1px solid var(--fg-hairline);
  border-radius: var(--fg-radius-card);
  padding: 1rem 1.25rem 1.15rem;
  display: grid;
  gap: 0.65rem;
  max-width: 34rem;
}

.fg-veste-scelta legend {
  font-weight: 600;
  padding: 0 0.35rem;
}

.fg-veste-scelta__voce {
  display: flex;
  gap: 0.6rem;
  align-items: baseline;
}

/* ==========================================================================
   Impostazioni › Widget della Home (issue #466). Scoped su
   .fg-widget-impostazioni: la sola pagina che le usa.
   ========================================================================== */
/* Il primo submit del form è «Salva» ma non si vede (classe .fg-sr-only,
   già in casa): Invio in un campo salva, mai sposta — il default button
   del browser è il PRIMO submit. */
.fg-widget-impostazioni__tabella {
  margin: 1rem 0;
}
.fg-widget-impostazioni__ordine {
  white-space: nowrap;
}
.fg-widget-impostazioni__ordine .fg-btn {
  padding-inline: 0.55rem;
}
.fg-widget-impostazioni__azioni {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-items: center;
}

/* ==========================================================================
   Piè di pagina del portale — riga di trasparenza AI (issue #547 poi #569,
   voce D60 della Spec). Il testo vive in fga/ui/templates/portale/
   _piede_ai.html, unica casa; dall'11/09/2026 lo includono le sole tre
   pagine della sezione guide.
   ========================================================================== */
/* Deve leggersi senza mai chiedere attenzione: è una nota di servizio in
   fondo alle guide, non un messaggio. Quindi colore secondario e corpo
   piccolo (0.8125rem, misura già in uso nel foglio), nessuno Scarlatto —
   l'unico accento di queste viste è già del bottone «Conferma ordine»
   (Carta di CORE §3, un solo accento per vista).
   Stessa gabbia di .fg-main (max-width 70rem, padding laterale 1.5rem) così
   la riga si allinea al contenuto invece di incollarsi al bordo; il
   padding-bottom di 2rem la stacca dal fondo della finestra. */
.fg-piede-ai {
  max-width: 70rem;
  margin: 0 auto;
  padding: 0 1.5rem 2rem;
  color: var(--fg-testo-secondario);
  font-size: 0.8125rem;
  line-height: 1.5;
}

/* ==========================================================================
   Scheda Relazione a UNA schermata — issue #571 punto 2, SPEC 3.11.1 §3
   «Struttura della scheda Relazione — v2.1» (firma Giuseppe 10/09/2026).
   Calco del mockup approvato (`_lavorazione/mockup-20260910-relazione/
   relazione-v2.html`): testata in una riga, tre gruppi in tre colonne, due
   note in fondo. Nessun colore e nessun font nuovo — solo le variabili già
   in questo foglio; l'unico Scarlatto della vista resta il filetto di
   .fg-errore-inline.
   ========================================================================== */
.fg-rel-testata {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.fg-rel-testata .fg-titolo {
  margin: 0;
  font-size: 1.25rem;
}
.fg-rel-meta {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  font-size: 0.85rem;
  color: var(--fg-testo-secondario);
}
.fg-rel-nome {
  font-size: 0.75rem;
  color: var(--fg-stone);
}
.fg-rel-azioni {
  margin-left: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
}

/* Tendina di «Copia condizioni da…» (#571 punto 5): larghezza tenuta, la
   fila va a capo sotto i 1280 invece di debordare. */
.fg-copia-sorgente {
  max-width: 22rem;
}
/* Firma e chiusura stanno in un <details>: il pannello si apre SOPRA la
   pagina (position:absolute) invece di spingere i gruppi più in basso —
   altrimenti aprirlo costerebbe la schermata unica. */
.fg-rel-azione {
  position: relative;
}
.fg-rel-azione > summary {
  list-style: none;
  cursor: pointer;
}
.fg-rel-azione > summary::-webkit-details-marker {
  display: none;
}
.fg-rel-azione[open] > div {
  position: absolute;
  right: 0;
  z-index: 20;
  min-width: 24rem;
  padding: 0.75rem;
  background: var(--fg-bianco);
  border: 1px solid var(--fg-bordo);
  border-radius: var(--fg-radius-card);
  box-shadow: var(--fg-shadow-hover);
}
.fg-rel-griglia {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.75rem;
}
.fg-rel-gruppo {
  min-width: 0;
  margin: 0;
  padding: 0.5rem 0.75rem 0.75rem;
  border: 1px solid var(--fg-hairline-strong);
  border-radius: var(--fg-radius-card);
}
.fg-rel-gruppo__titolo {
  margin: 0 0 0.5rem;
  font-size: 0.95rem;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}
.fg-rel-campi {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.35rem 0.6rem;
}
.fg-rel-campo,
.fg-rel-form {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.fg-rel-campo--largo,
.fg-rel-fila {
  grid-column: 1 / -1;
}
.fg-rel-fila {
  display: flex;
  gap: 0.25rem;
  flex-wrap: wrap;
}
.fg-rel-fila--giorno .fg-rel-campo {
  flex: 1 1 2.4rem;
}
.fg-rel-et {
  display: block;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--fg-testo-secondario);
}
.fg-rel .fg-input,
.fg-rel .fg-textarea {
  width: 100%;
  padding: 0.2rem 0.4rem;
  font-size: 0.85rem;
}
.fg-rel-letto {
  margin: 0;
  font-size: 0.85rem;
}
/* Grigio = ereditato dal cliente (firma 10/09, §6 «doppioni»): è il testo
   secondario già in uso, nessun colore nuovo. */
.fg-rel-eredita {
  font-size: 0.7rem;
  color: var(--fg-steel);
}
.fg-rel-ereditato {
  color: var(--fg-testo-secondario);
}
/* I sette giorni: la casella resta una casella (regge senza JS, la tastiera
   la trova), ma si vede come il pulsante del mockup. Nessun :has() — lo
   stato acceso si legge col fratello adiacente, che è supportato ovunque. */
.fg-rel-giorno {
  position: relative;
  display: block;
  cursor: pointer;
}
.fg-rel-giorno input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.fg-rel-giorno span {
  display: block;
  padding: 0.25rem 0.15rem;
  text-align: center;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--fg-testo-secondario);
  border: 1px solid var(--fg-bordo);
  border-radius: var(--fg-radius-control);
}
.fg-rel-giorno input:checked + span {
  background: var(--fg-nero);
  color: var(--fg-bianco);
  border-color: var(--fg-nero);
}
.fg-rel-giorno input:focus-visible + span {
  outline: 2px solid var(--fg-nero);
  outline-offset: 2px;
}
.fg-rel-fila--vincolo .fg-rel-campo {
  flex: 0 1 auto;
}
.fg-rel-casella {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.8rem;
}
.fg-rel-note {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
}
/* Le due celle della fascia bassa: una regola vera, non solo un gancio per
   il test che le conta (rilievo della revisione, giro 1). Impilano
   etichetta e campo come una cella di gruppo. */
.fg-rel-note__cella {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-width: 0;
}
/* Il glifo del titolo di gruppo: misura del mockup (.rv2-glifo). */
.fg-rel-glifo {
  margin-right: 0.35rem;
  font-size: 1.05rem;
}
/* La riserva sotto un campo (oggi solo lo sconto a cascata): stessa scala
   e stesso grigio del valore ereditato, mai lo Scarlatto — non è un
   errore, è un fatto da sapere. */
.fg-rel-nota-campo {
  margin: 0.15rem 0 0;
  font-size: 0.7rem;
  color: var(--fg-steel);
}
.fg-rel-note textarea.fg-textarea {
  height: 5.5rem;
  resize: vertical;
}
/* Sotto i 1100 px la schermata unica non è più un obiettivo: i gruppi si
   impilano invece di stringersi fino all'illeggibile (stessa soglia del
   mockup approvato). */
@media (max-width: 68.75rem) {
  .fg-rel-griglia,
  .fg-rel-note {
    grid-template-columns: 1fr;
  }
}
