/* ===========================================================================
   FlowSet 2.0 — Design system (futuristico pulito × token del render v0.3)
   Sfondo grigio-bianco, accento UNICO iris #5b6bef, glassmorphism, angoli
   morbidi, ariosità, font Inter, interfaccia "parlante" (icona + etichetta).
   Sidebar CHIARA. Zero dipendenze. Vedi memoria: ui-design-system-apple-google.
   =========================================================================== */
/* 0.5.102 (AF-E2, 30/07/2026): VIA le regole delle chips della continuity — .cont-chips,
   .cont-chip, :hover, .on, .cont-chips.ro, .cont-chip.ro (6 regole). Gemelle CSS
   dell'estirpazione in sections.js 0.5.156: il pannello continuity e' un foglio bianco di
   note. Vanno via anche .rcbook .chlbl/.chp/.ctbl .chp (CSS di stampa, dentro sections.js).
   ⚠ .dv-chips e .cf-chips NON si toccano: omonime, sono i filtri e le schede.  */
/* 0.5.101 (AE2a-bis, 30/07/2026): `.an2-sec-lbl` (nowrap + ellissi) e `.an2-sec-n{flex:none}` in
   coda — il titolo di categoria non si spezza più a metà parola su Firefox. Vedi il banco di prova
   web/_render/an2_titolo_firefox.html: A = com'era, B = com'è, scattati sullo STESSO motore. */
/* 0.5.100 (AE2a, 30/07/2026): `.undo-bar` + `.ub-*` in coda — la barra del ripristino, gemella in
   uscita di `.ask-ovl`. z-index 125 DICHIARATO nel contratto UNDO-RIPRISTINA (sotto la conferma 130,
   sopra i modali): cambiarlo qui fa fallire il gate, ed e' voluto. `body.has-undo .toast-wrap` sale
   a 96px o i toast normali finirebbero sotto la barra (stesso angolo). Mobile <=640px: a tutta
   larghezza, sopra il pollice. */
/* 0.5.99 (AE1-bis, 31/07/2026): RIMOSSE `.fs-confirm-inline` e le tre `.fci-*` — erano la conferma
   «Scartare le modifiche?» del 05/07, con overlay e riquadro PROPRI. Facevano lo stesso mestiere di
   `.ask-*` (stare sopra un form senza distruggerlo) con un altro vestito: due conferme diverse nello
   stesso sito si disallineano al primo ritocco, ed è il difetto che Emanuele ha chiesto di chiudere
   («le uniche cose che devono divergere sono le scritte»). Nessuna regola nuova: il dirty-guard ora
   passa da askConfirm e riusa `.ask-*`. Delta netto sul file: -0 byte (il blocco è stato sostituito
   da una lapide di pari lunghezza che dice dove è finito). */
/* 0.5.98 (AE1, 31/07/2026): `.ask-*` — la CONFERMA UNICA in un overlay proprio (z-index 130, sopra
   i modali a 90 e sopra il visore a 120), perche' deve poter comparire sopra un modale. Su
   smartphone i due tasti si impilano con column-reverse: il distruttivo resta in basso, ma non
   dove il pollice cade per caso. */
/* 0.5.97 (AD, 31/07/2026): blocco APPEND per la GALLERIA DEL FORM — le miniature delle foto che una
   copia si porta dietro (.fm-gal*), con la ✕ per escluderne una e la ★ della predefinita. Forma
   presa dalle thumb del carosello, contenitore dalla scatola grigia dei riquadri di form, token
   quelli di sempre: l'unico colore fuori palette è il giallo della stellina, che è già il giallo
   del segnalibro nel visore. Zero token nuovi. */
/* 0.5.96 (AC, 30/07/2026): blocco APPEND per «Nuova continuita'» — le pillole del cast (.cont-new-p)
   riusano la forma dei chip con lo stato .on dell'accento, e il riquadro del personaggio scelto si
   accende con lo stesso anello --accent-bord del campo attivo dei form. Zero token nuovi. */
/* 0.5.95 (AB2/AB3, 30/07/2026): la tab Continuity non porta componenti nuovi. Lo switcher delle
   due facce RIUSA .role-sw e il suo selettore storico e' stato ESTESO a .cont-view-sw nei 3 punti
   che gia' nominavano .db-view-sw/.foto-view-sw (rastrello, non una quarta regola). In coda al
   file un blocco APPEND con le sole rifiniture che i componenti riusati non hanno: l'etichetta
   .cont-var-tag della variante, il rientro .cont-pers.cont-var (la variante e' FIGLIA della
   principale, e si deve vedere), il campo titolo .cont-vtit e il preventivo .cont-dup-prev della
   duplica. Le due colonne di prosa cedono con overflow-wrap:anywhere (canone O.3), zero token
   nuovi, zero colori nuovi. */
/* 0.5.94 (AA2, 29/07/2026): la colonna azioni della tab Scene passa da 84 a 124px, con min-width,
   perché ospita ora TRE tasti (duplica · modifica · elimina). Misurato prima di toccare: gli 84px
   dichiarati venivano resi 36 dal layout auto della tabella, e col terzo bottone `.row-act`
   (flex-wrap:wrap globale) incolonnava le icone facendo crescere la riga a 120px di altezza.
   `.scn-table .row-act{flex-wrap:nowrap}` per la sola tab Scene: le card cambio continuano ad
   andare a capo come prima. */
/* 0.5.93 (Z2 + Z10 + Z11a · i tre appunti di Andrea dall'iPad vero, 29/07/2026): tre difetti che
   l'emulazione non poteva vedere, tutti curati in questo foglio.
   · Z2 — LA DATA CHE SI SPINGE ADDOSSO AL CAMPO ACCANTO (blocco in coda). Su iOS il valore di un
     <input type="date"> lo disegna WebKit dentro ::-webkit-date-and-time-value, che di suo è
     CENTRATO: nella testata ODG «29 lug 2026» finiva a metà del box mentre gli altri otto campi
     partono da sinistra, e l'occhio lo legge come un campo che sconfina in «Giorno settimana».
     Nessun motore desktop lo riproduce — per questo 39 misure in emulazione davano zero: lo
     strumento cercava l'intersezione dei due rettangoli, che infatti non si toccano MAI.
   · Z10 — LE TABELLE (in loco, :1646). Le tre invarianti anti-sbordo della TAPPA O escono dalla
     fascia «921-1280» e valgono sopra i 921. Erano già la cura giusta; scritte come FASCIA
     valevano solo dentro la fascia, e l'iPad Pro 12.9 in orizzontale (1366px CSS) ne restava
     fuori: l'Inventario tornava a incolonnare «IMP/ONIB/ILE» e «€2/76/,0/0», cioè esattamente il
     difetto che la TAPPA O aveva già chiuso a 1024. Più nowrap su intestazioni e celle
     monospaziate: un'etichetta e un prezzo non si spezzano mai.
   · Z11a — LA FOTO CHE RIEMPIE IL VISORE (:2200). C'erano solo due massimi (88vw/82vh), e un
     massimo dice quanto una foto PUÒ crescere, non quanto DEVE: una piccola restava un
     francobollo in mezzo al nero. Ora il box è dato e `contain` ci scala dentro l'immagine, in su
     come in giù. Contain e non cover: su una foto di continuity il ritaglio è perdita di dato.
   Più l'appoggio CSS allo zoom del visore (touch-action, transform-origin) — la logica sta in
   carousel.js 0.5.16. */
/* 0.5.92 (Z8 · i tasti di stato diventano solidi, 29/07/2026): tre modifiche, blocco APPEND in
   coda + due ritocchi in loco alla tavolozza. I badge semantici smettono di essere pellicole
   (fondo --c-*-bg velato + testo della stessa tinta) e diventano fondo PIENO + testo bianco:
   sopra la fotografia delle card cambio misuravano 1,90 e 1,97:1, ora il rapporto non dipende
   più da cosa c'è sotto. In loco: le quattro tinte semantiche scurite del 2-8% (:201-205) e tre
   toni reparto (:464-467), il minimo perché il bianco arrivi a 4,5:1 — scarti che accanto
   all'originale non si distinguono. Confine misurato, non a naso: i comandi sopra le foto e i
   tenui d'accent NON si toccano (l'accent pieno col bianco regge in 2 temi su 9). Dettaglio e
   ragioni nel blocco in coda. Guardia: tools/qa_Z/z39_prova_tasti_solidi.js
   0.5.91 (Z7 · la card cambio è un tasto solo, 29/07/2026): blocco APPEND in coda. La classe
   della forma-poster passa da `.has-shot` a `.cb-poster` (19 selettori rinominati: quel nome
   mentiva, ora la forma ce l'hanno anche le card senza scatto) e chi non ha foto prende
   `.cb-noshot`, che scurisce lo scrim perché il bianco regga sul segnaposto #8A8278 (2,9:1 →
   oltre 7:1). Più la cintura anti-drag sulle immagini di anteprima del Carousel e del Diario. */
/* 0.5.90 (Z5 · la testata di macro-categoria nella tab Cambi, 28/07/2026): `.cbx-cat` +
   `.cbx-cat-n/.cbx-cat-c` (vicino a .cbx-row). Divide la cascata delle righe-personaggio in
   sezioni — Cast · Feat. extra · Crowd · Stunts + le custom — con nome e conteggio. NON è un
   comando: non si clicca e non filtra, i filtri restano il pannello Facce. Solo token. */
/* 0.5.89 (Z4 · l'etichetta corta delle barre continuity, 28/07/2026): una riga sola,
   `.cont-bar .cont-bar-lbl.s{display:none}`. Le due barre continuity emettono ora anche
   un'etichetta CORTA («◂ Ingresso» / «▸ Registra»), che serve al piede della scheda scena
   su smartphone (fm-view.css 0.5.17, piede a una riga). Qui la spengo di BASE: nei due
   contesti storici — il toast scena di odg.js e la riga della Home — la barra è larga
   quanto la riga e l'etichetta lunga ci sta, quindi non devono cambiare di un pixel.
   Accesa solo da `.fm-view .modal-foot .cont-bar-lbl.s` sotto i 560px. */
/* 0.5.88 (Z1 · la ✕ che elimina è rossa PRIMA di toccarla, 28/07/2026): due regole, non una virata
   cromatica. `.icon-btn.danger` (:1266) era dipinta SOLO su :hover — su un tablet il :hover non
   esiste, quindi il tasto che cancella un dato era grigio identico a quello che chiude la finestra,
   sotto un dito che non ha modo di "provare". L'idioma `.danger` esisteva già ed era rosso a riposo
   in tutti gli altri gemelli (.btn-ghost.danger :1298, .mb-pop button.danger :2617, .fm-act.gho.danger
   in fm-view.css:142, .btn-danger :1295): questo era l'unico rimasto indietro — RASTRELLO, non stile.
   Seconda regola: `.sel-item .x` (:1248), la ✕ del foglio feedback che fa `delete SEL[k]`.
   ⚠ IL CONFINE: rosso = elimina un DATO. Le 14 ✕ che chiudono un modale, svuotano una ricerca o
   tolgono un chip-filtro restano neutre (censite in Z1, piano §Z1): un rosso ovunque non dice niente.
   Zona grigia dichiarata: `.msn-x` (sections.js:5388) esclude una foto dalla cartella ma NON la
   cancella — resta neutra, e il suo title lo dice già. */
/* 0.5.87 (Y3b · gli switch delle card di stampa vanno a capo, 28/07/2026): `.rc-sw{flex-wrap:wrap;
   row-gap:3px}` — una riga sola, in coda al file accanto al CSS che spiega (blocco «v0.5.87»).
   Misurato sul banco a 390px: 8 switch su 17 avevano l'ultimo valore OLTRE il bordo del pannello
   e senza scroll — sul telefono «Archiviato», «Pagine» e «Stato» erano IRRAGGIUNGIBILI. RASTRELLO:
   il difetto era della pillola, quindi la cura vale anche per le card box consegnate in Y3a.
   Il desktop non cambia. (Riga di testata aggiunta alla TAPPA Y7: la modifica era documentata in
   coda ma la testata si fermava alla 0.5.86, e chi apre il file legge la testata.) */
/* 0.5.86 (X3c · «Prendi dal moodboard», 28/07/2026): .mbp-grid/.mbp-tile — griglia di miniature
   quadrate per scegliere, dentro una cartella aperta, fra le foto di ricerca gia' caricate. Usa la
   spunta di casa (.mb-check): la selezione di una foto si fa in un modo solo in tutto il sito. */
/* 0.5.85 (X3b · i bottoni della barra di selezione, 28/07/2026): scope `.mb-selbar .btn-*` — i
   bottoni dentro la barra vivono su una superficie SCURA (var(--ink)) e usavano classi disegnate
   per fondi CHIARI: «Annulla» (.btn-ghost) veniva fuori come pillola BIANCA PIENA con testo bianco
   (il «popup tutto bianco» segnalato da Emanuele) e «Aggiungi a cartella» (.btn-soft) come testo
   nero su nero. Misurato sul DOM vivo, non dedotto. Via anche la toppa inline `color:#fff` che
   c'era sul solo Annulla: toccava il testo e non il fondo. Aggiunto il rosso .btn-danger, lo stesso
   del modale di conferma, per il tasto «Elimina» traslocato qui dalla testata. */
/* 0.5.84 (X3 · le cartelle del moodboard prendono il token della Galleria, 28/07/2026):
   .mb-folder passa allo stampo di .fs-folder — copertina QUADRATA a filo del bordo (era
   rientrata di 12px, in 4/3, con un secondo raggio dentro la card), raggio 14px come tutte
   le card (era var(--r-lg)=22px), hover -2px, e sotto la .fs-body del sito con .fs-name +
   .fsf-n. Bolle e foto vivono nella STESSA .foto-grid (moodView): erano due linguaggi-card
   affiancati. Le varianti n0/n1/n2/n3 delle copertine a mosaico diventano UNA regola
   condivisa (:2482) fra .mb-cover, .fsf-cover e .cr-cover — prima erano scritte due volte
   con numeri diversi e la terza non le aveva. Allineati anche .mb-pill e .mb-drag (16→8px,
   l'origine di .fs-tag), .mb-new (raggio 20→14), .mb-ph.folder (20→14, regola oggi inerte),
   .cr-cover (gap 1→2px, fondo --s2→--s3). ⚰ TOLTE perché morte da mesi e verificate con
   grep: .mb-grid (griglia della vista sparita il 05/07) e le 14 regole del DOCK
   (.mb-dock/.dock-folder/.df-cover/.df-name/.dock-lab, nodo rimosso alla TAPPA D) — il piano
   di X3 dava .df-cover fra le quattro copertine da allineare: le vive sono TRE.
   ⚠ Il ?v= salta da 0.5.83 a 0.5.84: 0.5.83 è esistito solo come cache-bust in index.html
   (TAPPA P·P6), senza voce qui in testa. */
/* 0.5.82 (TAPPA O · responsive secondo strato, 27/07/2026): le invarianti anti-sbordo diventano
   REGOLE invece che elenchi — :528 `body{overflow-wrap:anywhere}` (ereditata, la prendono anche
   i componenti futuri), fascia tablet: chi ospita una tabella scorre e le celle non spezzano le
   parole, piu' 33 dichiarazioni di griglia con le tracce liberate a minmax(0,...). Misurato sul
   banco di stress: da 9 misure su 85 con contenuto perso a 0. Guardia: tools/qa_O/z23. */
/* 0.5.80 (TAPPA U3b · la coda del noleggio, 27/07/2026): blocco APPEND in coda — .field[hidden]
   (il campo «Riconsegna entro» resta nel DOM ma si vede solo sul noleggio), .fld-hint (la riga
   d'aiuto sotto un campo semplice: gemella di .toggle-hint :1649 meno il rientro della casella) e
   .dv-fact.wide (la tessera di una FRASE prende due colonne: «29/07/2026 · fra 2 giorni» in 120px
   si spezzava su tre righe — visto allo screenshot; sul telefono la griglia e' gia' a colonna
   singola e lo span si disattiva). Zero token nuovi, zero componenti nuovi. */
/* 0.5.79 (TAPPA U3e · budget a doppia barra, 27/07/2026): blocco APPEND .bd-split/.bd-part/
   .bd-plab/.bd-pv/.bd-fill.nol. .bd-track/.bd-fill/.bd-k/.bd-pct INVARIATI (è la stessa barra di
   sempre, affiancata due volte); la tinta dei noleggi è il token del chip «Noleggio» (--c-info),
   zero colori nuovi. Sotto i 560px le due barre si impilano invece di dimezzarsi (regola 7). */
/* 0.5.78 (TAPPA U2 · la card e' un poster, 27/07/2026): blocco APPEND in coda — .cb-card.cb-poster
   e figli. Foto di fondo a tutta card (aspect-ratio 3/4, 4/5 sotto i 560px), scrim a DUE gradienti
   (denso dal basso dietro al testo, appena accennato dall'alto dietro codice e stato) con
   pointer-events:none per non rubare i click al carosello, testo bianco con ombra. Tutto scoped su
   .has-shot: una card senza foto non ha quella classe e resta identica.
   ⚠ SUPERATA da 0.5.91 (Z7): la classe si chiama .cb-poster e ce l'hanno tutte le card; chi non ha
   foto prende in più .cb-noshot, e il click sulla copertina non apre più il carosello ma la scheda. */
/* 0.5.77 (TAPPA U1-bis · il bis, 27/07/2026): il campo codice cambio non è più `type=number` —
   deve accettare anche «1B». Stessa cornice, niente spinner, font monospazio. */
/* 0.5.76 (TAPPA U1 · il numero decide la posizione, 26/07/2026): blocco APPEND in coda —
   .chc/.chc-sig/.chc-num/.chc-hint. La sigla del reparto (CH/MU) vive DENTRO la cornice
   dell'input in sola lettura, stesso idioma delle unità di .meas (:592): nessun componente
   nuovo, zero token nuovi. */
/* 0.5.75 (TAPPA V · la testata non balla, 26/07/2026): blocco APPEND in coda — .ph-id/.ph-idrow/
   .ph-nav/.ph-act, i ganci del QUARTO slot di head() (app.js:314). Tutto scoped su .page-head
   .has-nav: le viste che non passano il nav non cambiano di un pixel. La navigazione (le barre
   .role-sw) esce dal gruppo azioni ed entra nella riga del titolo, che è invariante fra le viste
   che essa stessa commuta → il delta è zero per costruzione, non per fortuna. Sotto i 560px la
   barra si stira a tutta riga (bersaglio del dito più grande, regola 7). Zero token nuovi. */
/* ⚠ TAPPA T4 (26/07/2026): la riga qui sotto mancava — index.html serviva ?v=0.5.74 e il
   changelog si fermava a 0.5.73. Ricostruita dal commento di index.html:9, non a memoria. */
/* 0.5.74 (TAPPA J2 · la ricerca dentro le liste, 26/07/2026): stili del motore UNICO ListSearch —
   barra di ricerca in-lista con contatore «N su M» e tasto x, innestata su Scene (.panel con
   data-lq-box, righe data-lq-row, testate di gruppo data-lq-grp) e Galleria Foto (card e cartelle). */
/* 0.5.73 (TAPPA E, 25/07/2026): griglia foto ridimensionabile sui dispositivi TOUCH — blocco
   nuovo in coda a .gal-drag: .gal-dens{display:none} + @media (pointer:coarse),(hover:none){
   .gal-dens visibile · .foto-grid.dens-2 floor 150px · .dens-3 floor 104px + rifiniture }.
   Le TRE regole storiche delle colonne (:1253 base, :1422 telefono, :1517 touch) NON sono
   toccate: il livello di default non ha classe → il tablet non regredisce di un pixel. */
/* 0.5.72 (TAPPA D, 25/07/2026): nessuna dichiarazione nuova — il selettore delle 4 regole
   .role-sw.db-view-sw e del salvagente mobile è ESTESO a .foto-view-sw (swap Galleria|Moodboard). */
/* 0.5.71 (TAPPA C/C-bis, 25/07/2026): galleria pura, cartelle derivate e visore a schermo
   intero — changelog esteso nel commento HTML accanto al <link> in index.html. */
/* (0.5.71→0.5.73 riportate qui in TAPPA F, 25/07: erano documentate solo in index.html —
   stessa svista già sanata una volta per la 0.5.55→0.5.58, vedi nota più sotto.) */
/* 0.5.70 (TAPPA B, 25/07/2026): .fs-tag.moodboard — etichetta della QUARTA specie di foto
   (tipo:"mood", ambiente moodboard). Token esistente --c-night, nessun colore nuovo. */
/* ===== v0.5.60 (LOTTO FORM CONTINUITY, 18/07/2026 sera — sample v2 approvato): blocco .cont-2col/.cont-media/.cont-data (scheda persona a 2 zone, 300px media | dati; collassa ≤720px), box note flex:1 min-height:190px max-height:none (scoped: la base .nfmt-edit resta 110/300), override carosello scoped in .cont-media (lead 4/5, thumb 68px), .cont-lead-ph (placeholder statico a 0 foto), .cont-mode-tag[.insp] (badge testata Registrazione/Ispezione via opts.headActions, gemello parametrico di .fm-ro-tag su --c-info). NIENTE pillole CONT_CHIPS e NIENTE card Set&oggetti nel form (decisione Emanuele 18/07): .cont-chip/.cont-chips restano SOLO per la resa legacy .ro in ispezione, .cont-setbox resta per la coda «Note generali». sections.js 0.5.76 gemello. ===== */
/* ===== v0.5.59 (RIFINITURE ② CHECKBOX, 18/07/2026): gruppo canonico .fs-ck-box → draw scoped su svg .ck-real + NUOVA regola .ck-ghost (hint semitrasparente statico, stroke var(--t3) op .45); .nfmt-eck cursor:default (spunta solo in ispezione) + ghost ::before (grid-area 1/1 su ::before/::after); .tr-ck ghost ::before (sparisce su :checked; tap-target mobile :1465 INTATTO). NB: v0.5.55→0.5.58 documentate solo nei commenti ?v= di index.html (header rimasto fermo a 0.5.54, sanato oggi). ===== */
/* ===== v0.5.54 (LOTTO C, 17/07/2026): blocco APPEND in coda — .scn-tools/.scn-chips/.scn-pers (toolbar facce tab Scene; chip=.fchip globali cambifiltri, combo=combo unico, soli token esistenti). · v0.5.52 (LOTTO U1, 17/07/2026): .role-sw.db-pk-tabs (tab del picker giornata, riuso .role-sw + salvagente mobile, blocco APPEND in coda). · v0.5.51 (LOTTO U2, 16/07/2026): .role-sw.db-view-sw button (override scoped in coda, :2849) padding 9px→11px + min-height:44px — tocco ≥44px (R7); box-sizing:border-box globale rende il min-height un pavimento garantito. Misure runtime 390/760/1280: 44px esatti, zero overflow, gemelli .role-sw (Master/reparto) intatti a 29px. · v0.5.50 (FASE C Lotto 4, 16/07/2026): blocco APPEND in coda — pannello filtri del Diario: .fd-filters (details-pillola gemello di .fd-capi:2658, badge .fd-filters-n) + .social-filters (facce impilate come .db-cp-filters:1644; RIUSA le .cf-face/.cf-chips/.fchip globali di cambifiltri, zero ridefinizioni). Soli token reali. Bump ?v= rinviato a fine FASE C. · v0.5.49 (FASE C Lotto 3, 16/07/2026): blocco APPEND in coda — barra di ricerca del Diario: SOLO .social-search (margini + max-width:none nel feedCol), la barra RIUSA .search (:429) e l'input esistenti. Zero token nuovi. Bump ?v= rinviato a fine FASE C. · v0.5.48 (Lotto 3 fix 2+4, 14/07/2026): blocco APPEND in coda — modale integrato NOTE+FOTO (render-vivo lotto3.html approvato). Classi NUOVE .nt-fwrap/.nt-fotos/.nt-foto(+.rm)/.nt-fbar/.nt-fthumb (carosello foto della nota con barra-cursore) · .nt-lb* (lightbox schermo intero ← →) · .db-note-foot (composer a tutta larghezza) · .db-m-body.nt-scene + override .nt-msg{max-width:none} (bolla larga come il box inserimento, fix proporzioni Emanuele). SOLI token reali, .nt-msg/-meta/-txt/-foot ESISTONO (0.5.33) → zero ridefinizioni. · v0.5.47 (Lotto 1, 14/07/2026): .bb-act (bottoni azione card con etichetta+tinta ruolo), .bb-cont (pannello continuità sempre presente), .bb-contchip. · v0.5.46 (E-R2, 14/07/2026, richiesta Emanuele) — seconda onda di rifiniture alla
   dashboard, sul banco di prova (:8803). Task 1: .bb-bento torna a colonna piena larghezza
   — .bb-kpi (box quadrato) MORTA, RIMOSSA, sostituita da .bb-kpis/.bb-kpi-pill (riga
   sottile di pillole); .bb-alert diventa protagonista (righe .row più larghe/leggibili:
   14px/1.5/8px invece di 12.5px/1.4/6px). Task 2: blocco .db-act-* (modale Attività,
   marcatore ═══ R3b ═══ sotto) ELIMINATO — JS morto (dashboard.js 0.7.2 ha rimosso tutto il
   modale). Al suo posto blocco NUOVO .db-foto-modal/.db-foto-grid/.db-foto-i/.db-foto-cap
   (marcatore ═══ E-R2 ═══, dove viveva R3b): modale grande foto, griglia auto-fill
   minmax(180px,1fr). .bb-move 24×24→30×30, .bb-tagcnt font 10.5→12px pad 4px 10px (ora
   anche bottone cliccabile, non più <span> muto). Task 3: .fd-layout/.fd-note-only
   (gemelli) 600→760px, .fd-post/.fd-meta/.fd-txt più grandi, .fd-media max-width
   420px→none — SOLO in style.css, dashboard.js non tocca il Diario. SOLI token esistenti,
   zero colori nuovi, prefers-reduced-motion sulle transizioni nuove. ===== */
/* ===== v0.5.45 (14/07/2026, collaudo Q — MISSIONE_E-R_rifiniture, richiesta Emanuele) —
   RIFINITURE Home board. .bb-bento passa da grid(4 col fisse, righe 92px) a FLEX
   (align-items:stretch): .bb-hero rimossa (dashboard.js 0.7.1), .bb-alert ne prende lo
   spazio (flex:2, altezza libera fino a 10 righe invece delle 4 di prima) mentre i 2
   .bb-kpi si stirano alla stessa altezza — box assente → il flex compatta i soli KPI,
   zero buchi bianchi in entrambi i casi (marcatore ═══ fine E3 ═══ poi R3b sotto per il
   resto). .bb-c-foot .dv-chips/.dv-link/.dv-more-btn: override SOLO di taglia (pillole
   nome-intero compatte al posto delle bolle .avatar/.pile, RIMOSSE — riusano .dv-link
   ESISTENTE di VIEWS.scene, zero classe nuova per la pillola). Blocco NUOVO .db-act-*
   in coda (marcatore ═══ R3b ═══): modale Attività della scena, 2 colonne stage+users,
   mobile ≤768 impilate. ===== */
/* ===== v0.5.44 E3 (14/07/2026, collaudo Q — MISSIONE_E3_foto_riferimenti) — marcatore
   .fd-chip-sc.derived APPEND in coda (marcatore ═══ E3 ═══): opacità ridotta, SOLO
   proprietà numerica (idiom già in uso: .wxcover.calm/.th-hint/.scene-opt .add-ico),
   zero colori nuovi. Badge «da taggare» e bottoni 📷 riusano .chip.warn/.bb-move/
   .icon-btn esistenti — zero CSS aggiuntivo per loro. ===== */
/* ===== v0.5.43 E2 (14/07/2026, collaudo Q — MISSIONE_E2_note_roundtrip) — 💬 card board
   apribile: blocco .bb-note-det/.bb-note-body/.bb-note-row APPEND in coda (marcatore
   ═══ E2 ═══) + override flex-wrap:wrap su .bb-c-foot. Soli token esistenti. ===== */
/* ===== v0.5.42 E1 (14/07/2026, collaudo Q — MISSIONE_E1_giornata_modulare) — banner
   stantiezza ODG: blocco .db-stale APPEND in coda al file, SOLO token esistenti
   (var(--c-warn)/var(--c-warn-bg) :43, già usati da .chip.warn/.sync-ind.warn — vedi il
   marcatore ═══ E1 ═══ in coda). Il bottone «Sincronizza da ODG» (dashboard.js 0.6.2) riusa
   .btn.btn-soft esistente, zero CSS nuovo per lui. ===== */
/* ===== v0.5.41 D8 (13/07/2026, PIANO_APPROVATO.md FASE D) — chiusura FASE D: border:0 su
   .avatar (D7, azzera il bordo UA nativo "bordini" del cerchio topbar) + blocchi append
   .db-pk-search/.db-pk-clear (D5, barra ricerca picker giornata), .bb-* (D2, Home board),
   .fd-note-only (D4, tetto larghezza vista Note) — vedi i marcatori ═══ D2/D4/D5 ═══ già
   presenti più sotto nel file. ===== */
/* ===== TAPPA P · P6 (27/07/2026) — QUI C'ERA L'@import DEI FONT DA GOOGLE: RIMOSSO.
   Ogni apertura dell'app faceva una richiesta a fonts.googleapis.com/fonts.gstatic.com, e una
   richiesta è un'IDENTIFICAZIONE: l'IP di chi lavora (il set, il teatro, casa) finiva nei log di
   Google a ogni caricamento di pagina, senza che nessuno l'avesse scelto. I font sono già tutti
   self-hosted in web/fonts/ dalla RETTIFICA 1 (in fondo al file): l'@import era una ridondanza
   che pagavamo in privacy. Tolto anche l'unico peso che mancava davvero (Inter 500, 17 usi nel
   file, scaricato una tantum in web/fonts/inter-500.woff2). Da oggi la CSP del server dichiara
   "style-src 'self'; font-src 'self'": se qualcuno rimette un font esterno, il browser lo BLOCCA
   e la pagina si vede sbagliata — la regola non dipende più dal fatto che uno se la ricordi.
   NON rimettere @import/<link> verso CDN: un font nuovo si scarica in web/fonts/. ===== */

:root{
  /* ── accento unico (iris/indaco del render v0.3) ── */
  --accent:#5b6bef; --accent-deep:#4453d6; --accent-rgb:91,107,239;
  --accent-mute:rgba(91,107,239,.10);
  --accent-soft:rgba(91,107,239,.12); --accent-bord:rgba(91,107,239,.30);
  --accent-tag:#eaecfe;                /* tag iris su fondo chiaro (render) */
  --terra:#c0563f;                     /* numero-zona standard del render */
  /* alias retro-compatibili (alcune inline-style usano ancora --orange*) */
  --orange:var(--accent); --orange-deep:var(--accent-deep); --orange-mute:var(--accent-mute); --orange-bord:var(--accent-bord);

  /* ── FONT TOKENS — un solo punto di swap-font per tema (default Inter, zero regressione sugli altri temi) ── */
  --ff-sans:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,system-ui,'Helvetica Neue',Arial,sans-serif;
  --ff-display:var(--ff-sans);
  --ff-mono:'JetBrains Mono',ui-monospace,'SF Mono',Menlo,monospace;

  /* ── superfici neutre, grigio-bianco freddo (token render v0.3) ── */
  --bg:#eef0f4; --surface:#FFFFFF; --s1:#FFFFFF; --s2:#f7f8fa; --s3:#f1f3f7;
  --s4:#e3e7ee;                        /* fill barrette / segnaposto del render */
  --ink:#3a4150;                       /* badge #ID + toast (ink del render) */
  --t1:#3a4150; --t2:#7a8394; --t3:#9aa3b2;
  --border:#d6dbe4; --border2:#c2c9d6; --border-soft:#eceff4;

  /* ── glass ── */
  --glass-bg:rgba(255,255,255,.72); --glass-brd:rgba(255,255,255,.55);

  /* ── legenda colori semantica (identica in OGNI tab) ──
     Verde=OK · Ambra=da completare · Rosso=attenzione/hard-out · Blu=info/noleggio
     Viola=Costumi · Oro=Giorno · Indaco=Notte · Rosa=Alba/Tramonto

     Z8 (29/07/2026): le quattro tinte semantiche sono state SCURITE del minimo indispensabile
     — dal 2% all'8%, uno scarto che accanto all'originale non si distingue — perché da oggi
     fanno da FONDO PIENO sotto una scritta bianca, e col vecchio valore il testo bianco non
     arrivava alla soglia di leggibilità (4,5:1): verde 4,15 · ambra 3,96 · rosso 4,39 ·
     viola 4,35. Ora: 4,53 · 4,54 · 4,50 · 4,50. Il blu era già a 4,51 e resta com'era.
     Nessuno dei 9 temi rimappa questi token (verificato: compaiono solo qui, nel :root base),
     quindi la correzione vale in tutti. Gli usi come TESTO su fondo chiaro non peggiorano,
     migliorano: 4,15→4,53, 3,96→4,54, 4,39→4,50, 4,35→4,50.
     Oro/Indaco/Rosa NON si toccano: lì il difetto non è la tinta ma il testo — vedi .dn nel
     blocco Z8 in coda. Le varianti -bg seguono la tinta nuova, stessa alpha di prima. */
  --c-ok:#1C8753;   --c-ok-bg:rgba(28,135,83,.12);
  --c-warn:#A36A12; --c-warn-bg:rgba(163,106,18,.14);
  --c-crit:#CE4A3C; --c-crit-bg:rgba(206,74,60,.12);
  --c-info:#2A7DB0; --c-info-bg:rgba(42,125,176,.12);
  --c-cost:#7A5AFA; --c-cost-bg:rgba(122,90,250,.12);
  --c-day:#E0A21B;  --c-night:#4B57C4; --c-dawn:#E6779E; --c-golden:#E2683C;

  /* ── raggi & ombre soft ── */
  --r-sm:12px; --r:16px; --r-lg:22px; --r-pill:999px; --r-row:10px;
  --sh-1:0 1px 2px rgba(17,24,39,.04), 0 1px 3px rgba(17,24,39,.05);
  --sh-2:0 2px 8px rgba(17,24,39,.05), 0 8px 24px rgba(17,24,39,.06);
  --sh-3:0 4px 14px rgba(17,24,39,.07), 0 20px 48px rgba(17,24,39,.10);
  --sh-pop:0 18px 56px rgba(17,24,39,.20);
  --ring:0 0 0 4px rgba(91,107,239,.16);
  /* glow neon iris dei riquadri (richiesta Emanuele: come «Presenze del giorno», su tutto il sito) */
  --glow:0 0 0 4px var(--accent-mute);
  /* z-index UNICO per OGNI menù a tendina/popover → sempre in primo piano, mai sotto le card (Emanuele) */
  --z-pop:9000;

  /* ── scala SPAZIATURA fluida (clamp) — respiro per REGOLA, non a gradini.
     MAX = valore desktop attuale (zero regressione) · MIN = mobile più compatto.
     Da ~360 a ~1280px scala dolce. Collaudo: banco di stress. [[flowset--banco-di-stress-responsive]] */
  --sp-1:clamp(6px,1.2vw,9px);
  --sp-2:clamp(8px,1.6vw,12px);
  --sp-3:clamp(10px,2vw,14px);
  --sp-4:clamp(12px,2.6vw,18px);
  --sp-5:clamp(14px,3vw,22px);
  --sp-6:clamp(15px,3.4vw,24px);
  /* ── scala TIPOGRAFICA fluida — gli INPUT restano ≥16px a parte (no zoom iOS) ── */
  --fs-xs:clamp(10px,2.4vw,11px);
  --fs-sm:clamp(11.5px,2.8vw,12.5px);
  --fs-base:clamp(12.5px,3.2vw,14px);
  --fs-md:clamp(14px,3.6vw,16px);
  --fs-lg:clamp(15px,4vw,19px);
  --fs-xl:clamp(19px,4.6vw,25px);

  /* ── motion tokens v0.3 — il "respiro" UNICO del sito (durate + curve condivise).
     Ogni elemento nuovo pesca da qui: animazioni allineate per costruzione. ── */
  --dur-fast:.16s; --dur-base:.3s; --dur-slow:.5s;
  --ease-out:cubic-bezier(.2,.8,.2,1); --ease-spring:cubic-bezier(.175,.885,.32,1.275);
  /* ── segnalibro / foto master (oro = token semantico --c-day) ── */
  --bm-gold:var(--c-day); --bm-idle:rgba(255,255,255,.82); --bm-size:18px;   /* segnalibro proporzionato e UNICO sitewide (Emanuele) */
}

/* ===========================================================================
   TEMI selezionabili (menù «Tema» in alto a dx Home). Ridefiniscono le CSS
   variables → TUTTO il sito eredita. Default = iris (:root). Persistito in
   localStorage['flowset_theme'] e applicato via documentElement[data-theme].
   Dark classico + 5 varianti chiare (tonalità di bianco diverse su fondale E
   box + un pastello diverso al posto del celeste/iris).
   =========================================================================== */
:root[data-theme="dark"]{
  --bg:#15171e; --surface:#1f232c; --s1:#1f232c; --s2:#262b35; --s3:#2e3440; --s4:#374050;
  --ink:#e8eaf0; --t1:#e8eaf0; --t2:#aab2c2; --t3:#7c8493;
  --border:#343c49; --border2:#3f4856; --border-soft:#2a303b;
  --glass-bg:rgba(31,35,44,.74); --glass-brd:rgba(255,255,255,.07);
  --accent:#7f8cff; --accent-deep:#9aa6ff; --accent-rgb:127,140,255;
  --accent-soft:rgba(127,140,255,.18); --accent-mute:rgba(127,140,255,.13); --accent-bord:rgba(127,140,255,.42); --accent-tag:#2b3052;
}
:root[data-theme="salvia"]{
  --bg:#eef2ec; --surface:#ffffff; --s2:#f1f5ef; --s3:#e9efe6; --s4:#dde7d8;
  --border:#d3ddcf; --border2:#c2cebd; --border-soft:#e7ede4;
  --accent:#5f9d77; --accent-deep:#4d8463; --accent-rgb:95,157,119;
  --accent-soft:rgba(95,157,119,.14); --accent-mute:rgba(95,157,119,.10); --accent-bord:rgba(95,157,119,.32); --accent-tag:#e2efe5;
}
:root[data-theme="pesca"]{
  --bg:#f5efe9; --surface:#fffefc; --s2:#faf3ec; --s3:#f3e9df; --s4:#ecdccc;
  --border:#e3d6c9; --border2:#d4c3b2; --border-soft:#efe5db;
  --accent:#cf7a5b; --accent-deep:#b5634a; --accent-rgb:207,122,91;
  --accent-soft:rgba(207,122,91,.14); --accent-mute:rgba(207,122,91,.10); --accent-bord:rgba(207,122,91,.32); --accent-tag:#f6e6dd;
}
:root[data-theme="lavanda"]{
  --bg:#f1eff7; --surface:#ffffff; --s2:#f4f1fa; --s3:#ece8f5; --s4:#ddd6ee;
  --border:#dcd6e8; --border2:#cbc2dd; --border-soft:#e9e4f2;
  --accent:#8b7bd6; --accent-deep:#7363c2; --accent-rgb:139,123,214;
  --accent-soft:rgba(139,123,214,.14); --accent-mute:rgba(139,123,214,.10); --accent-bord:rgba(139,123,214,.32); --accent-tag:#ebe6f7;
}
:root[data-theme="cielo"]{
  --bg:#eaf1f6; --surface:#ffffff; --s2:#eef4f9; --s3:#e4edf3; --s4:#d3e2ee;
  --border:#cfdde8; --border2:#bccedd; --border-soft:#e1eaf1;
  --accent:#4f93c4; --accent-deep:#3d7dac; --accent-rgb:79,147,196;
  --accent-soft:rgba(79,147,196,.14); --accent-mute:rgba(79,147,196,.10); --accent-bord:rgba(79,147,196,.32); --accent-tag:#dfecf5;
}
:root[data-theme="sabbia"]{
  --bg:#f3f0e8; --surface:#fffdf8; --s2:#f6f2ea; --s3:#eee8db; --s4:#e3d9c4;
  --border:#e0d8c7; --border2:#d0c5ad; --border-soft:#ebe4d5;
  --accent:#b59154; --accent-deep:#9c7a41; --accent-rgb:181,145,84;
  --accent-soft:rgba(181,145,84,.15); --accent-mute:rgba(181,145,84,.10); --accent-bord:rgba(181,145,84,.33); --accent-tag:#efe7d4;
}

/* ── TEMA «FLAT» (Emanuele): vira completamente dall'iris. Niente trasparenze/vetro, niente glow/neon,
   palette teal-ardesia piatta, ombre minime, angoli più contenuti e allungati. Solo override di VARIABILI
   + poche regole scoped (non riscrive i blocchi base). ── */
:root[data-theme="flat"]{
  /* palette CORALLO data da Emanuele («Palet FLAT»): accent #f7687f su bianco puro, testi near-black */
  --accent:#f7687f; --accent-deep:#e14b66; --accent-rgb:247,104,127;
  --accent-mute:rgba(247,104,127,.10); --accent-soft:rgba(247,104,127,.13); --accent-bord:rgba(247,104,127,.36); --accent-tag:#fde4e9;
  --terra:#aa1923;                     /* crimson della palette per i numeri-zona */
  --bg:#f3f4f6; --surface:#ffffff; --s1:#ffffff; --s2:#f5f6f8; --s3:#edeff2; --s4:#e1e4e9;
  --ink:#222222; --t1:#222222; --t2:#5a6066; --t3:#949aa2;
  --border:#e4e7eb; --border2:#cfd4da; --border-soft:#eef0f3;
  /* niente vetro: superfici OPACHE */
  --glass-bg:#ffffff; --glass-brd:#e4e7eb;
  /* niente neon */
  --glow:0 0 0 0 transparent;
  /* angoli più contenuti e «allungati» (rettangolari) — solo variabili, eredita tutto il sito */
  --r-sm:6px; --r:8px; --r-lg:9px; --r-row:6px; --r-pill:8px;
  /* ombre minime, piatte */
  --sh-1:0 1px 2px rgba(17,24,39,.06);
  --sh-2:0 1px 3px rgba(17,24,39,.08);
  --sh-3:0 2px 6px rgba(17,24,39,.09);
  --sh-pop:0 8px 28px rgba(17,24,39,.16);
  --ring:0 0 0 3px rgba(247,104,127,.20);
}
/* override scoped: tolgo i contorni accent/neon e il vetro dove sono hard-coded nei componenti */
:root[data-theme="flat"] .panel,
:root[data-theme="flat"] .card,
:root[data-theme="flat"] .pg-panel,
:root[data-theme="flat"] .tl-step.now .tl-chip{border:1px solid var(--border);box-shadow:var(--sh-1)}
:root[data-theme="flat"] .tg-tile{background:var(--surface);-webkit-backdrop-filter:none;backdrop-filter:none;border:1px solid var(--border);box-shadow:var(--sh-1)}
:root[data-theme="flat"] .modal.tg-float .tg-grid.tg2{background:var(--surface);-webkit-backdrop-filter:none;backdrop-filter:none;border:1px solid var(--border);box-shadow:var(--sh-2)}
:root[data-theme="flat"] .modal-back.tg-back{background:rgba(20,24,31,.45)}   /* backdrop piatto, niente bloom radiale */
:root[data-theme="flat"] .btn{border-radius:7px}
:root[data-theme="flat"] .dv-idcode{background:var(--accent)}   /* badge piatto, niente gradiente */

/* ── TEMA «ISTITUZIONALE» (Emanuele 29/06, render Gemini «Elegante ed istituzionale 2»): flat & clean
   MONOCROMO nero su grigio-bianco freddo, font SERIF display (DM Serif) su titoli + Plus Jakarta Sans
   sul corpo (mono = JetBrains, invariato). Semantici TENUTI (dot giorno/notte, ⚠). Eredita la struttura
   «flat» (niente vetro/neon/ombre pesanti). Solo override di VARIABILI + poche regole scoped. ── */
:root[data-theme="istituzionale"]{
  /* font: serif display + Jakarta corpo (mono invariato) */
  --ff-sans:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,system-ui,sans-serif;
  --ff-display:'DM Serif Display',Georgia,'Times New Roman',serif;
  /* accento MONOCROMO nero #111111 — chrome nero, niente colore */
  --accent:#111111; --accent-deep:#000000; --accent-rgb:17,17,17;
  --accent-mute:rgba(17,17,17,.06); --accent-soft:rgba(17,17,17,.08); --accent-bord:rgba(17,17,17,.18); --accent-tag:#ececec;
  --terra:#7a1f17;                     /* numeri-zona sobri, non sgargianti */
  /* superfici: bg grigio-bianco freddo del render, schede BIANCO PURO */
  --bg:#F5F7FA; --surface:#FFFFFF; --s1:#FFFFFF; --s2:#F5F7FA; --s3:#EEF1F5; --s4:#E3E8EF;
  --ink:#111111; --t1:#111111; --t2:#555555; --t3:#8A9099;
  --border:#E4E8EE; --border2:#D4DAE2; --border-soft:#EEF1F5;
  /* niente vetro: superfici OPACHE */
  --glass-bg:#FFFFFF; --glass-brd:#E4E8EE;
  /* niente neon */
  --glow:0 0 0 0 transparent;
  /* angoli eleganti (render ~12-14px) */
  --r-sm:10px; --r:14px; --r-lg:16px; --r-row:10px; --r-pill:999px;
  /* ombre minime, pulite */
  --sh-1:0 1px 2px rgba(16,24,40,.04);
  --sh-2:0 1px 3px rgba(16,24,40,.06);
  --sh-3:0 4px 12px rgba(16,24,40,.07);
  --sh-pop:0 12px 40px rgba(16,24,40,.14);
  --ring:0 0 0 3px rgba(17,17,17,.12);
}
/* override scoped (gemello del tema flat): via vetro/neon dai componenti hard-coded */
:root[data-theme="istituzionale"] .panel,
:root[data-theme="istituzionale"] .card,
:root[data-theme="istituzionale"] .pg-panel,
:root[data-theme="istituzionale"] .tl-step.now .tl-chip{border:1px solid var(--border);box-shadow:var(--sh-1)}
:root[data-theme="istituzionale"] .tg-tile{background:var(--surface);-webkit-backdrop-filter:none;backdrop-filter:none;border:1px solid var(--border);box-shadow:var(--sh-1)}
:root[data-theme="istituzionale"] .modal.tg-float .tg-grid.tg2{background:var(--surface);-webkit-backdrop-filter:none;backdrop-filter:none;border:1px solid var(--border);box-shadow:var(--sh-2)}
:root[data-theme="istituzionale"] .modal-back.tg-back{background:rgba(17,20,27,.45)}
:root[data-theme="istituzionale"] .btn{border-radius:var(--r-pill)}
:root[data-theme="istituzionale"] .dv-idcode{background:var(--accent)}
/* TIPOGRAFIA display: serif SOLO su hero + numerone (peso 400 — DM Serif è già display/heavy) */
:root[data-theme="istituzionale"] .odg-title{font-family:var(--ff-display);font-weight:400;font-size:30px;letter-spacing:-.2px;line-height:1.06}
:root[data-theme="istituzionale"] .odg-num .big{font-family:var(--ff-display);font-weight:400;letter-spacing:0}
/* ===== v0.5 RETTIFICA 1 FONT HOME 4.0 — serif sui display .h4-* (port di css/06-istituzionale.css §2).
   In 4.0 i titoli home (.h4-h1 "Roma Criminale", header sezione, numeroni statcard, gradi meteo) sono
   DM Serif Display; in v0.5 era mappato solo .odg-title/.odg-num .big (selettori v0.3 mai usati da home4),
   cosi il titolo ereditava il sans del body. Specificita 0,3,0 > .h4-h1 (0,1,0) iniettato da home4 → vince
   senza !important. DM Serif ha SOLO peso 400 → forzo 400 (no faux-bold) e allento il letter-spacing.
   Scoped istituzionale + .h4-* (solo home) → zero impatto su Compiler/altri temi. Revert = cancella il blocco. ===== */
:root[data-theme="istituzionale"] .h4-h1,
:root[data-theme="istituzionale"] .h4-sec-h h2,
:root[data-theme="istituzionale"] .h4-sn,
:root[data-theme="istituzionale"] .h4-deg,
:root[data-theme="istituzionale"] .modal h2{font-family:var(--ff-display);font-weight:400;letter-spacing:-.005em}
/* il sottotitolo <small> dell'hero resta in sans (Plus Jakarta), come in 4.0 */
:root[data-theme="istituzionale"] .h4-h1 small{font-family:var(--ff-sans);font-weight:600;letter-spacing:0}
/* ===== fine rettifica 1 font home ===== */
/* ICONE: variante DEFAULT = contorno inspessito (le filled native = confronto a parte) */
:root[data-theme="istituzionale"] .ic{stroke-width:2.3px}
/* RASTRELLO leak-iris → MONOCROMO: logo brand, avatar (topbar + toast), FAB feedback */
:root[data-theme="istituzionale"] .side-top .logo{background:var(--accent);box-shadow:none}
:root[data-theme="istituzionale"] .avatar,
:root[data-theme="istituzionale"] .dv-av{background:var(--accent)}
:root[data-theme="istituzionale"] .fab{background:var(--accent);box-shadow:var(--sh-3)}
:root[data-theme="istituzionale"] .fb-head .logo{background:var(--accent)}
/* NAV: icone più presenti; voce ATTIVA grigia tenue + testo/icona neri (come render), niente ombra blu */
:root[data-theme="istituzionale"] .nav-item .ico{color:var(--t2)}
:root[data-theme="istituzionale"] .nav-item.active{background:var(--s4);color:var(--t1);box-shadow:none;font-weight:600}
:root[data-theme="istituzionale"] .nav-item.active .ico{color:var(--t1)}
:root[data-theme="istituzionale"] .nav-item.active .pin{color:var(--t1);background:rgba(17,17,17,.08)}
/* BOX METEO .wxu: da vetro scuro → card bianca, testo scuro, niente bloom colorato (coerente col flat) */
:root[data-theme="istituzionale"] .wxu-glow{display:none}
:root[data-theme="istituzionale"] .wxu-card{background:var(--surface);border:1px solid var(--border);box-shadow:var(--sh-1);backdrop-filter:none;-webkit-backdrop-filter:none}
:root[data-theme="istituzionale"] .wxu-city,
:root[data-theme="istituzionale"] .wxu-ico,
:root[data-theme="istituzionale"] .wxu-temp,
:root[data-theme="istituzionale"] .wxu-h{color:var(--t1)}
:root[data-theme="istituzionale"] .wxu-cond,
:root[data-theme="istituzionale"] .wxu-tv{color:var(--t2)}
:root[data-theme="istituzionale"] .wxu-max{border-left-color:var(--border)}

/* menù «Tema» (combo in alto a dx Home) */
.thm{position:relative;display:inline-flex}
.thm-pop{position:fixed;z-index:var(--z-pop);background:var(--surface);border:1px solid var(--border);
  border-radius:14px;box-shadow:var(--sh-pop);padding:7px;width:208px}
.thm-pop[hidden]{display:none}
.thm-opt{display:flex;align-items:center;gap:10px;width:100%;text-align:left;background:transparent;border:0;border-radius:9px;
  padding:8px 10px;font:600 13px var(--ff-sans);color:var(--t1);cursor:pointer;transition:background .12s}
.thm-opt:hover{background:var(--s2)}
.thm-opt.on{background:var(--accent-mute);color:var(--accent-deep);font-weight:700}
.thm-sw{width:22px;height:22px;border-radius:50%;position:relative;flex:none;display:inline-grid;place-items:center;border:1px solid rgba(0,0,0,.1)}
.thm-sw.sm{width:16px;height:16px;margin-right:1px}
.thm-ac{width:9px;height:9px;border-radius:50%;box-shadow:0 0 0 1.5px var(--surface)}
.thm-nm{flex:1}
.thm-ck{color:var(--accent);font-weight:800}

/* ===========================================================================
   METEO — componente Uiverse «grumpy-mule-23» (glass card + cerchio sfocato),
   copiato e normalizzato; classi .wxu-* (namespacate). Alimentato da meteoAuto.
   =========================================================================== */
.wxu{position:relative;display:flex;align-items:center;justify-content:center;padding:6px;
  width:fit-content;max-width:100%;margin-inline:auto;overflow:hidden;border-radius:22px}   /* clip: il glow resta un bloom INTERNO, non sborda (era senza overflow) */
.wxu-glow{position:absolute;width:120px;height:120px;border-radius:50%;filter:blur(10px);opacity:.85;z-index:0;
  left:54%;top:22%;transition:transform 1s var(--ease-out)}
.wxu:hover .wxu-glow{transform:translate(-46px,46px)}
.wxu-card{position:relative;z-index:1;width:234px;min-height:230px;display:flex;flex-direction:column;align-items:center;
  justify-content:space-between;gap:8px;padding:20px 14px;border-radius:16px;
  backdrop-filter:blur(30px) saturate(150%);-webkit-backdrop-filter:blur(30px) saturate(150%);
  background:rgba(40,46,66,.36);border:1px solid rgba(255,255,255,.24);
  box-shadow:var(--sh-2),inset 0 1px 0 rgba(255,255,255,.14)}   /* bordo un filo più in rilievo */
.wxu-city{font:700 14px var(--ff-sans);letter-spacing:1.2px;color:#fff;text-align:center;line-height:1.2}
.wxu-cond{font:500 11px var(--ff-sans);letter-spacing:1px;color:rgba(255,255,255,.82);text-align:center}
.wxu-ico{color:#fff;display:grid;place-items:center;margin:2px 0}
.wxu-temp{font:300 42px var(--ff-sans);color:#fff;line-height:1}
.wxu-mm{width:100%;display:flex;align-items:center;justify-content:center}
.wxu-min,.wxu-max{width:50%;display:flex;flex-direction:column;align-items:flex-end;gap:2px;padding:0 18px}
.wxu-max{align-items:flex-start;border-left:2px solid rgba(255,255,255,.55)}
.wxu-h{font:600 11px var(--ff-sans);color:#fff}
.wxu-tv{font:500 12px var(--ff-sans);color:rgba(255,255,255,.82)}
.wxu.mini .wxu-card{width:212px;min-height:182px;padding:16px 12px;gap:5px}
.wxu.mini .wxu-temp{font-size:33px}
@media(max-width:560px){.wxu-card{width:100%}}

/* toni per reparto (card convocati, dot, compiler)
   Z8: tre toni scuriti perché anche loro fanno da fondo pieno sotto il bianco in .chip.tone.
   L'elettricisti era il caso grave — giallo #C79A12 col bianco sopra faceva 2,61:1, cioè una
   scritta che sul serio non si legge; ora 4,51. Scenografia 4,02→4,50, costumi 4,35→4,50.
   Produzione, regia, camera, macchinisti e trucco reggevano già (4,51-6,00) e restano identici. */
.tone-prod    {--tone:#5B6470;--tone-bg:rgba(91,100,112,.12)}
.tone-regia   {--tone:#5E5CE6;--tone-bg:rgba(94,92,230,.13)}
.tone-camera  {--tone:#2A7DB0;--tone-bg:rgba(42,125,176,.12)}
.tone-grip    {--tone:#8A5A2B;--tone-bg:rgba(138,90,43,.14)}
.tone-electric{--tone:#93720D;--tone-bg:rgba(147,114,13,.16)}
.tone-art     {--tone:#1C8576;--tone-bg:rgba(28,133,118,.12)}
.tone-costume {--tone:#7A5AFA;--tone-bg:rgba(122,90,250,.12)}
.tone-makeup  {--tone:#C0497E;--tone-bg:rgba(192,73,126,.12)}
.tone-sound   {--tone:#4B57C4;--tone-bg:rgba(75,87,196,.12)}
.tone-cast    {--tone:#1E8E57;--tone-bg:rgba(30,142,87,.12)}
.tone-misc    {--tone:#6B7280;--tone-bg:rgba(107,114,128,.12)}

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{font-family:var(--ff-sans);
  background:var(--bg);color:var(--t1);font-size:14px;line-height:1.5;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
button{font-family:inherit;cursor:pointer}
a{color:inherit;text-decoration:none}
.mono{font-family:'JetBrains Mono',ui-monospace,'SF Mono',Menlo,monospace}
.muted{color:var(--t3)}
.link{color:var(--accent-deep);font-weight:600}
.link:hover{color:var(--accent);text-decoration:underline}
.ic{display:inline-block;vertical-align:-.18em;flex-shrink:0}
::-webkit-scrollbar{width:12px;height:12px}
::-webkit-scrollbar-thumb{background:#CFD2D9;border-radius:8px;border:3px solid var(--bg)}
::-webkit-scrollbar-thumb:hover{background:#B9BDC6}

/* utility glass */
.glass-panel{background:var(--glass-bg);backdrop-filter:blur(20px) saturate(180%);
  -webkit-backdrop-filter:blur(20px) saturate(180%);border:1px solid var(--glass-brd);
  box-shadow:var(--sh-2);border-radius:var(--r-lg)}

/* ===========================================================================
   LAYOUT — sidebar flottante chiara + contenuto
   =========================================================================== */
.app{display:flex;height:100vh;overflow:hidden;
  background:
    radial-gradient(900px 480px at 100% -10%, rgba(91,107,239,.07), transparent 62%),
    radial-gradient(720px 420px at -6% 112%, rgba(124,92,255,.05), transparent 60%),
    var(--bg)}

.side-col{width:248px;flex-shrink:0;display:flex;flex-direction:column;padding:14px 4px 14px 14px;gap:8px;
  transition:width .28s cubic-bezier(.2,.8,.2,1)}
.app.collapsed .side-col{width:92px;padding:14px 7px}

.sidebar{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);
  align-self:stretch;width:100%;max-height:calc(100vh - 28px);overflow:visible;
  display:flex;flex-direction:column;gap:2px;padding:14px 12px 12px;box-shadow:var(--sh-2);color:var(--t1)}
.side-top{display:flex;align-items:center;gap:10px;padding:4px 6px 12px;border-bottom:1px solid var(--border);margin-bottom:8px}
.side-top .logo{width:30px;height:30px;border-radius:9px;flex-shrink:0;display:grid;place-items:center;color:#fff;
  background:linear-gradient(135deg,#6b78f5,#4453d6);box-shadow:0 4px 12px rgba(91,107,239,.4)}
.side-top .brand-name{font-size:16px;font-weight:800;letter-spacing:-.4px;color:var(--t1);white-space:nowrap}
.side-top .ver{font:700 9px 'JetBrains Mono',monospace;color:var(--accent-deep);background:var(--accent-soft);border-radius:5px;padding:2px 6px}
.side-collapse{margin-left:auto;width:30px;height:30px;border-radius:9px;border:1px solid var(--border);
  background:var(--surface);color:var(--t2);display:grid;place-items:center;flex-shrink:0;transition:all .15s}
.side-collapse:hover{background:var(--s2);color:var(--t1);border-color:var(--border2)}
.side-collapse .ic{transition:transform .26s cubic-bezier(.2,.8,.2,1)}
.app:not(.collapsed) .side-collapse .ic{transform:rotate(180deg)}
.side-nav{display:flex;flex-direction:column;gap:2px;overflow-y:auto;overflow-x:hidden;flex:1 1 auto;min-height:0;padding-top:2px}
.side-foot{color:var(--t3);font-size:11px;padding:2px 16px;line-height:1.5;white-space:nowrap;overflow:hidden}
.app.collapsed .side-foot{display:none}

.nav-item{display:flex;align-items:center;gap:12px;color:var(--t2);padding:10px 12px;border-radius:12px;
  font-size:13.5px;font-weight:500;transition:background .14s,color .14s,box-shadow .14s;cursor:pointer;
  position:relative;white-space:nowrap}
.nav-item .ico{width:20px;height:20px;display:grid;place-items:center;color:var(--t3);flex-shrink:0;transition:color .14s}
.nav-item .lbl{overflow:hidden;text-overflow:ellipsis}
.nav-item:hover{background:var(--s2);color:var(--t1)}
.nav-item:hover .ico{color:var(--t1)}
.nav-item.active{background:var(--accent);color:#fff;font-weight:600;box-shadow:0 8px 18px rgba(91,107,239,.30)}
.nav-item.active .ico{color:#fff}
.nav-item .pin{margin-left:auto;font:700 9px 'JetBrains Mono';color:var(--accent-deep);background:var(--accent-soft);border-radius:5px;padding:2px 6px}
.nav-item.active .pin{color:#fff;background:rgba(255,255,255,.22)}
.nav-sep{height:1px;background:var(--border);margin:9px 8px}
.nav-cap{color:var(--t3);font:700 9.5px var(--ff-sans);letter-spacing:.7px;text-transform:uppercase;padding:11px 12px 5px}
/* collassata: solo icone centrate */
.app.collapsed .sidebar{padding:14px 7px 10px;overflow-x:hidden}
.app.collapsed .side-top{justify-content:center;gap:4px;padding:4px 0 12px}
.app.collapsed .side-top .logo{width:28px;height:28px}
.app.collapsed .side-top .brand-name,.app.collapsed .side-top .ver,
.app.collapsed .nav-item .lbl,.app.collapsed .nav-item .pin,.app.collapsed .nav-cap{display:none}
/* collassata: pulsanti QUADRATI centrati (background+ombra contenuti negli 86px,
   così la voce attiva non sborda sul contenuto) + contenuto con più respiro */
.app.collapsed .nav-item{justify-content:center;padding:0;width:44px;height:44px;margin:2px auto}
.app.collapsed .nav-item.active{box-shadow:0 4px 12px rgba(91,107,239,.28)}
.app.collapsed .nav-item .ico{margin:0}
.app.collapsed .content{padding-left:14px}
.app.collapsed .side-collapse{margin-left:0;width:28px;height:28px}

/* contenuto: topbar glass + area scrollabile */
.content{flex:1;min-width:0;display:flex;flex-direction:column;height:100vh;padding:14px 16px 0 6px}
.topbar{background:var(--glass-bg);backdrop-filter:blur(20px) saturate(180%);-webkit-backdrop-filter:blur(20px) saturate(180%);
  border:1px solid var(--border);border-radius:var(--r);display:flex;align-items:center;gap:12px;
  padding:0 16px;height:58px;flex-shrink:0;z-index:40;box-shadow:var(--sh-1)}
.main{flex:1;overflow-y:auto;padding:22px 16px 110px;z-index:1;scrollbar-gutter:stable}   /* C2-bis (feedback Emanuele): .main è lo scroller REALE del contenuto → riservo SEMPRE lo spazio della scrollbar (12px, ::-webkit-scrollbar) così il contenuto non salta di larghezza quando la scrollbar appare/scompare (la card del compositore stampe si allargava/restringeva allo swap ORDINA PER perché il riepilogo .rc-sum cambiava altezza e tuffava dentro/fuori la scrollbar). Su mobile la scrollbar è overlay → riserva 0, nessun effetto. */

/* topbar bits */
.prod-pill{display:inline-flex;align-items:center;gap:8px;background:var(--s2);border:1px solid var(--border);
  border-radius:var(--r-pill);padding:7px 14px;font-weight:600;font-size:12.5px;color:var(--t1);transition:all .15s}
.prod-pill:hover{background:var(--surface);border-color:var(--border2)}
.prod-pill .ic{color:var(--t3)}
.search{flex:1;max-width:560px;display:flex;align-items:center;gap:10px;background:var(--s2);border:1px solid var(--border);
  border-radius:var(--r-pill);padding:9px 16px;transition:all .16s}
.search .ic{color:var(--t3)}
.search:focus-within{border-color:var(--accent-bord);box-shadow:var(--ring);background:var(--surface)}
.search input{flex:1;border:0;background:transparent;outline:none;font-size:13px;color:var(--t1)}
.search input::placeholder{color:var(--t3)}
.search .ai-badge{font:700 9.5px var(--ff-sans);letter-spacing:.4px;color:#fff;background:var(--accent);border-radius:6px;padding:3px 7px;white-space:nowrap;flex:0 0 auto}
.icon-btn{width:36px;height:36px;display:grid;place-items:center;border:1px solid var(--border);border-radius:var(--r-pill);background:var(--surface);color:var(--t2);transition:all .15s}
.icon-btn:hover{border-color:var(--border2);color:var(--t1);background:var(--s2)}
.avatar{width:36px;height:36px;border:0;border-radius:50%;background:linear-gradient(135deg,#6b78f5,#4453d6);color:#fff;display:grid;place-items:center;font-weight:700;font-size:12px;flex-shrink:0}
.role-sw{display:flex;align-items:center;border:1px solid var(--border);border-radius:var(--r-pill);background:var(--s2);padding:3px;font-size:11.5px;font-weight:600}
.role-sw button{border:0;background:transparent;color:var(--t3);padding:6px 12px;border-radius:var(--r-pill);transition:all .15s;display:flex;align-items:center;gap:5px}
.role-sw button.on{background:var(--surface);color:var(--t1);box-shadow:var(--sh-1)}
.role-sw button.on.master{background:var(--accent);color:#fff}
/* #E switcher reparto attivo (multireparto) — specchia .role-sw; [hidden] deve battere display:flex */
.rep-sw{display:flex;align-items:center;border:1px solid var(--border);border-radius:var(--r-pill);background:var(--s2);padding:3px;font-size:11.5px;font-weight:600}
.rep-sw button{border:0;background:transparent;color:var(--t3);padding:6px 12px;border-radius:var(--r-pill);transition:all .15s;display:flex;align-items:center;gap:5px;cursor:pointer}
.rep-sw button.on{background:var(--surface);color:var(--t1);box-shadow:var(--sh-1)}
.rep-sw[hidden]{display:none}

/* ===========================================================================
   HEADINGS · PANNELLI · CARD
   =========================================================================== */
.page-head{display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:22px;gap:18px;flex-wrap:wrap}
.h-title{font-size:25px;font-weight:800;letter-spacing:-.6px;color:var(--t1)}
.h-sub{color:var(--t3);font-size:var(--fs-sm);margin-top:4px}

/* A1.3 (fix 03/07, richiesta Andrea): riga azioni Annulla/Anteprima/Pubblica del
   compilatore ODG SEGUE lo scroll. Scope SOLO .odg-cmp-head (wrapper attorno al
   page-head di odg.js renderCompiler) → il .page-head GLOBALE (Home/Anagrafica/…)
   resta invariato. position:sticky, MAI transform (non crea containing-block per i
   fixed → nessuna trappola sui modali, regola d'oro #3). */
.odg-cmp-head{position:sticky;top:0;z-index:5;background:var(--bg);margin:0 -16px 22px;padding:16px 16px 12px;border-bottom:1px solid var(--border)}
.odg-cmp-head .page-head{margin-bottom:0}
@media(max-width:560px){.odg-cmp-head{margin:0 -12px 22px;padding:14px 12px 10px}}

.panel{background:var(--surface);border:1.5px solid var(--accent);border-radius:var(--r-lg);box-shadow:var(--glow),var(--sh-2);margin-bottom:20px;position:relative;overflow:visible}
.panel.pad{padding:var(--sp-5) var(--sp-6)}
.panel-head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:var(--sp-4) var(--sp-5);border-bottom:1px solid var(--border)}
.panel-head h3{font-size:var(--fs-md);font-weight:700;letter-spacing:-.3px;display:flex;align-items:center;gap:10px;color:var(--t1)}
.panel-head .accent{width:4px;height:18px;border-radius:3px;background:var(--accent)}
.panel-body{padding:var(--sp-4) var(--sp-5)}

.sect{border-left:3px solid var(--tone,var(--accent));padding-left:14px;margin:6px 0 14px;position:relative}
.sect .lab{font:700 10.5px var(--ff-sans);letter-spacing:.5px;text-transform:uppercase;color:var(--t3);display:flex;align-items:center;gap:7px}
.sect .lab .ic{color:var(--tone,var(--accent))}

.card{background:var(--surface);border:1.5px solid var(--accent);border-radius:var(--r);box-shadow:var(--glow),var(--sh-1)}
.card-pad{padding:18px 20px}
.card-head{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid var(--border)}
.card-head h3{font-size:15px;font-weight:700}
.grid2{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:20px;align-items:start}
/* RESPONSIVE — invariante anti-sbordo n.1: un testo lunghissimo (nome/URL/parola senza spazi) DEVE
   spezzarsi, non dilatare il box né uscire dallo schermo. Collaudo: banco di stress
   ?stress=xl&audit=1 [[flowset--banco-di-stress-responsive]]

   ⚑ TAPPA O (27/07/2026) — era un ELENCO di 22 selettori, e un elenco non è una regola: ogni
   componente nato dopo il 22/06 (h4-* della Home, .ph-id della Dashboard, il sottotitolo
   dell'ODG) ricascava nel difetto perché nessuno si ricordava di aggiungercelo, e a 390px il
   testo usciva dallo schermo TAGLIATO DI NETTO — senza a-capo e senza ellissi, perché .app ha
   overflow:hidden e se lo mangia in silenzio (misurato: 9 misure su 85 perdevano contenuto).
   Ora la regola sta sulla RADICE e si EREDITA — overflow-wrap è una proprietà ereditata —
   quindi qualunque cosa nasca dentro la pagina (viste, modali, pop, portali, e la roba che non
   esiste ancora) la prende gratis. Dove serve l'ellissi c'è `white-space:nowrap`, che vince su
   questa e la rende inerte: i chip e le righe troncate restano identici.
   ⚑ `anywhere`, non `break-word`, e la differenza è stata MISURATA sul banco, non scelta a
   gusto: solo `anywhere` conta le occasioni di rottura anche nel calcolo della LARGHEZZA MINIMA
   del contenuto, ed è quella che permette a una cella di stringersi invece di sfondare. Provate
   entrambe sulle stesse 85 misure: `break-word` ne lasciava 14 con contenuto perso, `anywhere`
   zero. Il prezzo è che una colonna davvero strettissima può spezzare una parola a metà
   («Prossi / ma», visto in Home a 390px): quello si cura dando una larghezza minima a QUELLA
   colonna — scelta tipografica del componente, vedi .od-deck-mid in home4.js — non rinunciando
   all'invariante e ributtando via il testo.
   Guardia che impedisce la ricaduta: tools/qa_O/z23_responsive_niente_perso.js */
body{overflow-wrap:anywhere}

/* ===========================================================================
   TABELLE (ariose, niente bordi rigidi)
   =========================================================================== */
.table{width:100%;border-collapse:collapse}
.table th{text-align:left;font-size:10.5px;letter-spacing:.5px;text-transform:uppercase;color:var(--t3);font-weight:700;padding:13px 18px;border-bottom:1px solid var(--border)}
.table td{padding:14px 18px;border-bottom:1px solid var(--s3);font-size:13px;vertical-align:middle;color:var(--t1)}
.table tr:last-child td{border-bottom:0}
.table tbody tr{transition:background .12s}
.table tbody tr:hover{background:var(--s2)}
.table tbody tr.row-click{cursor:pointer}   /* intera riga cliccabile → apre la scheda (feedback Emanuele) */
.table th.ta-c,.table td.ta-c{text-align:center}   /* colonne Stato/Q.tà centrate (feedback Andrea) */
/* Bug 4 — intestazioni ordinabili (Inventario): click sull'header → ordina, l'ordine resta in memoria per utente */
/* header ORDINABILE: font più marcato e scuro delle colonne statiche, così si vede che è cliccabile.
   ▾ = hint "riordina" (inattiva); quando attiva ▲/▼ = direzione + badge col numero di priorità (multi-chiave). */
.table th.th-sort{cursor:pointer;user-select:none;transition:color .12s;color:var(--t1);font-weight:800}
.table th.th-sort:hover{color:var(--accent-deep)}
.table th.th-sort.on{color:var(--accent-deep)}
.table th.th-sort .th-hint{display:inline-block;margin-left:4px;font-size:8px;vertical-align:middle;color:var(--t3);opacity:.5;transition:opacity .12s,color .12s}
.table th.th-sort:hover .th-hint{opacity:1;color:var(--accent)}
.table th.th-sort .th-arrow{display:inline-block;margin-left:4px;font-size:9px;vertical-align:middle;color:var(--accent)}
.table th.th-sort .th-rank{display:inline-flex;align-items:center;justify-content:center;width:14px;height:14px;margin-left:5px;border-radius:50%;background:var(--accent);color:#fff;font:700 9px 'JetBrains Mono',monospace;vertical-align:middle;line-height:1}
/* #6 (Andrea): l'evidenziazione dell'ultima riga combacia con gli angoli arrotondati del pannello */
.table tbody tr:last-child td:first-child{border-bottom-left-radius:var(--r-lg)}
.table tbody tr:last-child td:last-child{border-bottom-right-radius:var(--r-lg)}
.table tbody tr:first-child td{background-clip:padding-box}
/* ricerca nei chips lunghi (modali) */
.chip-search-wrap{max-width:none!important;margin-bottom:8px;background:var(--surface)!important}

/* ===========================================================================
   BOTTONI
   =========================================================================== */
.btn{display:inline-flex;align-items:center;gap:8px;border:1px solid transparent;border-radius:var(--r-pill);padding:10px 16px;
  font-size:13px;font-weight:600;transition:all .16s;white-space:nowrap;line-height:1}
.btn .ic{margin:-2px 0}
.btn-primary{background:var(--accent);color:#fff;box-shadow:0 6px 16px rgba(91,107,239,.26)}
.btn-primary:hover{background:var(--accent-deep);transform:translateY(-1px);box-shadow:0 10px 22px rgba(91,107,239,.32)}
.btn-soft{background:var(--accent-soft);color:var(--accent-deep)}
.btn-soft:hover{background:rgba(91,107,239,.18)}
.btn-ink{background:var(--ink);color:#fff}
.btn-ink:hover{background:#000;transform:translateY(-1px)}
.btn-ghost{background:var(--surface);border-color:var(--border);color:var(--t2)}
.btn-ghost:hover{border-color:var(--border2);color:var(--t1);background:var(--s2)}
.btn-sm{padding:7px 12px;font-size:12px;border-radius:var(--r-pill);gap:6px}
.btn-lg{padding:12px 20px;font-size:14px;border-radius:14px}
.btn[disabled]{opacity:.55;cursor:progress;transform:none;box-shadow:none;pointer-events:none}

/* ===========================================================================
   CHIP / BADGE
   =========================================================================== */
.chip{display:inline-flex;align-items:center;gap:6px;font-size:11px;font-weight:600;padding:4px 11px;border-radius:var(--r-pill);border:1px solid transparent;line-height:1.3}
.chip .dot{width:7px;height:7px;border-radius:50%}
.chip.ok{background:var(--c-ok-bg);color:var(--c-ok)}
.chip.warn,.chip.todo{background:var(--c-warn-bg);color:var(--c-warn)}
.chip.crit{background:var(--c-crit-bg);color:var(--c-crit)}
.chip.info{background:var(--c-info-bg);color:var(--c-info)}
.chip.cost{background:var(--c-cost-bg);color:var(--c-cost)}
.chip.neutral{background:var(--s2);color:var(--t2);border-color:var(--border)}
.chip.tone{background:var(--tone-bg);color:var(--tone)}
.thumb{width:38px;height:38px;border-radius:11px;background:var(--s3);border:1px solid var(--border);display:grid;place-items:center;color:var(--t3);flex-shrink:0}
.ie{font:700 10px 'JetBrains Mono';padding:3px 7px;border-radius:6px;border:1px solid var(--border)}
.ie.INT{background:var(--c-info-bg);color:var(--c-info);border-color:transparent}
.ie.EXT{background:var(--accent-mute);color:var(--accent-deep);border-color:transparent}
.dn{font:700 10px 'JetBrains Mono';padding:3px 8px;border-radius:6px;color:#fff}
.dn.D{background:var(--c-day)} .dn.N{background:var(--c-night)} .dn.A,.dn.T{background:var(--c-dawn)}

/* ===========================================================================
   INPUT
   =========================================================================== */
.input,select.input,textarea.input{width:100%;min-width:0;max-width:100%;background:var(--surface);border:1px solid var(--border);border-radius:12px;
  padding:11px 13px;font-size:13px;color:var(--t1);font-family:inherit;outline:none;transition:border-color .15s,box-shadow .15s}
textarea.input{resize:vertical;min-height:64px}
.input:focus{border-color:var(--accent-bord);box-shadow:var(--ring)}
.field{margin-bottom:14px;min-width:0}
/* invariante anti-dilatazione: i grid-item hanno min-width:auto di default → NON collassano
   sotto il min-content e un campo/valore lungo sfonda la traccia. min-width:0 li libera. */
.cmp-grid>*,.modal-grid>*,.grid2>*{min-width:0}
.field>label{display:block;font-size:var(--fs-xs);color:var(--t3);font-weight:700;margin-bottom:6px;text-transform:uppercase;letter-spacing:.4px}
/* campo misura: input con suffisso unità + riga di conversione live [[pattern--flowset-input-misura]] */
.meas{position:relative;display:flex;align-items:center}
.meas-in{padding-right:46px!important}
.meas-unit{position:absolute;right:13px;font:700 12px 'JetBrains Mono';color:var(--t3);pointer-events:none}
.meas-conv{display:block;margin-top:5px;font:600 11px 'JetBrains Mono';color:var(--accent-deep);min-height:13px}
.meas-conv:empty{display:none}

/* ===========================================================================
   HOME ODG — hero + meteo
   =========================================================================== */
.odg-hero{display:flex;gap:0;align-items:stretch;flex-wrap:wrap;overflow:hidden}
.odg-hero .meta{flex:1;min-width:300px;padding:24px 26px;display:flex;flex-direction:column;gap:12px}
.odg-num{display:inline-flex;align-items:center;gap:12px}
.odg-num .big{font:800 32px var(--ff-sans);letter-spacing:-1px;line-height:1;color:var(--t1)}
.odg-num .big b{color:var(--accent)}
.odg-num .tag{font:700 11px 'JetBrains Mono';color:var(--accent-deep);background:var(--accent-soft);border-radius:var(--r-pill);padding:4px 11px}
.odg-title{font-size:21px;font-weight:800;letter-spacing:-.5px}
.odg-sub{color:var(--t2);font-size:13px}
.odg-facts{display:flex;flex-wrap:wrap;gap:10px;margin-top:4px}
.fact{display:flex;flex-direction:column;gap:2px;background:var(--s2);border:1px solid var(--border);border-radius:14px;padding:9px 14px;min-width:104px}
.fact .k{font:700 9.5px var(--ff-sans);letter-spacing:.5px;text-transform:uppercase;color:var(--t3)}
.fact .v{font:700 16px 'JetBrains Mono';color:var(--t1)}
.fact.crit{border-color:rgba(209,75,61,.3);background:var(--c-crit-bg)} .fact.crit .v{color:var(--c-crit)}

/* box meteo: cielo per day/night + animazioni per condizione */
.wx{width:316px;min-height:206px;border-radius:var(--r-lg);position:relative;overflow:hidden;color:#fff;align-self:center;margin:18px 22px 18px 0;
  display:flex;flex-direction:column;justify-content:flex-end;padding:18px;flex-shrink:0;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.14),0 14px 34px rgba(17,24,39,.18)}
.wx[data-dn="giorno"] {background:linear-gradient(160deg,#5BA7D8 0%,#8FC4E6 55%,#DCEAF2 100%)}
.wx[data-dn="notte"]  {background:linear-gradient(160deg,#1A1F4A 0%,#34306B 60%,#5A4E86 100%)}
.wx[data-dn="alba"]   {background:linear-gradient(160deg,#F2A65A 0%,#E2683C 50%,#9C5C9E 100%)}
.wx[data-dn="tramonto"]{background:linear-gradient(160deg,#E2683C 0%,#C0497E 52%,#4B57C4 100%)}
.wx-sky{position:absolute;inset:0;overflow:hidden}
.wx-meta{position:relative;z-index:3;text-shadow:0 1px 3px rgba(0,0,0,.3)}
.wx-temp{font:800 36px var(--ff-sans);line-height:1}
.wx-temp small{font:700 16px var(--ff-sans);opacity:.8}
.wx-cond{font-weight:600;font-size:13px;margin-top:3px;text-transform:capitalize}
.wx-line{font:600 11.5px 'JetBrains Mono';opacity:.94;margin-top:8px;display:flex;gap:14px;flex-wrap:wrap;align-items:center}
.wx-line .ic{opacity:.9}
.wx-sun{position:absolute;top:28px;right:32px;width:54px;height:54px;border-radius:50%;
  background:radial-gradient(circle at 38% 35%,#FFF6D4,#FFD45A 60%,#FFB02E);
  box-shadow:0 0 30px 8px rgba(255,206,84,.55);animation:wxglow 4s ease-in-out infinite}
.wx-sun::before{content:"";position:absolute;inset:-16px;border-radius:50%;
  background:conic-gradient(from 0deg,rgba(255,214,102,0) 0 8deg,rgba(255,214,102,.5) 8deg 12deg,rgba(255,214,102,0) 12deg 30deg);animation:wxspin 22s linear infinite}
@keyframes wxspin{to{transform:rotate(360deg)}}
@keyframes wxglow{0%,100%{filter:brightness(1)}50%{filter:brightness(1.12)}}
.wx-moon{position:absolute;top:28px;right:34px;width:48px;height:48px;border-radius:50%;
  background:#EAE6F5;box-shadow:inset -14px -6px 0 0 #C9C2E6,0 0 26px 6px rgba(220,214,245,.5);animation:wxglow 6s ease-in-out infinite}
.wx-star{position:absolute;width:3px;height:3px;border-radius:50%;background:#fff;opacity:.85;animation:wxtwinkle 3s ease-in-out infinite}
@keyframes wxtwinkle{0%,100%{opacity:.25}50%{opacity:.95}}
.wx-cloud{position:absolute;background:rgba(255,255,255,.9);border-radius:40px;filter:blur(.3px);opacity:.92;width:74px;height:22px;animation:wxdrift 16s linear infinite}
.wx-cloud::before,.wx-cloud::after{content:"";position:absolute;background:inherit;border-radius:50%}
.wx-cloud::before{width:30px;height:30px;top:-13px;left:12px}
.wx-cloud::after{width:22px;height:22px;top:-9px;left:40px}
.wx-cloud.c1{top:42px;left:-80px;animation-duration:19s}
.wx-cloud.c2{top:78px;left:-120px;transform:scale(.7);opacity:.7;animation-duration:26s;animation-delay:-6s}
.wx[data-dn="notte"] .wx-cloud{background:rgba(200,196,224,.55)}
@keyframes wxdrift{from{transform:translateX(0)}to{transform:translateX(440px)}}
.wx-precip{position:absolute;inset:0;z-index:2}
.wx-precip i{position:absolute;top:-12px;width:2px;height:12px;background:linear-gradient(rgba(255,255,255,0),rgba(220,235,245,.85));border-radius:2px;animation:wxrain 1.1s linear infinite}
.wx-neve .wx-precip i{width:6px;height:6px;background:#fff;border-radius:50%;animation:wxsnow 3.4s linear infinite;opacity:.9}
@keyframes wxrain{to{transform:translateY(230px)}}
@keyframes wxsnow{to{transform:translateY(230px) translateX(14px)}}
.wx-gust{position:absolute;height:2px;background:linear-gradient(90deg,transparent,rgba(255,255,255,.7),transparent);border-radius:2px;animation:wxgust 3s ease-in-out infinite}
@keyframes wxgust{0%{transform:translateX(-120px) scaleX(.6);opacity:0}40%{opacity:.9}100%{transform:translateX(380px) scaleX(1.2);opacity:0}}
/* arco solare + sparkline (widget meteo cinematografico) */
.wx-arc{position:absolute;top:6px;left:0;width:100%;height:72px;z-index:1;overflow:visible}
.wx-arc-line{fill:none;stroke:rgba(255,255,255,.42);stroke-width:1.5;stroke-dasharray:2 5;stroke-linecap:round}
.wx-arc-horizon{stroke:rgba(255,255,255,.16);stroke-width:1}
.wx-arc-astro{filter:drop-shadow(0 0 7px rgba(255,255,255,.85))}
.wx-arc-astro.sun{fill:#FFD45A;animation:wxglow 4s ease-in-out infinite}
.wx-arc-astro.moon{fill:#EAE6F5}
.wx-place{font:600 11px var(--ff-sans);opacity:.93;display:flex;align-items:center;gap:4px;margin-bottom:3px;text-shadow:0 1px 3px rgba(0,0,0,.35)}
.wx-place .ic{opacity:.9}
.wx-spark{display:block;width:100%;height:24px;margin:7px 0 3px;overflow:visible}
.wx-spark polyline{fill:none;stroke:rgba(255,255,255,.9);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;filter:drop-shadow(0 1px 2px rgba(0,0,0,.35));stroke-dasharray:520;stroke-dashoffset:520;animation:wxdraw 1.5s ease-out forwards}
@keyframes wxdraw{to{stroke-dashoffset:0}}

/* ===========================================================================
   TIMELINE — flusso temporale della giornata (slide "Flusso Temporale Scene")
   =========================================================================== */
.timeline{display:flex;gap:0;padding:14px 6px 6px;overflow-x:auto}
.tl-step{flex:1 0 0;min-width:128px;display:flex;flex-direction:column;align-items:center;text-align:center;gap:9px;position:relative;padding:0 6px}
/* connettore DENTRO lo step (left:0;width:100% → da bordo a bordo, gap:0 = linea continua):
   non sborda più del box (era left:50%;width:100% → +79px a tablet). Primo/ultimo si fermano al dot. */
.tl-step::before{content:"";position:absolute;top:39px;left:0;width:100%;height:2px;background:var(--border);z-index:0}
.tl-step:first-child::before{left:50%;width:50%}
.tl-step:last-child::before{width:50%}
.tl-chip{font:700 11.5px 'JetBrains Mono';color:var(--accent-deep);background:var(--accent-soft);border-radius:var(--r-pill);padding:4px 12px;z-index:1}
.tl-step.now .tl-chip{background:var(--surface);border:1.5px solid var(--accent);color:var(--accent-deep)}
.tl-dot{width:16px;height:16px;border-radius:50%;background:var(--accent);box-shadow:0 0 0 4px var(--surface),0 0 0 5px var(--border);z-index:1}
.tl-step.now .tl-dot{box-shadow:0 0 0 4px var(--surface),0 0 0 5px var(--accent),0 0 14px rgba(91,107,239,.5)}
.tl-step.done .tl-dot{background:var(--c-ok)}
.tl-title{font-weight:700;font-size:13.5px;color:var(--t1)}
.tl-sub{color:var(--t3);font-size:11.5px}

/* ===========================================================================
   SCENE DEL GIORNO
   =========================================================================== */
/* Scene del giorno = righe compatte cliccabili (render HOME box 4) */
/* C3 (04/07 sera): ripristinato blocco singolo cliccabile (pre-C1a) — le barre continuity
   (.cont-bar/.cont-bar.in) sono state tolte da qui, vivono ora nel modale scena. Il blocco
   base .cont-bar poco sotto RESTA (riusato dai due tasti nel modale). */
.sc-row{display:flex;align-items:center;gap:8px;padding:9px 11px;border-radius:var(--r-row);background:var(--s3);border:1px solid var(--border-soft);margin-bottom:6px;cursor:pointer;transition:background .12s,border-color .12s}
.sc-row:last-child{margin-bottom:0}
.sc-row:hover{background:var(--s2);border-color:var(--border2)}
.sc-row .sc-nm{flex:1;min-width:0;font:700 12.5px system-ui;color:var(--t1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sc-row .sc-warn{flex:none;font-size:12px;color:var(--terra);cursor:help}
.sc-row .sc-pill{flex:none;display:inline-flex;align-items:center;height:22px;border-radius:11px;background:var(--s4);border:1px solid var(--border2);padding:0 11px;font:600 11px system-ui;color:var(--t2);white-space:nowrap}
.sc-row .sc-chev{flex:none;color:var(--t3);font:700 14px system-ui;margin-left:2px}
/* CONTINUITY (C1a) — barra "▸ Registra continuity" del toast scena, condivisa da .sc-row (odg.js)
   e .h4-row (home4.js, cruscotto 4.0): grid-column:1/-1 ha effetto SOLO dentro la grid di .h4-row,
   no-op (innocuo) dentro .sc-row che è flex — un solo componente, due contesti [[pattern--flowset]]. */
.cont-bar{grid-column:1/-1;width:100%;display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:44px;padding:0 14px;margin:0;border-radius:var(--r-sm,10px);background:var(--s4);border:1px solid var(--border2);cursor:pointer;font:inherit;text-align:left;transition:background .12s,border-color .12s}
.cont-bar:hover{background:var(--s2);border-color:var(--accent-bord)}
.cont-bar .cont-bar-lbl{font:700 12.5px system-ui;color:var(--t1)}
/* Z4 (28/07/2026): l'etichetta CORTA («◂ Ingresso» / «▸ Registra») esce dal markup sempre, ma è
   spenta ovunque tranne che nel piede della scheda scena su smartphone (fm-view.css). Qui — toast
   ODG e riga Home, dove la barra è larga tutta la riga — la lunga resta l'unica visibile. */
.cont-bar .cont-bar-lbl.s{display:none}
.cont-bar .cont-bar-st{font:600 11.5px system-ui;color:var(--t3);white-space:nowrap}
.cont-bar.done{background:var(--c-ok-bg);border-color:rgba(30,142,87,.32)}
.cont-bar.done .cont-bar-st{color:var(--c-ok);font-weight:700}
/* pannello registrazione (openContinuityPanel, sections.js) — full-screen sotto 560px */
.modal-back .modal.cont-modal{width:min(1080px,96vw);max-height:min(90vh,1300px)}
.modal.cont-modal .modal-body{flex:1 1 auto;min-height:0;overflow:auto}
@media(max-width:560px){.modal-back.cont-back{padding:0}.modal-back .modal.cont-modal{width:100%;max-width:100%;height:100dvh;max-height:100dvh;border-radius:0}}
/* C3 (04/07 sera): transizione DIREZIONALE dei due pannelli continuity — STESSO pattern
   dell'apertura base del modale (.modal-back .modal{transform:translateY(10px) scale(.99)} →
   .modal-back.show .modal{transform:none}, riga ~955), solo con una direzione invece del default.
   Tasto SOPRA (openContinuityReadPanel, "in ingresso") → enter-top, scende dall'alto.
   Tasto SOTTO (openContinuityPanel, "registra") → enter-bottom, sale dal basso.
   VINCOLO DI SICUREZZA (trappola storica, vedi RIPRENDI_DA_QUI.md): il transform sta SOLO su
   .cont-modal stesso (stessa foglia della regola base .modal-back .modal), MAI su un antenato
   (.modal-back/.fm-back2/.main) — nessun containing-block nuovo, il Carousel .pcar-back resta
   appeso a document.body e position:fixed intatto anche con un pannello continuity aperto. */
.modal-back .modal.cont-modal.enter-top{transform:translateY(-40px)}
.modal-back .modal.cont-modal.enter-bottom{transform:translateY(40px)}
.modal-back.show .modal.cont-modal.enter-top,
.modal-back.show .modal.cont-modal.enter-bottom{transform:none}
.cont-pers{border:1px solid var(--border-soft);border-radius:var(--r-lg);background:var(--s3);padding:14px 16px;margin-bottom:14px}
.cont-pers:last-of-type{margin-bottom:0}
.cont-pers.cont-setbox{background:var(--s2)}
.cont-pers-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:10px}
.cont-pers-head b{font-size:14.5px;color:var(--t1)}
.cont-strip{margin-bottom:10px}
.cont-strip:empty{display:none}
.cont-pick{margin-bottom:12px}
.cont-generalnote{margin-top:4px}
.cont-generalnote label{display:block;font:700 11px system-ui;text-transform:uppercase;letter-spacing:.05em;color:var(--t3);margin-bottom:6px}
/* C2 (04/07, BLUEPRINT_C2_CONTINUITY_UX.md): textarea esaustive — SOLO dentro .cont-pers/
   .cont-generalnote (rastrello-safe, NON tocca .input globale condiviso da tutte le form del
   sito). Specificità (0,2,1) > la regola font-size:13px desktop di style.css:~1232 (0,1,1). */
.cont-pers textarea.input{min-height:120px;font-size:14px;line-height:1.4}
.cont-generalnote textarea.input{min-height:84px;font-size:14px;line-height:1.4}
/* CONTINUITY (C1b) — barra "◂ Continuity in ingresso" = RIUSO di .cont-bar con modifier .in
   (scelta documentata: un solo componente, un solo contesto ORA — i due tasti fissi in cima/in
   fondo alla colonna .fm-info del modale scena, CONTINUITY_TASTI_DESTRA 04/07 — la variante
   lettura si distingue per l'etichetta accentata, il resto è identico). Niente transform. */
.cont-bar.in .cont-bar-lbl{color:var(--accent)}
.cont-bar.in.done .cont-bar-lbl{color:var(--c-ok)}
/* C3: .sc-row .cont-bar.in + .sc-body e .cont-dvsec (dvSec "Continuity" in colonna info) rimossi —
   dead CSS dopo lo spostamento dei due tasti nel modale scena, vedi BLUEPRINT_C3_CONTINUITY_NAV.md */
/* pannello LETTURA: foto GRANDI della sorgente (tap → scheda foto), taglia ~2x del thumb .dv-foto-i */
.cont-strip-lg{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:10px}
.cont-thumb-lg{position:relative;width:104px;height:130px;border-radius:12px;overflow:hidden;border:1px solid var(--border);background:var(--s3);cursor:pointer;padding:0;transition:border-color .12s,box-shadow .12s}
.cont-thumb-lg:hover{border-color:var(--accent-bord);box-shadow:0 7px 16px -7px rgba(91,107,239,.5)}
.cont-thumb-lg img{width:100%;height:100%;object-fit:cover;display:block}
/* chips/note della SORGENTE rese leggibili (readonly, non toggle) */
.cont-srcnote{margin:0 0 10px;font:500 14px system-ui;line-height:1.5;color:var(--t2);white-space:pre-wrap}
/* NFMT (F2, 18/07/2026) — componente RIUSABILE "nota formattata" (classi/token GENERICI, NON .cont-*):
   toolbar 4 tastini nel form + render checkbox/bullet/numerata/libera in ispezione. Retrocompat:
   .nfmt-p = equivalente esatto di .cont-srcnote (pre-wrap). SOLO --token esistenti. R7: tap ≥44px. */
.nfmt{font:500 14px system-ui;line-height:1.5;color:var(--t2)}
.nfmt-toolbar{display:flex;gap:8px;margin-bottom:8px}
.nfmt-mk.icon-btn{width:44px;height:44px;font:600 15px system-ui;flex-shrink:0}
.nfmt-p{white-space:pre-wrap;margin:0 0 10px}
.nfmt-p:last-child{margin-bottom:0}
.nfmt-lead{font:700 11px system-ui;text-transform:uppercase;letter-spacing:.05em;color:var(--t3);margin:0 0 6px}
.nfmt-bul{position:relative;padding-left:18px;margin:0 0 5px}
.nfmt-bul::before{content:"•";position:absolute;left:4px;color:var(--t3)}
.nfmt-num{display:flex;gap:8px;margin:0 0 5px}
.nfmt-num-n{color:var(--t3);flex-shrink:0;font-variant-numeric:tabular-nums}
.nfmt-ck{display:flex;align-items:flex-start;gap:10px;min-height:32px;cursor:pointer;user-select:none;margin:0 0 5px;position:relative}
.nfmt-ck-in{position:absolute;opacity:0;width:0;height:0}
/* ═══ CHECKBOX CANONICA · pallino tondo + spunta che si «disegna» (Emanuele 18/07/2026) ═══
   Token grafico UNICO del sito: FORMA (pallino) + ANIMAZIONE (spunta stroke-draw sulla lucide
   "check") prese dal Sigillo dei sample segnalibro, MA senza la ghiera di vetro (a fianco a una
   nota stonerebbe). Forma/animazione = canoniche; COLORE = semantico via --ck-c (--c-ok "fatto",
   --accent "selezione": convenzione X3 :1580). La spunta si disegna SOLO al click (transition su
   :checked), non al load. Futuro: usa .fs-ck-box o aggiungi il selettore al gruppo → 1 solo posto
   da toccare. Markup via helper fsCk() (sections.js): svg a DOPPIO path — .ck-ghost = hint statico
   semitrasparente visibile in idle, .ck-real = spunta vera che si disegna sopra su :checked. */
.fs-ck-box,.nfmt-ck-box,.cont-prep-box,.toggle-box{
  --ck-c:var(--c-ok);border-radius:50%;border:1.5px solid var(--border);background:var(--surface);
  display:grid;place-items:center;color:transparent;flex-shrink:0;
  transition:background var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out),color var(--dur-fast) var(--ease-out)}
.fs-ck-box svg .ck-real,.nfmt-ck-box svg .ck-real,.cont-prep-box svg .ck-real,.toggle-box svg .ck-real{
  stroke-dasharray:24;stroke-dashoffset:24;transition:stroke-dashoffset var(--dur-base) var(--ease-out) .05s}
.fs-ck-box svg .ck-ghost,.nfmt-ck-box svg .ck-ghost,.cont-prep-box svg .ck-ghost,.toggle-box svg .ck-ghost{
  stroke:var(--t3);opacity:.45;stroke-dasharray:24;stroke-dashoffset:0}
.fs-ck-in:checked + .fs-ck-box,.nfmt-ck-in:checked + .nfmt-ck-box,.cont-prep-ck:checked + .cont-prep-box,.toggle-ck:checked + .toggle-box{
  background:var(--ck-c);border-color:var(--ck-c);color:#fff}
.fs-ck-in:checked + .fs-ck-box svg .ck-real,.nfmt-ck-in:checked + .nfmt-ck-box svg .ck-real,.cont-prep-ck:checked + .cont-prep-box svg .ck-real,.toggle-ck:checked + .toggle-box svg .ck-real{stroke-dashoffset:0}
.fs-ck-in:focus-visible + .fs-ck-box,.nfmt-ck-in:focus-visible + .nfmt-ck-box,.cont-prep-ck:focus-visible + .cont-prep-box,.toggle-ck:focus-visible + .toggle-box{box-shadow:0 0 0 3px var(--accent-mute)}
@media (prefers-reduced-motion:reduce){.fs-ck-box svg path,.nfmt-ck-box svg path,.cont-prep-box svg path,.toggle-box svg path{transition:none}}
.nfmt-ck-box{width:24px;height:24px}
.nfmt-ck-tx{padding-top:3px}
.nfmt-ck.done .nfmt-ck-tx{text-decoration:line-through;color:var(--t3)}
/* EDITOR NFMT (F2-bis, 18/07): box nota del FORM = contenteditable WYSIWYG (checkbox/puntini VERI mentre
   scrivi; il DB resta TESTO via nfmtSerialize). Enter continua la lista. SOLO --token esistenti. R7 tap ≥44px. */
.nfmt-edit{min-height:110px;max-height:300px;overflow-y:auto;padding:10px 12px;line-height:1.6;position:relative;cursor:text;counter-reset:nfmtn}
.nfmt-edit:focus{outline:none;border-color:var(--accent,var(--border2))}
.nfmt-edit.is-empty::before{content:attr(data-ph);position:absolute;left:12px;top:10px;color:var(--t3);pointer-events:none;font:500 14px system-ui;opacity:.75}
.nfmt-edit .nfmt-ln{margin:0 0 3px}
.nfmt-edit .nfmt-ln[data-t="ck"],.nfmt-edit .nfmt-ln[data-t="bul"],.nfmt-edit .nfmt-ln[data-t="num"]{display:flex;align-items:flex-start;gap:8px;min-height:26px}
.nfmt-edit .nfmt-tx{flex:1;min-width:0;outline:none;padding-top:1px;white-space:pre-wrap;word-break:break-word}
.nfmt-eck{width:22px;height:22px;border-radius:50%;border:1.6px solid var(--border);background:var(--surface);flex-shrink:0;cursor:default;display:grid;place-items:center;margin-top:1px;position:relative;transition:background var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out)}   /* pallino tondo = token checkbox canonico (:752); FORM: solo resa, la spunta "fatto" vive in ispezione (nfmtFlip) */
.nfmt-eck::before{content:"";grid-area:1/1;width:5px;height:10px;border:solid var(--t3);border-width:0 2.4px 2.4px 0;transform:rotate(45deg);margin-top:-2px;opacity:.45}   /* ghost-spunta: hint "è una checkbox" */
.nfmt-ln.on .nfmt-eck::before{opacity:0}
.nfmt-ln.on .nfmt-eck{background:var(--c-ok);border-color:var(--c-ok)}
.nfmt-ln.on .nfmt-eck::after{content:"";grid-area:1/1;width:5px;height:10px;border:solid #fff;border-width:0 2.4px 2.4px 0;transform:rotate(45deg);margin-top:-2px}
.nfmt-ln.on .nfmt-tx{text-decoration:line-through;color:var(--t3)}
.nfmt-b{color:var(--t3);flex-shrink:0;font:600 14px system-ui;min-width:18px;text-align:right;padding-top:1px;user-select:none}
.nfmt-n::before{counter-increment:nfmtn;content:counter(nfmtn) "."}
.cont-empty{margin:0 0 10px;font:500 12.5px system-ui;color:var(--t3)}
.cont-srclink{margin-left:auto}   /* link "da Sc. M" a destra dell'header personaggio */
.cont-src-tag{font:600 11.5px system-ui;color:var(--t3)}
/* checkbox "Preparato ✓" — target touch ≥44px, scrive cont.pers[nome].prep della scena CORRENTE */
.cont-prep{display:inline-flex;align-items:center;gap:10px;min-height:44px;cursor:pointer;user-select:none;position:relative}
.cont-prep-ck{position:absolute;opacity:0;width:0;height:0}
.cont-prep-box{width:26px;height:26px}   /* forma/colore/spunta-draw = CHECKBOX CANONICA (:752) */
.cont-prep-txt{font:700 13px system-ui;color:var(--t1)}
/* contatore vivo "Preparati N/M" in testa al pannello lettura */
.cont-prep-count{display:inline-flex;align-items:center;gap:6px;padding:6px 14px;border-radius:var(--r-pill,999px);background:var(--s3);border:1px solid var(--border2);font:600 12.5px system-ui;color:var(--t2);margin-bottom:14px}
.cont-prep-count b{color:var(--c-ok)}
/* ── LOTTO FORM CONTINUITY (18/07/2026, sample v2 approvato — _render/cont_form_ispezione.html):
   scheda persona a 2 ZONE — media (300px: carosello variant lead+strip) | dati (note nfmt a
   tutta altezza). Vale per FORM e ISPEZIONE (.cont-read). Collassa a 1 colonna ≤720px. ── */
.cont-2col{display:grid;grid-template-columns:300px minmax(0,1fr);gap:12px 20px;align-items:start}
.cont-2col .cont-pers-head{grid-column:1/-1;margin-bottom:2px}
.cont-media{display:flex;flex-direction:column;gap:9px;min-width:0}
.cont-mediabox{display:flex;flex-direction:column;gap:9px;min-width:0}   /* wrapper re-renderizzabile (upload foto) dentro .cont-media, stesso ritmo verticale */
.cont-2col .cont-data{display:flex;flex-direction:column;align-self:stretch;min-width:0}
.cont-2col .cont-data .nfmt-edit{flex:1;min-height:190px;max-height:none}   /* niente chips → il box note riempie l'altezza della colonna foto */
.cont-2col .cont-pick{margin-bottom:0}
/* carosello nella zona media: SOLI override scoped (carousel.js INTATTO) — lead 4/5 a tutta
   colonna, thumb quadrate 68px (tap ≥44px, R7) */
.cont-media .pcar-lead-img{aspect-ratio:4/5}
.cont-media .pcar-strip{gap:7px}
.cont-media .pcar-thumb{width:68px;height:68px;border-radius:var(--r-sm)}
/* placeholder statico a 0 foto (non cliccabile: l'azione utile è «Scatta / carica» lì sotto) */
.cont-lead-ph{width:100%;aspect-ratio:4/5;border-radius:var(--r);border:1px solid var(--border);background:var(--s2);display:grid;place-items:center;color:var(--t3)}
/* badge ruolo vista in testata modale (via opts.headActions): gemello parametrico di .fm-ro-tag */
.cont-mode-tag{--tag-c:var(--accent);--tag-bg:var(--accent-soft);display:inline-flex;align-items:center;gap:7px;font:600 12px system-ui;color:var(--tag-c);background:var(--tag-bg);padding:6px 12px;border-radius:var(--r-sm);white-space:nowrap}
.cont-mode-tag.insp{--tag-c:var(--c-info);--tag-bg:var(--c-info-bg)}
@media(max-width:720px){.cont-2col{grid-template-columns:minmax(0,1fr)}.cont-media .pcar-lead-img,.cont-lead-ph{aspect-ratio:16/10}}
/* placeholder per foto remote rotte/offline (vedi window.imgFallback) */
.img-fbk{display:inline-flex;align-items:center;justify-content:center;width:100%;height:100%;background:var(--s3);color:var(--t3)}
.castdot{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:8px;background:var(--ink);color:#fff;font:700 10px 'JetBrains Mono';margin-left:-4px;border:2px solid var(--surface)}
.wxcover{display:flex;gap:10px;align-items:center;background:var(--c-info-bg);border:1px dashed rgba(42,125,176,.4);border-radius:12px;padding:12px 14px;margin:12px 4px 4px;font-size:12.5px;color:var(--c-info)}
.wxcover.calm{opacity:.62;background:var(--s2);border-color:var(--border);color:var(--t3)}
.wxcover .ic{flex-shrink:0}

/* ===========================================================================
   CONVOCATI — card per macro-categoria
   =========================================================================== */
.conv-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(208px,1fr));gap:14px;align-items:start}
.conv-card{border:1px solid var(--border);border-radius:var(--r);background:var(--surface);overflow:visible;box-shadow:var(--sh-1);transition:transform .16s,box-shadow .16s;cursor:pointer}
.conv-card:hover{transform:translateY(-2px);box-shadow:var(--sh-2)}
.conv-card .cc-top{height:4px;background:var(--tone);border-radius:var(--r) var(--r) 0 0}
.conv-card .cc-head{display:flex;align-items:center;gap:11px;padding:14px 15px}
.conv-card .cc-ico{width:34px;height:34px;border-radius:11px;display:grid;place-items:center;background:var(--tone-bg);color:var(--tone)}
.conv-card .cc-name{font-weight:700;font-size:13px;flex:1;letter-spacing:-.2px}
.conv-card .cc-count{font:700 11px 'JetBrains Mono';color:#fff;background:var(--tone);border-radius:var(--r-pill);padding:3px 9px}
/* G5-A (Andrea voce 4, 04/07): SOLO il numero "Comparse" ingrandito (+36%, 11px→15px) — .cc-count è
   condivisa con Cast e ogni reparto troupe, quindi selettore SCOPED su data-cat="comparse" (rastrello
   verificato: .conv-card[data-cat="cast"]/[data-cat="<reparto>"] restano al font-size di riga sopra). */
.conv-card[data-cat="comparse"] .cc-count{font:800 15px 'JetBrains Mono';padding:4px 11px}
.conv-card .cc-chev{color:var(--t3);transition:transform .26s}
.conv-card.open .cc-chev{transform:rotate(180deg)}
.conv-card .cc-list{padding:0 15px;display:flex;flex-direction:column;gap:0;max-height:0;overflow:hidden;transition:max-height .3s ease}
.conv-card.open .cc-list{max-height:560px;padding-bottom:13px}
.conv-card .cc-row{display:flex;justify-content:space-between;gap:8px;font-size:12px;padding:8px 0;border-top:1px solid var(--s3)}
.conv-card .cc-row .who b{font-weight:700}
.conv-card .cc-row .who small{color:var(--t3);display:block;font-size:10.5px;margin-top:1px}
.conv-card .cc-row .ct{font:700 11px 'JetBrains Mono';color:var(--t2);white-space:nowrap}

/* ===========================================================================
   ⭐ PRESENZE DEL GIORNO — blocco unico a 3 colonne dense (render v0.3)
   troupe(per reparto, comprimibile) · cast del giorno · crowd/comparse
   =========================================================================== */
.pg-panel{border:1.5px solid var(--accent);box-shadow:0 0 0 4px var(--accent-mute),var(--sh-2)}
.pg-grid{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr) minmax(0,1fr);gap:20px;align-items:start}
.pg-col{min-width:0}
.pg-chead{display:flex;align-items:center;gap:7px;font-weight:800;font-size:13px;color:var(--t1);
  padding-bottom:8px;border-bottom:2px solid var(--border-soft);margin-bottom:11px}
.pg-cnt{margin-left:auto;font:700 11px 'JetBrains Mono';color:#fff;background:var(--t3);border-radius:var(--r-pill);padding:2px 9px}
/* G5-A (Andrea voce 4, 04/07): SOLO il numero "Crowd / Comparse" ingrandito (+36%, 11px→15px) —
   .pg-cnt è condivisa con "Cast del giorno" nello stesso pannello (odg.js castCrowdPanel), quindi
   classe dedicata .pg-cnt-comparse (rastrello verificato: Cast del giorno resta all'11px di sopra).
   Questo è il conteggio REALMENTE a schermo (home4.js richiama ODG.castCrowdPanel), a differenza di
   .conv-card[data-cat="comparse"] .cc-count qui sotto (soddisfa solo la lettera del blueprint: quel
   markup — convCards() — è verificato codice morto, mai nel DOM). */
.pg-cnt.pg-cnt-comparse{font-size:15px;padding:3px 11px}
.pg-repwrap{margin-bottom:6px}
.pg-rep{display:flex;align-items:center;gap:9px;padding:9px 11px;border-radius:var(--r-row);background:var(--s3);
  border:1px solid var(--border-soft);cursor:pointer;transition:background .12s,border-color .12s}
.pg-rep:hover{background:var(--s2);border-color:var(--border2)}
.pg-dot{width:9px;height:9px;border-radius:50%;background:var(--tone,#b9c0cc);flex:none}
.pg-rep .pg-nm{font-weight:700;font-size:12.5px;flex:1;color:var(--t1)}
.pg-pill{font:700 11px 'JetBrains Mono';color:var(--t2);background:var(--surface);border:1px solid var(--border);border-radius:var(--r-pill);padding:1px 9px}
.pg-chev{color:var(--t3);display:grid;place-items:center;transition:transform .26s var(--ease-out)}
.pg-repwrap.open .pg-chev{transform:rotate(180deg)}
.pg-replist{max-height:0;overflow:hidden;transition:max-height .3s var(--ease-out)}
.pg-repwrap.open .pg-replist{max-height:480px}
.pg-sub{display:flex;justify-content:space-between;gap:8px;align-items:center;font-size:11.5px;padding:6px 11px;border-bottom:1px solid var(--border-soft)}
.pg-sub b{font-weight:700;color:var(--t1)}
.pg-sub small{color:var(--t3)}
.pg-sub .ct{font:700 10.5px 'JetBrains Mono';color:var(--t2);white-space:nowrap}
.pg-person{display:flex;justify-content:space-between;align-items:center;gap:8px;padding:8px 10px;
  border-radius:var(--r-row);background:var(--s2);border:1px solid var(--border-soft);margin-bottom:6px}
.pg-pnm{font-weight:700;font-size:12px;color:var(--t1);min-width:0}
.pg-pnm small{display:block;font-weight:500;font-size:10.5px;color:var(--t3);margin-top:1px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pg-tag{font:700 11px 'JetBrains Mono';color:var(--accent-deep);white-space:nowrap;flex:none}
.pg-empty{font-size:12px;padding:8px 10px}
@media(max-width:720px){.pg-grid{grid-template-columns:minmax(0,1fr);gap:22px}}
/* Blocco 2 — Cast&Crowd: il CAST scorre su 2 colonne interne (multicol) + Comparse in colonna a parte
   (feedback Emanuele 30/06: liste lunghe troppo alte → 2 col cast + 1 comparse per accorciare la pagina).
   Troupe macro-categorie su 2 col (auto-fit). */
.pg-grid.pg-grid-cc{grid-template-columns:minmax(0,2fr) minmax(0,1fr)}
.pg-cast-cols{column-count:2;column-gap:12px}
.pg-cast-cols>.pg-person{break-inside:avoid;-webkit-column-break-inside:avoid}
@media(max-width:720px){.pg-grid.pg-grid-cc{grid-template-columns:minmax(0,1fr)}.pg-cast-cols{column-count:1}}
.pg-troupe-cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,240px),1fr));gap:6px 18px;align-items:start}
.pg-troupe-cols .pg-repwrap{min-width:0}
/* riga RICHIAMI cast sotto il nome (pescati dall'ODG, ordinati per orario, etichetta in chiaro) */
.pg-person.pg-cast{flex-direction:column;align-items:stretch;gap:7px}
.pg-prow{display:flex;justify-content:space-between;align-items:center;gap:8px;min-width:0}
.pg-tag.pg-hard{color:var(--c-crit);background:var(--c-crit-bg);border-radius:var(--r-pill);padding:1px 9px;font-size:10.5px}
.pg-calls{display:flex;flex-wrap:wrap;gap:6px}
.pg-call{display:inline-flex;flex-direction:column;align-items:center;gap:2px;min-width:62px;background:var(--accent-soft);border:1px solid var(--accent-bord);border-radius:var(--r-sm);padding:5px 11px}
.pg-call i{font-style:normal;font-weight:600;font-size:11px;color:var(--t2);white-space:nowrap;line-height:1}
.pg-call b{font:800 14px 'JetBrains Mono';color:var(--accent-deep);line-height:1.05;letter-spacing:.01em}
.pg-call.is-set{background:var(--accent);border-color:var(--accent)}
.pg-call.is-set i{color:rgba(255,255,255,.82)}
.pg-call.is-set b{color:#fff}

/* ===========================================================================
   HOVER GALLERY OUTFIT (daisyUI-style: scrub orizzontale tra le foto)
   Sostituisce la vecchia gallery 3D (niente più stacking 3D rotto).
   =========================================================================== */
.gal-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(212px,1fr));gap:20px}
.hg{position:relative;aspect-ratio:4/5;border-radius:var(--r);overflow:hidden;border:1px solid var(--border);
  box-shadow:var(--sh-1);cursor:ew-resize;background:var(--s3);transition:box-shadow .2s,transform .2s}
.hg:hover{box-shadow:var(--sh-2);transform:translateY(-2px)}
.hg-imgs{position:absolute;inset:0}
.hg-img{position:absolute;inset:0;opacity:0;transition:opacity .32s ease;display:flex;align-items:flex-end;padding:14px;background-size:cover;background-position:center}
.hg-img::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,transparent 62%,rgba(0,0,0,.55));pointer-events:none}
.hg-img .grain{position:absolute;inset:0;background-image:radial-gradient(circle at 30% 22%,rgba(255,255,255,.22),transparent 42%);pointer-events:none}
.hg-img .lbl{position:relative;z-index:2;color:#fff;font-weight:600;font-size:12px;text-shadow:0 1px 3px rgba(0,0,0,.5)}
.hg .hg-img:first-child{opacity:1}
.hg[data-a] .hg-img{opacity:0}
.hg[data-a="0"] .hg-imgs .hg-img:nth-child(1){opacity:1}
.hg[data-a="1"] .hg-imgs .hg-img:nth-child(2){opacity:1}
.hg[data-a="2"] .hg-imgs .hg-img:nth-child(3){opacity:1}
.hg[data-a="3"] .hg-imgs .hg-img:nth-child(4){opacity:1}
.hg-dots{position:absolute;bottom:11px;left:12px;right:12px;display:flex;gap:5px;justify-content:center;z-index:3}
.hg-dot{height:3px;flex:0 1 28px;border-radius:2px;background:rgba(255,255,255,.45);transition:background .2s}
.hg .hg-dot:first-child{background:#fff}
.hg[data-a] .hg-dot{background:rgba(255,255,255,.45)}
.hg[data-a="0"] .hg-dot:nth-child(1),.hg[data-a="1"] .hg-dot:nth-child(2),.hg[data-a="2"] .hg-dot:nth-child(3),.hg[data-a="3"] .hg-dot:nth-child(4){background:#fff}
.hg-hint{position:absolute;top:10px;right:10px;z-index:3;color:#fff;opacity:.85;background:rgba(0,0,0,.22);border-radius:8px;padding:3px 5px;display:grid;place-items:center}
.gal-cap{display:flex;align-items:center;gap:11px;margin-top:12px}
.gal-cap .id{width:30px;height:30px;border-radius:9px;background:var(--ink);color:#fff;display:grid;place-items:center;font:700 11px 'JetBrains Mono';flex-shrink:0}
.gal-cap .nm{font-weight:700;font-size:14px;display:flex;align-items:center;gap:7px}
.gal-cap .ro{color:var(--t3);font-size:11.5px;margin-top:1px}
.gal-hard{margin-top:8px}

.legend{display:flex;flex-wrap:wrap;gap:9px}
.legend .lg{display:flex;align-items:center;gap:8px;font-size:11.5px;font-weight:500;color:var(--t2);background:var(--s2);border:1px solid var(--border);border-radius:var(--r-pill);padding:6px 13px}
.legend .sw{width:11px;height:11px;border-radius:4px}

/* ===========================================================================
   COMPILER (master)
   =========================================================================== */
.preset-row{display:flex;flex-wrap:wrap;gap:9px;margin-bottom:6px}
.preset{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--border);background:var(--surface);border-radius:var(--r-pill);padding:8px 14px;font-size:12.5px;font-weight:600;color:var(--t2);transition:all .15s}
.preset:hover{border-color:var(--border2);background:var(--s2)}
.preset .ic{color:var(--t3)}
.preset.on{background:var(--ink);color:#fff;border-color:var(--ink)} .preset.on .ic{color:#fff}
.preset.on.day{background:var(--c-day);border-color:var(--c-day);color:#3a2c00} .preset.on.day .ic{color:#3a2c00}
.preset.on.night{background:var(--c-night);border-color:var(--c-night)}
.preset.on.golden{background:var(--c-dawn);border-color:var(--c-dawn)}
.cmp-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px}
.cmp-full{grid-column:1/-1}
/* Picker scene cercabile (compiler) — feedback Andrea: cerca-e-aggiungi parlante */
.scene-add{margin-top:4px}
.scene-search-wrap{max-width:none!important;margin-bottom:10px;background:var(--surface)!important}
.scene-add-list{display:flex;flex-direction:column;gap:5px;max-height:240px;overflow-y:auto;overflow-x:hidden;padding:2px}
.scene-opt{display:flex;align-items:center;gap:8px;width:100%;min-width:0;text-align:left;background:var(--surface);border:1px solid var(--border);border-radius:10px;padding:8px 12px;font-size:12.5px;cursor:pointer;transition:border-color .12s,background .12s}
.scene-opt:hover{border-color:var(--accent-bord);background:var(--accent-mute)}
/* SIMMETRIA lista scene (compiler picker, feedback «simmetria!!!!»): numero + badge a larghezza FISSA
   → la sinossi parte sempre dalla stessa x, colonne incolonnate (prima «Sc.7» e «Sc.112» sfasavano tutto). */
.scene-opt .n{font:700 12px 'JetBrains Mono';color:var(--t1);flex:none;min-width:54px}
.scene-opt .ie{flex:none;min-width:62px;display:inline-flex;align-items:center;justify-content:center}
.scene-opt .dn{flex:none;min-width:26px;display:inline-flex;align-items:center;justify-content:center}
.scene-opt .so{color:var(--t3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}
.scene-opt .add-ico{margin-left:auto;color:var(--accent);flex-shrink:0;opacity:.45;transition:opacity .12s,transform .12s}
.scene-opt:hover .add-ico{opacity:1;transform:scale(1.15)}
.scene-add-empty{color:var(--t3);font-size:12.5px;padding:12px;text-align:center}
.pick{display:flex;flex-wrap:wrap;gap:8px}
.pick .opt{border:1px solid var(--border);border-radius:10px;padding:7px 12px;font-size:12.5px;font-weight:600;cursor:pointer;background:var(--surface);display:flex;gap:7px;align-items:center;transition:all .14s}
.pick .opt:hover{border-color:var(--border2);background:var(--s2)}
.pick .opt.on{background:var(--accent-soft);border-color:var(--accent-bord);color:var(--accent-deep)}
.pick .opt .x{opacity:.6;display:inline-flex}
.cmp-bar{position:sticky;bottom:14px;z-index:30;margin:18px 0 6px;padding:13px 86px 13px 18px;display:flex;gap:12px;justify-content:flex-end;flex-wrap:wrap;align-items:center;
  background:var(--glass-bg);backdrop-filter:blur(18px) saturate(180%);-webkit-backdrop-filter:blur(18px) saturate(180%);
  border:1px solid var(--border);border-radius:var(--r);box-shadow:var(--sh-2)}

/* ===========================================================================
   TOAST · MODAL · ANIMAZIONI
   =========================================================================== */
.toast-wrap{position:fixed;bottom:26px;left:50%;transform:translateX(-50%);z-index:60;display:flex;flex-direction:column;gap:9px;align-items:center}
.toast{background:var(--ink);color:#fff;border-radius:14px;padding:13px 18px;font-size:13px;font-weight:500;box-shadow:var(--sh-pop);display:flex;align-items:center;gap:10px;animation:toastIn .26s cubic-bezier(.2,.8,.2,1)}
.toast .tdot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
.toast.ok .tdot{background:#34D399}.toast.err .tdot{background:#FF6B5E}.toast.info .tdot{background:var(--accent)}
/* tasto "Annulla" dentro il toast (undo dopo eliminazione) */
.toast-undo{margin-left:6px;background:rgba(255,255,255,.16);color:#fff;border:0;border-radius:8px;padding:5px 12px;font-weight:700;font-size:12px;cursor:pointer;transition:background .12s}
.toast-undo:hover{background:rgba(255,255,255,.3)}
@keyframes toastIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}

.overlay{position:fixed;inset:0;background:rgba(17,24,39,.46);backdrop-filter:blur(4px);z-index:80;display:grid;place-items:center;animation:fade .22s;padding:18px;padding-left:max(18px,env(safe-area-inset-left));padding-right:max(18px,env(safe-area-inset-right))}
@keyframes fade{from{opacity:0}to{opacity:1}}
.modal{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--sh-pop);width:min(480px,100%);padding:26px;max-height:90vh;overflow:auto}
.modal h2{font-size:19px;margin-bottom:8px;letter-spacing:-.4px}
.modal p{color:var(--t2);font-size:13px;margin-bottom:18px}

@keyframes riseIn{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
.anim{opacity:0;animation:riseIn .46s cubic-bezier(.2,.8,.2,1) forwards;animation-delay:calc(var(--i,0)*55ms)}

/* ===========================================================================
   ANNOTATION LAYER (feedback beta)
   =========================================================================== */
.annot-host{position:relative !important}
/* F4 (04/07, BLUEPRINT_FIX_GROVIERA_2026-07-04.md): top era -9px → il badge (~19px
   di altezza reale) rientrava 10px dentro l'host, coprendo la prima riga di testo
   (nomi Inventario/Anagrafica, etichette campo nei modali). Ora il badge sta
   INTERAMENTE sopra il bordo superiore dell'host (zero overlap verticale, verificato
   sul DOM reale: gap minimo osservato 16px in .cmp-grid, sufficiente per i 19px del
   badge) — funziona sia per host larghi (label più corte della box) sia per host
   stretti (link/celle a larghezza-contenuto) dove spostare solo left/right non basta.
   width:max-content + white-space:nowrap eliminano il collasso "a capo carattere per
   carattere" su host stretti (shrink-to-fit era vincolato alla larghezza dell'host,
   che è il containing block dell'assoluto). */
.annot-tag{position:absolute;z-index:45;top:-20px;left:-9px;display:inline-flex;align-items:center;gap:3px;
  width:max-content;white-space:nowrap;
  background:var(--surface);border:1px solid var(--border2);border-radius:6px;padding:2px 4px 2px 5px;
  font:600 9.5px 'JetBrains Mono',monospace;color:var(--t3);box-shadow:var(--sh-1);user-select:none;line-height:1}
.annot-tag .n{pointer-events:none;white-space:nowrap}
.annot-tag input{appearance:none;-webkit-appearance:none;width:13px;height:13px;border:1.5px solid var(--border2);border-radius:4px;background:var(--surface);cursor:pointer;position:relative;margin:0;transition:all .12s}
.annot-tag input:hover{border-color:var(--accent)}
.annot-tag input:checked{background:var(--accent);border-color:var(--accent-deep)}
.annot-tag input:checked::after{content:"";position:absolute;left:3.5px;top:1px;width:3px;height:6px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg)}
.annot-tag.sel{border-color:var(--accent);color:var(--accent-deep);background:var(--accent-mute)}
/* sui .sect (titoletti note allineati a sinistra) sposto il tag a destra per non coprirli */
.sect.annot-host>.annot-tag{left:auto;right:-8px}
/* F4: host che clippano il proprio contenuto (overflow:hidden/auto — es. .ana-nm con
   ellissi sui nomi lunghi in Anagrafica): il badge non può sporgere fuori dal bordo
   (verrebbe tagliato via e reso non cliccabile, riprodotto dal vivo: elementFromPoint
   sulla checkbox restituiva il <td> sottostante). annotate.js (decorate) marca questi
   host con .annot-clip: gli apriamo uno spazio VERO dentro il bordo — padding-top
   compensato da un margin-top negativo di pari misura, quindi ZERO spostamento di
   riga/fratelli (verificato: bounding box della riga tabella invariata prima/dopo) —
   e il tag resta dentro il bordo, mai clippato. */
.annot-host.annot-clip{overflow:visible !important;padding-top:20px !important;margin-top:-20px !important}
.annot-host.annot-clip>.annot-tag{top:1px}
/* F4: qui a clippare è un ANTENATO stretto (card/thumbnail con overflow:hidden per
   gli angoli arrotondati — es. .wb-card, .cbx-pers), non l'host. Il trucco
   padding/margin sull'host lo spingerebbe fuori dal bordo di clip dell'antenato
   (badge invisibile, riprodotto dal vivo); applicarlo all'antenato invece genera
   uno spostamento di layout reale su griglie (verificato: +35px di altezza card,
   riga successiva -5px — la cancellazione non è pulita come su flex/tabella).
   Qui il badge resta DENTRO il bordo ORIGINALE dell'host, mai spostato: diventa un
   cerchietto compatto in alto a destra con la sola checkbox (il codice numerico
   resta comunque salvato/consultabile nel pannello ✎ — qui serve solo il controllo
   click/contatore, zero rischio layout sull'antenato). */
.annot-host.annot-clip-parent>.annot-tag{top:2px;left:auto;right:2px;padding:1px;width:16px;height:16px;justify-content:center;border-radius:50%}
.annot-host.annot-clip-parent>.annot-tag .n{display:none}
/* F4 TENTATIVO 2 (04/07, verify indipendente su T1 → FAIL: 116/131 badge sul
   testo in Inventario lista tablet/phone): il caso .annot-clip-parent sopra
   assume che l'host riempia quasi tutta la larghezza dell'antenato che clippa
   (vero per .wb-body/.fs-photo, ratio ~0.99 misurato dal vivo — lì il cerchietto
   d'angolo non tocca mai il testo, verificato, INVARIATO). Ma un host STRETTO
   di sola-andata (es. l'<a class="link"> nome-capo dentro .inv-name, o Scena/
   Attori: ratio host/antenato misurato dal vivo 0.02–0.69, mai oltre 0.7) è
   quasi tutto testo: il cerchietto d'angolo in top:2/right:2 cade SOPRA le
   ultime lettere (riprodotto dal vivo: "…(tg." perdeva ")"). annotate.js
   (isNarrowParentClip, soglia 0.85 verificata su Inventario/Scene/Attori vs
   WrapBox/Foto) distingue i due casi per MISURA reale, non per selettore, e
   marca questi host .annot-clip-inline: qui il badge non è più assoluto ma IN
   FLUSSO e inserito PRIMA del testo (insertBefore, non appendChild) — un
   cerchietto compatto (solo checkbox, niente codice) che spinge il testo di
   ~20px verso destra DENTRO l'host stesso. Zero spostamento verticale delle
   righe: l'host è un item flex a larghezza intrinseca dentro una riga la cui
   altezza è già dettata da un elemento più alto (thumbnail/riga), verificato
   dal vivo — bounding box della card invariata prima/dopo su Inventario. */
.annot-host.annot-clip-inline{overflow:visible !important}
/* niente "display" qui apposta: .annot-tag base (riga 908) è già inline-flex —
   ridichiararlo qui alzerebbe la specificità (3 classi) sopra body.annot-off
   .annot-tag (2 classi+elemento) e il toggle "numeri" non spegnerebbe più questi
   badge (bug rastrellato dal vivo nel primo giro di verifica di questo T2: 116
   badge clip-inline restavano visibili dopo lo spegnimento su tablet/phone). */
.annot-host.annot-clip-inline>.annot-tag{position:static;top:auto;left:auto;right:auto;
  vertical-align:middle;flex:none;width:16px;height:16px;padding:1px;
  margin:0 5px 0 0;justify-content:center;align-items:center;border-radius:50%}
.annot-host.annot-clip-inline>.annot-tag .n{display:none}
body.annot-off .annot-tag{display:none}

.annot-gtag{position:absolute;z-index:46;top:-11px;right:12px;display:inline-flex;align-items:center;gap:5px;max-width:62%;
  background:var(--accent-mute);border:1px solid var(--accent-bord);border-radius:7px;padding:2px 9px 2px 6px;
  font:600 10px 'JetBrains Mono',monospace;color:var(--accent-deep);box-shadow:var(--sh-1);user-select:none;line-height:1;white-space:nowrap;overflow:hidden}
.annot-gtag .gn{pointer-events:none;overflow:hidden;text-overflow:ellipsis}
.annot-gtag input{appearance:none;-webkit-appearance:none;width:13px;height:13px;border:1.5px solid var(--accent-bord);border-radius:4px;background:var(--surface);cursor:pointer;position:relative;margin:0;flex-shrink:0;transition:all .12s}
.annot-gtag input:hover{border-color:var(--accent)}
.annot-gtag input:checked{background:var(--accent);border-color:var(--accent-deep)}
.annot-gtag input:checked::after{content:"";position:absolute;left:3.5px;top:1px;width:3px;height:6px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg)}
.annot-gtag.sel{background:var(--accent);color:#fff;border-color:var(--accent-deep)}
.annot-gtag.sel input{border-color:#fff;background:#fff}
.annot-gtag.sel input:checked::after{border-color:var(--accent-deep)}
body.annot-off .annot-gtag{display:none}

/* ── Feedback bubble + pannello ── */
.fab{position:fixed;right:26px;bottom:26px;z-index:70;width:58px;height:58px;border-radius:50%;
  background:linear-gradient(135deg,#0A84FF 0%,#5B6BFF 60%,#8E73FF 100%);color:#fff;border:0;
  box-shadow:0 12px 30px rgba(0,90,220,.4);display:grid;place-items:center;transition:transform .18s}
.fab:hover{transform:scale(1.07)}
.fab .count{position:absolute;top:-4px;right:-4px;min-width:22px;height:22px;padding:0 5px;background:var(--ink);color:#fff;border-radius:11px;font:700 11px var(--ff-sans);display:grid;place-items:center;border:2px solid var(--bg)}
.panel-fb{position:fixed;right:26px;bottom:94px;z-index:70;width:min(412px,94vw);max-height:74vh;display:flex;flex-direction:column;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--sh-pop);overflow:hidden;animation:panelIn .22s cubic-bezier(.2,.8,.2,1)}
@keyframes panelIn{from{opacity:0;transform:translateY(14px) scale(.98)}to{opacity:1;transform:none}}
.panel-fb.hidden,.fab.hidden{display:none}

/* Voce 8 (05/07, BLUEPRINT_C5-SHELL.md): freccia "torna in alto" globale — fissa
   sopra al FAB feedback (.fab occupa right:26 bottom:26-84px; qui bottom:98-144px,
   zero overlap a riposo), z-index sotto al FAB (65 < 70, coerente con .nav-fly) così
   se il pannello feedback si apre resta sopra come overlay transitorio. */
.back-top{position:fixed;right:26px;bottom:98px;z-index:65;width:46px;height:46px;border-radius:50%;
  background:var(--surface);color:var(--t2);border:1px solid var(--border);box-shadow:var(--sh-1);
  display:grid;place-items:center;opacity:0;visibility:hidden;transform:translateY(8px);
  transition:opacity .2s,transform .2s,visibility .2s;cursor:pointer}
.back-top.show{opacity:1;visibility:visible;transform:none}
.back-top:hover{background:var(--s2);border-color:var(--border2)}
.fb-head{padding:15px 17px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:10px}
.fb-head .logo{width:22px;height:22px;border-radius:7px;background:linear-gradient(135deg,#0A84FF,#5B6BFF);color:#fff;display:grid;place-items:center}
.fb-head b{font-size:14.5px}.fb-head .who{margin-left:auto;font-size:11px;color:var(--t3)}
.tabs{display:flex;border-bottom:1px solid var(--border)}
.tab{flex:1;padding:11px;text-align:center;font-size:12px;font-weight:600;color:var(--t3);cursor:pointer;border-bottom:2px solid transparent}
.tab.active{color:var(--accent-deep);border-bottom-color:var(--accent)}
.fb-body{overflow-y:auto;padding:14px 16px;flex:1}
.sel-empty{color:var(--t3);font-size:12.5px;text-align:center;padding:30px 10px;line-height:1.7}
.sel-item{border:1px solid var(--border);border-radius:12px;padding:12px;margin-bottom:10px;background:var(--s2)}
.sel-item .top{display:flex;align-items:center;gap:8px;margin-bottom:9px}
.sel-item .num{font:600 10px 'JetBrains Mono',monospace;color:#fff;background:var(--accent);border-radius:6px;padding:2px 6px}
.sel-item .lab{font-size:12px;font-weight:600;flex:1;color:var(--t1)}
.sel-item .x{color:var(--c-crit);cursor:pointer;display:inline-flex}   /* Z1: toglie la selezione dal foglio feedback (annotate.js:236 `delete SEL[k]`) — elimina, quindi rossa */
.sel-item select{width:100%;margin-bottom:7px;font-size:11.5px;padding:7px 9px;border:1px solid var(--border);border-radius:9px;background:var(--surface);color:var(--t2)}
.sel-item textarea{width:100%;border:1px solid var(--border);border-radius:9px;padding:8px;font-family:inherit;font-size:12.5px;resize:vertical;min-height:50px;outline:none}
.sel-item textarea:focus{border-color:var(--accent-bord)}
.fb-foot{padding:13px 16px;border-top:1px solid var(--border);background:var(--s2);display:flex;gap:9px;align-items:center}
.feed-item{border-bottom:1px solid var(--s3);padding:11px 2px;font-size:12px}
.feed-item .meta{display:flex;gap:6px;align-items:center;margin-bottom:4px;color:var(--t3);font-size:10.5px;flex-wrap:wrap}
.feed-item .who-b{font-weight:700;color:var(--accent-deep)}
.feed-item .num{font:600 9.5px 'JetBrains Mono',monospace;background:var(--s3);border-radius:5px;padding:1px 5px;color:var(--t2)}
.feed-item .nota{color:var(--t1)}

/* ===========================================================================
   SEZIONI REALI (CRUD) — modali, stato vuoto, azioni riga, tab segmentate
   =========================================================================== */
.empty{display:flex;flex-direction:column;align-items:center;gap:12px;text-align:center;color:var(--t3);
  background:var(--surface);border:1px dashed var(--border2);border-radius:var(--r-lg);padding:48px 24px}
.empty .ic{color:var(--border2)} .empty p{font-size:13.5px;max-width:420px}
.row-act{display:inline-flex;gap:6px;justify-content:flex-end;align-items:center;width:100%}
/* Z1 (28/07/2026): la ✕ che ELIMINA è rossa PRIMA di toccarla, non solo sotto il dito. L'idioma
   `.danger` esisteva già ed era rosso a riposo dappertutto — .btn-ghost.danger (:1292),
   .mb-pop button.danger (:2611), .fm-act.gho.danger (fm-view.css:142), .btn-danger (:1289) —
   TRANNE qui: .icon-btn.danger si accendeva solo su :hover, e su un tablet il :hover non esiste
   proprio. Il rosso deve poter dire «questo cancella» a un dito che non ha ancora toccato.
   ⚠ Il confine (Z1): rosso = elimina un DATO. La ✕ che chiude un modale, svuota una ricerca o
   toglie un chip-filtro resta neutra: se il rosso fosse ovunque non direbbe più niente. */
.icon-btn.danger{color:var(--c-crit);border-color:rgba(209,75,61,.28)}
.icon-btn.danger:hover{border-color:rgba(209,75,61,.4);color:var(--c-crit);background:var(--c-crit-bg)}
a.icon-btn{text-decoration:none}
.seg{display:inline-flex;background:var(--s2);border:1px solid var(--border);border-radius:12px;padding:3px;gap:2px}
.seg-btn{border:0;background:transparent;color:var(--t3);font-size:12.5px;font-weight:600;padding:8px 15px;border-radius:9px;transition:all .14s}
.seg-btn.on{background:var(--surface);color:var(--t1);box-shadow:var(--sh-1)}
.req{color:var(--c-crit)}

/* ── Modale CRUD (backdrop .modal-back; riusa .modal con struttura head/body/foot) ── */
.modal-back{position:fixed;inset:0;background:rgba(17,24,39,.46);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);
  z-index:90;display:grid;place-items:center;padding:18px;padding-left:max(18px,env(safe-area-inset-left));padding-right:max(18px,env(safe-area-inset-right));opacity:0;transition:opacity .16s}
.modal-back.show{opacity:1}
.modal-back .modal{padding:0;width:min(1040px,96vw);max-height:90vh;display:flex;flex-direction:column;overflow:hidden;
  border:1.5px solid var(--accent);box-shadow:var(--glow),var(--sh-pop);
  transform:translateY(10px) scale(.99);transition:transform .18s cubic-bezier(.2,.8,.2,1)}
.modal-back.show .modal{transform:none}
.modal-head{display:flex;align-items:center;justify-content:space-between;padding:18px 22px;border-bottom:1px solid var(--border)}
.modal-head b{font-size:16px;font-weight:800;letter-spacing:-.3px}
.modal-body{padding:20px 22px;overflow:auto}
.modal-foot{display:flex;gap:10px;justify-content:flex-end;padding:14px 22px;border-top:1px solid var(--border);background:var(--s2)}
.modal-grid{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
/* B4 (05/07, BLUEPRINT_C3-FORMDATI.md): overlay di conferma "Scartare le modifiche?" — appeso a
   <body> (sections.js showDiscardConfirm), MAI passato per modal(): sta SOPRA il form ancora
   aperto senza distruggerlo. z-index 95 > .modal-back (90) così resta visibile sopra il toast. */
/* AE1-bis (31/07/2026): .fs-confirm-inline e le sue .fci-* sono state RIMOSSE — il dirty-guard
   che le usava è passato alla conferma unica `.ask-ovl` (askConfirm, sections.js). Erano nate il
   05/07 per lo stesso motivo (stare sopra un form senza distruggerlo) e facevano lo stesso
   mestiere con un altro vestito: due conferme diverse nello stesso sito sono il difetto che
   Emanuele ha chiesto di chiudere. Le regole di `.ask-*` stanno in fondo al file. */
.btn-danger{background:var(--c-crit);color:#fff;box-shadow:0 6px 16px rgba(209,75,61,.26)}
.btn-danger:hover{background:#B83B2E;transform:translateY(-1px)}
/* Elimina nelle schede: ghost ma ROSSO, così attira lo sguardo senza eliminazioni accidentali (feedback Andrea) */
.btn-ghost.danger{color:var(--c-crit);border-color:rgba(209,75,61,.38)}
.btn-ghost.danger:hover{background:var(--c-crit-bg);border-color:var(--c-crit);color:var(--c-crit)}
/* testata scheda: cluster azioni a destra = frecce cronologia ‹ › + chiusura X (navigazione tra schede) */
.mh-actions{display:flex;align-items:center;gap:6px;flex-shrink:0}
.mh-acts{display:flex;align-items:center;gap:8px}
.mh-sep{width:1px;height:20px;background:var(--border2);margin:0 2px}
.mh-navbtn[disabled]{opacity:.3;pointer-events:none}
.img-prev{margin-top:12px;display:flex;justify-content:center;min-height:0}
.img-prev img{max-height:200px;border-radius:12px;border:1px solid var(--border);max-width:100%;object-fit:cover}
.img-prev.big{min-height:150px;align-items:center}
.img-prev.big img{max-height:260px}

/* ── Sourcing Hub ── */
.sourcing{background:linear-gradient(135deg,var(--accent-mute),rgba(124,92,255,.08));border:1px solid var(--accent-bord);
  border-radius:var(--r);padding:14px 16px;margin-bottom:18px}
.sourcing.in-modal{margin-bottom:16px}
.src-row{display:flex;gap:9px;align-items:center}
.src-row .input{flex:1}
.src-hint{font-size:11.5px;color:var(--accent-deep);margin-top:8px;display:flex;align-items:center;gap:6px}
.src-hint .ic{flex-shrink:0}

/* ── Budget bar ── */
.budget{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);box-shadow:var(--sh-1);padding:16px 18px;margin-bottom:18px}
.bd-info{display:flex;gap:26px;align-items:center;flex-wrap:wrap;margin-bottom:11px}
.bd-info>div{display:flex;flex-direction:column;gap:1px}
.bd-k{font:700 9.5px var(--ff-sans);letter-spacing:.5px;text-transform:uppercase;color:var(--t3)}
.bd-v{font:700 17px 'JetBrains Mono';color:var(--t1)} .bd-v.over{color:var(--c-crit)}
.bd-track{height:9px;background:var(--s3);border-radius:6px;overflow:hidden}
.bd-fill{display:block;height:100%;background:var(--c-ok);border-radius:6px;transition:width .5s cubic-bezier(.2,.8,.2,1)}
.bd-fill.warn{background:var(--c-warn)} .bd-fill.over{background:var(--c-crit)}
.bd-pct{font-size:11.5px;color:var(--t3);margin-top:6px} .bd-pct.over{color:var(--c-crit);font-weight:600}

/* ── Inventario ── */
.inv-tools{display:flex;gap:10px;align-items:center;margin-bottom:14px}
.inv-tools .search{max-width:340px}
.inv-name{display:flex;align-items:center;gap:10px}
.inv-thumb{width:34px;height:42px;border-radius:8px;object-fit:cover;border:1px solid var(--border);flex-shrink:0}
.inv-thumb.ph{display:grid;place-items:center;background:var(--s3);color:var(--t3)}
/* Bug 2 — foto del personaggio in Anagrafica (DB foto condiviso): mini-strip carosello accanto al nome,
   o icona-immagine quando non ce ne sono. Stesso comportamento delle altre tab (hover→preview, click→fissa). */
/* media-object: avatar (1ª foto) a SINISTRA + nome/#id incolonnati → righe uniformi e allineate (simmetria, feedback Emanuele) */
.ana-name{display:flex;align-items:center;gap:11px;min-width:0;flex-wrap:nowrap}
.ana-meta{display:flex;flex-direction:column;gap:1px;min-width:0;line-height:1.25}
.ana-nm{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:230px}
.ana-id{font:600 11px 'JetBrains Mono';color:var(--t3);letter-spacing:.4px}
.ana-foto{flex:0 0 36px;width:36px;min-width:0;display:inline-flex;align-items:center;justify-content:center;overflow:visible}   /* min-width:0 annulla il min-content del flex item → larghezza FISSA = avatar: i nomi partono tutti dalla stessa x (visible: la miniatura che sale in hover non si taglia) */
.ana-foto .pcar-strip{flex-wrap:nowrap;gap:0}
.ana-foto .pcar-thumb{width:36px;height:44px;border-radius:8px;border:1px solid var(--border)}
.ana-foto .pcar-thumb:nth-child(n+2){display:none}   /* in tabella SOLO la prima foto (avatar); le altre restano nel carosello (hover→preview, click→fissa) */
.ana-foto .pcar-ph-btn{display:grid;place-items:center;color:var(--t3)}   /* placeholder «immagine assente»: riquadro 36×44 come la thumb (regola sopra), sola icona — niente conteggio «0» → la riga non si deforma e resta coerente con .fs-photo .ph */
tr:has(.ana-name) td{vertical-align:middle}   /* righe Personaggio allineate verticalmente alle colonne dati */

/* ── Foto: filtri + galleria reale ── */
/* M1e (03/07, punto 4): barra comandi (.gal-tools) + filtri rapidi (.foto-cats) della Galleria SEGUONO
   lo scroll — stesso paradigma di .odg-cmp-head (riga 414): SOLO position:sticky, MAI transform sugli
   antenati (trappola modali fixed, regola d'oro #3). Scope dedicato, .page-head globale invariato. */
.fs-gal-head{position:sticky;top:0;z-index:5;background:var(--bg);margin:0 -16px 12px;padding:16px 16px 4px;border-bottom:1px solid var(--border)}
.fs-gal-head .foto-cats{margin-bottom:10px}
@media(max-width:560px){.fs-gal-head{margin:0 -12px 12px;padding:14px 12px 4px}}
/* Bug 3 — barra MACRO-CATEGORIE foto: pochi bottoni (Personaggi/Scene/…) al posto del muro di chip.
   Click → le card della categoria volano in cima (FLIP) e restano col contorno basso celeste acceso. */
.foto-cats{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:16px}
.foto-cats .fc-lab{color:var(--t3);font-size:12px;font-weight:600;margin-right:2px}
.foto-cat{border:1px solid var(--border);background:var(--surface);color:var(--t2);font-size:12.5px;font-weight:600;padding:8px 14px;border-radius:10px;cursor:pointer;transition:all .14s;display:inline-flex;align-items:center;gap:6px}
.foto-cat:hover{border-color:var(--accent-bord);color:var(--accent-deep)}
.foto-cat.on{background:var(--accent);border-color:var(--accent-deep);color:#fff;box-shadow:var(--sh-1)}
.foto-cat .fc-n{font:700 11px 'JetBrains Mono';opacity:.7}
.foto-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(224px,1fr));gap:18px}   /* M1c: restyle StudioBinder (168→224, gap 16→18) approvato sul sample */
/* card foto = stile Uiverse (dull-moose-30) normalizzato ai token: HERO = la foto con badge tipo
   (research/continuity) alto-sx + bookmark alto-dx; FOOTER = caption + sottotitolo + bottone elimina. */
.foto-card{display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--border);border-radius:var(--r);overflow:hidden;box-shadow:var(--sh-1);transition:transform .16s,box-shadow .16s,border-color .16s}
.foto-card:hover{transform:translateY(-2px);box-shadow:var(--sh-2)}
/* contorno BASSO celeste acceso (resta finché non si cambia categoria) — come da Esempio.png */
.foto-card.cat-hit{border-color:var(--accent-bord);box-shadow:inset 0 -3px 0 0 var(--accent),0 8px 20px -9px rgba(91,107,239,.5)}
.foto-img{position:relative;aspect-ratio:3/4;background:var(--s3);display:grid;place-items:center;color:var(--t3);cursor:pointer}
.foto-img img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.foto-badge{position:absolute;top:8px;left:8px;z-index:2}
/* bookmark alto-dx (decorativo, eredita l'estetica Uiverse) su pastiglia leggibile su qualsiasi foto */
.foto-mark{position:absolute;top:8px;right:8px;z-index:2;display:grid;place-items:center;width:26px;height:26px;border-radius:50%;
  background:var(--accent-mute);color:var(--accent-deep);backdrop-filter:blur(2px);box-shadow:0 1px 3px rgba(0,0,0,.18)}
.foto-cap{display:flex;align-items:center;gap:8px;padding:10px 11px;background:var(--s2);border-top:1px solid var(--border);margin-top:auto}
.foto-cap-txt{flex:1;min-width:0}
.foto-cap b{display:block;font-size:13px;font-weight:700;color:var(--t1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.foto-cap small{display:block;color:var(--t3);font-size:10.5px;font-weight:400;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-top:1px}
.foto-cap .icon-btn{width:30px;height:30px;border-radius:var(--r-pill);flex-shrink:0}

/* ── AI Breakdown ── */
.bd-load{display:flex;align-items:center;gap:9px;color:var(--accent-deep);font-size:13px;padding:18px 4px;font-weight:600}
.bd-load.err{color:var(--c-crit)}
.bd-res{margin-top:12px;border-top:1px solid var(--border);padding-top:12px}
.bd-stat{font-size:12.5px;color:var(--t2);display:flex;align-items:center;gap:7px;font-weight:600}
.bd-stat .ic{color:var(--c-ok)}
.tag{display:inline-flex;align-items:center;gap:5px;border:1px solid var(--border);border-radius:8px;padding:3px 9px;font-size:11.5px;margin:2px;background:var(--s2)}

/* ── Stampe: griglia report ── */
.rep-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(290px,1fr));gap:16px}
.rep-card{display:flex;flex-direction:column;gap:9px}
.rep-top{display:flex;align-items:center;gap:11px}.rep-top b{font-size:14.5px}
.rep-desc{font-size:12.5px;min-height:36px;flex:1}

/* ── Cambi: righe a griglia con colonne fisse (chip di stato sempre allineati) ── */
.cambi-block{padding:0;overflow:hidden}
.cambi-head{padding:14px 18px;border-bottom:1px solid var(--border)}
.cambi-head h3{font-size:15px;font-weight:700}
/* macro-categorie anagrafica: header di gruppo (Cast/Feat.extra/Crowd/Stunts) */
.grp-row td.grp-cell{background:var(--s2);font:800 11px var(--ff-sans);letter-spacing:.5px;text-transform:uppercase;color:var(--t2);padding:9px 18px;border-bottom:1px solid var(--border)}
.grp-row .grp-n{color:var(--t3);font-weight:700;margin-left:4px}
.grp-row:hover{background:transparent}
.cambio-row{display:grid;grid-template-columns:58px minmax(0,1fr) 140px minmax(0,1.1fr) auto;align-items:center;gap:12px;padding:12px 18px;border-bottom:1px solid var(--s3);transition:background .12s}
.cambio-row:last-child{border-bottom:0}
.cambio-row:hover{background:var(--s2)}
.cambio-row .ch{font-weight:700;font-size:13px}
.cambio-row .desc{font-size:11px;margin-top:2px}
.cambio-row .sc{font-size:12px}
@media(max-width:920px){.cambio-row{grid-template-columns:46px minmax(0,1fr) auto auto;gap:8px}.cambio-row .sc{display:none}}

/* ── Topbar: indicatore sync (#13) + hamburger mobile (#1) ── */
/* la search assorbe lo spazio centrale e spinge role-sw/sync/notifiche/avatar all'ANGOLO destro */
.topbar .search{margin-right:auto;position:relative}
/* #5 dropdown risultati ricerca */
.search-results{position:absolute;top:calc(100% + 8px);left:0;right:0;background:var(--surface);border:1px solid var(--border);border-radius:var(--r);box-shadow:var(--sh-pop);z-index:var(--z-pop);max-height:64vh;overflow:auto;padding:6px}
.sr-head{font-size:11px;color:var(--t3);padding:6px 10px 3px;position:sticky;top:0;background:var(--surface);z-index:1}
.sr-cat{font:700 10px var(--ff-sans);letter-spacing:.5px;text-transform:uppercase;color:var(--t3);padding:9px 10px 3px}
.sr-item{display:block;width:100%;text-align:left;background:transparent;border:0;border-radius:10px;padding:8px 10px;cursor:pointer}
.sr-item:hover{background:var(--s2)}
.sr-item b{font-size:13px;font-weight:600;color:var(--t1);display:block}
.sr-item small{font-size:11.5px;color:var(--t3)}
.sr-empty{padding:16px;color:var(--t3);font-size:12.5px;text-align:center}
/* ricerca smart: etichetta categoria + match evidenziato + risultato animato */
.sr-item{display:flex;flex-direction:column;gap:1px}
.sr-cat-tag{font:700 9px var(--ff-sans);letter-spacing:.4px;text-transform:uppercase;color:var(--accent-deep);background:var(--accent-mute);border-radius:5px;padding:1px 5px;align-self:flex-start;margin-bottom:2px}
.sr-item mark{background:var(--accent-mute);color:var(--accent-deep);border-radius:3px;padding:0 1px;font-weight:800}
.rk-flash{opacity:1!important;transform:none!important;border-radius:10px;position:relative;z-index:2;animation:rkPulse 1.9s ease-out}
@keyframes rkPulse{0%{box-shadow:0 0 0 0 rgba(10,132,255,.5)}12%{box-shadow:0 0 0 3px var(--accent),0 8px 26px -6px rgba(10,132,255,.5)}68%{box-shadow:0 0 0 3px var(--accent),0 8px 26px -6px rgba(10,132,255,.5)}100%{box-shadow:0 0 0 0 rgba(10,132,255,0)}}
tr.rk-flash{outline:2px solid var(--accent);outline-offset:-2px;border-radius:8px}
tr.rk-flash>td{animation:rkRowBg 1.9s ease-out forwards}
@keyframes rkRowBg{0%,68%{background:var(--accent-mute)}100%{background:transparent}}

/* #4 navigazione rapida avanti/indietro (flottante, sempre visibile) */
.nav-fly{position:fixed;left:18px;bottom:24px;z-index:65;display:flex;gap:5px;
  background:var(--glass-bg);backdrop-filter:blur(18px) saturate(180%);-webkit-backdrop-filter:blur(18px) saturate(180%);
  border:1px solid var(--border);border-radius:var(--r-pill);padding:5px;box-shadow:var(--sh-2)}
.nav-fly-btn{width:38px;height:38px;border-radius:50%;border:0;background:transparent;color:var(--t2);display:grid;place-items:center;transition:all .15s}
.nav-fly-btn:hover:not(:disabled){background:var(--s2);color:var(--t1)}
.nav-fly-btn:disabled{opacity:.32;cursor:default}
.sync-ind{display:inline-flex;align-items:center;gap:7px;background:var(--s2);border:1px solid var(--border);
  border-radius:var(--r-pill);padding:6px 12px;font-size:11.5px;font-weight:600;color:var(--t2);white-space:nowrap}
.sync-ind .sync-dot{width:8px;height:8px;border-radius:50%;background:var(--c-ok);box-shadow:0 0 0 3px var(--c-ok-bg);animation:syncpulse 2.4s ease-in-out infinite}
/* G4/S1b (03/07, fix falla B1): stato ambra ben visibile — offline e/o coda di
   modifiche non ancora sincronizzate col gruppo (era un semplice grigio muto,
   troppo discreto: il server caduto passava inosservato). */
.sync-ind.warn{background:var(--c-warn-bg);border-color:var(--c-warn);color:var(--c-warn)}
.sync-ind.warn .sync-dot{background:var(--c-warn);box-shadow:0 0 0 3px var(--c-warn-bg);animation:syncpulse 1.4s ease-in-out infinite}
@keyframes syncpulse{0%,100%{opacity:1}50%{opacity:.45}}
.hamb{display:none}
@keyframes drawerIn{from{transform:translateX(-100%)}to{transform:none}}

/* ===========================================================================
   RESPONSIVE
   =========================================================================== */
/* ===== TABLET / sotto i 920: sidebar → hamburger + drawer ===== */
@media (max-width:920px){
  .side-col{display:none}
  .content{padding:12px;height:100vh}
  .main{overflow-x:hidden}
  .grid2,.cmp-grid,.modal-grid{grid-template-columns:minmax(0,1fr)}
  .hamb{display:grid}
  .prod-pill,.role-sw,.rep-sw{display:none}
  .role-sw.db-view-sw,.role-sw.foto-view-sw,.role-sw.cont-view-sw{display:flex}   /* D8 fix: lo switcher Home/Diario/Note (D1) riusa .role-sw ma NON è il toggle Master/Membro/reparto — deve restare usabile sotto i 920px. TAPPA D: stesso salvagente per lo swap Galleria|Moodboard della tab Foto, che sul telefono è l'UNICA strada per raggiungere le moodboard */
  .role-sw.rc-sw{display:flex}   /* LOTTO I2 fix: gli switcher del compositore Continuity (Reparto/Ordina/Stato/sotto-scelta Foto, tab Stampe) riusano .role-sw ma NON sono il toggle Master/Membro/reparto — devono restare usabili sotto i 920px (gemello di .role-sw.db-view-sw sopra) */
  .sync-ind .sync-lbl{display:none}
  .sync-ind.warn .sync-lbl{display:inline}   /* G4/S1b: l'avviso offline/coda resta leggibile anche su tablet */
  /* hero ODG impilato: meta sopra, meteo sotto a TUTTA larghezza (niente sbordo) */
  .odg-hero{flex-direction:column}
  .odg-hero .meta{min-width:0;padding:20px 18px}
  .odg-hero>div:last-child{padding:0 16px 16px!important;width:100%}
  .wx{width:100%!important;margin:0!important}
  /* tabelle nei modali (es. anteprima breakdown): scroll orizzontale interno */
  .panel{overflow-x:auto}
  .table{min-width:520px}
  .bd-info{gap:16px}
  /* LISTE PRINCIPALI → card a DOPPIA COLONNA (tablet-first: meno lunghe, comode al tatto) */
  .main .panel{overflow-x:visible}
  .main .table{min-width:0;display:block}
  .main .table thead{display:none}
  .main .table tbody{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,340px),1fr));gap:10px;padding:12px;align-items:start}
  .main .table tr{display:block;background:var(--surface);border:1px solid var(--border);border-radius:14px;box-shadow:var(--sh-1);overflow:hidden}
  .main .table tr:hover{background:var(--surface)}
  .main .table tr.grp-row{grid-column:1/-1;border:0;box-shadow:none;background:transparent;margin-top:4px}
  .main .table td{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:9px 13px;border:0;border-bottom:1px solid var(--s3);text-align:right;font-size:13px}
  .main .table td::before{content:attr(data-label);color:var(--t3);font-weight:700;font-size:10px;letter-spacing:.4px;text-transform:uppercase;text-align:left;flex-shrink:0}
  .main .table td:not([data-label]){justify-content:flex-end}
  .main .table td:last-child{border-bottom:0}
  .main .table td:empty{display:none}
  .main .table td.grp-cell{border:0;padding:4px 6px 2px;justify-content:flex-start;background:transparent}
  .main .table td.grp-cell::before{display:none}
  .main .inv-name{justify-content:flex-end;text-align:right}
  /* drawer mobile a scomparsa */
  .app.mobile-open .side-col{display:flex;position:fixed;top:0;left:0;bottom:0;z-index:100;width:272px;padding:14px;
    background:var(--bg);box-shadow:var(--sh-pop);overflow-y:auto;animation:drawerIn .22s cubic-bezier(.2,.8,.2,1)}
  .app.mobile-open .sidebar{max-height:none;width:100%}
  .app.mobile-open::before{content:"";position:fixed;inset:0;background:rgba(17,24,39,.45);backdrop-filter:blur(3px);z-index:99}
  /* IL DRAWER IGNORA lo stato "collassato" desktop → sempre espanso e leggibile */
  .app.mobile-open.collapsed .side-col{width:272px}
  .app.mobile-open.collapsed .sidebar{padding:14px 12px 12px;overflow-x:visible}
  .app.mobile-open.collapsed .side-top{justify-content:flex-start;gap:10px;padding:4px 6px 12px}
  .app.mobile-open.collapsed .side-top .brand-name{display:block}
  .app.mobile-open.collapsed .side-top .ver{display:inline-block}
  .app.mobile-open.collapsed .nav-item .pin{display:inline-block}   /* il badge (es. "rev") resta visibile nel drawer */
  .side-collapse{display:none}                /* su mobile la barra è già a scomparsa: il toggle "collassa" non serve */
  .app.mobile-open.collapsed .nav-item{width:auto;height:auto;padding:10px 12px;margin:0;justify-content:flex-start}
  .app.mobile-open.collapsed .nav-item .lbl{display:block}
  .app.mobile-open.collapsed .nav-cap{display:block}
  .app.mobile-open.collapsed .side-foot{display:block}
}
/* ===== PHONE: impilamento e proporzioni scalate ===== */
@media (max-width:560px){
  .h-title{font-size:21px;letter-spacing:-.4px}
  .h-sub{font-size:12px}
  /* TIMELINE verticale su telefono: niente scroll orizzontale (P3) */
  .timeline{flex-direction:column;overflow-x:visible;gap:14px;padding:12px 8px 6px}
  .timeline .tl-step{min-width:0;flex:0 0 auto}
  .timeline .tl-step::before{display:none}
  .topbar{gap:8px;padding:0 10px}
  .topbar .ai-badge{display:none}
  .main{padding:16px 12px 96px}
  /* azioni di testata a tutta larghezza, impilate ordinatamente */
  .page-head>div:last-child{width:100%}
  .page-head .btn{flex:1 1 auto;justify-content:center}
  /* budget e sourcing impilati, bottoni full-width */
  .bd-info{gap:12px}
  .budget .bd-info>button{margin-left:0;width:100%;justify-content:center}
  .src-row{flex-wrap:wrap}.src-row .btn{width:100%;justify-content:center}
  .inv-tools .search{max-width:none}
  /* griglie a 1 colonna / foto più piccole */
  .rep-grid{grid-template-columns:minmax(0,1fr)}
  .foto-grid{grid-template-columns:repeat(auto-fill,minmax(176px,1fr));gap:18px}   /* M1c: variante tablet proporzionata al restyle (era 132px) */
  .gal-grid{grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}
  .conv-grid{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
  /* modali e nav rapida */
  .modal-foot{flex-wrap:wrap}.modal-foot .btn{flex:1;justify-content:center}
  .nav-fly{left:12px;bottom:14px}
  .odg-num .big{font-size:26px}
  /* tabelle → card leggibili (niente scroll orizzontale su telefono) */
  .main .panel{overflow-x:visible}
  .main .table{min-width:0}
  .main .table thead{display:none}
  .main .table tr{display:block;background:var(--surface);border:1px solid var(--border);border-radius:14px;margin-bottom:10px;box-shadow:var(--sh-1);overflow:hidden}
  .main .table tr:hover{background:var(--surface)}
  .main .table td{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:10px 14px;border:0;border-bottom:1px solid var(--s3);text-align:right;font-size:13px}
  .main .table td::before{content:attr(data-label);color:var(--t3);font-weight:700;font-size:10px;letter-spacing:.4px;text-transform:uppercase;text-align:left;flex-shrink:0}
  .main .table td:not([data-label]){justify-content:flex-end}
  .main .table td:last-child{border-bottom:0}
  .main .table td:empty{display:none}
  .main .inv-name{justify-content:flex-end;text-align:right}
  /* header categoria come separatore (non card) */
  .main .table tr.grp-row{border:0;box-shadow:none;background:transparent;margin:12px 0 2px}
  .main .table td.grp-cell{border:0;padding:2px 4px;justify-content:flex-start;background:transparent}
  .main .table td.grp-cell::before{display:none}
}

/* ===========================================================================
   RESPONSIVE HARDENING — audit Cowork (19/06): non rompere mai su nessun device
   =========================================================================== */
/* 0. rete di sicurezza onesta (le CAUSE vere sono risolte sotto) */
html,body{overflow-x:hidden}

/* 1. shell su viewport reale mobile (svh non taglia col browser dinamico) */
.app{height:100svh}
.content{height:100svh}
.sidebar{max-height:calc(100svh - 28px)}

/* 2. CAUSA RADICE overflow: i flex item non scendono sotto il min-content senza
   min-width:0. La .search (con <input>) spingeva sync/notifiche/avatar fuori. */
.topbar{gap:8px;min-width:0}
.search{min-width:0}
.search input{min-width:0;width:100%}
.avatar,.icon-btn,.sync-ind,.hamb,.role-sw,.rep-sw{flex-shrink:0}
.src-row,.cc-row,.page-head,.modal-foot,.bd-info,.inv-name{min-width:0}
.annot-gtag .gn{min-width:0;text-overflow:ellipsis}
.foto-cap b,.so,.cc-row .who,.inv-name a{min-width:0}

/* 3. niente zoom involontario iOS: campi editabili >= 16px (desktop torna compatto) */
.input,select.input,textarea.input,.search input,.sel-item select,.sel-item textarea{font-size:16px;line-height:1.3}
@media (min-width:921px){
  .input,select.input,textarea.input,.search input{font-size:13px}
  .sel-item select{font-size:11.5px} .sel-item textarea{font-size:12.5px}
}

/* fascia tablet 921-1280 */
@media (min-width:921px) and (max-width:1280px){
  .prod-pill{display:none}
  .search{min-width:240px}
  .panel{overflow-x:auto}
}

/* ── TABELLE: le tre invarianti anti-sbordo valgono OVUNQUE la tabella sia una tabella ──────────
   Z10 (29/07/2026, appunto di Andrea «in inventario i testi sono troppo stretti»): queste tre
   regole nascono alla TAPPA O (27/07) e stavano dentro la fascia «921-1280». Andrea le ha trovate
   assenti sul suo iPad Pro 12.9 in orizzontale, che è 1366px CSS: 86px oltre la porta. Sopra il
   1280 tornava a valere l'invariante n.1 (`anywhere`) e l'Inventario ricadeva ESATTAMENTE nel
   difetto che la TAPPA O aveva già curato a 1024 — le intestazioni incolonnate una lettera per
   riga («IMP/ONIB/ILE», «CO/ST/O», «Q./T/À») e i prezzi pure («€2/76/,0/0»).
   La lezione non è «alzare 1280 a 1366»: è che una cura scritta come FASCIA vale solo dentro la
   fascia, e il difetto ricompare al primo schermo che ne esce. Il confine vero non è una
   larghezza, è uno STATO: sopra i 921px la tabella è una tabella (thead visibile, celle in
   colonna) e allora le tre regole servono sempre; sotto i 921 diventa una lista di card
   (.main .table thead{display:none}, :1541) e lì l'invariante n.1 torna a essere quella giusta.
   Sopra il 1280 non costano nulla: la tabella ci sta già, lo scroller non si attiva e il
   min-width è inerte — VERIFICATO a 1920 con scrollWidth==clientWidth (tools/qa_Z/z40).       */
@media (min-width:921px){
  /* invariante n.2 — chi ospita una tabella DEVE poter scorrere, altrimenti se la mangia. Non è
     scritta per .panel ma per CHIUNQUE ospiti una tabella (l'Anagrafica 2.0 le tiene in
     .an2-sec-inner, che clippa per animare l'apertura della sezione, e a 1024px tagliava via
     88px di colonne in silenzio). Dice CHI ospita, chiunque sia, oggi e domani. */
  .main :has(> .table){overflow-x:auto}
  .table{min-width:780px}
  /* invariante n.3 — DENTRO UNA TABELLA CHE PUÒ SCORRERE, le celle non spezzano le parole.
     L'invariante n.1 (`anywhere`, ~:548) è giusta ovunque il contenuto debba STARE in una
     larghezza data; qui la larghezza non è data, il contenitore scorre (regola sopra). Applicata
     anche qui portava la larghezza minima di ogni cella a UN CARATTERE e il layout tabellare
     degenerava: tutto dentro lo schermo, nessuno sbordo da misurare, e illeggibile. Con `normal`
     ogni colonna chiede la sua parola più lunga, la tabella si allarga quanto le serve e si
     scorre — che è esattamente a cosa serve uno scroller. */
  .main .table td,.main .table th{overflow-wrap:normal}
  /* Z10 · un'INTESTAZIONE non si spezza mai, nemmeno fra due parole: «Q.tà» e «Totale giornate»
     sono etichette, non prosa. `normal` da solo lascia andare a capo su spazio e su punto, ed è
     così che «Q.tà» diventava «Q.» + «tà». Stesso discorso per i valori monospaziati (prezzi,
     codici box, quantità): un numero spezzato a metà non è un numero. */
  .main .table th,.main .table td.mono,.main .table td.ta-c{white-space:nowrap}
}

/* 4. touch target >= 44 (area tap estesa: nessun layout shift; solo touch per i .btn) */
.icon-btn{position:relative}
/* hit-area estesa SENZA sbordo orizzontale: top/bottom/left non gonfiano lo scrollWidth,
   right:0 evita il +Npx di overflow su OGNI icona (era marcato dal banco su ogni riga). */
.icon-btn::after{content:"";position:absolute;top:-5px;bottom:-5px;left:-5px;right:0}
.hamb::after{content:"";position:absolute;inset:-5px -11px}
.nav-fly-btn{width:44px;height:44px}
@media (pointer:coarse),(max-width:920px){
  .btn{min-height:44px}
  .seg-btn{min-height:44px}
  .nav-item{min-height:44px}
  .combo-btn,.input,select,textarea{min-height:44px}
  .icon-btn::after{top:-7px;bottom:-7px;left:-7px;right:0}    /* area tap ~50px, senza sbordo dx */
  .mc-ck,.tr-ck{position:relative}
  .mc-ck::after,.tr-ck::after{content:"";position:absolute;inset:-13px}  /* checkbox 18px → tap ~44px */
  .mb-check::after{content:"";position:absolute;inset:-10px}   /* M1e: checkbox foto 24px → tap ~44px, sempre visibile su coarse */
}

/* 5. safe-area (notch / home indicator) — richiede viewport-fit=cover nel meta */
.topbar{padding-left:max(16px,env(safe-area-inset-left));padding-right:max(16px,env(safe-area-inset-right))}
.fab{right:max(26px,env(safe-area-inset-right));bottom:max(26px,env(safe-area-inset-bottom))}
.nav-fly{left:max(12px,env(safe-area-inset-left));bottom:max(14px,env(safe-area-inset-bottom))}
.back-top{right:max(26px,env(safe-area-inset-right));bottom:calc(98px + env(safe-area-inset-bottom))}
.main{padding-bottom:calc(110px + env(safe-area-inset-bottom))}
.app.mobile-open .side-col{padding-bottom:max(14px,env(safe-area-inset-bottom))}

/* 6. modali/pannelli su dvh (altezza reale che segue la barra del browser) */
.modal-back .modal{max-height:90dvh}
.panel-fb{max-height:74dvh}
.search-results{max-height:64dvh}

/* 7. griglie immuni anche sotto la traccia minima (min(100%,N)) */
.conv-grid{grid-template-columns:repeat(auto-fill,minmax(min(100%,208px),1fr))}
.gal-grid{grid-template-columns:repeat(auto-fill,minmax(min(100%,212px),1fr))}
.foto-grid{grid-template-columns:repeat(auto-fill,minmax(min(100%,224px),1fr));gap:18px}   /* M1c: floor mobile allineato al restyle (era 168px) */
.rep-grid{grid-template-columns:repeat(auto-fill,minmax(min(100%,290px),1fr))}

/* 8. fluid type sul titolo pagina (scala con continuità, niente salti) */
.h-title{font-size:clamp(20px,5vw,25px)}

/* 9. guardia immagini: niente sforamenti dal contenitore */
img,.inv-thumb,.foto-img{max-width:100%}
.inv-thumb img,.foto-img img{width:100%;height:100%;object-fit:cover}

/* 10. terzo breakpoint: telefoni stretti (<=480) → la ricerca cede ai controlli */
@media (max-width:480px){
  .sync-ind .sync-lbl{display:none}
  .sync-ind.warn .sync-lbl{display:inline}   /* G4/S1b: idem a 390px — l'avviso non deve sparire */
  .topbar .search{margin-right:8px}
  .page-head .h-sub{font-size:12px}
}

/* ===========================================================================
   PRINT — l'ODG come call sheet A4
   =========================================================================== */
@media print{
  .side-col,.topbar,.fab,.panel-fb,.toast-wrap,.annot-tag,.annot-gtag,.no-print,.hg-hint,.hg-dots{display:none!important}
  .app{display:block;height:auto;background:#fff}
  .content{height:auto;padding:0}
  .main{padding:0;background:#fff;overflow:visible}
  .panel{box-shadow:none;border:1px solid #bbb;break-inside:avoid;margin-bottom:12px}
  .wx{color:#1D1D1F;background:#fff!important;border:1px solid #bbb}
  .wx-sky{display:none}
  body{font-size:11px}
  .anim{animation:none;opacity:1}
}

/* ===========================================================================
   REDUCED MOTION — rispetta le preferenze di sistema
   =========================================================================== */
@media (prefers-reduced-motion:reduce){
  *{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
  .anim{opacity:1;transform:none}
  .wx-sun::before,.wx-cloud,.wx-precip i,.wx-gust,.wx-star,.wx-sun,.wx-moon{animation:none!important}
}

/* ===========================================================================
   SCHEDE DETTAGLIO (VIEW) — modale CENTRATO con sfocato attorno (desktop),
   a TUTTO SCHERMO che sale dal basso e copre tutto su tablet/telefono.
   =========================================================================== */
.modal .mh-tit{display:flex;flex-direction:column;gap:1px;min-width:0}
.modal-sub{font:700 10px var(--ff-sans);color:var(--t3);text-transform:uppercase;letter-spacing:.5px}
.modal.dv-modal{width:min(1160px,96vw)}
.modal.dv-modal .modal-foot{justify-content:space-between}
@media (max-width:720px){
  .modal-back.dv-back{padding:0}
  .modal-back .modal.dv-modal{width:100%;max-width:100%;height:100dvh;max-height:100dvh;border-radius:0;
    transform:translateY(100%)}
  .modal-back.show .modal.dv-modal{transform:none}
  .modal.dv-modal .modal-body{flex:1;min-height:0}
}
.dv{display:flex;flex-direction:column;gap:15px}
.dv-hero{display:flex;align-items:center;gap:14px}
.dv-av,.dv-code,.dv-thumb{flex-shrink:0}
.dv-av{width:52px;height:52px;border-radius:14px;background:linear-gradient(135deg,#6b78f5,#4453d6);color:#fff;display:grid;place-items:center;font:800 17px var(--ff-sans)}
.dv-code{min-width:52px;height:52px;padding:0 13px;border-radius:14px;background:var(--ink);color:#fff;display:grid;place-items:center;font:800 18px 'JetBrains Mono'}
.dv-thumb{width:52px;height:64px;border-radius:12px;overflow:hidden;border:1px solid var(--border);background:var(--s3);display:grid;place-items:center;color:var(--t3)}
.dv-thumb img{width:100%;height:100%;object-fit:cover}
.dv-thumb.big{width:92px;height:114px}
.dv-htxt{min-width:0}
.dv-title{font:800 20px var(--ff-sans);letter-spacing:-.4px;line-height:1.15;color:var(--t1);word-break:break-word}
.dv-sub{color:var(--t3);font-size:12.5px;margin-top:2px}
.dv-facts{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,120px),1fr));gap:8px}
.dv-fact{background:var(--s2);border:1px solid var(--border);border-radius:12px;padding:8px 11px;display:flex;flex-direction:column;gap:2px;min-width:0}
.dv-fact .k{font:700 9px var(--ff-sans);letter-spacing:.5px;text-transform:uppercase;color:var(--t3)}
.dv-fact .v{font:700 14px var(--ff-sans);color:var(--t1);overflow:hidden;text-overflow:ellipsis}
.dv-sec{border-top:1px solid var(--border);padding-top:12px}
.dv-sec-h{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:9px;min-height:30px}
.dv-sec-h b{font-size:13px;font-weight:700;color:var(--t1);display:inline-flex;align-items:center}
.dv-n{font:700 10px 'JetBrains Mono';color:var(--accent-deep);background:var(--accent-soft);border-radius:6px;padding:1px 6px;margin-left:6px}
.dv-text{font-size:13px;color:var(--t2);line-height:1.55;word-break:break-word}
.dv-text.warn{color:var(--c-warn)}
.dv-empty{font-size:12px;color:var(--t3);font-style:italic}
.dv-star{color:var(--c-day);margin-right:4px;font-size:12px;line-height:1}
.dv-dot{color:var(--c-warn);margin-right:5px;font-size:9px;vertical-align:1px}
.dv-chips{display:flex;flex-wrap:wrap;gap:7px}
.dv-link{display:inline-flex;align-items:center;gap:6px;background:var(--surface);border:1px solid var(--border);border-radius:10px;
  padding:8px 11px;min-height:40px;font-size:12.5px;font-weight:600;color:var(--t1);cursor:pointer;transition:all .14s;text-align:left;max-width:100%}
.dv-link small{color:var(--t3);font-weight:500;white-space:nowrap}
.dv-link:hover{border-color:var(--accent-bord);background:var(--accent-mute);color:var(--accent-deep)}
.dv-link.off{color:var(--t3);cursor:default;background:var(--s2)}
.dv-link.off:hover{border-color:var(--border);background:var(--s2);color:var(--t3)}
/* lista entità scalabile: chip pinnato + tasto "altri N" (→ toast con la lista completa, Andrea 167dd22423) */
.dv-link.pinned{border-color:var(--accent-bord);background:var(--accent-mute);color:var(--accent-deep);font-weight:700}
.dv-more{position:relative;display:inline-flex}
.dv-more-btn{display:inline-flex;align-items:center;gap:6px;background:var(--s2);border:1px dashed var(--border);border-radius:10px;padding:6px 11px;font:600 12px var(--ff-sans);color:var(--t2);cursor:pointer}
.dv-more-btn:hover{border-color:var(--accent-bord);color:var(--accent-deep)}
/* toggle "parlante" (flag pinned, scheda personaggio) */
.field-toggle{display:flex;flex-direction:column;gap:3px}
.toggle-lab{display:inline-flex;align-items:center;gap:9px;cursor:pointer;user-select:none}
.toggle-ck{position:absolute;opacity:0;width:0;height:0}
.toggle-box{width:22px;height:22px;--ck-c:var(--accent)}   /* "selezione" → accent; forma/spunta-draw = CHECKBOX CANONICA (:752) */
.toggle-txt{font:600 13px var(--ff-sans);color:var(--t1)}
.toggle-hint{font:500 11px var(--ff-sans);color:var(--t3);padding-left:31px;line-height:1.35}
/* FIX 13/07 (L1 login): dentro un .field il label.toggle-lab EREDITAVA .field>label (:522,
   specificità 0-1-1 > 0-1-0): display:block spezzava la riga (il .toggle-box è grid = block-level
   e va a capo) e text-transform:uppercase urlava il testo nei figli. Override mirato (0-2-1),
   vale per ENTRAMBI i siti del pattern (login.html:51 «Ricordami», sections.js:229 toggle dei form). */
.field>label.toggle-lab{display:inline-flex;text-transform:none;letter-spacing:normal;margin-bottom:0}
/* X3 (11/07, idea 3 Andrea): scene "già girate" — spunta in tabella Scene (clone di .toggle-box
   qui sopra; ON = verde semantico --c-ok della legenda, NON accent: è uno stato "fatto") +
   riga attenuata. Opacity sui td (non sul tr) per non litigare con l'animazione .anim della
   riga. Nella SCHEDA scena "Girata" è un fact (dvFacts): fmArrange scarta l'hero → zero badge. */
.th-gir{width:34px}
.td-gir{text-align:center}
.gir-ck{width:22px;height:22px;border-radius:7px;border:1.5px solid var(--border);background:var(--surface);display:inline-grid;place-items:center;color:transparent;cursor:pointer;padding:0;vertical-align:middle;transition:all .15s}
.gir-ck:hover{border-color:var(--c-ok)}
.gir-ck.on{background:var(--c-ok);border-color:var(--c-ok);color:#fff}
.gir-ck.ro{cursor:default}
.tr-girata>td{background:var(--c-ok-bg);transition:background .15s}
tr.tr-girata:hover>td{background:rgba(30,142,87,.2)}
/* ── X2 NOTE-chat (nt-*, 11/07): vista provvisoria #note — con la dashboard X1 il feed
   migra nella colonna destra (mockup congelato). Solo token esistenti; flash ricerca = .rk-flash. ── */
.nt-feed{display:flex;flex-direction:column;gap:10px;max-width:820px;margin:0 auto;padding:4px 2px 12px}
.nt-msg{background:var(--surface);border:1px solid var(--border);border-radius:14px;padding:10px 13px;max-width:86%;align-self:flex-start}
.nt-mine{align-self:flex-end;background:var(--accent-soft);border-color:var(--accent-bord)}
.nt-done{opacity:.62}
.nt-meta{display:flex;gap:8px;align-items:center;font-size:12px;margin-bottom:3px;flex-wrap:wrap}
.nt-rep{border:1px solid var(--border);border-radius:var(--r-pill);padding:1px 8px;font-size:11px}
.nt-prod{border-style:dashed}
.nt-anc{display:inline-flex;align-items:center;gap:4px;font-size:12px;margin:2px 0}
.nt-txt{white-space:pre-wrap;word-break:break-word}
.nt-foot{margin-top:6px;display:flex;gap:8px;align-items:center;font-size:12px;flex-wrap:wrap}
.nt-mini{padding:4px 10px;font-size:12px}
.nt-comp{display:flex;gap:8px;max-width:820px;margin:10px auto 0;align-items:flex-end}
.nt-ancin{width:104px;flex:0 0 auto}
.nt-txtin{flex:1}
.nt-tabs{display:flex;gap:8px;max-width:820px;margin:0 auto 10px}   /* X1: tab Aperte/Storico dentro colHTML (prima erano nelle azioni di pageHead) */

/* ── X1 (11/07) — DASHBOARD DI REPARTO (dashboard.js) · mockup congelato rivestito coi
   token reali; il picker giornata è un overlay DEDICATO .db-ovl (NIENTE .modal-back:
   closeModal/onKey di sections.js la agganciano via querySelector generico) ── */
.db-wrap{display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);gap:16px;align-items:start}
@media(max-width:920px){.db-wrap{grid-template-columns:minmax(0,1fr)}}
.db-ptit{display:flex;align-items:center;gap:8px;font-size:12.5px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--t2);margin:0 0 12px;flex-wrap:wrap}
.db-cnt{background:var(--s3);border-radius:var(--r-pill);padding:2px 10px;font-size:11.5px;color:var(--t1);font-weight:600;text-transform:none;letter-spacing:0}
.db-ptit .btn{margin-left:auto;text-transform:none;letter-spacing:0}
.db-sync{width:8px;height:8px;border-radius:var(--r-pill);background:var(--c-ok);box-shadow:0 0 6px var(--c-ok);flex:0 0 auto}
@media(prefers-reduced-motion:no-preference){.db-sync{animation:dbPulse 2.4s infinite}}
@keyframes dbPulse{50%{opacity:.35}}
.db-sc{border:1px solid var(--border);border-radius:var(--r-sm);background:var(--surface);margin-bottom:10px;overflow:hidden}
.db-sc.girata>.db-sc-head{opacity:.55}
.db-sc-head{display:flex;align-items:center;gap:9px;padding:10px 12px;cursor:pointer;flex-wrap:wrap}
.db-sc-head:hover{background:var(--s2)}
.db-num{background:var(--accent-soft);color:var(--accent-deep);border:1px solid var(--accent-bord);border-radius:var(--r-pill);padding:2px 10px;font-weight:700;font-size:12px;white-space:nowrap}
.db-dn{width:8px;height:8px;border-radius:var(--r-pill);flex:0 0 auto}
.db-tit{flex:1;min-width:0}
.db-tit b{display:block;font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.db-tit .muted{font-size:11.5px}
.db-b-cover{color:var(--c-info);background:var(--c-info-bg);border-color:currentColor}
.db-b-girata{color:var(--c-ok);background:var(--c-ok-bg);border-color:currentColor}
.db-chev{display:flex;color:var(--t3);transition:transform .18s}
.db-chev.on{transform:rotate(180deg)}
@media(prefers-reduced-motion:reduce){.db-chev{transition:none}}
.db-sc-body{padding:4px 12px 12px;border-top:1px dashed var(--border)}
.db-pers{margin-top:9px}
.db-pers-h{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--t2);flex-wrap:wrap}
.db-pid{color:var(--t3);font-size:11px}
.db-pers-btn{background:none;border:0;padding:0;font:inherit;font-weight:700;color:var(--t1);cursor:pointer}
.db-pers-btn:hover{color:var(--accent-deep);text-decoration:underline}
.db-inh{font-size:10.5px}
.db-chips{display:flex;gap:6px;flex-wrap:wrap;margin-top:5px}
.db-chip{cursor:pointer}
.db-dot{display:inline-block;width:7px;height:7px;border-radius:var(--r-pill);margin-right:5px}
.db-hint{font-size:11.5px;margin-top:8px}
.db-note{position:sticky;top:12px}
.db-note .nt-tabs,.db-note .nt-feed,.db-note .nt-comp{max-width:none}
.db-note .nt-feed{max-height:calc(100dvh - 330px);min-height:180px;overflow-y:auto}
@media(max-width:920px){.db-note{position:static}.db-note .nt-feed{max-height:48dvh}}
.db-ovl{position:fixed;inset:0;background:rgba(17,24,39,.46);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);display:none;align-items:center;justify-content:center;z-index:95;padding:16px}
.db-ovl.on{display:flex}
.db-modal{background:var(--surface);border:1px solid var(--border2);border-radius:var(--r-lg);box-shadow:var(--sh-3);width:min(640px,100%);max-height:86dvh;display:flex;flex-direction:column}
.db-m-head{display:flex;align-items:center;gap:10px;padding:14px 16px 6px}
.db-m-head b{display:flex;align-items:center;gap:8px;font-size:15px;flex:1}
.db-m-sub{padding:0 16px 12px;font-size:12px;border-bottom:1px solid var(--border)}
.db-m-body{overflow-y:auto;padding:10px 12px;flex:1}
.db-pk-row{display:flex;align-items:center;gap:10px;padding:8px;border-radius:var(--r-sm)}
.db-pk-row:hover{background:var(--s2)}
.db-pk-row.sel{background:var(--accent-soft)}
.db-pk-ck{flex:0 0 auto}
.db-pk-tit{flex:1;min-width:0;font-size:12.5px}
.db-pk-tit .muted{font-size:10.5px}
.db-pk-cov{cursor:pointer}
.db-pk-cov.on{color:var(--c-info);background:var(--c-info-bg);border-color:currentColor;font-weight:700}
.db-pk-cov.off{opacity:.35;pointer-events:none}
.db-m-foot{display:flex;gap:10px;justify-content:flex-end;padding:12px 16px;border-top:1px solid var(--border)}
body.db-ovl-open{overflow:hidden}
@media(max-width:560px){.db-sc-head{gap:6px;padding:9px 10px}.db-tit b{font-size:12.5px}.db-note .nt-feed{max-height:44dvh}}
/* X1b: colonna sinistra (scene + box capi) e box capi filtrabile — chip/facce = classi
   GLOBALI di cambifiltri.css (.cf-face/.fchip/.cf-reset), qui solo il contenitore e le righe */
.db-col{display:flex;flex-direction:column;gap:16px;min-width:0}
.db-cp-filters{display:flex;flex-direction:column;margin:2px 0 12px}
.db-cp-filters .cf-foot{margin-top:10px}
.db-cp-list{display:flex;flex-direction:column;gap:6px;max-height:420px;overflow-y:auto;padding-right:4px;scrollbar-width:thin}
.db-cp-row{display:flex;align-items:center;gap:10px;width:100%;text-align:left;min-height:40px;padding:8px 10px;
  border:1px solid var(--border);border-radius:var(--r-sm);background:var(--surface);cursor:pointer;transition:border-color .14s}
.db-cp-row:hover{border-color:var(--accent)}
.db-cp-nome{font-weight:700;font-size:12.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:0 1 auto}
.db-cp-sub{flex:1;min-width:0;font-size:11.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.db-cp-st{flex:0 0 auto;font-size:10.5px}
.db-cp-more{margin-top:8px;width:100%}
@media(max-width:560px){.db-cp-sub{display:none}}
.dv-foto{display:flex;gap:7px;flex-wrap:wrap}
.dv-foto-i{position:relative;width:48px;height:60px;border-radius:9px;overflow:hidden;border:1px solid var(--border);background:var(--s3);
  display:grid;place-items:center;color:var(--t3);cursor:pointer;padding:0;transition:transform .18s cubic-bezier(.2,.8,.2,1),box-shadow .18s,border-color .14s;will-change:transform}
.dv-foto-i:hover{transform:translateY(-3px);border-color:var(--accent-bord);box-shadow:0 7px 16px -7px rgba(91,107,239,.5);z-index:2}
.dv-foto-i img{width:100%;height:100%;object-fit:cover}
.foto-img.js-act{cursor:pointer}

/* ===========================================================================
   COMBO — menù a tendina CON ricerca (compare oltre le 5 voci)
   =========================================================================== */
.combo{position:relative}
.combo-btn{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;text-align:left;cursor:pointer;background:var(--surface)}
.combo-btn .ic{color:var(--t3);flex-shrink:0}
.combo-val{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.combo-val.ph{color:var(--t3)}
/* menù a tendina = LAYER FLOTTANTE: position:fixed → esce da overflow/stacking di
   qualsiasi contenitore (modale, card), MAI clippato e MAI sotto altri elementi.
   left/top/width sono calcolati da placePop() dentro la cornice visibile (la scheda
   se presente, altrimenti il viewport): non "spunta fuori". [[pattern--flowset-layer-flottante-centrato]] */
.combo-pop{position:fixed;z-index:var(--z-pop);min-width:200px;max-width:min(440px,92vw);background:var(--surface);border:1px solid var(--border);
  border-radius:12px;box-shadow:var(--sh-pop);padding:8px;max-height:min(62vh,440px);display:flex;flex-direction:column;gap:6px}
.combo-pop[hidden]{display:none}   /* l'attributo hidden DEVE vincere su display:flex → il menù si richiude davvero */
.combo-search-wrap{max-width:none!important;background:var(--s2)!important;padding:8px 12px!important}
.combo-list{display:flex;flex-direction:column;gap:3px;overflow-y:auto}
.combo-opt{text-align:left;background:transparent;border:0;border-radius:9px;padding:10px 11px;font-size:13px;color:var(--t1);cursor:pointer;min-height:42px;white-space:normal}
.combo-opt:hover{background:var(--s2)}
.combo-opt.on{background:var(--accent-soft);color:var(--accent-deep);font-weight:600}
/* combo MULTI-selezione: voci con casella di spunta + riepilogo nel pulsante */
.combo-opt.mc{display:flex;align-items:center;gap:10px}
.mc-ck{width:18px;height:18px;border:1.6px solid var(--border2);border-radius:6px;flex-shrink:0;position:relative;transition:all .12s}
.combo-opt.mc.on .mc-ck{background:var(--accent);border-color:var(--accent-deep)}
.combo-opt.mc.on .mc-ck::after{content:"";position:absolute;left:5px;top:1px;width:4px;height:9px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg)}
.mc-lb{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.combo-empty{font-size:12px;padding:10px}

/* ===========================================================================
   CAMBI — blocchi per personaggio a griglia (multi-colonna, compatto)
   =========================================================================== */
.cambi-wrap{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,440px),1fr));gap:16px;align-items:start}
.cambi-wrap .cambi-block{margin-bottom:0}
.row-act{flex-wrap:wrap}
@media(max-width:560px){.cambio-row [data-cambio-move]{display:none}}

/* ── Cambi: una riga per personaggio · box personaggio CONGELATO a sinistra (come le righe
   fisse di Excel) + card outfit in RAIL orizzontale touch a destra (mai liste verticali). [[pattern--flowset-card-adattiva]] ── */
/* Z5 (28/07/2026): testata di MACRO-CATEGORIA fra le righe-personaggio. NON è un comando —
   non si clicca e non filtra (i filtri restano il pannello Facce, e un comando in più avrebbe
   voluto il contratto della vista): è l'indice della cascata, che senza divisione faceva
   scorrere 70 righe tutte uguali. Solo token, mai colori a mano (regola 6). */
.cbx-cat{display:flex;align-items:baseline;justify-content:space-between;gap:10px;flex-wrap:wrap;
  margin:18px 0 8px;padding:0 4px 6px;border-bottom:2px solid var(--accent-bord)}
.cbx-cat:first-child{margin-top:4px}
.cbx-cat-n{font-size:15px;font-weight:800;letter-spacing:.4px;text-transform:uppercase;color:var(--t1)}
.cbx-cat-c{font-size:12px;color:var(--t2)}
@media(max-width:560px){.cbx-cat{margin:14px 0 6px;padding:0 2px 5px}.cbx-cat-n{font-size:14px}}
.cbx-row{display:flex;gap:16px;align-items:stretch;padding:16px 18px}
/* colonna personaggio CONGELATA (sticky-left) = card Uiverse (dull-moose-30) normalizzata ai token:
   HERO colorato (badge #id alto-sx + bookmark alto-dx + nome grande) + FOOTER (avatar/striscia foto + meta + bottone Apri).
   Classi namespacizzate .upc__* per non collidere con .card del sito. [[pattern--flowset-card-adattiva]] */
.cbx-pers{width:236px;flex-shrink:0;position:sticky;left:0;z-index:1;background:var(--surface)}
.upc{display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--border);border-radius:var(--r);overflow:hidden;box-shadow:var(--sh-1);transition:box-shadow .18s,transform .14s,border-color .18s}
.upc:hover{box-shadow:var(--sh-2);transform:translateY(-2px);border-color:var(--accent-bord)}
/* ── HERO (clic = apre la scheda personaggio) ── */
.upc__hero{background:var(--accent-mute);padding:13px 14px 16px;cursor:pointer;display:flex;flex-direction:column;gap:10px;border-bottom:1px solid var(--border)}
.upc__hero-top{display:flex;align-items:center;justify-content:space-between;gap:8px}
.upc__badge{font:800 12px 'JetBrains Mono';color:var(--accent-deep);background:var(--surface);border:1px solid var(--accent-bord);border-radius:var(--r-pill);padding:3px 10px;letter-spacing:.2px;white-space:nowrap}
.upc__badge--ghost{font-family:var(--ff-sans);letter-spacing:0}
.upc__mark{display:grid;place-items:center;color:var(--accent);opacity:.85;flex-shrink:0}
.upc__title{margin:0;font-weight:800;font-size:1.4rem;line-height:1.12;letter-spacing:-.3px;color:var(--t1);
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:break-word;hyphens:auto}
.upc__hero:hover .upc__title{color:var(--accent-deep)}
/* ── FOOTER ── */
.upc__footer{display:flex;flex-direction:column;gap:10px;padding:12px 13px 13px}
.upc__sum{display:flex;align-items:center;gap:11px;min-width:0}
.upc__av{width:42px;height:42px;border-radius:12px;font-size:14px;flex-shrink:0}
.upc__foto{min-width:0;width:100%;overflow:visible}   /* striscia foto = carosello UNICO continuità DB [[pattern--flowset-carosello-foto]] · su riga propria, visible: hover non si taglia */
.upc__foto .pcar-strip{gap:5px}
.upc__foto .pcar-thumb{width:38px;height:48px;border-radius:8px}
.upc__foto .pcar-thumb:nth-child(n+5){display:none}   /* max 4 miniature in colonna stretta, il resto nel carosello al clic */
.upc__meta{min-width:0;flex:1}
.upc__sub{margin:0;font-weight:700;font-size:12.5px;color:var(--t2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.upc__cnt{margin:3px 0 0;font:700 11px 'JetBrains Mono';color:var(--accent-deep)}
.upc__btn{width:100%;border:none;cursor:pointer;text-align:center;padding:9px 14px;border-radius:var(--r-pill);
  background:var(--accent);color:#fff;font-size:13.5px;font-weight:700;letter-spacing:.2px;transition:background .15s,box-shadow .15s}
.upc__btn:hover{background:var(--accent-deep);box-shadow:var(--sh-1)}
/* alias storici ancora referenziati dalla riga "orfani" (Senza personaggio) */
.cbx-pers-main{display:flex;gap:12px;align-items:center;cursor:pointer;min-width:0}
.cbx-who{min-width:0}
.cbx-name{font-weight:800;font-size:15px;letter-spacing:-.2px;display:flex;align-items:center;gap:4px;flex-wrap:wrap}
.cbx-sub{color:var(--t3);font-size:12px;margin-top:1px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cbx-foto{min-width:0;overflow:visible}
/* RAIL orizzontale SEMPRE (desktop e mobile): le card scorrono a destra, niente wrap verticale */
/* align-items:stretch → tutte le card della riga hanno la STESSA altezza (uniformi, feedback Emanuele);
   padding verticale → un po' di respiro sopra e sotto nella colonna che scorre (e la card sollevata in hover non viene tagliata) */
.cbx-cards{flex:1 1 0;min-width:0;display:flex;flex-wrap:nowrap;align-items:stretch;gap:10px;overflow-x:auto;overflow-y:hidden;
  scroll-snap-type:x proximity;-webkit-overflow-scrolling:touch;scrollbar-width:thin;padding:6px 2px 8px}
/* CAMBI_SCROLL_FILTRI (04/07, BLUEPRINT_CAMBI_SCROLL_FILTRI.md): drag-orizzontale col mouse
   (funzionalità NUOVA — verificato con grep "cursor:grab" che non esisteva su .cbx-cards prima
   d'ora, era solo del mosaico moodboard). Logica in sections.js:wire() (mousedown/mousemove/
   mouseup, soglia TH=6px). Gated pointer:fine: su touch lo scroll nativo basta (fix causa reale
   in cambifiltri.css .cf-results{min-width:0}), niente cursore "a manina" fuori luogo su schermi
   touch-only. */
@media(pointer:fine){
  .cbx-cards{cursor:grab}
  .cbx-cards.cbx-dragging{cursor:grabbing;scroll-snap-type:none}
  .cbx-cards.cbx-dragging .cb-card,.cbx-cards.cbx-dragging .cb-add{cursor:grabbing}
}
body.cbx-dragging{cursor:grabbing;user-select:none}
.cb-card{container-type:inline-size;flex:0 0 auto;width:218px;background:var(--s2);border:1px solid var(--border);border-radius:14px;overflow:hidden;display:flex;flex-direction:column;transition:transform .16s,box-shadow .16s,border-color .16s;scroll-snap-align:start}
.cb-card:hover{transform:translateY(-2px);box-shadow:var(--sh-2);background:var(--surface)}
.cb-card.cb-moved{border-color:var(--accent-bord);background:var(--surface);box-shadow:inset 0 -3px 0 0 var(--accent),0 10px 22px -10px rgba(91,107,239,.55)}   /* card appena riordinata: barra celeste (come tab Foto / ricerca) */
/* densità adattiva: card stretta → resta solo l'essenziale, mai testo che sborda [[pattern--flowset-card-adattiva]] */
@container (max-width:168px){
  .cb-body{padding:10px 11px 8px}
  .cb-ti{font-size:12.5px}
  .cb-desc{display:none}
  .cb-meta{font-size:10.5px;margin-top:5px}
}
.cb-body{padding:12px 13px 10px;cursor:pointer;flex:1;min-width:0}
.cb-top{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:7px}
.cb-ch{font-weight:800;font-size:14px;color:var(--t1)}
.cb-ti{font-weight:700;font-size:13px;line-height:1.3;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.cb-desc{color:var(--t3);font-size:11.5px;margin-top:3px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.cb-meta{color:var(--t3);font-size:11px;margin-top:7px;display:flex;align-items:center;gap:4px;flex-wrap:wrap}
.cb-meta .ic{color:var(--accent);opacity:.8}
.cb-act{display:flex;gap:4px;justify-content:flex-end;padding:7px 10px;border-top:1px solid var(--border);background:var(--surface)}
.cb-act .icon-btn{width:30px;height:30px;border-radius:var(--r-pill)}
.cb-add{flex:0 0 auto;width:160px;border:1.5px dashed var(--border2);border-radius:14px;background:transparent;color:var(--t3);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;cursor:pointer;font-weight:600;font-size:12.5px;transition:all .14s;scroll-snap-align:start}
.cb-add:hover{border-color:var(--accent-bord);color:var(--accent-deep);background:var(--accent-mute)}
@media(max-width:920px){   /* F3b (03/07): breakpoint unificato a 920 (era 720) — allineato all'app-shell e a cambifiltri.css */
  /* la colonna personaggio resta a SINISTRA e congelata anche su mobile, solo più stretta */
  .cbx-row{gap:11px;padding:13px}
  .cbx-pers{width:158px}
  .upc__hero{padding:11px 11px 13px}
  .upc__title{font-size:1.08rem;-webkit-line-clamp:4}
  .upc__footer{padding:10px 10px 11px;gap:9px}
  .upc__av{width:36px;height:36px;border-radius:11px;font-size:13px}
  .upc__sum{gap:9px}
  .cb-card{width:200px}
}

/* ===========================================================================
   WRAPBOX — griglia di scatole di fine giornata
   =========================================================================== */
.wb-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,240px),1fr));gap:14px;align-items:start}
.wb-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);box-shadow:var(--sh-1);overflow:hidden;transition:transform .16s,box-shadow .16s;display:flex;flex-direction:column}
.wb-card:hover{transform:translateY(-2px);box-shadow:var(--sh-2)}
.wb-body{padding:15px 16px 9px;cursor:pointer;flex:1}
.wb-top{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}
.wb-code{font:800 16px 'JetBrains Mono';color:var(--t1)}
.wb-scopo{font-size:13.5px;font-weight:600;color:var(--t1);margin-bottom:7px;line-height:1.35}
.wb-meta{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--t3)}
.wb-meta .ic{color:var(--accent)}
.wb-act{display:flex;justify-content:flex-end;padding:8px 12px;border-top:1px solid var(--s3)}

/* ===========================================================================
   COMPILER · CONVOCATI TROUPE — due colonne, checkbox interattiva, riga spenta
   =========================================================================== */
/* due colonne PER REGOLA: grid auto-fit → collassa da solo (niente @media a gradini)
   e NON taglia il contenuto espandibile come faceva il multicolumn (column-count). */
.troupe-cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,240px),1fr));gap:var(--sp-5) 22px;align-items:start}
.troupe-cols .sect{margin-bottom:16px;width:100%}
.tr-row{display:flex;align-items:center;gap:11px;border-top:1px solid var(--s3);padding:8px 2px;transition:opacity .16s}
.tr-row:first-of-type{border-top:0}
.tr-row.off{opacity:.34}
.tr-ck{appearance:none;-webkit-appearance:none;width:19px;height:19px;flex-shrink:0;border:1.5px solid var(--border2);border-radius:50%;background:var(--surface);cursor:pointer;position:relative;transition:background var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out)}   /* pallino tondo = token checkbox canonico (:752); "selezione" → accent; spunta ::after */
.tr-ck::before{content:"";position:absolute;left:6px;top:2.5px;width:4px;height:8px;border:solid var(--t3);border-width:0 2px 2px 0;transform:rotate(45deg);opacity:.45}   /* ghost-spunta idle (rifinitura C) */
.tr-ck:checked::before{opacity:0}
.tr-ck:checked{background:var(--accent);border-color:var(--accent)}
.tr-ck:checked::after{content:"";position:absolute;left:6px;top:2.5px;width:4px;height:8px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg)}
.tr-who{flex:1;min-width:0;cursor:pointer;display:flex;flex-direction:column;line-height:1.25}
.tr-who b{font-weight:700;font-size:13px;color:var(--t1);letter-spacing:-.1px}
.tr-who small{color:var(--t3);font-size:11px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tr-ora{width:74px;flex-shrink:0;text-align:center;padding:7px 8px!important;font-weight:600}
.tr-man .input{padding:6px 8px!important}
.tr-man{flex-wrap:wrap}

/* ════════ PRESENZE DEL GIORNO (compilazione) — blocco unico Cast→Crowd→Troupe ════════
   Reparti troupe come macro-categorie COMPRIMIBILI su 2 colonne. Solo token, 7 temi ok. */
.cmpx-block{margin-top:18px}
.cmpx-block:first-of-type{margin-top:8px}
.cmpx-h{font:800 13px var(--ff-sans);color:var(--t1);display:flex;align-items:center;gap:9px;
  margin:0 0 11px;padding-bottom:8px;border-bottom:2px solid var(--border-soft);letter-spacing:-.2px}
.cmpx-ok{font:700 9.5px var(--ff-sans);color:var(--c-ok,#1E8E57);background:var(--accent-mute);
  border-radius:var(--r-sm);padding:2px 8px;letter-spacing:.03em}
/* override del .sect generico: il wrapper reparto è una card comprimibile, non una label */
.cmpx-cols .cmpx-repwrap.sect{border-left:0;padding-left:0;margin:0 0 10px}
.cmpx-repwrap{width:100%}
.cmpx-rep{display:flex;align-items:center;gap:9px;padding:9px 11px;border-radius:var(--r-sm);
  background:var(--s3);cursor:pointer;transition:background .12s;user-select:none}
.cmpx-rep:hover{background:var(--s2)}
.cmpx-dot{width:9px;height:9px;border-radius:50%;background:var(--tone,var(--accent));flex:none}
.cmpx-nm{font-weight:700;font-size:12.5px;flex:1;color:var(--t1);display:flex;align-items:center;gap:7px;min-width:0}
.cmpx-nm .ic{color:var(--tone,var(--accent))}
.cmpx-pill{font:700 11px 'JetBrains Mono';color:var(--t2);background:var(--surface);
  border:1px solid var(--border);border-radius:var(--r-pill);padding:1px 9px;flex:none}
.cmpx-chev{color:var(--t3);display:grid;place-items:center;flex:none;transition:transform .26s var(--ease-out)}
.cmpx-repwrap.open .cmpx-chev{transform:rotate(180deg)}
.cmpx-replist{max-height:0;overflow:hidden;transition:max-height .32s var(--ease-out);
  padding:0 4px;border-left:2px solid var(--border-soft);margin-left:4px}
.cmpx-repwrap.open .cmpx-replist{max-height:1400px;padding:8px 4px 4px}
.cmpx-tools{display:flex;justify-content:flex-end;margin-bottom:2px}
/* (rimosso @media column-count:1 — .cmpx-cols ora è grid auto-fit via .troupe-cols) */

/* numero univoco di cast (#ID) nelle liste personaggi */
.pid{font:700 11px 'JetBrains Mono';color:var(--accent-deep);background:var(--accent-soft);border-radius:5px;padding:1px 5px}

/* ════════════════ CAROSELLO FOTO UNICO [[pattern--flowset-carosello-foto]] ════════════════
   3 trigger (card grande / striscia thumb / chip conteggio) + overlay centrato.
   Empty-state = card-colore segnaposto (.pcar-ph). Tutto su token :root. */
.pcar-ph{position:absolute;inset:0;display:flex;align-items:flex-end;padding:14px;background-size:cover;background-position:center}
.pcar-ph::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,transparent 58%,rgba(0,0,0,.5));pointer-events:none}
.pcar-ph-lb{position:relative;z-index:2;color:#fff;font-weight:600;font-size:12px;text-shadow:0 1px 3px rgba(0,0,0,.5)}
.pcar-ph-lb.big{font-size:16px;text-align:center;line-height:1.35}
/* trigger CARD (ODG Cast & Outfit) — stesso linguaggio della vecchia hover-gallery */
.pcar-card{cursor:pointer}
.pcar-card-img{position:relative;aspect-ratio:4/5;border-radius:var(--r);overflow:hidden;border:1px solid var(--border);box-shadow:var(--sh-1);background:var(--s3);transition:transform .16s,box-shadow .16s}
.pcar-card:hover .pcar-card-img{box-shadow:var(--sh-2);transform:translateY(-2px)}
.pcar-card-img>img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.pcar-card-dots{position:absolute;bottom:11px;left:12px;right:12px;display:flex;gap:5px;justify-content:center;z-index:3}
.pcar-card-dots .pcar-d{height:3px;flex:0 1 28px;border-radius:2px;background:rgba(255,255,255,.45)}
.pcar-card-dots .pcar-d.on{background:#fff}
/* trigger STRIP (schede: striscia di thumb) */
.pcar-strip{display:flex;gap:7px;flex-wrap:wrap;align-items:center}
.pcar-thumb{position:relative;width:48px;height:60px;border-radius:9px;overflow:hidden;border:1px solid var(--border);background:var(--s3);cursor:pointer;padding:0;transition:transform .18s cubic-bezier(.2,.8,.2,1),box-shadow .18s,border-color .14s;will-change:transform}
.pcar-thumb:hover{transform:translateY(-3px);border-color:var(--accent-bord);box-shadow:0 7px 16px -7px rgba(91,107,239,.5);z-index:2}   /* sale di qualche px, ombra morbida, sopra le altre — non si taglia (feedback Emanuele) */
.pcar-thumb>img{width:100%;height:100%;object-fit:cover}
.pcar-thumb .pcar-ph{padding:6px}.pcar-thumb .pcar-ph-lb{font-size:9px}
.pcar-more{font:700 12px var(--ff-sans);color:var(--t3);align-self:center}
/* trigger CHIP (card Cambi: conteggio foto) */
.pcar-chip{display:inline-flex;align-items:center;gap:5px;background:var(--s2);border:1px solid var(--border);border-radius:var(--r-pill);padding:3px 10px;font:600 11.5px var(--ff-sans);color:var(--t2);cursor:pointer;transition:all .14s}
.pcar-chip:hover{border-color:var(--accent-bord);color:var(--accent-deep);background:var(--accent-soft)}
.cb-foto{margin-top:9px}
/* LOTTO D (20/07/2026): la card cambio mostra la FOTO (era variant:"chip" = solo icona+numero).
   Override scoped dell'aspect-ratio: il 4/5 di .pcar-card-img (:1930) è tarato sull'anteprima
   ODG e su una card cambio da ~218px darebbe ~272px di foto, raddoppiando l'altezza della card.
   Stesso idioma già in casa: .cont-media .pcar-lead-img (:817) e .tg-grid.tg2 .pcar-lead-img (:2253). */
.cb-foto .pcar-card-img{aspect-ratio:16/10}
/* OVERLAY: preview flottante centrata (hover) / modale fissata (click) / fullscreen (touch) */
.pcar-back{position:fixed;inset:0;z-index:120;display:grid;place-items:center;opacity:0;transition:opacity .18s ease;
  padding:max(24px,env(safe-area-inset-top)) max(24px,env(safe-area-inset-right)) max(24px,env(safe-area-inset-bottom)) max(24px,env(safe-area-inset-left))}
.pcar-back.show{opacity:1}
.pcar-back.preview{background:transparent;pointer-events:none}            /* preview: non blocca la pagina */
.pcar-back.preview .pcar{pointer-events:auto}
.pcar-back.pinned{background:rgba(17,24,39,.5);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}
.pcar{position:relative;width:min(760px,100%);max-height:90dvh;display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--sh-pop);overflow:hidden;transform:translateY(10px);transition:transform .2s cubic-bezier(.2,.8,.2,1)}
.pcar-back.show .pcar{transform:none}
.pcar-stage{position:relative;flex:1;min-height:200px;display:grid;place-items:center;background:#0d0f12;max-height:74dvh;overflow:hidden}
.pcar-full{max-width:100%;max-height:74dvh;object-fit:contain;display:block}
.pcar-full.pcar-ph{position:static;width:100%;height:60dvh;align-items:center;justify-content:center}
.pcar-nav{position:absolute;top:calc(50% - 28px);transform:translateY(-50%);z-index:3;width:42px;height:42px;border-radius:50%;border:0;background:rgba(255,255,255,.92);box-shadow:var(--sh-2);color:var(--t1);display:grid;place-items:center;cursor:pointer;transition:transform .14s,background .14s}
.pcar-nav:hover{background:#fff;transform:translateY(-50%) scale(1.07)}
.pcar-prev{left:12px;transform:translateY(-50%) scaleX(-1)}
.pcar-prev:hover{transform:translateY(-50%) scaleX(-1) scale(1.07)}
.pcar-next{right:12px}
.pcar-x{position:absolute;top:12px;right:12px;z-index:4;width:36px;height:36px;border-radius:50%;border:0;background:rgba(255,255,255,.92);box-shadow:var(--sh-2);color:var(--t1);display:grid;place-items:center;cursor:pointer}
.pcar-x:hover{background:#fff}
.pcar-back.preview .pcar-x{display:none}                                  /* in preview niente X: si chiude all'uscita del mouse */
.pcar-foot{display:flex;align-items:center;gap:12px;padding:11px 16px;border-top:1px solid var(--border);background:var(--surface);min-height:48px}
.pcar-cap{font-size:13px;color:var(--t1);display:flex;align-items:center;gap:9px;min-width:0;flex:1}
.pcar-cap b{font-weight:700}
.pcar-count{font:700 11px 'JetBrains Mono';color:var(--t3);flex-shrink:0}
.pcar-dots{display:flex;gap:6px;align-items:center}
.pcar-dot{width:8px;height:8px;border-radius:50%;border:0;background:var(--border2);cursor:pointer;padding:0;transition:background .14s,transform .14s}
.pcar-dot.on{background:var(--accent);transform:scale(1.2)}
.pcar-add{margin-left:auto}
/* LOTTO B (20/07/2026): visore FULLSCREEN in stato .pinned — gemello .nt-lb (:3181-3191), stesso
   backdrop di prima (.pcar-back.pinned, :1953, invariato). .pcar perde la "card" e va a tutto
   schermo: stesso pattern già in produzione per altri modali fullscreen dentro un grid
   place-items:center (.modal-back .modal.dv-modal, :1567 — width:100% ok in questo contesto,
   ma l'altezza va in dvh e non in % altrimenti resta "auto" nella riga di grid implicita — e
   siccome dvh è assoluto rispetto al viewport e NON al content-box del genitore, il padding
   desktop di .pcar-back (:1949) andrebbe in conflitto con height:100dvh facendo traboccare
   .pcar di 24px sotto il fold, VERIFICATO dal vivo: da qui .pcar-back.pinned{padding:0} sotto,
   che rende .pinned edge-to-edge a QUALSIASI larghezza, non solo ≤720px — la regola mobile
   :1986 diventa ridondante ma resta, invariata).
   .pcar-foot esce dal flusso (posizionamento assoluto) → .pcar-stage resta l'UNICO figlio in-flow
   di .pcar e con flex:1 riempie tutta l'altezza: lo scuro diventa un fondo UNIFORME a tutto
   schermo, esattamente come .nt-lb (niente più "card" con un buco nero dentro accanto a un
   backdrop diverso fuori — QUELLO era il difetto della lezione qui sotto (F3c), non il fatto in
   sé che compaiano margini scuri intorno a una foto non quadrata: .nt-lb, già approvato, li ha
   sempre e nessuno li ha mai letti come bug). */
.pcar-back.pinned{padding:0}
.pcar-back.pinned .pcar{width:100%;max-width:none;height:100dvh;max-height:none;background:transparent;border:0;border-radius:0;box-shadow:none}
.pcar-back.pinned .pcar-stage{max-height:none}
/* Z11a (29/07/2026, appunto di Andrea): la foto RIEMPIE il visore, anche se è piccola.
   Prima qui c'erano SOLO due massimi (max-width:88vw;max-height:82vh): un massimo dice quanto
   una foto può crescere, non quanto DEVE — una 100×100 restava 100×100 in mezzo al nero, e
   nessun cap le è mai stato d'ostacolo. Da qui il box è dato (100% × --pcar-h) e `contain` ci
   adatta dentro l'immagine SCALANDOLA, in su come in giù: almeno una delle due dimensioni tocca
   sempre il bordo. `contain` e non `cover`, e non è una sfumatura: su una foto di continuity il
   ritaglio è perdita di dato — il bottone che manca nell'inquadratura è il motivo per cui la
   foto esiste. Quindi le bande restano possibili sul lato corto, ma non c'è più il caso «foto
   francobollo in mezzo allo schermo» che Andrea ha cerchiato (IMG_1238, frecce sopra e sotto).
   ⚠ Questo ROVESCIA la nota di LOTTO B qui sopra («nessuno li ha mai letti come bug»): i margini
   scuri intorno a una foto non quadrata restano legittimi, ma NON quando nascono dal fatto che
   l'immagine non è stata ingrandita — quello è spazio sprecato, e Andrea lo ha letto come bug.  */
.pcar-back.pinned img.pcar-full{width:100%;height:var(--pcar-h,100dvh);max-width:none;max-height:var(--pcar-h,100dvh);object-fit:contain}
.pcar-back.pinned .pcar-nav{top:50%;width:52px;height:52px}
.pcar-back.pinned .pcar-prev{left:18px}
.pcar-back.pinned .pcar-next{right:18px}
.pcar-back.pinned .pcar-foot{position:absolute;left:0;right:0;bottom:0;z-index:5;border-top:0;background:rgba(0,0,0,.4)}
.pcar-back.pinned .pcar-cap{color:#fff}
.pcar-back.pinned .pcar-count{color:rgba(255,255,255,.65)}
@media(max-width:560px){                 /* stessa soglia del gemello .nt-lb (:3191) */
  .pcar-back.pinned .pcar-nav{width:44px;height:44px}
  .pcar-back.pinned .pcar-prev{left:8px}
  .pcar-back.pinned .pcar-next{right:8px}
}
@media (max-width:720px){
  /* F3c (04/07 BLUEPRINT_FIX_GROVIERA): "place-items:stretch" + .pcar forzato a height:100dvh
     tenevano lo STAGE sempre alto quanto lo schermo anche quando l'immagine (contenuta via
     max-height/object-fit) era molto più bassa (es. panoramica) → bande nere enormi sopra/sotto,
     fino al 69% di spazio sprecato in verticale, misurato dal vivo. Tolto il forzato: .pcar torna ad
     auto-dimensionarsi sul contenuto (stessa regola base di tablet/desktop, .pcar{max-height:90dvh}),
     lo stage riprende il cap .pcar-stage{max-height:74dvh}/.pcar-full{max-height:74dvh} — la card si
     stringe sull'immagine, il backdrop scurito (già fullscreen, .pcar-back.pinned sopra) riempie lo
     spazio restante SENZA sprecarlo in nero. width:100%/niente radius/bordo restano (edge-to-edge
     in larghezza, invariato). Frecce/chiudi restano ancorati a .pcar (invariati); swipe resta legato
     a .pcar-stage (invariato, si limita a seguire il nuovo perimetro reale dell'immagine). */
  .pcar-back.pinned{padding:0}
  .pcar-back.pinned .pcar{width:100%;max-width:100%;border-radius:0;border:0}
  .pcar-full.pcar-ph{height:70dvh}
  /* Z11a: qui .pcar NON è forzato a 100dvh (vedi F3c sopra) — si auto-dimensiona sul contenuto e
     lo stage tiene il suo cap a 74dvh. Se l'immagine chiedesse 100dvh lo stage la taglierebbe
     (overflow:hidden), quindi il box su cui `contain` lavora vale 74dvh anche lui. L'upscale
     resta: cambia il tetto, non il fatto che la foto ci arrivi. */
  .pcar-back.pinned{--pcar-h:74dvh}
}
@media (prefers-reduced-motion:reduce){
  .pcar-back,.pcar,.pcar-nav,.pcar-card-img,.pcar-thumb{transition:none}
  .pcar{transform:none}
}

/* ════════════════ SEGNALIBRO · FOTO MASTER — STELLA (18/07/2026) ════════════════
   Sostituisce la vecchia bandierina Uiverse (Galahhad). Pill di VETRO (leggibilità su foto chiara
   E scura) + stella oro che scatta al click con 5 scintille. Token: oro = --bm-gold (=--c-day),
   dimensione UNICA sitewide = --bm-size. Le animazioni (pop + scintille) partono SOLO col click che
   attiva (classe .animate aggiunta da carousel.js), MAI su hover (regola d'oro anti-hover-liquido).
   Markup carosello: <label class="ui-bookmark[ animate]"><input><span class="bm-shape"><svg .star/>
   ×5 <span class="spark sN"/></span></label>. Origine: sample variante 2 (scelta da Emanuele). */
.pcar-stage .ui-bookmark{position:absolute;top:12px;left:12px;z-index:6}
.ui-bookmark{
  display:inline-flex;align-items:center;justify-content:center;cursor:pointer;
  width:calc(var(--bm-size) + 15px);height:calc(var(--bm-size) + 15px);border-radius:var(--r-pill);
  background:rgba(20,24,34,.30);border:1px solid rgba(255,255,255,.30);
  backdrop-filter:blur(5px) saturate(1.2);-webkit-backdrop-filter:blur(5px) saturate(1.2);
  box-shadow:0 2px 8px rgba(0,0,0,.22);
  transition:background var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out),box-shadow var(--dur-fast) var(--ease-out)}
.ui-bookmark:hover{background:rgba(20,24,34,.42);box-shadow:0 6px 18px rgba(0,0,0,.30)}
.ui-bookmark:active{box-shadow:0 1px 4px rgba(0,0,0,.28)}
.ui-bookmark input{position:absolute;opacity:0;width:0;height:0;pointer-events:none}
.ui-bookmark:has(input:checked){background:rgba(224,162,27,.20);border-color:rgba(224,162,27,.55)}
.ui-bookmark .bm-shape{position:relative;display:flex;align-items:center;justify-content:center;width:var(--bm-size);height:var(--bm-size)}
.ui-bookmark .bm-shape svg{width:100%;height:100%;overflow:visible;display:block;filter:drop-shadow(0 1px 2px rgba(0,0,0,.45))}
.ui-bookmark .star{fill:none;stroke:var(--bm-idle);stroke-width:2.4;stroke-linejoin:round;
  transform-box:fill-box;transform-origin:center;
  transition:fill var(--dur-base) var(--ease-out),stroke var(--dur-base) var(--ease-out)}
.ui-bookmark input:checked + .bm-shape .star{fill:var(--bm-gold);stroke:var(--bm-gold)}
.ui-bookmark.animate input:checked + .bm-shape .star{animation:bm-pop .34s var(--ease-spring)}
@keyframes bm-pop{0%{transform:scale(.55)}55%{transform:scale(1.22)}100%{transform:scale(1)}}
.ui-bookmark .spark{position:absolute;left:50%;top:50%;width:4px;height:4px;border-radius:50%;
  background:var(--bm-gold);transform:translate(-50%,-50%) scale(0);opacity:0;pointer-events:none}
.ui-bookmark.animate input:checked + .bm-shape .spark{animation:bm-spark .42s var(--ease-out) forwards}
.ui-bookmark .s1{--a:-90deg}.ui-bookmark .s2{--a:-18deg}.ui-bookmark .s3{--a:54deg}.ui-bookmark .s4{--a:126deg}.ui-bookmark .s5{--a:198deg}
@keyframes bm-spark{0%{opacity:0;transform:translate(-50%,-50%) rotate(var(--a)) translateY(0) scale(.3)}
  30%{opacity:1}
  100%{opacity:0;transform:translate(-50%,-50%) rotate(var(--a)) translateY(-17px) scale(.9)}}
@media (prefers-reduced-motion:reduce){.ui-bookmark *{animation:none!important}}

/* ════════════════ #1 VETRINA scheda — foto master grande (sx) + dati su grigio (dx) ════════════════
   Primitiva unica riusata da tutte le schede-entità (P15). La foto sale in cima ed è grande;
   clic → carosello unico fullscreen. Tutto su token :root. */
.dv-show{display:grid;grid-template-columns:200px minmax(0,1fr);gap:16px;align-items:start}
.dv-show-data{min-width:0}
.dv-show-acts .btn{flex:1;justify-content:center}
/* POLISH (04/07, BLUEPRINT_POLISH_FOTO_CONTINUITY.md): qFoto ora è .icon-btn (era pillola testo
   "Foto") — OVERLAY in basso a destra sulla foto (non più in flusso sotto: verificato a video che
   in flusso il bottone (qualsiasi altezza, anche solo 36px) protrude sempre oltre il bordo dello
   stage — la foto forza height:100% del proprio contenitore in .fm-stage-photo, niente spazio
   residuo per un fratello sotto — causa la stessa già nota in fm-view.css/margin-bottom:48px, ma
   lì compensata SOLO per il caso scena/tablet; sulle altre schede e su desktop il bottone restava
   comunque coperto/tagliato, verificato con screenshot+elementFromPoint). .dv-show-ph è già
   .tg-tile → position:relative (style.css:1763), nessuna nuova regola di posizionamento serve lì.
   Angolo ALTO-destro (angolo libero post-A8: rimossi gli hint "immagine+conteggio" del carosello; il basso-destro resta ai dots). */
.dv-show-ph{display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:1fr}
.dv-show-ph>*{grid-area:1/1}
/* LOTTO A (20/07/2026, richiesta Emanuele: «disallineato e sborda fuori la foto»). Il comando era
   ancorato in ALTO nella cella della griglia, ma dentro .pcar-lead c'è uno <span class="annot-tag">
   alto 16px PRIMA della foto: il badge partiva 6px SOPRA il bordo superiore dell'immagine (misurato
   dal vivo: badge top 153 vs foto top 159, identico su scheda scena E personaggio) e lo scarto
   CAMBIAVA a seconda che l'annotazione ci fosse o no — di qui l'aria storta. In BASSO invece il
   fondo della cella e quello della foto coincidono (scarto misurato: 1px, il bordo) → ancoraggio
   stabile a prescindere dall'annotazione. A SINISTRA perché il basso-destro è occupato dai dots
   (.pcar-lead-dots, misurati a x 586-719). Vale per tutte e 6 le schede che usano dvShowcase. */
.dv-show-acts{position:static;align-self:end;justify-self:start;margin:10px;z-index:5;display:flex;gap:7px;pointer-events:none}
.dv-show-acts>*{pointer-events:auto}
.dv-show-acts .icon-btn{width:38px;height:38px;border:1px solid rgba(255,255,255,.3);border-radius:var(--r-pill);background:rgba(20,24,34,.42);backdrop-filter:blur(4px);color:#fff;box-shadow:var(--sh-2);position:relative}
.dv-show-acts .icon-btn::before{content:"";position:absolute;inset:-4px;border-radius:inherit}
/* LOTTO A: da tondo con la sola icona a PILLOLA con etichetta — «ha l'icona della fotocamera ma non
   lascia intendere di poter caricare altre foto» (Emanuele). Stessa veste vetro del tondo (regola
   sopra), solo larghezza auto per ospitare il testo. Il testo è quello di carousel.js:147 e del
   moodboard: un comando, un nome solo. Sotto i 420px l'etichetta sparisce e torna il tondo 38px
   (R7: il tocco resta ≥38px, e su schermo stretto la foto non va coperta). */
/* display:inline-flex OBBLIGATORIO: la .icon-btn base (:438) è display:grid+place-items:center →
   con due figli (svg + etichetta) li impilerebbe su DUE righe invece di affiancarli. */
.dv-show-acts .icon-btn.dvph-add{width:auto;min-width:38px;padding:0 13px;gap:7px;font:600 12.5px var(--ff-sans);white-space:nowrap;display:inline-flex;align-items:center;justify-content:center}
.dv-show-acts .dvph-add-lb{line-height:1}
@media (max-width:420px){
  .dv-show-acts .icon-btn.dvph-add{width:38px;padding:0;gap:0}
  .dv-show-acts .dvph-add-lb{display:none}
}
.pcar-lead{cursor:pointer;display:block;position:relative}   /* relative: il segnalibro (.lead-star) ora vive QUI, fuori dall'overflow della foto → animazione non tagliata */
.pcar-lead-img{position:relative;aspect-ratio:3/4;border-radius:var(--r);overflow:hidden;border:1px solid var(--border);
  box-shadow:var(--sh-1);background:var(--s3);transition:transform var(--dur-fast),box-shadow var(--dur-fast)}
.pcar-lead:hover .pcar-lead-img{box-shadow:var(--sh-2);transform:translateY(-2px)}
.pcar-lead-img>img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.pcar-lead-img .pcar-ph{position:absolute;inset:0;display:grid;place-items:center}
.pcar-lead-dots{position:absolute;bottom:11px;right:12px;display:flex;align-items:center;gap:5px;z-index:3}
.pcar-lead-dots .pcar-d{height:3px;width:18px;border-radius:2px;background:rgba(255,255,255,.5);cursor:pointer;position:relative;transition:width .15s ease,background .15s ease}   /* L2 (22/07): trattini cliccabili → scorri le foto nel modale */
.pcar-lead-dots .pcar-d.on{background:#fff}
.pcar-lead-dots .pcar-d.edge{width:8px;background:rgba(255,255,255,.32)}   /* P2 (22/07): bordo della finestra scorrevole → segnala "c'è altro oltre" */
.pcar-lead-dots .pcar-d::before{content:"";position:absolute;inset:-9px -4px}   /* L2: area di tocco ~21px, l'aspetto visivo resta 3px */
.pcar-lead-num{font-size:10px;font-weight:600;line-height:1;color:#fff;background:rgba(0,0,0,.42);padding:2px 5px;border-radius:6px;letter-spacing:.02em;pointer-events:none}   /* P2 (22/07): contatore «k/n» quando le foto superano la finestra (pointer-events:none → non intercetta i click) */
@media (max-width:560px){.dv-show{grid-template-columns:minmax(0,1fr)}.pcar-lead-img{aspect-ratio:4/3}}

/* ════════════════ #2 COLORE della scheda ════════════════
   Tint dell'header del toast al 50% + box-entità colorato OVUNQUE (propagazione P15).
   color-mix → un solo meccanismo per hex, hsl (palette estesa) e colore personalizzato. */
.modal-head.tinted{background:linear-gradient(90deg, color-mix(in srgb,var(--card-col) 50%, transparent), color-mix(in srgb,var(--card-col) 12%, transparent))}
.dv-link.tinted{border-left:4px solid var(--card-col);background:color-mix(in srgb,var(--card-col) 8%, var(--surface))}
.dv-link.tinted:hover{background:color-mix(in srgb,var(--card-col) 16%, var(--surface));border-color:var(--card-col)}
/* pallino colore nel footer della scheda */
.cs-wrap{position:relative;display:inline-flex}
.cs-dot{width:30px;height:30px;border-radius:50%;border:2px solid var(--surface);background:var(--s3);
  box-shadow:0 0 0 1.5px var(--border2),var(--sh-1);cursor:pointer;position:relative;flex:none;overflow:hidden}
.cs-dot.has{background:var(--card-col)}
.cs-dot::after{content:"";position:absolute;inset:0;border-radius:50%;
  background:conic-gradient(from 0deg,#ff5f6d,#ffc371,#47e891,#37c2e8,#5b6bef,#b06bff,#ff5f6d);opacity:0}
.cs-dot:not(.has)::after{opacity:.9}
/* popover palette — si apre verso l'ALTO, dentro il modale (niente clipping) */
.cs-pop{position:fixed;width:220px;background:var(--surface);
  border:1px solid var(--border);border-radius:14px;box-shadow:var(--sh-pop);padding:12px;z-index:var(--z-pop)}   /* fixed + placePop + --z-pop: la palette va SEMPRE in primo piano (Emanuele) */
.cs-pt{font:700 9px var(--ff-sans);letter-spacing:.6px;text-transform:uppercase;color:var(--t3);margin-bottom:9px}
.cs-grid{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:9px}
.cs-sw{aspect-ratio:1;border-radius:50%;border:0;cursor:pointer;padding:0;position:relative;box-shadow:inset 0 0 0 1px rgba(0,0,0,.08)}
.cs-sw.sel{box-shadow:inset 0 0 0 1px rgba(0,0,0,.08),0 0 0 2.5px var(--t1)}
.cs-none{background:var(--surface);box-shadow:inset 0 0 0 1.5px var(--border2)}
.cs-none::after{content:"";position:absolute;left:16%;right:16%;top:calc(50% - 1px);height:2px;background:var(--c-crit);transform:rotate(-45deg);border-radius:2px}
.cs-more{background:conic-gradient(from 0deg,#ff5f6d,#ffc371,#47e891,#37c2e8,#5b6bef,#b06bff,#ff5f6d);color:#fff;display:grid;place-items:center}
.cs-more svg{filter:drop-shadow(0 1px 2px rgba(0,0,0,.55))}
.cs-ext{margin-top:11px;padding-top:10px;border-top:1px solid var(--border)}
.cs-xgrid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:4px}
.cs-x{aspect-ratio:1;border-radius:5px;border:0;cursor:pointer;padding:0;position:relative;box-shadow:inset 0 0 0 1px rgba(0,0,0,.06)}
.cs-x.sel{box-shadow:inset 0 0 0 1px rgba(0,0,0,.06),0 0 0 2px var(--t1)}
.cs-custom{overflow:hidden;display:grid;place-items:center;background:conic-gradient(from 0deg,#ff5f6d,#ffc371,#47e891,#37c2e8,#5b6bef,#b06bff,#ff5f6d)}
.cs-custom input[type=color]{position:absolute;inset:0;opacity:0;width:100%;height:100%;border:0;padding:0;cursor:pointer}
@media (max-width:560px){.cs-pop{width:200px}}

/* ===========================================================================
   TOAST SCHEDA FLOTTANTE (v0.3.8) — la scheda-entità NON è più un pannello solido
   unico: ogni blocco (header, vetrina+dati, collegamenti, stato, azioni) è una
   TESSERA «vetro» (.tg-tile) che galleggia su un backdrop SFOCATO+OSCURATO (bloom).
   Apertura: tessere in stagger (spring). Chiusura: tessere che escono (tgOut).
   Attivato da viewEntity con .tg-float (modal) + .tg-back (backdrop). 1:1 col render
   _wireframes/toast_scheda_v03.html. Su token :root → coerente sui 7 temi.
   =========================================================================== */
/* — BLOOM: oscura+sfoca il sito dietro le tessere (più chiaro al centro, scuro ai bordi) — */
.modal-back.tg-back{background:radial-gradient(135% 110% at 50% 26%, rgba(12,15,26,.34), rgba(8,10,18,.66));
  -webkit-backdrop-filter:blur(15px) saturate(118%);backdrop-filter:blur(15px) saturate(118%);align-items:start;padding-top:max(34px,6vh)}
.modal-back.tg-back.tg-closing{opacity:0}
/* — CONTENITORE: trasparente, è solo il telaio che dispone le tessere; scrolla il body — */
.modal-back .modal.tg-float{background:transparent;border:0;box-shadow:none;overflow:visible;width:min(1080px,96vw);transform:none}
.modal-back.show .modal.tg-float{transform:none}
.modal.tg-float .modal-head{background:transparent;border-bottom:0;padding:0 2px 12px}
.modal.tg-float .mh-tit{display:none}                       /* il titolo lo porta la tessera-header */
.modal.tg-float .mh-actions{margin-left:auto}
/* barra in alto del render: bottoni ‹ › ✕ resi «vetro» flottanti (da destra: ✕, poi frecce) */
.modal.tg-float .mh-actions .icon-btn{width:36px;height:36px;border-radius:var(--r-pill);background:var(--glass-bg);
  -webkit-backdrop-filter:blur(12px) saturate(160%);backdrop-filter:blur(12px) saturate(160%);
  border:1px solid var(--glass-brd);box-shadow:var(--sh-2);color:var(--t1)}
.modal.tg-float .mh-actions .icon-btn:hover:not([disabled]){border-color:var(--accent-bord);color:var(--accent-deep)}
.modal.tg-float .mh-sep{display:none}
.modal.tg-float .modal-body{flex:1;min-height:0;background:transparent;padding:0 4px 6px;overflow:auto}
/* — GRID delle tessere (impilate, header/footer a piena larghezza) — */
.tg-grid{display:flex;flex-direction:column;gap:13px;padding:2px}
/* — TESSERA «vetro»: semi-trasparente + blur + bordo chiaro + glow iris + ombra profonda — */
.tg-tile{position:relative;background:var(--glass-bg);-webkit-backdrop-filter:blur(17px) saturate(165%);
  backdrop-filter:blur(17px) saturate(165%);border:1px solid var(--glass-brd);border-radius:var(--r);
  box-shadow:var(--glow),var(--sh-3);padding:15px 17px}
.tg-grid>.dv-sec{border-top:0;padding-top:15px}                /* dentro la tessera niente separatore extra */
/* header: tessera con badge + nome; tinta col COLORE scheda se presente (--card-col dal .tg-grid) */
.tg-tile.tg-head{display:flex;align-items:center;gap:14px;padding:16px 18px}
.tg-grid.has-col>.tg-head{background:linear-gradient(100deg, color-mix(in srgb,var(--card-col) 42%, var(--glass-bg)), color-mix(in srgb,var(--card-col) 9%, var(--glass-bg)));border-color:color-mix(in srgb,var(--card-col) 30%, var(--glass-brd))}
/* footer azioni flottante (ex .modal-foot): colore a sx · Elimina/Modifica a dx */
.tg-tile.tg-foot{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.tg-foot-lab{font:600 11px var(--ff-sans);color:var(--t3)}
.tg-foot-r{display:flex;gap:9px;margin-left:auto}
/* — APERTURA: ogni tessera entra in stagger con curva spring — */
@keyframes tgIn{from{opacity:0;transform:translateY(22px) scale(.955)}to{opacity:1;transform:none}}
@keyframes tgOut{from{opacity:1;transform:none}to{opacity:0;transform:translateY(12px) scale(.97)}}
@keyframes tgHeadIn{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}
.tg-grid>.tg-tile{opacity:0;animation:tgIn .54s var(--ease-spring) both}
.tg-grid>.tg-tile:nth-child(1){animation-delay:.03s}
.tg-grid>.tg-tile:nth-child(2){animation-delay:.09s}
.tg-grid>.tg-tile:nth-child(3){animation-delay:.15s}
.tg-grid>.tg-tile:nth-child(4){animation-delay:.21s}
.tg-grid>.tg-tile:nth-child(5){animation-delay:.27s}
.tg-grid>.tg-tile:nth-child(6){animation-delay:.33s}
.tg-grid>.tg-tile:nth-child(7){animation-delay:.39s}
.tg-grid>.tg-tile:nth-child(8){animation-delay:.45s}
.tg-grid>.tg-tile:nth-child(n+9){animation-delay:.5s}
.modal.tg-float .modal-head{animation:tgHeadIn .42s var(--ease-out) both}
/* — CHIUSURA: tessere che escono mentre il backdrop sfuma — */
.modal-back.tg-back.tg-closing .tg-tile{animation:tgOut .22s var(--ease-out) forwards}
.modal-back.tg-back.tg-closing .modal-head{opacity:0;transition:opacity .18s}
/* — adattività: su tablet/stretto il toast resta flottante ma quasi a piena larghezza — */
@media (max-width:720px){
  .modal-back.tg-back.dv-back{padding:14px 12px;align-items:start}
  .modal-back .modal.tg-float.dv-modal{width:100%;max-width:100%;height:auto;max-height:94dvh;border-radius:0;transform:none}
  .modal-back.show .modal.tg-float.dv-modal{transform:none}
  .tg-grid{gap:11px}
  .tg-tile{padding:13px 14px}
}
@media (prefers-reduced-motion:reduce){
  .tg-grid>.tg-tile,.modal.tg-float .modal-head{animation:none;opacity:1;transform:none}
  .modal-back.tg-back.tg-closing .tg-tile{animation:none}
}

/* ════════════════════════════════════════════════════════════════════════
   TOAST SCHEDA · COMPATTO — DEFAULT (approvato da Emanuele 22/06, build 0.3.9)
   Attivo via .tg2, che viewEntity aggiunge SEMPRE (promosso da prova A/B: il
   flag __TG2 / localStorage 'flowset_tg2' è stato rimosso).
   Idea: stesse tessere SEPARATE ma dense → sfrutta la larghezza (sezioni corte
   affiancate a 2 colonne), foto più piccola, facts compatti, meno padding/gap →
   una scheda minima (nome + 1 cambio) non costringe più a scrollare.
   I BOX VUOTI sono sempre spinti a destra/in fondo (order + :has(.dv-empty)).
   ════════════════════════════════════════════════════════════════════════ */
.tg-grid.tg2{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:9px;align-items:start}
/* RIQUADRO NEON attorno al toast — come i riquadri della Home (.panel: bordo accent + --glow iris).
   Richiesta Emanuele («inserisci un riquadro neon come quelli sulla home»): le tessere restano
   separate ma ora sono RACCHIUSE in una cornice neon su vetro semitrasparente sul backdrop bloom. */
.modal.tg-float .tg-grid.tg2{
  padding:13px;border:1.5px solid var(--accent);border-radius:var(--r-lg);
  box-shadow:var(--glow),var(--sh-pop);
  background:color-mix(in srgb,var(--surface) 20%, transparent);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}
.tg-grid.tg2.has-col{border-color:color-mix(in srgb,var(--card-col) 55%, var(--accent))}   /* la cornice prende un filo del colore-scheda, se impostato */
.tg-grid.tg2>.tg-head,
.tg-grid.tg2>.dv-show,
.tg-grid.tg2>.tg-foot{grid-column:1 / -1}                 /* header, vetrina e footer a piena larghezza */
/* BOX VUOTI/poco pieni sempre a destra/in fondo: orderTilesByDensity() assegna a ogni .dv-sec uno
   style.order calcolato (piene a SINISTRA, vuote/corte a DESTRA). I valori sotto sono il FALLBACK
   se il JS non gira: piene order 2, vuote order 3, footer sempre ultimo (Emanuele 22/06). */
.tg-grid.tg2>.tg-head{order:0}
.tg-grid.tg2>.dv-show,.tg-grid.tg2>.tg-main{order:1}
.tg-grid.tg2>.dv-sec{order:2}
.tg-grid.tg2>.dv-sec:has(.dv-empty){order:3}              /* sezione vuota → spinta in coda (lato destro) */
.tg-grid.tg2>.tg-foot{order:90}                           /* footer SEMPRE ultimo (oltre gli order JS) */
.tg-grid.tg2>.tg-tile{padding:12px 14px}
.tg-grid.tg2>.dv-sec{padding-top:12px}
.tg-grid.tg2>.tg-head{padding:12px 15px;gap:12px}
.tg-grid.tg2 .dv-title{font-size:17px}
.tg-grid.tg2 .dv-show{grid-template-columns:140px minmax(0,1fr);gap:13px}
.tg-grid.tg2 .pcar-lead-img{aspect-ratio:4/5}             /* foto meno alta → meno aria sprecata */
.tg-grid.tg2 .dv-facts{grid-template-columns:repeat(auto-fill,minmax(min(100%,92px),1fr));gap:6px}
.tg-grid.tg2 .dv-fact{padding:6px 9px;border-radius:9px}
.tg-grid.tg2 .dv-fact .v{font-size:12.5px}
.tg-grid.tg2 .dv-fact .k{font-size:8px}
.tg-grid.tg2 .dv-sec-h{margin-bottom:6px;min-height:24px}
.tg-grid.tg2 .dv-sec-h b{font-size:12.5px}
/* footer v2: tutto in fondo a DESTRA → Elimina · Modifica · Palette */
.tg-foot.tg-foot2{justify-content:flex-end;padding:10px 14px}
.tg-foot2 .tg-foot-r{margin-left:0;align-items:center}
.tg-foot2 .cs-wrap{margin-left:3px}

/* ── 0.3.13 (Emanuele): AZIONI nell'header · foto/dati in 2 tessere · badge = codice # ── */
/* header del toast: titolo a sx, Elimina · Modifica · Palette a DESTRA (ex barra footer, ora rimossa) */
.tg-head-acts{margin-left:auto;display:flex;align-items:center;gap:9px;flex-wrap:wrap;justify-content:flex-end}
.tg-head-acts .btn{padding:8px 13px}
.tg-head-acts .cs-wrap{margin-left:1px}
.dv-idcode{display:inline-grid;place-items:center;min-width:52px;height:52px;padding:0 10px;border-radius:14px;
  background:linear-gradient(135deg,var(--accent),var(--accent-deep));color:#fff;font:800 17px 'JetBrains Mono';letter-spacing:.5px}
.tg-grid.tg2 .dv-idcode{min-width:42px;height:42px;font-size:15px;border-radius:12px}
/* VETRINA: il wrapper .dv-show non è più una tessera; foto e dati sono due tessere SEPARATE */
.dv-show{background:transparent;border:0;box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none;padding:0}
.dv-show-ph.tg-tile{padding:10px}
.tg-grid.tg2 .dv-show-ph.tg-tile{padding:9px}

@media (max-width:720px){
  .tg-grid.tg2{grid-template-columns:minmax(0,1fr);gap:9px}
  .tg-grid.tg2 .dv-show{grid-template-columns:120px minmax(0,1fr)}
  .tg-head-acts .btn span:not([class]){display:none}   /* su mobile solo icone, per non spezzare l'header */
}

/* ════════════════════════════════════════════════════════════════════════
   MOODBOARD / CARTELLE FOTO (feedback Andrea 99f18e91b4) — stile APPROVATO.
   CARD BASE UNIFICATA .fs-card (foto sopra + rettangolo bianco sotto): è IL
   linguaggio card del sito (rastrello). Etichette PIENE, drag&drop touch+PC,
   bolle stile Android con mosaico 2×2. [[flowset--moodboard-cartelle-foto]]
   ════════════════════════════════════════════════════════════════════════ */
.fs-card{position:relative;display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--border);
  border-radius:14px;overflow:hidden;box-shadow:var(--sh-1);transition:transform .16s,box-shadow .16s;touch-action:pan-y}
.fs-card:hover{transform:translateY(-2px);box-shadow:0 12px 26px -14px rgba(91,107,239,.45)}
.fs-photo{aspect-ratio:1;position:relative;background:var(--s3);background-size:cover;background-position:center;display:grid;place-items:center;color:var(--t3);cursor:pointer}
.fs-photo img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.fs-body{padding:9px 11px;background:var(--surface)}              /* RETTANGOLO BIANCO sotto la foto */
.fs-name{font-size:12.5px;font-weight:700;color:var(--t1);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* etichetta PIENA (niente trasparenza) testo bianco in contrasto */
.fs-tag{position:absolute;left:8px;top:8px;z-index:2;font-size:10.5px;font-weight:800;letter-spacing:.2px;padding:4px 9px;
  border-radius:8px;color:#fff;box-shadow:0 2px 7px rgba(0,0,0,.28);text-transform:lowercase}
.fs-tag.continuity{background:var(--c-ok)}
.fs-tag.research{background:var(--c-info)}
.fs-tag.capo{background:var(--c-cost)}
/* TAPPA B (25/07/2026): quarta specie di foto — `mood` (ambiente moodboard, materiale di
   ricerca). Token esistente --c-night, l'unico non già impegnato dalle altre tre etichette. */
.fs-tag.moodboard{background:var(--c-night)}
.fs-card.drag-src{opacity:.4}
.fs-card .fs-mark{position:absolute;right:8px;top:8px;z-index:2;display:grid;place-items:center;width:26px;height:26px;border-radius:50%;color:#fff;background:rgba(0,0,0,.32);box-shadow:0 1px 4px rgba(0,0,0,.4)}
/* M1e (03/07): via .fs-del (✕ elimina dalla card) — l'eliminazione resta SOLO dalla scheda foto aperta
   e dal nuovo tasto "Elimina (N)" in barra (sbloccato dalla selezione, vedi .gal-tools in sections.js) */
/* blocco del drag NATIVO del browser su tutte le superfici Moodboard (no fantasma «salva immagine») */
.fs-card,.fs-photo,.mb-folder,.mb-cover i,.fold-card,.fc-img,.fs-folder,.fsf-cover i,.mb-ghost,.mb-ghost .gimg,.cr-cover i,.msn-item,.msn-item img{-webkit-user-drag:none;user-select:none;-webkit-user-select:none}   /* X3: via .dock-folder/.df-cover i (classi morte, lapide a :2530) — entrano .fs-folder/.fsf-cover i, che sono le copertine VIVE della Galleria e avevano lo stesso identico bisogno */

/* ── Galleria: selezione multipla ── */
.foto-grid.selecting .fs-card{cursor:pointer}
.mb-check{position:absolute;right:8px;top:8px;width:24px;height:24px;border-radius:50%;border:2px solid #fff;
  background:rgba(0,0,0,.25);display:grid;place-items:center;color:#fff;box-shadow:0 1px 4px rgba(0,0,0,.4);
  opacity:0;transform:scale(.8);transition:all .15s;z-index:3}
/* M1e (03/07, punto 2): spunta SEMPRE presente (niente più tasto "Seleziona") — su touch sempre
   visibile, su desktop a comparsa in hover sulla card (mosaico pulito, rifinitura approvata da
   Emanuele in prosa); una card già selezionata resta sempre visibile (.sel), su qualunque device. */
@media (pointer:coarse){ .mb-check{opacity:1;transform:scale(1)} }
@media (hover:hover) and (pointer:fine){ .fs-card:hover .mb-check{opacity:1;transform:scale(1)} }
.fs-card.sel{outline:3px solid var(--accent);outline-offset:-3px}
.fs-card.sel .mb-check{opacity:1;transform:scale(1);background:var(--accent);border-color:#fff}
/* v17 (05/07, BLUEPRINT_C3-FORMDATI.md): maniglia di drag dedicata (Galleria foto/moodboard) —
   SEMPRE visibile su pointer:coarse/mobile (stesso principio di .mb-check sopra), INVISIBILE su
   desktop fine-pointer (lì il drag esistente con soglia TH resta invariato, niente cambio UX).
   Bypassa lpArm/300ms in sections.js (onMbPointerDown/startDrag): il resto della tile mantiene
   il comportamento long-press invariato (tap = apri, hold = trascina, come oggi). */
.gal-drag{display:none;position:absolute;z-index:4;width:30px;height:30px;border:0;border-radius:9px;
  background:rgba(0,0,0,.52);color:#fff;place-items:center;cursor:grab}
@media (pointer:coarse),(max-width:920px){ .gal-drag{display:grid} }
.fs-drag{right:8px;bottom:8px}
.mb-drag{right:8px;top:8px}   /* X3: la copertina della bolla è a filo come .fs-photo → la maniglia si allinea agli 8px di casa (era 16px, misurati sul vecchio padding di 12px). Resta in ALTO a destra e non in basso come .fs-drag: sotto la copertina ora c'è la .fs-body col menu ⋯, e si sovrapporrebbero */
body.mb-dragging .gal-drag{opacity:0;pointer-events:none}

/* ══ TAPPA E (25/07/2026) · DIMENSIONE DELLA GRIGLIA FOTO — solo sui dispositivi TOUCH ══
   Sintomo di Emanuele dal telefono: «le foto escono grandi quasi a schermo e si possono
   scorrere solo verso il basso». Misurato: a 390px la griglia sta a UNA colonna da 330px,
   perché la regola di :1517 (@media pointer:coarse,max-width:920px) rialza il floor a 224px
   e sovrascrive la variante telefono da 176px di :1422.
   ⛔ Quella catena NON si tocca e NESSUNA delle sue tre regole viene modificata: il livello di
   default non ha classe e vale esattamente quanto prima — chi non tocca il tastino non vede
   una virgola di differenza, TABLET COMPRESO (vincolo vitale: non regredire spostamento,
   selezione multipla e scorrimento). Qui si aggiungono SOLO i due livelli ridotti, e vivono
   dove ha senso il dito — pointer:coarse / hover:none, MAI la larghezza dello schermo
   (piano :763-765: il tablet è largo ma è touch, e deve avere tutto).
   Maniglia .gal-drag (30px) e spunta .mb-check (24px) restano INVARIATE a ogni livello:
   proprio dove le card si stringono non si tolgono millimetri al bersaglio del dito. */
.gal-dens{display:none}
@media (pointer:coarse),(hover:none){
  .gal-dens{display:inline-flex}
  .foto-grid.dens-2{grid-template-columns:repeat(auto-fill,minmax(min(100%,150px),1fr));gap:12px}
  .foto-grid.dens-3{grid-template-columns:repeat(auto-fill,minmax(min(100%,104px),1fr));gap:8px}
  .foto-grid.dens-3 .fs-body{padding:6px 7px}
  .foto-grid.dens-3 .fs-name{font-size:11px}
  /* X3: qui c'erano due righe per la bolla (.mb-folder{padding:8px} e
     .mb-folder-name{font-size:12px}). Non servono più: la bolla non ha padding e
     il suo nome È una .fs-name dentro una .fs-body — le due righe sopra la
     coprono già. Meno CSS, e la densità 3 non può più sfasarsi fra card e bolla. */
}
.mb-selbar{position:fixed;left:50%;bottom:22px;transform:translateX(-50%) translateY(160%);opacity:0;pointer-events:none;
  display:flex;align-items:center;gap:12px;background:var(--ink);color:#fff;padding:10px 14px;border-radius:16px;
  box-shadow:0 18px 40px -14px rgba(0,0,0,.5);z-index:60;transition:transform .25s,opacity .25s;font-size:13px;font-weight:600}
.mb-selbar.show{transform:translateX(-50%) translateY(0);opacity:1;pointer-events:auto}
.mb-selbar .sb-n{background:rgba(255,255,255,.18);border-radius:9px;padding:4px 10px}
/* ── X3b (28/07/2026) · I BOTTONI DELLA BARRA VIVONO SU UNA SUPERFICIE SCURA ──────────────
   Difetto segnalato da Emanuele («il popup è tutto bianco»), misurato sul DOM vivo:
     · «Annulla» = .btn-ghost → `background:var(--surface)` = BIANCO PIENO, e sopra una toppa
       inline `color:#fff` → pillola bianca con scritta bianca, invisibile;
     · «Aggiungi a cartella…» = .btn-soft → `background:var(--accent-soft)` e
       `color:var(--accent-deep)`, che nel tema «istituzionale» (l'unico servito, odg.js:44)
       valgono nero all'8% e NERO pieno → testo nero su barra nera.
   Nessuna delle due classi era rotta: sono disegnate per fondi CHIARI e stavano su un fondo
   SCURO (`var(--ink)`). Si rivestono QUI, in uno scope che vale per tutta la barra — così il
   bottone che qualcuno aggiungerà domani nasce già leggibile invece di ereditare la toppa.
   ⚠ Se nasce un'ALTRA superficie scura con dentro dei .btn, non si copiano queste righe: si
   promuove lo scope e ci si aggancia (la lezione delle tre copertine, :2515). */
.mb-selbar .btn-soft{background:rgba(255,255,255,.16);color:#fff}
.mb-selbar .btn-soft:hover{background:rgba(255,255,255,.26)}
.mb-selbar .btn-ghost{background:transparent;border-color:rgba(255,255,255,.3);color:#fff}
.mb-selbar .btn-ghost:hover{background:rgba(255,255,255,.12);border-color:rgba(255,255,255,.55);color:#fff}
.mb-selbar .btn-danger{background:var(--c-crit);color:#fff}          /* lo stesso rosso del modale di conferma */
.mb-selbar .btn-danger:hover{background:#B83B2E;color:#fff}
.mb-selbar .btn[disabled]{opacity:.42;pointer-events:none}

/* ── X3c (28/07/2026) · «Prendi dal moodboard»: le foto già caricate, dentro la cartella ──────
   Griglia di miniature quadrate con la spunta di casa (.mb-check, la STESSA della Galleria: la
   selezione di una foto si fa in un modo solo in tutto il sito). Non riusa .fs-card perché quella
   porta con sé nome, etichetta e il motore di drag della griglia principale, che qui non servono
   e in un modale sarebbero ingombro. Tessere 1:1 come le copertine di X3. */
.mbp-hint{font-size:12px;margin:0 2px 10px}
.mbp-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,104px),1fr));gap:8px}
.mbp-tile{position:relative;aspect-ratio:1;border-radius:12px;overflow:hidden;background-color:var(--s3);
  background-size:cover;background-position:center;cursor:pointer;box-shadow:inset 0 0 0 1px var(--border);
  transition:transform .14s,box-shadow .14s}
.mbp-tile:hover{transform:translateY(-2px);box-shadow:inset 0 0 0 1px var(--border2),var(--sh-2)}
.mbp-tile .mb-check{opacity:1;transform:scale(1);background:rgba(17,24,39,.42);border-color:rgba(255,255,255,.85);color:#fff}
.mbp-tile.sel{box-shadow:inset 0 0 0 3px var(--accent)}
.mbp-tile.sel .mb-check{background:var(--accent);border-color:#fff}
.mb-pick-modal .modal-body{max-height:min(58vh,520px);overflow:auto}

/* ── Moodboard: marcatore "foto già in un moodboard" (visibile col toggle «Mostra quelle nei moodboard») ── */
.fs-card.in-mb .fs-photo{opacity:.8}
.fs-card .fs-inmb{position:absolute;left:8px;top:8px;z-index:3;font-size:9.5px;font-weight:800;letter-spacing:.2px;padding:3px 7px;border-radius:7px;color:#fff;background:var(--accent);box-shadow:0 2px 7px rgba(0,0,0,.22);display:inline-flex;align-items:center;gap:3px;pointer-events:none}

/* ── Moodboard: bolle cartella ─────────────────────────────────────────────────
   X3 (28/07/2026 — mandato di Emanuele: «usa quel token grafico anche nella
   sezione moodboard, così da rendere coerente la grafica su tutte le viste»):
   la bolla prende il TOKEN della cartella-Galleria .fs-folder (:3611) — copertina
   QUADRATA a filo del bordo + rettangolo .fs-body sotto. Prima era rientrata di
   12px, in formato 4/3, raggio var(--r-lg)=22px e con una seconda copertina
   arrotondata dentro la card: due linguaggi-card diversi nella STESSA .foto-grid,
   perché in moodView bolle e foto stanno fianco a fianco (sections.js:4508).
   ⚠ Restano tutte le cose che il moodboard ha in più — è un'ENTITÀ, non un join
   derivato come le cartelle della Galleria: pill «moodboard», maniglia di drag,
   menu ⋯, drop-target, animazione mbReceive, tessera «+N».
   ⚰ Qui viveva .mb-grid, la griglia della vista «Moodboard» sparita il 05/07:
   dalla TAPPA D le bolle vivono nella .foto-grid e NESSUN markup emette più
   quella classe (grep su tutti i .js/.html: zero). Tolta invece di allinearla. */
.mb-folder{position:relative;background:var(--surface);border:1px solid var(--border);border-radius:14px;overflow:hidden;
  cursor:pointer;transition:transform .16s,box-shadow .16s,border-color .16s;box-shadow:var(--sh-1);touch-action:pan-y;user-select:none}
.mb-folder:hover{transform:translateY(-2px);box-shadow:var(--sh-2);border-color:var(--border2)}
.mb-folder.drag-src{opacity:.4}
.mb-folder.drop-tgt{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-soft),0 14px 30px -14px rgba(91,107,239,.6)}
/* copertina a mosaico: stesse identiche regole di .fsf-cover (il modello, :3614),
   più la tessera «+N» che la Galleria non ha (là il conteggio sta nel testo). */
.mb-cover{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);grid-template-rows:1fr 1fr;gap:2px;aspect-ratio:1;background:var(--s3);place-items:stretch}
.mb-cover i{display:block;background-size:cover;background-position:center;position:relative;min-height:0}
.mb-cover i.more{display:grid;place-items:center;color:#fff;font-weight:800;font-size:15px;background:linear-gradient(135deg,rgba(0,0,0,.35),rgba(0,0,0,.55))}
.mb-cover .ph{grid-column:1/-1;grid-row:1/-1;display:grid;place-items:center;color:var(--t3)}

/* ══ X3 · LE TRE COPERTINE A MOSAICO — UNA REGOLA SOLA ═══════════════════════
   Nel sito ci sono tre posti dove 1-4 foto compongono una copertina: la bolla
   moodboard (.mb-cover), la cartella-Galleria (.fsf-cover, :3611) e la riga del
   modale «Aggiungi a…» (.cr-cover, :2600). Prima le varianti n1/n2/n3 erano
   scritte DUE volte con numeri diversi e la terza non le aveva affatto: una foto
   sola riempiva il riquadro in Galleria e restava un francobollo in alto a
   sinistra nel modale. Ora la disposizione sta QUI, in un posto solo, e le tre
   base (sotto e a :2600/:3611) dicono solo quanto sono grandi.
   ⚠ Chi aggiunge una quarta copertina la aggancia a questa riga: se scrive le
   sue n1/n2/n3 a mano, sta ricreando esattamente la divergenza che X3 ha chiuso.
   ⚠ `.chooser-row .cr-cover` e non `.cr-cover`: la regola base della miniatura (:2600) è scritta
   così, e a parità di specificità (0-2-0) avrebbe vinto lei perché sta più in basso nel file —
   la variante n1 sarebbe rimasta senza effetto. Se ne è accorta la guardia z26 (B5: «tessera
   22px su 46px di miniatura»), non io: è il motivo per cui la guardia si scrive PRIMA. */
.mb-cover.n0,.fsf-cover.n0,.chooser-row .cr-cover.n0{display:grid;place-items:center}
.mb-cover.n1,.fsf-cover.n1,.chooser-row .cr-cover.n1{grid-template-columns:minmax(0,1fr);grid-template-rows:1fr}
.mb-cover.n2,.fsf-cover.n2,.chooser-row .cr-cover.n2{grid-template-rows:1fr}
.mb-cover.n3 i:first-child,.fsf-cover.n3 i:first-child,.chooser-row .cr-cover.n3 i:first-child{grid-row:span 2}
/* la riga sotto la copertina È la .fs-body del sito (padding e fondo da :2397),
   con dentro .fs-name e .fsf-n come la cartella-Galleria: qui in più il menu ⋯. */
.mb-folder .fs-body{display:flex;align-items:center;gap:8px}
.mb-folder-txt{min-width:0;flex:1}
.mb-folder-menu{flex:0 0 auto;width:30px;height:30px;margin-right:-5px;border-radius:9px;border:0;background:transparent;color:var(--t3);display:grid;place-items:center;cursor:pointer;transition:all .14s}
.mb-folder-menu:hover{background:var(--s2);color:var(--t1)}
.mb-new{display:grid;place-items:center;gap:8px;background:transparent;border:2px dashed var(--border2);border-radius:14px;
  min-height:170px;color:var(--t3);cursor:pointer;font-weight:700;font-size:13px;transition:all .16s;text-align:center}
.mb-new:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}

/* animazione: la cartella ACCOGLIE le nuove foto */
@keyframes mbReceive{0%{transform:scale(1)}30%{transform:scale(1.07)}55%{transform:scale(.975)}100%{transform:scale(1)}}
.mb-receive{animation:mbReceive .55s cubic-bezier(.2,.8,.2,1)}
/* X3: l'anello dell'accoglienza diventa INSET — la copertina ora è a filo del bordo
   e l'overflow:hidden della card mangerebbe un'ombra esterna su tre lati.
   Via il ramo .dock-folder .df-cover: quel dock non esiste più (vedi lapide sotto). */
.mb-receive .mb-cover{box-shadow:inset 0 0 0 2px var(--accent);transition:box-shadow .25s}
.mb-fly{position:fixed;left:0;top:0;z-index:9998;width:90px;aspect-ratio:1;border-radius:13px;background-size:cover;background-position:center;
  pointer-events:none;box-shadow:0 16px 34px -8px rgba(0,0,0,.5);transition:transform .5s cubic-bezier(.5,0,.35,1),opacity .5s}
.mb-fly img{width:100%;height:100%;object-fit:cover;border-radius:13px}

/* menu cartella */
.mb-pop{position:fixed;z-index:var(--z-pop,9000);background:var(--surface);border:1px solid var(--border);border-radius:12px;box-shadow:var(--sh-pop);padding:6px;min-width:160px;display:none}
.mb-pop.show{display:block}
.mb-pop button{display:flex;align-items:center;gap:9px;width:100%;border:0;background:transparent;color:var(--t1);font-size:13px;font-weight:600;padding:9px 11px;border-radius:8px;cursor:pointer;text-align:left}
.mb-pop button:hover{background:var(--s2)}
.mb-pop button.danger{color:var(--c-crit)}
.mb-pop button.danger:hover{background:var(--c-crit-bg)}

/* ⚰ X3 (28/07/2026) — QUI VIVEVA IL DOCK delle cartelle (.mb-dock, .dock-folder,
   .df-cover, .df-name, .dock-lab: 14 regole), la barra che saliva dal fondo durante
   il drag di una foto. Il nodo #mbDock è stato rimosso alla TAPPA D, e da allora
   NESSUN .js emette più quelle classi — verificato con grep su tutti i .js/.html
   (unica occorrenza di "mb-dock": il commento di sections.js:7274 che ne annuncia
   la morte). Il piano di X3 me le dava fra le QUATTRO copertine a mosaico da
   allineare: le copertine vive sono TRE — .mb-cover, .cr-cover e il modello
   .fsf-cover. Una regola che nessun elemento può mai incontrare non si allinea:
   si toglie, altrimenti al prossimo censimento qualcuno la ritrova e la "ripara".
   Bersaglio del drop oggi: le bolle stesse nella griglia + la tile .mb-new. */

/* ghost di trascinamento COMPLETO (foto + riga nome) */
.mb-ghost{position:fixed;z-index:9999;pointer-events:none;width:140px;border-radius:14px;overflow:hidden;background:var(--surface);
  border:1px solid var(--border);box-shadow:0 22px 44px -10px rgba(0,0,0,.55);opacity:.96;transform:translate(-50%,-50%) rotate(-3deg)}
.mb-ghost .gimg{aspect-ratio:1;background-size:cover;background-position:center}
.mb-ghost .gimg img{width:100%;height:100%;object-fit:cover;display:block}
.mb-ghost .gname{padding:7px 10px;font-size:12px;font-weight:700;color:var(--t1);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mb-ghost .gcount{position:absolute;right:-6px;top:-6px;background:var(--accent);color:#fff;font-weight:800;font-size:12px;min-width:24px;height:24px;border-radius:50%;display:grid;place-items:center;box-shadow:0 2px 8px rgba(0,0,0,.4)}

/* contenuto cartella (toast/modale) */
.fold-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:12px}
.fold-card{position:relative;border:1px solid var(--border);border-radius:12px;overflow:hidden;background:var(--surface);touch-action:pan-y}
.fold-card .fc-img{aspect-ratio:1;background:var(--s3);background-size:cover;background-position:center}
.fold-card .fc-img img{width:100%;height:100%;object-fit:cover;display:block}
.fold-card .fc-x{position:absolute;right:6px;top:6px;z-index:2}
.fold-card .fc-handle{position:absolute;left:6px;top:6px;z-index:2;width:26px;height:26px;border-radius:8px;background:rgba(0,0,0,.45);color:#fff;display:grid;place-items:center;cursor:grab}
.fold-card.drag-src{opacity:.4}
.fold-card.drop-tgt{outline:2px dashed var(--accent);outline-offset:-2px}

/* ════════════════════════════════════════════════════════════════════════
   M1c — MOSAICO STUDIOBINDER dentro una bolla (innesto dal sample APPROVATO
   _wireframes/moodboard_v05_studiobinder.html): grid dense + span dal
   rapporto d'aspetto reale (naturalWidth/Height) + taglie miste s/l (⤢,
   FLIP) + drag long-press (riusa lpArm/lpMove/lpClear di sections.js) + tap
   sulla foto = carosello UNICO (Carousel + Store.fotoFor("moodboard",fid)).
   Sostituisce .fold-grid/.fold-card qui sopra (lasciate, ora inerti).
   ════════════════════════════════════════════════════════════════════════ */
.msn-tools{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-bottom:16px}
.msn-tools .muted{flex:1;min-width:200px;font-size:12px}
.msn-grid{display:grid;grid-template-columns:repeat(var(--msn-cols,3),minmax(0,1fr));grid-auto-rows:8px;grid-auto-flow:row dense;gap:12px}
.msn-item{position:relative;border-radius:var(--r-sm);overflow:hidden;background:var(--s3);cursor:pointer;touch-action:pan-y;user-select:none}
.msn-item .msn-img,.msn-item .msn-noimg{width:100%;height:100%;object-fit:cover;display:block}
.msn-item .msn-noimg{display:grid;place-items:center;color:var(--t3);background:var(--s3)}
.msn-overlay{position:absolute;left:0;right:0;bottom:0;padding:9px 10px 8px;
  background:linear-gradient(to top,rgba(10,12,16,.66),rgba(10,12,16,0) 85%);
  display:flex;align-items:flex-end;justify-content:space-between;gap:8px;opacity:0;transition:opacity .16s var(--ease-out);pointer-events:none}
@media (hover:hover) and (pointer:fine){ .msn-item:hover .msn-overlay{opacity:1;pointer-events:auto} }
.msn-name{color:#fff;font-size:11.5px;font-weight:700;text-shadow:0 1px 3px rgba(0,0,0,.55);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;cursor:pointer}
.msn-size-badge{position:absolute;left:8px;top:8px;z-index:2;font:700 9.5px var(--ff-mono);letter-spacing:.3px;color:#fff;
  background:rgba(0,0,0,.4);padding:3px 7px;border-radius:7px;pointer-events:none;opacity:.85;text-transform:lowercase}
.msn-x{position:absolute;right:8px;top:8px;z-index:3;width:34px;height:34px;border:1px solid rgba(255,255,255,.3);border-radius:var(--r-pill);
  background:rgba(20,24,34,.46);backdrop-filter:blur(4px);color:#fff;display:grid;place-items:center;transition:background .14s}
.msn-x::before{content:"";position:absolute;inset:-5px;border-radius:inherit}
.msn-x:hover{background:rgba(20,24,34,.72)}
/* v17 (05/07, BLUEPRINT_C3-FORMDATI.md): maniglia di drag dedicata (mosaico-in-cartella) — stesso
   principio di .gal-drag sopra: SEMPRE visibile su pointer:coarse/mobile, invisibile su desktop
   fine-pointer. Bypassa lpArm/300ms in msnPointerDown (sections.js) SENZA toccare il guard F3a
   (L3: ⤢ eliminato; la ✕ .msn-x resta esclusa dall'armo del drag). */
.msn-drag{display:none;position:absolute;left:8px;bottom:8px;z-index:3;width:30px;height:30px;border:0;
  border-radius:9px;background:rgba(0,0,0,.52);color:#fff;place-items:center;cursor:grab}
@media (pointer:coarse),(max-width:920px){
  .msn-overlay{display:none}
  .msn-drag{display:grid}
}
body.msn-dragging .msn-drag{opacity:0}
/* F3b aggiornato L3 (19/07): a ≤480px le tile sono strette (2 colonne) — la ✕ .msn-x si riduce
   e si riavvicina allo spigolo per lasciare aria al badge categoria (left:8/top:8); il ::before
   allargato tiene il tap a 44px. */
@media (max-width:480px){
  .msn-x{width:30px;height:30px;top:6px;right:6px}
  .msn-x::before{inset:-7px}
}
body.msn-dragging .msn-x{opacity:0}
body.msn-dragging .msn-item:hover .msn-overlay{opacity:0}
body.msn-dragging{cursor:grabbing}
.msn-ph{border-radius:var(--r-sm);border:2px dashed var(--accent-bord);background:var(--accent-mute);
  box-shadow:inset 0 0 0 2px rgba(255,255,255,.55)}
:root[data-theme="dark"] .msn-ph{box-shadow:inset 0 0 0 2px rgba(255,255,255,.12)}
.msn-lift{position:fixed;z-index:9999;pointer-events:none;border-radius:var(--r-sm);overflow:hidden;
  box-shadow:0 26px 50px -12px rgba(17,24,39,.5);transform:scale(1.035) rotate(1.1deg);cursor:grabbing}
.msn-lift img,.msn-lift .msn-noimg{width:100%;height:100%;object-fit:cover;display:block}
.msn-landing{transition:left .22s var(--ease-out),top .22s var(--ease-out),width .22s var(--ease-out),height .22s var(--ease-out),transform .22s var(--ease-out);transform:scale(1) rotate(0)}
.name-edit{font:inherit;font-size:16px;font-weight:800;color:var(--t1);border:0;border-bottom:2px solid var(--accent);background:transparent;outline:none;padding:2px 0;max-width:60vw}
.empty-mini{text-align:center;color:var(--t3);padding:30px 10px;font-size:13px}
.chooser-list{display:flex;flex-direction:column;gap:8px;max-height:50vh;overflow:auto}
.chooser-row{display:flex;align-items:center;gap:12px;padding:10px 12px;border:1px solid var(--border);border-radius:12px;cursor:pointer;transition:all .14s}
.chooser-row:hover{border-color:var(--accent);background:var(--accent-soft)}
/* X3: la terza copertina a mosaico prende gap e fondo delle altre due (gap 1px→2px,
   --s2→--s3) e le varianti n1/n2/n3 dalla regola condivisa (:2482): con una foto sola
   la miniatura ora si riempie invece di lasciare tre quarti di riquadro vuoto.
   Il raggio resta 10px e non 14: è una miniatura di 46px in una riga di elenco,
   non una card della griglia — il token di casa è la DISPOSIZIONE, non il numero. */
.chooser-row .cr-cover{width:46px;height:46px;border-radius:10px;overflow:hidden;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);grid-template-rows:1fr 1fr;gap:2px;background:var(--s3);place-items:stretch;flex:0 0 auto}
.chooser-row .cr-cover i{display:block;background-size:cover;background-position:center;min-height:0}
.chooser-row .cr-cover .ph{grid-column:1/-1;grid-row:1/-1;display:grid;place-items:center;color:var(--t3)}
.chooser-row .cr-cover i img{width:100%;height:100%;object-fit:cover}
.chooser-row .cr-txt b{display:block;font-size:13.5px;color:var(--t1)}
.chooser-row .cr-txt span{font-size:11.5px;color:var(--t3)}

/* RASTRELLO Cambi: la card info-attore usa .fs-card (foto attore 4/5 + info nel rettangolo) */
.cbx-pers.fs-card{padding:0}
.cbx-pers.fs-card .fs-photo{aspect-ratio:4/5}
.cbx-pers .badge-id{display:inline-grid;place-items:center;min-width:30px;height:24px;padding:0 7px;border-radius:8px;background:var(--accent);color:#fff;font-weight:800;font-size:12px}
.cbx-pers .pp-sub{font-size:11.5px;color:var(--t3);margin-top:2px}
.cbx-pers .pp-cnt{font-size:11.5px;color:var(--t2);font-weight:600;margin-top:8px}
.cbx-pers.fs-card .fs-body{display:flex;flex-direction:column;gap:2px}
/* CAMBI_SCROLL_FILTRI (04/07, BLUEPRINT_CAMBI_SCROLL_FILTRI.md): "+" overlay sulla card-foto
   dell'attore (Emanuele: aggiungere un cambio riconoscendo la persona dalla foto, non da un
   menu a tendina) — riusa data-quick="cambi|pers:<nome>" (stesso dispatcher generico di .cb-add,
   zero nuova logica). Sibling di .fs-photo (NON figlio: .fs-photo ha già data-view="personaggi:…"
   sull'intera area — se il bottone fosse annidato lì dentro, t.closest("[data-view]") lo
   intercetterebbe PRIMA di data-quick nel dispatcher di onClick, aprendo la scheda personaggio
   invece del form cambio). .cbx-pers è position:sticky → containing block valido per l'assoluto. */
.cbx-addcb{position:absolute;top:8px;right:8px;z-index:3;background:var(--accent);color:#fff;border-color:var(--accent);box-shadow:var(--sh-2)}
.cbx-addcb:hover{background:var(--accent-deep);border-color:var(--accent-deep)}

/* ════════════════════════════════════════════════════════════════════════
   MOODBOARD v04 — bolle DENTRO la Galleria (in cima) + DRAG SORTABLE:
   la card reale si solleva e segue il dito, il suo posto si richiude (FLIP),
   auto-scroll ai bordi. [[flowset--moodboard-cartelle-foto]]
   ════════════════════════════════════════════════════════════════════════ */
.foto-grid{align-items:start}                       /* bolle e foto convivono nella stessa griglia, niente stretch */
.mb-folder .mb-pill{position:absolute;left:8px;top:8px;z-index:2;font-size:10px;font-weight:800;letter-spacing:.2px;   /* X3: 16→8px, stessa origine di .fs-tag sulle foto accanto (:2400) */
  padding:3px 8px;border-radius:7px;color:#fff;background:var(--accent);box-shadow:0 2px 7px rgba(0,0,0,.22);text-transform:lowercase}
/* card sollevata: position:fixed, segue il dito */
.fs-card.mb-lift,.mb-folder.mb-lift{position:fixed!important;margin:0!important;z-index:9999;pointer-events:none;cursor:grabbing;
  box-shadow:0 26px 50px -12px rgba(17,24,39,.45);transform:scale(1.04) rotate(1.5deg);transition:box-shadow .15s}
/* atterraggio morbido sullo slot finale */
.fs-card.mb-landing,.mb-folder.mb-landing{transition:left .2s cubic-bezier(.2,.8,.2,1),top .2s cubic-bezier(.2,.8,.2,1),width .2s,height .2s,transform .2s;transform:scale(1) rotate(0)}
/* segnaposto: il "buco" dove cadrà la card */
.mb-ph{border:2px dashed var(--accent-bord);background:var(--accent-mute);border-radius:14px;box-shadow:inset 0 0 0 2px rgba(255,255,255,.55)}
.mb-ph.folder{border-radius:14px}   /* X3: era 20px, misurato sul vecchio raggio della bolla; ora bolla e card hanno lo stesso raggio. ⚠ Regola INERTE oggi: nessun .js crea più un .mb-ph (il motore B usa applyGap+FLIP, non un segnaposto) — allineata, non finta: se il segnaposto tornasse, tornerebbe già giusto */
/* badge "N selezionate" sulla card trascinata */
.mb-lift-count{position:absolute;top:-8px;right:-8px;min-width:24px;height:24px;padding:0 6px;border-radius:12px;background:var(--accent);
  color:#fff;font-weight:800;font-size:12px;display:grid;place-items:center;box-shadow:0 4px 12px -3px var(--accent);z-index:5}
body.mb-dragging{cursor:grabbing}
body.mb-dragging .fs-card:hover,body.mb-dragging .mb-folder:hover{transform:none;box-shadow:var(--sh-1)}

/* ===== v0.5 SIDEBAR «PULSANTONI» — port 1:1 da v0.4 css/05-flow.css §① — SOLO sidebar, NIENTE transform/.flow-* (era il bug click-disallineati) ===== */
.sidebar{ background:transparent; border:0; box-shadow:none; border-radius:0; padding:6px 4px 12px; }
.side-top{ border-bottom:0; margin-bottom:14px; padding:4px 8px 2px; }
.side-col{ width:264px; }
.side-nav{ gap:6px; }
.nav-cap{ font-size:10px; letter-spacing:.14em; color:var(--t3); padding:16px 14px 6px; opacity:.65; }
.nav-sep{ display:none; }
.nav-item{ gap:16px; padding:15px 16px; font-size:16px; font-weight:600; border-radius:16px; letter-spacing:-.01em; color:var(--t1); }
.nav-item .lbl{ font-size:16px; }
.nav-item .ico{ width:30px; height:30px; line-height:1; }
.nav-item .ico svg.ic{ width:24px; height:24px; }   /* glyph 18->24 senza toccare app.js (CSS batte width/height dell'SVG) */
.nav-item:hover{ background:var(--s2); }
.nav-item.active{ background:var(--accent); color:#fff; border-radius:16px; box-shadow:none; }
.nav-item.active .ico{ color:#fff; }
.app.collapsed .side-col{ width:86px; }
.app.collapsed .nav-item{ width:52px; height:52px; border-radius:16px; }
.app.collapsed .nav-item .ico{ width:30px; height:30px; }
/* ===== fine blocco sidebar pulsantoni ===== */

/* ===== v0.5 HOME4 — armonizza i pannelli LEGACY (Cast & Crowd del giorno + Note/Sicurezza)
   col look card 4.0. SCOPED su .h4-legacy → tocca SOLO la home4, non i gemelli .panel/.pg-*
   del Compiler/altre viste. Prefisso .h4-wrap per battere il tema istituzionale (style.css §192-195). ===== */
/* guscio = card 4.0: superficie pulita, bordo soft, raggio grande, niente alone/ombra/barra accento */
.h4-wrap .h4-legacy .panel{ background:var(--surface); border:1px solid var(--border-soft); box-shadow:none; border-radius:var(--r-lg); margin:0; overflow:hidden; }
.h4-wrap .h4-legacy .pg-panel{ border:1px solid var(--border-soft); box-shadow:none; }
.h4-wrap .h4-legacy .panel.pad{ padding:22px; }
/* header come i titoli delle card reparto: niente divisoria, niente barretta accento, titolo 800 */
.h4-wrap .h4-legacy .panel-head{ border-bottom:0; padding:20px 22px 4px; }
.h4-wrap .h4-legacy .panel-head h3{ font-size:var(--fs-md); font-weight:800; letter-spacing:-.01em; }
.h4-wrap .h4-legacy .panel-head .accent{ display:none; }
.h4-wrap .h4-legacy .panel-body{ padding:14px 22px 20px; }
/* intestazioni colonna + conteggio: pill accent-soft (come i .h4-*) invece del badge scuro */
.h4-wrap .h4-legacy .pg-chead{ font-size:var(--fs-md); border-bottom:1px solid var(--border-soft); padding-bottom:10px; margin-bottom:12px; }
.h4-wrap .h4-legacy .pg-cnt{ background:var(--accent-soft); color:var(--accent); }
/* righe cast/crowd: da "chip pieno su --s2" a riga pulita con hairline, come .h4-rep-crow */
.h4-wrap .h4-legacy .pg-person{ background:transparent; border:0; border-bottom:1px solid var(--border-soft); border-radius:0; margin:0; padding:11px 2px; }
.h4-wrap .h4-legacy .pg-col .pg-person:last-child{ border-bottom:0; }
/* ===== fine blocco home4 legacy ===== */

/* ===== v0.5 RETTIFICA 1 — FONT SELF-HOSTED (parita con 4.0 css/00-fonts.css; offline-safe, no dipendenza CDN).
   Path = fonts/ (style.css sta in web/). P6 (27/07/2026): non sono più un doppione dell'@import Google —
   sono l'UNICA sorgente dei font, l'@import in cima al file è stato rimosso. Tutti subset `latin` di
   Google Fonts, scaricati una volta (accentate italiane comprese). Aggiungere un peso = scaricare il
   .woff2 in fonts/ e aggiungere la riga qui; MAI riaprire una strada verso la CDN. ===== */
@font-face{font-family:"Inter";font-style:normal;font-weight:400;font-display:swap;src:url("fonts/inter-400.woff2") format("woff2")}
/* P6: il 500 arrivava da Google ed era l'unico peso non self-hosted — 17 usi nel file (`font:500 …`,
   `font-weight:500`). Senza, il browser lo avrebbe finto ispessendo il 400: testo leggermente diverso. */
@font-face{font-family:"Inter";font-style:normal;font-weight:500;font-display:swap;src:url("fonts/inter-500.woff2") format("woff2")}
@font-face{font-family:"Inter";font-style:normal;font-weight:600;font-display:swap;src:url("fonts/inter-600.woff2") format("woff2")}
@font-face{font-family:"Inter";font-style:normal;font-weight:700;font-display:swap;src:url("fonts/inter-700.woff2") format("woff2")}
@font-face{font-family:"Inter";font-style:normal;font-weight:800;font-display:swap;src:url("fonts/inter-800.woff2") format("woff2")}
@font-face{font-family:"JetBrains Mono";font-style:normal;font-weight:400;font-display:swap;src:url("fonts/jetbrains-mono-400.woff2") format("woff2")}
@font-face{font-family:"JetBrains Mono";font-style:normal;font-weight:600;font-display:swap;src:url("fonts/jetbrains-mono-600.woff2") format("woff2")}
@font-face{font-family:"DM Serif Display";font-style:normal;font-weight:400;font-display:swap;src:url("fonts/dm-serif-display-400.woff2") format("woff2")}
@font-face{font-family:"DM Serif Display";font-style:italic;font-weight:400;font-display:swap;src:url("fonts/dm-serif-display-400-italic.woff2") format("woff2")}
@font-face{font-family:"Plus Jakarta Sans";font-style:normal;font-weight:200 800;font-display:swap;src:url("fonts/plus-jakarta-sans.woff2") format("woff2")}
/* ===== fine font self-hosted ===== */

/* ===== v0.5 RETTIFICA 3a — HOVER righe-conteggio cliccabili (Carico del giorno + Carico costumi).
   Le righe .h4-nrow.h4-lk cambiavano solo colore-testo → non si capiva fossero cliccabili. Ora highlight
   pieno della riga. Scoped .h4-wrap .h4-panel → non tocca i gemelli .h4-legacy/.pg-*; specificita (0,5,0)
   batte l'injectCSS di home4 senza !important. Padding+margin costanti → niente layout-shift. Revert = cancella. ===== */
.h4-wrap .h4-panel .h4-nrow.h4-lk{ margin:0 -10px; padding-left:10px; padding-right:10px; border-radius:var(--r-sm,12px); transition:background var(--dur-fast,.16s) var(--ease,cubic-bezier(.19,1,.22,1)),color var(--dur-fast,.16s) var(--ease,cubic-bezier(.19,1,.22,1)); }
.h4-wrap .h4-panel .h4-nrow.h4-lk:hover{ background:var(--accent-soft); }
/* ===== fine rettifica 3a hover ===== */
/* ===== PREMIUM tab Foto (05/07, richiesta Emanuele — lavoro Fable in prima persona) =====
   1) tile "Nuovo Moodboard" DINAMICA: nascosta a riposo, appare (FLIP + pop) solo durante un drag
      di foto (.foto-grid.mb-dragfoto, vedi liftCard in sections.js);
   2) stack multi-foto: ghost di coda che inseguono il puntatore con durate diverse (coda elastica);
   3) ritorno animato al rilascio a vuoto (.mb-flyback). Revert = cancella il blocco. */
.foto-grid .mb-folder.mb-new{display:none}
.foto-grid.mb-dragfoto .mb-folder.mb-new{display:grid;border-color:var(--accent);color:var(--accent);background:var(--accent-soft);
  animation:mbTileIn .24s cubic-bezier(.2,.8,.2,1)}
@keyframes mbTileIn{from{opacity:0;transform:scale(.84)}to{opacity:1;transform:scale(1)}}
.mb-stack-ghost{position:fixed;left:0;top:0;z-index:9998;border-radius:16px;background-size:cover;background-position:center;
  background-color:var(--s2);pointer-events:none;box-shadow:0 18px 38px -10px rgba(17,24,39,.42)}
.mb-stack-ghost.g1{transform:rotate(-5deg) scale(.96);transition:left .28s cubic-bezier(.2,.8,.2,1),top .28s cubic-bezier(.2,.8,.2,1)}
.mb-stack-ghost.g2{transform:rotate(4.5deg) scale(.92);transition:left .40s cubic-bezier(.2,.8,.2,1),top .40s cubic-bezier(.2,.8,.2,1)}
.mb-flyback{transition:left .42s cubic-bezier(.25,.8,.3,1),top .42s cubic-bezier(.25,.8,.3,1),width .42s cubic-bezier(.25,.8,.3,1),
  height .42s cubic-bezier(.25,.8,.3,1),transform .42s cubic-bezier(.25,.8,.3,1),opacity .42s cubic-bezier(.25,.8,.3,1)!important}
/* la barra "N selezionate" si scansa durante il drag (il puntatore lavora in basso) */
body.mb-dragging .mb-selbar{opacity:0;pointer-events:none;transform:translateX(-50%) translateY(160%)}

/* ═══ SX-MEGA (ricerca_3, attivato 06/07) ═══
   Ricerca globale: mega-panel a due colonne (.sx-mega > .sx-idx + .sx-res) al posto
   della lista piatta. Base .search-results/.sr-item/.sr-head/.sr-empty/mark INVARIATA
   (righe ~1188-1199): qui solo override (stessa specificità, vince per ordine sorgente)
   + classi nuove .sx-*, prefissate come da sample. */
/* mappa colore-per-categoria: solo token esistenti; 8 categorie reali (searchAll) contro
   le 6 del sample demo — WrapBox e Troupe (ODG) in più, colori scelti fra i token già in uso */
[data-cat="Scene"]{--cat-c:var(--c-info);--cat-bg:var(--c-info-bg)}
[data-cat="Personaggi"]{--cat-c:var(--accent);--cat-bg:var(--accent-mute)}
[data-cat="Attori"]{--cat-c:var(--c-golden);--cat-bg:color-mix(in srgb,var(--c-golden) 14%,transparent)}
[data-cat="Cambi"]{--cat-c:var(--c-warn);--cat-bg:var(--c-warn-bg)}
[data-cat="Inventario"]{--cat-c:var(--c-cost);--cat-bg:var(--c-cost-bg)}
[data-cat="Foto"]{--cat-c:var(--c-dawn);--cat-bg:color-mix(in srgb,var(--c-dawn) 14%,transparent)}
[data-cat="WrapBox"]{--cat-c:var(--c-day);--cat-bg:color-mix(in srgb,var(--c-day) 14%,transparent)}
[data-cat="Troupe (ODG)"]{--cat-c:var(--c-night);--cat-bg:color-mix(in srgb,var(--c-night) 14%,transparent)}

.search-results{width:min(760px,92vw);right:auto;padding:0;overflow:hidden;
  display:flex;flex-direction:column;max-height:70vh}
/* il display:flex qui sopra vincerebbe sull'attributo hidden usato da closeSearch() */
.search-results[hidden]{display:none}
.sx-mega{display:flex;min-height:0;flex:1;overflow:hidden}
.sx-idx{flex:0 0 196px;border-right:1px solid var(--border-soft);padding:8px;overflow-y:auto;background:var(--s2)}
.sx-idx-item{display:flex;align-items:center;gap:8px;width:100%;text-align:left;border:0;background:transparent;
  color:var(--t2);font:700 12px var(--ff-sans);padding:9px 10px;border-radius:9px;cursor:pointer;
  margin-bottom:2px;transition:all var(--dur-fast) var(--ease-out)}
.sx-idx-item .sx-ic{display:inline-flex;color:var(--cat-c,var(--t3))}
.sx-idx-item b{margin-left:auto;font-weight:800;color:var(--t3);font-size:11px}
.sx-idx-item:hover{background:var(--surface);color:var(--t1)}
.sx-idx-item.on{background:var(--surface);color:var(--t1);box-shadow:var(--sh-1)}
.sx-idx-item.on b{color:var(--cat-c,var(--accent))}
.sx-idx-item[disabled]{opacity:.38;cursor:default}
.sx-res{flex:1;min-width:0;overflow-y:auto;padding:10px}
.sx-sec{margin-bottom:10px}
.sx-sec-head{display:flex;align-items:center;gap:7px;font:800 10.5px var(--ff-sans);letter-spacing:.4px;
  text-transform:uppercase;color:var(--cat-c);padding:6px 8px;cursor:pointer;border-radius:8px}
.sx-sec-head:hover{background:var(--s2)}
.sx-sec-head .sx-gn{margin-left:auto;background:var(--cat-bg);color:var(--cat-c);border-radius:var(--r-pill);
  padding:1px 8px;font-size:10px}
.sx-sec-head.sx-more{color:var(--accent-deep);text-transform:none;font-weight:700;letter-spacing:0}
.sx-back{display:inline-flex;align-items:center;gap:5px;border:0;background:transparent;color:var(--accent-deep);
  font:700 12px var(--ff-sans);padding:6px 8px;cursor:pointer;margin-bottom:6px;border-radius:8px}
.sx-back:hover{background:var(--s2)}
.sx-back svg{transform:rotate(180deg)}
@media (max-width:560px){
  .search-results{width:min(360px,88vw)}
  .sx-mega{flex-direction:column}
  .sx-idx{flex-direction:row;flex-wrap:nowrap;overflow-x:auto;overflow-y:visible;flex:none;
    border-right:0;border-bottom:1px solid var(--border-soft);display:flex;gap:4px;white-space:nowrap}
  .sx-idx-item{flex:none;margin-bottom:0}
}
/* ═══ fine SX-MEGA ═══ */
/* ===== fine PREMIUM tab Foto ===== */

/* ═══ AN2-SEC (anagrafica_2, attivato 06/07) ═══
   Sezioni collassabili per macro-categoria nel tab Personaggi (sections.js:
   groupByCatCollapsible, usata SOLO lì — l'Attori resta su groupByCat/.grp-row,
   INVARIATO). Base .table/.search/.seg riusata as-is: qui solo le classi
   nuove .an2-*, prefissate come da sample approvato web/samples-0607/anagrafica_2.html. */
.an2-toolbar{margin-bottom:14px}
.an2-groups{display:flex;flex-direction:column;gap:14px}
.an2-sec{background:var(--surface);border:1.5px solid var(--border-soft);border-radius:var(--r-lg);box-shadow:var(--sh-1);overflow:hidden;transition:border-color var(--dur-base) var(--ease-out)}
.an2-sec.open{border-color:var(--accent)}
.an2-sec-head{width:100%;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:16px 20px;background:transparent;border:0;text-align:left;transition:background var(--dur-fast) var(--ease-out)}
.an2-sec-head:hover{background:var(--s2)}
.an2-sec-title{display:flex;align-items:center;gap:10px;font-size:15.5px;font-weight:800;letter-spacing:-.2px;color:var(--t1)}
.an2-sec-n{font:700 12px var(--ff-mono);color:var(--t3);background:var(--s3);border-radius:var(--r-pill);padding:2px 10px}
.an2-sec.open .an2-sec-n{background:var(--accent-soft);color:var(--accent-deep)}
.an2-chev{display:inline-flex;transition:transform .28s var(--ease-out);color:var(--t3)}
.an2-sec.open .an2-chev{transform:rotate(180deg);color:var(--accent)}
.an2-sec-wrap{display:grid;grid-template-rows:0fr;transition:grid-template-rows .3s var(--ease-out)}
.an2-sec.open .an2-sec-wrap{grid-template-rows:1fr}
.an2-sec-inner{min-height:0;overflow:hidden}
.an2-sec-body{border-top:1px solid var(--border-soft)}
.an2-sec-body .table{margin:0}
.an2-sec-empty{padding:22px;text-align:center;color:var(--t3);font-size:12.5px}
@media(max-width:720px){
  .an2-sec-head{padding:13px 14px}
}
/* ═══ fine AN2-SEC ═══ */

/* ==== B1 MENU UTENTE (.um-*) ====
   Avatar-bottone in topbar (#userBtn, app.js:370) → popover .um-pop + modale dedicata
   "Cambia password" .um-ovl, tradotti fedeli da 01_menu_utente.html (mockup approvato),
   già sui token reali. Popover e modale sono figli DIRETTI di document.body, posizionati
   in JS (umPosition/.um-pop position:fixed) — niente wrapper .um position:relative come
   nel mockup: qui non serve, ed evita clip da overflow/stacking di antenati. #userBtn
   riusa la classe .avatar esistente (36px, stesso gradiente): qui solo le proprietà IN
   PIÙ per lo stato interattivo (position/hover/apertura), aggiunte via JS (classList.add
   "um-btn") SOLO col whoami OK — auth OFF l'avatar resta esattamente com'è oggi. NIENTE
   .thm-pop (closeAllPops di sections.js la chiuderebbe, sections.js:297) né .modal-back
   (closeModal/onKey la agganderebbero — stessa lezione di .db-ovl in dashboard.js). */
.um-btn{position:relative;cursor:pointer;
  transition:border-radius var(--dur-base) var(--ease-spring),box-shadow var(--dur-fast) ease,transform var(--dur-fast) ease}
.um-btn:hover{transform:translateY(-1px);box-shadow:var(--sh-2)}
.um-btn.open{border-radius:11px;box-shadow:var(--ring)}
.um-chev{position:absolute;right:-3px;bottom:-3px;width:15px;height:15px;border-radius:50%;
  background:var(--surface);border:1px solid var(--border);color:var(--t2);display:grid;place-items:center;
  transition:transform var(--dur-base) var(--ease-spring),background .15s,color .15s}
.um-btn.open .um-chev{transform:rotate(180deg);background:var(--accent);border-color:var(--accent);color:#fff}
/* popover: stessa anatomia del menù Tema (.thm-pop) ma classe dedicata — nasce dall'angolo dell'avatar */
.um-pop{position:fixed;z-index:var(--z-pop);width:264px;
  background:var(--surface);border:1px solid var(--border);border-radius:16px;box-shadow:var(--sh-pop);
  padding:8px;transform-origin:top right;transform:scale(.72) translateY(-8px);opacity:0;pointer-events:none;
  transition:transform var(--dur-base) var(--ease-spring),opacity var(--dur-fast) ease}
.um-pop.open{transform:none;opacity:1;pointer-events:auto}
@media (prefers-reduced-motion: reduce){ .um-btn,.um-chev,.um-pop{transition:none} }
.um-head{display:flex;align-items:center;gap:11px;padding:8px 8px 10px;flex-wrap:wrap}
.um-big{width:42px;height:42px;border-radius:12px;background:linear-gradient(135deg,#6b78f5,#4453d6);
  color:#fff;display:grid;place-items:center;font:700 14px var(--ff-sans);flex-shrink:0}
.um-id{flex:1;min-width:0}
.um-id b{display:block;font-size:14px;color:var(--t1);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.um-role{font:700 10px var(--ff-mono);color:var(--accent-deep);background:var(--accent-soft);border-radius:5px;padding:2px 7px;text-transform:uppercase;letter-spacing:.5px}
.um-reps{display:flex;gap:5px;flex-wrap:wrap;width:100%;padding:2px 8px 6px}
.um-sep{height:1px;background:var(--border);margin:4px 6px}
.um-opt{display:flex;align-items:center;gap:10px;width:100%;text-align:left;background:transparent;border:0;
  border-radius:10px;padding:9px 10px;font:600 13px var(--ff-sans);color:var(--t1);cursor:pointer;transition:background .12s}
.um-opt:hover{background:var(--s2)}
.um-opt .ico{width:18px;height:18px;display:grid;place-items:center;color:var(--t3)}
.um-opt:hover .ico{color:var(--t1)}
.um-tag{margin-left:auto;font:700 9px var(--ff-mono);color:var(--accent-deep);background:var(--accent-soft);border-radius:5px;padding:2px 6px;text-transform:uppercase}
.um-exit{color:var(--c-crit)}
.um-exit .ico{color:var(--c-crit)}
.um-exit:hover{background:var(--c-crit-bg)}
.um-exit:hover .ico{color:var(--c-crit)}
.um-foot{padding:7px 10px 4px;color:var(--t3);font:500 10.5px var(--ff-sans)}
/* mobile: il popover si allarga ancorato a destra (non serve sheet: 264px ci sta anche a 375) */
@media (max-width:560px){ .um-pop{width:min(300px,calc(100vw - 24px))} }

/* modale "Cambia password" — overlay DEDICATO .um-ovl (figlio di body, come .db-ovl in
   dashboard.js: NIENTE .modal-back, sennò closeModal/onKey di sections.js la agganciano) */
.um-ovl{position:fixed;inset:0;background:rgba(17,24,39,.46);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);
  display:none;align-items:center;justify-content:center;z-index:calc(var(--z-pop) + 1);padding:16px}
.um-ovl.on{display:flex}
.um-modal{background:var(--surface);border:1px solid var(--border2);border-radius:var(--r-lg);box-shadow:var(--sh-3);width:min(380px,100%)}
.um-m-head{display:flex;align-items:center;gap:10px;padding:16px 16px 4px}
.um-m-head b{font-size:15px;flex:1}
.um-m-body{padding:12px 16px 4px}
.um-m-foot{display:flex;gap:10px;justify-content:flex-end;padding:14px 16px}
.um-msg{margin-top:4px;padding:9px 11px;border-radius:var(--r-sm);font-size:12.5px;font-weight:600;display:none}
.um-msg.err{display:block;background:var(--c-crit-bg);color:var(--c-crit);border:1px solid currentColor}
.um-msg.ok{display:block;background:var(--c-ok-bg);color:var(--c-ok);border:1px solid currentColor}
body.um-ovl-open{overflow:hidden}
/* ==== fine B1 MENU UTENTE ==== */

/* ==== B2 DASHBOARD C (.fd-*) ====
   Traduzione fedele di 04_dashboard_C_diario.html (.fd-layout/.fd-head/.fd-tabs/.fd-rail/
   .fd-hero/.fd-mini/.fd-kpi) + le BOLLE SCENA GRANDI di 02_dashboard_A_timeline.html righe
   37-47 (.fa-strip/.fa-story/.fa-ring, taglia 86px/anello 76px → qui .fd-strip/.fd-story/
   .fd-ring — decisione esplicita di Emanuele: solo le bolle dal mockup A, il resto è il
   layout C). SOLO STRUTTURA (BLUEPRINT_B2_DASHBOARD_C.md): niente .fd-comp/.fd-post/.fd-grp/
   .fd-pill-new (feed unificato + composer social = B3, non tradotti qui — il feed resta
   NoteChat.colHTML() dentro [data-note-root], vedi dashboard.js). Cast in .fd-hero = RIUSO
   della classe .avatar esistente (r.396, già bottone in app.js:368), NON la .fd-av del
   mockup (colori inline non-token, vietati). Flash bolla→mini-riga = RIUSO di .rk-flash
   (r.1205), nessuna nuova .fd-flash. Solo token esistenti, prefers-reduced-motion su ogni
   transizione/animazione nuova, niente .thm-pop/.modal-back (dashboard.js li evita di
   proposito sul chip mobile, stessa lezione di .db-ovl/.um-ovl). */
.fd-layout{display:grid;grid-template-columns:minmax(0,760px) minmax(290px,330px);gap:20px;justify-content:center;align-items:start}
.fd-layout>*{min-width:0}   /* invariante anti-dilatazione (gemello di .grid2>* :521) */

.fd-head{position:sticky;top:0;z-index:6;background:var(--glass-bg);backdrop-filter:blur(14px) saturate(160%);
  -webkit-backdrop-filter:blur(14px) saturate(160%);border:1px solid var(--border);border-radius:var(--r);
  display:flex;align-items:center;gap:8px;padding:10px 14px;margin-bottom:12px;box-shadow:var(--sh-1);flex-wrap:wrap}
.fd-head h2{font-size:16px;font-weight:800;letter-spacing:-.3px;margin-right:auto}
.fd-tabs{display:flex;gap:2px;overflow-x:auto;scrollbar-width:none;min-width:0}
.fd-tabs::-webkit-scrollbar{display:none}
.fd-tab{position:relative;border:0;background:transparent;color:var(--t2);padding:7px 11px;border-radius:10px;
  font:600 12.5px var(--ff-sans);cursor:pointer;white-space:nowrap;transition:color .15s,background .15s}
.fd-tab:hover{background:var(--s2);color:var(--t1)}
.fd-tab.on{color:var(--accent-deep)}
.fd-tab.on::after{content:"";position:absolute;left:10px;right:10px;bottom:2px;height:3px;border-radius:3px;background:var(--accent)}

/* bolle scena GRANDI (taglia/prominenza del mockup A, righe 37-47) */
.fd-strip{display:grid;grid-auto-flow:column;grid-auto-columns:86px;gap:14px;overflow-x:auto;
  scroll-snap-type:x mandatory;overscroll-behavior-x:contain;scrollbar-width:none;padding:6px 4px 14px;
  mask-image:linear-gradient(90deg,transparent,#000 16px,#000 calc(100% - 16px),transparent)}
.fd-strip::-webkit-scrollbar{display:none}
.fd-story{scroll-snap-align:start;border:0;background:transparent;cursor:pointer;display:flex;flex-direction:column;align-items:center;gap:6px;padding:0}
.fd-ring{width:76px;height:76px;border-radius:50%;padding:3px;background:conic-gradient(var(--accent),#8b5cf6,var(--accent));transition:filter .4s,opacity .4s}
.fd-story.girata .fd-ring{background:var(--border2);filter:grayscale(1);opacity:.55}
.fd-ring>span{display:grid;place-items:center;width:100%;height:100%;border-radius:50%;background:var(--surface);
  border:2px solid var(--surface);font:800 16px var(--ff-mono);color:var(--t1)}
.fd-story small{font:600 10.5px var(--ff-sans);color:var(--t2);max-width:86px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fd-story.girata small{color:var(--t3);text-decoration:line-through}

/* capiBox() esistente, INTATTA, dietro un toggle collassato di default */
.fd-capi{margin-bottom:16px}
.fd-capi summary{display:flex;align-items:center;gap:8px;cursor:pointer;list-style:none;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r);
  padding:11px 15px;font:700 12.5px var(--ff-sans);color:var(--t2)}
.fd-capi summary::-webkit-details-marker{display:none}
.fd-capi summary:hover{background:var(--s2)}
.fd-capi .chev{margin-left:auto;color:var(--t3);display:flex;transition:transform .18s}
.fd-capi[open] .chev{transform:rotate(180deg)}
.fd-capi[open] summary{border-radius:var(--r) var(--r) 0 0;border-bottom:0}
.fd-capi-body{border:1px solid var(--border);border-top:0;border-radius:0 0 var(--r) var(--r);padding:10px 15px 4px}
.fd-capi-body .panel{border-radius:0;border:0;box-shadow:none;margin-bottom:0}

/* rail destro: Ora sul set + mini-board + KPI */
.fd-rail{position:sticky;top:14px;display:flex;flex-direction:column;gap:14px}
.fd-rail-x{display:none}
.fd-hero{background:var(--surface);border:1.5px solid var(--accent);border-radius:var(--r-lg);box-shadow:var(--glow),var(--sh-2);padding:16px 18px}
.fd-hero .k{font:700 10px var(--ff-sans);letter-spacing:.7px;text-transform:uppercase;color:var(--t3)}
.fd-hero-num{border:0;background:transparent;padding:0;cursor:pointer;display:block;text-align:left}
.fd-hero .big{font:800 30px var(--ff-mono);letter-spacing:-1px;color:var(--t1);line-height:1.1;margin:2px 0}
.fd-hero-num:hover .big{color:var(--accent-deep)}
.fd-hero .sub{font-size:12px;color:var(--t2)}
.fd-hero.fd-hero-empty .big{font-size:20px;font-family:var(--ff-sans)}
.fd-pile{display:flex;gap:6px;flex-wrap:wrap;margin-top:11px}
.fd-hero-act{display:flex;gap:8px;align-items:center;margin-top:12px}

.fd-mini{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--sh-1);padding:6px}
.fd-mini details{border-radius:12px;overflow:hidden}
.fd-mini details+details{margin-top:2px}
.fd-mini summary{display:flex;align-items:center;gap:8px;padding:9px 10px;cursor:pointer;list-style:none;font:700 12px var(--ff-sans);color:var(--t1)}
.fd-mini summary::-webkit-details-marker{display:none}
.fd-mini summary:hover{background:var(--s2)}
.fd-mini .dot{width:8px;height:8px;border-radius:50%;flex:0 0 auto}
.fd-mini .cnt{margin-left:auto;background:var(--s3);border-radius:var(--r-pill);padding:1px 8px;font:700 10.5px var(--ff-mono);color:var(--t2)}
.fd-mini .chev{display:flex;color:var(--t3);transition:transform .18s}
.fd-mini details[open] .chev{transform:rotate(180deg)}
.fd-mini-row{display:flex;align-items:center;gap:7px;padding:7px 10px 7px 26px}
.fd-mini-row:hover{background:var(--s2)}
.fd-mini-lbl{display:flex;align-items:center;gap:7px;flex:1;min-width:0;border:0;background:transparent;padding:0;text-align:left;font:600 12px var(--ff-sans);color:var(--t2);cursor:pointer}
.fd-mini-lbl:hover{color:var(--t1)}
.fd-mini-lbl small{color:var(--t3);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fd-mini-empty{padding:7px 10px 7px 26px;font-size:11.5px}

.fd-kpi{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px}
.fd-kpi .card{padding:13px 15px}
.fd-kpi .n{font:800 26px var(--ff-mono);color:var(--t1);letter-spacing:-1px}
.fd-kpi .k{font:700 10px var(--ff-sans);letter-spacing:.6px;text-transform:uppercase;color:var(--t3)}

/* chip mobile che apre il RAIL INTERO come pannello (niente .thm-pop/.modal-back) */
.fd-rail-chip{display:none;position:sticky;top:56px;z-index:6;align-items:center;gap:7px;
  background:var(--accent);color:#fff;border:0;border-radius:var(--r-pill);padding:8px 16px;
  font:700 12px var(--ff-sans);box-shadow:0 8px 22px rgba(91,107,239,.4);cursor:pointer;
  width:fit-content;margin:0 0 12px}
.fd-rail-chip-n{background:rgba(255,255,255,.25);border-radius:var(--r-pill);padding:1px 7px;font:700 11px var(--ff-mono)}

@media (prefers-reduced-motion:reduce){
  .fd-ring,.fd-tab,.fd-capi .chev,.fd-mini .chev,.fd-rail.fd-rail-open{transition:none;animation:none}
}

@media (max-width:768px){
  .fd-layout{grid-template-columns:minmax(0,1fr)}
  .fd-rail{display:none}
  .fd-rail.fd-rail-open{display:flex;order:-1;position:relative;margin-bottom:14px;animation:fdRailIn .22s var(--ease-out)}
  .fd-rail-x{display:flex;position:absolute;top:-10px;right:-10px;z-index:2;box-shadow:var(--sh-2)}
  .fd-rail-chip{display:flex}
  .fd-strip{grid-auto-columns:74px;padding:6px 2px 12px}
  .fd-ring{width:64px;height:64px}
  .fd-story small{max-width:74px}
}
@keyframes fdRailIn{from{opacity:0;transform:translateY(-10px)}}
/* ==== fine B2 DASHBOARD C ==== */

/* ==== B3 FEED SOCIAL (.fd-*) ====
   Traduzione fedele di 04_dashboard_C_diario.html: composer :214-227 (.fd-comp/-row/-in/
   -extra/-foot), post :235-242, post foto :245-257, compact :262-275, divisore giorno
   :231/289, linea nuovi :259, gruppo scena :278-287 (.fd-grp/-row), .fd-re (+keyframe
   fdPop) :96-102 — SOLO token esistenti, nessun pixel/colore inventato. Cast = RIUSO di
   .avatar esistente (NON .fd-av del mockup, colori hardcoded non-token — stessa scelta di
   B2). Chip reparto = RIUSO di .chip.tone + .tone-costume/.tone-makeup/.tone-prod
   (style.css:285-295) al posto degli inline style --tone/--tone-bg del mockup. Flash
   deep-link = RIUSO di .rk-flash via flashTarget (nessuna nuova .fd-flash — ESCLUSA).
   ESCLUSI dal blueprint: .fd-pill-new (il poll 4s rerenderizza già il feed), .fd-flash
   (sopra), «✓ Visto»/.fd-re.on reattivo (B4, il contatore serve un campo nuovo su note —
   qui si trasla SOLO lo stile .fd-re per i bottoni azione del post).
   NUOVI (non nel mockup, richiesti dal blueprint B3 in prosa, SOLO token esistenti):
   .fd-ac* (autocomplete @/# DEDICATA — mai .thm-pop/.combo-pop/.modal-back, vincolo 6),
   .fd-ancin (input àncora compatto del composer), .fd-cast-chips (riga chip cast sotto
   l'àncora), .fd-chip-sc.on (stato attivo dei cast-chip toggle), .fd-post .avatar override
   dimensione (38px, gemello del pattern B2 su .fd-pile .avatar). position:relative su
   .fd-comp: necessario per ancorare .fd-ac (position:absolute) al contenitore, il mockup
   non lo dichiara esplicitamente essendo statico di suo. .fd-day{top:56px}: valore invariato
   dal mockup — la .fd-head del banco (style.css:2589-2591) è la STESSA regola già tradotta
   in B2, stessa altezza attesa (~56px con padding 10px 14px + tab 30px). prefers-reduced-
   motion su ogni animazione/transizione nuova (blocco dedicato, la riga B2 :2669-2671 non
   si tocca). */
.fd-comp{position:relative;background:var(--surface);border:1.5px solid var(--accent);border-radius:var(--r);box-shadow:var(--glow),var(--sh-1);
  padding:10px 12px;margin-bottom:14px;transition:box-shadow .2s}
.fd-comp:focus-within{box-shadow:var(--ring),var(--sh-2)}
.fd-comp-row{display:flex;gap:10px;align-items:center}
.fd-comp-in{flex:1;min-width:0;border:0;background:var(--s2);border-radius:var(--r-pill);padding:10px 16px;font:500 13px var(--ff-sans);color:var(--t1);outline:none;resize:none}
.fd-comp-in::placeholder{color:var(--t3)}
.fd-comp-extra{display:grid;grid-template-rows:0fr;transition:grid-template-rows .28s var(--ease-out)}
.fd-comp:focus-within .fd-comp-extra,.fd-comp.stay .fd-comp-extra{grid-template-rows:1fr}
.fd-comp-extra>div{overflow:hidden;min-height:0}
.fd-comp-foot{display:flex;gap:8px;align-items:center;flex-wrap:wrap;padding-top:10px}
.fd-anchor{display:inline-flex;align-items:center;gap:5px;background:var(--accent-mute);color:var(--accent-deep);
  border:1px dashed var(--accent-bord);border-radius:var(--r-pill);padding:4px 10px;font:600 11px var(--ff-sans);cursor:pointer}
.fd-anchor.off{background:var(--s2);color:var(--t3);border-color:var(--border)}
.fd-ancin{width:88px;flex:0 0 auto;background:var(--s2);border:0;border-radius:var(--r-pill);padding:8px 12px;font:600 12.5px var(--ff-mono)}
.fd-cast-chips{display:flex;flex-wrap:wrap;gap:6px}

/* card del feed: grammatica ATTORE ha VERBO OGGETTO */
/* E-R2 (14/07/2026, richiesta Emanuele): colonna feed .fd-layout 600→760px (sopra, :2616,
   gemello .fd-note-only aggiornato insieme) — post/testi/miniature più grandi e leggibili:
   .fd-post padding 13px 15px→15px 18px, .fd-meta 12→13px, .fd-meta b 13.5→15px, .fd-txt
   13.5→15px, .fd-media max-width 420px→none (segue la colonna più larga). .bb-note-row
   .fd-txt (:2983, contesto card compatta) NON toccata — resta 12px. SOLI token esistenti,
   zero colori nuovi. */
.fd-day{position:sticky;top:56px;z-index:5;display:flex;justify-content:center;margin:16px 0 10px}
.fd-day span{background:var(--s3);border:1px solid var(--border);border-radius:var(--r-pill);padding:4px 14px;
  font:700 10.5px var(--ff-sans);letter-spacing:.6px;text-transform:uppercase;color:var(--t2)}
.fd-new{display:flex;align-items:center;gap:10px;margin:14px 0 10px;color:var(--c-crit);font:700 10.5px var(--ff-sans);letter-spacing:.5px;justify-content:center}
.fd-new::before,.fd-new::after{content:"";flex:1;height:1px;background:var(--c-crit);opacity:.4;max-width:120px}
.fd-post{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);padding:15px 18px;margin-bottom:10px;
  display:grid;grid-template-columns:38px minmax(0,1fr);column-gap:11px;transition:transform .2s,box-shadow .2s}
.fd-post:hover{transform:translateY(-2px);box-shadow:var(--sh-2)}
.fd-post.compact{border-top:0;border-radius:0 0 var(--r) var(--r);margin-top:-11px;padding-top:6px}
.fd-post .avatar{width:38px;height:38px}
.fd-post.compact .avatar{visibility:hidden;height:0}
.fd-meta{display:flex;gap:7px;align-items:center;flex-wrap:wrap;font-size:13px;color:var(--t3);margin-bottom:3px}
.fd-meta b{font-size:15px;color:var(--t1)}
.fd-verb{color:var(--t2)}
.fd-txt{font-size:15px;color:var(--t1);line-height:1.55;white-space:pre-wrap;word-break:break-word}
.fd-post.done .fd-txt{opacity:.55;text-decoration:line-through}
.fd-chip-sc{display:inline-flex;align-items:center;gap:4px;background:var(--accent-mute);color:var(--accent-deep);
  border-radius:var(--r-pill);padding:2px 9px;font:700 11px var(--ff-mono);cursor:pointer;border:0;transition:background .15s}
.fd-chip-sc:hover{background:var(--accent-soft)}
.fd-chip-sc.on{background:var(--accent-deep);color:#fff}
.fd-media{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:3px;border-radius:12px;overflow:hidden;margin-top:8px;max-width:none}
.fd-media>div{aspect-ratio:4/3;display:grid;place-items:center;color:#fff;font:700 11px var(--ff-sans);letter-spacing:.4px;background:var(--s3)}
.fd-media>div:first-child{grid-row:span 2;aspect-ratio:auto}
.fd-media img{width:100%;height:100%;object-fit:cover;display:block}
.fd-foot{display:flex;gap:6px;margin-top:9px;flex-wrap:wrap}
.fd-re{display:inline-flex;align-items:center;gap:5px;border:1px solid var(--border);background:var(--surface);color:var(--t2);
  border-radius:var(--r-pill);padding:4px 11px;font:600 11.5px var(--ff-sans);cursor:pointer;transition:all .15s}
.fd-re:hover{border-color:var(--border2);color:var(--t1)}
.fd-re.on{background:var(--accent-soft);border-color:var(--accent-bord);color:var(--accent-deep)}
.fd-re.on .n{animation:fdPop .45s var(--ease-spring)}
@keyframes fdPop{40%{transform:scale(1.35)}70%{transform:scale(.9)}}
.fd-re:active{transform:scale(.95)}

/* gruppo per scena (alla Notion): details nativo */
.fd-grp{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);margin-bottom:10px;overflow:hidden}
.fd-grp summary{display:flex;align-items:center;gap:9px;padding:11px 15px;cursor:pointer;list-style:none;font:600 13px var(--ff-sans)}
.fd-grp summary::-webkit-details-marker{display:none}
.fd-grp summary:hover{background:var(--s2)}
.fd-grp .chev{margin-left:auto;color:var(--t3);display:flex;transition:transform .18s}
.fd-grp[open] .chev{transform:rotate(180deg)}
.fd-grp-body{border-top:1px dashed var(--border);padding:4px 15px 10px}
.fd-row{display:flex;gap:8px;align-items:center;padding:7px 0;font-size:12.5px;color:var(--t2);border-bottom:1px solid var(--border-soft)}
.fd-row:last-child{border-bottom:0}
.fd-row b{color:var(--t1)}
.fd-row .when{margin-left:auto;color:var(--t3);font:600 11px var(--ff-mono);white-space:nowrap}

/* autocomplete @ menzioni / # scene — DEDICATA (vincolo 6: mai .thm-pop/.combo-pop/.modal-back) */
.fd-ac{position:absolute;left:12px;right:12px;top:100%;margin-top:4px;background:var(--surface);
  border:1px solid var(--border);border-radius:var(--r);box-shadow:var(--sh-2);z-index:20;
  max-height:220px;overflow-y:auto;padding:4px}
.fd-ac[hidden]{display:none}
.fd-ac-row{display:flex;flex-direction:column;gap:1px;padding:7px 10px;border-radius:8px;cursor:pointer}
.fd-ac-row b{color:var(--t1);font-size:12.5px}
.fd-ac-row small{color:var(--t3);font-size:11px}
.fd-ac-row:hover,.fd-ac-row.on{background:var(--accent-soft)}

@media (prefers-reduced-motion:reduce){
  .fd-post,.fd-comp-extra,.fd-re,.fd-re .n,.fd-chip-sc,.fd-grp .chev{transition:none;animation:none}
}

/* mobile: SOLO le regole full-bleed del mockup (@container :160-170 → @media, coerente B2) */
@media (max-width:768px){
  .fd-post{border-radius:0;border-left:0;border-right:0;margin:0 -12px;padding:12px 14px;margin-bottom:0;border-bottom:0}
  .fd-post:hover{transform:none;box-shadow:none}
  .fd-media{max-width:none}
}
/* ==== fine B3 FEED SOCIAL ==== */

/* ═══ FASE C · L0 — Swapbar Home/Diario/Note in evidenza (richiesta Emanuele 14/07) ═══
   Override SCOPED su .db-view-sw: NON tocca .role-sw base (condivisa con Master/reparto).
   L'attivo prende var(--accent) → «gioco di colori dettato dal tema» (eredita ogni [data-theme]).
   Non tocca `display` → la ripristina-mobile :1283 (.role-sw.db-view-sw{display:flex}) resta valida.
   Variante A «pill piena» scelta da Emanuele nel render-vivo. Blocco RIMOVIBILE (torna al piccolo). */
/* TAPPA D (25/07/2026): il SELETTORE di queste 4 dichiarazioni è esteso a .foto-view-sw (swap
   Galleria|Moodboard della tab Foto). Nessuna dichiarazione nuova, nessun pixel diverso: è la
   STESSA barra della dashboard, come chiede il piano :656-658. Gemello del salvagente a :1354. */
.role-sw.db-view-sw,.role-sw.foto-view-sw,.role-sw.cont-view-sw{padding:4px;font-size:13px;gap:2px}
.role-sw.db-view-sw button,.role-sw.foto-view-sw button,.role-sw.cont-view-sw button{padding:11px 18px;min-height:44px}
.role-sw.db-view-sw button.on,.role-sw.foto-view-sw button.on{background:var(--accent);color:#fff;box-shadow:var(--sh-1)}
.role-sw.db-view-sw button:not(.on):hover,.role-sw.foto-view-sw button:not(.on):hover{background:var(--s2);color:var(--t1)}

/* ═══ B4: chip «Visto» ═══
   Chip reaction sul post-nota del feed (BLUEPRINT_B4_VISTO.md), agganciata dentro
   .fd-foot accanto ai tag personaggio e al bottone Segna risolta/Riapri (dashboard.js
   fdVistoChip/fdNotaFoot). Pill coerente con .fd-chip-sc/.fd-re (:2742/:2751): SOLI
   token var(--…) già in uso nei blocchi .fd-* — nessun colore nuovo. Blocco RIMOVIBILE
   (assieme alla funzione + ai 3 agganci di dashboard.js): togliendolo la chip sparisce,
   il campo note.visti residuo nei record resta innocuo. */
.fd-visto{display:inline-flex;align-items:center;gap:4px;border:1px solid var(--border);
  background:transparent;color:var(--t2);border-radius:var(--r-pill);padding:2px 8px;
  font:600 11.5px var(--ff-sans);cursor:pointer;transition:border-color .15s,background .15s,color .15s}
.fd-visto:not(.ro):hover{border-color:var(--accent-bord);color:var(--accent-deep)}
.fd-visto.on{background:var(--accent-soft);border-color:var(--accent-bord);color:var(--accent-deep)}
.fd-visto.ro{cursor:default;opacity:1}
@media (prefers-reduced-motion:reduce){ .fd-visto{transition:none} }
/* ═══ fine B4 ═══ */

/* ═══ D5: barra ricerca del picker giornata (#dbPkSearch, dashboard.js ensureOvl) ═══
   Gemello locale di .scene-search-wrap/.combo-search-wrap (odg.js): stessa classe base
   .search, override di larghezza/margine per starci fra .db-m-sub e .db-m-body. Nascosta
   via JS se le scene candidate sono ≤5 (soglia gemella di .picker-search), azzerata a ogni
   apertura del picker. Pulsante ✕ pulizia = icon-btn compatto senza bordo, SOLI token
   esistenti. */
.db-pk-search{max-width:none!important;margin:0 16px 10px!important;background:var(--surface)!important}
.db-pk-clear{width:22px;height:22px;display:grid;place-items:center;border:0;background:transparent;
  color:var(--t3);border-radius:var(--r-pill);flex:0 0 auto;cursor:pointer;transition:color .15s,background .15s}
.db-pk-clear:hover{color:var(--t1);background:var(--s2)}
/* ═══ fine D5 ═══ */

/* ═══ D2: Home board (PIANO_APPROVATO.md FASE D blocco D2) — traduzione fedele di
   03_dashboard_B_board.html (mockup r.24-107): bento (hero "Ora sul set" + 2 KPI + alert
   continuità) + board 2 colonne derivate Oggi/Fatto (NIENTE "In lavorazione": il mockup
   stesso la dichiara irrealizzabile senza scene.stato_reparto NUOVO, r.255) + rail attività
   compressa. @container del mockup → @media (max-width:760px), coerente col resto del file
   (B2/B3 usano @media 768px per lo stesso motivo). Facepile = .avatar esistente con
   override SCOPED (mai .bb-av coi colori hardcoded del mockup demo). VIA .moving/.landed/
   .bump/.unread/.bb-rail-comp (drag/unread/composer-finto del JS demo — muoiono col
   rerender pieno, dashboard.js non li porta). border-left della card: il mockup usa
   var(--tone,#7C5CFF) per-card (differenziava per episodio — campo che FlowSet non ha) →
   qui var(--accent) fisso, zero hex hardcoded.
   R1 (RIFINITURE dashboard — MISSIONE E-R, 14/07/2026, richiesta Emanuele): .bb-hero
   RIMOSSA (bbHeroHTML non esiste più, dashboard.js) — «Alert continuità» prende il suo
   posto/spazio. .bb-bento passa da grid(4 col fisse, righe 92px fisse — dimensionate per
   l'hero) a FLEX con align-items:stretch.
   E-R2 (14/07/2026, richiesta Emanuele): i 2 KPI non sono più box quadrati — diventano
   PILLOLE compatte in una riga sottile (.bb-kpis > .bb-kpi-pill, sotto) e l'Alert
   continuità DIVENTA il protagonista del bento (righe più larghe/leggibili: font 14px,
   line-height 1.5, padding 8px, invece di 12.5px/1.4/6px). .bb-bento torna a colonna
   piena larghezza a ogni breakpoint (pillole-poi-alert nell'ordine del DOM) — alert
   assente → resta solo la riga di pillole, zero buchi bianchi (stesso principio di R1,
   qui riverificato). Regole .bb-kpi (box quadrato) ormai MORTE, RIMOSSE: bbBentoHTML
   (dashboard.js) non le emette più. */
.bb-bento{display:flex;flex-direction:column;gap:10px;margin-bottom:18px}
.bb-kpis{display:flex;flex-wrap:wrap;gap:8px}
.bb-kpi-pill{display:inline-flex;align-items:center;gap:6px;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-pill);padding:4px 12px;font:700 11px var(--ff-sans);letter-spacing:.3px;text-transform:uppercase;color:var(--t3)}
.bb-kpi-pill b{font:800 15px var(--ff-mono);color:var(--t1);letter-spacing:-.3px;text-transform:none}
.bb-alert{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--sh-1);padding:14px 16px;overflow:hidden;display:flex;flex-direction:column}
.bb-alert .k{font:700 10px var(--ff-sans);letter-spacing:.6px;text-transform:uppercase;color:var(--t3);display:block;margin-bottom:6px}
.bb-alert .row{display:flex;gap:8px;align-items:center;font-size:14px;line-height:1.5;color:var(--t2);padding:8px;border:0;background:transparent;width:100%;text-align:left;border-radius:8px;cursor:pointer;transition:background .15s}
.bb-alert .row:hover{background:var(--s2)}
.bb-alert .row .chip{flex-shrink:0}

.bb-lower{display:grid;grid-template-columns:minmax(0,1fr) 330px;gap:18px;align-items:start}
.bb-lower>*,.bb-bento>*{min-width:0}   /* invariante anti-dilatazione (gemello di .grid2>* :521) */
.bb-tabs{display:none;position:sticky;top:0;z-index:6;margin-bottom:10px}
.bb-board{display:grid;grid-template-columns:repeat(2,minmax(240px,1fr));gap:14px}
.bb-col{background:var(--s2);border:1px solid var(--border);border-radius:var(--r-lg);padding:10px;min-height:200px}
.bb-col-h{display:flex;align-items:center;gap:8px;padding:4px 6px 10px;font:700 11px var(--ff-sans);letter-spacing:.6px;text-transform:uppercase;color:var(--t2)}
.bb-col-h .dot{width:8px;height:8px;border-radius:50%}
.bb-col-h .cnt{margin-left:auto;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-pill);padding:1px 9px;font:700 11px var(--ff-mono);color:var(--t1)}

.bb-card{background:var(--surface);border:1px solid var(--border);border-left:3px solid var(--accent);
  border-radius:var(--r-sm);box-shadow:var(--sh-1);padding:12px 13px;margin-bottom:10px;
  transition:transform .2s,box-shadow .2s}
.bb-card:hover{transform:translateY(-2px);box-shadow:var(--sh-2)}
.bb-c-top{display:flex;align-items:center;gap:8px;margin-bottom:5px}
.bb-c-lbl{display:flex;align-items:center;gap:8px;flex:1;min-width:0;border:0;background:transparent;padding:0;text-align:left;cursor:pointer}
.bb-c-top .db-num{font-size:11px;padding:1px 8px}
.bb-c-top b{font-size:13px;color:var(--t1);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bb-move{border:0;background:var(--s2);color:var(--t2);border-radius:8px;width:30px;height:30px;display:grid;place-items:center;cursor:pointer;flex-shrink:0;transition:background .15s,color .15s}
.bb-move:hover{background:var(--accent-soft);color:var(--accent-deep)}
.bb-c-meta{font-size:11.5px;color:var(--t3);margin-bottom:8px}
.bb-c-foot{display:flex;align-items:center;gap:5px}
/* R2 (RIFINITURE dashboard — MISSIONE E-R, richiesta Emanuele): pillole NOME INTERO
   (.dv-link/.dv-chips, IDIOMA REALE di VIEWS.scene "Personaggi in scena" — sostituiscono le
   bolle-iniziali .avatar/.pile qui sotto, RIMOSSE). Override SOLO di taglia (compatto per la
   card, base .dv-link:1503 è pensata per la colonna sezioni di una scheda, min-height:40px —
   troppo alta per una riga di card): stesse classi, stesso comportamento/colori, mai una
   .dv-link nuova. min-width:0 sul contenitore = la card può stringersi senza spingere in
   overflow orizzontale gli altri bottoni della riga (📷/+Nota/💬/👥) — a 375px il flex-wrap
   nativo di .dv-chips (:1502) manda le pillole a capo dentro la card, mai fuori. */
.bb-c-foot .dv-chips{margin-right:auto;min-width:0;gap:5px}
.bb-c-foot .dv-link{padding:3px 8px;min-height:0;font-size:11px;gap:4px;border-radius:var(--r-pill)}
.bb-c-foot .dv-more-btn{padding:3px 8px;min-height:0;font-size:11px;border-radius:var(--r-pill)}
.bb-tagcnt{display:inline-flex;align-items:center;gap:4px;background:var(--s2);border:1px solid var(--border);border-radius:var(--r-pill);padding:4px 10px;font:600 12px var(--ff-sans);color:var(--t2)}

/* ═══ Lotto 1 (14/07/2026, render-vivo approvato: fix1=C, fix5=A, fix6) ═══
   fix 1 · bottoni azione della card con ETICHETTA + tinta per ruolo (sostituiscono .bb-move muto). */
.bb-c-foot{flex-wrap:wrap;row-gap:6px}   /* i bottoni più alti vanno a capo, mai overflow */
.bb-act{display:inline-flex;align-items:center;gap:6px;min-height:40px;padding:0 13px;border:1px solid var(--border);background:var(--s2);color:var(--t2);border-radius:var(--r-sm);font:700 12px var(--ff-sans);cursor:pointer;flex-shrink:0;transition:background .16s var(--ease-out),border-color .16s,color .16s,transform .12s}
.bb-act svg,.bb-act .i{width:16px;height:16px;flex-shrink:0;display:grid;place-items:center}
.bb-act:hover{transform:translateY(-1px)}
.bb-act:active{transform:translateY(0)}
.bb-act--note{background:var(--accent-mute);border-color:var(--accent-bord);color:var(--accent-deep)}
.bb-act--note:hover{background:var(--accent-soft)}
.bb-act--note.v3{background:var(--accent-deep);border-color:var(--accent-deep);color:#fff;box-shadow:var(--sh-1)}   /* variante C: +Nota protagonista */
.bb-act--note.v3:hover{background:var(--accent);box-shadow:var(--sh-2)}
.bb-act--foto{background:var(--s2);border-color:var(--border);color:var(--t2)}
.bb-act--foto:hover{background:var(--s3);border-color:var(--border2);color:var(--t1)}
.bb-act--done{background:var(--c-ok-bg);border-color:rgba(30,142,87,.32);color:var(--c-ok)}
.bb-act--done:hover{filter:brightness(.97)}
/* fix 5 · pannello continuità SEMPRE presente (gemello di .bb-alert), con STATO verde/ambra */
.bb-cont{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--sh-1);padding:0;overflow:hidden;display:flex;flex-direction:column}
.bb-cont-hd{display:flex;align-items:center;gap:10px;padding:12px 15px;border-bottom:1px solid var(--border-soft)}
.bb-cont-hd .k{font:700 10px var(--ff-sans);letter-spacing:.6px;text-transform:uppercase;color:var(--t3)}
.bb-cont-hd .st{margin-left:auto;display:inline-flex;align-items:center;gap:6px;font:700 12px var(--ff-sans);padding:4px 11px;border-radius:var(--r-pill)}
.bb-cont-hd .st.ok{background:var(--c-ok-bg);color:var(--c-ok)}
.bb-cont-hd .st.warn{background:var(--c-warn-bg);color:var(--c-warn)}
.bb-cont--ok .bb-cont-hd{border-bottom:0}
.bb-cont-body{display:flex;flex-direction:column;padding:6px 8px 8px}
.bb-cont-row{display:flex;gap:9px;align-items:center;font-size:13.5px;line-height:1.5;color:var(--t2);padding:9px 8px;border:0;background:transparent;width:100%;text-align:left;border-radius:9px;cursor:pointer;transition:background .15s}
.bb-cont-row:hover{background:var(--s2)}
.bb-cont-row .chip{flex-shrink:0}
.bb-cont-empty{display:flex;align-items:center;gap:10px;padding:16px 15px;color:var(--c-ok);font:600 13px var(--ff-sans);line-height:1.4}
.bb-cont-empty .big{font-size:20px}
/* fix 6 · chip continuità sulla card, distinto dal 💬 note */
.bb-contchip{display:inline-flex;align-items:center;gap:5px;min-height:32px;padding:0 11px;border-radius:var(--r-pill);font:700 11.5px var(--ff-sans);border:1px solid transparent}
.bb-contchip.ok{background:var(--c-ok-bg);color:var(--c-ok)}
.bb-contchip.warn{background:var(--c-warn-bg);color:var(--c-warn)}
@media (prefers-reduced-motion:reduce){ .bb-act,.bb-cont-row{transition:none} }

.bb-rail{position:sticky;top:14px;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--sh-1);display:flex;flex-direction:column;max-height:calc(100dvh - 40px)}
.bb-rail-h{display:flex;align-items:center;gap:8px;padding:13px 15px;border-bottom:1px solid var(--border);font:700 13px var(--ff-sans)}
.bb-rail-b{overflow-y:auto;padding:6px;flex:1}
.bb-ev{position:relative;display:grid;grid-template-columns:34px minmax(0,1fr) auto;gap:9px;align-items:center;padding:8px 9px;border-radius:10px;cursor:pointer}
.bb-ev:hover{background:var(--s2)}
.bb-ev .avw{position:relative}
.bb-ev .avw .avatar{width:30px;height:30px;font-size:10px}
.bb-ev .badge{position:absolute;right:-3px;bottom:-3px;width:14px;height:14px;border-radius:50%;border:2px solid var(--surface);display:grid;place-items:center;font-size:8px;color:#fff}
.bb-ev .txt{font-size:12px;color:var(--t2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bb-ev .txt b{color:var(--t1)}
.bb-ev .when{font:600 10.5px var(--ff-mono);color:var(--t3)}
.bb-rail-day{padding:9px 12px 3px;font:700 9.5px var(--ff-sans);letter-spacing:.6px;text-transform:uppercase;color:var(--t3)}
.bb-rail-foot{border-top:1px solid var(--border);padding:9px}
.bb-rail-foot .btn{width:100%;justify-content:center}

@media (prefers-reduced-motion:reduce){
  .bb-card,.bb-move,.bb-alert .row{transition:none}
}
@media (max-width:760px){
  /* E-R2: .bb-bento è già colonna piena larghezza a ogni breakpoint (bb-kpis/bb-alert
     impilati) — le pillole vanno a capo da sole (flex-wrap nativo di .bb-kpis), zero
     regole qui sotto per loro (le vecchie .bb-alert/.bb-kpi flex-basis di R1 sono morte,
     RIMOSSE: il layout non è più una riga orizzontale a nessun breakpoint). */
  .bb-lower{grid-template-columns:minmax(0,1fr)}
  .bb-tabs{display:flex}
  .bb-board{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;gap:10px;padding-bottom:6px}
  .bb-col{flex:0 0 100%;scroll-snap-align:start}
  .bb-rail{position:static;max-height:420px;margin-top:14px}
}
/* ═══ fine D2 ═══ */

/* ═══ D4: vista Note (switcher → Note) ═══
   Nessun layout nuovo: il contenitore [data-note-root] qui NON vive dentro .fd-layout
   (niente rail, solo feed) — senza un tetto si stenderebbe a tutta la larghezza di
   #main. Stessa larghezza di lettura della colonna feed del Diario (.fd-layout
   minmax(0,760px), :2616 — E-R2 14/07/2026: era 600px, ora 760px, AGGIORNATI INSIEME
   come gemelli), token riusato 1:1. */
.fd-note-only{max-width:760px;margin:0 auto}
/* ═══ fine D4 ═══ */

/* ═══ E1 (14/07/2026, collaudo Q — MISSIONE_E1_giornata_modulare, dashboard.js 0.6.2):
   banner stantiezza ODG sotto il sottotitolo del pageHead (staleBannerHTML(f), SOLO
   quando fonteGiorno() è nel fallback retrocompat: nessuna giornata di oggi + ODG
   pubblicato ma di un giorno passato). SOLO token esistenti — var(--c-warn)/
   var(--c-warn-bg) :43, stesso accoppiamento di .chip.warn/.sync-ind.warn (:1229-1230),
   stesso border-radius di .bb-alert (:2854, box di alert affine). Il bottone «Sincronizza
   da ODG» riusa .btn.btn-soft esistente: zero CSS nuovo per lui. ═══ */
.db-stale{display:flex;align-items:center;gap:8px;background:var(--c-warn-bg);border:1px solid var(--c-warn);color:var(--c-warn);border-radius:var(--r-lg);padding:10px 14px;font:600 12.5px var(--ff-sans);margin-bottom:16px}
/* ═══ fine E1 ═══ */

/* ═══ E2 (14/07/2026, collaudo Q — MISSIONE_E2_note_roundtrip, dashboard.js 0.6.3): il
   contatore 💬 di bbCardHTML diventa un <details class="bb-note-det"> — idioma nativo
   di .fd-capi/.fd-grp (:2626/:2771, marker nascosto, zero JS di posizionamento). Summary
   = STESSA pillola .bb-tagcnt di prima (:2889, invariata a vista chiusa). flex-wrap:wrap
   SOLO override su .bb-c-foot esistente (:2885): permette al corpo aperto di andare a
   capo a piena larghezza (flex-basis:100%) invece di spingere in overflow orizzontale gli
   altri elementi della riga (pile/📷/+Nota) — nessun'altra card va mai a capo (bb-note-det
   è l'unico figlio con flex-basis:100%, e solo da [open]). SOLI token esistenti
   (var(--s2)/var(--border)/var(--r), nessun colore nuovo). ═══ */
.bb-c-foot{flex-wrap:wrap}   /* i tastini .bb-act della card possono andare a capo su schermi stretti */
/* Lotto 3 (fix 2): rimosse .bb-note-det/summary/[open] · .bb-note-body · .bb-note-row (orfane) —
   il counter 💬 non è più un <details> inline: ora è un bottone .bb-tagcnt che apre il modale-thread. */
/* ═══ fine E2 ═══ */

/* ═══ E3 (14/07/2026, collaudo Q — MISSIONE_E3_foto_riferimenti, dashboard.js 0.6.4/
   sections.js 0.5.62): chip scena DERIVATA nel post-foto del Diario (postFoto, f.scena
   vuota ma f.cambio ha scene[] non vuoto) — STESSO markup di .fd-chip-sc, solo un
   marcatore visivo discreto (opacità ridotta, idiom già in uso: .wxcover.calm :732,
   .th-hint :476, .scene-opt .add-ico :879) per distinguerlo dai chip di continuity reale
   senza introdurre un colore nuovo. Badge «da taggare» (chip.warn esistente) e i nuovi
   bottoni 📷 (bb-move/icon-btn esistenti) non richiedono CSS aggiuntivo. ═══ */
.fd-chip-sc.derived{opacity:.72}
/* ═══ fine E3 ═══ */

/* ═══ E-R2 (14/07/2026, richiesta Emanuele, dashboard.js): il modale Attività della scena
   (R3b, dashboard.js 0.7.1) è STATO RIMOSSO — blocco .db-act-* (sopra questa riga fino a
   qui) ELIMINATO, JS morto (grep verificato: zero call-site residui). Al suo posto, il
   counter 📷 apre un modale GRANDE con le foto della scena — overlay GEMELLO di
   #dbOvl/#bbQaOvl (.db-ovl/.db-modal/.db-m-head, zero CSS duplicato per quelli, solo un
   modificatore di larghezza: il modale base a 640px sarebbe troppo stretto per una griglia
   di foto). Corpo NUOVO .db-foto-grid/.db-foto-i/.db-foto-cap — griglia auto-fill
   minmax(180px,1fr) di celle ~200px (aspect 4/3, object-fit cover, fallback icona come
   l'idioma già in uso in .dv-foto-i), caption sotto ogni foto (autore + data breve). Mobile
   ≤768: la griglia si stringe da sola (auto-fill nativo), zero regole dedicate. ═══ */
.db-foto-modal{width:min(920px,96vw)}
.db-foto-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:8px}
.db-foto-grid>div{display:flex;flex-direction:column;gap:5px;min-width:0}
.db-foto-i{position:relative;aspect-ratio:4/3;border-radius:var(--r);overflow:hidden;border:1px solid var(--border);background:var(--s3);padding:0;display:grid;place-items:center;color:var(--t3);cursor:pointer;transition:transform .15s,box-shadow .15s}
.db-foto-i:hover{transform:translateY(-2px);box-shadow:var(--sh-2)}
.db-foto-i img{width:100%;height:100%;object-fit:cover;display:block}
.db-foto-cap{font-size:11px;color:var(--t3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
@media (prefers-reduced-motion:reduce){ .db-foto-i{transition:none} }
/* ═══ fine E-R2 ═══ */

/* ═══ Lotto 3 (fix 2+4, 14/07/2026): modale integrato NOTE+FOTO — carosello foto della nota
   (barra-cursore da mouse, swipe da touch), lightbox a schermo intero con navigazione ← →,
   composer a tutta larghezza con camera MULTIPLA e bozza. Render-vivo lotto3.html APPROVATO
   da Emanuele. SOLI token reali var(--...); .nt-msg/-meta/-txt/-foot/-mine/-mini/-prod/-anc
   ESISTONO già (blocco .nt-* 0.5.33) → qui SOLO le classi nuove, zero ridefinizioni. ═══ */
/* carosello foto della nota */
.nt-fwrap{margin:8px 0 2px}
.nt-fotos{display:flex;flex-wrap:nowrap;gap:6px;overflow-x:auto;scroll-snap-type:x proximity;
  scrollbar-width:none;-ms-overflow-style:none;padding-bottom:2px;touch-action:pan-x}
.nt-fotos::-webkit-scrollbar{display:none}
.nt-foto{position:relative;width:78px;height:78px;border-radius:var(--r);overflow:hidden;border:1px solid var(--border);
  background:var(--s3);cursor:pointer;flex:0 0 auto;scroll-snap-align:start;transition:transform .15s,box-shadow .15s}
.nt-foto:hover{transform:translateY(-2px);box-shadow:var(--sh-2)}
.nt-foto img{width:100%;height:100%;object-fit:cover;display:block;pointer-events:none}
.nt-foto .rm{position:absolute;top:3px;right:3px;width:19px;height:19px;border-radius:50%;border:0;
  background:rgba(17,24,39,.62);color:#fff;display:grid;place-items:center;cursor:pointer;font-size:12px;line-height:1;padding:0}
.nt-foto .rm:hover{background:var(--c-crit,#d14b3d)}
/* barra-cursore sotto (compare solo se il carosello è scrollabile) */
.nt-fbar{height:6px;margin-top:5px;border-radius:6px;background:var(--s3);position:relative;display:none;max-width:100%}
.nt-fbar.on{display:block}
.nt-fthumb{position:absolute;top:0;bottom:0;left:0;width:30%;border-radius:6px;background:var(--accent);opacity:.55;cursor:grab}
.nt-fthumb:active{cursor:grabbing;opacity:.8}
/* footer del modale col composer a tutta larghezza */
.db-note-foot{padding:12px 14px 14px;border-top:1px solid var(--border);background:var(--surface)}
.db-note-foot .fd-comp{margin:0}
.db-m-body.nt-scene{padding:12px 14px}
/* proporzioni (fix Emanuele): nel modale-scena la bolla nota riempie la colonna come il box
   di inserimento — via il max-width:86%/align-self:flex-start della chat 1:1 (:1567) */
.db-m-body.nt-scene .nt-msg{max-width:none;align-self:stretch}
/* lightbox a schermo intero con navigazione */
.nt-lb{position:fixed;inset:0;background:rgba(9,12,18,.9);display:none;z-index:220;place-items:center;touch-action:pan-y}
.nt-lb.on{display:grid}
.nt-lb img{max-width:88vw;max-height:82vh;border-radius:10px;box-shadow:0 20px 60px rgba(0,0,0,.5);user-select:none}
.nt-lb .nav{position:absolute;top:50%;transform:translateY(-50%);width:52px;height:52px;border-radius:50%;border:0;
  background:rgba(255,255,255,.14);color:#fff;font-size:26px;cursor:pointer;display:grid;place-items:center;backdrop-filter:blur(3px)}
.nt-lb .nav:hover{background:rgba(255,255,255,.26)}
.nt-lb .prev{left:18px}.nt-lb .next{right:18px}
.nt-lb .cx{position:absolute;top:16px;right:20px;width:44px;height:44px;color:#fff;font-size:30px;cursor:pointer;background:none;border:0}
.nt-lb .cnt{position:absolute;bottom:20px;left:50%;transform:translateX(-50%);color:#fff;font-size:12.5px;
  background:rgba(0,0,0,.4);padding:5px 12px;border-radius:20px}
@media(max-width:560px){ .nt-lb .nav{width:44px;height:44px;font-size:22px} .nt-lb .prev{left:8px}.nt-lb .next{right:8px} }
@media (prefers-reduced-motion:reduce){ .nt-foto{transition:none} }
/* ═══ fine Lotto 3 ═══ */

/* ═══ FASE C · L1 — DIARIO PER INSERIMENTO (16/07/2026) ═══
   Render-vivo APPROVATO 14/07: web/_render/flowset_diario_swap_render.html (contratto
   pixel+motion). Guscio «diario di bordo»: righe di registro su fondo pagina chiuse da una
   linea, NIENTE card bianca né avatar — SOLO i post .fd-ins del Diario (gli altri verb —
   girata/giorno/noteok — e le viste Note/«Da taggare» restano card .fd-post classiche).
   SOLI token del tema (eredita ogni [data-theme]); in coda al file così vince i pari-
   specificità del blocco B3 e del suo @media 768px. Blocco RIMOVIBILE. */
.fd-post.fd-ins{display:block;background:transparent;border:0;border-bottom:1px solid var(--border);
  border-radius:0;padding:15px 2px 17px;margin-bottom:0}
.fd-post.fd-ins:hover{transform:none;box-shadow:none}
/* titolo: data · Sc.N nome scena · @utente caricante */
.fd-title{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:11px}
.fd-t-date{font-weight:800;color:var(--t1);font-size:13.5px;letter-spacing:-.2px}
.fd-t-sep{color:var(--border2);font-weight:700}
.fd-box-sc{display:inline-flex;align-items:center;background:var(--accent-deep);color:#fff;border-radius:var(--r-pill);
  padding:3px 11px;font:700 12px var(--ff-mono);cursor:pointer;border:0}
.fd-t-name{font-weight:700;color:var(--t1);font-size:13.5px;letter-spacing:-.2px}
.fd-t-user{display:inline-flex;align-items:center;gap:5px;color:var(--t2);font-size:12.5px;font-weight:600}
.fd-t-user .av{width:19px;height:19px;border-radius:50%;background:linear-gradient(135deg,var(--accent),var(--accent-deep));
  color:#fff;display:grid;place-items:center;font-weight:700;font-size:9.5px}
/* corpo: foto SX + box DX (inserimento nota-sola → .solo, solo colonna DX) */
.fd-photo{display:grid;grid-template-columns:minmax(0,300px) minmax(0,1fr);gap:16px;align-items:start}
.fd-photo.solo{grid-template-columns:minmax(0,1fr)}
/* visore-swap: le foto scorrono nella STESSA cornice; click → lightbox .nt-lb riusato.
   Gli scrim rgba scuri stanno SOPRA la foto (identici in ogni tema, come .nt-lb). */
.fd-viewer{position:relative;border-radius:12px;overflow:hidden;background:var(--s3);aspect-ratio:4/3;
  user-select:none;cursor:zoom-in}
.fd-viewer .slide{position:absolute;inset:0;opacity:0;transition:opacity .18s}
.fd-viewer .slide.on{opacity:1}
.fd-viewer .slide img{width:100%;height:100%;object-fit:cover;display:block}
.fd-nav{position:absolute;top:50%;transform:translateY(-50%);width:30px;height:30px;border:0;cursor:pointer;
  border-radius:50%;background:rgba(20,24,34,.55);color:#fff;display:grid;place-items:center;font-size:16px;
  backdrop-filter:blur(2px);transition:background .15s;z-index:2}
.fd-nav:hover{background:rgba(20,24,34,.8)}
.fd-nav.prev{left:8px} .fd-nav.next{right:8px}
.fd-count{position:absolute;top:8px;right:8px;background:rgba(20,24,34,.6);color:#fff;border-radius:var(--r-pill);
  padding:2px 9px;font:700 10.5px var(--ff-mono);z-index:2}
.fd-zoom{position:absolute;bottom:8px;right:8px;background:rgba(20,24,34,.55);color:#fff;border-radius:8px;
  padding:2px 7px;font:700 10px var(--ff-sans);z-index:2;pointer-events:none;opacity:0;transition:opacity .15s}
.fd-viewer:hover .fd-zoom{opacity:1}
.fd-dots{position:absolute;bottom:8px;left:0;right:0;display:flex;gap:5px;justify-content:center;z-index:2}
.fd-dots i{width:6px;height:6px;border-radius:50%;background:rgba(255,255,255,.45);cursor:pointer;transition:all .15s}
.fd-dots i.on{background:#fff;width:16px;border-radius:3px}
.fd-viewer.single .fd-nav,.fd-viewer.single .fd-dots,.fd-viewer.single .fd-count{display:none}
/* colonna DX */
.fd-photo-box{display:flex;flex-direction:column;gap:10px;min-width:0}
.fd-box-badges{display:flex;gap:6px;flex-wrap:wrap}
.fd-badge{display:inline-flex;align-items:center;gap:4px;border-radius:var(--r-pill);padding:3px 10px;font:700 11px var(--ff-sans)}
.fd-badge.ok{background:var(--c-ok-bg);color:var(--c-ok)}
.fd-badge.warn{background:var(--c-warn-bg);color:var(--c-warn)}
/* la NOTA inserita (record live; .done = barrata come .fd-post.done .fd-txt) */
.fd-note-main{font-size:13.5px;color:var(--t1);line-height:1.5;white-space:pre-wrap;word-break:break-word}
.fd-note-main.done{text-decoration:line-through;opacity:.55}
.fd-note-empty{font-size:12.5px;color:var(--t3);font-style:italic}
/* tasto «💬 Interazioni (N)» collassabile (default chiuso) + pannello */
.fd-inter-toggle{align-self:flex-start;display:inline-flex;align-items:center;gap:7px;background:var(--s2);
  border:1px solid var(--border);color:var(--t2);border-radius:var(--r-pill);padding:5px 13px;
  font:700 11.5px var(--ff-sans);cursor:pointer}
.fd-inter-toggle:hover{background:var(--s3);color:var(--t1)}
.fd-inter-toggle .ar{font-size:9px;transition:transform .16s}
.fd-inter-toggle.open .ar{transform:rotate(180deg)}
.fd-inter{display:none;flex-direction:column;gap:5px;padding:9px 0 2px;margin-top:2px;border-top:1px solid var(--border-soft)}
.fd-inter.open{display:flex}
.fd-inter-row{display:flex;align-items:center;gap:7px;font-size:12px}
.fd-inter-row.exec.ok{color:var(--c-ok);font-weight:600}
.fd-inter-row.exec.open{color:var(--t3)}
.fd-inter-row.seen{color:var(--t2)}
.fd-inter-row .who{font-weight:700;color:var(--t1)}
.fd-seen-av{display:inline-flex}
.fd-seen-av i{width:17px;height:17px;border-radius:50%;border:2px solid var(--bg);margin-left:-5px;font-style:normal;
  display:grid;place-items:center;font:700 8px var(--ff-sans);color:#fff;background:var(--accent-deep)}
.fd-seen-av i:first-child{margin-left:0}
/* azioni: esegui / riapri QUI (data-note-done/reopen di note.js, già globali) */
.fd-act{display:flex;gap:7px;flex-wrap:wrap;margin-top:2px}
.fd-do,.fd-reopen{border-radius:var(--r-pill);padding:6px 14px;font:700 12px var(--ff-sans);cursor:pointer;
  display:inline-flex;align-items:center;gap:6px}
.fd-do{background:var(--c-ok);color:#fff;border:1px solid transparent}
.fd-do:hover{filter:brightness(1.06)}
.fd-reopen{background:transparent;color:var(--t2);border:1px solid var(--border2)}
.fd-reopen:hover{background:var(--s2);color:var(--t1)}
/* chip cast (scena/cambio riusano .fd-chip-sc esistente :2791) */
.fd-cast-chip{display:inline-flex;align-items:center;background:var(--s2);color:var(--t2);border:1px solid var(--border);
  border-radius:var(--r-pill);padding:2px 10px;font:600 11.5px var(--ff-sans);cursor:pointer}
@media (max-width:768px){
  .fd-photo{grid-template-columns:minmax(0,1fr)}   /* render: box SOTTO la foto */
  /* il full-bleed mobile di B3 (:2837) azzera border-bottom su .fd-post: la linea di
     registro va ripristinata qui (specificità maggiore + posizione in coda) */
  .fd-post.fd-ins{margin:0 -12px;padding:12px 14px 16px;border-bottom:1px solid var(--border)}
}
@media (prefers-reduced-motion:reduce){
  .fd-viewer .slide,.fd-nav,.fd-zoom,.fd-dots i,.fd-inter-toggle .ar{transition:none}
}
/* ═══ fine FASE C L1 ═══ */

/* ═══ FASE C L3 (16/07/2026) — barra di ricerca del Diario (#socialSearch) ═══
   La barra RIUSA .search (:429, stessa resa di #anaSearch/#invSearch): qui solo
   il posizionamento nel feedCol — a tutta colonna (il max-width:560px di .search
   è pensato per le toolbar) e staccata dal chip rail sopra e dalla section sotto. */
.social-search{margin:12px 0 14px;max-width:none}
/* ═══ fine FASE C L3 ═══ */

/* ═══ FASE C L4 (16/07/2026) — pannello filtri del Diario (scope "social") ═══
   Il <details> clona la resa di .fd-capi (:2658, stesso summary-pillola con chev);
   dentro, facce e chip sono le .cf-face/.cf-chips/.fchip GLOBALI di cambifiltri
   (zero ridefinizioni), impilate come .db-cp-filters (:1644). */
.fd-filters{margin:0 0 14px}
.fd-filters summary{display:flex;align-items:center;gap:8px;cursor:pointer;list-style:none;
  border:1px solid var(--border);border-radius:var(--r);padding:9px 14px;font:600 13px var(--ff-sans);color:var(--t2)}
.fd-filters summary::-webkit-details-marker{display:none}
.fd-filters summary:hover{background:var(--s2)}
.fd-filters .chev{margin-left:auto;color:var(--t3);display:flex;transition:transform .18s}
.fd-filters[open] .chev{transform:rotate(180deg)}
.fd-filters[open] summary{border-radius:var(--r) var(--r) 0 0;border-bottom:0}
.fd-filters-n{background:var(--accent);color:#fff;border-radius:var(--r-pill);padding:1px 8px;font:700 11px var(--ff-sans)}
.social-filters{display:flex;flex-direction:column;border:1px solid var(--border);border-top:0;
  border-radius:0 0 var(--r) var(--r);padding:10px 15px 12px}
.social-filters .cf-foot{margin-top:10px}
@media (prefers-reduced-motion:reduce){ .fd-filters .chev{transition:none} }
/* ═══ fine FASE C L4 ═══ */
/* ── v0.5.52 (LOTTO U1, 17/07/2026): tab del picker giornata «Da aggiungere / Già eseguite» —
   RIUSA .role-sw base (:439), scoped su .db-pk-tabs; le 2 classi battono la display:none
   mobile di :1282 anche da fuori media (stesso salvagente di .db-view-sw :1283).
   width:max-content: .role-sw è un flex block-level, senza tetto si stirerebbe a tutta
   la modale. SOLI token esistenti, zero colori nuovi. ── */
.role-sw.db-pk-tabs{display:flex;width:max-content;max-width:calc(100% - 32px);margin:0 16px 10px}
/* ═══ v0.5.54 (LOTTO C, 17/07/2026, BLUEPRINT_C_SCENE.md): toolbar facce della tab Scene.
   .scn-tools = riga sotto il pageHead (gemella di .inv-tools :1148); i chip sono le .fchip
   GLOBALI di cambifiltri.css (zero ridefinizioni); il combo è il combo unico (:1665) con solo
   una misura di contenimento. SOLI token esistenti. ═══ */
.scn-tools{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:14px}
.scn-tools .scn-chips{display:flex;flex-wrap:wrap;gap:7px}
.scn-tools .scn-pers{min-width:240px;max-width:340px}
.scn-tools .scn-pers .combo-btn{min-height:38px}
/* ═══ v0.5.56 (LOTTO C2 SCENE-BAR, 18/07/2026, BLUEPRINT_C2_SCENEBAR.md, R1 simmetria) ═══
   .scn-lab = etichetta di ruolo "Filtra" davanti ai chip (R2, sciolta la sovrapposizione con
   gli header di colonna che riordinano). .scn-table: th nowrap ferma «SCE NA»/«PA G.», più
   larghezze fisse sulle colonne strette/numeriche — Personaggi e Note si spartiscono il resto.
   SOLI token esistenti, zero colori nuovi; l'overflow-x della tabella a ≤840px è già del
   .panel (0.5.29), nessuna media query nuova qui. */
.scn-lab{font-size:12px;letter-spacing:.04em;text-transform:uppercase;align-self:center;margin-right:2px}
.scn-table th{white-space:nowrap}
.scn-table .th-gir{width:34px}
.scn-table th[data-sort="n"]{width:76px}
.scn-table th[data-sort="intext"]{width:92px}
.scn-table th[data-sort="dn"]{width:58px}
.scn-table th[data-sort="loc"]{width:17%}
.scn-table th[data-sort="pag"]{width:64px}
/* AA2 (29/07/2026): la colonna delle azioni della tab Scene ospita ORA TRE tasti — duplica,
   modifica, elimina — e non più due. Gli 84px erano 36+6+36 esatti: col terzo i bottoni andavano
   a capo (`.row-act` ha `flex-wrap:wrap` globale, :1991) e la riga cresceva a 120px di altezza
   con le icone incolonnate. 124px = 3×36 + 2×6 + 4 di respiro. `min-width` e non la sola `width`
   perché su una tabella auto-layout la width è un suggerimento che le altre colonne possono
   schiacciare: misurato sul DOM vivo, la colonna dichiarata 84px veniva resa a 36px. */
.scn-table th:last-child{width:124px;min-width:124px}
.scn-table .row-act{flex-wrap:nowrap}
/* …e i 40px che la colonna azioni si prende in più li cedono le DUE colonne di TESTO LIBERO.
   È la regola O.3 applicata a una tabella — «l'etichetta è testo nostro e ha una misura giusta,
   il valore è dell'utente e va tenuto a bada» — e serviva una misura, non un'impressione: sul
   banco la nota della scena 1 è una parola sola di 47 caratteri senza spazi, e l'invariante n.3
   (`.main .table td{overflow-wrap:normal}`, :1707) le lasciava chiedere 332px su 1108,
   spingendo il tasto Elimina a x=1461 su una finestra da 1440 — fuori schermo. Sostituendo
   quella nota con una frase normale lo scroll della tabella tornava a ZERO: la prova che il
   caso da curare è la parola non spezzabile, non i tre tasti.
   L'invariante n.3 resta giusta dove è nata (le INTESTAZIONI, e i valori monospaziati che un
   a-capo renderebbe illeggibili); qui si eccettuano le due colonne che ospitano prosa
   dell'utente. Le percentuali danno il bersaglio quando lo spazio c'è, `anywhere` è la valvola
   quando arriva un URL incollato o un nome di file lungo — che in produzione arriverà. */
.scn-table .th-pers{width:13%}
.scn-table .th-note{width:19%}
.scn-table td[data-label="Note"],.scn-table td[data-label="Personaggi"]{overflow-wrap:anywhere}
.scn-table td[data-label="Pag."],.scn-table td[data-label="INT/EXT"]{white-space:nowrap}
/* ═══ fine LOTTO C2 SCENE-BAR ═══ */
/* ═══ LOTTO I2 (19/07/2026, BLUEPRINT_I2_COMPOSITORE.md): compositore Continuity Book, card
   .rep-comp in cima alla griglia Stampe (sostituisce la vecchia card 1-click "continuity").
   Blocco portato IDENTICO dal mock APPROVATO web/_render/stampa_compositore.html righe 36-78
   (ESCLUSI .smp-* e .is-mobile .rc-*, telaio sample non di produzione). Riusa .role-sw/.chip/
   .combo/.combo-multi/.toggle-* già esistenti: zero token nuovi. ═══ */
.rep-comp{grid-column:1/-1}
.rep-comp .rep-desc{min-height:0}
.rc-rows{display:flex;flex-wrap:wrap;gap:16px 26px;margin:4px 0 2px}
.rc-grp{display:flex;flex-direction:column;gap:7px}
.rc-lab{font:700 10.5px var(--ff-sans);letter-spacing:.7px;text-transform:uppercase;color:var(--t3)}
.rc-grp .role-sw{align-self:flex-start}
/* SALVAGENTE MOBILE (gemello di .role-sw.rc-sw dentro @media(max-width:920px) sopra, stessa
   tecnica di .role-sw.db-view-sw :1352 — doppia specificità batte .role-sw{display:none} :1351
   indipendentemente dall'ordine): qui "base", fuori media, come nel mock (riga 53). */
.role-sw.rc-sw{display:flex}
/* Personaggi = combo multi-select A TENDINA (RIUSO .combo/.combo-multi/.combo-btn/.combo-pop/
   .combo-opt.mc/.mc-ck già di produzione, :1732 — chips scartate, non scalano con 45
   personaggi di una serie). Solo larghezza scoped qui. */
.rc-rows .combo{min-width:230px;max-width:270px;align-self:flex-start}
.rc-rows .combo-btn svg{transition:transform .15s}
.rc-rows .combo.open .combo-btn svg{transform:rotate(180deg)}
/* C2-bis (feedback Emanuele): la combo Personaggi si allinea alle pillole .role-sw sorelle —
   pill radius + altezza 37px + fondo --s2 (il .combo-btn base è 12px/41px/bianco e "stonava"
   tra i pill). Scoped al compositore: il .combo-btn globale (ogni altro combo del sito) resta invariato. */
.rc-rows .combo-btn{border-radius:var(--r-pill);min-height:37px;height:37px;padding:0 14px;background:var(--s2)}
.rc-pers-count{font:700 10.5px var(--ff-mono);letter-spacing:.4px;color:var(--t3);padding:4px 11px 8px;border-bottom:1px solid var(--border);margin-bottom:2px}
.rc-foto{display:flex;flex-wrap:wrap;align-items:center;gap:16px;margin:14px 0 2px;padding-top:14px;border-top:1px dashed var(--border)}
.rc-fsub{display:flex;align-items:center;gap:10px;transition:opacity .15s}
.rc-fsub .rc-lab{text-transform:none;font-weight:600;font-size:11.5px;letter-spacing:0}
.rc-fsub.is-disabled{opacity:.4;pointer-events:none}
.rc-inc{display:flex;gap:20px;flex-wrap:wrap;align-items:center;margin:14px 0 2px;padding-top:14px;border-top:1px dashed var(--border)}
.rc-foot{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;border-top:1px dashed var(--border);padding-top:14px;margin-top:14px}
.rc-sum{font-size:13px;color:var(--t2);line-height:1.5;max-width:62ch}
.rc-sum b{color:var(--t1);font-weight:700}
.rep-comp [hidden]{display:none!important}   /* la display: delle classi (.chip) NON deve vincere sull'attributo hidden */
/* mobile: gruppi impilati, tocco ≥44px (R7 — precedente .db-view-sw v0.5.51) */
@media(max-width:720px){
  .rc-grp{width:100%}
  .rc-grp .role-sw{align-self:stretch;display:flex}
  .rc-grp .role-sw button{flex:1;justify-content:center;min-height:44px;white-space:nowrap}
  .rc-rows .combo{width:100%;max-width:none;align-self:stretch}
  .rc-rows .combo-btn{min-height:44px}
  .rc-foto{flex-direction:column;align-items:flex-start}
}
/* ═══ fine LOTTO I2 ═══ */

/* ═══ LOTTO A (20/07/2026) — foglio di scelta SCATTA / GALLERIA ═══════════════
   Sintomo Emanuele da telefono: «premo il tastino foto e mi apre la galleria, non
   posso scattare». La cura sta nelle due funzioni sorgente (sections.js pickPhoto/
   pickPhotos); qui vive solo il foglio che chiede all'utente COSA vuole fare.
   Appare SOLO dove si può scattare (matchMedia pointer:coarse / hover:none — MAI la
   larghezza schermo: il tablet è largo ma coarse e deve poter scattare). Su desktop
   il foglio non viene mai costruito: si va dritti al picker multiplo.
   z-index 110: SOPRA .modal-back (90, :1161) e .db-ovl (95, :1690) — il foglio nasce
   quasi sempre sopra un modale aperto — e SOTTO .pcar-back (120, :1948), che è il
   visore foto a tutto schermo e deve restare il livello più alto.
   Backdrop: stesso literal di .db-ovl. Tocco 52px > 44px (R7). Niente colori nuovi. */
.pk-ovl{position:fixed;inset:0;z-index:110;display:grid;align-items:end;justify-items:center;
  background:rgba(17,24,39,.46);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);
  padding:16px;padding-bottom:max(16px,env(safe-area-inset-bottom))}
.pk-sheet{width:100%;max-width:420px;display:flex;flex-direction:column;gap:10px;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r);padding:14px}
.pk-sheet .btn{width:100%;min-height:52px;justify-content:center;font-size:16px}
@media(prefers-reduced-motion:no-preference){
  .pk-sheet{animation:pkRise .16s ease}
  @keyframes pkRise{from{transform:translateY(12px);opacity:0}to{transform:none;opacity:1}}
}
/* schermi alti/desktop-touch: il foglio si centra invece di incollarsi al fondo */
@media(min-height:620px) and (min-width:640px){ .pk-ovl{align-items:center} }
/* ═══ fine LOTTO A ═══ */

/* ══════════════════ TAPPA C (25/07/2026) — GALLERIA PURA ══════════════════
   Cartelle DERIVATE (non entità: nessun menu), breadcrumb e le TRE ZONE della
   cartella-scena. Tutto su token var(--): nessun colore nuovo. Regola 7: a 920px
   le fasce laterali si IMPILANO (ingresso sopra, corpo, uscita sotto).
   ⚠ Le fasce NON sono .foto-grid e le loro card NON sono .fs-card[data-fid]:
   è quello che tiene il motore di drag M1a fuori dal contorno. */
.fs-folder{position:relative;background:var(--surface);border:1px solid var(--border);border-radius:14px;
  overflow:hidden;box-shadow:var(--sh-1);cursor:pointer;transition:transform .16s,box-shadow .16s,border-color .16s;touch-action:pan-y}
.fs-folder:hover{transform:translateY(-2px);box-shadow:var(--sh-2);border-color:var(--border2)}
.fsf-cover{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);grid-template-rows:1fr 1fr;gap:2px;aspect-ratio:1;background:var(--s3);place-items:stretch}
.fsf-cover i{display:block;background-size:cover;background-position:center;min-height:0}
.fsf-cover .ph{grid-column:1/-1;grid-row:1/-1;display:grid;place-items:center;color:var(--t3)}
/* X3: le varianti n0/n1/n2/n3 di questa copertina sono salite nella regola CONDIVISA
   con .mb-cover e .cr-cover (:2482). Qui restava solo la copia: era il modello, ma
   ognuna delle tre copertine se lo riscriveva a modo suo. */
.fsf-n{font-size:11.5px;color:var(--t3);margin-top:2px}
/* breadcrumb della cartella aperta */
.foto-crumb{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:2px 0 12px}
.foto-crumb .fcr-t{font-weight:800;font-size:14.5px;color:var(--t1)}
/* le tre zone */
.foto-zones{display:grid;grid-template-columns:minmax(148px,196px) minmax(0,1fr) minmax(148px,196px);gap:16px;align-items:start}
.fz-body{min-width:0}
.fz-side{background:var(--s2);border:1px solid var(--border);border-radius:var(--r-lg);padding:10px;display:flex;flex-direction:column;gap:8px}
.fz-h{font-size:11.5px;font-weight:800;letter-spacing:.2px;color:var(--t3);text-transform:uppercase}
.fz-card{display:flex;align-items:center;gap:9px;min-height:44px;padding:5px;border-radius:10px;background:var(--surface);
  border:1px solid var(--border);cursor:pointer;transition:border-color .14s,transform .14s}
.fz-card:hover{border-color:var(--accent-bord);transform:translateX(2px)}
.fz-card i{flex:0 0 auto;width:44px;height:44px;border-radius:8px;background:var(--s3);background-size:cover;background-position:center}
.fz-card span{font-size:11.5px;color:var(--t2);line-height:1.25;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.fz-empty{font-size:11.5px;padding:4px 2px}
@media (max-width:920px){
  /* niente tre colonne su tablet/telefono: le fasce diventano strisce sopra e sotto il corpo */
  .foto-zones{grid-template-columns:minmax(0,1fr)}
  .fz-side{flex-direction:row;flex-wrap:wrap;align-items:center}
  .fz-side .fz-h{flex:1 0 100%}
  .fz-card{flex:1 1 190px;min-width:0}
}

/* ══ J2 (26/07/2026) — LA RICERCA DENTRO LE LISTE (motore ListSearch, sections.js:540) ══
   Barra unica per TUTTE le liste: riusa .search (:444) senza ridefinirne niente, così se un
   giorno cambia il look della ricerca globale cambia anche questa — un concetto, un componente.
   Larghezza allineata a .inv-tools .search (340px), che è la ricerca-lista che c'era già.
   Mobile (regola 7): l'input eredita il font 13px di .search; il tocco cade sulla × che è 30px
   alta con padding, sopra la soglia comoda dentro un campo. */
.lq-bar{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:0 0 14px}
.lq-bar .search{max-width:340px}
.lq-x{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;
  border:0;border-radius:50%;background:transparent;color:var(--t3);cursor:pointer;padding:0}
.lq-x:hover{background:var(--s3);color:var(--t1)}
/* ⚠ SERVE: .lq-x dichiara un display, e un display esplicito BATTE la regola UA [hidden]{display:none}
   — senza questa riga il tasto x resta visibile anche quando il markup lo nasconde. Difetto trovato dal
   GATE DEI COMANDI, non a occhio: due FAIL su scene (e: «atteso assente e c'e'» · f: comando visibile). */
.lq-x[hidden]{display:none}
.lq-cnt{font-size:12px;white-space:nowrap}
.lq-none{font-size:12px}
@media (max-width:760px){ .lq-bar .search{max-width:none;flex:1 1 100%} }

/* ══ V (26/07/2026) — LA TESTATA NON BALLA PIÙ: lo slot `nav` di pageHead (app.js:314) ══
   Il difetto, misurato PRIMA di toccare con tools/qa_V/z16 su :8899: passando da Galleria a
   Moodboard la barra di scambio si spostava di 901,8px in orizzontale e 78,3px in verticale a
   1440px (483,8/78,3 a 760px); lo switcher della Dashboard di 405,9px fra Home e Note. La causa
   non era estetica: la barra viveva nel gruppo azioni, incollato a destra da space-between, e
   ogni bottone che compariva la spingeva via.
   Regola applicata (Primer PageHeader: slot Navigation ≠ slot Actions · Apple HIG: il segmented
   control sta sopra il contenuto che governa e non divide la barra con altri controlli): la
   navigazione entra nella RIGA DEL TITOLO, che è invariante fra le viste che essa stessa
   commuta. Il sottotitolo — che invece CAMBIA da una vista all'altra — resta sotto, dove può
   crescere di quante righe vuole senza muovere niente.
   ⚠ Tutto è scoped su .has-nav: senza il quarto argomento il markup e la resa sono quelli di
   sempre, e le ~40 viste che chiamano head(t,s,a) non cambiano di un pixel. */
.ph-id{min-width:0}
.ph-idrow{display:flex;align-items:center;gap:14px;min-width:0}
.ph-nav{display:flex;align-items:center;flex-shrink:0}
/* IL PERNO DI TUTTO, in tre dichiarazioni:
   · la riga titolo+nav NON va mai a capo (nowrap) e il titolo non si spezza → il nav sta sempre
     attaccato al titolo, e la sua x dipende SOLO dalla lunghezza del titolo;
   · quel titolo è invariante fra le viste che il nav commuta ("Foto" di qua e di là, dbTitle()
     uguale in tutte e tre le viste Dashboard) → delta zero PER COSTRUZIONE, non per fortuna;
   · le azioni restano libere di stare accanto o di andare a capo secondo lo spazio: qualunque
     cosa facciano, non hanno più modo di spingere la barra. Prima erano nello stesso contenitore
     ed è per questo che la spostavano di 901,8px.
   Il sottotitolo — che invece CAMBIA da una vista all'altra e può occupare righe diverse — sta
   sotto il nav: cresca quanto vuole, non muove niente. */
.page-head.has-nav .ph-idrow{flex-wrap:nowrap}
.page-head.has-nav .h-title{white-space:nowrap}
.page-head.has-nav .ph-id{flex:1 1 auto}
.page-head.has-nav .ph-act{flex:0 1 auto;justify-content:flex-end}
.page-head.has-nav .h-sub{margin-top:6px}
/* Regola 7 (mobile) — e insieme il salvagente del nowrap qui sopra: sotto i 560px un titolo
   lungo più la barra non ci starebbero, e senza questa regola la pagina scorrerebbe in
   orizzontale. Qui la barra va a capo SEMPRE (è una regola di larghezza, non di contenuto:
   scatta identica nelle due viste, quindi la stabilità regge) e si stira a tutta riga — il
   bersaglio del dito cresce invece di stringersi. I 44px di altezza vengono da
   .role-sw.db-view-sw/.foto-view-sw button (:3031), qui non si toccano. */
@media (max-width:560px){
  .page-head.has-nav .ph-idrow{flex-wrap:wrap;gap:10px}
  .page-head.has-nav .h-title{white-space:normal}
  .page-head.has-nav .ph-nav{flex:1 1 100%}
  .page-head.has-nav .ph-nav .role-sw{width:100%}
  .page-head.has-nav .ph-nav .role-sw button{flex:1 1 0;justify-content:center}
}

/* ===========================================================================
   U1 (26/07/2026) — CODICE CAMBIO: sigla fissa + numero  (field type:"chcode")
   La sigla (CH costumi / MU trucco) non è una scelta dell'utente ma la sua tab:
   sta DENTRO la cornice dell'input, in sola lettura, come le unità di .meas
   (:592) — stesso idioma, nessun componente nuovo. Il numero è l'unica cosa
   digitabile perché è l'unica che conta: è la posizione nella sequenza del
   personaggio.
   U1-bis (27/07/2026): il campo accetta anche il BIS (1B, 2B), quindi non è più `type=number` —
   niente spinner, stessa cornice e stesso ingombro. Font monospazio: «12B» dev'essere leggibile
   come un codice, non come una parola.
   =========================================================================== */
.chc{position:relative;display:flex;align-items:center}
.chc-sig{position:absolute;left:1px;top:1px;bottom:1px;min-width:44px;display:flex;align-items:center;justify-content:center;
  padding:0 10px;font:700 13px 'JetBrains Mono';color:var(--t2);background:var(--s3);
  border-right:1px solid var(--border);border-radius:11px 0 0 11px;pointer-events:none;user-select:none}
.chc-num{padding-left:56px!important;font-family:'JetBrains Mono',ui-monospace,monospace;font-weight:700}
.chc-hint{display:block;margin-top:5px;font-size:11px;line-height:1.35;color:var(--t3)}
.chc-hint:empty{display:none}

/* ===========================================================================
   U2 (27/07/2026) — LA CARD CAMBIO DIVENTA UN POSTER
   Richiesta di Emanuele: «la foto occupa tutta la card tranne la barra dei 4
   tasti in basso, e le info stanno sopra l'immagine». Un costume si riconosce
   dalla foto, non dal titolo.
   Il punto delicato era la leggibilità: la strada scelta è lo SCRIM A
   GRADIENTE, quello dei manifesti — il velo è denso solo dietro al testo e
   sfuma a ZERO prima di metà immagine, invece del velo uniforme che spegne
   proprio ciò che si vuole guardare. Due gradienti: uno forte dal basso (dove
   stanno titolo, descrizione e scene) e uno appena accennato dall'alto (dove
   stanno codice e stato).
   Tutto è scoped su `.cb-card.cb-poster` — che dal 29/07/2026 (Z7) ce l'hanno
   TUTTE le card, con e senza foto: la classe si chiamava `.has-shot` e il nome
   ha smesso di dire il vero quando la forma è diventata una sola. Chi non ha
   foto prende `.cb-noshot` (blocco Z7 qui sotto): stessa forma, copertina di
   colore pieno e velo più fitto perché il bianco regga anche sul chiaro.
   IL CLICK invece dal 29/07 è UNO SOLO: tutta la card apre la scheda del cambio
   (carousel.js si fa da parte dentro .cb-card). Lo scrim resta pointer-events:none
   e i blocchi di testo cliccabili: sotto c'è il .cb-body, che è il tasto.
   =========================================================================== */
.cb-card.cb-poster .cb-body{position:relative;padding:0;display:block;aspect-ratio:3/4;min-height:220px}
.cb-card.cb-poster .cb-shot{position:absolute;inset:0;overflow:hidden}
.cb-card.cb-poster .cb-shot .pcar-card{height:100%}
.cb-card.cb-poster .cb-shot .pcar-card-img{height:100%;aspect-ratio:auto;border-radius:0}
.cb-card.cb-poster .cb-shot .pcar-card-img>img{width:100%;height:100%;object-fit:cover}
.cb-card.cb-poster .cb-over{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:space-between;
  gap:8px;padding:10px 11px 11px;pointer-events:none;
  background:linear-gradient(to top,rgba(10,13,20,.86) 0%,rgba(10,13,20,.62) 22%,rgba(10,13,20,.18) 44%,rgba(10,13,20,0) 62%),
             linear-gradient(to bottom,rgba(10,13,20,.42) 0%,rgba(10,13,20,0) 26%)}
.cb-card.cb-poster .cb-top,
.cb-card.cb-poster .cb-txt{pointer-events:auto}
.cb-card.cb-poster .cb-top{margin-bottom:0}
.cb-card.cb-poster .cb-ch{color:#fff;text-shadow:0 1px 3px rgba(0,0,0,.55)}
.cb-card.cb-poster .cb-ti{color:#fff;text-shadow:0 1px 3px rgba(0,0,0,.5);-webkit-line-clamp:2}
.cb-card.cb-poster .cb-desc{color:rgba(255,255,255,.86);text-shadow:0 1px 2px rgba(0,0,0,.5);-webkit-line-clamp:2}
.cb-card.cb-poster .cb-meta{color:rgba(255,255,255,.86);text-shadow:0 1px 2px rgba(0,0,0,.5)}
.cb-card.cb-poster .cb-meta .ic{color:#fff;opacity:.9}
/* i trattini del carosello (più foto) stanno in basso a destra e finirebbero sotto le scritte:
   li si porta in ALTO, accanto al codice, dove lo scrim è leggero e non danno fastidio. */
.cb-card.cb-poster .cb-shot .pcar-card-dots{top:10px;bottom:auto;right:11px}
/* TELEFONO (regola 7): la card è più stretta, la descrizione già sparisce (:1839) e il poster
   si accorcia — resta leggibile senza mangiare mezzo schermo per un solo cambio. */
@media (max-width:560px){
  .cb-card.cb-poster .cb-body{aspect-ratio:4/5;min-height:190px}
  .cb-card.cb-poster .cb-over{padding:9px 10px 10px}
}

/* ═══ U3e (27/07/2026) — BUDGET A DOPPIA BARRA (acquisti · noleggi) ═══════════════════
   Due nature di spesa diverse: quello che compri resta un bene della produzione, quello
   che noleggi è un costo che finisce. Il tetto è UNO e le due barre lo scompongono.
   Blocco APPEND: .bd-track/.bd-fill/.bd-k/.bd-pct restano IDENTICI (stessa barra di
   sempre, solo affiancata due volte) — qui si aggiunge solo la griglia e la tinta della
   seconda barra, presa dal token del chip "Noleggio" (--c-info), zero colori nuovi. */
.bd-split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:14px 22px;margin-top:2px}
.bd-part{min-width:0}
.bd-plab{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin-bottom:5px}
.bd-pv{font:700 14px 'JetBrains Mono';color:var(--t1)}
.bd-part .bd-pct{margin-top:4px}
.bd-fill.nol{background:var(--c-info)}
/* la riga del TOTALE chiude il blocco: senza aria e senza filo si legge come la coda della barra
   che le sta sopra, invece che come la somma delle due (visto allo screenshot del collaudo). */
.budget > .bd-pct{margin-top:13px;padding-top:10px;border-top:1px solid var(--border);font-weight:600;color:var(--t2)}
/* TELEFONO (regola 7): le due barre si impilano invece di dimezzarsi — a 390px una barra
   larga 150px non si legge, e il numero le andrebbe addosso. */
@media (max-width:560px){
  .bd-split{grid-template-columns:minmax(0,1fr);gap:12px}
}

/* ═══ U3b (27/07/2026) — LA CODA DEL NOLEGGIO: campo che compare, riga che parla ═══════
   Due sole regole, entrambe minime.
   1. `.field[hidden]` — il campo «Riconsegna entro» esiste sempre nel DOM (readForm continua a
      leggerlo) ma si vede solo sul noleggio. .field non dichiara `display`, quindi l'attributo
      hidden basterebbe da solo: la regola è scritta lo stesso perché domani qualcuno potrebbe
      dare a .field un display esplicito e il campo riapparirebbe in silenzio sugli acquisti.
   2. `.fld-hint` — la riga d'aiuto sotto un campo semplice. È il gemello esatto di .toggle-hint
      (:1649), meno il rientro della casella: stesso font, stesso colore, stessa interlinea.
      Zero token nuovi, zero componenti nuovi. */
.field[hidden]{display:none}
.fld-hint{display:block;margin-top:5px;font:500 11px var(--ff-sans);color:var(--t3);line-height:1.35}
.fld-hint:empty{display:none}
/* U3b: la tessera di una FRASE (non di un dato secco) prende due colonne — «29/07/2026 · fra 2
   giorni» in 120px si spezzava su tre righe, etichetta compresa. Sul telefono la griglia e' gia'
   a colonna singola: lo span tornerebbe a sfondare, quindi li' si disattiva. */
.dv-fact.wide{grid-column:span 2}
@media (max-width:560px){ .dv-fact.wide{grid-column:auto} }
/* U3b: il riscontro vivo sotto il campo data — gemello di .meas-conv (:616), stessa misura e
   stesso token d'accento. Dice la data in italiano e quanto manca, qualunque formato mostri
   l'input nativo (che segue la lingua del browser, non la nostra). */
.fld-live{display:block;margin-top:5px;font:600 11px 'JetBrains Mono';color:var(--accent-deep)}
.fld-live:empty{display:none}

/* ══════════════════════════════════════════════════════════════════════════════
   0.5.81 (TAPPA U3c · il centro notifiche, 27/07/2026) — blocco APPEND in coda.
   La campanella smette di essere un toast e diventa un PANNELLO. Non nasce un
   componente nuovo: e' l'idioma di .search-results (:1349) — dropdown assoluto
   dentro un wrapper relative in topbar, stesso fondo, stesso raggio, stessa
   ombra, stesso z — applicato all'altro bottone della stessa barra. Le righe
   riusano .chip warn/neutral (gli STESSI del chip «entro» in riga inventario,
   U3b) e .btn-soft/.icon-btn: chi legge il pannello riconosce i pezzi.
   Regola 7: sotto i 480px il pannello si stira quasi a tutto schermo e la riga
   passa a due piani (testo sopra, azioni sotto) invece di comprimere il nome
   del capo a due lettere. ══════════════════════════════════════════════════ */
.notif-wrap{position:relative;display:inline-flex;flex-shrink:0}
#notifBtn{position:relative}
/* il pallino sulla campanella: conta gli avvisi APERTI (mai uno "0" — zero avvisi,
   zero pallino), rosso quando almeno uno e' per oggi o gia' scaduto. */
.nf-badge{position:absolute;top:-4px;right:-4px;min-width:17px;height:17px;padding:0 4px;border-radius:var(--r-pill);
  background:var(--c-warn);color:#fff;font:800 10px var(--ff-sans);line-height:17px;text-align:center;
  border:2px solid var(--surface);pointer-events:none}
.nf-badge.urg{background:var(--c-crit)}
.notif-pop{position:absolute;top:calc(100% + 8px);right:0;width:min(460px,calc(100vw - 24px));
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r);box-shadow:var(--sh-pop);
  z-index:var(--z-pop);max-height:min(70vh,560px);overflow:auto;padding:6px}
.notif-pop[hidden]{display:none}
.nf-head{display:flex;align-items:center;gap:8px;padding:8px 10px 6px;font-size:13px;color:var(--t1)}
.nf-n{background:var(--s3);color:var(--t2);border-radius:var(--r-pill);padding:1px 8px;font:800 11px var(--ff-sans)}
.nf-list{display:flex;flex-direction:column;gap:2px}
/* TRE PIANI, non uno. Il primo giro teneva chip+nome+due tasti sulla STESSA riga: in 420px il
   nome del capo — cioe' la cosa che stai cercando — si riduceva a «Frac da cerimoni…» e il
   dettaglio si spezzava in tre. Difetto visto allo SCREENSHOT, non da un test: un troncamento
   e' HTML valido e nessun controllo lo nota. Ora il nome ha quasi tutta la larghezza. */
.nf-row{display:grid;grid-template-columns:auto minmax(0,1fr) auto;
  grid-template-areas:"chip nome x" "meta meta meta" "act act act";
  column-gap:9px;row-gap:3px;align-items:center;padding:9px 10px;border-radius:var(--r-row)}
.nf-row + .nf-row{border-top:1px solid var(--border-soft)}
.nf-row:hover{background:var(--s2)}
.nf-chip{grid-area:chip}
/* .link in casa vive sugli <a> (9 occorrenze): messa su un <button> non basta, perche' l'aspetto
   NATIVO del bottone vince e resta — misurato qui: bordo 2px outset, fondo #efefef, testo NERO
   invece dell'accento. Difetto visto allo screenshot (il nome del capo sembrava una casella di
   testo) e confermato con getComputedStyle, non a occhio. Nessun gemello da sanare: gli altri
   button-link della casa usano .dv-link, che il suo aspetto ce l'ha gia'. */
.nf-nome{grid-area:nome;appearance:none;-webkit-appearance:none;background:none;border:0;padding:0;
  color:var(--accent-deep);text-align:left;font-weight:700;font-size:13.5px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}
.nf-meta{grid-area:meta;display:block;color:var(--t3);font-size:11px;line-height:1.4}
.nf-reso{grid-area:act;justify-self:end;margin-top:3px}
.nf-x{grid-area:x;width:30px;height:30px;color:var(--t3)}
.nf-x:hover{color:var(--c-crit)}
.nf-empty{display:flex;flex-direction:column;align-items:center;gap:5px;text-align:center;padding:22px 18px;color:var(--t2)}
.nf-empty .ic{color:var(--c-ok)}
.nf-empty small{color:var(--t3);font-size:11px;line-height:1.45;max-width:30ch}
/* il piede = la riga di stato che PRIMA era il toast della campanella (app.js:517).
   Non si e' persa: ha solo cambiato posto, ed e' diventata leggibile con calma. */
.nf-foot{position:sticky;bottom:-6px;margin-top:6px;border-top:1px solid var(--border-soft);
  background:var(--surface);padding:8px 10px 6px;
  font:600 10px var(--ff-sans);color:var(--t3);text-align:center}
/* Regola 7: sul telefono il pannello NON puo' restare ancorato alla campanella — largo quanto lo
   schermo e agganciato a destra di un bottone che sta a 3/4 della barra, sfora a SINISTRA (misurato
   a 390px: bordo sinistro a -47px, col nome del capo fuori schermo). Qui diventa fixed fra i due
   margini; --nf-top lo scrive avvisi.js dal fondo REALE della campanella (stesso principio di
   placePop per i menu a tendina), il fallback 78px vale se quella riga non gira. */
@media (max-width:480px){
  .notif-pop{position:fixed;top:var(--nf-top,78px);left:10px;right:10px;width:auto;max-height:min(74dvh,560px)}
  .nf-x{width:36px;height:36px}
  .nf-nome{font-size:14px}
}

/* ===== v0.5.87 (Y3b, 28/07/2026): gli switch delle card di stampa VANNO A CAPO ==================
   Misurato sul banco a 390px: 8 switch su 17 avevano l'ultimo valore OLTRE il bordo del pannello
   (l'ordine dell'Inventario arrivava a 574px con 390px di viewport) e NON c'era nessuno scroll
   (.role-sw è flex-wrap:nowrap con overflow visibile). Sul telefono «Archiviato», «Pagine» e
   «Stato» erano semplicemente IRRAGGIUNGIBILI — regola 7, mobile obbligatorio.
   Il wrap vale per TUTTE le .rc-sw, comprese le tre card box consegnate in Y3a (RASTRELLO: il
   difetto era della pillola, non delle card nuove) e non tocca il desktop, dove lo spazio c'è.
   row-gap: senza, andando a capo i bottoni si toccano e la pillola sembra un blocco solo. */
.rc-sw{flex-wrap:wrap;row-gap:3px}

/* ═══ Z7 (29/07/2026) — LA CARD CAMBIO È UN TASTO, E IL RAIL SI TRASCINA ═══════════════
   Tre cose in un blocco solo, perché sono la stessa cosa vista da tre lati: la card
   cambio è un OGGETTO INTERO, non un collage di zone che reagiscono in modo diverso.

   1. FORMA UNICA. Prima la forma-poster valeva solo per chi aveva una foto (.has-shot,
      rinominata .cb-poster proprio qui) e le altre ripiegavano su testo in flusso più un
      riquadrino da 190×119 in mezzo a una card di 218×392. Solo che sul banco 210 card
      su 213 sono senza foto: la forma «di ripiego» era quella che si vedeva sempre.
      Ora il poster è uno solo e chi non ha lo scatto prende .cb-noshot.
   2. IL VELO PIÙ FITTO di .cb-noshot non è un vezzo: è la ragione per cui il ramo
      separato esisteva. Il segnaposto del Carousel è #8A8278, e il bianco su quel grigio
      dà ~2,9:1 — sotto la soglia. Con lo scrim di .cb-noshot il fondo dietro al testo
      scende a ~#3a3833 e il rapporto sale sopra 7:1. Misurato, non stimato.
   3. NIENTE DRAG NATIVO sulle immagini di anteprima. Le copertine del Carousel e le foto
      del Diario stanno dentro rail che si trascinano col mouse (.cbx-cards, .nt-fotos):
      il drag&drop nativo del browser partiva per primo e portava via la foto invece di
      far scorrere il rail. Questa è la CINTURA (WebKit/Blink); la cura che vale su tutti
      i motori è il preventDefault su dragstart in sections.js — Firefox, cioè il tablet
      Android di Emanuele, -webkit-user-drag non lo conosce. */
.cb-card.cb-noshot .cb-over{
  background:linear-gradient(to top,rgba(10,13,20,.88) 0%,rgba(10,13,20,.74) 34%,rgba(10,13,20,.55) 66%,rgba(10,13,20,.46) 100%)}
/* il segnaposto colorato riempie la copertina come farebbe una foto (senza questo resta
   alto quanto il suo aspect-ratio e sotto si vede il fondo della card) */
.cb-card.cb-poster .cb-shot .pcar-ph{position:absolute;inset:0}
/* il gradiente interno del segnaposto (.pcar-ph::after) qui è di troppo: lo scrim della card
   fa già quel mestiere, e sommati diventano una macchia scura in basso */
.cb-card.cb-noshot .cb-shot .pcar-ph::after{display:none}
/* le immagini di anteprima non si staccano dalla pagina: sono comandi, non allegati */
.pcar-card-img>img,.pcar-thumb>img,.pcar-lead-img>img,.pcar-ph,.nt-foto img{
  -webkit-user-drag:none;user-select:none;-webkit-user-select:none}
/* LAPIDE: .cb-foto (:2116) era il riquadrino della card senza foto — non lo emette più nessuno
   dal 29/07/2026. Le sue due regole restano innocue e si potranno togliere al prossimo giro
   di pulizia del CSS; qui c'è scritto perché, così non le si rianima per sbaglio. */

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   Z8 · I TASTI DI STATO DIVENTANO SOLIDI (29/07/2026)
   ═══════════════════════════════════════════════════════════════════════════════════════════
   Un badge di stato era finora una PELLICOLA: fondo semitrasparente della propria tinta
   (--c-*-bg, alpha .12-.14) e testo della stessa tinta piena. Su un pannello bianco funziona —
   il velo poggia sul chiaro e la scritta scura si stacca. Ma il fondo non è più solo bianco:
   dalla U2 le card dei cambi sono POSTER, e lì sotto c'è una fotografia. Misurato sul banco:
   «da completare» 1,90:1 e «ok» 1,97:1, contro i 3,36 e 3,58 che gli stessi badge fanno su
   fondo chiaro. Non è un difetto della card: è che un fondo trasparente non è un fondo, e
   quindi il contrasto di quel badge non se lo sceglie il badge — glielo detta quello che
   capita di avere sotto.
   La cura è togliere la dipendenza: il fondo diventa OPACO e il testo bianco. Da lì il
   rapporto è FISSO, sopra una foto, sopra un pannello o sopra qualunque cosa inventeremo.
   È anche la faccia flat che chiedeva Andrea, ma la ragione per cui si fa è la prima.

   IL CONFINE, e perché sta dove sta (censimento meccanico: 88 regole con fondo velato + testo)
   ✔ SI FANNO le pastiglie SEMANTICHE (fondo --c-*-bg + testo --c-*): sono quelle che dicono uno
     STATO, e sono le uniche che possono finire sopra una fotografia.
   ✘ NON si toccano i comandi SOPRA le foto (.fs-mark, .gal-drag, .msn-x, .fd-nav, .mb-check…,
     22 regole): hanno già fondo nero velato e testo bianco, e sulla foto misurano 13-16:1.
     Sono il modello, non il problema.
   ✘ NON si toccano i tenui d'ACCENT (.btn-soft, .tl-chip, .um-role, .ie.INT/.EXT…, 34 regole).
     Due ragioni, entrambe misurate: su fondo chiaro fanno già 5,24-6,08:1, e soprattutto il
     testo bianco sull'accent PIENO regge solo in 2 temi su 9 — negli altri sette crolla fra
     2,90 e 3,56:1 (l'accent è rimappato da ogni tema, le tinte semantiche no). Renderli
     "flat" li peggiorerebbe. E .btn-soft pieno diventerebbe indistinguibile da .btn-primary:
     si perderebbe la differenza fra il comando principale e quello secondario.
   ✘ NON si toccano i BANNER larghi (.wxcover, .db-stale): un rettangolo grande a tinta piena
     grida, e lì il velo su fondo chiaro fa il suo mestiere.
   ✘ .chip.neutral resta velato: non è una tinta accesa, è il grigio del "niente da segnalare".
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

/* ── le pastiglie di stato ─────────────────────────────────────────────────────────────────
   Il testo bianco vale per TUTTO il contenuto, icone comprese: le .ic dentro un chip ereditano
   `color`, quindi seguono da sole. Il bordo va dichiarato: dove era `currentColor` seguirebbe
   il testo e disegnerebbe una cornice bianca attorno al fondo pieno. */
.chip.ok,.chip.warn,.chip.todo,.chip.crit,.chip.info,.chip.cost,.chip.tone,
.bb-cont-hd .st.ok,.bb-cont-hd .st.warn,.bb-contchip.ok,.bb-contchip.warn,
.fd-badge.ok,.fd-badge.warn,.bb-act--done,.pg-tag.pg-hard,.sync-ind.warn,
.db-pk-cov.on,.um-msg.ok,.um-msg.err,.cmpx-ok{color:#fff;border-color:transparent}
.chip.ok,.bb-cont-hd .st.ok,.bb-contchip.ok,.fd-badge.ok,.bb-act--done,.um-msg.ok,
.cmpx-ok{background:var(--c-ok)}
.chip.warn,.chip.todo,.bb-cont-hd .st.warn,.bb-contchip.warn,.fd-badge.warn,
.sync-ind.warn{background:var(--c-warn)}
.chip.crit,.pg-tag.pg-hard,.um-msg.err{background:var(--c-crit)}
.chip.info,.db-pk-cov.on{background:var(--c-info)}
.chip.cost{background:var(--c-cost)}
.chip.tone{background:var(--tone)}
/* .sync-ind.warn teneva il bordo colorato per farsi notare da spenta: ora lo fa il fondo */
.sync-ind.warn{border-color:var(--c-warn)}

/* i due :hover in rosso completano il gesto invece di accennarlo (a riposo restano com'erano) */
.icon-btn.danger:hover,.btn-ghost.danger:hover{background:var(--c-crit);color:#fff;border-color:var(--c-crit)}

/* ── i badge Giorno/Notte/Alba (.dn) ───────────────────────────────────────────────────────
   Questi il fondo pieno ce l'avevano già dal principio: il loro difetto era l'opposto, testo
   BIANCO su tinte CHIARE. Misurato: Giorno (oro #E0A21B) 2,25:1 — la lettera D era quasi
   invisibile — e Alba/Tramonto (rosa #E6779E) 2,80:1. Qui non si scurisce la tinta, perché
   l'oro e il rosa non sono badge soltanto: sono la stella dei segnalibri, le fasce della home
   e le categorie, e cambiarli si vedrebbe ovunque. Si cambia il TESTO, che costa niente.
   Giorno passa a 6,07:1 e Alba/Tramonto a 4,87:1. Notte (indaco) faceva già 6,07 col bianco e
   resta bianco.
   IL TESTO È UN VALORE FISSO, e la ragione è una trappola in cui questa modifica era già caduta:
   il primo giro scriveva `color:var(--ink)`, che sul banco misurava benissimo (8,41 e 6,74)
   perché lì gira il tema istituzionale, dove --ink è #111111. Ma --ink lo rimappa OGNI tema, e
   nel tema scuro vale #e8eaf0 — quasi bianco: la lettera D sull'oro sarebbe scesa a 1,87:1,
   cioè peggio di prima della cura. Il fondo di questi badge invece è FISSO (l'oro e il rosa non
   li rimappa nessun tema), e un fondo fisso vuole un testo fisso: se uno dei due segue il tema
   e l'altro no, il contrasto è un caso.
   #3a2c00 non è un colore nuovo: è lo stesso inchiostro caldo già scelto per .preset.on.day
   (:1101), che risolveva esattamente questo — una scritta scura sopra l'oro. */
.dn.D,.dn.A,.dn.T{color:#3a2c00}

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   Z2 · LA DATA CHE SI SPINGE ADDOSSO AL CAMPO ACCANTO  (29/07/2026 — chiuso con le foto di
   Andrea dall'iPad vero, IMG_1240/IMG_1241)
   ───────────────────────────────────────────────────────────────────────────────────────────
   Andrea lo segnalava da settimane: «il calendario è ancora compenetrato con il dato sulla
   destra». Tre giorni di misure in emulazione non hanno mai trovato niente — 39 prove, 3 motori
   (WebKit/Chromium/Firefox) × 13 configurazioni iPad, Split View e le soglie 920/921 comprese,
   e SEMPRE zero sovrapposizioni. Non perché l'app fosse a posto: perché lo strumento misurava
   l'intersezione geometrica dei due rettangoli, e i rettangoli non si toccano davvero. Mai.
   Quello che si sposta è il TESTO DENTRO il campo. Su iOS il valore di un <input type="date">
   non lo disegna il nostro CSS: lo disegna WebKit, dentro lo pseudo-elemento
   ::-webkit-date-and-time-value, che di suo è CENTRATO. Con l'input largo quanto la colonna
   (width:100%), «29 lug 2026» finisce a metà del box — cioè a ridosso del bordo destro — mentre
   ODG numero, Produzione, Titolo, Regia, Giornata, Episodio e tutti gli orari partono da
   sinistra. Un campo su nove allineato diversamente, e per giunta proprio quello che confina
   con «Giorno settimana»: l'occhio lo legge come un campo che sconfina nell'altro. Andrea non
   ha usato la parola sbagliata — l'ha usata per un difetto che non era dove lo cercavamo.
   Nessun motore desktop lo riproduce (lì il valore è già a sinistra), ed è per questo che
   l'emulatore diceva il vero: NON C'È, sullo schermo che stava emulando.
   La cura è una riga di allineamento. Scritta per TUTTA la famiglia data/ora anche se oggi in
   FlowSet esiste un solo campo così (odg.js:1034, la Data della testata ODG) e nessun type=time
   — il giorno che ne nasce un secondo non deve ricominciare da capo. ::-webkit-datetime-edit è
   il gemello desktop dello stesso pseudo (Chrome/Edge): lì il valore è già a sinistra, la riga
   è inerte, e serve solo a non lasciare la regola vera da sola.
   ⚠ LEZIONE, vale oltre questo caso: uno strumento che misura la cosa sbagliata non dà un
   risultato debole, ne dà uno FALSO — e un «0 sovrapposizioni su 39 misure» sembra una prova.
   Vedi nodo global--prova-del-nove-del-collaudo §20.                                          */
input[type="date"],input[type="time"],input[type="month"],input[type="week"],input[type="datetime-local"]{text-align:left}
input[type="date"]::-webkit-date-and-time-value,
input[type="time"]::-webkit-date-and-time-value,
input[type="month"]::-webkit-date-and-time-value,
input[type="week"]::-webkit-date-and-time-value,
input[type="datetime-local"]::-webkit-date-and-time-value{text-align:left}
input[type="date"]::-webkit-datetime-edit,
input[type="time"]::-webkit-datetime-edit,
input[type="month"]::-webkit-datetime-edit,
input[type="week"]::-webkit-datetime-edit,
input[type="datetime-local"]::-webkit-datetime-edit{text-align:left}

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   Z11b · ZOOM SULLA FOTO — appoggio CSS  (29/07/2026, appunto di Andrea)
   ───────────────────────────────────────────────────────────────────────────────────────────
   Andrea: «se provo a zoommare da Safari si zooma l'app sotto al carosello, non la foto».
   Ha ragione, e non è un bug nostro: è il comportamento di default. Finché nessuno dichiara di
   voler gestire il pizzico, il gesto appartiene al BROWSER, che fa l'unica cosa che sa fare —
   ingrandire la pagina. touch-action:none è la dichiarazione: dentro il visore i gesti li
   gestiamo noi (carousel.js, blocco ZOOM). Vale solo dentro .pcar-stage, cioè solo mentre il
   visore è aperto: fuori, il pinch di sistema resta quello di sempre.
   La transizione è dichiarata SOLO sulla classe .zooming-off (messa a mano quando lo zoom si
   azzera): durante il gesto ogni frame deve essere immediato, un transition qui darebbe
   l'effetto elastico che fa sembrare l'app lenta.                                             */
.pcar-back.pinned .pcar-stage{touch-action:none}
.pcar-full{transform-origin:0 0}
img.pcar-full.zoom-anim{transition:transform .18s cubic-bezier(.2,.8,.2,1)}
img.pcar-full.zoomed{cursor:grab}
img.pcar-full.zoom-grab{cursor:grabbing}
/* a zoom attivo i comandi si fanno da parte: coprirebbero la parte di foto che si sta guardando */
.pcar-back.pinned.is-zoom .pcar-nav,.pcar-back.pinned.is-zoom .pcar-foot{opacity:0;pointer-events:none;transition:opacity .16s}
@media (prefers-reduced-motion:reduce){img.pcar-full.zoom-anim{transition:none}}

/* ═══ AB2/AB3 (30/07/2026) — TAB CONTINUITY · blocco APPEND in coda ═══════════════════════════
   Zero componenti nuovi e zero colori nuovi: la tab RIUSA .an2-sec (sezioni collassabili
   dell'Anagrafica), .table (liste), .chip (stati), .row-act/.icon-btn (azioni di riga) e
   .role-sw (lo switcher delle due facce, il cui selettore è stato ESTESO a .cont-view-sw nei
   3 punti storici — non è stata scritta una quarta regola). Qui vivono solo le rifiniture che
   quei componenti non hanno: l'etichetta della variante, il rientro del blocco-variante nel
   pannello di registrazione e il preventivo della duplica. */
.cont-sec-sub{font-weight:400;font-size:12.5px;margin-left:6px}
.an2-sec-n.ok{background:var(--c-ok-bg);color:var(--c-ok)}
.cont-table td[data-label="Note"]{overflow-wrap:anywhere}   /* regola O.3: il testo dell'utente cede, l'etichetta no */
.cont-table .cont-td-note{max-width:420px}
.cont-table tr.cont-r-empty td{opacity:.62}                  /* la coppia ancora da registrare resta leggibile ma non compete con quelle piene */
.cont-var-tag{display:inline-flex;align-items:center;gap:4px;font:700 11px var(--ff-mono);letter-spacing:.03em;text-transform:uppercase;
  background:var(--accent-soft);color:var(--accent-deep);border-radius:var(--r-pill);padding:2px 9px;margin-left:8px}
.cont-var-tag.sm{padding:1px 7px;font-size:10.5px;margin-left:6px}
.cont-var-tit{font-size:13px;color:var(--t2);margin-left:8px}
.cont-pers.cont-var{border-left:3px solid var(--accent-soft);margin-left:14px}   /* la variante è FIGLIA della principale, e si vede */
.cont-vtit{flex:1 1 160px;min-width:0;max-width:320px;height:32px;font-size:13px;margin-left:8px}
.cont-pers-head .cont-vdel{margin-left:auto}
.cont-dup-src{margin:14px 0 8px;padding:10px 14px;background:var(--s2);border:1px solid var(--border);border-radius:var(--r);font-size:13.5px}
.cont-dup-prev{padding:10px 14px;border:1px dashed var(--accent-bord);border-radius:var(--r);font-size:13.5px;line-height:1.55;background:var(--accent-soft)}
.cont-dup-prev.warn{border-color:var(--c-warn);background:var(--c-warn-bg)}
.cont-dup-warn{color:var(--c-warn);font-weight:600}
@media (max-width:560px){
  .cont-table .cont-td-note{max-width:none}
  .cont-pers.cont-var{margin-left:0;border-left-width:2px}
  .cont-vtit{max-width:none;margin-left:0;flex-basis:100%}
}

/* AC (30/07/2026) — «Nuova continuità» e il fuoco sul personaggio scelto. Nessun componente
   nuovo: le pillole del cast riusano la forma dei chip (.chip) con lo stato .on dell'accento,
   il riquadro a fuoco riusa l'anello .accent-bord già in uso per il campo attivo dei form. */
.cont-new-h{font-weight:600;font-size:13px;margin:12px 0 8px}
.cont-new-chips{display:flex;flex-wrap:wrap;gap:8px}
.cont-new-p{display:inline-flex;align-items:center;gap:7px;min-height:38px;padding:8px 14px;font-size:13px;
  background:var(--s2);border:1px solid var(--border);border-radius:var(--r-pill);cursor:pointer;
  transition:background var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out)}
.cont-new-p:hover{background:var(--s3);border-color:var(--accent-bord)}
.cont-new-p.on{background:var(--accent-soft);border-color:var(--accent);color:var(--accent-deep);font-weight:600}
.cont-new-n{font:700 11px var(--ff-mono);background:var(--c-ok-bg);color:var(--c-ok);border-radius:var(--r-pill);padding:1px 7px}
.cont-pers.cont-fuoco{box-shadow:0 0 0 2px var(--accent-bord);border-radius:var(--r)}
.h4-lk.h4-cont{cursor:pointer}

/* ═══ AD (31/07/2026) — LA GALLERIA DEL FORM · blocco APPEND ═══════════════════════════════════
   Le miniature che Emanuele ha chiesto «stile galleria android»: quadrate, in griglia che si
   adatta, la ✕ nell'angolo, la ★ sulla predefinita della copia. Nessun componente nuovo inventato
   da zero — la forma è quella delle thumb del carosello (quadrato, object-fit:cover, angolo
   morbido), il contenitore è la stessa scatola grigia dei riquadri di form (.cont-dup-src), e i
   token sono quelli di sempre. L'unico colore fuori palette è il giallo della stellina, che è già
   il giallo del segnalibro nel visore: la stessa cosa deve avere lo stesso colore.
   La ✕ ha fondo scuro semitrasparente perché sta SOPRA una fotografia, dove nessun token di
   sfondo garantisce contrasto (stessa ragione dello scrim .cb-noshot di Z7).                    */
.fm-gal{margin:14px 0 4px;padding:12px 14px;background:var(--s2);border:1px solid var(--border);border-radius:var(--r)}
.fm-gal-h{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.fm-gal-t{font-weight:600;font-size:13px}
.fm-gal-n{font:400 12px var(--ff-mono);color:var(--t3)}
.fm-gal-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(76px,1fr));gap:8px;margin-top:10px}
.fm-gal-it{position:relative;aspect-ratio:1;border-radius:var(--r);overflow:hidden;background:var(--s3);border:1px solid var(--border)}
.fm-gal-it.master{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-bord)}
.fm-gal-open{position:absolute;inset:0;width:100%;height:100%;padding:0;margin:0;border:0;background:none;cursor:zoom-in}
.fm-gal-open img{width:100%;height:100%;object-fit:cover;display:block;-webkit-user-drag:none;user-select:none}
.fm-gal-ph{display:flex;align-items:center;justify-content:center;width:100%;height:100%;color:var(--t3)}
.fm-gal-x{position:absolute;top:3px;right:3px;width:24px;height:24px;display:flex;align-items:center;justify-content:center;
  border:0;border-radius:50%;background:rgba(17,17,17,.62);color:#fff;cursor:pointer;padding:0;line-height:0;
  transition:background var(--dur-fast) var(--ease-out)}
.fm-gal-x:hover{background:var(--c-err,#c0392b)}
.fm-gal-star{position:absolute;bottom:1px;left:5px;font-size:15px;color:#ffd23f;text-shadow:0 1px 2px rgba(0,0,0,.55);pointer-events:none}
.fm-gal-tag{position:absolute;bottom:3px;right:4px;font:700 9.5px var(--ff-mono);letter-spacing:.02em;text-transform:uppercase;
  color:#fff;background:rgba(17,17,17,.6);border-radius:var(--r-pill);padding:1px 6px;pointer-events:none}
.fm-gal-empty{margin:10px 0 0;font-size:12.5px;color:var(--t3);overflow-wrap:anywhere}   /* regola O.3 */
.fm-gal-act{margin-top:10px}
/* ── AE1 · LA CONFERMA UNICA (.ask-*) ───────────────────────────────────────────────────────
   Una forma sola per ogni «sei sicuro?» del sito: solo le scritte cambiano. Vive in un overlay
   PROPRIO e non in .modal-back, perché deve poter comparire sopra un modale (la ✕ di una
   miniatura sta dentro il form di duplica) — z-index 130, cioè sopra i modali (90) e sopra il
   visore foto (120). Stessa scelta di .db-ovl/.um-ovl, per la stessa ragione.
   Su smartphone i due tasti si impilano e il distruttivo finisce IN BASSO, sotto il pollice ma
   non dove il pollice cade per caso: column-reverse mette Annulla sopra Elimina.               */
.ask-ovl{position:fixed;inset:0;z-index:130;display:grid;place-items:center;padding:18px;
  background:rgba(17,24,39,.5);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  opacity:0;transition:opacity .16s var(--ease-out)}
.ask-ovl.on{opacity:1}
.ask-box{width:min(430px,100%);background:var(--s1,#fff);border:1px solid var(--border);border-radius:var(--r);
  box-shadow:var(--sh-2);padding:20px 22px;transform:translateY(7px) scale(.99);
  transition:transform .16s var(--ease-out)}
.ask-ovl.on .ask-box{transform:none}
.ask-t{font-size:16px;font-weight:700;line-height:1.32;overflow-wrap:anywhere}
.ask-p{margin-top:8px;font-size:13.5px;color:var(--t2);line-height:1.55;overflow-wrap:anywhere}
.ask-act{margin-top:18px;display:flex;gap:10px;justify-content:flex-end;flex-wrap:wrap}
.ask-img{text-align:center;margin-bottom:14px}
.ask-img img{max-width:210px;max-height:170px;border-radius:var(--r);border:1px solid var(--border)}
@media (max-width:560px){
  .ask-box{padding:16px}
  .ask-act{flex-direction:column-reverse;gap:8px}
  .ask-act .btn{width:100%;justify-content:center}
  .ask-img img{max-width:150px;max-height:130px}
}
@media (prefers-reduced-motion:reduce){ .ask-ovl,.ask-box{transition:none} }
@media (max-width:560px){
  .fm-gal{padding:10px 11px}
  .fm-gal-grid{grid-template-columns:repeat(auto-fill,minmax(68px,1fr));gap:7px}
  .fm-gal-x{width:28px;height:28px}          /* sotto il dito, non sotto il mouse */
  .fm-gal-askimg img{max-width:160px;max-height:140px}
}

/* ══ AE2a (30/07/2026) — LA BARRA DEL RIPRISTINO ═══════════════════════════════════════════════
   La gemella in uscita di `.ask-ovl`: la domanda prima, l'offerta di tornare indietro dopo.
   Portale proprio appeso al <body> (app.js undoBar), z-index 125 — SOTTO la conferma (130) e
   SOPRA i modali (100/110) e l'overlay dashboard (120): mentre confermi non deve coprirti la
   domanda, ma dopo deve stare davanti a tutto, anche a un form rimasto aperto.
   ⚠ Lo z-index è DICHIARATO nei contratti (UNDO-RIPRISTINA, atteso `=== 125`): cambiarlo qui
   fa fallire il gate delle viste, ed è voluto — è un numero che regge un ordine di sovrapposizione,
   non una preferenza estetica.                                                                  */
.undo-bar{position:fixed;left:50%;bottom:26px;transform:translateX(-50%) translateY(14px);z-index:125;
  display:flex;align-items:center;gap:12px;max-width:min(560px,calc(100vw - 28px));
  background:var(--ink);color:#fff;border-radius:14px;padding:12px 12px 12px 18px;
  box-shadow:var(--sh-pop);font-size:13px;font-weight:500;line-height:1.35;overflow:hidden;
  opacity:0;transition:opacity .18s ease,transform .18s cubic-bezier(.2,.8,.2,1)}
.undo-bar.on{opacity:1;transform:translateX(-50%) translateY(0)}
.ub-msg{flex:1;min-width:0}
.ub-msg b{font-weight:700}
.ub-act{flex:none;background:rgba(255,255,255,.16);color:#fff;border:0;border-radius:8px;
  padding:7px 14px;font-weight:700;font-size:12.5px;cursor:pointer;transition:background .12s}
.ub-act:hover{background:rgba(255,255,255,.3)}
.ub-x{flex:none;background:none;border:0;color:rgba(255,255,255,.55);font-size:14px;line-height:1;
  cursor:pointer;padding:6px 4px;transition:color .12s}
.ub-x:hover{color:#fff}
/* il tempo che resta si VEDE: una barra che si consuma, non un numero che nessuno legge */
.ub-timer{position:absolute;left:0;right:0;bottom:0;height:2px;background:rgba(255,255,255,.14)}
.ub-timer i{display:block;height:100%;background:rgba(255,255,255,.5);transform-origin:left center;
  animation:ubTick linear forwards}
@keyframes ubTick{from{transform:scaleX(1)}to{transform:scaleX(0)}}
/* i toast normali salgono, o finirebbero SOTTO la barra (stesso angolo, .toast-wrap bottom:26px) */
body.has-undo .toast-wrap{bottom:96px}
@media (max-width:640px){
  /* regola 7 del canone: sul telefono è a tutta larghezza, e il tasto resta sotto il dito */
  .undo-bar{left:12px;right:12px;bottom:14px;transform:translateY(14px);max-width:none;padding:11px 10px 11px 15px}
  .undo-bar.on{transform:translateY(0)}
  .ub-act{padding:9px 14px}
  body.has-undo .toast-wrap{bottom:88px}
}
@media (prefers-reduced-motion:reduce){ .undo-bar{transition:none} .ub-timer i{animation:none} }

/* ══ AE2a-bis (30/07/2026) — IL TITOLO DI CATEGORIA NON SI SBRICIOLA (difetto FIREFOX-ONLY) ═════
   Segnalato da Emanuele: in Anagrafica «Feat./extra», «Crow/d», «Stunt/s», «prov/a» — a capo
   DENTRO la parola, con mezzo pannello di spazio libero a destra. Su Chrome non succede: l'ha
   provato lui sui due browser, ed è la ragione per cui le mie 42 misure su Chromium headless
   dicevano tutte «0 spezzati». Le guardie di casa girano tutte su Chromium: un difetto
   Firefox-only è, per costruzione, invisibile al gate.
   LA CAUSA: `.an2-sec-title` è un flex container e il titolo era un NODO DI TESTO NUDO — cioè un
   flex item ANONIMO. Firefox lo lascia comprimere sotto la sua min-content e la parola si spezza;
   Blink no. Non è un bug di Firefox da aggirare a tentoni: è markup che chiedeva al motore di
   indovinare. La cura è dare al titolo un elemento SUO (`.an2-sec-lbl`, sections.js) e dirgli a
   chiare lettere cosa deve fare — e allora i due motori non hanno più niente da interpretare.
   E se un giorno lo spazio mancasse per davvero, fa i PUNTINI come i nomi lunghi altrove, non si
   sbriciola: un titolo tagliato si legge, un titolo a pezzi no.                                  */
.an2-sec-lbl{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.an2-sec-n{flex:none}
