/* ==========================================================================
   dt-ui — Design system Design Tessile ERP
   Stile: denso / professionale. Temi: light + dark via [data-theme].
   Tutti i moduli ERP devono usare SOLO queste variabili e classi.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design tokens
   -------------------------------------------------------------------------- */

:root {
  /* Tipografia */
  --dt-font-ui: "Inter", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", sans-serif;
  --dt-font-mono: "JetBrains Mono", "Cascadia Mono", "Consolas", ui-monospace, monospace;

  /* La scala e' salita di mezzo gradino su tutta la riga. Denso resta denso —
     una riga di tabella cresce di due pixel — ma il programma si legge in
     furgone, su un tablet appoggiato al cruscotto e con la luce di fuori, e
     lassu' i dieci pixel e mezzo delle scritte minute (l'indirizzo, l'orario
     dentro al blocco, la data in tabella) erano il primo pezzo di interfaccia
     a diventare una macchia grigia.
     Il rapporto fra i gradini e' rimasto quello: quello che era secondario si
     legge ancora come secondario.

     Stretta la finestra la scala sale, e sale scorrendo. Un telefono tenuto in
     mano sta a meta' della distanza di un monitor ma ha un quarto della sua
     larghezza: le stesse tredici unita' che in ufficio sono dense, lassu' sono
     piccole. Non c'e' una soglia in cui il testo diventa grande di colpo — la
     misura si interpola fra i 720px, dove resta quella dell'ufficio, e i 360px
     di un telefono stretto, dove e' un gradino e mezzo piu' su. Un gradino di
     mezzo, non due: quello che deve restare denso resta denso, e i rapporti
     fra i gradini non si toccano, cosi' il secondario si legge ancora come
     secondario.
     La pendenza e' la stessa per tutti (`- 0.56vw`), che e' l'unico modo per
     cui la scala si alza tutta insieme invece di stringersi a fisarmonica. */
  --dt-fs-xs: clamp(11px, 15px - 0.56vw, 12.5px);
  --dt-fs-sm: clamp(12px, 16px - 0.56vw, 13.5px);
  --dt-fs-md: clamp(13px, 17px - 0.56vw, 15px);     /* base ERP: denso ma leggibile */
  --dt-fs-lg: clamp(15px, 19px - 0.56vw, 17px);
  --dt-fs-xl: clamp(18px, 22px - 0.56vw, 20px);
  /* Le due misure grosse non salgono: sono i numeri dei riquadri e i titoli, e
     a ventitre pixel non erano piccoli nemmeno in furgone. Farli crescere
     sullo stretto vuol dire solo che due riquadri di numeri non ci stanno piu'
     affiancati — il contrario di quello che serve su un telefono. */
  --dt-fs-2xl: 23px;
  --dt-fs-3xl: 31px;

  --dt-lh-tight: 1.2;
  --dt-lh-normal: 1.45;

  --dt-fw-regular: 400;
  --dt-fw-medium: 500;
  --dt-fw-semibold: 600;
  --dt-fw-bold: 700;

  /* Spaziature (scala 2px, densa) */
  --dt-sp-0: 0px;
  --dt-sp-1: 2px;
  --dt-sp-2: 4px;
  --dt-sp-3: 6px;
  --dt-sp-4: 8px;
  --dt-sp-5: 12px;
  --dt-sp-6: 16px;
  --dt-sp-7: 20px;
  --dt-sp-8: 24px;
  --dt-sp-9: 32px;
  --dt-sp-10: 48px;

  /* Raggi.
     Tre gradini e non quattro sfumature: il quadretto (una casella di spunta,
     un campione di colore), la cosa che si preme o si scrive, e il riquadro
     che contiene le altre. Sono saliti di un pixel ciascuno perche' col corpo
     del testo cresciuto un raggio da tre pixel su una casella alta ventotto
     tornava a sembrare uno spigolo vivo. */
  --dt-r-xs: 2px;
  --dt-r-sm: 4px;
  --dt-r-md: 6px;
  --dt-r-lg: 10px;
  --dt-r-full: 999px;

  /* Altezze controlli — coerenza verticale su tutta la piattaforma */
  --dt-h-sm: 22px;
  --dt-h-md: 28px;
  --dt-h-lg: 34px;
  /* Fuori dall'ufficio si preme col pollice e senza mirare: i controlli che
     l'operatore usa in cantiere non stanno sulla scala densa, hanno la loro. */
  --dt-h-tocco: 40px;
  /* Quanto e' alto un tastino dentro alla barra di comandi di una riga. E' una
     misura sua e non `--dt-h-sm` perche' sul telefono passa al pollice mentre
     un bollino resta un bollino — e perche' la riga che lo contiene deve
     saperlo: sotto ai 560px e' la barra dei comandi, non il testo, a decidere
     quanto e' alta una riga d'elenco. Vedi `--dt-riga-h`. */
  --dt-h-comando: var(--dt-h-sm);

  /* Layout.
     Le misure che dipendono dalla finestra non saltano a una soglia: si
     interpolano. `clamp` tiene fermi un minimo e un massimo e in mezzo lascia
     scorrere la misura con la larghezza, cosi' fra uno stadio e l'altro del
     responsive non c'e' uno scatto ma una salita, e chi ridimensiona la
     finestra vede il disegno seguirlo invece di riassestarsi di colpo.
     Le soglie restano dove a cambiare e' la disposizione — una colonna che
     va sotto, una barra che passa in fondo: quello e' un altro disegno, non
     lo stesso piu' stretto. */
  --dt-sidebar-w: clamp(168px, 10vw + 40px, 208px);
  --dt-topbar-h: 40px;
  /* Respiro del corpo pagina e dei riquadri che lo riempiono. */
  --dt-pad-body: clamp(12px, 1.4vw, 20px);
  /* Il righello degli orari di una giornata: lo stesso numero dentro alla
     colonna e nell'asse comune alle tre colonne affiancate, se no gli orari
     non cadono sopra alle tacche delle tele. */
  --dt-asse-w: clamp(34px, 3vw, 44px);
  /* Quanto e' alta una voce della barra bassa, e quindi la barra stessa. Un
     numero solo perche' non lo usa solo lei: quello che galleggia sopra alla
     pagina (gli avvisi) deve sapere dove finisce la barra per non finirci
     sotto, e due misure separate si scordano l'una dell'altra. */
  --dt-voce-h: 46px;
  --dt-barra-bassa-h: calc(
    var(--dt-voce-h) + var(--dt-sp-3) * 2 + env(safe-area-inset-bottom, 0px)
  );

  /* Il binario degli elenchi: riferimenti e catalogo.
     Una riga d'elenco comincia sempre con le stesse corsie, larghe uguali e
     sempre allo stesso posto: la maniglia da cui si prende, la freccia che
     apre, e — su una riga che non ha ne' l'una ne' l'altra — il vuoto che ne
     tiene la misura. Sono queste tre misure a incolonnare il bordo sinistro di
     tutte le righe di tutte le schermate: prima ogni riga se lo decideva da
     se', e due elenchi accanto non cominciavano nella stessa colonna.
     Il passo e' di quanto rientra un piano dell'albero, ed e' anche dove cade
     il filo che regge quel piano: mezza corsia dal bordo della riga sopra, cioe'
     sotto al segno da cui quel piano si e' aperto. */
  --dt-corsia: 22px;
  /* Quanto la corsia del segno sta staccata dal nome. Piu' del passo fra le
     corsie — che restano attaccate fra loro, sono due segni — perche' li'
     comincia la parte che si legge: sei pixel da tutte e due le parti facevano
     del segno la prima lettera del nome. Una misura sola, usata dalla voce e
     dalla tendina, se no i nomi delle due escono da colonne diverse. */
  --dt-corsia-testo: 10px;
  --dt-riga-x: var(--dt-sp-4);
  --dt-passo: calc(var(--dt-riga-x) + var(--dt-corsia) / 2);

  /* **Quanto e' alta una riga d'elenco. Una misura sola, in tutte le schede.**
     L'altezza se la decideva il contenuto: una riga col solo nome era alta
     quarantotto, una col nome e una scritta sotto quarantaquattro, e le
     attivita' — che sotto al nome ne hanno due — sessantadue. Tre passi
     diversi in tre linguette della stessa barra, e scorrendo da una all'altra
     l'elenco cambiava respiro senza che fosse cambiato niente di quello che
     c'era scritto.
     Qui il passo lo decide la misura, e il contenuto ci sta dentro: e' il nome
     piu' **una** riga di sottotitolo, e resta quello anche dove il sottotitolo
     non c'e' e dove ne servirebbero due (vedi `.dt-voce__sotti`, che le mette
     in fila invece che in colonna).
     Cresce col carattere invece di essere un numero fisso, perche' la scala
     tipografica sale stringendo la finestra: a un numero fisso il testo di un
     telefono sfonderebbe la riga proprio dove la riga conta di piu'. Il pixel
     in piu' e' per gli arrotondamenti del motore, che tira su la riga di testo
     al centesimo: senza, una riga poteva restare piu' alta delle altre di
     mezzo capello.
     I tre numeri fra cui sceglie sono le tre cose che una riga contiene: il
     pollice (`--dt-h-tocco`, il pavimento: sotto quello non si scende), quello
     che c'e' scritto, e la barra dei comandi col suo filo intorno — che in
     ufficio e' la piu' bassa delle tre e sul telefono la piu' alta, ed e' il
     motivo per cui una misura scritta a mano qui si sarebbe scollata da sola
     alla prima soglia. */
  --dt-riga-testo: calc((var(--dt-fs-md) + var(--dt-fs-sm)) * var(--dt-lh-normal) + 1px);
  --dt-riga-h: calc(
    max(
      var(--dt-h-tocco),
      var(--dt-riga-testo),
      calc(var(--dt-h-comando) + 2px)
    ) + var(--dt-sp-2) * 2
  );

  /* Motion */
  --dt-t-fast: 90ms ease;
  --dt-t-med: 160ms ease;
  /* Quando a spostarsi e' una cosa larga quanto una colonna: la stessa
     velocita' di un colore che cambia, su quella distanza, sarebbe uno strappo.
     Parte svelta e si posa piano, come una cosa che ha una massa. */
  --dt-t-slitta: 240ms cubic-bezier(0.22, 0.61, 0.36, 1);

  --dt-z-sticky: 100;
  --dt-z-menu: 200;
  --dt-z-modal: 900;
  --dt-z-toast: 1000;
  --dt-z-tooltip: 1100;
}

/* Tema chiaro (default).
   Palette "inchiostro": monocromatica, l'accento e' il nero.
   L'unico colore in pagina e' quello di stato, cosi' un errore o un avviso
   si vede subito anche in una griglia dati fitta. */
:root,
[data-theme="light"] {
  color-scheme: light;

  --dt-bg: #f2f2f0;
  --dt-surface: #ffffff;
  --dt-surface-2: #f8f8f7;
  --dt-surface-3: #e9e9e6;
  --dt-surface-inset: #f2f2f0;

  --dt-border: #d9d9d5;
  --dt-border-soft: #e9e9e6;
  --dt-border-strong: #ababa5;

  /* Tre gradini di grigio, non quattro sfumature dello stesso.
     Il terzo era #85857f: sul bianco fa 3,6 a 1, e sotto ci stavano gli
     indirizzi, le date e gli orari — roba piccola, che si legge di sguincio e
     che a quel contrasto in cantiere spariva. Adesso il secondo sta a 9,6 e il
     terzo a 5,3: restano tre pesi diversi e riconoscibili, ma anche il piu'
     smorto e' sopra alla soglia di leggibilita' per le scritte piccole. */
  --dt-text: #131313;
  --dt-text-2: #45453f;
  --dt-text-3: #6c6c65;
  /* La freccia delle tendine a discesa: la stessa `chevron-down` del set di
     icone, col colore scritto per esteso perche' dentro a un `<select>` non ci
     va un elemento da cui ereditarlo. */
  --dt-freccia-giu: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236c6c65' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  --dt-text-inv: #ffffff;

  --dt-accent: #1c1c1a;
  --dt-accent-hover: #333330;
  --dt-accent-active: #000000;
  --dt-accent-soft: #ececea;
  --dt-accent-border: #b8b8b2;

  --dt-danger: #b3382f;
  --dt-danger-hover: #962e26;
  --dt-danger-soft: #fae9e6;
  --dt-danger-border: #ebb3ac;

  --dt-warn: #96660c;
  --dt-warn-soft: #faf0da;
  --dt-warn-border: #e3c489;

  --dt-ok: #2c6e49;
  --dt-ok-hover: #235a3b;
  --dt-ok-soft: #e3f1e8;
  --dt-ok-border: #a7cfb6;

  --dt-info: #2b6382;
  --dt-info-soft: #e4eff5;
  --dt-info-border: #a8c8db;

  --dt-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.08);
  --dt-shadow-md: 0 3px 8px rgba(0, 0, 0, 0.11), 0 1px 2px rgba(0, 0, 0, 0.07);
  --dt-shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.18);
  --dt-overlay: rgba(18, 18, 17, 0.45);

  /* La riga pari di una tabella. Era #f9f9f8, un punto e mezzo di grigio: sul
     monitor dell'ufficio non si vedeva affatto, e una zebratura che non si
     vede e' solo un valore in piu' da mantenere. */
  --dt-zebra: #f5f5f2;
  --dt-hover: rgba(0, 0, 0, 0.055);
  --dt-selected: #ececea;

  /* Tinte dei blocchi della giornata: dal codice arriva solo la tonalita', il
     resto lo decide il tema. Campiture pastello — chiare e poco cariche — con
     la scritta scura sopra: la tonalita' resta quella che distingue un viaggio
     da un montaggio dall'altra parte del furgone, ma il colore poggia sotto la
     scritta invece di gridare, e una giornata piena non diventa un muro di
     campiture accese.
     In OKLCH e non in HSL: due tinte HSL con la stessa luminosita' scritta
     non hanno la stessa luminosita' vista — un ciano al 50% acceca dove un
     blu al 50% e' cupo — e le quattro tinte finirebbero una piu' carica
     dell'altra senza che nessuno l'abbia voluto. In OKLCH la luminosita' e'
     quella percepita, quindi un numero solo vale per tutte e quattro. */
  /* La luminosita' e' scesa da 86 a 82, e non per smorzare: e' il contrario.
     In OKLCH il tetto di croma che lo schermo sa fare dipende dalla
     luminosita', e a 86 quel tetto strozzava mezza ruota — il turchese si
     fermava a 0,156 e il cielo a 0,069, cioe' meno della meta' di quello che
     l'occhio sa distinguere. Quattro punti piu' in basso il tetto si alza per
     tutte, e le tinte in `tinte.rs` sono salite di conseguenza (dal 19% del
     cielo al 50% della menta). Il fondo e' piu' colorato, non piu' scuro: la
     scritta nera sopra tiene comunque un contrasto fra 11 e 12 a uno. */
  /* **La luminosita' e' del tema, non della tinta** — con una sola eccezione,
     ed e' la scala di grigi. Un grigio tonalita' non ne ha, quindi l'unica
     cosa che puo' distinguerlo da un altro grigio e' quanto e' chiaro:
     `--dt-blocco-luce` arriva dallo stile in linea insieme a tonalita' e
     carica, e dice di quanti punti la campitura sta sopra o sotto a questo
     numero. Zero — cioe' assente — per tutte le ventisei tinte colorate, che
     restano dove sono sempre state.
     La somma si scrive dove la campitura si compone e non qui, perche' qui
     `--dt-blocco-luce` non c'e' ancora: una proprieta' personalizzata risolve
     i suoi `var()` dove e' scritta, e scritta su `:root` si porterebbe dietro
     lo zero fino in fondo alla pagina.
     La banda in cui i grigi possono muoversi la fissa `tinte.rs`: otto punti
     per parte, che sul tema scuro vuol dire un fondo mai sotto al 68% — sotto,
     il velo dell'orario smetterebbe di reggere sopra al pastello. */
  --dt-tinta-l: 82%;
  --dt-tinta-c: 0.08;
  --dt-tinta-c-scala: 1;
  /* Il fondo del blocco che si sta per premere: piu' scuro, non piu' chiaro.
     Sul chiaro schiarire vorrebbe dire andare verso la pagina. */
  --dt-tinta-l-forte: 76%;
  --dt-tinta-l-bordo: 68%;
  /* Il tratteggio del blocco che le ore non le conta. Non e' il bordo di un
     blocco pieno: quello poggia su un pastello, questo sulla pagina, e a 68%
     un contorno su un fondo quasi bianco e' un colore che si indovina invece
     di vederlo. Piu' scuro il pastello si riconosce lo stesso — la tonalita'
     non cambia — e il tratteggio regge anche da un metro.
     Piu' in basso c'e' anche piu' gamut: le cariche di `tinte.rs` sono tarate
     sull'82% dei blocchi pieni, e a 55 le quattro tinte piu' pallide — cielo,
     pervinca, ghiaccio, pesca — ci starebbero larghe. Il moltiplicatore le
     tira su; quelle che a questa luminosita' sono gia' al tetto (sabbia,
     turchese, oliva) restano dove sono, che e' comunque il loro massimo. */
  --dt-tinta-l-tratto: 55%;
  --dt-tinta-c-tratto: 1.4;
  /* La scritta e' nera, non una tinta scura: su quattro pastelli diversi
     quattro scritte diverse facevano leggere ogni colonna con un peso suo, e
     il nero e' l'unico che pesa uguale su tutti e quattro. Nero anche sul
     tema scuro: il fondo del blocco resta chiaro comunque, e la scritta segue
     il blocco, non la pagina. */
  --dt-tinta-l-testo: 0%;
  --dt-tinta-c-testo: 0;
  /* **Il velo**: la stessa tinta appena accennata sopra alla pagina. E' il
     primo dei tre livelli in cui una campitura si presenta — velato,
     acquerellato, pieno — e serve dove il colore deve dire *quale*, non
     *quanto*: la striscia di un viaggio calcolato, il fondo di una riga di
     catalogo.
     Il velo lo scostamento dei grigi se lo prende a meta' e non tutto, e senza
     mai passare il 96%: qui si parte gia' dal 95, e un grigio chiaro sommato
     per intero uscirebbe piu' bianco della pagina — cioe' un velo che non si
     vede. A meta' la scala si legge lo stesso, e il pieno — dove i grigi
     contano davvero — resta quello vero. */
  --dt-velo-l: 95%;
  --dt-velo-c-scala: 0.45;
  --dt-velo-l-bordo: 87%;
  /* **L'acquerello**: la tinta di un blocco consegnato e non ancora fatto.
     Sta *in mezzo* alle altre due apposta — piu' carico del velo, piu'
     scarico del pieno di un lavoro scritto — e i tre livelli
     si leggono in fila senza didascalie: velato, acquerellato, pieno. Messo
     alla stessa altezza del velo, un appuntamento e un viaggio calcolato
     sarebbero lo stesso colore, distinti da un binario di tre pixel; messo al
     pieno non direbbe piu' che quell'ora non e' ancora successa.
     Il contorno invece e' quello dei blocchi pieni, tirato giu' di poco: e' il
     secondo segno che lo separa dal calcolato, che ha il contorno tenue e il
     binario a sinistra. */
  --dt-acquerello-l: 89%;
  --dt-acquerello-c-scala: 0.62;
  --dt-acquerello-l-bordo: 74%;
  /* Le due strisce dell'appuntamento: l'acquerello e il velo, i due livelli
     che gia' esistono. Sei punti di distanza: le righe si vedono da mezza
     stanza senza diventare un nastro da cantiere. */
  --dt-riga-l-a: 89%;
  --dt-riga-l-b: 95%;
  /* Il gradino dell'hover sulle campiture a righe: sul chiaro si scende verso
     il pieno, sullo scuro si sale — verso il basso c'e' la pagina. */
  --dt-riga-hover: 3%;
}

/* Tema scuro: stessa monocromia, accento quasi bianco. */
[data-theme="dark"] {
  color-scheme: dark;

  --dt-bg: #0e0e0d;
  --dt-surface: #161615;
  --dt-surface-2: #1d1d1c;
  --dt-surface-3: #282826;
  --dt-surface-inset: #0b0b0a;

  --dt-border: #2c2c2a;
  --dt-border-soft: #212120;
  --dt-border-strong: #454542;

  /* Stessa correzione del tema chiaro, nell'altro verso: il terzo grigio era
     #757570, 4,2 a uno sul fondo delle superfici, e sul nero le scritte
     piccole si spengono prima ancora che sul bianco. */
  --dt-text: #f0f0ee;
  --dt-text-2: #b6b6b0;
  --dt-text-3: #8f8f89;
  --dt-freccia-giu: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238f8f89' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  --dt-text-inv: #0e0e0d;

  --dt-accent: #e8e8e4;
  --dt-accent-hover: #ffffff;
  --dt-accent-active: #cfcfca;
  --dt-accent-soft: #232322;
  --dt-accent-border: #43433f;

  --dt-danger: #ef6a5f;
  --dt-danger-hover: #f4837a;
  --dt-danger-soft: #331c1a;
  --dt-danger-border: #6a3630;

  --dt-warn: #dda63f;
  --dt-warn-soft: #302713;
  --dt-warn-border: #675026;

  --dt-ok: #4dbb84;
  --dt-ok-hover: #62c996;
  --dt-ok-soft: #12291e;
  --dt-ok-border: #2b5740;

  --dt-info: #56b0cf;
  --dt-info-soft: #12262d;
  --dt-info-border: #2a5261;

  --dt-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --dt-shadow-md: 0 4px 10px rgba(0, 0, 0, 0.45);
  --dt-shadow-lg: 0 16px 40px rgba(0, 0, 0, 0.55);
  --dt-overlay: rgba(0, 0, 0, 0.62);

  --dt-zebra: #1a1a19;
  --dt-hover: rgba(255, 255, 255, 0.07);
  --dt-selected: #242422;

  /* Gli stessi pastelli, appena piu' scuri e un filo meno carichi: sul quasi
     nero un pastello chiaro sembra illuminato da dietro e ogni blocco diventa
     una lampada. Qui il blocco che si sta per premere schiarisce invece di
     scurire: verso il basso finirebbe nella pagina. */
  --dt-tinta-l: 76%;
  --dt-tinta-c: 0.08;
  --dt-tinta-c-scala: 0.95;
  --dt-tinta-l-forte: 82%;
  --dt-tinta-l-bordo: 62%;
  /* Qui il tratteggio va nell'altro verso: sotto c'e' la pagina quasi nera, e
     scurirlo lo spegnerebbe. Piu' chiaro del pastello pieno, cosi' il contorno
     resta la cosa piu' accesa di un blocco che dentro non ha niente. Qui la
     carica resta quella dei blocchi pieni: a 78% il tetto e' quello di
     partenza, e caricare di piu' vorrebbe dire solo farla tagliare allo
     schermo. */
  --dt-tinta-l-tratto: 78%;
  --dt-tinta-c-tratto: 1;
  --dt-tinta-l-testo: 0%;
  --dt-tinta-c-testo: 0;
  /* Sul quasi nero il velo va nell'altro verso — e' un fondo scuro colorato,
     con la scritta chiara della pagina sopra — e va caricato di piu': a queste
     luminosita' la stessa carica non si vede. */
  --dt-velo-l: 23%;
  --dt-velo-c-scala: 0.55;
  --dt-velo-l-bordo: 33%;
  /* Sul fondo scuro la distanza fra velo e pieno e' molto piu' larga — 23% e
     76% — e l'acquerello sta a meta' come di la'. */
  --dt-acquerello-l: 46%;
  --dt-acquerello-c-scala: 0.72;
  --dt-acquerello-l-bordo: 58%;
  /* Sul quasi nero la coppia velo/acquerello dista ventitre' punti, e a
     righe alterne sarebbe un nastro da cantiere: le strisce si prendono una
     distanza loro, otto punti, come di la'. */
  --dt-riga-l-a: 46%;
  --dt-riga-l-b: 38%;
  --dt-riga-hover: -4%;
}

/* --------------------------------------------------------------------------
   2. Reset + base
   -------------------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
}

/* Il trackpad a due dita, arrivato a fondo corsa, fa scivolare via la pagina
   con l'animazione di "indietro" del browser: qui non c'e' cronologia da
   sfogliare, e l'ERP sembra rotto. Il gesto si ferma dentro al contenitore.
   Nella finestra desktop la stessa cosa la spegne `additionalBrowserArgs`. */
html,
body,
.dt-app__body,
.dt-nav,
.dt-scroll {
  overscroll-behavior: none;
}

body {
  background: var(--dt-bg);
  color: var(--dt-text);
  font-family: var(--dt-font-ui);
  font-size: var(--dt-fs-md);
  line-height: var(--dt-lh-normal);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6, p, figure {
  margin: 0;
}

a {
  color: var(--dt-accent);
  text-decoration: none;
}
a:hover { text-decoration: underline; }

::selection {
  background: var(--dt-accent);
  color: var(--dt-text-inv);
}

:focus-visible {
  outline: 2px solid var(--dt-accent);
  outline-offset: 1px;
}

/* Scrollbar coerente col tema */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--dt-border-strong) transparent;
}
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--dt-border-strong);
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: var(--dt-r-full);
}
*::-webkit-scrollbar-thumb:hover { background-color: var(--dt-text-3); background-clip: content-box; }

/* --------------------------------------------------------------------------
   3. Tipografia utility
   -------------------------------------------------------------------------- */

.dt-h1 { font-size: var(--dt-fs-3xl); font-weight: var(--dt-fw-bold); line-height: var(--dt-lh-tight); letter-spacing: -0.02em; }
.dt-h2 { font-size: var(--dt-fs-2xl); font-weight: var(--dt-fw-semibold); line-height: var(--dt-lh-tight); letter-spacing: -0.01em; }
.dt-h3 { font-size: var(--dt-fs-xl); font-weight: var(--dt-fw-semibold); line-height: var(--dt-lh-tight); }
.dt-h4 { font-size: var(--dt-fs-lg); font-weight: var(--dt-fw-semibold); }
.dt-body { font-size: var(--dt-fs-md); }
.dt-small { font-size: var(--dt-fs-sm); }
.dt-caption { font-size: var(--dt-fs-xs); }
.dt-muted { color: var(--dt-text-2); }
.dt-faint { color: var(--dt-text-3); }
.dt-mono { font-family: var(--dt-font-mono); font-variant-numeric: tabular-nums; }
.dt-num { font-variant-numeric: tabular-nums; }
/* Un numero sotto zero: in una colonna di importi il segno meno da solo si
   perde, e un margine in perdita e' la cella che va vista per prima. */
.dt-negativo { color: var(--dt-danger); font-weight: var(--dt-fw-semibold); }
.dt-overline {
  font-size: var(--dt-fs-xs);
  font-weight: var(--dt-fw-semibold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--dt-text-3);
}
.dt-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* --------------------------------------------------------------------------
   4. Layout primitives
   -------------------------------------------------------------------------- */

.dt-stack { display: flex; flex-direction: column; }
.dt-row { display: flex; flex-direction: row; align-items: center; }
.dt-row--top { align-items: flex-start; }
.dt-row--wrap { flex-wrap: wrap; }
.dt-grow { flex: 1 1 auto; min-width: 0; }
/* Il contrario: un campo che non deve crescere. Un numero di due cifre in fila
   con due nomi lunghi si prenderebbe comunque un terzo della riga, e una
   casella larga promette un valore lungo che non arrivera' mai. Largo quanto
   basta a tenere su una riga l'aiuto che gli sta sotto: piu' stretto, la riga
   di aiuto va a capo e sfalsa il fondo di tutta la fila di campi. */
.dt-corto { flex: 0 0 120px; }
.dt-spacer { flex: 1 1 auto; }
/* Spazio riservato, invisibile: il contenuto tiene la sua misura naturale e
   sta al centro, ma la colonna occupa sempre lo stesso posto anche quando
   l'etichetta cambia. Serve nelle tabelle, perche' non si riassestino. */
.dt-fisso { display: inline-flex; align-items: center; justify-content: center; }

.dt-gap-1 { gap: var(--dt-sp-1); }
.dt-gap-2 { gap: var(--dt-sp-2); }
.dt-gap-3 { gap: var(--dt-sp-3); }
.dt-gap-4 { gap: var(--dt-sp-4); }
.dt-gap-5 { gap: var(--dt-sp-5); }
.dt-gap-6 { gap: var(--dt-sp-6); }
.dt-gap-7 { gap: var(--dt-sp-7); }
.dt-gap-8 { gap: var(--dt-sp-8); }

.dt-divider {
  border: 0;
  border-top: 1px solid var(--dt-border);
  margin: 0;
  width: 100%;
}
.dt-divider--v {
  border-top: 0;
  border-left: 1px solid var(--dt-border);
  width: 0;
  align-self: stretch;
  min-height: 16px;
}

.dt-toolbar {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-3);
  padding: var(--dt-sp-3) var(--dt-sp-4);
  background: var(--dt-surface-2);
  border-bottom: 1px solid var(--dt-border);
  min-height: var(--dt-topbar-h);
}
/* La barra in cima all'applicazione — quella da cui si trascina la finestra sul
   desktop — e' anche la prima fascia della pagina sul telefono, dove installata
   passa sotto all'orologio e alla batteria: il posto per quella roba lo fa lei.
   Le altre barre no: stanno in mezzo alla pagina, e li' sopra non c'e' niente
   da scansare. Fuori dal telefono `env()` vale zero e non cambia niente. */
.dt-toolbar[data-tauri-drag-region="deep"] {
  padding-top: calc(var(--dt-sp-3) + env(safe-area-inset-top, 0px));
}

/* Riduci / ingrandisci / chiudi della finestra desktop: in fondo alla barra,
   staccati dai comandi della piattaforma. */
.dt-finestra { display: flex; align-items: center; gap: var(--dt-sp-1); flex: none; }
/* Le zone che spostano la finestra non devono sembrare testo da selezionare. */
[data-tauri-drag-region] { user-select: none; -webkit-user-select: none; }

/* Shell applicativa: usata dal launcher e da ogni modulo */
.dt-app {
  display: grid;
  grid-template-columns: var(--dt-sidebar-w) 1fr;
  /* `dvh` e non `vh`: nel browser di un telefono la barra dell'indirizzo si
     ritira scorrendo, e `vh` resta fermo sull'altezza di quando non era
     ritirata — la barra bassa dell'applicazione finiva sotto al bordo. `vh`
     prima come rete per chi non sa l'altra unita'. Installata la differenza non
     c'e' proprio: li' la barra del browser non esiste. */
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  /* Installata, la pagina arriva ai bordi dello schermo (`viewport-fit=cover`)
     e di lato puo' finirci sotto la tacca quando il telefono e' coricato. Le
     due fasce alte e basse se le prendono la barra in cima e quella in fondo,
     che sono loro a toccare quei bordi. */
  padding-left: env(safe-area-inset-left, 0px);
  padding-right: env(safe-area-inset-right, 0px);
}
.dt-app__side {
  background: var(--dt-surface);
  border-right: 1px solid var(--dt-border);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.dt-app__main {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--dt-bg);
  /* La colonna del contenuto non si allarga per far posto a quello che ci sta
     dentro: e' `1fr` di una griglia, e una casella di griglia di suo non
     scende sotto il minimo del suo contenuto — una tabella larga o una fila di
     giornate spingeva la casella oltre la finestra, e a scorrere in
     orizzontale finiva la pagina intera, barra laterale compresa. Con lo zero
     la misura la detta la finestra, e a scorrere e' il riquadro che deve
     (`dt-app__body`, che ha gia' il suo `overflow`). */
  min-width: 0;
}
/* Colonna, cosi' un modulo puo' chiedere di riempire l'altezza rimasta
   (`dt-card--pieno`) invece di indovinarla con un calcolo. */
.dt-app__body {
  flex: 1 1 auto;
  overflow: auto;
  padding: var(--dt-pad-body);
  display: flex;
  flex-direction: column;
}
/* Quello che sta dentro a un riquadro che scorre non si schiaccia per starci.
   La colonna e' un `flex`, e un figlio di `flex` di suo si lascia stringere: di
   norma non sotto al proprio contenuto, ma quella rete salta per chi ha un
   `overflow` diverso da `visible` — ed e' il caso di ogni scheda
   (`.dt-card { overflow: hidden }`). Una scheda piu' alta della finestra
   veniva schiacciata all'altezza rimasta e il resto delle righe tagliato via:
   niente sporgeva, e quindi non c'era niente da scorrere. Impedito il
   restringimento la scheda resta alta quanto le sue righe, sporge, e a scorrere
   e' il riquadro come deve.
   Il peso zero (`:where`) serve a chi l'altezza rimasta la vuole per davvero —
   `dt-card--pieno`, `dt-giorno__pagina` — che si riprende il `flex` con la sua
   sola classe, senza dover rincorrere questa regola. */
:where(.dt-app__body) > * {
  flex-shrink: 0;
}

.dt-brand {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-3);
  padding: var(--dt-sp-4) var(--dt-sp-5);
  border-bottom: 1px solid var(--dt-border);
  min-height: var(--dt-topbar-h);
}
.dt-brand__name { font-size: var(--dt-fs-md); font-weight: var(--dt-fw-semibold); letter-spacing: -0.01em; }

/* Sigla che ondeggia: grigio smorzato, lettere sfasate fra loro. */
.dt-onda {
  display: inline-flex;
  margin-left: 0.35em;
  color: var(--dt-text-3);
  font-weight: var(--dt-fw-bold);
  letter-spacing: 0.02em;
}
.dt-onda__lettera {
  display: inline-block;
  animation: dt-onda 2.4s ease-in-out infinite;
}
@keyframes dt-onda {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-0.18em); }
}

.dt-nav { padding: var(--dt-sp-3); overflow: auto; flex: 1 1 auto; }
.dt-nav__group { margin-bottom: var(--dt-sp-4); }
.dt-nav__label {
  font-size: var(--dt-fs-xs);
  font-weight: var(--dt-fw-semibold);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--dt-text-3);
  padding: var(--dt-sp-2) var(--dt-sp-3);
}
.dt-nav__item {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-3);
  width: 100%;
  /* Sei pixel sopra e sotto e non quattro: la voce viene alta trentadue, che
     e' il minimo con cui si prende col pollice senza mirare. Sono quattro voci
     in tutto il programma, lo spazio c'e'. */
  padding: var(--dt-sp-3) var(--dt-sp-3);
  border: 0;
  border-radius: var(--dt-r-md);
  background: transparent;
  color: var(--dt-text-2);
  font: inherit;
  font-size: var(--dt-fs-md);
  text-align: left;
  cursor: pointer;
  transition: background var(--dt-t-fast), color var(--dt-t-fast);
}
.dt-nav__item:hover { background: var(--dt-hover); color: var(--dt-text); }
.dt-nav__item--active {
  background: var(--dt-selected);
  color: var(--dt-accent);
  font-weight: var(--dt-fw-medium);
}
.dt-nav__item svg { flex: none; opacity: 0.85; }

/* Quante cose aspettano dentro a quella schermata: il lavoro arretrato si
   legge dalla barra, senza entrare. Tinto come il conto sulla linguetta a cui
   corrisponde — e' lo stesso numero visto da due distanze — e spinto contro il
   bordo destro della voce, dove l'occhio scorre la colonna. */
.dt-nav__conto {
  flex: none;
  margin-left: auto;
  display: inline-grid;
  place-items: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: var(--dt-r-full);
  background: var(--dt-warn-soft);
  border: 1px solid var(--dt-warn-border);
  color: var(--dt-warn);
  font-size: var(--dt-fs-xs);
  font-weight: var(--dt-fw-semibold);
  font-variant-numeric: tabular-nums;
}
/* Etichetta minuta in coda a un nome: dice a chi e' riservata una voce
   senza rubarle spazio. Stessa altezza e stesso peso di un badge neutro,
   cosi' non sembra un elemento di un'altra interfaccia; in grigio e non a
   colori perche' non e' uno stato, e' una nota. */
.dt-tag {
  flex: none;
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  height: 20px;
  padding: 0 var(--dt-sp-2);
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-sm);
  background: var(--dt-surface-3);
  color: var(--dt-text-3);
  font-size: var(--dt-fs-xs);
  font-weight: var(--dt-fw-semibold);
  letter-spacing: 0.02em;
  white-space: nowrap;
}

/* Piede della barra laterale: chi ha la sessione aperta e le impostazioni.
   `margin-top: auto` lo tiene incollato in fondo anche quando sopra non c'e'
   la navigazione (l'operatore ha una vista sola e la barra resta vuota). */
.dt-app__sidefoot {
  position: relative;
  margin-top: auto;
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--dt-sp-3);
  padding: var(--dt-sp-4) var(--dt-sp-5);
  min-height: var(--dt-topbar-h);
  border-top: 1px solid var(--dt-border);
}
/* Chi ha la sessione aperta e' un tasto che apre le impostazioni, ma non deve
   sembrarlo: dentro alla barra e' una scritta, e un bordo o una campitura
   attorno al nome farebbero un secondo comando di fianco all'ingranaggio.
   Si accende sotto al dito, come le voci di un menu. */
.dt-sideuser {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-3);
  flex: 1 1 auto;
  min-width: 0;
  padding: var(--dt-sp-1) var(--dt-sp-2);
  margin: 0 calc(var(--dt-sp-2) * -1);
  border: 0;
  border-radius: var(--dt-r-md);
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background var(--dt-t-fast);
}
.dt-sideuser:hover { background: var(--dt-hover); }
.dt-sideuser__testo {
  display: flex;
  flex-direction: column;
  gap: 1px;
  flex: 1 1 auto;
  min-width: 0;
}
/* La prima parola del nome: serve solo allo slot della barra bassa. */
.dt-sideuser__breve { display: none; }

/* Cerchietto con l'iniziale: il colore arriva da uno `style` inline,
   perche' e' calcolato dal nome. */
.dt-avatar {
  flex: none;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: var(--dt-r-full);
  font-size: var(--dt-fs-md);
  font-weight: var(--dt-fw-bold);
  line-height: 1;
  user-select: none;
}
.dt-avatar--sm { width: 24px; height: 24px; font-size: var(--dt-fs-xs); }
.dt-avatar--lg { width: 38px; height: 38px; font-size: var(--dt-fs-lg); }

/* ==========================================================================
   Le facce: una cosa, un negozio, una persona
   ==========================================================================
   Tre facce con una grammatica sola — segno a sinistra, nome a destra,
   allineati sulla mezzeria — perche' la stessa cosa deve avere lo stesso
   disegno in qualunque schermata compaia. Le misure stanno qui e non nelle
   schermate: e' l'unico modo perche' il negozio dell'elenco e quello della
   scheda escano davvero identici. */
.dt-faccia {
  display: inline-flex;
  align-items: center;
  gap: var(--dt-sp-2);
  min-width: 0;
  vertical-align: middle;
}
/* Il nome si taglia, la faccia no: e' il pezzo che si riconosce anche
   dimezzato, mentre mezzo nome non e' un nome. */
.dt-faccia__nome {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dt-faccia--sm { gap: var(--dt-sp-1); font-size: var(--dt-fs-xs); }
.dt-faccia--lg { gap: var(--dt-sp-3); font-size: var(--dt-fs-lg); }

/* Il negozio in mezzo a una riga di testo: la sua campitura non deve crescere
   col testo intorno, se no la stessa faccia esce di due misure diverse in due
   elenchi che si somigliano. Le misure sono quelle del cerchietto di una
   persona — 24, 30, 38 — perche' le facce si contano a colpo d'occhio solo se
   sono grandi uguali. */
.dt-faccia--negozio > .dt-tinta-segno { --dt-corsia: 30px; }
.dt-faccia--sm.dt-faccia--negozio > .dt-tinta-segno { --dt-corsia: 24px; }
.dt-faccia--lg.dt-faccia--negozio > .dt-tinta-segno { --dt-corsia: 38px; }

/* Piu' persone: accavallate di un terzo, cosi' quattro facce stanno dove ne
   starebbero due e mezzo e l'iniziale di sotto resta leggibile. L'anello del
   colore di fondo e' quello che le stacca l'una dall'altra: senza, tre
   cerchietti sovrapposti diventano una macchia sola. */
.dt-facce {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
}
.dt-facce > .dt-faccia + .dt-faccia { margin-left: -10px; }
.dt-facce--sm > .dt-faccia + .dt-faccia { margin-left: -8px; }
.dt-facce--lg > .dt-faccia + .dt-faccia { margin-left: -13px; }
.dt-facce .dt-avatar {
  box-shadow: 0 0 0 2px var(--dt-facce-anello, var(--dt-surface));
}
/* Il conto di quelle che non si disegnano. Sta sulla riga come una faccia in
   piu' — stessa altezza, stesso anello — perche' e' quello che e': le altre. */
.dt-facce__resto {
  display: inline-grid;
  place-items: center;
  flex: none;
  height: 24px;
  min-width: 24px;
  margin-left: -8px;
  padding: 0 var(--dt-sp-1);
  border-radius: var(--dt-r-full);
  background: var(--dt-surface-2);
  box-shadow: 0 0 0 2px var(--dt-facce-anello, var(--dt-surface));
  color: var(--dt-text-2);
  font-size: var(--dt-fs-xs);
  font-weight: var(--dt-fw-bold);
  line-height: 1;
}
.dt-facce--lg .dt-facce__resto { height: 30px; min-width: 30px; font-size: var(--dt-fs-sm); }

/* Pannello che si apre dal piede della barra: si chiude cliccando ovunque. */
.dt-menu__velo {
  position: fixed;
  inset: 0;
  z-index: var(--dt-z-menu);
}
.dt-menu {
  position: absolute;
  z-index: calc(var(--dt-z-menu) + 1);
  bottom: calc(100% + var(--dt-sp-3));
  /* Il pannello sta dentro la barra laterale, con lo stesso margine su tutti
     e due i lati: non sborda mai sul contenuto. */
  left: var(--dt-sp-3);
  right: var(--dt-sp-3);
  display: flex;
  flex-direction: column;
  background: var(--dt-surface-2);
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-lg);
  box-shadow: var(--dt-shadow-lg);
  overflow: hidden;
}
/* Il pannello e' fatto di fasce separate da una riga, non di voci sparse:
   ogni fascia si prende lo stesso respiro, cosi' il riquadro resta ordinato
   anche quando ci si aggiunge qualcosa. */
.dt-menu > * + * { border-top: 1px solid var(--dt-border-soft); }

/* Chi e' entrato e, subito a fianco, la via d'uscita. */
.dt-menu__testa {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-3);
  padding: var(--dt-sp-4);
  background: var(--dt-surface-3);
}
.dt-menu__chi {
  display: flex;
  flex-direction: column;
  gap: 1px;
  flex: 1 1 auto;
  min-width: 0;
  font-weight: var(--dt-fw-semibold);
}

/* Etichetta a sinistra, controllo a destra. */
.dt-menu__riga {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--dt-sp-4);
  padding: var(--dt-sp-3) var(--dt-sp-4);
  font-size: var(--dt-fs-sm);
  color: var(--dt-text-2);
}

.dt-menu__label {
  font-size: var(--dt-fs-xs);
  font-weight: var(--dt-fw-semibold);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--dt-text-3);
  padding: var(--dt-sp-2) var(--dt-sp-2) var(--dt-sp-1);
}
.dt-menu__item {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-3);
  width: 100%;
  padding: var(--dt-sp-3) var(--dt-sp-3);
  border: 0;
  border-radius: var(--dt-r-sm);
  background: transparent;
  color: var(--dt-text-2);
  font: inherit;
  font-size: var(--dt-fs-md);
  text-align: left;
  cursor: pointer;
  transition: background var(--dt-t-fast), color var(--dt-t-fast);
}
.dt-menu__item:hover { background: var(--dt-hover); color: var(--dt-text); }
.dt-menu__item svg { flex: none; opacity: 0.85; }
.dt-menu__item--danger { color: var(--dt-danger); }
/* Dentro al menu il segmentato fa da controllo di riga: niente margini
   propri, ci pensa la fascia che lo contiene. */
.dt-menu__riga .dt-segmented { flex: none; }

/* Schermo verticale (tablet, monitor ruotato) o finestra stretta: la
   navigazione passa da colonna a sinistra a barra in basso, sempre a portata
   di pollice. Le etichette dei gruppi spariscono, le voci diventano
   icona + testo. Sotto gli 820px la colonna da 208px si mangerebbe un quarto
   della finestra. */
@media (orientation: portrait), (max-width: 820px) {
  .dt-app {
    grid-template-columns: 1fr;
    grid-template-rows: 1fr auto;
  }
  .dt-app__main { grid-row: 1; }

  .dt-app__side {
    grid-row: 2;
    flex-direction: row;
    align-items: center;
    gap: var(--dt-sp-2);
    /* La barra e' una fascia sola: la spaziatura sta qui, cosi' voci e piede
       stanno sulla stessa linea invece di avere ognuno il proprio bordo. */
    padding: var(--dt-sp-4) var(--dt-sp-3);
    padding-bottom: calc(var(--dt-sp-4) + env(safe-area-inset-bottom, 0px));
    /* Il pannello delle impostazioni esce dalla barra verso l'alto: se qui
       restasse `hidden` verrebbe tagliato. */
    overflow: visible;
    border-right: 0;
    border-top: 1px solid var(--dt-border);
    /* Gli angoli in alto arrotondati: la fascia e' una tavoletta appoggiata
       sopra alla pagina, non il bordo dello schermo. In basso restano vivi,
       perche' li' lo schermo finisce davvero. */
    border-radius: var(--dt-r-lg) var(--dt-r-lg) 0 0;
    background: var(--dt-surface);
    box-shadow: var(--dt-shadow-md);
  }
  .dt-app__side .dt-brand { display: none; }

  .dt-nav {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: var(--dt-sp-2);
    padding: 0;
    /* `min-width: 0` o la lista lunga sfonda la fascia invece di scorrere. */
    flex: 1 1 auto;
    min-width: 0;
    overflow-x: auto;
    overflow-y: hidden;
    /* La barra e' alta quanto una voce: una scrollbar orizzontale la
       taglierebbe in due. Si scorre col dito. */
    scrollbar-width: none;
  }
  .dt-nav::-webkit-scrollbar { display: none; }
  .dt-nav__group {
    display: flex;
    align-items: center;
    gap: var(--dt-sp-2);
    margin: 0;
  }
  /* Fra un gruppo e l'altro un puntino: il trattino verticale rigava la
     fascia in colonne, e con le pastiglie tonde delle voci era l'unica linea
     dritta rimasta. Un punto separa lo stesso e non disegna niente. */
  .dt-nav__group + .dt-nav__group {
    position: relative;
    margin-left: var(--dt-sp-3);
    padding-left: var(--dt-sp-4);
  }
  .dt-nav__group + .dt-nav__group::before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    width: 3px;
    height: 3px;
    border-radius: var(--dt-r-full);
    transform: translateY(-50%);
    background: var(--dt-border-strong);
  }
  .dt-nav__label { display: none; }
  .dt-nav__item {
    flex-direction: column;
    justify-content: center;
    gap: var(--dt-sp-1);
    width: auto;
    /* La voce si stringe con la fascia invece di aspettare una seconda
       soglia: fra il telefono stretto e il tablet largo passa per tutte le
       misure di mezzo. */
    min-width: clamp(54px, 7vw, 64px);
    max-width: clamp(84px, 13vw, 104px);
    /* Bersaglio da pollice: la voce e' alta quanto le due righe piu' l'aria,
       e la fascia si adatta a lei. */
    min-height: var(--dt-voce-h);
    padding: var(--dt-sp-2) clamp(4px, 1vw, 8px);
    /* Il pieno non e' piu' il tasto intero: sta dietro all'icona (sotto), e
       qui resta trasparente. Il raggio serve solo al contorno del fuoco. */
    background: transparent;
    border-radius: var(--dt-r-lg);
    text-align: center;
    font-size: var(--dt-fs-sm);
    line-height: 1.15;
    white-space: nowrap;
  }
  .dt-nav__item > span { max-width: 100%; }
  /* Il segno di dove si e' e' una pastiglia tonda dietro all'icona, col nome
     scritto sotto sul fondo della barra. Il rettangolo pieno alto quanto la
     voce faceva della fascia una fila di mattonelle attaccate, e da fermo non
     si capiva se il colore fosse il tasto o la selezione. La pastiglia sta
     dentro alla voce, quindi il dito continua a premere su tutto il tasto. */
  .dt-nav__item svg {
    box-sizing: content-box;
    padding: var(--dt-sp-2) clamp(10px, 2.6vw, 16px);
    border-radius: var(--dt-r-full);
    background: transparent;
    opacity: 1;
    transition: background var(--dt-t-fast), color var(--dt-t-fast);
  }
  .dt-nav__item:hover { background: transparent; }
  .dt-nav__item:hover svg { background: var(--dt-hover); }
  .dt-nav__item--active { background: transparent; }
  .dt-nav__item--active svg { background: var(--dt-selected); }
  /* Nella barra bassa lo spazio e' poco: il tag sparisce, il gruppo
     "Amministratore" dice gia' la stessa cosa. */
  .dt-nav__item .dt-tag { display: none; }
  /* Il conto invece resta: e' lavoro che aspetta, ed e' l'unica cosa della
     barra che cambia da sola. In colonna non puo' stare in fondo alla riga —
     finirebbe sotto al nome — quindi si appoggia all'angolo dell'icona, come
     il numerino sopra a un'applicazione. */
  .dt-nav__item { position: relative; }
  .dt-nav__item .dt-nav__conto {
    position: absolute;
    top: 0;
    right: clamp(2px, 1.5vw, 10px);
    margin: 0;
  }

  .dt-app__sidefoot {
    position: relative;
    margin-top: 0;
    margin-left: auto;
    align-self: center;
    gap: var(--dt-sp-2);
    min-height: 0;
    padding: 0 0 0 var(--dt-sp-4);
    border-top: 0;
  }
  /* Chi sta usando il programma resta scritto, nome e ruolo, anche nella
     fascia bassa: su un dispositivo condiviso e' l'unico modo di accorgersi
     di stare segnando le ore nella giornata di un altro, e la sola iniziale
     nel cerchietto non basta a farsene una domanda. Si stringe invece di
     sparire, e si stringe di continuo: il nome si taglia un po' di piu' a
     ogni pollice di finestra in meno, la barra non si sfonda mai. */
  .dt-sideuser__testo {
    flex: 0 1 auto;
    max-width: clamp(88px, 14vw + 30px, 168px);
  }
  /* Stesso puntino che separa i gruppi: il piede e' l'ultimo gruppo della
     fascia, non un riquadro a parte. Se la navigazione non c'e' (operatore)
     non c'e' niente da separare e il punto non compare. */
  .dt-nav ~ .dt-app__sidefoot::before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    width: 3px;
    height: 3px;
    border-radius: var(--dt-r-full);
    transform: translateY(-50%);
    background: var(--dt-border-strong);
  }
  /* Il pannello si apre verso l'alto e si ancora a destra, sopra la barra. */
  .dt-menu {
    left: auto;
    right: 0;
    min-width: 220px;
    max-width: calc(100vw - var(--dt-sp-6));
  }
}

/* --------------------------------------------------------------------------
   5. Bottoni
   -------------------------------------------------------------------------- */

.dt-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--dt-sp-2);
  height: var(--dt-h-md);
  padding: 0 var(--dt-sp-5);
  border: 1px solid transparent;
  border-radius: var(--dt-r-md);
  font-family: inherit;
  font-size: var(--dt-fs-md);
  font-weight: var(--dt-fw-medium);
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  transition: background var(--dt-t-fast), border-color var(--dt-t-fast),
              color var(--dt-t-fast), box-shadow var(--dt-t-fast);
}
.dt-btn:disabled,
.dt-btn[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}
.dt-btn:active:not(:disabled) { transform: translateY(0.5px); }

/* Varianti */
.dt-btn--primary {
  background: var(--dt-accent);
  border-color: var(--dt-accent);
  color: var(--dt-text-inv);
  box-shadow: var(--dt-shadow-sm);
}
.dt-btn--primary:hover { background: var(--dt-accent-hover); border-color: var(--dt-accent-hover); }
.dt-btn--primary:active { background: var(--dt-accent-active); }

.dt-btn--secondary {
  background: var(--dt-surface);
  border-color: var(--dt-border-strong);
  color: var(--dt-text);
  box-shadow: var(--dt-shadow-sm);
}
.dt-btn--secondary:hover { background: var(--dt-surface-3); }

.dt-btn--ghost {
  background: transparent;
  border-color: transparent;
  color: var(--dt-text-2);
}
.dt-btn--ghost:hover { background: var(--dt-hover); color: var(--dt-text); }

.dt-btn--danger {
  background: var(--dt-danger);
  border-color: var(--dt-danger);
  color: var(--dt-text-inv);
}
.dt-btn--danger:hover { background: var(--dt-danger-hover); border-color: var(--dt-danger-hover); }

/* La stessa azione dove non e' la protagonista: il rosso resta, la campitura
   no. Un "Elimina" pieno di fianco a un "Salva" pieno fa due tasti che gridano
   uguale, e il piu' pericoloso dei due grida di piu' perche' e' rosso. */
.dt-btn--danger-ghost {
  background: transparent;
  border-color: transparent;
  color: var(--dt-danger);
}
.dt-btn--danger-ghost:hover { background: var(--dt-danger-soft); }

.dt-btn--success {
  background: var(--dt-ok);
  border-color: var(--dt-ok);
  color: var(--dt-text-inv);
}
.dt-btn--success:hover { background: var(--dt-ok-hover); border-color: var(--dt-ok-hover); }

.dt-btn--link {
  background: transparent;
  border-color: transparent;
  color: var(--dt-accent);
  padding: 0 var(--dt-sp-1);
  height: auto;
}
.dt-btn--link:hover { text-decoration: underline; }

/* Il bottone che resta premuto.
   Non e' il passaggio del dito e non e' il fuoco: e' uno stato che dura, e per
   questo si veste come la voce scelta di un segmentato — fondo pieno di
   pagina, scritta a piena forza — invece di prendersi un colore suo. Cosi'
   dentro a una barra "acceso" si legge allo stesso modo dovunque. */
.dt-btn--premuto,
.dt-btn--ghost.dt-btn--premuto {
  background: var(--dt-selected);
  border-color: var(--dt-accent-border);
  color: var(--dt-text);
  font-weight: var(--dt-fw-semibold);
}

/* Taglie */
.dt-btn--sm { height: var(--dt-h-sm); padding: 0 var(--dt-sp-4); font-size: var(--dt-fs-sm); border-radius: var(--dt-r-sm); }
.dt-btn--lg { height: var(--dt-h-lg); padding: 0 var(--dt-sp-6); font-size: var(--dt-fs-lg); }
.dt-btn--block { width: 100%; }

/* Bottone solo icona */
.dt-iconbtn {
  display: inline-grid;
  place-items: center;
  width: var(--dt-h-md);
  height: var(--dt-h-md);
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--dt-r-md);
  background: transparent;
  color: var(--dt-text-2);
  cursor: pointer;
  transition: background var(--dt-t-fast), color var(--dt-t-fast);
}
.dt-iconbtn:hover { background: var(--dt-hover); color: var(--dt-text); }
.dt-iconbtn--sm { width: var(--dt-h-comando); height: var(--dt-h-comando); }
.dt-iconbtn--lg { width: var(--dt-h-lg); height: var(--dt-h-lg); }
.dt-iconbtn--bordered { border-color: var(--dt-border-strong); background: var(--dt-surface); }
.dt-iconbtn--danger { color: var(--dt-danger); }
.dt-iconbtn--danger:hover { color: var(--dt-danger); background: var(--dt-danger-soft); }
.dt-iconbtn:disabled { opacity: 0.45; cursor: not-allowed; }

/* Gruppo bottoni / segmented control */
.dt-btngroup { display: inline-flex; }
.dt-btngroup > .dt-btn { border-radius: 0; margin-left: -1px; }
.dt-btngroup > .dt-btn:first-child { border-radius: var(--dt-r-md) 0 0 var(--dt-r-md); margin-left: 0; }
.dt-btngroup > .dt-btn:last-child { border-radius: 0 var(--dt-r-md) var(--dt-r-md) 0; }
.dt-btngroup > .dt-btn:only-child { border-radius: var(--dt-r-md); }

.dt-segmented {
  display: inline-flex;
  padding: 2px;
  gap: 2px;
  background: var(--dt-surface-inset);
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-md);
}
.dt-segmented__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--dt-sp-2);
  border: 0;
  background: transparent;
  color: var(--dt-text-2);
  font: inherit;
  font-size: var(--dt-fs-sm);
  font-weight: var(--dt-fw-medium);
  padding: 0 var(--dt-sp-4);
  height: calc(var(--dt-h-md) - 6px);
  border-radius: var(--dt-r-sm);
  cursor: pointer;
  transition: background var(--dt-t-fast), color var(--dt-t-fast);
}
/* Sole icone: due quadratini, giusto lo spazio del simbolo. */
.dt-segmented--icone .dt-segmented__item {
  width: calc(var(--dt-h-md) - 6px);
  padding: 0;
}
.dt-segmented__item:hover { color: var(--dt-text); }
.dt-segmented__item--active {
  background: var(--dt-surface);
  color: var(--dt-text);
  box-shadow: var(--dt-shadow-sm);
}
/* Un segmentato che non si tocca piu': la scelta del tema, da quando lo scuro
   e' spento. Resta a schermo e resta leggibile — dice ancora quale dei due si
   sta usando — ma smorta e senza il dito che cambia forma sopra. Sparita,
   avrebbe lasciato chi la usava a cercare un pannello; smorta dice da sola
   che quella strada c'era. */
.dt-segmented--spento {
  opacity: 0.55;
  background: var(--dt-surface-2);
}
.dt-segmented__item:disabled { cursor: default; }
.dt-segmented__item:disabled:hover { color: var(--dt-text-2); }
.dt-segmented__item--active:disabled:hover { color: var(--dt-text); }

/* La fila dei gettoni: come il segmentato, ma se ne accendono quanti si
   vuole. Stesso riquadro incassato e stessi tasti piatti dentro — e' la stessa
   famiglia, e una seconda forma per la stessa cosa si imparerebbe due volte.
   Va a capo: i gettoni sono tanti quante le persone, e a finestra stretta una
   fila che scorre nasconde proprio quello che si sta cercando. */
.dt-gettoni {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  padding: 2px;
  gap: 2px;
  background: var(--dt-surface-inset);
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-md);
}
.dt-gettone {
  display: inline-flex;
  align-items: center;
  gap: var(--dt-sp-2);
  border: 0;
  background: transparent;
  color: var(--dt-text-3);
  font: inherit;
  font-size: var(--dt-fs-sm);
  font-weight: var(--dt-fw-medium);
  padding: 0 var(--dt-sp-4);
  height: calc(var(--dt-h-md) - 6px);
  border-radius: var(--dt-r-sm);
  cursor: pointer;
  transition: background var(--dt-t-fast), color var(--dt-t-fast);
}
.dt-gettone:hover { color: var(--dt-text); }
/* Spento perche' non c'e' niente da fare: "Tutti" quando ci sono gia' tutti.
   Resta al suo posto e si ingrigisce — un comando che sparisce farebbe ballare
   la fila ogni volta che si accende l'ultimo. */
.dt-gettone:disabled {
  cursor: default;
  opacity: 0.45;
}
.dt-gettone:disabled:hover { color: var(--dt-text-3); }
/* Acceso: il fondo pieno del segmentato scelto. Spento resta piatto e grigio —
   c'e', ma e' stato messo via. */
.dt-gettone--acceso {
  background: var(--dt-surface);
  color: var(--dt-text);
  box-shadow: var(--dt-shadow-sm);
}
/* L'ultimo comando della fila non e' un gettone e non si accende: sta di la'
   dal filo. */
.dt-gettoni__filo {
  width: 1px;
  align-self: stretch;
  margin: 2px var(--dt-sp-3);
  background: var(--dt-border);
}

/* --------------------------------------------------------------------------
   6. Campi form
   -------------------------------------------------------------------------- */

/* L'etichetta sta staccata dal suo campo di sei pixel e non di quattro: sotto
   al campo, di aiuto, ce ne sono altri quattro, e con la stessa misura sopra e
   sotto non si capiva a quale dei due campi appartenesse una riga. */
.dt-field { display: flex; flex-direction: column; gap: var(--dt-sp-3); }
.dt-field__label {
  font-size: var(--dt-fs-sm);
  font-weight: var(--dt-fw-medium);
  color: var(--dt-text-2);
  display: flex;
  align-items: center;
  gap: var(--dt-sp-2);
}
.dt-field__req { color: var(--dt-danger); }
.dt-field__hint { font-size: var(--dt-fs-xs); color: var(--dt-text-3); }
.dt-field__error { font-size: var(--dt-fs-xs); color: var(--dt-danger); display: flex; align-items: center; gap: var(--dt-sp-2); }

/* Form orizzontale denso (label a sinistra) — tipico data entry ERP */
.dt-formgrid {
  display: grid;
  grid-template-columns: minmax(110px, max-content) 1fr;
  gap: var(--dt-sp-3) var(--dt-sp-5);
  align-items: center;
}
.dt-formgrid > .dt-field__label { justify-content: flex-end; text-align: right; }

/* Griglia di campi a colonne uguali. Le larghezze le decide la griglia, non i
   controlli: `1fr` a testa, cosi' la casella di testo, la tendina e il gruppo
   con l'unita' attaccata vengono tutti della stessa misura e le righe si
   incolonnano. Il `minmax(0, ...)` e' quello che tiene: senza, una tendina con
   una voce lunga porta la sua colonna oltre l'`1fr` e sbilancia la riga.
   Lo stacco fra le righe e' piu' largo di quello fra le colonne, perche' sotto
   ogni campo c'e' il suo hint e serve aria per non attaccarlo alla label di
   sotto. `align-items: start` perche' un campo con l'hint su due righe non
   deve tirare in mezzo il vicino che l'hint non ce l'ha. */
.dt-campi {
  /* Le righe stanno in cima e non si stirano: di fianco c'e' la colonna della
     tavolozza, che e' alta il doppio, e senza questo i due campi in fondo
     scendevano a meta' maschera per riempire il vuoto. */
  align-content: start;
  display: grid;
  grid-template-columns: repeat(var(--dt-campi-colonne, 2), minmax(0, 1fr));
  gap: var(--dt-sp-5) var(--dt-sp-4);
  align-items: start;
}
/* Il campo che vale per tutta la riga: il nome, di solito, che e' lungo e non
   ha senso stringerlo a meta' finestra. */
.dt-campi > .dt-tutta { grid-column: 1 / -1; }
/* Due gradini, non uno. A tre colonne si sta solo nella maschera larga con la
   finestra larga; appena si stringe, tre caselle in fila diventano tre caselle
   troppo corte per quello che ci va dentro (un nome di negozio, una data) e
   allora si scende a due. Le griglie gia' a due colonne questo gradino non lo
   sentono: `repeat(2, ...)` su una griglia da due non cambia niente. */
@media (max-width: 900px) {
  .dt-campi { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .dt-campi { grid-template-columns: minmax(0, 1fr); }
}

/* Maschera a due colonne: a sinistra quello che si scrive, a destra quello che
   si sceglie guardando. Sono due gesti diversi — battere e riconoscere — e in
   colonna unica il secondo spinge il primo fuori dalla finestra, tanto che per
   rileggere il nome appena scritto bisognava risalire oltre la tavolozza.
   La colonna di destra e' larga quanto le sue griglie e non un terzo dello
   spazio: si dimensiona sui quadretti che deve contenere. Stretta la finestra,
   torna sotto — sopra ci va quello che va compilato per forza. */
.dt-maschera {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--dt-sp-6);
}
@media (min-width: 720px) {
  .dt-maschera { grid-template-columns: minmax(0, 1fr) 288px; gap: var(--dt-sp-7); }
}

.dt-input,
.dt-select,
.dt-textarea {
  width: 100%;
  height: var(--dt-h-md);
  padding: 0 var(--dt-sp-3);
  background: var(--dt-surface);
  border: 1px solid var(--dt-border-strong);
  border-radius: var(--dt-r-sm);
  color: var(--dt-text);
  font-family: inherit;
  font-size: var(--dt-fs-md);
  transition: border-color var(--dt-t-fast), box-shadow var(--dt-t-fast), background var(--dt-t-fast);
}
.dt-textarea { height: auto; padding: var(--dt-sp-3); resize: vertical; min-height: 64px; line-height: var(--dt-lh-normal); }

.dt-input::placeholder,
.dt-textarea::placeholder { color: var(--dt-text-3); }

.dt-input:hover:not(:disabled),
.dt-select:hover:not(:disabled),
.dt-textarea:hover:not(:disabled) { border-color: var(--dt-text-3); }

.dt-input:focus,
.dt-select:focus,
.dt-textarea:focus {
  outline: none;
  border-color: var(--dt-accent);
  box-shadow: 0 0 0 3px var(--dt-accent-soft);
}

.dt-input:disabled,
.dt-select:disabled,
.dt-textarea:disabled {
  background: var(--dt-surface-inset);
  color: var(--dt-text-3);
  cursor: not-allowed;
}
.dt-input[readonly] { background: var(--dt-surface-inset); }

.dt-input--invalid,
.dt-select--invalid,
.dt-textarea--invalid {
  border-color: var(--dt-danger);
}
.dt-input--invalid:focus { box-shadow: 0 0 0 3px var(--dt-danger-soft); }

.dt-input--sm { height: var(--dt-h-sm); font-size: var(--dt-fs-sm); }
.dt-input--lg { height: var(--dt-h-lg); font-size: var(--dt-fs-lg); }
.dt-input--num { text-align: right; font-variant-numeric: tabular-nums; font-family: var(--dt-font-mono); }

/* La tendina a discesa porta la stessa freccia di tutto il resto.
   Era un triangolino pieno, disegnato con due sfumature incrociate: l'unico
   segno "si apre in giu'" di tutta l'interfaccia a non essere la `chevron-down`
   del set: le sezioni, le linguette e le tendine dell'albero hanno sempre avuto
   quella. Due segni per la stessa cosa vogliono dire che chi guarda deve
   impararli tutti e due.
   Sta in un `url()` e non in un'icona vera perche' dentro a un `<select>` non
   ci si mettono elementi: il colore quindi non puo' arrivare da `currentColor`
   e sta scritto nel token, un valore per tema. */
.dt-select {
  appearance: none;
  padding-right: var(--dt-sp-8);
  background-image: var(--dt-freccia-giu);
  background-position: right var(--dt-sp-3) center;
  background-size: 13px 13px;
  background-repeat: no-repeat;
  cursor: pointer;
}

/* Input con affissi (icona, unita di misura, valuta) */
.dt-inputgroup {
  display: flex;
  align-items: stretch;
  width: 100%;
  border: 1px solid var(--dt-border-strong);
  border-radius: var(--dt-r-sm);
  background: var(--dt-surface);
  overflow: hidden;
  transition: border-color var(--dt-t-fast), box-shadow var(--dt-t-fast);
}
.dt-inputgroup:focus-within {
  border-color: var(--dt-accent);
  box-shadow: 0 0 0 3px var(--dt-accent-soft);
}
.dt-inputgroup .dt-input {
  border: 0;
  border-radius: 0;
  background: transparent;
}
.dt-inputgroup .dt-input:focus { box-shadow: none; }
.dt-inputgroup__affix {
  display: grid;
  place-items: center;
  padding: 0 var(--dt-sp-3);
  background: var(--dt-surface-inset);
  color: var(--dt-text-3);
  font-size: var(--dt-fs-sm);
  white-space: nowrap;
  flex: none;
}
.dt-inputgroup__affix--plain { background: transparent; }
/* La barra di ricerca la ✕ ce l'ha gia' sua, dentro il riquadro e con la lente
   in pari: quella che il motore attacca da solo a `type=search` sarebbe la
   seconda, con un altro disegno e in un altro posto. Via anche le decorazioni
   di WebKit, che sull'altro motore comparirebbero al suo posto. */
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-results-button,
input[type="search"]::-webkit-search-results-decoration {
  -webkit-appearance: none;
  appearance: none;
  display: none;
}

/* Numero col dito: `−` e `+` ai lati, larghi quanto un pollice, e il campo
   scrivibile in mezzo — da 1 a 24 a colpi di `+` non ci si arriva.
   Un riquadro solo con i pezzi divisi da un filo, come le barre di comandi:
   e' un oggetto, non tre bottoni vicini. */
.dt-stepper {
  display: flex;
  align-items: stretch;
  height: var(--dt-h-tocco);
  border: 1px solid var(--dt-border-strong);
  border-radius: var(--dt-r-sm);
  background: var(--dt-surface);
  overflow: hidden;
  transition: border-color var(--dt-t-fast), box-shadow var(--dt-t-fast);
}
.dt-stepper:focus-within {
  border-color: var(--dt-accent);
  box-shadow: 0 0 0 3px var(--dt-accent-soft);
}
.dt-stepper__passo {
  flex: none;
  width: var(--dt-h-tocco);
  display: grid;
  place-items: center;
  border: 0;
  background: var(--dt-surface-inset);
  color: var(--dt-text-2);
  cursor: pointer;
  transition: background var(--dt-t-fast), color var(--dt-t-fast), opacity var(--dt-t-fast);
}
.dt-stepper__passo:first-child { border-right: 1px solid var(--dt-border); }
.dt-stepper__passo:last-child { border-left: 1px solid var(--dt-border); }
.dt-stepper__passo:hover:not(:disabled) { background: var(--dt-hover); color: var(--dt-text); }
/* Arrivato al fondo della scala il tasto resta dov'e' e si spegne: sparendo
   sposterebbe l'altro sotto al dito che sta gia' scendendo. */
.dt-stepper__passo:disabled { opacity: 0.35; cursor: not-allowed; }
.dt-stepper__campo {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--dt-text);
  text-align: center;
  font-family: var(--dt-font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--dt-fs-lg);
}
.dt-stepper__campo:focus { outline: none; }
.dt-stepper__campo:disabled { opacity: 0.45; }
.dt-stepper__unita {
  display: grid;
  place-items: center;
  padding-right: var(--dt-sp-3);
  color: var(--dt-text-3);
  font-size: var(--dt-fs-sm);
  white-space: nowrap;
  flex: none;
}

/* --------------------------------------------------------------------------
   7. Checkbox / radio / switch
   -------------------------------------------------------------------------- */

.dt-check {
  display: inline-flex;
  align-items: center;
  gap: var(--dt-sp-3);
  cursor: pointer;
  font-size: var(--dt-fs-md);
  user-select: none;
}
.dt-check input { position: absolute; opacity: 0; width: 0; height: 0; }
.dt-check__box {
  width: 15px;
  height: 15px;
  flex: none;
  border: 1px solid var(--dt-border-strong);
  border-radius: var(--dt-r-xs);
  background: var(--dt-surface);
  display: grid;
  place-items: center;
  transition: background var(--dt-t-fast), border-color var(--dt-t-fast);
}
.dt-check__box::after {
  content: "";
  width: 8px;
  height: 4px;
  border-left: 2px solid var(--dt-text-inv);
  border-bottom: 2px solid var(--dt-text-inv);
  transform: rotate(-45deg) scale(0);
  transform-origin: center;
  transition: transform var(--dt-t-fast);
  margin-top: -2px;
}
.dt-check input:checked + .dt-check__box {
  background: var(--dt-accent);
  border-color: var(--dt-accent);
}
.dt-check input:checked + .dt-check__box::after { transform: rotate(-45deg) scale(1); }
.dt-check input:indeterminate + .dt-check__box {
  background: var(--dt-accent);
  border-color: var(--dt-accent);
}
.dt-check input:indeterminate + .dt-check__box::after {
  transform: none;
  width: 8px;
  height: 0;
  border-left: 0;
  border-bottom: 2px solid var(--dt-text-inv);
  margin-top: 0;
}
.dt-check input:focus-visible + .dt-check__box { box-shadow: 0 0 0 3px var(--dt-accent-soft); }
.dt-check input:disabled + .dt-check__box { opacity: 0.45; }
.dt-check:has(input:disabled) { cursor: not-allowed; color: var(--dt-text-3); }

/* radio */
.dt-check--radio .dt-check__box { border-radius: var(--dt-r-full); }
.dt-check--radio .dt-check__box::after {
  content: "";
  width: 6px;
  height: 6px;
  border: 0;
  border-radius: var(--dt-r-full);
  background: var(--dt-text-inv);
  transform: scale(0);
  margin: 0;
}
.dt-check--radio input:checked + .dt-check__box::after { transform: scale(1); }

/* switch */
.dt-switch { display: inline-flex; align-items: center; gap: var(--dt-sp-3); cursor: pointer; user-select: none; }
.dt-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.dt-switch__track {
  width: 30px;
  height: 17px;
  flex: none;
  border-radius: var(--dt-r-full);
  background: var(--dt-border-strong);
  position: relative;
  transition: background var(--dt-t-med);
}
.dt-switch__track::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 13px;
  height: 13px;
  border-radius: var(--dt-r-full);
  background: #fff;
  box-shadow: var(--dt-shadow-sm);
  transition: transform var(--dt-t-med);
}
.dt-switch input:checked + .dt-switch__track { background: var(--dt-accent); }
.dt-switch input:checked + .dt-switch__track::after {
  transform: translateX(13px);
  background: var(--dt-text-inv);
}
.dt-switch input:focus-visible + .dt-switch__track { box-shadow: 0 0 0 3px var(--dt-accent-soft); }
.dt-switch input:disabled + .dt-switch__track { opacity: 0.45; }

/* L'elenco: la scelta di **una** voce fra una dozzina, in colonna.

   Erano mattonelle — caselle grosse quanto un pollice, in griglia, ognuna con
   la sua campitura velata. Due conti sbagliati insieme: dodici campiture
   insegnavano una corrispondenza fra colore e attivita' che nel programma non
   esiste piu' (il colore e' del negozio, e di nessun altro), e dodici caselle
   da dito riempivano la finestra prima ancora della prima domanda. Un elenco
   costa una riga per voce, e il bersaglio non si stringe: una riga intera e'
   piu' larga di una casella in griglia.

   **Bianco.** Nessun fondo, ne' pieno ne' velato: la pagina, e basta. A dire
   quale voce si e' presa e' la spunta a destra — un segno d'inchiostro, che si
   vede da mezza stanza e non chiede un colore per farsi notare.

   Un filo fra una riga e l'altra e una cornice sola intorno a tutte: sono un
   elenco, non dodici scatole. Oltre le sei righe scorre per conto suo invece
   di allungare la finestra — le domande che vengono dopo devono restare in
   vista, e un elenco che si scorre lo dice da se' con la riga tagliata in
   fondo. */
.dt-elenco {
  display: flex;
  flex-direction: column;
  /* Cinque righe e mezza, non sei: la mezza riga tagliata in fondo e' l'unica
     cosa che dice "ce ne sono altre" senza scriverlo. A sei tonde l'elenco
     finisce pulito sul bordo e sembra finito davvero — e chi cerca la pausa
     pranzo smette di cercarla. */
  max-height: calc(var(--dt-h-tocco) * 5.5);
  overflow-y: auto;
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-md);
  background: var(--dt-surface);
  /* Qui non si trattiene niente. C'era un `overscroll-behavior: contain`, e in
     un elenco piu' corto del suo tetto — cinque attivita' in tutto, e di righe
     da scorrere non ce n'e' nemmeno una — fermava la rotella in un riquadro
     che non aveva dove andare: col puntatore sopra all'elenco non si muoveva
     niente, due dita piu' in la' sullo sfondo la stessa rotella muoveva la
     maschera. Un elenco che scorre davvero, arrivato in fondo, adesso passa il
     gesto alla maschera dietro: e' quello che fa ogni altro elenco al mondo, e
     costa infinitamente meno di un elenco che sembra rotto. */
}
/* La copertina se lo toglie, il tetto: li' l'elenco e' l'unico contenuto e le
   domande dopo non esistono ancora — la ragione del tetto non c'e', e uno
   scorrimento dentro a una finestra che scorre sarebbe il muro dentro al
   muro. Nelle altre schermate il tetto resta.

   E col tetto se ne va anche lo scorrimento, non solo il suo motivo: senza
   tetto l'elenco non ha mai niente da scorrere, e un riquadro che scorre a
   vuoto e' un posto dove la rotella si perde. `clip` taglia gli spigoli delle
   righe sotto agli angoli tondi come faceva `auto`, ma non e' un riquadro che
   scorre — e quello che non scorre lascia passare. */
.dt-elenco--pieno {
  max-height: none;
  overflow: clip;
}
.dt-elenco__voce {
  display: flex;
  flex: none;
  align-items: center;
  gap: var(--dt-sp-4);
  min-height: var(--dt-h-tocco);
  padding: var(--dt-sp-2) var(--dt-sp-4);
  border: none;
  background: none;
  color: var(--dt-text);
  cursor: pointer;
  font: inherit;
  text-align: left;
  transition: color var(--dt-t-fast), box-shadow var(--dt-t-fast);
}
.dt-elenco__voce + .dt-elenco__voce { border-top: 1px solid var(--dt-border-soft); }
/* Sotto al dito non si accende un fondo: si accende un filo d'inchiostro sul
   bordo sinistro. Un velo grigio sulla riga sarebbe la stessa campitura smorta
   che si e' appena tolta, e per mezzo secondo direbbe "presa" al posto della
   spunta. */
.dt-elenco__voce:hover:not(:disabled) {
  box-shadow: inset 2px 0 0 var(--dt-border-strong);
}
.dt-elenco__voce:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--dt-accent);
}
.dt-elenco__voce:disabled { opacity: 0.4; cursor: not-allowed; }
/* La riga presa: il nome pesa un gradino di piu' e il bordo sinistro porta il
   pieno d'inchiostro. Sono due segni oltre alla spunta perche' scorrendo
   l'elenco con il pollice sopra la spunta e' il pollice a coprirla. */
.dt-elenco__voce--scelta {
  box-shadow: inset 3px 0 0 var(--dt-accent);
}
.dt-elenco__voce--scelta:hover:not(:disabled) {
  box-shadow: inset 3px 0 0 var(--dt-accent);
}
.dt-elenco__voce--scelta .dt-elenco__nome { font-weight: var(--dt-fw-semibold); }
/* Il segno sta nella sua corsia, come nell'albero del catalogo: i nomi devono
   cominciare tutti dalla stessa colonna, se no l'elenco non si legge in
   colonna affatto. Smorto finche' la riga non e' quella presa — e' un
   contorno, non il dato. */
.dt-elenco__segno {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 22px;
  color: var(--dt-text-3);
}
.dt-elenco__voce--scelta .dt-elenco__segno { color: var(--dt-text); }
.dt-elenco__nome {
  flex: 1 1 0;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--dt-fs-md);
  line-height: var(--dt-lh-tight);
}
/* Il posto della spunta c'e' sempre, anche vuoto: comparendo dal nulla
   sposterebbe il nome a ogni tocco. */
.dt-elenco__spunta {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 16px;
  color: var(--dt-accent);
}

/* Le due griglie con cui l'anagrafica veste una cosa — un'attivita', un
   articolo, un tipo di tendaggio: la tavolozza e i segni. Sono quadretti
   piccoli perche' qui non preme nessuno col guanto — si sceglie col mouse,
   guardando — e con la casella da dito dodici colori piu' quarantacinque
   icone erano due schermate di finestra da scorrere per compilare cinque
   campi di testo.

   Le colonne sono un numero fisso e non `auto-fill`: cosi' le righe restano
   piene fino all'ultima (due da sei, cinque da nove) invece di finire con tre
   quadretti spaiati appena la finestra cambia di venti pixel. Il `minmax` da'
   il tetto, non la misura: nella colonna della maschera i quadretti stanno
   larghi quanto entrano, altrove non crescono oltre. */
.dt-tinte,
.dt-icone {
  display: grid;
  gap: var(--dt-sp-2);
  justify-content: start;
}
/* Sette colonne e non piu' sei, da quando le tinte sono ventisei: a sei la
   tavolozza scendeva a cinque righe, e la colonna che la ospita — gia' alta il
   doppio di quella dei campi — tirava giu' tutta la maschera. Sette quadretti
   da 42px stanno nella larghezza di sei da 48, quindi la maschera non si
   allarga: cresce di una riga sola. */
.dt-tinte { grid-template-columns: repeat(7, minmax(0, 42px)); }
/* I segni in una griglia sola, quanti ce ne stanno per riga: l'ordine in cui
   sono scritti basta a orientarsi, e spezzarli in pezzi intestati faceva di
   una scelta di due secondi un elenco da leggere.

   Da quando i segni sono piu' di cento la griglia intera e' piu' alta della
   finestra: si ferma a un'altezza che lascia vedere il resto della scheda e
   scorre dentro di se'. La misura e' in clamp perche' fra un portatile e uno
   schermo grande cambia quanto ci sta, non come e' fatta. */
.dt-icone {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(30px, 32px));
  gap: var(--dt-sp-2);
  justify-content: start;
  max-height: clamp(180px, 34vh, 320px);
  overflow-y: auto;
}

.dt-tinta,
.dt-icona {
  --dt-blocco-c: calc(var(--dt-blocco-croma, var(--dt-tinta-c)) * var(--dt-tinta-c-scala));
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1;
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-sm);
  cursor: pointer;
  transition: background var(--dt-t-fast), border-color var(--dt-t-fast),
    color var(--dt-t-fast), box-shadow var(--dt-t-fast);
}

/* La tavolozza porta le campiture piene, tutte quante: e' un elenco di
   colori, e dei colori accennati si leggono male proprio nella cosa che devono
   dire. Il fondo quindi non e' libero di segnare anche la scelta, e la scelta
   la fa un anello staccato da un filo di pagina. */
.dt-tinta {
  background: oklch(
    calc(var(--dt-tinta-l) + var(--dt-blocco-luce, 0%))
    var(--dt-blocco-c)
    var(--dt-blocco-tinta)
  );
  border-color: oklch(
    calc(var(--dt-tinta-l-bordo) + var(--dt-blocco-luce, 0%))
    var(--dt-blocco-c)
    var(--dt-blocco-tinta)
  );
}
/* Il quadretto vuoto: nessuna campitura. La sbarra e non il bianco, perche' un
   quadretto bianco in una fila di colori si legge come "bianco". */
.dt-tinta--nessuna {
  background: var(--dt-surface);
  background-image: linear-gradient(
    to top right,
    transparent calc(50% - 1px),
    var(--dt-text-3) calc(50% - 1px),
    var(--dt-text-3) calc(50% + 1px),
    transparent calc(50% + 1px)
  );
}
.dt-tinta--scelta {
  box-shadow: 0 0 0 2px var(--dt-surface), 0 0 0 4px var(--dt-accent);
}
.dt-tinta:hover { border-color: var(--dt-text-2); }

/* I segni a riposo restano sul grigio della pagina: colorarli tutti e
   quarantacinque faceva della griglia una macchia unica dove il segno scelto
   spariva dentro ai vicini, e sono i disegni che vanno confrontati fra loro,
   non i fondi, che li' sono tutti uguali. La campitura la prende solo quello
   scelto — ed e' esattamente come si vedra' in giornata — piu' un velo della
   stessa tinta sotto al puntatore, che vale da anteprima prima di decidere. */
.dt-icona {
  background: var(--dt-surface-2);
  color: var(--dt-text-2);
}
.dt-icona:hover {
  background: oklch(
    min(96%, calc(var(--dt-velo-l) + var(--dt-blocco-luce, 0%) * 0.5))
    calc(var(--dt-blocco-c) * var(--dt-velo-c-scala))
    var(--dt-blocco-tinta)
  );
  border-color: oklch(
    min(96%, calc(var(--dt-velo-l-bordo) + var(--dt-blocco-luce, 0%) * 0.5))
    calc(var(--dt-blocco-c) * 0.6)
    var(--dt-blocco-tinta)
  );
  color: var(--dt-text);
}
.dt-icona--scelta,
.dt-icona--scelta:hover {
  background: oklch(
    calc(var(--dt-tinta-l) + var(--dt-blocco-luce, 0%))
    var(--dt-blocco-c)
    var(--dt-blocco-tinta)
  );
  border-color: oklch(
    calc(var(--dt-tinta-l-bordo) + var(--dt-blocco-luce, 0%))
    var(--dt-blocco-c)
    var(--dt-blocco-tinta)
  );
  color: oklch(var(--dt-tinta-l-testo) var(--dt-tinta-c-testo) var(--dt-blocco-tinta));
}
/* Il fuoco e' un contorno e non un'ombra come altrove: qui l'ombra la sta gia'
   usando l'anello della scelta, e la seconda cancellerebbe la prima proprio
   mentre ci si muove dentro con il tabulatore. */
.dt-tinta:focus-visible,
.dt-icona:focus-visible {
  outline: 2px solid var(--dt-accent);
  outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   8. Slider
   -------------------------------------------------------------------------- */

.dt-slider { display: flex; flex-direction: column; gap: var(--dt-sp-2); width: 100%; }
.dt-slider__head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--dt-sp-3); }
.dt-slider__value {
  font-family: var(--dt-font-mono);
  font-size: var(--dt-fs-sm);
  font-variant-numeric: tabular-nums;
  color: var(--dt-text);
  background: var(--dt-surface-inset);
  border: 1px solid var(--dt-border-soft);
  border-radius: var(--dt-r-sm);
  padding: 0 var(--dt-sp-2);
}
.dt-slider__input {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 16px;
  background: transparent;
  cursor: pointer;
  margin: 0;
}
.dt-slider__input::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: var(--dt-r-full);
  background: linear-gradient(
    to right,
    var(--dt-accent) 0%,
    var(--dt-accent) var(--dt-slider-pct, 50%),
    var(--dt-border) var(--dt-slider-pct, 50%),
    var(--dt-border) 100%
  );
}
.dt-slider__input::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 13px;
  height: 13px;
  margin-top: -4.5px;
  border-radius: var(--dt-r-full);
  background: var(--dt-surface);
  border: 2px solid var(--dt-accent);
  box-shadow: var(--dt-shadow-sm);
  transition: transform var(--dt-t-fast);
}
.dt-slider__input:hover::-webkit-slider-thumb { transform: scale(1.12); }
.dt-slider__input:active::-webkit-slider-thumb { transform: scale(1.2); }
.dt-slider__input::-moz-range-track {
  height: 4px;
  border-radius: var(--dt-r-full);
  background: var(--dt-border);
}
.dt-slider__input::-moz-range-progress {
  height: 4px;
  border-radius: var(--dt-r-full);
  background: var(--dt-accent);
}
.dt-slider__input::-moz-range-thumb {
  width: 11px;
  height: 11px;
  border-radius: var(--dt-r-full);
  background: var(--dt-surface);
  border: 2px solid var(--dt-accent);
}
.dt-slider__input:disabled { opacity: 0.45; cursor: not-allowed; }
.dt-slider__ticks {
  display: flex;
  justify-content: space-between;
  font-size: var(--dt-fs-xs);
  color: var(--dt-text-3);
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   9. Badge / pill / stato
   -------------------------------------------------------------------------- */

.dt-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--dt-sp-2);
  height: 20px;
  padding: 0 var(--dt-sp-3);
  border-radius: var(--dt-r-sm);
  border: 1px solid transparent;
  font-size: var(--dt-fs-xs);
  font-weight: var(--dt-fw-semibold);
  letter-spacing: 0.01em;
  white-space: nowrap;
}
.dt-badge--pill { border-radius: var(--dt-r-full); padding: 0 var(--dt-sp-4); }
.dt-badge--neutral { background: var(--dt-surface-3); border-color: var(--dt-border); color: var(--dt-text-2); }
.dt-badge--accent  { background: var(--dt-accent-soft); border-color: var(--dt-accent-border); color: var(--dt-accent); }
.dt-badge--success { background: var(--dt-ok-soft); border-color: var(--dt-ok-border); color: var(--dt-ok); }
.dt-badge--warning { background: var(--dt-warn-soft); border-color: var(--dt-warn-border); color: var(--dt-warn); }
.dt-badge--danger  { background: var(--dt-danger-soft); border-color: var(--dt-danger-border); color: var(--dt-danger); }
.dt-badge--info    { background: var(--dt-info-soft); border-color: var(--dt-info-border); color: var(--dt-info); }

.dt-dot { width: 6px; height: 6px; border-radius: var(--dt-r-full); background: currentColor; flex: none; }

.dt-count {
  display: inline-grid;
  place-items: center;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: var(--dt-r-full);
  background: var(--dt-danger);
  color: var(--dt-text-inv);
  font-size: var(--dt-fs-xs);
  font-weight: var(--dt-fw-bold);
}

/* --------------------------------------------------------------------------
   10. Superfici: card, panel, kpi, empty
   -------------------------------------------------------------------------- */

.dt-card {
  background: var(--dt-surface);
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-lg);
  box-shadow: var(--dt-shadow-sm);
  overflow: hidden;
}
/* Due fasce, non una riga di tre cose: sopra il titolo con i comandi in fondo,
   sotto la descrizione a tutta larghezza. Il perche' sta nel componente
   `CardHead` — la descrizione era l'unica delle tre che sa andare a capo, e a
   finestra stretta era sempre lei a cedere.
   Non c'e' una soglia: la fascia di sopra si spezza da se' quando i comandi non
   stanno di fianco al titolo, la descrizione sta larga come il riquadro
   sempre. */
.dt-card__head {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--dt-sp-2);
  padding: var(--dt-sp-5) var(--dt-sp-6);
  border-bottom: 1px solid var(--dt-border-soft);
  background: var(--dt-surface-2);
}
.dt-card__head__riga {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--dt-sp-4) var(--dt-sp-5);
}
/* Il titolo non si stira, i comandi stanno in fondo per conto loro: fra i due
   spinge il vuoto. Stirandosi (`dt-grow`) il titolo si prendeva lo spazio
   libero della riga, e a quel punto la fila dei comandi era larga quel che
   restava invece di quel che le serve.
   A spingere e' il titolo e non i comandi: la regola era scritta sulla fila
   (`.dt-row`), e una testata che di comandi ne ha uno solo — «Nuova attivita'»
   — il tasto non lo mette in fila, lo passa nudo. Quel tasto restava appiccicato
   al titolo, in mezzo alla testata, mentre su tutte le altre schede stava a
   destra. Col margine sul titolo va in fondo qualunque cosa gli si passi. */
.dt-card__head__riga > .dt-grow { flex-grow: 0; }
.dt-card__head__riga > .dt-card__title { margin-right: auto; }
/* Sotto i 900px la fila dei comandi va a capo dentro di se'. Sopra no, e la
   differenza conta: stretta la finestra, i comandi che non ci stanno vanno
   spezzati su due righe; larga, mandare a capo un tasto quando basterebbe
   stringere di trenta pixel il campo di ricerca fa due righe dove ne bastava
   una. Una casella di ricerca stretta si scrive uguale. */
@media (max-width: 900px) {
  .dt-card__head__riga > .dt-row { flex-wrap: wrap; }
}
/* Il campo di ricerca dentro a una testata nasce largo quattordici caratteri e
   da li' si stira per prendere quel che avanza. Di suo e' larga il cento per
   cento del posto che ha — buono in una maschera, dove sta da solo in colonna —
   e in una barra di comandi quel cento per cento e' la misura con cui il flex
   decide se la riga ci sta: la riga non ci stava mai, e i filtri finivano a capo
   anche su un monitor dove c'era posto per tutti. Che si stringa e' giusto: una
   casella di ricerca stretta si scrive uguale, una fila di filtri spezzata in
   due si legge peggio. */
.dt-card__head__riga .dt-inputgroup { flex: 1 1 14rem; width: auto; }
.dt-card__title { font-size: var(--dt-fs-lg); font-weight: var(--dt-fw-semibold); letter-spacing: -0.01em; }
.dt-card__sub { font-size: var(--dt-fs-sm); color: var(--dt-text-2); }
.dt-card__body { padding: var(--dt-sp-6); }
.dt-card__body--flush { padding: 0; }
/* Card alta quanto lo spazio rimasto: dentro ci sta chi scorre per conto
   proprio, e la pagina non prende altezza in piu'. */
.dt-card--pieno {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}
.dt-card--pieno .dt-card__body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}
.dt-card__foot {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-3);
  padding: var(--dt-sp-4) var(--dt-sp-6);
  border-top: 1px solid var(--dt-border-soft);
  background: var(--dt-surface-2);
}

.dt-kpi {
  display: flex;
  flex-direction: column;
  gap: var(--dt-sp-2);
  padding: var(--dt-sp-5);
  background: var(--dt-surface);
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-lg);
  min-width: 150px;
  /* In fila, tutti alti uguale: la terza cifra non ha il confronto col mese
     prima da scrivere sotto, e senza questo il suo riquadro finiva un gradino
     piu' corto degli altri — una fila di quattro con un dente in mezzo. */
  align-self: stretch;
}
.dt-kpi__label { font-size: var(--dt-fs-xs); text-transform: uppercase; letter-spacing: 0.07em; color: var(--dt-text-3); font-weight: var(--dt-fw-semibold); }
.dt-kpi__value { font-size: var(--dt-fs-2xl); font-weight: var(--dt-fw-semibold); font-variant-numeric: tabular-nums; line-height: 1.1; }
.dt-kpi__delta { font-size: var(--dt-fs-sm); display: inline-flex; align-items: center; gap: var(--dt-sp-2); }
.dt-kpi__delta--up { color: var(--dt-ok); }
.dt-kpi__delta--down { color: var(--dt-danger); }

.dt-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--dt-sp-4);
  padding: var(--dt-sp-10) var(--dt-sp-6);
  text-align: center;
  color: var(--dt-text-2);
}
.dt-empty__icon {
  width: 40px; height: 40px;
  display: grid; place-items: center;
  border-radius: var(--dt-r-full);
  background: var(--dt-surface-3);
  color: var(--dt-text-3);
}
.dt-empty__title { font-size: var(--dt-fs-lg); font-weight: var(--dt-fw-semibold); color: var(--dt-text); }

/* Campione colore (utile per moduli tessili: cartelle colore, filati) */
.dt-swatch { display: flex; flex-direction: column; gap: var(--dt-sp-2); width: 92px; }
.dt-swatch__chip {
  height: 46px;
  border-radius: var(--dt-r-md);
  border: 1px solid var(--dt-border);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.18);
}
.dt-swatch__name { font-size: var(--dt-fs-xs); font-weight: var(--dt-fw-medium); }
.dt-swatch__code { font-size: var(--dt-fs-xs); color: var(--dt-text-3); font-family: var(--dt-font-mono); }

/* Mattonella di modulo: il launcher la usa per aprire i moduli dell'ERP. */
.dt-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(238px, 1fr));
  gap: var(--dt-sp-4);
}
.dt-tile {
  display: flex;
  align-items: flex-start;
  gap: var(--dt-sp-4);
  width: 100%;
  padding: var(--dt-sp-5);
  text-align: left;
  background: var(--dt-surface);
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-lg);
  box-shadow: var(--dt-shadow-sm);
  color: inherit;
  font: inherit;
  font-size: var(--dt-fs-md);
  cursor: pointer;
  transition: border-color var(--dt-t-fast), background var(--dt-t-fast),
    box-shadow var(--dt-t-fast);
}
.dt-tile:hover {
  border-color: var(--dt-accent-border);
  background: var(--dt-hover);
  box-shadow: var(--dt-shadow-md);
}
.dt-tile:focus-visible { outline: 2px solid var(--dt-accent); outline-offset: 1px; }
.dt-tile--disabled,
.dt-tile--disabled:hover {
  cursor: not-allowed;
  background: var(--dt-surface);
  border-color: var(--dt-border);
  box-shadow: none;
  color: var(--dt-text-3);
}
.dt-tile__icon {
  flex: none;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: var(--dt-r-md);
  background: var(--dt-accent-soft);
  color: var(--dt-accent);
}
.dt-tile--disabled .dt-tile__icon { background: var(--dt-surface-3); color: var(--dt-text-3); }
.dt-tile__body { display: flex; flex-direction: column; gap: var(--dt-sp-2); min-width: 0; flex: 1; }
.dt-tile__title {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-2);
  font-size: var(--dt-fs-lg);
  font-weight: var(--dt-fw-semibold);
}
.dt-tile__desc { font-size: var(--dt-fs-sm); color: var(--dt-text-2); line-height: var(--dt-lh-normal); }
.dt-tile__foot { display: flex; align-items: center; gap: var(--dt-sp-3); margin-top: var(--dt-sp-1); }

/* --------------------------------------------------------------------------
   11. Tabs
   -------------------------------------------------------------------------- */

/* La riga sta ferma dove l'ha messa il filo, e le linguette scorrono di lato
   quando non ci stanno: mandarle a capo farebbe scendere di venti pixel tutta
   la schermata mentre si stringe la finestra. Il padding si interpola con la
   larghezza invece di scattare a una soglia. */
.dt-tabs { position: relative; border-bottom: 1px solid var(--dt-border); }
.dt-tabs__lista {
  display: flex;
  align-items: stretch;
  gap: var(--dt-sp-1);
  /* La sottolineatura della linguetta attiva copre il filo invece di
     galleggiarci sopra: dentro al riquadro che scorre, cosi' non viene
     tagliata. */
  margin-bottom: -1px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.dt-tabs__lista::-webkit-scrollbar { display: none; }
.dt-tabs__item {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--dt-sp-2);
  flex: none;
  border: 0;
  background: transparent;
  color: var(--dt-text-2);
  font: inherit;
  font-size: var(--dt-fs-md);
  font-weight: var(--dt-fw-medium);
  padding: var(--dt-sp-3) clamp(var(--dt-sp-3), 1.3vw, var(--dt-sp-5));
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--dt-t-fast);
}
.dt-tabs__item:hover { color: var(--dt-text); }
.dt-tabs__item--active { color: var(--dt-accent); }
.dt-tabs__item--active::after {
  content: "";
  position: absolute;
  left: var(--dt-sp-3);
  right: var(--dt-sp-3);
  bottom: 0;
  height: 2px;
  background: var(--dt-accent);
  border-radius: var(--dt-r-full) var(--dt-r-full) 0 0;
}
.dt-tabs__item:disabled { opacity: 0.45; cursor: not-allowed; }
.dt-tabs__item svg { flex: none; opacity: 0.9; }

/* Il filo che separa due gruppi di linguette: rientrato sopra e sotto, come i
   divisori dentro alle barre di comandi. */
.dt-tabs__filo {
  flex: none;
  width: 1px;
  margin: var(--dt-sp-3) var(--dt-sp-2);
  background: var(--dt-border);
}

/* Il conto sulla linguetta: smorto per default, perche' quasi sempre e' solo
   quante righe ci sono. Prende una tinta solo quando dice che c'e' del lavoro
   fermo. */
.dt-tabs__conto {
  display: inline-grid;
  place-items: center;
  min-width: 18px;
  height: 17px;
  padding: 0 5px;
  border-radius: var(--dt-r-full);
  background: var(--dt-surface-3);
  color: var(--dt-text-2);
  font-size: var(--dt-fs-xs);
  font-weight: var(--dt-fw-semibold);
  font-variant-numeric: tabular-nums;
}
.dt-tabs__conto--avviso { background: var(--dt-warn-soft); color: var(--dt-warn); }
.dt-tabs__conto--rosso { background: var(--dt-danger-soft); color: var(--dt-danger); }
.dt-tabs__item--active .dt-tabs__conto { background: var(--dt-accent-soft); color: var(--dt-accent); }
.dt-tabs__item--active .dt-tabs__conto--avviso { background: var(--dt-warn-soft); color: var(--dt-warn); }

/* Sezione che si apre e si chiude: il soffietto.

   Si chiamava `dt-piega`, ed era il nome sbagliato: la piega e' la riga in
   cui il foglio della bolla si gira (`.dt-piega`, piu' sotto), questa e' la
   sezione a soffietto di una maschera.

   L'altezza si interpola sugli stessi nodi: la pancia e' una griglia a una
   riga che passa da 0fr a 1fr, cioe' da "quanto serve, moltiplicato zero" a
   "quanto serve". E' l'unico modo di animare fino al contenuto vero senza
   misurarlo in JavaScript e senza un max-height a occhio, che o taglia il
   contenuto lungo o fa partire la chiusura in ritardo su quello corto. */
.dt-soffietto {
  border: 1px solid var(--dt-border-soft);
  border-radius: var(--dt-r-md);
  background: var(--dt-surface-2);
}
.dt-soffietto__testa {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-3);
  width: 100%;
  min-height: var(--dt-h-lg);
  padding: var(--dt-sp-2) var(--dt-sp-4);
  border: 0;
  background: transparent;
  color: var(--dt-text);
  font: inherit;
  font-size: var(--dt-fs-md);
  font-weight: var(--dt-fw-semibold);
  text-align: left;
  cursor: pointer;
}
.dt-soffietto__testa:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--dt-accent-border);
  border-radius: var(--dt-r-md);
}
.dt-soffietto__freccia {
  display: inline-flex;
  color: var(--dt-text-3);
  transform: rotate(-90deg);
  transition: transform var(--dt-t-med);
}
.dt-soffietto--aperto .dt-soffietto__freccia { transform: rotate(0deg); }
/* Il conto sta appiccicato al titolo e non in fondo alla barra: e' il titolo
   che conta, e un numero solo dall'altra parte del riquadro non si capisce a
   che cosa si riferisca. E' `margin-right: auto` a tenere vuoto il resto. */
.dt-soffietto__titolo { flex: 0 1 auto; }
.dt-soffietto__conto {
  margin-right: auto;
  padding: 0 var(--dt-sp-3);
  border-radius: var(--dt-r-full);
  background: var(--dt-surface-3);
  color: var(--dt-text-2);
  font-size: var(--dt-fs-sm);
  font-weight: var(--dt-fw-medium);
  font-variant-numeric: tabular-nums;
  line-height: 18px;
}
.dt-soffietto__pancia {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dt-t-med);
}
.dt-soffietto--aperto .dt-soffietto__pancia { grid-template-rows: 1fr; }
/* Nudo di proposito: e' la cella che si schiaccia, e con `border-box` un
   padding qui non si schiaccerebbe con lei — resterebbero i suoi pixel aperti
   anche a sezione chiusa. Il margine sta un livello piu' sotto. */
.dt-soffietto__dentro {
  overflow: hidden;
  min-height: 0;
}
.dt-soffietto__corpo { padding: 0 var(--dt-sp-4) var(--dt-sp-4); }

/* --------------------------------------------------------------------------
   11-bis. La barra del periodo
   -------------------------------------------------------------------------- */

/* Di che mese si sta parlando: sta sopra alle linguette perche' la domanda e'
   una sola per tutti e tre i fogli che ci stanno sotto.
   E' un riquadro solo, come la barra della giornata: un fondo, un bordo, e
   dentro i comandi piatti. Quello che non e' un comando — la parola "Periodo",
   il mese scritto per esteso — si separa con un filo verticale rientrato, non
   con un secondo riquadro. */
.dt-periodo {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--dt-sp-2);
  padding: var(--dt-sp-2) var(--dt-sp-3);
  background: var(--dt-surface);
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-lg);
  box-shadow: var(--dt-shadow-sm);
}
/* Dice di cosa parla la fila, e non si preme: peso da etichetta, non da
   titolo. */
.dt-periodo__voce {
  padding-left: var(--dt-sp-2);
  font-size: var(--dt-fs-xs);
  font-weight: var(--dt-fw-semibold);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--dt-text-3);
}
.dt-periodo__filo {
  flex: none;
  align-self: stretch;
  width: 1px;
  margin: var(--dt-sp-2) var(--dt-sp-1);
  background: var(--dt-border);
}
/* Il periodo scritto com'e' davvero. Con "Tutto" acceso le due tendine mostrano
   comunque un mese, e senza questa riga si leggerebbero i numeri sotto come se
   fossero i suoi. */
.dt-periodo__detto {
  padding-left: var(--dt-sp-2);
  font-size: var(--dt-fs-sm);
  font-weight: var(--dt-fw-medium);
  color: var(--dt-text);
}
/* Le frecce e le due tendine sono un gruppo solo: sul largo il gruppo e'
   trasparente alla barra — i quattro comandi stanno in fila come gli altri —
   e quando la barra va a capo si porta dietro tutti e quattro invece di
   lasciare una freccia di qua e una di la'. */
.dt-periodo__quando { display: contents; }
@media (max-width: 720px) {
  .dt-periodo__quando {
    display: flex;
    align-items: center;
    gap: var(--dt-sp-2);
  }
  /* Il filo che stacca "Tutto" dal gruppo della data: quando il gruppo va a
     capo il filo resta in fondo alla riga di sopra, a separare una cosa da
     niente. */
  .dt-periodo__filo:has(+ .dt-periodo__quando) { display: none; }
}
/* Le tendine del mese e dell'anno non si stirano: sono due parole, e larghe
   quanto la barra sembrerebbero due campi da compilare. */
.dt-periodo .dt-select { width: auto; min-width: 96px; }
.dt-periodo .dt-select + .dt-select { min-width: 78px; }
/* Sulla carta i comandi se ne vanno (li toglie gia' la regola generale sui
   tasti) ma il periodo **resta scritto**: un foglio di numeri senza il mese a
   cui si riferiscono, una volta staccato dallo schermo, non si sa piu' leggere.
   Quel che resta e' una riga di testo, non un riquadro. */
@media print {
  .dt-periodo {
    padding: 0;
    border: 0;
    box-shadow: none;
  }
  .dt-periodo .dt-select,
  .dt-periodo__filo { display: none; }
  .dt-periodo__voce { padding-left: 0; }
}

/* --------------------------------------------------------------------------
   12. Tabella dati (densa)
   -------------------------------------------------------------------------- */

.dt-tablewrap {
  width: 100%;
  overflow: auto;
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-md);
  background: var(--dt-surface);
}
.dt-card__body--flush .dt-tablewrap { border: 0; border-radius: 0; }

.dt-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--dt-fs-md);
}
/* L'incolonnamento: tutto a sinistra, tranne quello che si confronta cifra a
   cifra.
   Prima titolo e contenuto stavano al centro della cella, per far leggere la
   colonna come un blocco unico. Su una tabella larga fa il contrario: ogni
   cella parte da un punto suo — "Rossi" e "Condominio Aurora" cominciano a
   quindici pixel di distanza — e per scorrere una colonna di nomi l'occhio
   deve ritrovare ogni volta da dove attaccano le parole. A sinistra il bordo
   d'attacco e' uno solo e la colonna si legge scendendo dritti.
   Restano a destra i numeri e le date (`dt-td--num`, `dt-mono`): li' quello
   che conta e' l'ultima cifra, e allineare a destra e' quello che incolonna
   unita' con unita'. */
.dt-table thead th {
  position: sticky;
  top: 0;
  z-index: var(--dt-z-sticky);
  background: var(--dt-surface-2);
  border-bottom: 1px solid var(--dt-border);
  padding: var(--dt-sp-4) var(--dt-sp-4);
  text-align: left;
  font-size: var(--dt-fs-xs);
  font-weight: var(--dt-fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--dt-text-3);
  white-space: nowrap;
  user-select: none;
}
.dt-table th.dt-th--sortable { cursor: pointer; }
.dt-table th.dt-th--sortable:hover { color: var(--dt-text); background: var(--dt-surface-3); }
.dt-table tbody td {
  padding: var(--dt-sp-4) var(--dt-sp-4);
  border-bottom: 1px solid var(--dt-border-soft);
  vertical-align: middle;
  white-space: nowrap;
  text-align: left;
}
/* Le celle che mettono in fila piu' cose (avatar + nome, gruppi di bottoni)
   sono flex: l'attacco a sinistra glielo deve dire il flex, non il
   text-align. */
.dt-table tbody td > .dt-row { justify-content: flex-start; }
/* La prima colonna e' quella che si legge per trovare la riga: appoggiata al
   bordo con un po' d'aria, e col peso del testo normale invece che smorto —
   e' il nome che si cerca scorrendo, non un dato fra gli altri. */
.dt-table thead th:first-child,
.dt-table tbody td:first-child { padding-left: var(--dt-sp-5); }
.dt-table tbody td:first-child { font-weight: var(--dt-fw-medium); }
.dt-table tbody tr:last-child td { border-bottom: 0; }
.dt-table--zebra tbody tr:nth-child(even) { background: var(--dt-zebra); }
.dt-table--hover tbody tr:hover { background: var(--dt-hover); }
.dt-table tbody tr.dt-tr--selected { background: var(--dt-selected); }
.dt-table--compact tbody td,
.dt-table--compact thead th { padding: var(--dt-sp-3) var(--dt-sp-4); }
/* Il numero e' l'unica cosa che si incolonna a destra, e il suo titolo lo
   segue (`dt-th--num`): quello che si confronta e' l'ultima cifra. Le date e i
   codici restano a sinistra come il resto — in monospazio si incolonnano gia'
   da soli, carattere per carattere. */
.dt-td--num { text-align: right; font-variant-numeric: tabular-nums; font-family: var(--dt-font-mono); }
/* Ripetuti sulla cella: `.dt-table tbody td` pesa piu' di una classe da sola,
   e senza questa riga l'incolonnamento generale vincerebbe sul modificatore
   della singola colonna — che e' come le cifre stavano al centro insieme a
   tutto il resto anche quando erano marcate come numeri. */
.dt-table thead th.dt-th--num,
.dt-table tbody td.dt-td--num { text-align: right; }
/* I comandi di riga stanno sempre appoggiati al bordo destro, mai al centro
   della loro colonna. Il centro li fa ballare: ogni riga ne ha un numero
   diverso (il cestino manca dove non si puo' cancellare, lo sblocco compare
   solo se l'utente e' bloccato) e centrati finiscono ognuno in un punto suo,
   cosi' per premere lo stesso tasto su due righe vicine il dito si sposta.
   A destra invece l'ultimo tasto e' incolonnato e il pollice lo ritrova.
   Il `width: 1%` stringe la colonna sul contenuto; il `text-align` e il
   `justify-content` servono per le tabelle che quella colonna la allargano
   lo stesso, perche' non hanno altrove dove mettere lo spazio che avanza. */
.dt-td--actions { width: 1%; }
.dt-table tbody td.dt-td--actions { text-align: right; }
.dt-table tbody td.dt-td--actions > .dt-row { justify-content: flex-end; }
.dt-th--num { text-align: right; }

/* La colonna che dice di che colore e' una cosa e' quel colore.
   Scriverci la chiave della tavolozza — "ambra", "menta" — voleva dire dodici
   parole in colonna al posto di dodici campiture, e per sapere che faccia
   avesse un'attivita' bisognava tradurre il nome a mente. Qui la cella e' la
   campitura stessa: la stessa che il blocco avra' in giornata, dagli stessi
   `--dt-blocco-tinta` / `--dt-blocco-croma` che arrivano dallo stile in linea.
   Il nome resta nel `title`, per chi lo cerca.
   Stretta sul contenuto: e' un campione, non un dato da leggere, e allargarla
   toglierebbe spazio alle colonne che si leggono davvero. */
.dt-table tbody td.dt-td--tinta {
  --dt-blocco-c: calc(var(--dt-blocco-croma, var(--dt-tinta-c)) * var(--dt-tinta-c-scala));
  width: 1%;
  min-width: var(--dt-sp-8);
  background: oklch(
    calc(var(--dt-tinta-l) + var(--dt-blocco-luce, 0%))
    var(--dt-blocco-c)
    var(--dt-blocco-tinta)
  );
  background-clip: padding-box;
}

/* --------------------------------------------------------------------------
   13. Paginazione / breadcrumb
   -------------------------------------------------------------------------- */

.dt-pagination {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-2);
  font-size: var(--dt-fs-sm);
  color: var(--dt-text-2);
}
.dt-pagination__page {
  min-width: var(--dt-h-sm);
  height: var(--dt-h-sm);
  padding: 0 var(--dt-sp-2);
  border: 1px solid transparent;
  border-radius: var(--dt-r-sm);
  background: transparent;
  color: var(--dt-text-2);
  font: inherit;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}
.dt-pagination__page:hover { background: var(--dt-hover); color: var(--dt-text); }
.dt-pagination__page--active {
  background: var(--dt-accent);
  border-color: var(--dt-accent);
  color: var(--dt-text-inv);
  font-weight: var(--dt-fw-semibold);
}
.dt-pagination__page:disabled { opacity: 0.4; cursor: not-allowed; }

/* `min-width: 0` e ellissi: nella finestra senza cornice il percorso divide la
   barra coi comandi di riduci/ingrandisci/chiudi, e stringendo la finestra
   sarebbero quelli a finire fuori schermo. Si tronca il percorso, mai loro. */
.dt-breadcrumb {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-2);
  min-width: 0;
  overflow: hidden;
  font-size: var(--dt-fs-sm);
  color: var(--dt-text-3);
}
.dt-breadcrumb__item,
.dt-breadcrumb__testo { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dt-breadcrumb__item { color: var(--dt-text-2); cursor: pointer; background: none; border: 0; font: inherit; padding: 0; }
.dt-breadcrumb__item:hover { color: var(--dt-accent); }
/* Tappa che non porta da nessuna parte: si legge, non si clicca. */
.dt-breadcrumb__testo { color: var(--dt-text-3); }
.dt-breadcrumb__item--current { color: var(--dt-text); font-weight: var(--dt-fw-medium); cursor: default; }
.dt-breadcrumb__sep { opacity: 0.6; }

/* --------------------------------------------------------------------------
   14. Alert / progress / spinner
   -------------------------------------------------------------------------- */

.dt-alert {
  display: flex;
  align-items: flex-start;
  gap: var(--dt-sp-4);
  padding: var(--dt-sp-4) var(--dt-sp-5);
  border: 1px solid;
  border-left-width: 3px;
  border-radius: var(--dt-r-md);
  font-size: var(--dt-fs-md);
}
.dt-alert__icon { flex: none; margin-top: 1px; }
.dt-alert__title { font-weight: var(--dt-fw-semibold); }
.dt-alert__body { color: var(--dt-text-2); }
.dt-alert--info    { background: var(--dt-info-soft); border-color: var(--dt-info-border); color: var(--dt-info); }
.dt-alert--success { background: var(--dt-ok-soft); border-color: var(--dt-ok-border); color: var(--dt-ok); }
.dt-alert--warning { background: var(--dt-warn-soft); border-color: var(--dt-warn-border); color: var(--dt-warn); }
.dt-alert--danger  { background: var(--dt-danger-soft); border-color: var(--dt-danger-border); color: var(--dt-danger); }
.dt-alert .dt-alert__title { color: var(--dt-text); }

.dt-progress {
  width: 100%;
  height: 6px;
  background: var(--dt-surface-3);
  border-radius: var(--dt-r-full);
  overflow: hidden;
}
.dt-progress__bar {
  height: 100%;
  background: var(--dt-accent);
  border-radius: var(--dt-r-full);
  transition: width var(--dt-t-med);
}
.dt-progress__bar--success { background: var(--dt-ok); }
.dt-progress__bar--warning { background: var(--dt-warn); }
.dt-progress__bar--danger { background: var(--dt-danger); }
.dt-progress--indeterminate .dt-progress__bar {
  width: 35% !important;
  animation: dt-indet 1.1s ease-in-out infinite;
}
@keyframes dt-indet {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(320%); }
}

.dt-spinner {
  width: 14px;
  height: 14px;
  border: 2px solid var(--dt-border-strong);
  border-top-color: var(--dt-accent);
  border-radius: var(--dt-r-full);
  animation: dt-spin 0.65s linear infinite;
  flex: none;
}
.dt-spinner--sm { width: 11px; height: 11px; border-width: 1.5px; }
.dt-spinner--lg { width: 22px; height: 22px; border-width: 3px; }
.dt-spinner--on-accent { border-color: color-mix(in srgb, var(--dt-text-inv) 35%, transparent); border-top-color: var(--dt-text-inv); }
@keyframes dt-spin { to { transform: rotate(360deg); } }

.dt-skeleton {
  background: linear-gradient(90deg, var(--dt-surface-3) 25%, var(--dt-surface-2) 37%, var(--dt-surface-3) 63%);
  background-size: 400% 100%;
  animation: dt-shimmer 1.3s ease infinite;
  border-radius: var(--dt-r-sm);
  height: 12px;
}
@keyframes dt-shimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

/* --------------------------------------------------------------------------
   15. Modal
   -------------------------------------------------------------------------- */

.dt-modal__backdrop {
  position: fixed;
  inset: 0;
  background: var(--dt-overlay);
  z-index: var(--dt-z-modal);
  display: grid;
  place-items: center;
  padding: var(--dt-sp-8);
  animation: dt-fade var(--dt-t-med);
}
.dt-modal {
  background: var(--dt-surface);
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-lg);
  box-shadow: var(--dt-shadow-lg);
  width: 100%;
  max-width: 440px;
  max-height: 85vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: dt-pop var(--dt-t-med);
}
.dt-modal--md { max-width: 620px; }
.dt-modal--lg { max-width: 880px; }
.dt-modal__head {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-4);
  padding: var(--dt-sp-5) var(--dt-sp-6);
  border-bottom: 1px solid var(--dt-border-soft);
}
.dt-modal__title { font-size: var(--dt-fs-lg); font-weight: var(--dt-fw-semibold); flex: 1 1 auto; letter-spacing: -0.01em; }
.dt-modal__body { padding: var(--dt-sp-6); overflow: auto; flex: 1 1 auto; }
/* La striscia dell'avviso: `flex: 0 0 auto` di suo, quindi non scorre col
   corpo e resta appiccicata sopra ai tasti. Niente bordo e niente fondo
   proprio: quello che ci va dentro e' un `Alert`, che il suo colore ce l'ha
   gia'; una cornice attorno alla cornice farebbe due scatole. */
.dt-modal__avviso { padding: var(--dt-sp-4) var(--dt-sp-6) 0; }
.dt-modal__foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--dt-sp-3);
  padding: var(--dt-sp-4) var(--dt-sp-6);
  border-top: 1px solid var(--dt-border-soft);
  background: var(--dt-surface-2);
}
@keyframes dt-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes dt-pop { from { opacity: 0; transform: translateY(-6px) scale(0.985); } to { opacity: 1; transform: none; } }

/* --------------------------------------------------------------------------
   16. Toast
   -------------------------------------------------------------------------- */

.dt-toaster {
  position: fixed;
  right: var(--dt-sp-6);
  bottom: var(--dt-sp-6);
  z-index: var(--dt-z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--dt-sp-3);
  pointer-events: none;
  max-width: 340px;
}
.dt-toast {
  pointer-events: auto;
  display: flex;
  align-items: flex-start;
  gap: var(--dt-sp-3);
  padding: var(--dt-sp-4);
  background: var(--dt-surface);
  border: 1px solid var(--dt-border);
  border-left: 3px solid var(--dt-accent);
  border-radius: var(--dt-r-md);
  box-shadow: var(--dt-shadow-lg);
  animation: dt-slidein var(--dt-t-med);
}
.dt-toast--success { border-left-color: var(--dt-ok); }
.dt-toast--warning { border-left-color: var(--dt-warn); }
.dt-toast--danger  { border-left-color: var(--dt-danger); }
.dt-toast__title { font-weight: var(--dt-fw-semibold); font-size: var(--dt-fs-md); }
.dt-toast__msg { font-size: var(--dt-fs-sm); color: var(--dt-text-2); }
@keyframes dt-slidein { from { opacity: 0; transform: translateX(16px); } to { opacity: 1; transform: none; } }

/* --------------------------------------------------------------------------
   17. Tooltip (CSS only)
   -------------------------------------------------------------------------- */

.dt-tip { position: relative; display: inline-flex; }
.dt-tip::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%) translateY(3px);
  background: var(--dt-text);
  color: var(--dt-surface);
  font-size: var(--dt-fs-xs);
  font-weight: var(--dt-fw-medium);
  padding: 3px var(--dt-sp-3);
  border-radius: var(--dt-r-sm);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dt-t-fast), transform var(--dt-t-fast);
  z-index: var(--dt-z-tooltip);
  box-shadow: var(--dt-shadow-md);
}
.dt-tip:hover::after { opacity: 1; transform: translateX(-50%) translateY(0); }
.dt-tip--bottom::after { bottom: auto; top: calc(100% + 6px); transform: translateX(-50%) translateY(-3px); }
.dt-tip--bottom:hover::after { transform: translateX(-50%) translateY(0); }

/* --------------------------------------------------------------------------
   18. Utility varie
   -------------------------------------------------------------------------- */

.dt-scroll { overflow: auto; }
.dt-hidden { display: none !important; }
.dt-sr {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.dt-code {
  font-family: var(--dt-font-mono);
  font-size: var(--dt-fs-sm);
  background: var(--dt-surface-inset);
  border: 1px solid var(--dt-border-soft);
  border-radius: var(--dt-r-sm);
  padding: var(--dt-sp-4);
  color: var(--dt-text-2);
  overflow: auto;
  white-space: pre;
  margin: 0;
  line-height: 1.5;
}
.dt-kbd {
  font-family: var(--dt-font-mono);
  font-size: var(--dt-fs-xs);
  background: var(--dt-surface-3);
  border: 1px solid var(--dt-border);
  border-bottom-width: 2px;
  border-radius: var(--dt-r-sm);
  padding: 1px 5px;
  color: var(--dt-text-2);
}

/* --------------------------------------------------------------------------
   19. Accesso: scelta identita' e tastierino del PIN
   -------------------------------------------------------------------------- */

.dt-gate {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  padding: clamp(8px, 3vw, 16px);
  background: var(--dt-bg);
  overflow: auto;
}
.dt-gate__box {
  width: 100%;
  max-width: 340px;
  display: flex;
  flex-direction: column;
  gap: clamp(12px, 3vw, 16px);
  background: var(--dt-surface);
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-lg);
  box-shadow: var(--dt-shadow-lg);
  padding: clamp(16px, 4vw, 24px);
}
.dt-gate__box--largo { max-width: 420px; }

.dt-gate__lista {
  display: flex;
  flex-direction: column;
  gap: var(--dt-sp-2);
  max-height: 46vh;
  overflow: auto;
}
.dt-gate__utente {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-4);
  width: 100%;
  text-align: left;
  padding: var(--dt-sp-4) var(--dt-sp-5);
  background: var(--dt-surface-2);
  border: 1px solid var(--dt-border-soft);
  border-radius: var(--dt-r-md);
  color: var(--dt-text);
  font-size: var(--dt-fs-md);
  cursor: pointer;
  transition: background var(--dt-t-fast), border-color var(--dt-t-fast);
}
.dt-gate__utente:hover {
  background: var(--dt-surface-3);
  border-color: var(--dt-border-strong);
}
.dt-gate__utente:active { background: var(--dt-selected); }

/* Chi si sta facendo entrare: resta in testa al tastierino, con la via
   d'uscita per chi ha toccato il riquadro sbagliato. */
.dt-gate__scelto {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-4);
  padding: var(--dt-sp-4) var(--dt-sp-5);
  background: var(--dt-surface-2);
  border: 1px solid var(--dt-border-soft);
  border-radius: var(--dt-r-md);
  font-size: var(--dt-fs-md);
}
.dt-gate__cambia {
  flex: none;
  margin-left: auto;
  padding: 0;
  background: none;
  border: 0;
  color: var(--dt-text-3);
  font: inherit;
  font-size: var(--dt-fs-xs);
  text-decoration: underline;
  cursor: pointer;
}
.dt-gate__cambia:hover { color: var(--dt-text); }

/* Tastierino: cifre grandi, usabile anche col dito su un tablet in reparto. */
.dt-pin__punti {
  display: flex;
  justify-content: center;
  gap: var(--dt-sp-4);
  min-height: 11px;
}
.dt-pin__punto {
  width: 9px;
  height: 9px;
  border-radius: var(--dt-r-full);
  border: 1px solid var(--dt-border-strong);
}
.dt-pin__punto--pieno {
  background: var(--dt-accent);
  border-color: var(--dt-accent);
}
.dt-pin__tasti {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--dt-sp-4);
}
.dt-pin__tasto {
  /* Sul telefono il tasto e' un bersaglio da pollice, sul monitor non serve
     alto quanto: cresce da solo mentre la finestra si stringe, invece di
     allungarsi di sei pixel al passaggio di una soglia. */
  height: clamp(46px, 46px + (420px - 100vw) * 0.067, 54px);
  display: grid;
  place-items: center;
  background: var(--dt-surface-2);
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-md);
  color: var(--dt-text);
  font-family: var(--dt-font-mono);
  font-size: var(--dt-fs-lg);
  cursor: pointer;
  user-select: none;
  transition: background var(--dt-t-fast);
}
.dt-pin__tasto:hover { background: var(--dt-surface-3); }
.dt-pin__tasto:active { background: var(--dt-selected); }
.dt-pin__tasto:disabled { opacity: 0.4; cursor: not-allowed; }

/* Telefono: margini e misure ci arrivano gia' stretti per conto loro (vedi i
   `clamp` qui sopra); resta la sola cosa che una misura non sa fare — il
   riquadro smette di stare in mezzo e si appoggia in alto, cosi' l'elenco
   lungo scorre nella pagina invece che dentro a se stesso. */
@media (max-width: 420px) {
  .dt-gate { place-items: start center; }
  .dt-gate__lista { max-height: none; }
}

/* --------------------------------------------------------------------------
   20. Registro del server: elenco dei giorni e righe del file
   -------------------------------------------------------------------------- */

/* Due colonne dentro la card: l'elenco non si allarga a spese delle righe del
   registro, ma nemmeno resta di un palmo su una finestra stretta — si stringe
   con lei, senza aspettare la soglia in cui va sopra. */
.dt-registro {
  display: grid;
  grid-template-columns: clamp(150px, 16vw, 220px) minmax(0, 1fr);
  flex: 1 1 auto;
  min-height: 320px;
}
.dt-registro__elenco {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: var(--dt-sp-3);
  border-right: 1px solid var(--dt-border);
  overflow: auto;
}
.dt-registro__file {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-2);
  padding-right: var(--dt-sp-2);
  border-radius: var(--dt-r-md);
}
.dt-registro__file:hover { background: var(--dt-hover); }
.dt-registro__file--scelto { background: var(--dt-selected); }
.dt-registro__apri {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
  align-items: flex-start;
  padding: var(--dt-sp-3) var(--dt-sp-4);
  background: none;
  border: 0;
  border-radius: var(--dt-r-md);
  color: var(--dt-text);
  cursor: pointer;
  text-align: left;
}
.dt-registro__giorno {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-3);
  font-family: var(--dt-font-mono);
  font-size: var(--dt-fs-sm);
}
.dt-registro__peso { font-size: var(--dt-fs-xs); color: var(--dt-text-3); }

.dt-registro__vista {
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
}
.dt-registro__stato { padding: var(--dt-sp-5); }
.dt-registro__testata {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--dt-sp-4);
  padding: var(--dt-sp-3) var(--dt-sp-5);
  border-bottom: 1px solid var(--dt-border-soft);
  font-size: var(--dt-fs-sm);
}
/* Tipologie da mostrare: si accendono e si spengono, e ognuna dice quante
   righe porta con se'. */
.dt-registro__filtri {
  display: flex;
  flex-wrap: wrap;
  gap: var(--dt-sp-2);
  padding: var(--dt-sp-3) var(--dt-sp-5);
  border-bottom: 1px solid var(--dt-border-soft);
}
.dt-registro__filtro {
  display: inline-flex;
  align-items: center;
  gap: var(--dt-sp-3);
  padding: 2px var(--dt-sp-3);
  background: none;
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-sm);
  color: var(--dt-text-3);
  font-family: var(--dt-font-mono);
  font-size: var(--dt-fs-xs);
  cursor: pointer;
  transition: background var(--dt-t-fast), color var(--dt-t-fast), border-color var(--dt-t-fast);
}
.dt-registro__filtro:hover { border-color: var(--dt-border-strong); }
.dt-registro__filtro--acceso {
  background: var(--dt-selected);
  border-color: var(--dt-border-strong);
  color: var(--dt-text);
}
.dt-registro__conta { color: var(--dt-text-3); font-variant-numeric: tabular-nums; }

.dt-registro__righe {
  flex: 1 1 auto;
  overflow: auto;
  padding: var(--dt-sp-3) 0;
  background: var(--dt-surface-inset);
}
/* Una riga per riga di file: niente a capo, si scorre in orizzontale come in
   un terminale, cosi' le colonne restano allineate. */
.dt-registro__riga {
  padding: 1px var(--dt-sp-5);
  font-family: var(--dt-font-mono);
  font-size: var(--dt-fs-xs);
  line-height: 1.6;
  color: var(--dt-text-3);
  white-space: pre;
}
/* Il traffico resta smorzato: risaltano i fatti e cio' che si e' rotto. */
.dt-registro__riga--operazione { color: var(--dt-text); }
.dt-registro__riga--errore { color: var(--dt-danger); background: var(--dt-danger-soft); }
.dt-registro__vuoto {
  padding: var(--dt-sp-5);
  font-size: var(--dt-fs-sm);
  color: var(--dt-text-3);
}

/* Schermo stretto: l'elenco passa sopra e il file sotto. */
@media (max-width: 720px) {
  .dt-registro { grid-template-columns: 1fr; }
  .dt-registro__elenco {
    border-right: 0;
    border-bottom: 1px solid var(--dt-border);
    max-height: 220px;
  }
  .dt-registro__righe { max-height: 50vh; }
}

/* --------------------------------------------------------------------------
   21. Lavori: intestazione di una giornata
   -------------------------------------------------------------------------- */

/* La giornata si apre con la sua data scritta per esteso, i comandi che la
   muovono di fianco e i totali di seguito, ognuno con la propria icona.
   Nessun colore: la gerarchia la fanno peso, superficie e bordo. */
/* La pagina della giornata e' alta quanto lo spazio rimasto: la testata e il
   tasto per segnare un'ora restano fermi in cima, e a scorrere e' solo la
   colonna delle ore. In una giornata lunga il comando che si cerca di piu'
   non deve costringere a risalire. */
.dt-giorno__pagina {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--dt-sp-6);
  flex: 1 1 auto;
  min-height: 0;
  /* Il lato del tasto "piu'", che qui e' anche una misura di posto: la barra
     della data gli sta di fianco e si ancora al bordo tenendone conto, la
     giornata sotto si lascia in fondo l'aria per non finirci sotto. Un numero
     solo, cosi' le tre cose non possono scordarsi l'una dell'altra.
     Il minimo e' cinquanta e non quarantasei: dentro alla barra ci sta la data,
     e togliendo il bordo e l'aria a quarantasei restavano trentasei pixel di
     tasto — si prende mirando, e la si preme in piedi. Non e' una soglia, e'
     il fondo del `clamp`: da un telefono a un tablet stretto la misura e'
     questa, e piu' su sale come prima. */
  --dt-piu: clamp(50px, 3vw + 26px, 58px);
  /* Quanto stanno staccati dal bordo della pagina, e fra loro. */
  --dt-piu-orlo: var(--dt-sp-6);
}
.dt-giorno__scorri {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  /* `clip` e non `auto`: la colonna che entra scivolando esce di diciotto
     pixel dal bordo, e con `auto` per un attimo comparirebbe una barra di
     scorrimento orizzontale che nessuno ha chiesto. `clip` taglia e basta,
     senza rendere la cosa scorribile. */
  overflow-x: clip;
  overscroll-behavior: none;
  /* L'etichetta della prima ora e' centrata sulla sua riga, quindi meta' di
     essa sta sopra al principio della colonna: senza questo respiro finisce
     tagliata contro la testata e la giornata sembra cominciare un'ora dopo. */
  padding-top: var(--dt-sp-5);
  /* In fondo l'aria che serve alla barra della data per non coprire l'ultimo
     blocco: la sua altezza piu' i due orli. */
  padding-bottom: calc(var(--dt-piu) + var(--dt-piu-orlo) * 2);
}

/* Su una finestra larga la colonna del giorno non si stira all'infinito: al
   suo fianco compaiono i giorni prima e quelli dopo, da guardare e su cui
   saltare. Una colonna larga mezzo schermo non direbbe niente di piu' di una
   larga un palmo, e quello spazio in una giornata si usa per capire dove si e'
   arrivati.
   La regola e' una misura sola, `--dt-giorno-max`: nessuna giornata la supera,
   ne' quella su cui si scrive ne' quelle di fianco. Allargando la finestra ci
   arriva per prima quella in mezzo e li' si ferma; quello che avanza va alle
   colonne di lato, che crescono di continuo — non a scatti — fino allo stesso
   massimo; quando ci sono arrivate anche loro e avanza ancora spazio, compare
   un'altra coppia di giornate e si ricomincia. Sotto `--dt-lato-min` una
   giornata di fianco non si legge piu', e sotto quella misura non compare.
   Quante colonne siano, e quanto larghe, lo calcola il modulo Ore e lo scrive
   in uno `style` sopra questa regola: dipende da quante giornate e' andato a
   prendere, e qui non si puo' sapere. Qui restano solo le due misure. */
.dt-giorno__accanto {
  --dt-giorno-max: 380px;
  --dt-lato-min: 96px;
  /* Una fila e non una griglia. Le caselle di una griglia sono posti fissi: il
     giorno che cambia dovrebbe saltare da una casella all'altra, e fra una
     casella e l'altra non c'e' niente da percorrere. In fila invece ogni
     colonna porta con se' la propria larghezza, e cambiare giorno vuol dire
     cambiarle il valore: da li' in poi ci pensa la transizione. */
  display: flex;
  /* Arrivate tutte al massimo, quel che avanza si divide fra i due bordi
     invece di restare tutto a destra: la giornata aperta resta in mezzo. */
  justify-content: center;
  align-items: flex-start;
}
/* Il righello degli orari non scorre con le giornate: e' il fondo su cui
   passano. Quando pero' compare per la prima volta — la finestra si allarga e
   nasce la fila — sfuma dentro invece di apparire di colpo. */
.dt-giorno__asse {
  flex: 0 0 auto;
  animation: dt-arriva-lato var(--dt-t-med);
}
@keyframes dt-arriva-lato {
  from { opacity: 0; }
}

/* Cambiando giorno le giornate scorrono di una colonna, come si spinge di
   lato un calendario: avanti si spostano tutte a sinistra e quella nuova entra
   da destra, indietro il contrario. Non e' un vezzo — due giornate vicine si
   somigliano, e senza il movimento che dice da che parte si e' andati si
   finisce per scrivere sul giorno sbagliato.
   Lo scorrimento non e' uno spostamento: nessuna colonna si muove. Ogni
   colonna sta sempre alla sua data e cambia solo *ruolo* — chi era di fianco
   diventa quella aperta e si allarga, chi era aperta si stringe a lato, chi
   era fuori dal bordo entra da larghezza zero. Le somme tornano: quello che
   una perde lo prende l'altra, la fila resta larga uguale, e stando centrata
   non si sposta di un pixel mentre dentro tutto trasla. Il movimento che si
   vede e' l'effetto di larghezze che cambiano insieme, non una traslazione,
   e per questo non ha ne' un principio ne' una fine da far combaciare: si
   puo' cambiare giorno a meta' del cambio e la fila prende la nuova strada da
   dove si trova.
   Le tre misure — passo, lato, centro — le calcola il modulo Ore e le scrive
   in uno `style` qui sopra: dipendono da quante giornate ci stanno, e qui non
   si puo' sapere. */
.dt-giorno__quota {
  flex: 0 0 auto;
  width: var(--dt-lato);
  margin-left: var(--dt-giorno-gap);
  /* La colonna che si stringe taglia quello che non ci sta piu': una scritta
     non si accorcia come il riquadro che la contiene, e a colonna quasi chiusa
     uscirebbe sopra la giornata di fianco.
     Solo in orizzontale, e `clip` e non `hidden`: l'etichetta della prima ora
     e' centrata sulla sua riga e mezza sta sopra al principio della colonna.
     `hidden` porterebbe con se' anche il taglio verticale, e la giornata
     sembrerebbe cominciare un'ora dopo. */
  overflow-x: clip;
  cursor: pointer;
  transition: width var(--dt-t-slitta), margin-left var(--dt-t-slitta),
    opacity var(--dt-t-slitta);
}
.dt-giorno__quota--centro {
  width: var(--dt-centro);
  cursor: default;
}
/* Le due colonne oltre il bordo ci sono gia', con i loro blocchi dentro, larghe
   zero e invisibili. Servono a questo: una colonna che nasce nel momento in cui
   deve entrare non ha da dove venire, e comparirebbe di colpo. Cosi' invece
   quella nuova non nasce, cresce. */
.dt-giorno__quota--fuori {
  width: 0;
  margin-left: 0;
  opacity: 0;
}
/* Con piu' giornate in vista gli orari si scrivono una volta sola, nella
   colonnina di sinistra: e' quello che fa la settimana di un calendario, e
   righelli identici affiancati direbbero ogni volta la stessa cosa togliendo
   spazio ai blocchi. Perche' funzioni le tele devono partire dalla stessa
   altezza e dallo stesso minuto: alla prima ci pensa l'intestazione, che e'
   alta uguale su tutte le colonne; al secondo l'asse comune calcolato dal
   modulo Ore. */
/* Il nome del giorno sopra alla sua colonna. L'altezza e' fissa e non dettata
   dal testo: e' l'unica cosa che tiene allineate le tele, e sopra al righello
   degli orari lo stesso ingombro resta vuoto. */
.dt-giorno__intestazione {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 30px;
  margin-bottom: var(--dt-sp-3);
  padding: 0 var(--dt-sp-2);
  border-radius: var(--dt-r-md);
  font-size: var(--dt-fs-sm);
  font-weight: var(--dt-fw-semibold);
  color: var(--dt-text-3);
}
/* La giornata su cui si sta scrivendo: nome pieno, non sbiadito. */
.dt-giorno__intestazione--questa {
  background: var(--dt-surface-2);
  color: var(--dt-text);
}
/* Sbiadita e' la giornata, non il suo nome: se il velo prendesse anche
   l'intestazione il segno del passaggio nascerebbe gia' mezzo spento, e un
   segno mezzo spento non si vede.
   Anche il velo si accende e si spegne sfumando, e nello stesso tempo delle
   larghezze: la colonna che si allarga si sta schiarendo, quella che si
   stringe si sta velando, e alla fine sono passate l'una nel ruolo
   dell'altra senza che si veda un momento in cui erano due cose diverse. */
.dt-giorno__quota > :not(.dt-giorno__quota-testa) {
  opacity: 0.55;
  transition: opacity var(--dt-t-slitta);
}
.dt-giorno__quota--centro > :not(.dt-giorno__quota-testa) { opacity: 1; }
/* Dentro ai blocchi, quel che si legge solo sulla giornata aperta: chi ha
   fatto quel lavoro, a che ora, e il comando per togliere una pausa. In una
   colonna larga un palmo non ci starebbero, e in una colonna che si guarda e
   basta un comando non ha nessuno che lo prema.
   Nascosti sfumando e non tolti: la colonna che si allarga sta diventando
   quella su cui si scrive, e queste sono le cose che le crescono addosso
   mentre lo diventa. Toglierle dal DOM vorrebbe dire rifare i blocchi proprio
   nell'istante in cui si stanno spostando. */
.dt-blocco__ore,
.dt-blocco__info { transition: opacity var(--dt-t-slitta); }
.dt-giorno__quota:not(.dt-giorno__quota--centro) .dt-blocco__ore,
.dt-giorno__quota:not(.dt-giorno__quota--centro) .dt-blocco__info {
  opacity: 0;
  pointer-events: none;
}
.dt-giorno__quota-testa {
  width: 100%;
  background: transparent;
  border: 0;
  /* `font: inherit` da solo si riprenderebbe anche la misura del corpo del
     testo, e l'intestazione di ieri verrebbe piu' grande di quella di oggi. */
  font: inherit;
  font-size: var(--dt-fs-sm);
  font-weight: var(--dt-fw-semibold);
  cursor: pointer;
  transition: background var(--dt-t-fast), color var(--dt-t-fast),
    transform var(--dt-t-fast);
}
/* Le giornate di fianco restano sbiadite anche col dito sopra: sono li' per
   dare il colpo d'occhio, non per essere lette una alla volta, e accendere una
   colonna intera al passaggio del mouse spostava l'occhio via da quella su cui
   si sta scrivendo. A rispondere e' solo il nome in cima — "mar 4" — che e'
   anche l'unica cosa su cui si sta per premere.
   Il nome si riempie e si alza di un pelo: alzarsi e' quello che fa la cosa
   che si sta per prendere, e un pixel basta perche' la colonna sotto non si
   muova. Stesso segno per il dito e per la tastiera. */
.dt-giorno__quota:not(.dt-giorno__quota--centro):hover .dt-giorno__quota-testa,
.dt-giorno__quota-testa:focus-visible {
  /* Il velo del passaggio e non la superficie piena: piena e' l'intestazione
     della giornata aperta, e due nomi vestiti uguale direbbero che si e' gia'
     li'. */
  background: var(--dt-hover);
  color: var(--dt-text);
  transform: translateY(-1px);
}

/* Segnare un'ora e' l'unica cosa che si fa da questa schermata: il tasto sta
   appoggiato in basso a destra, dove arriva il pollice, invece che in fondo
   alla fila di comandi della testata, dove era il quarto bottone da sinistra.
   Sta fuori dalla colonna che scorre: la giornata gli passa sotto.
   Non e' un cerchio ma un quadrato dagli angoli tondi: il cerchio e' la forma
   dei cerchietti con l'iniziale, e qui era l'unica cosa premibile fatta come
   una cosa da leggere.
   Gli angoli sono quelli della barra che gli sta di fianco, e sono i soliti
   otto pixel di tutta la piattaforma: un raggio in percentuale li faceva
   crescere col tasto, e su un tasto alto cinquantotto pixel diventava una
   pastiglia che in questa interfaccia non assomiglia a niente. */
.dt-giorno__aggiungi {
  position: absolute;
  right: var(--dt-piu-orlo);
  bottom: var(--dt-piu-orlo);
  z-index: var(--dt-z-sticky);
  display: grid;
  place-items: center;
  width: var(--dt-piu);
  height: var(--dt-piu);
  padding: 0;
  border: 1px solid var(--dt-accent);
  border-radius: var(--dt-r-lg);
  background: var(--dt-accent);
  color: var(--dt-text-inv);
  box-shadow: var(--dt-shadow-lg);
  cursor: pointer;
  transition: background var(--dt-t-fast), transform var(--dt-t-fast);
}
.dt-giorno__aggiungi:hover { background: var(--dt-accent-hover); }
.dt-giorno__aggiungi:active { transform: scale(0.94); }

/* In cima resta il consuntivo e basta: quanto e' venuto fuori dalla giornata.
   Va a capo da sola su una finestra stretta.
   La riga sta ferma da un giorno all'altro — non c'e' niente che compaia o
   sparisca a seconda di dov'e' finito il dito nel calendario. */
.dt-giorno__head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--dt-sp-3) var(--dt-sp-5);
}

/* La barra della giornata: la data e i comandi che la muovono, appoggiati in
   basso a destra di fianco al tasto che aggiunge. Stava in cima alla pagina,
   all'angolo opposto dell'unica altra cosa che si fa da qui — e fra un giorno
   sfogliato e un'ora segnata c'era da attraversare tutto lo schermo.
   Galleggia sopra alla giornata invece di starle sopra in colonna: la fila
   dei giorni scorre a tutta altezza e la barra le passa davanti, come i
   comandi sopra a un video.
   Il fianco destro non e' il bordo della pagina ma il posto che il tasto
   "piu'" occupa, largo e staccato quanto lui: cosi' i due sono una coppia, e
   quando il tasto sparisce a mese chiuso la barra non si sposta di un pixel
   per andare a occupare il vuoto che ha lasciato.
   E' un riquadro solo — una barra vera, come i comandi sotto a un video — e
   non piu' quattro pastiglie sciolte, ognuna col suo bordo e la sua ombra:
   quattro ombre in venti pixel sporcavano la colonna che ci scorre sotto, e
   tre cose staccate non dicevano di parlare tutte della stessa data.
   Che la data non sia un tasto come gli altri lo dice un filo verticale e non
   un secondo riquadro: a sinistra del filo c'e' cosa stai guardando, a destra
   i comandi che lo cambiano. */
.dt-giorno__timone {
  position: absolute;
  z-index: var(--dt-z-sticky);
  right: calc(var(--dt-piu-orlo) + var(--dt-piu) + var(--dt-sp-4));
  bottom: var(--dt-piu-orlo);
  /* Non oltre il bordo di sinistra: su un telefono la barra arriva a filo
     della pagina e la data dentro si stringe da sola. */
  max-width: calc(100% - var(--dt-piu-orlo) * 2 - var(--dt-piu) - var(--dt-sp-4));
  display: flex;
  align-items: center;
  gap: var(--dt-sp-2);
  /* Alta quanto il "piu'" che le sta di fianco: i due sono la stessa coppia
     di comandi e stanno su una riga sola. */
  height: var(--dt-piu);
  padding: var(--dt-sp-2);
  background: var(--dt-surface);
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-lg);
  box-shadow: var(--dt-shadow-lg);
  /* L'altezza di quello che ci sta dentro: quel che resta della barra tolti
     il bordo e l'aria sopra e sotto. Un numero solo, cosi' la data, le frecce
     e "Oggi" non possono venire su di tre altezze diverse. */
  --dt-timone-h: calc(var(--dt-piu) - var(--dt-sp-2) * 2 - 2px);
}

/* Dentro alla barra i comandi sono piatti: il riquadro ce l'ha gia' la barra,
   e un bordo per tasto sarebbe una cornice dentro la cornice. Si accendono
   sotto al dito, come le voci di un menu. */
.dt-giorno__timone .dt-iconbtn,
.dt-giorno__timone .dt-btn {
  height: var(--dt-timone-h);
  border-radius: var(--dt-r-md);
  box-shadow: none;
}
.dt-giorno__timone .dt-iconbtn { width: var(--dt-timone-h); }
/* Il tasto e' grande quanto ci vuole per il pollice, e il segno dentro va
   grande di conseguenza: la freccia da quattordici pixel in un quadrato da
   quasi cinquanta si perdeva in mezzo al vuoto. */
.dt-giorno__timone .dt-iconbtn svg { width: 20px; height: 20px; }

/* La data scritta per intero, su due righe: il giorno della settimana sopra e
   "6 agosto 2026" sotto. Prima stava in due pezzi lontani — il foglietto col
   numero da una parte, il mese e l'anno dall'altra, con le frecce in mezzo —
   e per sapere che giorno fosse bisognava rimetterli insieme a mente; poi
   tutta di fila, e "giovedi'" si metteva davanti al numero che si viene a
   cercare.
   E' un tasto: ci si clicca sopra per saltare a un giorno preciso. Si vede
   che lo e' quando ci si passa sopra, non prima: dentro alla barra un bordo
   pieno sarebbe solo una cornice dentro la cornice.
   Alto quanto le frecce che gli stanno a fianco, cosi' il velo che si accende
   al passaggio e' un rettangolo della stessa taglia dei loro e non un
   francobollo in mezzo alla riga. */
.dt-giorno__data {
  font: inherit;
  display: inline-flex;
  align-items: center;
  gap: var(--dt-sp-2);
  /* Le righe sono quelle due e non vanno mai a capo da sole: le due insieme
     stanno nell'altezza della barra, una terza la farebbe crescere in su
     sopra alla giornata. Quando lo spazio finisce a togliersi e' l'anno. */
  white-space: nowrap;
  height: var(--dt-timone-h);
  padding: 0 var(--dt-sp-4);
  color: var(--dt-text);
  background: transparent;
  border: 0;
  border-radius: var(--dt-r-md);
  line-height: var(--dt-lh-tight);
  cursor: pointer;
  transition: background var(--dt-t-fast);
}
.dt-giorno__data:hover { background: var(--dt-hover); }

/* Le due righe della data, impilate e centrate nell'altezza del tasto: il
   giorno della settimana fa da cappello, sotto c'e' la data vera. In fila
   erano quattro parole da attraversare per arrivare al numero.
   Allineate a sinistra e non centrate una sull'altra: le due righe cominciano
   dallo stesso punto, e cambiando giorno il numero non balla di qua e di la'
   per stare in mezzo a un nome che si accorcia. */
.dt-giorno__data-pila {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  line-height: var(--dt-lh-tight);
}
/* La data e il suo anno sulla stessa linea di base: hanno due corpi diversi,
   e centrati uno sull'altro il "2026" verrebbe su a mezz'aria.
   Si chiama `data-riga` e non `riga` perche' `.dt-giorno__riga` e' gia' la
   riga di un'ora nella colonna qui sotto, che sta in `absolute`: due nomi
   uguali e le due scritte della data finivano una sopra all'altra. */
.dt-giorno__data-riga {
  display: flex;
  align-items: baseline;
  gap: var(--dt-sp-2);
}
.dt-giorno__dow {
  font-size: var(--dt-fs-sm);
  font-weight: var(--dt-fw-semibold);
  letter-spacing: 0.06em;
  color: var(--dt-text-3);
}
/* Cresce con la finestra invece di saltare a una soglia: e' la scritta piu'
   grande della schermata, e su un telefono in verticale deve stare comunque
   in riga coi suoi comandi.
   Il massimo e' sceso da ventidue a diciassette: adesso sopra ha una riga
   sua, e le due insieme devono stare nell'altezza della barra senza che la
   barra cresca — la barra e' alta quanto il tasto "piu'", e quello non si
   muove. */
.dt-giorno__quando {
  font-size: clamp(var(--dt-fs-lg), 0.35vw + 11px, var(--dt-fs-xl));
  font-weight: var(--dt-fw-semibold);
  font-variant-numeric: tabular-nums;
}
/* L'anno e' contorno, non notizia: sta con la data ma pesa come il giorno
   della settimana. Sotto alla soglia in cui la giornata si prende tutta la
   pagina non c'e' piu' spazio per lui nella barra, e se ne va: in che anno si
   e' lo si sa gia', e il calendario qui sotto lo scrive comunque. */
.dt-giorno__anno {
  font-size: var(--dt-fs-sm);
  font-weight: var(--dt-fw-semibold);
  color: var(--dt-text-3);
  font-variant-numeric: tabular-nums;
}
@media (max-width: 660px) {
  .dt-giorno__anno { display: none; }
}
/* Il segno che sotto c'e' un pannello: va con la riga, non con le lettere. */
.dt-giorno__data svg { align-self: center; color: var(--dt-text-3); }

/* I totali chiudono la riga e si prendono quello che avanza. */
.dt-giorno__cifre {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  flex: 1 1 auto;
  gap: var(--dt-sp-2) var(--dt-sp-5);
}

/* Il numero della giornata: e' quello che finisce in busta paga, ed e' il
   motivo per cui si apre la schermata.
   Cresce con la finestra invece di saltare a una soglia, come la data. */
.dt-giorno__totale {
  display: inline-flex;
  align-items: baseline;
  gap: var(--dt-sp-2);
  flex: 0 0 auto;
  font-size: var(--dt-fs-sm);
  color: var(--dt-text-3);
}
.dt-giorno__totale b {
  font-size: clamp(var(--dt-fs-lg), 0.25vw + 12px, var(--dt-fs-xl));
  font-weight: var(--dt-fw-semibold);
  color: var(--dt-text);
  font-variant-numeric: tabular-nums;
}

.dt-cifra {
  display: inline-flex;
  align-items: center;
  gap: var(--dt-sp-2);
  font-size: var(--dt-fs-sm);
  color: var(--dt-text-3);
}
.dt-cifra b {
  font-weight: var(--dt-fw-medium);
  color: var(--dt-text-2);
  font-variant-numeric: tabular-nums;
}
/* Un avviso in mezzo ai totali: e' un numero come gli altri, ma parla di
   qualcosa che non torna, quindi si tinge invece di stare grigio.
   Sta in fondo alla riga, spinto contro il bordo: e' l'unica cosa della
   testata che va e viene col giorno aperto, e da li' quando arriva non ha
   niente da spostare. In mezzo alle quote allontanava di uno scatto la
   giornata di ieri da quella di oggi. */
.dt-cifra--guaio { color: var(--dt-warn); margin-left: auto; }
.dt-cifra--guaio b { color: var(--dt-warn); }

/* I comandi stanno a fianco della data: sono quelli che la muovono, e messi
   in fondo alla riga sembrerebbero comandare la schermata. Le due frecce
   vicine e "Oggi" di seguito: indietro, avanti, torna. */
.dt-giorno__comandi {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-1);
  flex: 0 0 auto;
}
/* Il filo che separa la data dai suoi comandi: e' quanto basta per dire che
   di la' si legge e di qua si preme. Non arriva ai bordi della barra ma si
   ferma prima, come i separatori dei menu: toccando sopra e sotto sembrerebbe
   che la barra sia tagliata in due scatole. */
.dt-giorno__comandi::before {
  content: "";
  align-self: center;
  width: 1px;
  height: calc(var(--dt-timone-h) - var(--dt-sp-3) * 2);
  margin: 0 var(--dt-sp-3);
  background: var(--dt-border);
}
/* "Oggi" e' l'unica cosa della testata che cambia col giorno aperto: quando
   sei gia' su oggi resta dov'e' e ingrigisce, invece di richiudersi. Un tasto
   che spariva accorciava la fila dei comandi proprio mentre la si stava
   usando, e "avanti" finiva sotto un dito che cercava "Oggi". Ingrigisce
   sfumando, coi colori che il bottone interpola gia' di suo. */
.dt-giorno__oggi { display: flex; flex: 0 0 auto; }
/* E' l'unica scritta premibile della barra: viva sta scritta col nero pieno
   del testo, non col grigio delle icone, se no in mezzo a due frecce
   sembrerebbe l'etichetta di qualcos'altro. */
.dt-giorno__oggi .dt-btn { color: var(--dt-text); }
.dt-giorno__oggi .dt-btn:disabled {
  /* Grigia, non sbiadita: sbiadire vuol dire mezzo tono di tutto quanto, e su
     un tasto piatto si legge come una cosa rotta invece che spenta. */
  opacity: 1;
  background: transparent;
  color: var(--dt-text-3);
}

/* Dove sta la data dentro alla barra, e il gancio a cui il pannello dei
   giorni si appende quando si apre. Non ha piu' un riquadro suo: il riquadro
   e' la barra, e uno dentro l'altro erano due cornici per una cosa sola. */
.dt-giorno__scelta {
  position: relative;
  display: flex;
  align-items: center;
  flex: 0 0 auto;
}

/* --- Il calendario a comparsa ------------------------------------------- */

.dt-mese {
  position: absolute;
  z-index: calc(var(--dt-z-menu) + 1);
  top: calc(100% + var(--dt-sp-3));
  left: 0;
  display: flex;
  flex-direction: column;
  gap: var(--dt-sp-3);
  padding: var(--dt-sp-4);
  background: var(--dt-surface-2);
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-lg);
  box-shadow: var(--dt-shadow-lg);
  animation: dt-pop var(--dt-t-med);
}
/* Nella barra della giornata il pannello si apre all'insu' e verso l'interno:
   sotto c'e' il bordo della finestra e a destra il tasto "piu'", e da tutte e
   due le parti uscirebbe di pagina. Anche il piccolo scatto d'entrata cambia
   verso: sale da sotto invece di scendere, se no il pannello si aprirebbe
   venendo dalla parte in cui non c'e' il tasto che l'ha aperto. */
.dt-giorno__timone .dt-mese {
  top: auto;
  /* Il filo d'aria si misura dal bordo della barra e non da quello della
     data: la data adesso sta dentro alla barra, e sei pixel presi da lei
     lasciavano il pannello appiccicato al bordo di sopra. */
  bottom: calc(100% + var(--dt-sp-3) + var(--dt-sp-2) + 1px);
  left: auto;
  right: 0;
  animation-name: dt-pop-su;
}
@keyframes dt-pop-su { from { opacity: 0; transform: translateY(6px) scale(0.985); } to { opacity: 1; transform: none; } }
.dt-mese__testa {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--dt-sp-3);
}
.dt-mese__mese {
  flex: 1 1 auto;
  text-align: center;
  font-size: var(--dt-fs-sm);
  font-weight: var(--dt-fw-semibold);
  text-transform: capitalize;
}
/* L'intestazione cade sulle stesse sette colonne della griglia, se no le
   iniziali non stanno sopra ai loro giorni. */
.dt-mese__settimana,
.dt-mese__griglia {
  display: grid;
  grid-template-columns: repeat(7, clamp(28px, 6vw, 34px));
  gap: var(--dt-sp-1);
}
.dt-mese__settimana span {
  text-align: center;
  font-size: var(--dt-fs-xs);
  font-weight: var(--dt-fw-semibold);
  color: var(--dt-text-3);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.dt-mese__giorno,
.dt-mese__riempi {
  display: flex;
  align-items: center;
  justify-content: center;
  height: clamp(28px, 6vw, 34px);
  border-radius: var(--dt-r-sm);
  font-size: var(--dt-fs-sm);
  font-variant-numeric: tabular-nums;
}
.dt-mese__giorno {
  border: 1px solid transparent;
  background: transparent;
  color: var(--dt-text);
  cursor: pointer;
  transition: background var(--dt-t-fast), color var(--dt-t-fast);
}
.dt-mese__giorno:hover { background: var(--dt-hover); }
/* Oggi si segna con un bordo: e' un riferimento, non una scelta. */
.dt-mese__giorno--oggi { border-color: var(--dt-accent-border); font-weight: var(--dt-fw-semibold); }
/* Il giorno aperto invece e' una scelta gia' fatta: si inverte. */
.dt-mese__giorno--aperto {
  background: var(--dt-accent);
  border-color: var(--dt-accent);
  color: var(--dt-text-inv);
}
.dt-mese__giorno--aperto:hover { background: var(--dt-accent-hover); }

/* --------------------------------------------------------------------------
   22. Colonna della giornata: le ore in verticale
   -------------------------------------------------------------------------- */

/* La giornata si legge come un calendario, non come una tabella: l'altezza di
   un blocco *e'* la sua durata, quindi il buco fra un lavoro e l'altro si vede
   invece di doverlo calcolare. L'altezza di un minuto e' una variabile perche'
   il pollice ha bisogno di piu' spazio del mouse. */
.dt-giorno {
  --dt-min: 1.15px;
  display: grid;
  grid-template-columns: var(--dt-asse-w) 1fr;
  gap: var(--dt-sp-2);
}
/* Colonna senza righello: gli orari li scrive qualcun altro, di fianco a
   tutte. Vedi `.dt-giorno__accanto`. */
.dt-giorno--nuda { grid-template-columns: 1fr; }
/* Anche l'altezza si interpola, ed e' meta' del movimento.
   Le ore mostrate non sono sempre le stesse: la colonna si apre mezz'ora prima
   di chi ha cominciato per primo, e cambiando giornata quel primo puo' essere
   un altro. Allora la finestra si allarga o si stringe, e con lei l'altezza
   della colonna, la distanza fra le righe delle ore e la quota di ogni blocco.
   Senza transizione tutto questo succede in un fotogramma, mentre di fianco le
   larghezze stanno ancora scorrendo: e un giorno che scorre orizzontale ma
   salta in verticale si legge come un errore, non come un movimento.
   Le durate sono le stesse dello scorrimento, cosi' le due meta' finiscono
   insieme e si vedono come una cosa sola. */
.dt-giorno__ore {
  position: relative;
  transition: height var(--dt-t-slitta);
}
/* Il righello che sta per conto suo, a sinistra delle giornate affiancate:
   stessa larghezza della colonnina che avrebbero avuto dentro, cosi' gli
   orari restano dove l'occhio li cerca. In cima si tiene il posto vuoto
   dell'intestazione, altrimenti partirebbe un'intestazione piu' in alto delle
   tele che deve misurare. */
.dt-giorno__asse { width: var(--dt-asse-w); }
.dt-giorno__ora {
  position: absolute;
  right: 0;
  transition: top var(--dt-t-slitta);
  transform: translateY(-50%);
  font-size: var(--dt-fs-xs);
  font-variant-numeric: tabular-nums;
  color: var(--dt-text-3);
}
.dt-giorno__tela {
  position: relative;
  border-left: 1px solid var(--dt-border);
  transition: height var(--dt-t-slitta);
}
.dt-giorno__riga {
  position: absolute;
  left: 0;
  right: 0;
  border-top: 1px solid var(--dt-border-soft);
  transition: top var(--dt-t-slitta);
}
/* Dove siamo arrivati adesso: sopra a tutto, perche' e' la riga che si cerca
   per prima, e senza pointer-events perche' passa in mezzo ai blocchi e non
   deve rubare il dito a nessuno di loro. */
.dt-giorno__adesso {
  position: absolute;
  left: 0;
  right: 0;
  z-index: 3;
  pointer-events: none;
  border-top: 2px solid var(--dt-danger);
  transition: top var(--dt-t-slitta);
}
.dt-giorno__adesso::before {
  content: "";
  position: absolute;
  top: -5px;
  left: -4px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--dt-danger);
}
.dt-giorno__adesso-ora {
  position: absolute;
  top: -9px;
  right: 3px;
  padding: 0 var(--dt-sp-2);
  border-radius: var(--dt-r-sm);
  background: var(--dt-danger);
  color: #fff;
  font-size: var(--dt-fs-xs);
  font-weight: var(--dt-fw-medium);
  font-variant-numeric: tabular-nums;
  line-height: 16px;
}
/* Ora fuori dalla colonna: la riga sta in cima ma non e' li' che siamo, e
   tratteggiata si distingue da quella che indica un punto vero. */
.dt-giorno__adesso--fuori {
  border-top-style: dashed;
  opacity: 0.7;
}

.dt-giorno__vuoto {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: var(--dt-sp-6);
  text-align: center;
  color: var(--dt-text-3);
  font-size: var(--dt-fs-sm);
}

/* Il buco fra un pezzo di giornata e l'altro: una domanda, non un blocco.

   Fermo non si vede — un buco e' il posto dove non e' successo niente, e due
   parole in ogni buco della settimana riempirebbero di testo proprio le parti
   vuote della colonna. Col mouse sopra si accende appena, e dentro compaiono le
   risposte sottolineate.

   Si sposta e si ridimensiona come un blocco, e per lo stesso motivo: quando la
   finestra delle ore cambia, o quando il lavoro di fianco si trascina, il buco
   e' lo stesso buco che si stringe. */
.dt-buco {
  position: absolute;
  display: grid;
  place-items: center;
  overflow: hidden;
  border-radius: var(--dt-r-md);
  transition: background var(--dt-t-fast), top var(--dt-t-slitta),
    height var(--dt-t-slitta);
}
.dt-buco:hover,
.dt-buco:focus-within { background: var(--dt-hover); }

.dt-buco__scelte {
  display: flex;
  align-items: center;
  gap: 0.4em;
  max-width: 100%;
  padding: 0 var(--dt-sp-2);
  font-size: var(--dt-fs-xs);
  line-height: 1;
  white-space: nowrap;
  opacity: 0;
  transition: opacity var(--dt-t-fast);
}
.dt-buco:hover .dt-buco__scelte,
.dt-buco:focus-within .dt-buco__scelte { opacity: 1; }

/* La congiunzione: non si preme, e non deve sembrare che si prema. */
.dt-buco__o { color: var(--dt-text-3); }

.dt-buco__scelta {
  padding: 0;
  border: 0;
  background: none;
  color: var(--dt-text-2);
  font: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.dt-buco__scelta:hover { color: var(--dt-accent); }

/* Dove non c'e' un sopra le risposte stanno sempre in vista, velate: col dito
   il passaggio del mouse non esiste, e una domanda che non si vede non e' una
   domanda. Lo decide lo schermo e non un segnale, perche' cambia da schermo a
   schermo e non da giornata a giornata. */
@media (hover: none) {
  .dt-buco__scelte { opacity: 0.75; }
}

/* La colonna che si guarda e basta: la domanda non si fa. */
.dt-buco--fermo { pointer-events: none; }
.dt-buco--fermo .dt-buco__scelte { display: none; }

/* Un blocco corto resta leggibile: il testo si taglia, il riquadro no. */
.dt-blocco {
  position: absolute;
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow: hidden;
  min-height: 16px;
  /* Piu' aria di lato che sopra e sotto: sopra e sotto la misura la detta il
     blocco piu' corto che si possa disegnare (cinque minuti), di lato no. */
  padding: var(--dt-sp-2) var(--dt-sp-4);
  background: var(--dt-surface);
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-md);
  color: var(--dt-text);
  text-align: left;
  /* Il blocco si sposta e si ridimensiona invece di riapparire altrove: quando
     la finestra delle ore cambia cambiano quota e altezza di tutti, e quando
     due lavori smettono di accavallarsi cambiano corsia e larghezza. In tutti
     e tre i casi il blocco e' lo stesso — e' quello che uno guarda per capire
     dove sta andando la giornata — e un blocco che si teletrasporta va
     ritrovato ogni volta da capo. */
  transition: background var(--dt-t-fast), top var(--dt-t-slitta),
    height var(--dt-t-slitta), left var(--dt-t-slitta), width var(--dt-t-slitta);
}
button.dt-blocco { cursor: pointer; font: inherit; }
button.dt-blocco:hover { background: var(--dt-surface-2); }

/* Blocco colorato, come l'evento di un calendario: ogni tipo di lavoro ha il
   suo pastello, e la giornata si legge dai colori prima che dalle scritte.
   Dallo `style` inline arrivano la tonalita' (`--dt-blocco-tinta`, gradi
   OKLCH), quanto e' carica (`--dt-blocco-croma`) e — solo per i grigi, che
   tonalita' non ne hanno — di quanto si scosta dalla luminosita' del tema
   (`--dt-blocco-luce`): le sa solo chi ha scelto i colori, perche' fin dove
   ogni tonalita' arriva dipende dalla tonalita'.
   Quanto accenderla resta al tema, e la coppia fondo/scritta resta leggibile
   su tutti e due perche' il blocco non segue la pagina ma porta con se' il
   proprio contrasto.

   La carica del tema (`--dt-tinta-c`) e' il ripiego per chi la tonalita' la
   passa e basta: un valore prudente, che sta dentro al gamut di qualunque
   grado. `--dt-tinta-c-scala` e' invece il tocco del tema sopra alla scelta
   di chi disegna — sul fondo scuro si scarica un filo, dove la stessa
   campitura sembra accesa da dietro. */
.dt-blocco--tinta {
  --dt-blocco-c: calc(var(--dt-blocco-croma, var(--dt-tinta-c)) * var(--dt-tinta-c-scala));
  background: oklch(
    calc(var(--dt-tinta-l) + var(--dt-blocco-luce, 0%))
    var(--dt-blocco-c)
    var(--dt-blocco-tinta)
  );
  color: oklch(var(--dt-tinta-l-testo) var(--dt-tinta-c-testo) var(--dt-blocco-tinta));
  border-color: oklch(
    calc(var(--dt-tinta-l-bordo) + var(--dt-blocco-luce, 0%))
    var(--dt-blocco-c)
    var(--dt-blocco-tinta)
  );
}
/* Le righe minori sono la stessa scritta velata: il grigio di pagina su un
   fondo colorato sparirebbe. Velate di quanto basta a metterle sotto al
   titolo, non tanto da toglierle dal fondo: il posto tiene otto a uno sul suo
   pastello, l'orario cinque e mezzo — sopra la soglia anche per le scritte
   piccole, e sul piu' chiaro dei dodici.
   Due veli e non uno: il posto dove si e' lavorato si legge quasi sempre,
   l'orario solo quando si va a cercarlo. */
.dt-blocco--tinta .dt-blocco__info {
  color: inherit;
  opacity: 0.78;
}
.dt-blocco--tinta .dt-blocco__ore {
  color: inherit;
  opacity: 0.65;
}
button.dt-blocco--tinta:hover {
  background: oklch(
    calc(var(--dt-tinta-l-forte) + var(--dt-blocco-luce, 0%))
    var(--dt-blocco-c)
    var(--dt-blocco-tinta)
  );
}

/* **Il blocco che un colore non ce l'ha e' bianco.** Sono le ore che non si
   vanno a fare per conto di nessuno — l'ora d'ufficio, un negozio a cui
   nessuno ha ancora scelto la tinta — e prima erano di un grigio chiaro, che
   e' quello che i numeri dell'assenza (`NESSUNA` in `tinte.rs`) rendono da
   soli. Il grigio pero' la tavolozza ce l'ha per davvero: quattro grigi,
   scelti come le altre ventisei, e un negozio col cenere addosso faceva in
   colonna lo stesso identico blocco di uno senza niente. Il bianco non e' di
   nessuno — e' il foglio — e la colonna si divide in due senza doverci
   pensare.

   Scritto e non preso dal tema: la campitura di un blocco non segue la pagina,
   si porta dietro il proprio contrasto — e' il motivo per cui la scritta e'
   nera su tutti e due i temi — e un blocco che sullo scuro diventasse scuro
   sarebbe l'unico della colonna a cambiare faccia. Il filo intorno e' quello
   della pagina chiara: su un fondo bianco e' l'unico modo di vedere dove
   finisce un blocco e comincia quello che gli sta attaccato.

   Solo la campitura piena: la pausa tratteggiata, il viaggio velato e
   l'appuntamento rigato vengono dopo e si tengono i loro fondi, che sono i
   segni che dicono in che stato sono quelle ore. */
.dt-blocco--bianca {
  background: #fff;
  border-color: oklch(88% 0 0);
}
button.dt-blocco--bianca:hover { background: oklch(96% 0 0); }

/* Le ore che nel totale pagato non entrano — la pausa, il fermo — non portano
   la campitura: portano il contorno, tratteggiato, e il colore va li' dentro.
   Il pieno in colonna e' quanto della giornata e' lavoro pagato, e una pausa
   piena come un montaggio lo faceva contare a mente; vuota, la colonna si
   legge a occhio. Il colore pero' resta quello dell'attivita' — il tratteggio
   e' la sua tinta e non un grigio — se no la pausa smetterebbe di essere
   riconoscibile proprio come le altre undici.
   Piu' scuro del pastello (`--dt-tinta-l-tratto`) perche' sotto non c'e' piu'
   il pastello ma la pagina: un contorno chiaro su un fondo quasi bianco e' un
   colore che si indovina. Sul fondo scuro va nell'altro verso, e il token lo
   sa. Il tratto largo resta a sinistra, come nei blocchi smorzati: e' l'unico
   lato che si puo' ingrossare senza toccare l'altezza interna, da cui
   dipendono le soglie che decidono cosa ci sta scritto dentro. */
.dt-blocco--fuori-conto {
  --dt-blocco-c: calc(var(--dt-blocco-croma, var(--dt-tinta-c)) * var(--dt-tinta-c-scala));
  background: var(--dt-surface);
  border-style: dashed;
  border-left-width: 3px;
  border-color: oklch(
    calc(var(--dt-tinta-l-tratto) + var(--dt-blocco-luce, 0%))
    calc(var(--dt-blocco-c) * var(--dt-tinta-c-tratto))
    var(--dt-blocco-tinta)
  );
}
/* Il blocco che non ha scritto nessuno: il tragitto fra un lavoro e l'altro,
   che il programma tira da se' guardando il buco fra due ore.

   Tratteggiato non lo e' piu': il tratteggio dice una cosa sola — queste ore
   nel conto non entrano — e le ore del viaggio si pagano come tutte le altre.
   Un viaggio col contorno della pausa mandava a occhio il messaggio sbagliato,
   e la campitura si legge prima della scritta.

   Adesso e' **velata**: la tinta posata sopra la pagina, il contorno pieno un
   gradino piu' su, messa in colonna alla sua ora. Vuol dire la cosa giusta
   senza inventare un disegno nuovo: il velo e' una tinta *proposta*, che
   diventa quella del blocco appena qualcuno la conferma, ed e'
   esattamente cosa e' un viaggio calcolato finche' non lo si tocca. Riquadro
   chiuso e contorno pieno come tutti gli altri blocchi, perche' quelle ore
   sono vere: quello che cambia e' quanto e' carica la campitura, e in colonna
   il pieno resta il lavoro scritto.

   Le tre campiture si leggono in fila senza didascalie: piena = scritto e
   pagato, velata = pagato, ma a dirlo e' il programma, vuota e tratteggiata =
   scritto e non pagato.

   La scritta e' quella della pagina: il velo tiene il nero sul tema chiaro e
   il bianco su quello scuro, mentre il pastello pieno vuole sempre il nero.
   Il tratto largo a sinistra e' l'unica cosa che il viaggio tiene dei blocchi
   non campiti: e' il lato che si puo' ingrossare senza toccare le soglie di
   cosa ci sta scritto dentro, ed e' quello che lo fa riconoscere in mezzo a
   una colonna piena. */
.dt-blocco--calcolato {
  --dt-blocco-c: calc(var(--dt-blocco-croma, var(--dt-tinta-c)) * var(--dt-tinta-c-scala));
  background: oklch(
    min(96%, calc(var(--dt-velo-l) + var(--dt-blocco-luce, 0%) * 0.5))
    calc(var(--dt-blocco-c) * var(--dt-velo-c-scala))
    var(--dt-blocco-tinta)
  );
  border-color: oklch(
    min(96%, calc(var(--dt-velo-l-bordo) + var(--dt-blocco-luce, 0%) * 0.5))
    calc(var(--dt-blocco-c) * var(--dt-velo-c-scala))
    var(--dt-blocco-tinta)
  );
  border-left: 3px solid oklch(
    calc(var(--dt-tinta-l-tratto) + var(--dt-blocco-luce, 0%))
    calc(var(--dt-blocco-c) * var(--dt-tinta-c-tratto))
    var(--dt-blocco-tinta)
  );
}
/* Sotto al dito si accende come tutti gli altri blocchi: un gradino di
   luminosita', e niente di piu'. */
button.dt-blocco--calcolato:hover {
  background: oklch(
    min(96%, calc(var(--dt-velo-l-bordo) + var(--dt-blocco-luce, 0%) * 0.5))
    calc(var(--dt-blocco-c) * var(--dt-velo-c-scala))
    var(--dt-blocco-tinta)
  );
}

/* Quello che segue il buco e le ore non le conta — **la pausa scritta in un
   buco**, che dalla 0.3.0 sta li' dentro come il viaggio invece di essere un
   blocco a parte — porta il contorno della pausa e non il velo: fra le due
   cose, quella che pesa in colonna e' che quelle ore nel totale non entrano. Il
   velo dice chi l'ha scritto, il tratteggio dice se si paga, e a leggersi per
   prima e' la seconda. */
.dt-blocco--calcolato.dt-blocco--fuori-conto {
  background: var(--dt-surface);
  border-style: dashed;
  border-left: 3px dashed oklch(
    calc(var(--dt-tinta-l-tratto) + var(--dt-blocco-luce, 0%))
    calc(var(--dt-blocco-c) * var(--dt-tinta-c-tratto))
    var(--dt-blocco-tinta)
  );
  border-color: oklch(
    calc(var(--dt-tinta-l-tratto) + var(--dt-blocco-luce, 0%))
    calc(var(--dt-blocco-c) * var(--dt-tinta-c-tratto))
    var(--dt-blocco-tinta)
  );
}
button.dt-blocco--calcolato.dt-blocco--fuori-conto:hover {
  background: var(--dt-surface-2);
}

/* **L'appuntamento: consegnato, non ancora fatto.** Il posto e' riservato,
   sopra non e' ancora successo niente — quindi la campitura e' **a righe**: la
   tinta del negozio in strisce diagonali sul suo velo, come l'ora promessa e
   non confermata di qualunque calendario. Si legge da mezza stanza e senza
   didascalie: righe = da fare, pieno = successo. Confermata l'ora le righe si
   chiudono nel pieno, ed e' l'unico momento in cui un blocco cambia peso
   guardando la settimana.

   **Porta il colore del suo negozio**: la settimana che deve ancora succedere
   e' esattamente quella in cui serve sapere per conto di chi si va — la
   mattina in cui ci si prepara. Un piano che non si legge per negozio e' un
   piano che si legge una riga per volta.

   Le due strisce sono i due livelli che gia' esistono — l'acquerello e il
   velo — quindi la scritta nera sopra tiene il contrasto del piu'
   chiaro dei due, e il tema scuro le sposta insieme a tutto il resto.

   Non tratteggiato, e non e' una scelta di gusto: il tratteggio dice gia'
   un'altra cosa, cioe' *queste ore nel conto non entrano* (vedi
   `--fuori-conto`). Le righe sono un segno nuovo perche' dicono una cosa che
   prima non aveva un segno suo.

   Contro il viaggio calcolato — l'altra campitura non piena — la differenza e'
   tutta li': il calcolato e' un velo uniforme col binario a sinistra, questo
   e' rigato col contorno pieno della tinta. */
.dt-blocco--appuntamento {
  --dt-blocco-c: calc(var(--dt-blocco-croma, var(--dt-tinta-c)) * var(--dt-tinta-c-scala));
  /* Di quanto scendono le due strisce sotto al dito: una sola manopola, cosi'
     l'hover resta un gradino e non una campitura terza. */
  --dt-riga-giu: 0%;
  background: repeating-linear-gradient(
    -45deg,
    oklch(
      calc(var(--dt-riga-l-a) + var(--dt-blocco-luce, 0%) - var(--dt-riga-giu))
      calc(var(--dt-blocco-c) * var(--dt-acquerello-c-scala))
      var(--dt-blocco-tinta)
    ) 0 6px,
    oklch(
      calc(var(--dt-riga-l-b) + var(--dt-blocco-luce, 0%) - var(--dt-riga-giu))
      calc(var(--dt-blocco-c) * var(--dt-velo-c-scala))
      var(--dt-blocco-tinta)
    ) 6px 12px
  );
  border-color: oklch(
    calc(var(--dt-acquerello-l-bordo) + var(--dt-blocco-luce, 0%))
    var(--dt-blocco-c)
    var(--dt-blocco-tinta)
  );
  color: var(--dt-text);
}
button.dt-blocco--appuntamento:hover { --dt-riga-giu: var(--dt-riga-hover); }
/* Senza tinta — nessun negozio, nessuna attivita' colorata — resta comunque un
   riquadro che si distingue da uno pieno. */
.dt-blocco--appuntamento:not(.dt-blocco--tinta) {
  background: var(--dt-surface-inset);
  border-color: var(--dt-border-strong);
}
/* L'ora prevista sta nell'inchiostro smorto; confermata passa in quello pieno.
   E' il terzo segno, e non aggiunge niente da disegnare: si legge da vicino,
   quando il colpo d'occhio ha gia' detto il resto. */
.dt-blocco--appuntamento .dt-blocco__ore { opacity: 0.6; }

/* Tolta la campitura, la scritta torna l'inchiostro della pagina: il nero del
   blocco tinto seguiva il pastello, e senza pastello sotto sul tema scuro
   sarebbe nero su nero. */
.dt-blocco--tinta.dt-blocco--fuori-conto,
.dt-blocco--tinta.dt-blocco--calcolato { color: var(--dt-text); }
/* Una pausa messa in calendario e non ancora fatta: le due campiture si
   sommano, e vince il tratteggio — perche' quello riguarda il conto, che e' la
   domanda piu' urgente delle due. Che non sia ancora successo lo dice comunque
   l'ora smorta. */
.dt-blocco--appuntamento.dt-blocco--fuori-conto {
  background: oklch(
    min(96%, calc(var(--dt-velo-l) + var(--dt-blocco-luce, 0%) * 0.5)) calc(var(--dt-blocco-c) * var(--dt-velo-c-scala))
      var(--dt-blocco-tinta)
  );
  color: var(--dt-text-2);
}
button.dt-blocco--fuori-conto:hover { background: var(--dt-surface-2); }

/* Accavallato con un altro: si segnala, non si vieta. Il bordo intero e non
   solo un lato: e' l'unico modo di farsi vedere anche sopra a un blocco che ha
   gia' un colore suo. */
.dt-blocco--avviso { border-color: var(--dt-warn); }

/* Dentro al blocco ci sono tre cose e vanno lette in quest'ordine: che lavoro
   e', dove, e a che ora. Prima erano quasi la stessa scritta — undici pixel e
   mezzo il titolo, dieci e mezzo le altre due, tutte con lo stesso peso — e in
   una colonna di dieci blocchi non c'era niente che venisse letto per primo.
   Adesso il titolo e' il corpo pieno della piattaforma in semigrassetto,
   il posto un gradino sotto, l'orario un gradino sotto ancora: si guarda la
   colonna e si vede cosa si e' fatto, non sei righe da sillabare. */
.dt-blocco__testa {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-2);
  font-size: var(--dt-fs-md);
  font-weight: var(--dt-fw-semibold);
  line-height: 1.25;
}

/* Chi c'era, in cima al blocco e a destra.

   Sta nella testa e non fra i dati per un motivo di misura: i dati stanno su
   una riga che si taglia quando il blocco e' corto, e «con chi» era proprio
   quello che si andava a cercare guardando la giornata di ieri. Le facce non
   si tagliano — tre cerchietti stanno dove non sta una parola — e restano al
   loro posto anche su un blocco di mezz'ora.

   L'anello che stacca una faccia dall'altra deve essere del colore che il
   blocco ha davvero sotto, se no su una campitura ambra si vede un contorno
   bianco intorno a ogni testa. */
.dt-blocco { --dt-facce-anello: var(--dt-surface); }
.dt-blocco--tinta {
  --dt-facce-anello: oklch(
    calc(var(--dt-tinta-l) + var(--dt-blocco-luce, 0%))
    var(--dt-blocco-c)
    var(--dt-blocco-tinta)
  );
}
/* E sul blocco bianco l'anello e' bianco: sta piu' avanti nel foglio della
   regola qui sopra apposta, che a parita' di peso vince l'ultima scritta. */
.dt-blocco--bianca { --dt-facce-anello: #fff; }
.dt-blocco__testa .dt-facce { margin-left: auto; }
.dt-blocco__testa .dt-avatar {
  width: 18px;
  height: 18px;
  font-size: 10px;
  box-shadow: 0 0 0 1.5px var(--dt-facce-anello);
}
.dt-blocco__testa .dt-facce > .dt-faccia + .dt-faccia { margin-left: -6px; }
/* Il conto di quelle che non si disegnano, dentro a un blocco: una macchia
   dello stesso colore, un po' piu' carica. Col fondo della pagina — che e'
   quasi bianco — su una campitura ambra usciva un bollo bianco, e in una
   colonna di blocchi era la cosa piu' luminosa dello schermo per dire «e altri
   due». */
.dt-blocco__testa .dt-facce__resto {
  height: 18px;
  min-width: 18px;
  margin-left: -6px;
  font-size: 10px;
  background: rgba(0, 0, 0, 0.12);
  color: inherit;
  box-shadow: 0 0 0 1.5px var(--dt-facce-anello);
}
/* L'avviso: a questo blocco manca qualcosa che era preteso.
   Era un pallino pieno, e un pallino e' un segno muto — vuol dire quello che
   uno ha imparato che vuol dire, e chi apre il programma la prima volta lo
   legge come una decorazione. Il triangolo invece si sa gia' leggere: da
   fermo, senza didascalia, dice che li' c'e' qualcosa che non va. Cosa manca,
   per nome, resta nel `title`.
   Un segno e non una parola perche' mezz'ora di blocco e' alta trentaquattro
   pixel, e una riga in piu' toglierebbe il posto dove si e' stati. Alto quanto
   l'icona dell'attivita' che gli sta di fianco: piu' piccolo si impasterebbe,
   piu' grande si mangerebbe il titolo.
   `currentColor`: dentro a un blocco tinto la scritta e' nera e il triangolo
   con lei, in uno grigio e' l'inchiostro della pagina. Un giallo d'avviso qui
   sarebbe un colore che litiga con la tinta dell'attivita' — e su quella ambra
   sparirebbe del tutto. */
.dt-blocco__bollino {
  flex: none;
  display: inline-flex;
  align-items: center;
}
/* L'orario, in coda al titolo. `nowrap` e non a capo: e' una misura sola —
   `08:00 - 12:00` — e spezzata in due righe raddoppia l'altezza del titolo,
   che e' l'altezza da cui dipende quanti dati ci stanno sotto. A stringersi
   dev'essere il titolo, che sa andare a puntini. */
.dt-blocco__ore {
  flex: none;
  margin-left: auto;
  padding-left: var(--dt-sp-3);
  font-size: var(--dt-fs-xs);
  font-weight: var(--dt-fw-regular);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--dt-text-3);
}
/* Quello che il blocco si porta scritto dentro: il posto, il negozio, chi
   c'era, i chilometri, quanti tendaggi, quanti materiali, le foto, le note.
   Era una riga sola con i pezzi attaccati da un punto, e a puntini finiva
   sempre nello stesso posto: il primo dato si leggeva, gli altri si
   indovinavano. Adesso ogni dato e' un riquadro suo, col proprio segno
   davanti, e vanno a capo finche' il blocco e' alto abbastanza per tenerli.
   Quelli che non ci stanno restano fuori, e va bene: arrivano in ordine di
   importanza, quindi a cadere e' sempre il meno urgente.
   `align-content: flex-start` tiene le righe attaccate in alto invece di
   spaziarle in verticale: un dato solo dev'essere sotto al titolo, non in
   mezzo al blocco. */
.dt-blocco__info {
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  gap: 0 var(--dt-sp-4);
  overflow: hidden;
  /* Sotto la prima soglia non c'e' posto per niente: vedi le regole di
     contenitore in fondo alla sezione. */
  max-height: 0;
  color: var(--dt-text-2);
}
/* Un dato: il segno, e quello che dice. L'altezza della riga e' un numero
   fisso e non un multiplo del corpo del testo perche' e' l'unita' con cui si
   contano le righe che ci stanno: se cambiasse col testo, le soglie qui sotto
   taglierebbero l'ultima riga a meta'. */
.dt-blocco__dato {
  display: inline-flex;
  align-items: center;
  gap: var(--dt-sp-1);
  max-width: 100%;
  min-width: 0;
  height: 15px;
  font-size: var(--dt-fs-xs);
  line-height: 15px;
}
.dt-blocco__dato > svg { flex: none; opacity: 0.75; }

/* La fetta di stato: «Da fare», «Da finire», e il silenzio per «Fatto».
   Un disegno solo per un elemento solo: la stessa fetta sta in testa al blocco
   in colonna, sulla testata della sua scheda e sul cartellino della bolla.
   E' inchiostro e mai una tinta: il colore del blocco dice per conto di chi si
   lavora, e una fetta colorata gli parlerebbe sopra. `currentColor` fa il
   resto: sul pastello la scritta e' nera e la fetta con lei, sul grigio e'
   l'inchiostro della pagina.
   Tre toni, tre pesi, in ordine di urgenza:
   - `--fare` e' un contorno: il posto c'e', dentro non c'e' ancora niente —
     la stessa cosa che dicono le righe della campitura, da vicino;
   - `--finire` e' piena d'inchiostro: e' l'unica cosa del blocco che chiede
     di tornarci, e si vede per prima;
   - `--fatto` e' smorzata: compare solo in scheda, dove lo stato va detto per
     esteso, e non chiede niente. */
.dt-stato {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: var(--dt-sp-1);
  height: 18px;
  padding: 0 var(--dt-sp-3);
  border-radius: var(--dt-r-full);
  font-size: var(--dt-fs-xs);
  font-weight: var(--dt-fw-medium);
  line-height: 1;
  white-space: nowrap;
}
.dt-stato--fare {
  border: 1px solid currentColor;
  opacity: 0.85;
}
.dt-stato--finire {
  background: rgba(0, 0, 0, 0.78);
  color: #fff;
}
.dt-stato--fatto { opacity: 0.65; }
/* La misura da testata: sulla scheda di un blocco la fetta e' un titolo. */
.dt-stato--grande {
  height: 24px;
  padding: 0 var(--dt-sp-4);
  font-size: var(--dt-fs-sm);
}
/* Trascinamento.
   `touch-action` decide di chi e' il gesto quando a premere e' un dito o una
   penna: del browser, che scorre, o nostro, che sposta. Non si puo' avere tutti
   e due. Del mouse non dice niente — la freccia non scorre, per quello c'e' la
   rotella — e infatti qui non compare nessuna `@media` sulla punta: sarebbe una
   domanda sulla macchina, e su un due-in-uno la stessa macchina riceve il
   pollice e la freccia nello stesso pomeriggio. Chi deve distinguere sono i
   gesti, e lo fanno guardandosi il `pointerType` (`di_dito`, in `giorno.rs`).
   Qui si lascia scorrere e basta.
   La giornata e' piu' alta dello schermo, e il dito la scorre passando **da
   dovunque**: dal vuoto (`pan-y` sulla tela) e da sopra ai blocchi (`pan-y` sui
   blocchi, che su un telefono coprono quasi tutta la colonna — se se lo
   tenessero loro, per arrivare alla sera bisognerebbe indovinare i buchi fra
   l'uno e l'altro).
   Il gesto torna nostro in due modi, e nessuno dei due e' questa proprieta'
   quando il dito e' gia' sceso — a meta' gesto il browser non cambia idea:
   - sul vuoto **prima**, col doppio colpo: la finestra che apre `Doppio` mette
     `--armata` fra un tocco e l'altro, cioe' in tempo;
   - sul blocco **durante**, con la pressione tenuta: li' a fermare lo
     scorrimento e' il `preventDefault` sul `touchmove`, che vale perche' una
     pressione ferma non ha ancora fatto scorrere niente.
   L'ordine conta: dev'essere l'elemento toccato a dire `none`, e non un suo
   antenato, se no la tela spegnerebbe lo scorrimento anche sopra a se
   stessa. */
.dt-giorno__tela--viva { touch-action: pan-y; }
.dt-giorno__tela--armata { touch-action: none; }
.dt-blocco--mobile {
  touch-action: pan-y;
  cursor: grab;
  user-select: none;
  /* Tenere premuto e' il nostro gesto: il telefono non ci deve appiccicare
     sopra la sua lente sul testo. */
  -webkit-touch-callout: none;
}
/* Mentre e' in mano: sopra a tutti gli altri, altrimenti sparisce sotto il
   blocco che sta scavalcando proprio nel momento in cui serve vederlo. */
.dt-blocco--preso {
  z-index: 2;
  cursor: grabbing;
  border-color: var(--dt-accent);
  box-shadow: var(--dt-shadow-md);
  transition: none;
}
/* Il blocco che si sta disegnando col dito: non esiste ancora, e si vede. */
.dt-blocco--bozza {
  z-index: 2;
  pointer-events: none;
  background: var(--dt-accent-soft);
  border: 1px dashed var(--dt-accent);
  border-left: 3px solid var(--dt-accent);
  transition: none;
}
/* Mentre una mano e' sulla tela, li' dentro non si interpola piu' niente.
   Sotto al dito il ritardo non e' un movimento ma una gomma: il blocco resta
   indietro rispetto a dove si sta tirando, e la pausa che si stringe di fianco
   arriva un attimo dopo il bordo che l'ha stretta. Un blocco preso lo sa gia'
   per conto suo (`--preso`); questa regola lo dice a tutti gli altri della
   stessa tela, che si muovono per colpa sua. */
.dt-giorno__tela:has(.dt-blocco--preso) .dt-blocco,
.dt-giorno__tela:has(.dt-blocco--bozza) .dt-blocco {
  transition: background var(--dt-t-fast);
}

/* Le maniglie sono strisce invisibili sui bordi: si vedrebbero solo come
   ingombro, e su un blocco di mezz'ora l'ingombro e' meta' del blocco.
   Alte 14px perche' sotto non si prendono col pollice. */
.dt-blocco__maniglia {
  position: absolute;
  left: 0;
  right: 0;
  height: 14px;
  cursor: ns-resize;
  /* Come il blocco su cui stanno: col dito si scorre, il bordo si tira dopo
     averlo tenuto premuto. */
  touch-action: pan-y;
}
.dt-blocco__maniglia--su { top: 0; }
.dt-blocco__maniglia--giu { bottom: 0; }

/* Quanto ci sta scritto dentro dipende da quanto e' alto, e alto quanto dura.
   Il blocco e' alto quanto la sua durata: mezz'ora fa trentaquattro pixel, e
   li' dentro il titolo e il posto non ci stanno tutti e due — il secondo
   finiva tagliato a meta' contro il bordo, che e' peggio che non esserci.
   Sotto le due soglie le righe se ne vanno per intero, la piu' minuta per
   prima. Non e' una `@media`: la finestra non cambia, cambia il blocco, e a
   dirlo e' l'altezza sua (`@container`), quella che gli e' stata messa in
   `style` dagli orari.
   Cosa resta: sempre il titolo, che e' cosa si e' fatto; poi il posto; per
   ultimo l'orario, che nella colonna si legge gia' da dove sta il blocco. */
.dt-blocco {
  container-type: size;
  container-name: blocco;
}
/* Le soglie sono sull'altezza *interna*: una richiesta al contenitore misura
   il suo riquadro di contenuto, quindi i dieci pixel fra padding e orli sono
   gia' fuori dal conto. Trentaquattro dentro sono quarantaquattro di blocco,
   cioe' poco piu' di mezz'ora segnata. */
/* Le righe di dati si contano, non si tagliano a meta'. Il titolo si prende
   ventuno pixel — diciannove di riga piu' due di stacco — e quello che avanza
   si divide per quindici, che e' l'altezza di una riga di dati. Da qui le
   soglie: trentasei per la prima riga, quindici in piu' per ognuna delle
   altre.
   Sono `min-height` e non `max-height` perche' la regola cresce col blocco:
   sotto la prima soglia il tetto a zero lascia il titolo da solo, e da li' in
   su ogni soglia scoperchia una riga. Oltre le quattro il tetto sparisce: di
   righe di dati un blocco non ne ha piu' di quattro. */
@container blocco (min-height: 36px) {
  .dt-blocco__info { max-height: 15px; }
}
@container blocco (min-height: 51px) {
  .dt-blocco__info { max-height: 30px; }
}
@container blocco (min-height: 66px) {
  .dt-blocco__info { max-height: 45px; }
}
@container blocco (min-height: 81px) {
  .dt-blocco__info { max-height: 60px; }
}
@container blocco (min-height: 96px) {
  .dt-blocco__info { max-height: none; }
}
@container blocco (max-height: 16px) {
  .dt-blocco__testa { font-size: var(--dt-fs-sm); line-height: 1.1; }
  .dt-blocco__ore { display: none; }
  /* Su una fettina di cinque minuti lo stato lo dicono gia' le righe della
     campitura: la fetta si toglie prima che si mangi il titolo. */
  .dt-stato { display: none; }
}
/* Stretto: l'orario se ne va per primo. Dentro a un blocco largo un pollice
   `08:00 - 12:00` si prende due terzi della riga e del titolo resta
   un'iniziale, e a che ora sta un blocco lo dice gia' dove sta nella colonna —
   e' l'unica cosa che la colonna sa dire da se'. Succede in due posti: nelle
   giornate di fianco, che sono strette per mestiere, e nei blocchi che si
   accavallano, che si dividono la larghezza in due. */
@container blocco (max-width: 165px) {
  .dt-blocco__ore { display: none; }
  /* Stretta, la fetta tiene il segno e lascia la parola: le righe della
     campitura dicono gia' il grosso, il segno conferma da vicino. */
  .dt-stato__parola { display: none; }
  .dt-stato { padding: 0 var(--dt-sp-2); }
}

/* --------------------------------------------------------------------------
   23. Scheda del blocco: testatina, cartellino, commessa, righe a quantita',
       foto
   -------------------------------------------------------------------------- */

/* La commessa scelta non e' un campo ma un riquadro: una volta trovata resta
   li' e si legge, invece di restare dentro a una casella di ricerca che invita
   a ridigitarla. Il comando per cambiarla sta dentro al riquadro stesso —
   attaccato alla cosa che cambia, non in una barra da un'altra parte. */
.dt-commessa {
  --dt-blocco-c: calc(var(--dt-blocco-croma, var(--dt-tinta-c)) * var(--dt-tinta-c-scala));
  display: flex;
  flex-direction: column;
  gap: var(--dt-sp-2);
  padding: var(--dt-sp-5);
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-md);
  background: var(--dt-surface-2);
}
/* **Il filo a sinistra e' il colore del negozio**, ed e' lo stesso che il
   blocco avra' in colonna fra un momento: si sceglie «Tende & Design» qui, e in
   giornata compare un blocco di quel colore. Nessuno deve imparare la
   corrispondenza, la si vede succedere.

   Sta in una classe sua e non nella regola di sopra con un valore di ripiego,
   ed e' una precauzione vera e non pulizia: un `var()` senza valore non
   *ignora* la dichiarazione, la rende **invalida al momento del calcolo**, e
   una `border-left` invalida non ricade su quella di prima — torna al valore
   iniziale, cioe' `none`. Il riquadro di un negozio senza colore si sarebbe
   ritrovato con tre bordi su quattro. */
.dt-commessa--tinta {
  border-left-width: 4px;
  border-left-color: oklch(
    calc(var(--dt-tinta-l-bordo) + var(--dt-blocco-luce, 0%))
    var(--dt-blocco-c)
    var(--dt-blocco-tinta)
  );
  padding-left: calc(var(--dt-sp-5) - 3px);
}
/* Il nome del posto e' la cosa piu' grande della scheda dopo il titolo della
   finestra: e' l'unica riga che dice se si sta segnando l'ora sul lavoro
   giusto, e stava scritta come le tre righe di contorno che ha sotto. */
.dt-commessa__nome {
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--dt-fs-lg);
  font-weight: var(--dt-fw-semibold);
  line-height: var(--dt-lh-tight);
}
/* Indirizzo e resti stanno sotto e piu' smorti: servono a confermare di aver
   preso la commessa giusta, non a essere letti ogni volta. */
.dt-commessa__riga,
.dt-commessa__dove,
.dt-commessa__resta {
  color: var(--dt-text-2);
  font-size: var(--dt-fs-sm);
  line-height: var(--dt-lh-normal);
}
/* L'indirizzo sta su una riga sola con la sua puntina; i resti sono un elenco
   che va a capo, quindi restano testo che scorre. */
.dt-commessa__dove {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-2);
}
.dt-commessa__dove svg { flex: 0 0 auto; color: var(--dt-text-3); }
/* Chi paga sta sulla riga sotto al posto, e non e' smorto come l'indirizzo:
   e' la seconda cosa che si legge, non la terza. Il pallino davanti porta il
   suo colore — lo stesso del filo — cosi' la riga dice il nome e il colore
   insieme, ed e' li' che i due si imparano uno per l'altro. */
.dt-commessa__negozio {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-3);
  min-width: 0;
  color: var(--dt-text);
  font-size: var(--dt-fs-sm);
  font-weight: var(--dt-fw-medium);
  line-height: var(--dt-lh-normal);
}
.dt-commessa__negozio > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Il negozio che non c'e' ancora: e' un fatto, non un difetto di scrittura, e
   va detto con parole invece che con un vuoto. Corsivo e smorto perche' non e'
   un nome — leggerlo come tale manderebbe a cercare in archivio un negozio che
   si chiama cosi'. */
.dt-commessa__senza {
  color: var(--dt-text-2);
  font-style: italic;
  font-weight: var(--dt-fw-regular);
}
/* Il codice d'ordine e' un codice: si legge cifra per cifra, si detta al
   telefono, e in tondo proporzionale il numero uno e la elle sono lo stesso
   segno. Sta in coda alla riga del negozio e non su una riga sua: e' la stessa
   informazione — quale ordine, di chi — spezzata in due meta'. */
.dt-commessa__codice {
  flex: 0 0 auto;
  color: var(--dt-text-2);
  font-family: var(--dt-font-mono);
  font-size: var(--dt-fs-xs);
}
/* Cosa resta da montare e' l'unica riga per cui valga la pena tenere aperto il
   riquadro dopo aver scelto, e sta staccata dalle altre da un filo: sopra c'e'
   *quale lavoro*, sotto *cosa c'e' da fare*. Erano quattro righe di seguito, e
   la quarta si leggeva come la coda della terza. */
.dt-commessa__resta {
  margin-top: var(--dt-sp-2);
  padding-top: var(--dt-sp-3);
  border-top: 1px solid var(--dt-border-soft);
}

/* La testata della maschera con cui in cantiere nasce del lavoro nuovo.

   Non e' una finestra dentro alla finestra: prende il posto dell'albero nello
   stesso foglio. Su un telefono una seconda maschera sopra alla scheda del
   blocco e' un francobollo dentro a un francobollo, e la via d'uscita — il
   tasto che chiude quella di sopra senza chiudere quella di sotto — e' due
   tasti uguali a due centimetri di distanza.

   Titolo e riga sotto ripetono la coppia della `.dt-domanda`, un gradino piu'
   in basso: quella e' la domanda della schermata, questa e' cosa si sta
   facendo dentro alla risposta. Stesso ritmo, peso diverso, e non c'e' un
   secondo modo di intitolare qualcosa da imparare. */
.dt-apri {
  display: flex;
  flex-direction: column;
  gap: var(--dt-sp-2);
  padding-bottom: var(--dt-sp-4);
  border-bottom: 1px solid var(--dt-border-soft);
}
.dt-apri__titolo {
  font-size: var(--dt-fs-md);
  font-weight: var(--dt-fw-semibold);
  line-height: var(--dt-lh-tight);
}
.dt-apri__sotto {
  color: var(--dt-text-2);
  font-size: var(--dt-fs-sm);
  line-height: var(--dt-lh-normal);
}
/* Il colore del negozio appena scelto non si scrive qui sotto, ed e' una
   rinuncia decisa e non una dimenticanza: c'era, ed era un pallino con di
   fianco «in calendario i suoi blocchi sono ambra».
   Se n'e' andato per due motivi. Il primo e' che nominava la chiave della
   tavolozza, che e' vocabolario del programma: chi monta le tende non ha
   nessun motivo di sapere che quel colore si chiama ambra. Il secondo e' che
   arrivava tardi e diceva poco — un istante dopo, chiusa la maschera, quel
   colore riempie il cartellino in cima alla scheda e poi il blocco in colonna,
   che e' un modo molto piu' forte di dire la stessa cosa. */

/* Cose gia' scritte in tabella su cui si puo' anche premere: il distintivo che
   dice cosa manca, il numero delle commesse di un posto, il nome del posto
   dentro a una commessa. Leggere e andare a vedere erano due gesti scollegati —
   si leggeva qui e si ricominciava a cercare lo stesso nome dall'altra parte —
   e bastava che la cosa scritta fosse anche il comando.

   Niente aspetto da bottone: sono testo dentro a una riga di tabella, e
   incorniciarli li farebbe pesare piu' della riga che li contiene. */
/* Guscio senza forma per i comandi che su un telefono non ci sono (vedi la
   sezione 26): sul largo e' trasparente al flex che lo contiene, cosi' i tasti
   che avvolge stanno nella riga come se il guscio non ci fosse. */
.dt-solo-largo { display: contents; }

.dt-premibile,
.dt-legame {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
  /* Un tasto centra il proprio testo, e questi tasti sono nomi dentro a una
     cella: finche' stanno su una riga sola non si vede, ma appena il nome va a
     capo — e su un telefono va a capo — la seconda riga finisce centrata sotto
     la prima, in una colonna dove tutto il resto attacca a sinistra. */
  text-align: left;
}
/* Il puntinato dice "qui si va da un'altra parte" senza gridarlo come farebbe
   un link pieno: la tabella si legge per colonne, e una colonna sottolineata da
   cima a fondo diventa rumore. */
.dt-legame {
  text-decoration: underline dotted;
  text-underline-offset: 3px;
}
.dt-legame:hover { text-decoration: underline solid; }

/* Le tabelle orarie dentro alla scheda di una commessa: per ogni persona i
   totali che finiranno nel foglio di fine mese, e sotto i blocchi da cui
   vengono.

   Una griglia sola per tutte le persone, non una per ciascuna: le quattro
   colonne di un blocco — giorno, cosa, orario, quanto — devono incolonnarsi
   *fra* le persone, se no due tabelle una sotto l'altra si leggono come due
   tabelle diverse e le ore non si confrontano piu' a occhio. Le teste stanno
   nella stessa griglia e si prendono tutta la riga.
   `auto` alle colonne di cifre e `1fr` a quella del testo: sono le cifre che
   vanno tenute in colonna, e il nome dell'attivita' e' l'unico che puo' andare
   a capo senza far danni. */
.dt-oraria {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  gap: var(--dt-sp-1) var(--dt-sp-4);
  align-items: baseline;
}
.dt-oraria__testa {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--dt-sp-1) var(--dt-sp-3);
  margin-top: var(--dt-sp-3);
  padding-bottom: var(--dt-sp-2);
  border-bottom: 1px solid var(--dt-border-soft);
}
/* Il nome tiene la riga da solo quando lo spazio finisce: i numeri vanno a
   capo tutti insieme invece di spezzarsi uno per riga. */
.dt-oraria__testa > b:first-child { flex: 0 1 auto; }
.dt-oraria__testa:first-child { margin-top: 0; }
/* Il totale di tutti chiude la fila: sta sopra un filo pieno invece che sotto
   uno tenue, perche' non e' un'altra persona — e' la somma delle persone, ed e'
   il numero che deve tornare con la manodopera scritta qui sotto. */
.dt-oraria__testa--totale {
  margin-top: var(--dt-sp-4);
  padding: var(--dt-sp-3) 0 0;
  border-bottom: 0;
  border-top: 1px solid var(--dt-border);
}
/* Il giorno rientra: e' quello che stacca i blocchi di una persona dalla riga
   che li riassume, senza bisogno di un secondo riquadro. */
.dt-oraria__giorno { padding-left: var(--dt-sp-4); }

/* Una riga d'ordine: cosa montare, quanti, e il cestino in fondo. In flex
   ognuna si spezzava dove le capitava — la riga col tendaggio dal nome lungo
   mandava la quantita' a capo e le altre no — e un ordine si legge in
   verticale: quante tende di ogni tipo. Le colonne le decide la griglia, e le
   quantita' restano incolonnate.
   Misurata e' la quantita', che sono cifre e non testo: quattro cifre non
   hanno bisogno di un quinto della riga, e lasciarle crescere toglierebbe
   spazio proprio al nome del tendaggio. */
.dt-riga-ordine {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(112px, 21%, 132px) auto;
  gap: var(--dt-sp-3);
  align-items: center;
}
/* Senza, il campo dentro lo stepper pretende le sue venti battute e sfonda la
   colonna che gli si e' data. */
.dt-riga-ordine > * { min-width: 0; }
/* Stretti, il tendaggio si prende la riga sua e sotto resta la coppia
   quantita' col cestino: il nome di una tenda a questa larghezza non sta in
   mezza riga. */
@media (max-width: 640px) {
  .dt-riga-ordine { grid-template-columns: minmax(0, 1fr) auto; }
  .dt-riga-ordine > :first-child { grid-column: 1 / -1; }
  /* Due campi in fila per riga d'ordine: senza un filo in mezzo, i campi di
     due tendaggi diversi sembrano una lista sola e non si vede piu' dove
     finisce una tenda e comincia l'altra. Largo non serve: li' ogni riga sta
     su una riga. */
  .dt-riga-ordine + .dt-riga-ordine {
    padding-top: var(--dt-sp-4);
    border-top: 1px solid var(--dt-border-soft);
  }
}

/* Una riga della fila dei numeri: il numero, chi risponde, e il cestino in
   fondo. Stessa griglia della riga d'ordine e per lo stesso motivo — in flex il
   numero lungo manderebbe la nota a capo solo su quella riga — con le due
   colonne invertite: qui a misura sta il primo campo, perche' un numero e'
   quindici caratteri sempre, e a crescere e' la nota, che va da «Mario» a
   «amministratore del condominio». */
.dt-riga-telefono {
  display: grid;
  grid-template-columns: clamp(130px, 34%, 190px) minmax(0, 1fr) auto;
  gap: var(--dt-sp-3);
  align-items: center;
}
.dt-riga-telefono > * { min-width: 0; }
/* Stretti, il numero si prende la riga sua e sotto restano la nota e il
   cestino: a questa larghezza due campi affiancati sono due campi in cui non ci
   sta niente. Il filo separa un numero dall'altro, se no quattro caselle in
   colonna sembrano una lista sola. */
@media (max-width: 640px) {
  .dt-riga-telefono { grid-template-columns: minmax(0, 1fr) auto; }
  .dt-riga-telefono > :first-child { grid-column: 1 / -1; }
  .dt-riga-telefono + .dt-riga-telefono {
    padding-top: var(--dt-sp-4);
    border-top: 1px solid var(--dt-border-soft);
  }
}

/* La testatina della bolla: una riga sola, bianca, sotto alla testata.

   **Era una fascia.** Novanta pixel di campitura piena in cima a un foglio da
   compilare, e su un blocco appena disegnato quella campitura non c'era: il
   negozio non e' ancora stato scelto, quindi la fascia usciva grigia. Il primo
   terzo della finestra era una macchia di grigio che non voleva dire niente —
   e su un foglio bianco il grigio si legge come una cosa spenta, non come una
   cosa vuota.

   Adesso e' **una riga**, e su fondo bianco: cosa si sta segnando, per conto di
   chi, da che ora a che ora, e a che punto e'. Le stesse quattro cose di prima,
   sulla riga di un elenco invece che dentro a un riquadro. Nessun fondo, nessun
   raggio, nessun bordo tutt'intorno: un filo sotto, e finisce li'. Lo spazio
   che si e' liberato e' spazio in cui si vede la prima domanda senza scorrere,
   che su un tablet appoggiato al cruscotto e' la sola cosa che conti.

   `flex: none` perche' nel modale il corpo e' l'unico che deve allungarsi. */
.dt-testatina {
  position: relative;
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--dt-sp-1) var(--dt-sp-4);
  padding: var(--dt-sp-3) var(--dt-sp-6);
  border-bottom: 1px solid var(--dt-border);
  background: var(--dt-surface);
  color: var(--dt-text);
}

/* **La cimosa**: il colore del negozio, ridotto al bordo del foglio.

   E' l'orlo tessuto che corre lungo il lato della pezza, quello che porta il
   marchio di chi l'ha fatta — e qui fa lo stesso mestiere: dice per conto di
   chi si sta scrivendo, con un colore e senza una parola. Tre pixel bastano
   perche' e' l'unica cosa colorata della bolla: in mezzo al bianco non ha
   niente con cui competere, mentre dentro a una fascia dello stesso colore
   spariva.

   Al livello del tratto e non del pastello: tre pixel di pastello su una
   pagina quasi bianca sono un colore che si indovina.

   Senza negozio non c'e', e non diventa grigia. Un blocco che non sa ancora
   per chi e' non ha un colore — e il modo di dirlo e' non metterne nessuno,
   non metterne uno che non vuol dire niente. */
.dt-testatina__cimosa {
  position: absolute;
  left: 0;
  top: 0;
  bottom: -1px;
  width: 3px;
  background: oklch(
    calc(var(--dt-tinta-l-tratto) + var(--dt-blocco-luce, 0%))
    calc(var(--dt-blocco-c, var(--dt-tinta-c)) * var(--dt-tinta-c-tratto))
    var(--dt-blocco-tinta)
  );
}

/* Cosa si sta segnando: il segno e il nome, attaccati, e non si separano
   andando a capo. E' la coppia che l'elenco delle attivita' ha appena
   consegnato — stesso segno, stesso nome — cosi' la scelta si vede arrivare
   quassu' nell'istante in cui la si fa. */
.dt-testatina__cosa {
  display: inline-flex;
  align-items: center;
  gap: var(--dt-sp-3);
  min-width: 0;
}
.dt-testatina__cosa > svg {
  flex: none;
  align-self: center;
}
.dt-testatina__nome {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--dt-fs-lg);
  font-weight: var(--dt-fw-semibold);
  line-height: var(--dt-lh-tight);
  letter-spacing: -0.01em;
}
/* La matitina accanto al nome dell'attivita': riapre la copertina, cioe' si
   cambia «che lavoro e'» dal punto in cui c'e' scritto che lavoro e'. Solo
   sulla bolla in scrittura — sulla scheda che si legge non c'e'. */
.dt-testatina__matita {
  flex: none;
  align-self: center;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: none;
  border-radius: var(--dt-r-sm);
  background: none;
  color: var(--dt-text-3);
  cursor: pointer;
  transition: color var(--dt-t-fast), background var(--dt-t-fast);
}
.dt-testatina__matita:hover {
  background: var(--dt-surface-inset);
  color: var(--dt-text);
}
.dt-testatina__matita:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--dt-accent);
}
/* Per conto di chi si va, di seguito e piu' smorto: conferma, non si legge
   ogni volta. Si stringe prima di tutto il resto — un riferimento tagliato a
   meta' si riconosce lo stesso, un orario tagliato a meta' e' un altro
   orario. */
.dt-testatina__dove {
  /* Base vera e non zero: con `flex-basis: 0` questo pezzo si stringe fino a
     sparire e la riga non va **mai** a capo — le ore restavano attaccate al
     nome e uscivano dal bordo destro su una finestra stretta. Con una base
     misurata la riga si spezza dove non ci sta piu', e si spezza scorrendo:
     nessuna soglia, nessuno scatto. */
  flex: 1 1 12ch;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--dt-text-2);
  font-size: var(--dt-fs-sm);
}
/* Le ore chiudono la riga a destra, dove su un blocco in colonna stanno: stesso
   posto, stessa cosa da cercare. Si leggono e basta — a batterle e' la porta,
   in cima al resoconto. */
.dt-testatina__quando {
  flex: none;
  margin-left: auto;
  display: inline-flex;
  align-items: baseline;
  gap: var(--dt-sp-2);
  color: var(--dt-text-2);
  font-size: var(--dt-fs-md);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.dt-testatina__a { color: var(--dt-text-3); }
.dt-testatina__durata {
  color: var(--dt-text);
  font-weight: var(--dt-fw-semibold);
}
.dt-testatina .dt-stato { flex: none; align-self: center; }

/* La riga ferma della copertina: l'ora che il gesto ha gia' detto.

   Sta dove starebbe la testatina — stesso posto, stesso filo sotto — ma non
   e' una testatina: il blocco non ha ancora un'identita', e non se ne inventa
   una. Niente segno, niente fetta di stato, niente «Fatto» su una cosa appena
   nata: solo le ore, smorte, e la riga che dice da dove vengono. */
.dt-copertina__quando {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--dt-sp-1) var(--dt-sp-4);
  padding: var(--dt-sp-3) var(--dt-sp-6);
  border-bottom: 1px solid var(--dt-border);
  background: var(--dt-surface);
}
.dt-copertina__ore {
  display: inline-flex;
  align-items: baseline;
  gap: var(--dt-sp-2);
  color: var(--dt-text-2);
  font-size: var(--dt-fs-md);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.dt-copertina__a { color: var(--dt-text-3); }
.dt-copertina__durata {
  color: var(--dt-text);
  font-weight: var(--dt-fw-semibold);
}
.dt-copertina__nota {
  color: var(--dt-text-3);
  font-size: var(--dt-fs-xs);
  font-style: italic;
}
/* Il cartellino, in testa alla **scheda che si legge**: il blocco ingrandito.
   E' il cartellino spillato addosso a una tenda: cosa e', per conto di chi, per
   quando. Porta la campitura del blocco — quella del negozio, la stessa che ha
   in colonna — perche' quello che si e' toccato in giornata e quello che si sta
   guardando devono essere riconoscibilmente la stessa cosa.
   La bolla che si **compila** non ce l'ha: li' la testa e' una riga sola e
   bianca (`.dt-testatina`), perche' sopra a un foglio da riempire una fascia
   di colore alta novanta pixel e' la cosa piu' grossa della finestra e non e'
   quella che si deve guardare.
   Sta fuori dal corpo che scorre e sotto alla testata, quindi niente raggi ne'
   bordo tutt'intorno: e' una fascia saldata alla finestra, non una scatola
   dentro un'altra. `flex: none` perche' nel modale il corpo e' l'unico che
   deve allungarsi.
   Fondo e inchiostro sono quelli dei blocchi: la campitura resta chiara su
   tutti e due i temi e la scritta sopra e' nera in tutti e due, percio' quello
   che ci sta dentro non ha bisogno di sapere che tema sia. */
.dt-cartellino {
  --dt-blocco-c: calc(var(--dt-blocco-croma, var(--dt-tinta-c)) * var(--dt-tinta-c-scala));
  flex: none;
  display: flex;
  flex-direction: column;
  gap: var(--dt-sp-3);
  padding: var(--dt-sp-4) var(--dt-sp-6);
  background: oklch(
    calc(var(--dt-tinta-l) + var(--dt-blocco-luce, 0%))
    var(--dt-blocco-c)
    var(--dt-blocco-tinta)
  );
  border-bottom: 1px solid oklch(
    calc(var(--dt-tinta-l-bordo) + var(--dt-blocco-luce, 0%))
    var(--dt-blocco-c)
    var(--dt-blocco-tinta)
  );
  color: oklch(var(--dt-tinta-l-testo) var(--dt-tinta-c-testo) var(--dt-blocco-tinta));
  color-scheme: light;
  transition: background var(--dt-t-med), border-color var(--dt-t-med);
}
/* La stessa regola del blocco da cui si e' arrivati: senza colore da dire la
   striscia e' bianca, non grigia (vedi `.dt-blocco--bianca`). Il filo sotto
   resta, se no la fascia si salderebbe al foglio della scheda — che e' bianco
   anche lui — e la testata smetterebbe di essere una cosa a se'. */
.dt-cartellino--bianco {
  background: #fff;
  border-bottom-color: oklch(88% 0 0);
}
/* Due righe fisse e non una che va a capo dove capita: sopra cosa si sta
   segnando, sotto quando. Andando a capo per conto loro, su una finestra
   stretta il bollino finiva sotto agli orari e sopra restava una riga mezza
   vuota. Dentro alla riga si va a capo, che e' un'altra cosa: li' i pezzi sono
   pari fra loro. */
.dt-cartellino__riga {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--dt-sp-2) var(--dt-sp-4);
  min-height: var(--dt-h-lg);
}
/* Il nome dell'attivita' e' la cosa piu' grande della fascia: e' cosa e' quel
   blocco, ed e' la prima cosa che si legge aprendolo. */
.dt-cartellino__nome {
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--dt-fs-xl);
  font-weight: var(--dt-fw-semibold);
  line-height: var(--dt-lh-tight);
  letter-spacing: -0.01em;
}
.dt-cartellino__riga svg { flex: none; }
/* La fetta di stato chiude la prima riga a destra, dove su un blocco in
   colonna sta l'orario: stesso posto, stessa cosa da cercare. */
.dt-cartellino__riga .dt-stato { margin-left: auto; }

/* Per conto di chi si va: la faccia del negozio col suo nome, sulla riga di
   mezzo del cartellino. E' il negozio a dare la campitura a tutta la fascia,
   e questa riga gli mette il nome accanto al colore — e' qui che i due si
   imparano uno per l'altro. Senza commessa la riga non c'e': il grigio non ha
   bisogno di una didascalia. */
.dt-cartellino__negozio {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-3);
  min-width: 0;
  font-size: var(--dt-fs-md);
  font-weight: var(--dt-fw-medium);
}
.dt-cartellino__negozio > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Il contorno della commessa — riferimento, citta' — di fianco al negozio,
   un gradino piu' smorto: serve a confermare, non a essere letto ogni volta. */
.dt-cartellino__posto {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--dt-fs-sm);
  font-weight: var(--dt-fw-regular);
  opacity: 0.72;
}

/* Il cartellino a righe: la testata di un blocco che deve ancora succedere.
   Le stesse strisce del blocco in colonna — si tocca un blocco rigato e si
   apre una scheda con la testa rigata, cioe' quel blocco ingrandito. Solo
   sulla scheda che si guarda (`--fermo`): sulla bolla che si compila la
   testata sta ferma, e lo stato lo dice la fetta. */
.dt-cartellino--righe {
  background: repeating-linear-gradient(
    -45deg,
    oklch(
      calc(var(--dt-riga-l-a) + var(--dt-blocco-luce, 0%))
      calc(var(--dt-blocco-c) * var(--dt-acquerello-c-scala))
      var(--dt-blocco-tinta)
    ) 0 6px,
    oklch(
      calc(var(--dt-riga-l-b) + var(--dt-blocco-luce, 0%))
      calc(var(--dt-blocco-c) * var(--dt-velo-c-scala))
      var(--dt-blocco-tinta)
    ) 6px 12px
  );
  border-bottom-color: oklch(
    var(--dt-acquerello-l-bordo) var(--dt-blocco-c) var(--dt-blocco-tinta)
  );
  color: var(--dt-text);
  color-scheme: normal;
}

/* Le ore e i chilometri: campi veri, ma senza etichetta e appoggiati alla
   campitura invece che alla pagina. Il fondo e' un velo di bianco e non la
   superficie del tema: sul tema scuro una casella quasi nera dentro a una
   campitura chiara sarebbe un buco. */
.dt-cartellino__ora,
.dt-cartellino__km {
  height: var(--dt-h-lg);
  padding: 0 var(--dt-sp-3);
  border: 1px solid rgba(0, 0, 0, 0.16);
  border-radius: var(--dt-r-sm);
  background: rgba(255, 255, 255, 0.55);
  color: inherit;
  font: inherit;
  font-size: var(--dt-fs-md);
  font-variant-numeric: tabular-nums;
}
.dt-cartellino__ora:focus-visible,
.dt-cartellino__km:focus-within {
  outline: 2px solid oklch(var(--dt-tinta-l-testo) var(--dt-tinta-c-testo) var(--dt-blocco-tinta));
  outline-offset: 1px;
}
/* Il campo dentro all'etichetta dei chilometri non ha vestito suo: il riquadro
   ce l'ha gia' l'etichetta, che tiene insieme il numero e la sua unita'. */
.dt-cartellino__cifra {
  width: 3.5em;
  border: 0;
  padding: 0;
  background: none;
  color: inherit;
  font: inherit;
  font-variant-numeric: tabular-nums;
  text-align: right;
  outline: none;
}
/* Le frecce del campo numerico rubano meta' della casella per due mezzi tasti
   che nessuno prende col pollice. */
.dt-cartellino__cifra::-webkit-outer-spin-button,
.dt-cartellino__cifra::-webkit-inner-spin-button { appearance: none; margin: 0; }
.dt-cartellino__cifra { appearance: textfield; -moz-appearance: textfield; }
.dt-cartellino__a {
  opacity: 0.5;
  user-select: none;
}
/* La durata sta dalla parte del risultato: non si batte, si legge. */
.dt-cartellino__durata {
  font-variant-numeric: tabular-nums;
  opacity: 0.72;
}
.dt-cartellino__km {
  display: inline-flex;
  align-items: center;
  gap: var(--dt-sp-2);
}
.dt-cartellino__km > span { opacity: 0.6; font-size: var(--dt-fs-sm); }

/* Il bollino: il lavoro non e' finito.
   Ha preso il posto della scelta fra tre parole — "Da fare", "Da finire",
   "Fatto" — che erano tre etichette da rileggere ogni volta per dire quasi
   sempre la stessa cosa. Qui non c'e' niente da scegliere: o lo si mette o non
   c'e'.
   Messo, e' pieno d'inchiostro: sulla campitura chiara di qualunque delle
   dodici tinte e' il segno piu' forte della finestra, ed e' giusto che lo sia
   perche' e' l'unica cosa che chiede di tornare qui. */
.dt-cartellino__bollino {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: var(--dt-sp-3);
  height: var(--dt-h-lg);
  padding: 0 var(--dt-sp-5);
  border: 1px solid rgba(0, 0, 0, 0.16);
  border-radius: var(--dt-r-full);
  background: rgba(255, 255, 255, 0.55);
  color: inherit;
  font: inherit;
  font-size: var(--dt-fs-sm);
  font-weight: var(--dt-fw-medium);
  cursor: pointer;
  transition: background var(--dt-t-fast), border-color var(--dt-t-fast),
    color var(--dt-t-fast);
}
.dt-cartellino__bollino:hover { background: rgba(255, 255, 255, 0.85); }
.dt-cartellino__bollino:focus-visible {
  outline: 2px solid oklch(var(--dt-tinta-l-testo) var(--dt-tinta-c-testo) var(--dt-blocco-tinta));
  outline-offset: 2px;
}
.dt-cartellino__punto {
  width: 10px;
  height: 10px;
  border: 2px solid currentColor;
  border-radius: var(--dt-r-full);
  opacity: 0.55;
  transition: background var(--dt-t-fast), opacity var(--dt-t-fast);
}
.dt-cartellino__bollino--messo {
  background: oklch(var(--dt-tinta-l-testo) var(--dt-tinta-c-testo) var(--dt-blocco-tinta));
  border-color: transparent;
  /* Bianco fisso e non `--dt-text-inv`: la campitura sotto e' chiara su tutti e
     due i temi, quindi qui sopra il tema non c'entra niente. */
  color: #fff;
}
.dt-cartellino__bollino--messo:hover { background: rgba(0, 0, 0, 0.78); }
.dt-cartellino__bollino--messo .dt-cartellino__punto {
  background: currentColor;
  opacity: 1;
}

/* Lo stesso cartellino su una scheda che si guarda e basta: gli orari e il
   bollino tengono la loro forma — e' quello che lega la maschera al blocco che
   si e' appena toccato — ma non si accendono sotto al dito, perche' non c'e'
   niente da premere. Le caselle diventano etichette: stessa scatola, senza il
   cursore che invita a scriverci dentro. */
.dt-cartellino--fermo .dt-cartellino__ora,
.dt-cartellino--fermo .dt-cartellino__km {
  display: inline-flex;
  align-items: center;
  cursor: default;
}
.dt-cartellino--fermo .dt-cartellino__bollino { cursor: default; }

/* Le ore che non sono di questa cosa: gliele danno i vicini.

   E' il caso del viaggio, che ha quelle del buco fra i due lavori che lo
   chiudono. Restano scritte — servono a sapere di quale pezzo di giornata si
   sta parlando — ma perdono la scatola: una casella dice «puoi cambiarmi», e
   qui non si puo', perche' non c'e' niente da cambiare. Il carattere resta lo
   stesso, cosi' la riga si legge come su ogni altro cartellino. */
.dt-cartellino__ora--ferma {
  display: inline-flex;
  align-items: center;
  border-color: transparent;
  background: none;
  cursor: default;
}
.dt-cartellino--fermo .dt-cartellino__bollino--messo:hover {
  background: oklch(var(--dt-tinta-l-testo) var(--dt-tinta-c-testo) var(--dt-blocco-tinta));
}

/* ===========================================================================
   La bolla: un foglio con due facce

   La scheda di un blocco era una colonna che scorreva e chiedeva tutto insieme;
   poi e' stata una fila di schermate con una fettuccia in cima. Nessuna delle
   due diceva la cosa vera: che le meta' sono **due**, e hanno mestieri diversi.
   L'appuntamento si consegna — lo scrive chi manda, lo legge chi va — il
   resoconto torna indietro, e lo scrive chi c'e' stato.

   Da qui scendono le forme di questo pezzo di foglio:

   * tutte e due le facce sono **scritte**, righe e non campi
     (`.dt-consegna`), e ogni riga porta la sua matita
     (`.dt-consegna__matita`): si corregge un campo alla volta, in una
     finestra sua;
   * fra le due c'e' una porta sola, ed e' l'ora (`.dt-porta`) — passata, e'
     una riga come le altre;
   * le due facce e la porta si vedono sempre: e' la piega (`.dt-piega`),
     ferma sotto la testatina, e la faccia si gira da li' o dal tasto in
     fondo.

   Quali sezioni ci siano, su quale faccia e in che ordine non sta scritto qui:
   sta nel catalogo, riga per riga.
   =========================================================================== */

/* Una sezione di una faccia: un riquadro grosso, da premere col guanto.

   Il filo che le divide e non una cornice per ognuna: sono pezzi dello stesso
   foglio, e incorniciarli uno per uno farebbe una fila di schede dentro a una
   scheda. L'ultima non ha filo, perche' sotto non c'e' niente da dividere. */
.dt-sezione {
  display: flex;
  flex-direction: column;
  gap: var(--dt-sp-4);
  padding-bottom: var(--dt-sp-7);
  border-bottom: 1px solid var(--dt-border-soft);
}
.dt-sezione:last-child {
  padding-bottom: 0;
  border-bottom: none;
}

/* Piu' sezioni in fila dentro alla stessa finestra.

   Nella bolla la sezione e' una per volta: la copertina, o la finestra di un
   campo solo. Dove invece le domande si fanno tutte insieme — la consegna
   dell'ufficio, che compone un appuntamento in un colpo — ne servono quattro
   in colonna, e allora conta l'aria: **dentro** a una sezione otto pixel fra
   la domanda e la sua risposta, **fra** una sezione e l'altra venti piu' il
   filo. Il gruppo lo fa la distanza, non una cornice, ed e' quella differenza
   a dire quale risposta appartiene a quale domanda.

   Simmetrica sul filo — venti sopra e venti sotto — perche' un filo appoggiato
   alla domanda che viene dopo si legge come la sua sottolineatura invece che
   come la fine di quella prima. */
.dt-sezioni {
  display: flex;
  flex-direction: column;
}
.dt-sezioni > .dt-sezione + .dt-sezione { padding-top: var(--dt-sp-7); }

/* I comandi che riguardano il blocco intero e non la sezione: buttarlo, o
   uscirne lasciandolo ai colleghi. Stanno in coda a «cosa hai fatto» perche' e'
   li' che si scopre che quel blocco non doveva esserci, e non in fondo alla
   bolla, dove una mano che corre finirebbe per premerli. */
.dt-sezione__coda {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--dt-sp-3);
  padding-top: var(--dt-sp-5);
  border-top: 1px solid var(--dt-border-soft);
}

/* La riga smorta in testa a una faccia, col suo unico comando.

   Il nome grosso non c'e' piu': «Appuntamento» lo dice gia' la piega, qui
   sopra, e ripeterlo sarebbe la stessa parola due volte a quaranta pixel di
   distanza. Resta il sottotitolo — cosa sia questo foglio — e il comando:
   cambia il segno e cambia la parola (la matita apre, la spunta chiude), e
   non cambia niente altro, cosi' passare da una all'altra non sposta niente
   sotto agli occhi. */
.dt-faccia-testa {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--dt-sp-4);
  padding-bottom: var(--dt-sp-4);
  border-bottom: 1px solid var(--dt-border-soft);
  /* L'aria fra il filo e la prima riga del foglio: la stessa che le righe
     tengono fra loro, cosi' la testa non sembra attaccata alla prima. */
  margin-bottom: var(--dt-sp-3);
}
.dt-faccia-testa__sotto {
  min-width: 0;
  color: var(--dt-text-3);
  font-size: var(--dt-fs-xs);
  line-height: var(--dt-lh-normal);
}

/* La piega: la riga in cui il foglio si gira.

   Fissa sotto la testatina, fuori dal corpo che scorre: arrivati alle foto si
   vede ancora dove si e', e la strada per l'altra faccia e' sempre a un
   tocco. Ha preso il posto del tastino `dt-gira`, che era gia' un comando di
   navigazione — solo troppo piccolo, senza il nome della faccia corrente e
   presente su una faccia sola.

   Due meta' dentro un contenitore unico col filo divisorio, come da regola
   delle barre di comandi. La meta' attiva porta l'inchiostro e il filo
   d'accento sotto; l'altra e' grigia, e premerla gira il foglio. Le
   transizioni stanno sugli stessi nodi: niente scatti. */
.dt-piega {
  position: relative;
  flex: none;
  display: flex;
  align-items: stretch;
  border-bottom: 1px solid var(--dt-border);
  background: var(--dt-surface);
}
.dt-piega__faccia {
  flex: 1 1 0;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--dt-sp-2);
  padding: var(--dt-sp-3) var(--dt-sp-4);
  border: none;
  background: none;
  color: var(--dt-text-3);
  cursor: pointer;
  font: inherit;
  font-size: var(--dt-fs-sm);
  line-height: var(--dt-lh-tight);
  white-space: nowrap;
  transition: color var(--dt-t-fast), background var(--dt-t-fast),
    box-shadow var(--dt-t-fast);
}
/* Il filo divisorio sta sulla seconda meta' e non fra i fratelli adiacenti:
   in mezzo ai due tasti c'e' il tondino, e un selettore col `+` non
   scatterebbe mai. */
.dt-piega__faccia:last-of-type { border-left: 1px solid var(--dt-border-soft); }
.dt-piega__faccia:hover {
  background: var(--dt-surface-inset);
  color: var(--dt-text);
}
.dt-piega__faccia:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--dt-accent);
}
.dt-piega__faccia--attiva {
  color: var(--dt-text);
  font-weight: var(--dt-fw-semibold);
  box-shadow: inset 0 -2px 0 var(--dt-accent);
}
.dt-piega__faccia--attiva:focus-visible { box-shadow: inset 0 0 0 2px var(--dt-accent); }
/* Il campione: la lingua delle campiture della colonna, ridotta a un
   quadretto. Rigato = deve ancora succedere, pieno = successo — imparata la',
   riusata qui, gratis. I passi del rigato sono gli stessi della campitura a
   righe dei blocchi (-45 gradi, due bande), scalati alla misura del
   quadretto. */
.dt-piega__campione {
  flex: none;
  width: 11px;
  height: 11px;
  border: 1px solid var(--dt-border-strong);
  border-radius: var(--dt-r-xs);
}
.dt-piega__campione--rigato {
  background: repeating-linear-gradient(
    -45deg,
    var(--dt-text-3) 0 1.5px,
    transparent 1.5px 4px
  );
}
.dt-piega__campione--pieno {
  border-color: var(--dt-text-2);
  background: var(--dt-text-2);
}
.dt-piega__faccia--attiva .dt-piega__campione { border-color: var(--dt-text-2); }
.dt-piega__faccia--attiva .dt-piega__campione--pieno {
  border-color: var(--dt-text);
  background: var(--dt-text);
}
/* Il tondino: la porta, vista come cio' che sta fra le due facce. A cavallo
   del filo, col fondo pieno che lo copre nel punto in cui lo attraversa. Non
   e' un tasto — e' un segno: aperto con l'orologio finche' l'ora e' da
   confermare, pieno d'inchiostro con la spunta quando e' passata. */
.dt-piega__porta {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border: 1px solid var(--dt-border-strong);
  border-radius: var(--dt-r-full);
  background: var(--dt-surface);
  color: var(--dt-text-2);
  transition: background var(--dt-t-fast), border-color var(--dt-t-fast),
    color var(--dt-t-fast);
}
.dt-piega__porta--passata {
  border-color: var(--dt-accent);
  background: var(--dt-accent);
  color: var(--dt-text-inv);
}

/* ---------------------------------------------------------------------------
   L'appuntamento, scritto
   --------------------------------------------------------------------------- */

/* Il foglio delle consegne. Righe e non campi: chi lo apre sta per andarci, non
   sta per correggerlo, e su un tablet appoggiato al cruscotto una colonna di
   caselle e' anche il modo piu' facile di cambiare per sbaglio un'ora giusta. */
.dt-consegne {
  display: flex;
  flex-direction: column;
  gap: var(--dt-sp-5);
}
/* Una riga: il segno a sinistra, e a destra la parola sopra e la consegna
   sotto. Il segno in colonna sua e allineato al testo e non centrato: le
   consegne lunghe — un indirizzo su due righe — scendono, e un segno che
   scivolasse a meta' non punterebbe piu' a niente. */
.dt-consegna {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: var(--dt-sp-4);
}
.dt-consegna__segno {
  display: inline-flex;
  padding-top: 1px;
  color: var(--dt-text-3);
}
/* Il segno di una riga a meta' torna nell'inchiostro pieno: non un colore
   d'allarme — non e' un errore, e' un debito — ma il peso che serve perche' fra
   sei righe grigie quella si veda. */
.dt-consegna--manca .dt-consegna__segno { color: var(--dt-text); }
.dt-consegna__parole {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: var(--dt-sp-1);
}
.dt-consegna__parola {
  display: inline-flex;
  align-items: center;
  gap: var(--dt-sp-2);
  color: var(--dt-text-3);
  font-size: var(--dt-fs-xs);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
/* Lo stesso punto della sezione da riempire e del blocco in colonna: non e' un
   asterisco e non e' la parola "obbligatoria" — nessuno sta esigendo niente —
   e' che quel pezzo tornera' indietro. */
.dt-consegna__punto {
  width: 6px;
  height: 6px;
  border-radius: var(--dt-r-full);
  /* Lo stesso inchiostro del punto sulla sezione e sul blocco in colonna: un
     segno solo, tre posti, niente da imparare due volte. */
  background: var(--dt-accent);
}
/* La consegna com'e' scritta. `pre-line` perche' un indirizzo va a capo dopo il
   nome: e' una riga sola di informazione, letta su due righe come sulla busta. */
.dt-consegna__testo {
  font-size: var(--dt-fs-md);
  line-height: var(--dt-lh-normal);
  white-space: pre-line;
}
/* Il buco, detto. Non si nasconde la riga: un buco nella consegna e'
   esattamente la cosa che chi legge deve vedere, ed e' il motivo per cui quel
   blocco porta il triangolo in colonna. */
.dt-consegna__vuoto {
  color: var(--dt-text-3);
  font-size: var(--dt-fs-md);
  font-style: italic;
}

/* La riga che si corregge: tutta la riga e' il bersaglio, la matita e' il
   segno. Il rientro negativo tiene i testi nella colonna di tutti mentre il
   fondo del passaggio del mouse si allarga oltre, fino al bordo del foglio:
   e' lo stesso trucco delle voci d'elenco. */
.dt-consegna--tocca {
  grid-template-columns: auto 1fr auto;
  padding: var(--dt-sp-4);
  margin-inline: calc(-1 * var(--dt-sp-4));
  border-radius: var(--dt-r-md);
  cursor: pointer;
  transition: background var(--dt-t-fast);
}
.dt-consegna--tocca:hover { background: var(--dt-surface-inset); }
/* Nel foglio con le matite le righe si toccano: l'aria fra l'una e l'altra
   e' gia' nel loro imbottito, e sommarci il passo intero del foglio letto
   farebbe una scala coi gradini doppi. */
.dt-consegne--matite { gap: var(--dt-sp-3); }
/* La matita della riga: apre la finestra di quel campo solo. Gemella di
   quella in testatina, appena piu' larga perche' qui si preme col guanto. I
   margini negativi la tengono dentro all'altezza della prima riga di testo,
   cosi' una riga corta non si alza per farle posto. */
.dt-consegna__matita {
  align-self: start;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  margin: -5px 0;
  padding: 0;
  border: none;
  border-radius: var(--dt-r-sm);
  background: none;
  color: var(--dt-text-3);
  cursor: pointer;
  transition: color var(--dt-t-fast), background var(--dt-t-fast);
}
.dt-consegna--tocca:hover .dt-consegna__matita { color: var(--dt-text); }
.dt-consegna__matita:hover { background: var(--dt-border-soft); }
.dt-consegna__matita:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--dt-accent);
}

/* Le ore come riga del foglio: si leggono come si dicono, e la durata sta
   dalla parte del risultato. E' la riga in cui la porta si distende una
   volta passata. */
.dt-consegna__ore {
  display: inline-flex;
  align-items: baseline;
  gap: var(--dt-sp-2);
  font-variant-numeric: tabular-nums;
}
.dt-consegna__a { color: var(--dt-text-3); }
.dt-consegna__durata { font-weight: var(--dt-fw-semibold); }

/* I comandi che riguardano il blocco intero, in fondo al foglio: buttarlo, o
   uscirne lasciandolo ai colleghi. Staccati da un filo e da un salto d'aria,
   perche' la cosa piu' facile da premere quaggiu' deve restare il tasto nel
   piede, non il cestino. */
.dt-bolla__coda {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--dt-sp-3);
  margin-top: var(--dt-sp-8);
  padding-top: var(--dt-sp-5);
  border-top: 1px solid var(--dt-border-soft);
}

/* ---------------------------------------------------------------------------
   La porta: l'ora, e il comando che la conferma
   --------------------------------------------------------------------------- */

/* La sezione degli orari, e le sue due nature.

   Finche' la porta e' da passare e' **l'unico riquadro incassato del
   foglio**: bordo, raggio dai token, fondo incassato, subito sotto la piega —
   visivamente appesa al tondino che le sta sopra. Dentro ci stanno la
   domanda, le due caselle e la primaria che conferma. Confermata l'ora, il
   riquadro **si distende** nella sezione quieta: stessi nodi, transizione
   sulle dimensioni — niente keyframe che finti-traslano mentre il contenuto
   cambia. */
.dt-porta {
  display: flex;
  flex-direction: column;
  gap: var(--dt-sp-4);
  border: 1px solid transparent;
  border-radius: var(--dt-r-lg);
  transition: padding var(--dt-t-med), background var(--dt-t-med),
    border-color var(--dt-t-med);
}
.dt-porta--soglia {
  padding: var(--dt-sp-5);
  border-color: var(--dt-border);
  background: var(--dt-surface-inset);
}
/* Le due caselle e il comando, su una riga sola finche' ci stanno.

   Sotto ai 360 il comando va a capo e si posa sotto alle ore, allineato a
   sinistra con loro: e' il gesto piu' importante della bolla — quello che dice
   *ci sono stato* — e su uno schermo stretto sta meglio da solo su una riga sua
   che schiacciato di fianco a due caselle. A mandarcelo e' l'andare a capo del
   flex, non una soglia scritta: la riga si spezza dove non ci sta piu', e fra
   una larghezza e l'altra non c'e' nessuno scatto. */
.dt-porta__riga {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--dt-sp-4) var(--dt-sp-5);
}
.dt-porta__ore {
  display: inline-flex;
  flex: 1 1 auto;
  align-items: center;
  gap: var(--dt-sp-3);
}
.dt-porta__ora {
  padding: var(--dt-sp-3) var(--dt-sp-4);
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-md);
  background: var(--dt-surface);
  color: var(--dt-text);
  font: inherit;
  font-size: var(--dt-fs-lg);
  font-variant-numeric: tabular-nums;
  line-height: var(--dt-lh-tight);
}
.dt-porta__ora:focus-visible {
  border-color: var(--dt-accent);
  outline: none;
}
/* Un viaggio le ore non le ha sue: gliele danno i lavori che lo chiudono. Si
   leggono lo stesso — serve sapere di quale pezzo di giornata si parla — ma
   senza il contorno, che direbbe «puoi cambiarmi». */
.dt-porta__ora--ferma {
  border-color: transparent;
  background: none;
}
.dt-porta__a { color: var(--dt-text-3); }
/* La durata sta dalla parte del risultato e non si batte: e' la sottrazione di
   quello che si e' appena scritto a sinistra. */
.dt-porta__durata {
  color: var(--dt-text-2);
  font-size: var(--dt-fs-sm);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* La domanda in cima alla schermata.

   E' una domanda vera — "Dove hai lavorato?" — e non l'etichetta di un campo.
   Una schermata sola per volta se lo puo' permettere, e chiedere invece che
   intitolare e' la differenza che si sente stando in piedi: a un'etichetta si
   risponde solo se si e' gia' capito cosa si sta compilando. */
.dt-domanda {
  display: flex;
  flex-direction: column;
  gap: var(--dt-sp-2);
}
.dt-domanda__riga {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-4);
  color: var(--dt-text-3);
}
.dt-domanda__riga > svg { flex: none; }
.dt-domanda__testo {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  color: var(--dt-text);
  font-size: var(--dt-fs-xl);
  font-weight: var(--dt-fw-semibold);
  line-height: var(--dt-lh-tight);
  letter-spacing: -0.015em;
}
.dt-domanda__sotto {
  color: var(--dt-text-2);
  font-size: var(--dt-fs-sm);
  line-height: var(--dt-lh-normal);
}

/* Il punto: un debito, non un divieto.

   E' il segno che tiene insieme tre schermate che prima non si parlavano. In
   catalogo l'amministratore lo mette su una domanda per dire "questa la
   pretendo"; in giornata compare sulla fettuccia finche' quella domanda e'
   senza risposta; e se il blocco si salva lo stesso — che si puo', sempre — lo
   si ritrova identico sul blocco in colonna.

   **Il punto e' il debito: quando lo paghi, sparisce.** Non e' rosso e non e'
   un asterisco: tutti e due direbbero che qualcuno esige qualcosa, e qui invece
   non esige nessuno. E' inchiostro, come il resto della piattaforma, perche' la
   cosa che dice non e' un errore ma una nota — questo pezzo torna indietro.

   Fuori dal segno e non dentro: dentro coprirebbe l'icona, che e' quella che
   dice *quale* domanda. */
.dt-debito {
  position: absolute;
  top: -1px;
  right: -1px;
  width: 8px;
  height: 8px;
  border-radius: var(--dt-r-full);
  background: var(--dt-accent);
  /* L'anello del colore di sotto: su una campitura piena il punto d'inchiostro
     senza stacco si legge come un buco nell'icona. */
  box-shadow: 0 0 0 2px var(--dt-surface-2);
}
/* Sulla domanda in cima alla schermata sta in fila col titolo, non appeso a un
   angolo: li' non c'e' un segno da non coprire, c'e' una riga da leggere. */
.dt-debito--grande {
  position: static;
  flex: none;
  width: 10px;
  height: 10px;
  box-shadow: none;
}
/* Il tastino con cui l'amministratore mette il punto su una domanda.
   E' il punto stesso dentro a un bersaglio da pollice: quello che si preme e'
   quello che si vedra', e non c'e' una seconda forma da imparare fra chi scrive
   la regola e chi la subisce. Spento e' un contorno — la domanda c'e' ma non
   pretende niente — messo e' pieno d'inchiostro. */
.dt-pretendi {
  display: grid;
  place-items: center;
  width: var(--dt-h-md);
  height: var(--dt-h-md);
  padding: 0;
  border: 0;
  border-radius: var(--dt-r-sm);
  background: none;
  cursor: pointer;
  transition: background var(--dt-t-fast);
}
.dt-pretendi:hover { background: var(--dt-hover); }
.dt-pretendi:focus-visible { outline: 2px solid var(--dt-accent); outline-offset: -2px; }
/* Spento: contorno e basta. Il punto pieno lo prende quando lo si preme. */
.dt-pretendi .dt-debito {
  position: static;
  width: 11px;
  height: 11px;
  background: none;
  border: 2px solid var(--dt-border-strong);
  box-shadow: none;
}
.dt-pretendi--messo .dt-debito { background: var(--dt-accent); border-color: var(--dt-accent); }

/* I due secchi delle facce: cosa si consegna, cosa torna indietro.
   Affiancati e non uno sotto l'altro finche' c'e' spazio, perche' la domanda
   che si fa qui e' **di confronto** — questa domanda la chiedo prima o dopo? —
   e due elenchi incolonnati la fanno rispondere a memoria. Sotto la soglia si
   impilano: due colonne da centosessanta pixel non si leggono, e l'ordine
   verticale dice comunque la cosa giusta, cioe' che prima c'e' la consegna. */
.dt-facce-due {
  display: grid;
  gap: var(--dt-sp-6);
  grid-template-columns: 1fr;
}
@media (min-width: 860px) {
  .dt-facce-due { grid-template-columns: 1fr 1fr; align-items: start; }
}

.dt-fase {
  display: flex;
  flex-direction: column;
  gap: var(--dt-sp-3);
  min-width: 0;
}
.dt-fase__testa {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding-bottom: var(--dt-sp-2);
  border-bottom: 1px solid var(--dt-border);
}
.dt-fase__nome {
  font-size: var(--dt-fs-md);
  font-weight: var(--dt-fw-semibold);
  line-height: var(--dt-lh-tight);
}
.dt-fase__sotto {
  font-size: var(--dt-fs-xs);
  color: var(--dt-text-3);
  line-height: var(--dt-lh-normal);
}

/* Il secchio riceve anche da vuoto, quindi ha bisogno di un'altezza sua: senza,
   una faccia senza righe sarebbe un bersaglio alto zero pixel e l'unico modo di
   riempirla sarebbe premere una tessera. */
.dt-fase__fila {
  min-height: 64px;
  border-radius: var(--dt-r-md);
  transition: background var(--dt-t-fast), box-shadow var(--dt-t-fast);
}
/* La corsia accesa: qui dentro la sezione andrebbe a finire. E' lo stesso segno
   che una sezione di catalogo accende quando le si porta sopra un articolo. */
.dt-fase__fila.dt-cade--dentro {
  background: var(--dt-accent-soft);
  box-shadow: inset 0 0 0 1px var(--dt-accent-border);
}
/* Da vuoto lo stato vuoto occupa gia' il riquadro: gli si toglie l'aria che si
   prenderebbe in mezzo a una pagina, perche' qui e' una casella da riempire e
   non una schermata da leggere. */
.dt-fase__fila .dt-empty { padding: var(--dt-sp-5) var(--dt-sp-4); }

/* La coda: dove il lavoro c'era, ma questa persona no.

   Un blocco condiviso e' una riga sola, e fino a ieri voleva dire anche "tutti
   dalle stesse ore alle stesse ore". Adesso ognuno puo' avere la sua fetta, e
   nella sua giornata il blocco e' alto **quanto la sua fetta** — sono le sue
   ore, ed e' quello che il totale conta.

   Ma il lavoro e' andato avanti anche senza di lui, e farlo sparire sarebbe
   l'altra meta' della bugia. Da qui la coda: un filo tratteggiato della stessa
   tinta che sale o scende fino a dove il montaggio e' arrivato. Tratteggiata e
   non piena per lo stesso motivo per cui lo e' una pausa — c'e' qualcosa, ma
   non e' roba sua — e larga la meta' del blocco, appoggiata al bordo sinistro,
   cosi' non si confonde con un blocco vero e non copre quello accanto. */
.dt-blocco__coda {
  position: absolute;
  left: -1px;
  width: 34%;
  min-width: 10px;
  pointer-events: none;
  border-left: 2px dashed
    oklch(calc(var(--dt-tinta-l-tratto) + var(--dt-blocco-luce, 0%)) var(--dt-blocco-c, var(--dt-tinta-c)) var(--dt-blocco-tinta));
  opacity: 0.75;
}
.dt-blocco__coda--su {
  bottom: 100%;
  border-top: 2px dashed
    oklch(calc(var(--dt-tinta-l-tratto) + var(--dt-blocco-luce, 0%)) var(--dt-blocco-c, var(--dt-tinta-c)) var(--dt-blocco-tinta));
  border-top-left-radius: var(--dt-r-sm);
}
.dt-blocco__coda--giu {
  top: 100%;
  border-bottom: 2px dashed
    oklch(calc(var(--dt-tinta-l-tratto) + var(--dt-blocco-luce, 0%)) var(--dt-blocco-c, var(--dt-tinta-c)) var(--dt-blocco-tinta));
  border-bottom-left-radius: var(--dt-r-sm);
}
/* L'ora in punta alla coda: fin dove e' arrivato il lavoro senza di lui. E'
   quello che rende la coda un'informazione invece di una decorazione — un
   tratteggio senza numero dice "e' andato avanti" e non fino a quando. Smorta e
   piccola: e' un dato di contorno, e il blocco vero resta quello pieno. */
.dt-blocco__coda-ora {
  position: absolute;
  left: calc(100% + var(--dt-sp-2));
  font-size: var(--dt-fs-xs);
  font-variant-numeric: tabular-nums;
  color: var(--dt-text-3);
  white-space: nowrap;
}
.dt-blocco__coda--su .dt-blocco__coda-ora { top: -2px; }
.dt-blocco__coda--giu .dt-blocco__coda-ora { bottom: -2px; }

/* Il blocco taglia quello che gli esce fuori: la coda no. */
.dt-blocco { overflow: visible; }
.dt-blocco__testa { overflow: hidden; }

/* La fetta di un collega, aperta sotto alla sua riga.
   Due ore e una via di ritorno: "c'era per tutto" e' il caso normale, e ci si
   deve poter tornare senza indovinare quali ore rimettere. */
.dt-fetta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--dt-sp-3);
  padding: var(--dt-sp-4);
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-md);
  background: var(--dt-surface-2);
}
.dt-fetta__ora {
  flex: 1 1 96px;
  min-width: 0;
  height: var(--dt-h-tocco);
  padding: 0 var(--dt-sp-3);
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-sm);
  background: var(--dt-surface);
  color: var(--dt-text);
  font: inherit;
  font-size: var(--dt-fs-lg);
  font-variant-numeric: tabular-nums;
  text-align: center;
}
.dt-fetta__chi {
  flex: 1 1 100%;
  color: var(--dt-text-2);
  font-size: var(--dt-fs-sm);
}
.dt-fetta__chi b { color: var(--dt-text); }

/* Il riquadro da cui si sceglie: dentro alla scheda di un blocco, l'elenco
   che in ufficio riempie una scheda intera.

   **E' lo stesso elenco di la'**, e non gli somiglia: la barra della ricerca in
   cima, le sezioni che si aprono, e in fondo le righe col segno nella corsia e
   il nome di fianco. Vale per i Lavori — i posti si aprono, dentro ci sono le
   loro commesse — e vale per il catalogo dei tendaggi e per il listino, che
   qui erano diventati una griglia di caselle con le sezioni appiattite in
   un'intestazione sola. Chi impara a trovare un tassello alla scrivania sa gia'
   trovarlo su una scala.

   Il filo intorno fa quello che fa la `.dt-card` in ufficio: tiene insieme la
   barra e le righe, se no la barra galleggia sopra a un elenco che comincia dal
   niente. Non ha un tetto e non scorre per conto suo: le sezioni nascono
   chiuse, quindi l'elenco a riposo e' alto quanto i suoi reparti, e uno
   scorrimento dentro alla finestra che scorre gia' e' il muro dentro al muro. */
.dt-scelte {
  border: 1px solid var(--dt-border-soft);
  border-radius: var(--dt-r-md);
  background: var(--dt-surface);
  overflow: hidden;
}
/* La barra della ricerca, in cima al riquadro: il filo sotto ce l'ha gia', e
   qui dentro non c'e' la `.dt-card` che le da' il respiro dei lati. */
.dt-scelte > .dt-barra-elenco { padding: var(--dt-sp-3) var(--dt-sp-4); }
/* Il tetto ce l'ha il solo albero dei Lavori: li' le righe sono i posti in
   archivio, e non si chiudono da sole come le sezioni di un catalogo — con
   venti riferimenti aperti la fila dei tasti finiva fuori dallo schermo. */
.dt-scelte--tetto {
  max-height: clamp(180px, 38vh, 320px);
  overflow: auto;
}
/* Il −/+ su una riga gia' presa, dove il listino tiene il prezzo. Il campo di
   un `<input>` misura una ventina di caratteri se nessuno gli dice il
   contrario, e il − finirebbe a mezza riga di distanza dal +. Qui la quantita'
   e' al massimo quattro cifre: si tiene stretta, e i due tasti restano dove il
   pollice li ha trovati sulla riga di sopra. */
.dt-voce__qta {
  /* Misurata con `width` e non con la base del flex: dentro alla base una
     percentuale il motore la risolve quando gli pare, e il −/+ si prendeva
     la riga intera. */
  flex: 0 1 auto;
  width: clamp(132px, 34%, 160px);
  min-width: 0;
}
/* Le righe qui dentro sono le righe di sempre, col passo di sempre: vedi
   `--dt-riga-h`, che il pollice ce l'ha gia' dentro. Qui c'era una misura
   apposta, e diceva quaranta pixel dove l'ufficio ne diceva gia' quaranta —
   una riga in piu' da tenere allineata a mano con quella vera. */

/* La tavolozza: una fra poche scelte fisse, tutte in vista.

   Non e' il modo in cui si sceglie da un catalogo, e per un po' lo e' stato:
   articoli, tendaggi e colleghi si prendevano da qui. Un catalogo pero' ha
   sezioni, si cerca e cresce, e in ufficio sta in un albero di righe: due
   disegni per lo stesso elenco vogliono dire impararlo due volte. Qui resta
   quello per cui la griglia e' brava davvero — una dozzina di scelte che si
   vedono tutte insieme, ognuna col suo segno e una riga che la spiega.

   Le colonne le conta lo spazio che c'e', non una soglia della finestra: la
   griglia sta dentro a una maschera larga la sua, e legarla alla finestra
   vorrebbe dire tessere grandi il doppio quando la maschera e' stretta. */
.dt-tessere {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(clamp(104px, 26vw, 132px), 1fr));
  gap: var(--dt-sp-3);
}
.dt-tessera {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--dt-sp-2);
  min-height: 84px;
  padding: var(--dt-sp-4);
  border: 1px solid var(--dt-border-soft);
  border-radius: var(--dt-r-md);
  background: var(--dt-surface);
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background var(--dt-t-fast), border-color var(--dt-t-fast),
    box-shadow var(--dt-t-fast);
}
.dt-tessera:hover { background: var(--dt-surface-2); border-color: var(--dt-border); }
.dt-tessera:active { background: var(--dt-surface-3); }
.dt-tessera:focus-visible { outline: 2px solid var(--dt-accent); outline-offset: 2px; }

/* Il segno prima del nome: qui non si legge, si riconosce, ed e' lo stesso
   segno che quella cosa ha in ufficio. Quasi sempre e' nudo sul grigio della
   pagina — un listino di mille codici tinto tutto e' mille macchie — e la
   campitura ce l'hanno quei pochi che si cercano dieci volte al giorno. */
.dt-tessera__segno {
  --dt-blocco-c: calc(var(--dt-blocco-croma, var(--dt-tinta-c)) * var(--dt-tinta-c-scala));
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-sm);
  background: var(--dt-surface-2);
  color: var(--dt-text-2);
}
.dt-tessera--tinta .dt-tessera__segno {
  background: oklch(
    calc(var(--dt-tinta-l) + var(--dt-blocco-luce, 0%))
    var(--dt-blocco-c)
    var(--dt-blocco-tinta)
  );
  border-color: oklch(
    calc(var(--dt-tinta-l-bordo) + var(--dt-blocco-luce, 0%))
    var(--dt-blocco-c)
    var(--dt-blocco-tinta)
  );
  color: oklch(var(--dt-tinta-l-testo) var(--dt-tinta-c-testo) var(--dt-blocco-tinta));
}
/* Il nome va a capo dentro alla tessera, e se una parola non ci sta si spezza:
   in un listino vero ci sono "Guaina termorestringente" e "Controtelaio
   zanzariera", e su una colonna larga un pollice una parola sola e' piu' larga
   della tessera che la contiene. Senza questo usciva dal bordo e finiva sotto
   la tessera accanto. */
.dt-tessera__nome {
  max-width: 100%;
  font-size: var(--dt-fs-md);
  font-weight: var(--dt-fw-medium);
  line-height: var(--dt-lh-tight);
  overflow-wrap: anywhere;
}
/* Il modello, o il ramo di catalogo da cui viene: e' quello che distingue due
   cose che si chiamano uguale, ed e' proprio qui che serve. */
.dt-tessera__sotto {
  max-width: 100%;
  color: var(--dt-text-3);
  font-size: var(--dt-fs-xs);
  line-height: var(--dt-lh-normal);
  overflow-wrap: anywhere;
}
/* La via d'uscita in fondo a una griglia: quello che si cercava non c'e'.

   Sta sotto e non sopra, ed e' quello che si fa **dopo** aver guardato: in cima
   sarebbe una scorciatoia per riscrivere a mano roba che in catalogo c'e' gia'.
   Il contorno tratteggiato dice che quella riga il catalogo non ce l'ha ancora,
   ed e' lo stesso tratteggio con cui la giornata disegna le ore che non si
   pagano: qualcosa che c'e' ma non e' pieno. Due righe invece di una perche' la
   seconda dice cosa comporta — fra "lo apro in catalogo" e "lo segno solo per
   oggi" la differenza la deve capire chi e' su una scala. */
.dt-via-uscita {
  display: flex;
  align-items: flex-start;
  gap: var(--dt-sp-3);
  width: 100%;
  min-height: var(--dt-h-tocco);
  padding: var(--dt-sp-3) var(--dt-sp-4);
  border: 1px dashed var(--dt-border);
  border-radius: var(--dt-r-md);
  background: none;
  color: var(--dt-text-2);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: color var(--dt-t-fast), background var(--dt-t-fast),
    border-color var(--dt-t-fast);
}
.dt-via-uscita:hover:not(:disabled) {
  color: var(--dt-text);
  background: var(--dt-hover);
  border-color: var(--dt-border-strong);
}
.dt-via-uscita:disabled { opacity: 0.5; cursor: default; }
.dt-via-uscita > svg { flex: none; margin-top: 2px; }
.dt-via-uscita__testo { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.dt-via-uscita__nome { font-size: var(--dt-fs-sm); font-weight: var(--dt-fw-medium); }
.dt-via-uscita__sotto { color: var(--dt-text-3); font-size: var(--dt-fs-xs); }

/* Quello che si e' gia' preso, sopra all'elenco da cui lo si prende.

   E' lo stesso riquadro di `.dt-scelte` con le stesse righe dentro: quello che
   si e' preso e quello da cui lo si prende non sono due disegni diversi, e al
   posto del `+` c'e' il −/+. Erano riquadri sciolti uno per riga, e in colonna
   facevano una pila di scatole dove sotto c'era un elenco con un filo solo.
   Non cambia faccia fra una faccia e l'altra: sulla consegna dice cosa
   caricare, sul resoconto cosa si e' bruciato, ed e' la stessa riga guardata in
   due momenti. */
.dt-presi {
  border: 1px solid var(--dt-border-soft);
  border-radius: var(--dt-r-md);
  background: var(--dt-surface);
  overflow: hidden;
}
/* Il filo fra una riga e l'altra, dentro al riquadro: le `.dt-voce` ce l'hanno
   fra loro, e una riga scritta a mano che sta in mezzo lo deve avere uguale. */
.dt-presi > .dt-voce + .dt-riga-fuori,
.dt-presi > .dt-riga-fuori + .dt-voce,
.dt-presi > .dt-riga-fuori + .dt-riga-fuori {
  border-top: 1px solid var(--dt-border-soft);
}
/* Le due ore, grandi. Non e' vezzo: e' la sola schermata in cui si batte un
   numero che si legge da un orologio, e i campi alti quanto una riga di
   tabella qui si mancano col pollice. */
.dt-quando {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--dt-sp-4);
}
.dt-quando__ora {
  flex: 1 1 120px;
  min-width: 0;
  height: var(--dt-h-tocco);
  padding: 0 var(--dt-sp-4);
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-md);
  background: var(--dt-surface);
  color: var(--dt-text);
  font: inherit;
  font-size: var(--dt-fs-xl);
  font-variant-numeric: tabular-nums;
  text-align: center;
}
.dt-quando__ora:focus-visible { outline: 2px solid var(--dt-accent); outline-offset: 1px; }
.dt-quando__a { flex: none; color: var(--dt-text-3); user-select: none; }
/* Le durate che si segnano piu' spesso, da premere invece che da comporre
   spostando due orari. La fine si sposta, l'inizio no: e' l'inizio quello che
   si sa con certezza, perche' e' l'ora in cui si e' arrivati. */
.dt-durate { display: flex; flex-wrap: wrap; gap: var(--dt-sp-2); }
.dt-durata {
  min-height: var(--dt-h-tocco);
  padding: 0 var(--dt-sp-5);
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-full);
  background: var(--dt-surface);
  color: var(--dt-text-2);
  font: inherit;
  font-size: var(--dt-fs-sm);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background var(--dt-t-fast), border-color var(--dt-t-fast),
    color var(--dt-t-fast);
}
.dt-durata:hover { background: var(--dt-surface-2); color: var(--dt-text); }
.dt-durata--questa {
  background: var(--dt-accent);
  border-color: var(--dt-accent);
  color: var(--dt-text-inv);
}
/* Il numero grosso di una schermata che chiede un numero solo — i chilometri.
   Batterlo e non contarlo col −/+: sono quarantasette, non tre. */
.dt-cifrone {
  display: flex;
  align-items: baseline;
  gap: var(--dt-sp-4);
}
.dt-cifrone__campo {
  flex: 1 1 auto;
  min-width: 0;
  width: 100%;
  height: 56px;
  padding: 0 var(--dt-sp-5);
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-md);
  background: var(--dt-surface);
  color: var(--dt-text);
  font: inherit;
  font-size: var(--dt-fs-3xl);
  font-weight: var(--dt-fw-semibold);
  font-variant-numeric: tabular-nums;
  text-align: right;
  appearance: textfield;
  -moz-appearance: textfield;
}
.dt-cifrone__campo::-webkit-outer-spin-button,
.dt-cifrone__campo::-webkit-inner-spin-button { appearance: none; margin: 0; }
.dt-cifrone__campo:focus-visible { outline: 2px solid var(--dt-accent); outline-offset: 1px; }
.dt-cifrone__unita { flex: none; color: var(--dt-text-3); font-size: var(--dt-fs-lg); }

/* Le foto: quadrate e fitte, perche' quello che si guarda qui e' "quante ne ho
   fatte" e non il dettaglio. Il dettaglio si guarda dall'ufficio, su uno
   schermo vero.
   La misura minima e' in pixel e non in `vw`: la griglia sta dentro a una
   maschera larga la sua, e legarla alla finestra vorrebbe dire due foto grandi
   il doppio quando la maschera e' stretta e la finestra no. Cosi' invece le
   colonne le conta lo spazio che c'e' davvero. */
.dt-foto-griglia {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: var(--dt-sp-3);
}
.dt-foto {
  position: relative;
  margin: 0;
  aspect-ratio: 1;
  overflow: hidden;
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-md);
  background: var(--dt-surface-3);
}
.dt-foto__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* Il tastino per togliere sta sull'angolo della foto e non sotto: e' quella
   foto che si toglie, e a fianco ce ne sono altre cinque uguali. Fondo scuro
   fisso perche' sopra ci puo' essere qualsiasi cosa, anche un muro bianco. */
.dt-foto__togli {
  position: absolute;
  top: var(--dt-sp-2);
  right: var(--dt-sp-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: none;
  border-radius: var(--dt-r-full);
  background: rgba(18, 18, 17, 0.62);
  color: #fff;
  cursor: pointer;
  transition: background var(--dt-t-fast);
}
.dt-foto__togli:hover { background: rgba(18, 18, 17, 0.85); }
.dt-foto__togli:focus-visible {
  outline: 2px solid var(--dt-accent);
  outline-offset: 2px;
}

/* Scattare e' un'azione da pollice in cima a una scala: la riga intera e'
   bersaglio, non un'icona da 16px. E' una `<label>` perche' il campo file vero
   deve restare invisibile ma raggiungibile — nascosto con `display: none` non
   lo troverebbe piu' nemmeno chi naviga da tastiera. */
.dt-foto-aggiungi {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--dt-sp-3);
  min-height: var(--dt-h-tocco);
  padding: var(--dt-sp-3) var(--dt-sp-5);
  border: 1px dashed var(--dt-border-strong);
  border-radius: var(--dt-r-md);
  background: var(--dt-surface-2);
  color: var(--dt-text-2);
  font-size: var(--dt-fs-md);
  cursor: pointer;
  transition: background var(--dt-t-fast), border-color var(--dt-t-fast), color var(--dt-t-fast);
}
.dt-foto-aggiungi:hover {
  border-color: var(--dt-accent-border);
  background: var(--dt-surface-3);
  color: var(--dt-text);
}
.dt-foto-aggiungi:has(input:focus-visible) {
  outline: 2px solid var(--dt-accent);
  outline-offset: 2px;
}
/* Mentre carica non si preme piu': il campo e' spento, e la riga lo dice. */
.dt-foto-aggiungi:has(input:disabled) {
  cursor: default;
  opacity: 0.6;
}
.dt-foto-aggiungi input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   24. Vetrina: la scheda che si guarda e basta
   -------------------------------------------------------------------------- */

/* Una maschera da compilare e una da leggere non si disegnano uguali. Nella
   prima ogni dato sta dentro a una casella, e la casella e' il segno che li'
   si scrive; qui le caselle non ci sono, e a tenere insieme i dati restano
   soltanto la scala del testo e tre filetti. Il risultato assomiglia al foglio
   di lavoro da cui questi dati arrivano, che e' esattamente da dove chi guarda
   li ha copiati. */
.dt-vetrina {
  display: flex;
  flex-direction: column;
  gap: var(--dt-sp-7);
}

.dt-vetrina__testa { display: flex; flex-direction: column; gap: var(--dt-sp-2); }
/* Nome e bollini sulla stessa linea di base: il bollino e' un pezzo del nome,
   non una decorazione che gli galleggia accanto. Sotto la finestra stretta va
   a capo per conto suo invece di stringere il nome. */
.dt-vetrina__riga {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--dt-sp-3) var(--dt-sp-4);
}
.dt-vetrina__nome {
  font-size: var(--dt-fs-2xl);
  font-weight: var(--dt-fw-semibold);
  letter-spacing: -0.02em;
  line-height: var(--dt-lh-tight);
  overflow-wrap: anywhere;
}
.dt-vetrina__bollini { display: flex; flex-wrap: wrap; align-items: center; gap: var(--dt-sp-2); }
.dt-vetrina__sotto { font-size: var(--dt-fs-sm); color: var(--dt-text-2); }

/* L'occhiello del gruppo tira il suo filo fino al bordo: e' quello a dire dove
   comincia un discorso e dove finisce il precedente. I fatti dentro non hanno
   filetti loro — quattro righe di filo per sei dati sarebbero una grata. */
.dt-fatti { display: flex; flex-direction: column; gap: var(--dt-sp-4); }
.dt-fatti__occhiello {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-4);
  font-size: var(--dt-fs-xs);
  font-weight: var(--dt-fw-semibold);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--dt-text-3);
}
.dt-fatti__occhiello::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: var(--dt-border-soft);
}
/* Le colonne le decide la griglia e non il contenuto, come nella maschera dei
   campi: la misura si interpola con la finestra, cosi' passando da largo a
   stretto i fatti si ricompongono senza scatti. */
.dt-fatti__griglia {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(clamp(132px, 15vw, 176px), 1fr));
  gap: var(--dt-sp-5) var(--dt-sp-6);
}
.dt-fatto { display: flex; flex-direction: column; gap: var(--dt-sp-1); min-width: 0; }
.dt-fatto--tutta { grid-column: 1 / -1; }
.dt-fatto__etichetta { font-size: var(--dt-fs-xs); color: var(--dt-text-3); }
.dt-fatto__valore {
  font-size: var(--dt-fs-md);
  color: var(--dt-text);
  line-height: var(--dt-lh-normal);
  /* Le note sono scritte a mano andando a capo: sulla scheda vanno lette come
     sono state battute. */
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.dt-fatto__valore--mono { font-family: var(--dt-font-mono); font-variant-numeric: tabular-nums; }
/* Quello che nessuno ha scritto si legge come tale, e non come una cella che
   il programma non e' riuscito a riempire. */
.dt-fatto__vuoto { font-size: var(--dt-fs-md); color: var(--dt-text-3); }

/* I numeri di un riferimento: uno per riga, e accanto chi risponde.

   E' un elenco sotto a un occhiello e non una griglia di fatti, per la stessa
   ragione per cui non lo sono le righe d'ordine. Con la nota per etichetta e il
   numero sotto, una nota lunga — «l'amministratore del condominio» — va a capo
   e fa scendere il suo numero di una riga mentre i vicini restano su: tre
   numeri da leggere in colonna smettono di essere in colonna proprio dove
   serve. Qui la colonna del numero e' larga quanto il piu' lungo dei numeri e
   basta, quindi le cifre si incolonnano da sole e a crescere e' la nota.

   Stretti passano in due righe: il numero sopra, la nota rientrata sotto. Due
   colonne a questa larghezza vorrebbero dire una nota larga cinque caratteri. */
.dt-telefoni {
  display: grid;
  grid-template-columns: minmax(0, max-content) minmax(0, 1fr);
  gap: var(--dt-sp-1) var(--dt-sp-5);
  align-items: baseline;
}
.dt-telefoni__numero {
  font-size: var(--dt-fs-md);
  font-family: var(--dt-font-mono);
  font-variant-numeric: tabular-nums;
}
.dt-telefoni__nota { font-size: var(--dt-fs-sm); color: var(--dt-text-2); }
@media (max-width: 480px) {
  .dt-telefoni { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .dt-telefoni__nota { padding-bottom: var(--dt-sp-3); }
}

/* La riga dei numeri: l'unico punto della scheda che alza la voce, perche' e'
   quello che si viene a cercare. Il filo qui e' quello pieno, non il tenue dei
   gruppi: sotto ci sta un totale, e un totale si stacca da quello che lo fa. */
.dt-cifre {
  display: flex;
  flex-wrap: wrap;
  gap: var(--dt-sp-5) var(--dt-sp-9);
  padding-top: var(--dt-sp-5);
  border-top: 1px solid var(--dt-border);
}
.dt-cifra { display: flex; flex-direction: column; gap: var(--dt-sp-1); }
.dt-cifra__valore {
  font-family: var(--dt-font-mono);
  font-size: var(--dt-fs-2xl);
  font-weight: var(--dt-fw-semibold);
  font-variant-numeric: tabular-nums;
  line-height: var(--dt-lh-tight);
}
.dt-cifra__etichetta {
  font-size: var(--dt-fs-xs);
  font-weight: var(--dt-fw-semibold);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--dt-text-3);
}
.dt-cifra__nota { font-size: var(--dt-fs-sm); color: var(--dt-text-2); }

/* --------------------------------------------------------------------------
   25. Calendari: le giornate di tutti affiancate
   -------------------------------------------------------------------------- */

/* E' la stessa colonna della giornata, girata sull'altro asse: li' erano i
   giorni di una persona, qui sono le persone di un giorno. Il righello degli
   orari resta uno solo a sinistra, e questo e' tutto il punto — le 10:00 di
   Anna cadono alla stessa altezza delle 10:00 di Mario, e "chi e' dove a meta'
   mattina" si legge in orizzontale senza contare niente.
   Niente colori per persona: il colore in colonna vuol gia' dire un'altra
   cosa — che lavoro e' — e una seconda scala di tinte sulle stesse colonne
   renderebbe illeggibili tutte e due. Le persone si distinguono per nome, che
   e' come si distinguono anche fuori dal programma.

   **La pagina e' fatta di due file sovrapposte**: sopra i cartellini con i
   nomi, sotto le tele con le ore. Non e' un dettaglio di impaginazione — e' il
   motivo per cui i nomi non finiscono dentro alla griglia: li' dentro passano
   la riga rossa di adesso, i blocchi che si trascinano e le righe delle ore, e
   un nome in mezzo a quella roba viene scavalcato. Le due file stanno pero'
   dentro allo **stesso** riquadro che scorre, e con le stesse misure di
   colonna: cosi' scorrono di lato insieme, senza niente da tenere allineato a
   mano. */
.dt-calendari__scorri {
  flex: 1 1 auto;
  min-height: 0;
  /* Scorre in tutte e due i versi: in giu' le ore, di lato le persone quando
     sono piu' di quante ne tiene la finestra. */
  overflow: auto;
  overscroll-behavior: contain;
  /* In fondo l'aria che serve alla barra della data per non coprire l'ultimo
     blocco: la sua altezza piu' i due orli. */
  padding-bottom: calc(var(--dt-piu) + var(--dt-piu-orlo) * 2);
}
/* Le due file, incolonnate. Le misure stanno qui e non su ognuna: sono le
   stesse per i cartellini e per le tele, ed e' proprio questo che le tiene
   allineate. */
.dt-calendari__quadro {
  display: flex;
  flex-direction: column;
  /* Larga almeno quanto la pagina, cosi' in due o in tre le colonne si
     allargano invece di ammucchiarsi a sinistra; e almeno quanto le colonne,
     cosi' in dieci si scorre di lato invece di stringerle fino a non leggerle
     piu'. */
  min-width: min-content;
  /* Sotto questa larghezza un blocco non dice piu' ne' che lavoro era ne'
     dove: da li' in poi si scorre. Il massimo tiene una colonna larga un palmo
     anche quando in squadra c'e' una persona sola. */
  --dt-persona-min: clamp(124px, 11vw, 168px);
  --dt-persona-max: 300px;
  --dt-persona-gap: var(--dt-sp-4);
}
/* La fila dei cartellini: sta in cima e ci resta anche scorrendo la giornata.
   Fondo pieno, perche' le ore le passano sotto. */
.dt-calendari__testate {
  display: flex;
  align-items: stretch;
  gap: var(--dt-persona-gap);
  position: sticky;
  top: 0;
  z-index: var(--dt-z-sticky);
  background: var(--dt-bg);
  /* L'aria fra i nomi e la prima ora. Sta qui e non sul riquadro che scorre
     perche' e' aria che deve restare anche quando la fila e' appiccicata in
     cima: l'etichetta della prima ora e' centrata sulla sua riga, e meta' di
     essa sta sopra al principio della tela. */
  padding-bottom: var(--dt-sp-5);
}
.dt-calendari__fila {
  display: flex;
  align-items: flex-start;
  gap: var(--dt-persona-gap);
}
/* Il posto del righello, in cima: vuoto, ma largo uguale, se no i cartellini
   partono mezzo pollice piu' a sinistra delle tele che intestano. Sta fermo
   anche di lato, come il righello sotto. */
.dt-calendari__vuoto {
  flex: 0 0 var(--dt-asse-w);
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--dt-bg);
}
/* Il righello resta fermo mentre le persone scorrono di lato: e' la scala su
   cui si legge tutto il resto, e una scala che scorre via non misura piu'
   niente. */
.dt-calendari__fila .dt-giorno__asse {
  position: sticky;
  left: 0;
  z-index: var(--dt-z-sticky);
  background: var(--dt-bg);
}
/* Il posto vuoto che il righello si tiene in cima qui non serve: le
   intestazioni stanno nella fila di sopra, e questo lascerebbe le ore piu'
   basse dei blocchi che misurano. */
.dt-calendari__fila .dt-giorno__intestazione { display: none; }

/* Le due colonne di una persona — il cartellino e la tela — larghe uguali per
   forza: la stessa regola, scritta una volta per tutte e due. */
.dt-calendari__testa,
.dt-calendari__persona {
  flex: 1 1 var(--dt-persona-min);
  min-width: var(--dt-persona-min);
  max-width: var(--dt-persona-max);
}
.dt-calendari__persona {
  /* Un blocco stretto taglia il testo invece di sbordare sulla persona di
     fianco. */
  overflow-x: clip;
}

/* Il cartellino: chi e', e come e' andata la sua giornata. Sta fermo com'e' —
   non si accende, non si inverte, non cambia cornice a seconda di quello che
   c'e' sotto: a dire com'e' andata sono il numero e i blocchi, non il riquadro
   che li intesta. */
.dt-calendari__testa {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--dt-sp-2);
  padding: var(--dt-sp-3) var(--dt-sp-4);
  border: 1px solid var(--dt-border-soft);
  border-radius: var(--dt-r-md);
  background: var(--dt-surface-2);
  color: var(--dt-text);
}
.dt-calendari__riga {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--dt-sp-2);
  min-width: 0;
}
/* Chi e': la riga piu' grossa del cartellino, perche' e' quello che si cerca
   scorrendo la fila. Per intero finche' ci sta, poi troncato — due colleghi
   che si chiamano uguale si distinguono dal cognome, e mandarlo a capo
   alzerebbe il cartellino di una persona sola scollando tutta la fila. */
.dt-calendari__nome {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: var(--dt-fs-md);
  font-weight: var(--dt-fw-semibold);
  line-height: var(--dt-lh-tight);
}
/* Sotto al nome, una frase e non un numero nudo: "7h 45 segnate". Il numero da
   solo era la cosa piu' grossa del cartellino e non diceva di cosa fosse il
   conto. */
.dt-calendari__conto {
  display: inline-flex;
  align-items: baseline;
  gap: var(--dt-sp-2);
  min-width: 0;
}
/* Le ore in cifre tabellari: i cartellini stanno in fila, e due conti si
   confrontano a occhio solo se cadono incolonnati. */
.dt-calendari__ore {
  font-family: var(--dt-font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--dt-fs-sm);
  font-weight: var(--dt-fw-semibold);
  line-height: var(--dt-lh-tight);
}
/* La parola che dice di cosa e' il conto: sta al numero come un'unita' di
   misura, quindi piu' piccola e piu' spenta di lui. */
.dt-calendari__detto {
  font-size: var(--dt-fs-xs);
  color: var(--dt-text-3);
  white-space: nowrap;
}
/* Chi non ha segnato niente lo dice a parole. Un trattino si legge tanto come
   uno zero quanto come un dato che non e' arrivato, e a fine mese sono due
   cose molto diverse. */
.dt-calendari__niente {
  font-size: var(--dt-fs-sm);
  color: var(--dt-text-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Il segno che qualcosa non torna in quella giornata — blocchi accavallati,
   domande rimaste vuote. E' l'unica cosa colorata del cartellino, quindi si
   vede da sola in fondo alla riga. */
.dt-calendari__guaio {
  display: inline-flex;
  align-items: center;
  gap: var(--dt-sp-2);
  flex: 0 0 auto;
  font-size: var(--dt-fs-xs);
  font-variant-numeric: tabular-nums;
  color: var(--dt-warn);
}
/* La fila dei nomi da accendere, sopra a tutto. Va a capo con i suoi gettoni:
   l'etichetta resta attaccata alla fila anche quando questa occupa tre righe. */
.dt-calendari__filtro {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--dt-sp-3) var(--dt-sp-5);
}

/* Su un telefono questa e' una schermata da ufficio, ma ci si finisce lo
   stesso — dal furgone si controlla se il collega ha segnato. Le colonne si
   stringono al minimo che resta leggibile e si scorre: mostrarne una sola per
   volta vorrebbe dire perdere il confronto, che e' l'unico motivo per cui
   questa schermata esiste. */
@media screen and (max-width: 560px) {
  .dt-calendari__quadro { --dt-persona-min: 124px; }
}

/* --------------------------------------------------------------------------
   26. Versione: il segno in barra e il pannello delle novita'
   --------------------------------------------------------------------------

   Il segno sta nelle impostazioni, sulla riga della versione, di fianco al
   tema: la testata dice che programma e' questo e non cambia mai, mentre la
   versione e' una cosa che si va a cercare. Non e' un comando e non ne ha
   l'aspetto — nessun fondo pieno, nessuna icona — ma si preme, e quindi si
   accende sotto al dito come una voce di menu.

   Il numero e' in monospaziato come tutti i numeri del programma: gli orari
   nella colonna del giorno, gli importi in tabella. Un numero di versione
   scritto col carattere del testo si legge come una parola, e le sue tre
   cifre non si incolonnano con niente.
   -------------------------------------------------------------------------- */

.dt-versione {
  display: inline-flex;
  align-items: center;
  gap: var(--dt-sp-2);
  flex: none;
  /* In coda all'etichetta della riga, contro il bordo destro del pannello:
     e' il controllo di quella riga, come il tema e' quello della sua. */
  margin-left: auto;
  height: 20px;
  padding: 0 var(--dt-sp-2);
  border: 1px solid var(--dt-border);
  border-radius: var(--dt-r-sm);
  background: var(--dt-surface-2);
  color: var(--dt-text-3);
  font-family: var(--dt-font-mono);
  font-size: var(--dt-fs-xs);
  line-height: 1;
  cursor: pointer;
  transition: color var(--dt-t-fast), border-color var(--dt-t-fast),
    background var(--dt-t-fast);
}
.dt-versione:hover {
  background: var(--dt-surface-3);
  border-color: var(--dt-border-strong);
  color: var(--dt-text);
}
.dt-versione:focus-visible { outline: 2px solid var(--dt-accent); outline-offset: 1px; }
/* Il server risponde un numero diverso: la pagina aperta e' vecchia. Un punto
   e non un colore su tutto il segno — il numero deve restare leggibile, ed e'
   il pannello che ha lo spazio per dire cosa sia successo. */
.dt-versione__punto {
  width: 5px;
  height: 5px;
  flex: none;
  border-radius: var(--dt-r-full);
  background: var(--dt-warn);
}

/* Le due versioni in testa al pannello: questa pagina, e quello che risponde
   il server. Stanno appaiate perche' la domanda e' il loro confronto. */
.dt-novita__stato {
  display: flex;
  flex-wrap: wrap;
  gap: var(--dt-sp-6);
  padding-bottom: var(--dt-sp-5);
  border-bottom: 1px solid var(--dt-border-soft);
}
.dt-novita__quale { display: flex; flex-direction: column; gap: var(--dt-sp-1); }
.dt-novita__etichetta {
  font-size: var(--dt-fs-xs);
  font-weight: var(--dt-fw-semibold);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--dt-text-3);
}
.dt-novita__num {
  font-family: var(--dt-font-mono);
  font-size: var(--dt-fs-sm);
  color: var(--dt-text);
}
.dt-novita__scarto { padding-top: var(--dt-sp-5); }

/* L'elenco dei rilasci e' una colonna del tempo, come la giornata: un filo
   verticale, e su quel filo una tacca per ogni versione. La piu' recente ha la
   tacca piena, le altre vuote — e' la stessa grammatica dei blocchi, dove il
   pieno e' quello che c'e' e il contorno quello che e' solo segnato.
   Il filo dell'ultima si spegne invece di fermarsi netto: sotto non c'e' un
   rilascio piu' vecchio, c'e' il fondo di quello che sappiamo. */
.dt-novita {
  list-style: none;
  margin: var(--dt-sp-7) 0 0;
  padding: 0;
}
.dt-novita__rilascio {
  position: relative;
  padding-left: calc(var(--dt-corsia) + var(--dt-sp-2));
  padding-bottom: var(--dt-sp-8);
}
.dt-novita__rilascio:last-child { padding-bottom: 0; }
.dt-novita__rilascio::before {
  content: "";
  position: absolute;
  left: calc(var(--dt-corsia) / 2);
  top: var(--dt-sp-2);
  bottom: 0;
  width: 1px;
  background: var(--dt-border);
}
.dt-novita__rilascio:last-child::before {
  height: var(--dt-sp-9);
  bottom: auto;
  -webkit-mask-image: linear-gradient(to bottom, #000, transparent);
  mask-image: linear-gradient(to bottom, #000, transparent);
}
.dt-novita__rilascio::after {
  content: "";
  position: absolute;
  left: calc(var(--dt-corsia) / 2 - 3px);
  top: var(--dt-sp-2);
  width: 7px;
  height: 7px;
  border-radius: var(--dt-r-full);
  background: var(--dt-bg);
  box-shadow: inset 0 0 0 1.5px var(--dt-border-strong);
}
.dt-novita__rilascio:first-child::after {
  background: var(--dt-accent);
  box-shadow: inset 0 0 0 1.5px var(--dt-accent);
}

.dt-novita__capo {
  display: flex;
  align-items: baseline;
  gap: var(--dt-sp-4);
  margin-top: -2px;
}
.dt-novita__numero {
  font-family: var(--dt-font-mono);
  font-size: var(--dt-fs-lg);
  font-weight: var(--dt-fw-semibold);
  color: var(--dt-text-3);
  letter-spacing: -0.01em;
}
/* La versione di adesso e' l'unica scritta in inchiostro pieno: le altre sono
   storia, e la storia si legge dopo. */
.dt-novita__rilascio:first-child .dt-novita__numero { color: var(--dt-text); }
.dt-novita__data {
  font-family: var(--dt-font-mono);
  font-size: var(--dt-fs-xs);
  color: var(--dt-text-3);
}
/* Una riga per modifica, e la riga e' il titolo: niente pallini davanti — la
   colonna delle tacche sta gia' a sinistra e ne fa le veci — e niente
   descrizione sotto. Chi apre questo pannello sta scorrendo un elenco, non
   leggendo un documento. */
.dt-novita__voci {
  list-style: none;
  margin: var(--dt-sp-4) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--dt-sp-3);
}
.dt-novita__voci > li {
  max-width: 62ch;
  font-size: var(--dt-fs-md);
  line-height: var(--dt-lh-normal);
  color: var(--dt-text-2);
}
/* Le modifiche dell'ultima versione sono quelle che si e' venuti a leggere. */
.dt-novita__rilascio:first-child .dt-novita__voci > li { color: var(--dt-text); }
.dt-novita__cod {
  font-family: var(--dt-font-mono);
  font-size: 0.92em;
  padding: 1px var(--dt-sp-2);
  border-radius: var(--dt-r-xs);
  background: var(--dt-surface-3);
  color: var(--dt-text);
  /* Un percorso lungo va a capo dove capita invece di sfondare il pannello. */
  overflow-wrap: anywhere;
}

/* Lo spostamento: da che numero a che numero. E' la prima cosa che si legge
   entrando la mattina dopo l'aggiornamento, quindi e' scritta grossa e in
   monospaziato — due numeri di versione si confrontano cifra per cifra, e in
   proporzionale le cifre non stanno incolonnate.
   Quello di prima e' storia gia' un secondo dopo averlo letto: sta in grigio e
   piu' piccolo, e l'inchiostro pieno ce l'ha solo dove si e' arrivati. */
.dt-salto {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--dt-sp-3);
  font-family: var(--dt-font-mono);
  padding-bottom: var(--dt-sp-5);
  border-bottom: 1px solid var(--dt-border-soft);
}
.dt-salto__prima {
  font-size: var(--dt-fs-lg);
  color: var(--dt-text-3);
}
.dt-salto__freccia {
  font-size: var(--dt-fs-lg);
  color: var(--dt-accent);
}
.dt-salto__adesso {
  font-size: var(--dt-fs-2xl);
  font-weight: var(--dt-fw-semibold);
  letter-spacing: -0.01em;
  color: var(--dt-text);
}

/* Una versione sola: il numero sta gia' scritto sopra a caratteri grossi, e la
   colonna delle tacche segnerebbe il tempo di un punto solo. Restano le righe
   di cosa e' cambiato, che sono quelle che si e' venuti a leggere. */
.dt-novita--secche { margin-top: var(--dt-sp-5); }
.dt-novita--secche .dt-novita__rilascio { padding: 0; }
.dt-novita--secche .dt-novita__rilascio::before,
.dt-novita--secche .dt-novita__rilascio::after,
.dt-novita--secche .dt-novita__capo { display: none; }
.dt-novita--secche .dt-novita__voci { margin-top: 0; }

/* --------------------------------------------------------------------------
   27. Scambio del catalogo: il file che esce e quello che entra
   --------------------------------------------------------------------------

   Scaricare non chiede niente: si preme e il file e' li'. Caricare invece e'
   l'unico gesto del programma che tocca tutto il catalogo in un colpo, e le due
   strade — aggiungere e rimpiazzare — non si somigliano per niente.

   Da qui la forma: **non due voci in una tendina, ma due riquadri affiancati**,
   con dentro i numeri veri di quel file su questo catalogo. Il nome della strada
   e' la riga piu' piccola dei tre; quella che fa scegliere e' l'ultima, dove
   sta scritto quante righe entrano e quante si spengono. Si sceglie leggendo
   cosa succede, non il nome di cosa succede.

   Scelto, il riquadro prende il fondo e il bordo dell'accento invece di una
   spunta sola in un angolo: e' la stessa differenza fra acceso e spento che
   fanno gia' il segmentato e i gettoni.
   -------------------------------------------------------------------------- */

/* Il tasto che apre la finestra dei file. La finestra la puo' aprire solo il
   campo, quindi il campo sta qui dentro e non si vede — ma resta raggiungibile
   col tabulatore, e l'anello del fuoco lo disegna l'etichetta per lui. */
.dt-btn-file { position: relative; }
.dt-btn-file input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.dt-btn-file:has(input:focus-visible) {
  outline: 2px solid var(--dt-accent);
  outline-offset: 2px;
}

/* Il file scelto, in cima alla maschera: come si chiama e cosa c'e' dentro. */
.dt-scambio__file {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-3);
  min-width: 0;
  padding: var(--dt-sp-3) var(--dt-sp-4);
  border: 1px solid var(--dt-border-soft);
  border-radius: var(--dt-r-md);
  background: var(--dt-surface-2);
  color: var(--dt-text-2);
}
.dt-scambio__nome {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--dt-font-mono);
  font-size: var(--dt-fs-sm);
  color: var(--dt-text);
}
.dt-scambio__dentro { flex: 0 0 auto; font-size: var(--dt-fs-sm); }

/* I due riquadri, affiancati finche' c'e' posto. */
.dt-modi {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--dt-sp-4);
}
.dt-modo {
  display: flex;
  flex-direction: column;
  gap: var(--dt-sp-2);
  padding: var(--dt-sp-4);
  border: 1px solid var(--dt-border-soft);
  border-radius: var(--dt-r-md);
  background: var(--dt-surface);
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background var(--dt-t-fast), border-color var(--dt-t-fast),
              box-shadow var(--dt-t-fast);
}
.dt-modo:hover { border-color: var(--dt-border); background: var(--dt-surface-2); }
.dt-modo--preso {
  border-color: var(--dt-accent);
  background: var(--dt-accent-soft);
  box-shadow: var(--dt-shadow-sm);
}
.dt-modo__capo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--dt-sp-3);
  color: var(--dt-accent);
}
.dt-modo__nome { font-weight: var(--dt-fw-semibold); line-height: var(--dt-lh-tight); }
.dt-modo__sotto { color: var(--dt-text-2); font-size: var(--dt-fs-sm); }
/* I numeri: staccati da un filo, perche' sono l'unica cosa qui dentro che
   cambia da un file all'altro. */
.dt-modo__conti {
  display: flex;
  flex-direction: column;
  gap: var(--dt-sp-1);
  margin-top: var(--dt-sp-2);
  padding-top: var(--dt-sp-3);
  border-top: 1px dashed var(--dt-border-soft);
  font-size: var(--dt-fs-sm);
}
.dt-modo__conto { display: flex; gap: var(--dt-sp-2); }
/* La parola a sinistra tiene una colonna sua: tre righe che cominciano tutte
   allo stesso punto si confrontano fra i due riquadri senza rileggerle. */
.dt-modo__cosa {
  flex: 0 0 4.5rem;
  color: var(--dt-text-2);
  font-size: var(--dt-fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  line-height: 1.5;
}

/* --------------------------------------------------------------------------
   28. Telefono
   --------------------------------------------------------------------------

   Non e' l'ufficio piu' stretto: e' la stessa applicazione presa in una mano
   sola. Quello che cambia qui e' la disposizione, e per questo e' una soglia e
   non un `clamp` — le misure che possono scorrere scorrono gia' da sole piu'
   su. Sotto i 560px cambiano quattro cose, e ognuna perche' a quella larghezza
   la regola dell'ufficio produce qualcosa di rotto:

   1. la testata di un riquadro non e' piu' una riga (titolo a sinistra,
      comandi a destra): a 390px i comandi non ci stanno e spingono la
      descrizione in una colonna larga una parola;
   2. la barra bassa non scorre: cinque voci e chi sei ci stanno tutte, a slot
      uguali, perche' una barra di navigazione da cercare scorrendo non e' una
      barra di navigazione;
   3. la prima colonna di una tabella resta ferma mentre le altre scorrono: e'
      il nome, ed e' l'unica cosa che dice di che riga si sta leggendo il dato;
   4. una modale diventa il foglio intero, perche' un riquadro con l'aria
      intorno su uno schermo alto ottocento pixel e' un francobollo che scorre.

   `screen and`: sulla carta niente di tutto questo vale, e un foglio A4
   stretto non deve prendersi la barra bassa a slot ne' le colonne spente.
   -------------------------------------------------------------------------- */

@media screen and (max-width: 560px) {
  :root {
    /* Le altezze dei controlli passano alla scala del pollice. Non e' un
       ingrandimento: `--dt-h-tocco` e' la misura che l'operatore in cantiere
       aveva gia', e qui la prendono tutti perche' qui sono tutti in cantiere.
       `--dt-h-sm` resta com'e': la usano anche dei bollini (il conto su una
       linguetta), e un bollino alto quaranta pixel e' una pastiglia. */
    --dt-h-md: var(--dt-h-tocco);
    --dt-h-lg: 46px;
    /* E con loro i tastini di una riga d'elenco — che qui e' la cosa piu' alta
       della riga, e quindi quella che ne detta il passo (`--dt-riga-h`). */
    --dt-h-comando: var(--dt-h-tocco);
    --dt-topbar-h: 44px;
    /* Il corpo pagina si stringe: a 390px ogni pixel di margine e' un pixel
       tolto al nome che ci deve stare dentro. */
    --dt-pad-body: 8px;
  }

  /* I controlli minuti sono minuti perche' in ufficio stanno in fila dentro a
     una barra. Qui la fila e' andata a capo e non c'e' niente da comprimere:
     un tasto da ventidue pixel si manca col pollice. */
  .dt-btn--sm { height: var(--dt-h-tocco); padding: 0 var(--dt-sp-5); font-size: var(--dt-fs-md); }
  /* Il tastino solo icona lo fa gia' `--dt-h-comando` qui sopra: una misura
     sola, che la sa anche la riga che lo contiene. */
  .dt-input--sm { height: var(--dt-h-tocco); font-size: var(--dt-fs-md); }
  /* Sedici pixel e non quindici: sotto questa misura il telefono ingrandisce
     la pagina da solo quando il campo prende il fuoco, e non la rimpicciolisce
     piu' quando lo perde. Vale per quello in cui si scrive, non per i tasti. */
  .dt-input, .dt-select, .dt-textarea { font-size: 16px; }

  /* ---- La barra in cima: dove sei, e nient'altro --------------------------

     Il percorso diceva "Conti › Ore", e la fila di linguette subito sotto
     diceva "Ore" un'altra volta: su uno schermo alto ottocento pixel due righe
     di navigazione per la stessa informazione sono una riga di troppo. Resta
     il modulo — che le linguette non dicono — e la scheda la dice la linguetta
     accesa. Chi ha una schermata sola (l'operatore) ha un solo pezzo di
     percorso, che e' anche l'ultimo: quello resta, o non resterebbe niente. */
  .dt-toolbar { gap: var(--dt-sp-2); padding: var(--dt-sp-2) var(--dt-sp-4); }
  .dt-breadcrumb__sep { display: none; }
  .dt-breadcrumb__item--current:not(:first-child) { display: none; }
  .dt-breadcrumb > :first-child {
    font-size: var(--dt-fs-lg);
    font-weight: var(--dt-fw-semibold);
    color: var(--dt-text);
  }

  /* ---- Testata di un riquadro ---------------------------------------------

     Il titolo si prende la sua riga e i comandi la loro: a questa larghezza di
     fianco al titolo non ci sta nemmeno il solo campo di ricerca, e mezzo campo
     di ricerca non ci sta un indirizzo. La descrizione sta sotto a tutti e due,
     come sul largo. */
  .dt-card__head { padding: var(--dt-sp-5); gap: var(--dt-sp-3); }
  .dt-card__head__riga {
    flex-direction: column;
    align-items: stretch;
    gap: var(--dt-sp-4);
  }
  /* In colonna il margine automatico che sul largo spinge i comandi a destra
     annullerebbe lo `stretch`: la fila tornerebbe larga quanto il contenuto e
     appoggiata al bordo destro invece di prendersi la riga. */
  .dt-card__head__riga > .dt-row { margin-left: 0; }
  .dt-card__foot { flex-wrap: wrap; row-gap: var(--dt-sp-3); }
  /* La ricerca si prende la riga intera: e' il primo comando che si tocca in un
     elenco. */
  .dt-card__head .dt-inputgroup { flex: 1 1 100%; }
  /* Il segmentato resta un riquadro solo e scorre dentro di se': cinque stati
     ("Tutte, Aperta, Sospesa, Finita, Fatturata") a 390px non ci stanno, e
     spezzarli su due righe farebbe due riquadri di una cosa sola. */
  .dt-segmented {
    max-width: 100%;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .dt-segmented::-webkit-scrollbar { display: none; }
  /* Quello che avanza va ai tasti, che diventano larghi quanto la riga: sono
     l'azione della schermata, non una voce di una barra. */
  .dt-card__head__riga > .dt-row > .dt-btn,
  .dt-card__foot > .dt-btn { flex: 1 1 auto; }
  /* Il filo verticale che stacca "quello che filtra" da "quello che porta
     fuori" sparisce: fra due cose che sono andate a capo non c'e' piu' niente
     da separare di fianco, e resterebbe una stanghetta in mezzo alla riga. */
  .dt-card__head .dt-divider--v { display: none; }

  /* ---- Tabelle -----------------------------------------------------------

     La prima colonna sta ferma, le altre le scorre il dito. E' il compromesso
     che una tabella da ufficio su uno schermo da telefono permette: le colonne
     non ci stanno, ma senza il nome davanti un numero non si sa di chi sia.
     Il resto della riga si legge tutto in una volta dall'occhio, che apre la
     scheda in lettura — e li' non c'e' niente di tagliato.
     La pagina invece non scorre mai di lato: scorre il riquadro. */
  .dt-tablewrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .dt-table thead th,
  .dt-table tbody td { padding: var(--dt-sp-4) var(--dt-sp-3); }
  /* Le colonne di contorno si spengono. Quali siano lo dice ogni elenco per
     conto suo (`dt-col--sec`): e' una decisione su cosa serve per riconoscere
     una riga stando in piedi, non una regola generale. Quello che si spegne
     non se ne va: sta nella scheda che apre l'occhio, a un dito di distanza. */
  .dt-col--sec { display: none; }
  /* La colonna che sta ferma e' la **prima che si vede**, non la prima che
     c'e': negli articoli la prima e' il codice e si spegne, e la colonna da
     tenere sotto gli occhi diventa il nome. Due casi bastano — nessun elenco
     spegne le prime due — e scritti cosi' non c'e' un secondo posto dove
     ricordarsi quale sia la colonna del nome. */
  .dt-table thead th:first-child:not(.dt-col--sec),
  .dt-table tbody td:first-child:not(.dt-col--sec),
  .dt-table thead th.dt-col--sec:first-child + th,
  .dt-table tbody td.dt-col--sec:first-child + td {
    position: sticky;
    left: 0;
    padding-left: var(--dt-sp-4);
    /* Un filo, non un'ombra: il resto della piattaforma separa con dei fili, e
       un'ombra qui sembrerebbe che la colonna galleggia sopra alle altre. */
    border-right: 1px solid var(--dt-border-soft);
    /* Il nome va a capo invece di allargare la tabella: "Condominio Le
       Magnolie" su una riga sola sono duecento pixel di colonna, cioe' meta'
       dello schermo per una riga su dieci. */
    white-space: normal;
    min-width: 7.5rem;
    max-width: 11rem;
    /* Il peso della prima colonna: e' il nome che si cerca scorrendo. Sul largo
       ce l'ha `td:first-child`, che qui puo' essere la cella spenta. */
    font-weight: var(--dt-fw-medium);
  }
  /* Una cella che sta ferma sopra a quelle che le passano sotto deve essere
     opaca, e dello stesso colore della sua riga: la zebratura e la riga scelta
     se la portano dietro, altrimenti scorrendo si vedrebbe il testo delle
     altre colonne passare sotto al nome. */
  .dt-table tbody td:first-child:not(.dt-col--sec),
  .dt-table tbody td.dt-col--sec:first-child + td {
    z-index: 1;
    background-color: var(--dt-surface);
  }
  .dt-table--zebra tbody tr:nth-child(even) td:first-child:not(.dt-col--sec),
  .dt-table--zebra tbody tr:nth-child(even) td.dt-col--sec:first-child + td {
    background-color: var(--dt-zebra);
  }
  .dt-table tbody tr.dt-tr--selected td:first-child:not(.dt-col--sec),
  .dt-table tbody tr.dt-tr--selected td.dt-col--sec:first-child + td {
    background-color: var(--dt-selected);
  }
  .dt-table thead th:first-child:not(.dt-col--sec),
  .dt-table thead th.dt-col--sec:first-child + th {
    z-index: calc(var(--dt-z-sticky) + 1);
  }
  /* I comandi di riga sono l'unica cosa della tabella che si preme, e stanno
     appoggiati al bordo destro come il nome sta al sinistro: fra i due anchori
     scorre quello che non ci sta. Senza, per premere l'occhio di una riga
     bisognava prima portare la tabella fino in fondo. */
  .dt-table .dt-iconbtn { width: var(--dt-h-tocco); height: var(--dt-h-tocco); }
  /* Solo le celle, non la loro intestazione: l'intestazione della colonna dei
     comandi e' vuota, quindi non c'e' niente da tenere fermo, e inchiodare a
     destra l'ultima `th` di ogni tabella staccherebbe il titolo dalla sua
     colonna in tutti i fogli che di comandi non ne hanno (le tre estrazioni
     finiscono con un numero). */
  .dt-table tbody td.dt-td--actions {
    position: sticky;
    right: 0;
    z-index: 1;
    padding-left: var(--dt-sp-2);
    padding-right: var(--dt-sp-3);
    border-left: 1px solid var(--dt-border-soft);
    background-color: var(--dt-surface);
  }
  .dt-table--zebra tbody tr:nth-child(even) td.dt-td--actions { background-color: var(--dt-zebra); }
  .dt-table tbody tr.dt-tr--selected td.dt-td--actions { background-color: var(--dt-selected); }

  /* Comandi che restano all'ufficio.
     Fondere due doppioni e buttare via una riga sono decisioni da scrivania: si
     prendono guardando due schede insieme, non in piedi con una mano sul
     furgone. Quattro tasti in fila su una riga larga un pollice, poi, sono
     quattro bersagli attaccati di cui uno cancella — e quello sbagliato si
     preme. Restano quelli di ogni giorno: l'interruttore e la matita. Guardare
     non e' piu' un tastino da nessuna parte — si preme il nome, che e' il
     bersaglio piu' largo della riga. `display: contents` sul largo, cosi' i
     tasti stanno nella riga come se il guscio non ci fosse. */
  .dt-solo-largo { display: none; }

  /* ---- Barra bassa: cinque voci e chi sei, a slot uguali ------------------

     In portrait la barra scorreva di lato: cinque moduli piu' il piede non ci
     stavano, e il nome finiva tagliato a meta' parola ("Miche…"). Una barra di
     navigazione che si scorre non e' una barra: le voci devono stare tutte
     sotto gli occhi, e a slot uguali stanno anche sul telefono piu' stretto.
     I gruppi (Cantiere, Scrivania, Fondamenta) diventano trasparenti alla
     griglia — `display: contents` — cosi' a spartirsi la riga sono le voci e
     non i tre gruppi, che sono di due, due e una voce e verrebbero larghi
     uguali fra loro invece che le voci. Il puntino che li separava passa sul
     primo tasto del gruppo nuovo: e' lo stesso segno, appeso a un'altra cosa. */
  .dt-app__side {
    gap: 0;
    padding: var(--dt-sp-3);
    padding-bottom: calc(var(--dt-sp-3) + env(safe-area-inset-bottom, 0px));
  }
  .dt-nav {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 0;
    overflow: visible;
  }
  .dt-nav__group { display: contents; }
  .dt-nav__group + .dt-nav__group { margin-left: 0; padding-left: 0; }
  .dt-nav__group + .dt-nav__group::before { content: none; }
  .dt-nav__group + .dt-nav__group > .dt-nav__item:first-child::before {
    content: "";
    position: absolute;
    left: -1px;
    top: 50%;
    width: 3px;
    height: 3px;
    border-radius: var(--dt-r-full);
    transform: translateY(-50%);
    background: var(--dt-border-strong);
  }
  .dt-nav__item {
    min-width: 0;
    max-width: none;
    padding: var(--dt-sp-2) 2px;
    /* Il nome del modulo non si accorcia — "Catal…" non e' un nome — quindi la
       misura del testo la detta lo slot: cinque nomi piu' chi sei, divisi per
       la larghezza che c'e'. Scorre con la finestra invece di aspettare
       un'altra soglia, e "Catalogo", che e' il piu' lungo, ci sta intero. */
    font-size: clamp(10px, 2.9vw, 12.5px);
  }
  .dt-nav__item svg { padding: var(--dt-sp-2) var(--dt-sp-5); }

  /* Chi sei e' l'ultimo slot della barra, fatto come gli altri: il cerchietto
     al posto dell'icona e il nome sotto. Il nome per intero non ci sta e
     tagliato non si legge, quindi resta la prima parola — che e' come si
     chiamano fra loro — e il resto sta nel pannello che il cerchietto apre.
     Il cerchietto e' anche il tasto: l'ingranaggio di fianco era un bersaglio
     in piu' per la stessa cosa, e a questa larghezza costava uno slot. */
  .dt-app__sidefoot {
    /* Un filo di respiro a sinistra e non zero: il puntino che stacca il piede
       dalla navigazione sta li', e senza cadrebbe sopra al cerchietto. */
    width: clamp(60px, 17vw, 80px);
    padding: 0 var(--dt-sp-1) 0 var(--dt-sp-4);
    align-self: stretch;
  }
  .dt-app__sidefoot > .dt-iconbtn { display: none; }
  .dt-sideuser {
    flex-direction: column;
    justify-content: center;
    gap: var(--dt-sp-1);
    width: 100%;
    height: 100%;
    padding: var(--dt-sp-2) 2px;
  }
  .dt-sideuser__testo { display: none; }
  .dt-sideuser__breve {
    display: block;
    max-width: 100%;
    font-size: var(--dt-fs-xs);
    line-height: 1.15;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* ---- Modali: il foglio intero -----------------------------------------

     La scheda di un blocco e' la maschera piu' lunga del programma, e su un
     telefono la si compila in piedi su una scala. Dentro a un riquadro con
     l'aria intorno restavano seicento pixel di altezza utile su ottocento, e
     in una finestra di seicento si arriva a "Dove" solo scorrendo. A tutto
     schermo il foglio e' il foglio.
     Sale dal basso invece di apparire al centro: e' da la' che arriva il
     pollice, ed e' il verso in cui si chiude. */
  .dt-modal__backdrop { padding: 0; place-items: stretch; }
  .dt-modal {
    width: 100%;
    max-width: none;
    height: 100%;
    max-height: none;
    border: 0;
    border-radius: 0;
    animation: dt-sale var(--dt-t-med);
  }
  .dt-modal__head {
    padding: var(--dt-sp-4) var(--dt-sp-5);
    padding-top: calc(var(--dt-sp-4) + env(safe-area-inset-top, 0px));
  }
  .dt-modal__body { padding: var(--dt-sp-5); }
  .dt-modal__avviso { padding: var(--dt-sp-4) var(--dt-sp-5) 0; }
  .dt-modal__foot {
    padding: var(--dt-sp-4) var(--dt-sp-5);
    padding-bottom: calc(var(--dt-sp-4) + env(safe-area-inset-bottom, 0px));
  }
  /* Due tasti in fondo a un foglio si dividono la riga: cosi' stanno dove il
     pollice arriva senza spostare la mano, invece che appallottolati a destra. */
  .dt-modal__foot > .dt-btn { flex: 1 1 auto; }

  /* ---- Il resto ---------------------------------------------------------- */

  /* Le linguette sono il modo con cui si cambia scheda, e a sei pixel sopra e
     sotto il testo la fascia e' alta trentadue: si prende, ma mirando. Qui
     l'altezza la detta il pollice e non il testo. */
  .dt-tabs__item {
    min-height: var(--dt-h-tocco);
    padding-top: 0;
    padding-bottom: 0;
    padding-inline: var(--dt-sp-5);
  }

  /* Le griglie con l'etichetta a sinistra vanno in colonna: centodieci pixel
     di etichetta piu' un campo, a questa larghezza, e' un campo largo un
     pollice. */
  .dt-formgrid { grid-template-columns: minmax(0, 1fr); gap: var(--dt-sp-2); }
  .dt-formgrid > .dt-field__label { justify-content: flex-start; text-align: left; }
  /* I riquadri dei numeri: due per riga e larghi uguali. Il minimo da monitor
     (centocinquanta pixel) ne faceva stare uno solo, e lasciati alla loro
     misura naturale venivano di larghezze diverse uno sopra l'altro — che di
     una fila di numeri e' la cosa che si nota per prima. */
  .dt-kpi {
    flex: 1 1 40%;
    min-width: 0;
    padding: var(--dt-sp-4);
  }

  /* Gli avvisi passeggeri stanno sopra alla barra bassa, non sopra alle sue
     voci: in basso a destra coprivano "Account" e il tasto che segna un'ora,
     cioe' proprio quello che si stava per premere dopo aver salvato. E prendono
     la riga intera, perche' a 390px un riquadro da 340 e' quasi tutta. */
  .dt-toaster {
    left: var(--dt-sp-3);
    right: var(--dt-sp-3);
    bottom: calc(var(--dt-barra-bassa-h) + var(--dt-sp-3));
    max-width: none;
  }
}

/* ===========================================================================
   Il catalogo a scala
   ===========================================================================
   Articoli e tendaggi stanno su quattro gradini — reparto, famiglia, prodotto,
   modello — e i due larghi non sono colonne: sono la fascia che apre ogni
   gruppo. Ripeterli su ogni riga farebbe un elenco in cui tutte le righe
   cominciano uguale e il nome, che e' l'unica cosa che si sta cercando, finisce
   spinto a destra. */

/* --------------------------------------------------------------------------
   La barra dell'elenco: cercare, filtrare, e gli attrezzi della schermata
   --------------------------------------------------------------------------
   Una fascia sola, sotto alla testata e dentro allo stesso riquadro, uguale in
   tutte le schede dei Lavori, del Catalogo e degli Account.

   Prima non c'era una regola. Due schede si cercavano da qui, due dalla riga
   del titolo — dove il campo restava largo un pollice fra un filtro e un tasto,
   e il segmentato dei riferimenti si spezzava su due righe a milleduecento
   pixel — e due non si cercavano affatto. Tre posti per la stessa cosa, e chi
   passava da una linguetta all'altra doveva ritrovare il campo ogni volta.

   Adesso la riga del titolo tiene **una primaria e nient'altro** — «Nuovo
   negozio», «Nuova attivita'» — e tutto il resto scende qui: il campo che
   stringe l'elenco a sinistra, i filtri che valgono su tutto, e in fondo, oltre
   un filo, gli attrezzi della schermata (aprire l'albero, portarlo via,
   riportarlo dentro). Da sinistra a destra si va da «quale riga cerco» a «cosa
   faccio a questo elenco», che e' anche l'ordine in cui le due cose servono. */
.dt-barra-elenco {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-3);
  padding: var(--dt-sp-4) var(--dt-sp-6);
  border-bottom: 1px solid var(--dt-border-soft);
  background: var(--dt-surface);
}
/* Il campo prende quello che avanza e si stringe per primo: una casella di
   ricerca stretta si scrive uguale, una fila di filtri spezzata in due si
   legge peggio. */
.dt-barra-elenco__cerca {
  flex: 1 1 12rem;
  min-width: 0;
}
.dt-barra-elenco__cerca .dt-inputgroup { width: 100%; }
.dt-barra-elenco__filtri,
.dt-barra-elenco__attrezzi {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-3);
  flex: 0 0 auto;
}
/* Il filo che stacca gli attrezzi dai filtri: di la' si sceglie cosa vedere,
   di qua si tocca l'elenco. */
.dt-barra-elenco__filo {
  flex: 0 0 1px;
  align-self: stretch;
  margin: 0 var(--dt-sp-2);
  background: var(--dt-border-soft);
}
/* Stretta, il campo si prende la sua riga e gli attrezzi scendono sotto: sono
   due cose diverse, e schiacciarle sulla stessa riga vorrebbe dire un campo di
   ricerca largo tre lettere. */
@media (max-width: 760px) {
  .dt-barra-elenco { flex-wrap: wrap; }
  .dt-barra-elenco__cerca { flex: 1 1 100%; }
  .dt-barra-elenco__filo { display: none; }
  .dt-barra-elenco__attrezzi { margin-left: auto; }
}

/* --------------------------------------------------------------------------
   L'elenco a binario: la tendina, la voce, i comandi
   --------------------------------------------------------------------------
   Un catalogo e' un albero, e un riferimento non e' una riga ma un cancello con
   appeso del lavoro: per questo la riga si apre e quello che contiene sta sotto,
   rientrato. Quello che qui e' cambiato non e' che si apra — e' **dove
   comincia**. Ogni riga, di ogni elenco di queste schermate, comincia con le
   stesse corsie: la maniglia, la freccia, e il vuoto che ne tiene il posto
   quando non c'e' ne' l'una ne' l'altra. Prima le corsie andavano e venivano
   riga per riga — una sezione con la maniglia, la fila «senza sezione» senza,
   un riferimento con la freccia e la sua commessa con niente — e il bordo
   sinistro dell'elenco era una scaletta storta in cui non si incolonnava
   nulla.

   Da questo viene il **binario**: il filo verticale che regge un piano
   dell'albero cade a mezza corsia dal bordo della riga che l'ha aperto, cioe'
   sotto al segno che si e' premuto per aprirlo. Quello che si vede e' che le
   righe di dentro pendono da quella riga li', e non che sono un secondo elenco
   che comincia piu' a destra.

   Come in `.dt-piega`, la pancia passa da `0fr` a `1fr` sugli stessi nodi: e'
   l'unico modo di arrivare all'altezza vera senza misurarla in JavaScript e
   senza un `max-height` a occhio. */

/* Il contenitore dell'albero: un filo fra un ramo e l'altro e niente intorno.
   Sta dentro a un `.dt-card__body--flush`, che il bordo ce l'ha gia'. */
.dt-albero > .dt-tendina + .dt-tendina,
.dt-tendina + .dt-tendina,
.dt-albero > .dt-voce + .dt-voce { border-top: 1px solid var(--dt-border-soft); }

/* ===== La costola: come si vede che una cartellina e' aperta =====
   E' la cosa che nella vecchia grafica non si vedeva. Aperta e chiusa si
   distinguevano per una freccia da quattordici pixel che ruotava, e quello che
   la cartellina conteneva pendeva da un filo di un pixel che cominciava *sotto*
   alla riga che l'aveva aperta — cioe' staccato da lei. Con tre piani si
   contavano tre fili identici ai fili che separano le righe, sullo stesso
   grigio e nella stessa pagina: da qui «confusionarie».

   La costola e' quel filo portato a due pixel e **tirato su fino a comprendere
   la testa**. Una cartellina aperta e' una staffa: il coperchio, il fianco, il
   piedino. Quello che ci sta dentro non e' un secondo elenco che comincia piu'
   a destra — e' roba tenuta da quella riga li', e si vede.

   Chiusa non ha niente: il posto dei due pixel lo tiene un bordo trasparente,
   cosi' aprire non sposta di un capello quello che c'e' scritto. Un catalogo
   quasi tutto chiuso resta la pagina bianca di prima, e le costole che si
   vedono sono esattamente le cartelline che qualcuno ha aperto. E' l'opposto
   della fascia grigia sulle sezioni, che si provo' e si tolse: quella tingeva
   anche quello che nessuno aveva chiesto di vedere. */
.dt-tendina { position: relative; }
/* Il fianco. Non tocca il bordo del riquadro — sei pixel di stacco — se no
   sull'ultimo piano si legge come un bordo di riquadro ispessito invece che
   come il fianco di qualcosa che sta li' dentro. */
.dt-tendina--aperta::before,
.dt-tendina--aperta::after {
  content: "";
  position: absolute;
  left: var(--dt-sp-3);
  background: var(--dt-border-strong);
  border-radius: 1px;
}
.dt-tendina--aperta::before {
  top: 0;
  bottom: 0;
  width: 2px;
}
/* Il piedino: dove il gruppo finisce. Senza, una cartellina che si chiude e
   quella che ricomincia sotto sono la stessa cosa — il fianco smette e basta —
   e per sapere se la riga dopo sta ancora dentro bisogna risalire a cercare i
   rientri. */
.dt-tendina--aperta::after {
  bottom: 0;
  width: 9px;
  height: 2px;
}
.dt-tendina__barra {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-3);
  /* Lo stesso passo di una voce: una sezione e una cosa sono due righe dello
     stesso elenco, e una sezione col sottotitolo — "Senza sezione", un
     riferimento col suo indirizzo — era alta quattro pixel piu' di una senza.
     Vedi `--dt-riga-h`. */
  min-height: var(--dt-riga-h);
  padding: 0 var(--dt-riga-x);
  background: var(--dt-surface);
}
/* Il nome di una cartellina aperta va a inchiostro pieno, quello di una chiusa
   sta un tono sotto. Non e' decorazione: e' la stessa distinzione della
   costola, detta dove l'occhio sta gia' guardando — sul nome. */
.dt-tendina--aperta > .dt-tendina__barra .dt-tendina__titolo { color: var(--dt-text); }
.dt-tendina__titolo { color: var(--dt-text-2); }
/* **Chi contiene e chi sta dentro si distinguono nella corsia, non dal fondo.**
   Una sezione ci tiene la freccia, una cosa ci tiene la sua faccia; non ci sono
   righe che hanno tutte e due, e non c'e' altro da imparare. Il fondo resta
   bianco per tutti, come nei riferimenti: le sezioni tinte di grigio facevano
   di un catalogo aperto mezzo schermo di fasce con dentro qualche riga chiara,
   e il grigio finiva per pesare piu' della cosa che doveva dire.
   Il resto della gerarchia lo dicono il peso del nome — reparto, famiglia,
   ripiano — e il binario che regge ogni piano. */
.dt-tendina__barra:hover {
  background-image: linear-gradient(var(--dt-hover), var(--dt-hover));
}

/* Il tasto che apre si prende tutta la riga tranne i comandi: su un elenco si
   preme il nome, non la freccia da otto pixel. */
.dt-tendina__scatto {
  display: flex;
  align-items: center;
  /* La freccia e' il segno di questa riga: si stacca dal nome come il segno di
     una voce si stacca dal suo. */
  gap: var(--dt-corsia-testo);
  flex: 1 1 auto;
  min-width: 0;
  min-height: var(--dt-h-tocco);
  padding: var(--dt-sp-2) 0;
  border: 0;
  background: transparent;
  color: var(--dt-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.dt-tendina__scatto:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--dt-accent-border);
}
/* La corsia del segno: la seconda colonna di ogni riga d'elenco. Ci sta la
   freccia se la riga si apre, il segno che la riga porta con se' — la
   campitura di un'attivita' — se ne ha uno, e il vuoto se non ha ne' l'una ne'
   l'altro. Larga sempre uguale, che e' tutto il punto. */
.dt-tendina__freccia,
.dt-corsia {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 var(--dt-corsia);
  align-self: stretch;
}
/* La faccia di una persona sta nella corsia con la stessa misura del segno di
   una cosa e della campitura di un negozio. Tre facce di tre misure diverse in
   tre linguette diverse sono esattamente quello che si e' venuti a togliere:
   la corsia e' una colonna sola, e chi la guarda scorrendo deve trovarci
   sempre un segno grande uguale. */
/* La corsia del segno: e' l'ultima prima del nome, e si stacca. La corsia
   della presa no — presa e segno sono due segni di fila, e allontanarli
   spezzerebbe in due il bordo sinistro della riga. */
.dt-corsia--segno { margin-right: calc(var(--dt-corsia-testo) - var(--dt-sp-3)); }
.dt-corsia > .dt-avatar {
  width: var(--dt-corsia);
  height: var(--dt-corsia);
  font-size: var(--dt-fs-xs);
}
.dt-tendina__freccia {
  color: var(--dt-text-3);
  transform: rotate(-90deg);
  transition: transform var(--dt-t-med), color var(--dt-t-fast);
}
.dt-tendina__barra:hover .dt-tendina__freccia { color: var(--dt-text-2); }
.dt-tendina--aperta > .dt-tendina__barra > .dt-tendina__scatto .dt-tendina__freccia {
  transform: rotate(0deg);
  color: var(--dt-text-2);
}
.dt-tendina__testo {
  display: flex;
  flex-direction: column;
  flex: 0 1 auto;
  min-width: 0;
}
.dt-tendina__titolo {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: var(--dt-fw-semibold);
}
/* Il reparto — il primo piano di un catalogo — si legge come l'intestazione di
   un elenco e non come un nome: e' l'unica riga che intitola invece di
   nominare. Sotto di lui non ci sono piu' tre pesi ma uno solo: a dire a che
   piano si sta ci pensano le costole, che si contano, e un terzo peso di
   carattere diceva la stessa cosa una seconda volta e peggio.
   Un nome di cosa — un riferimento, "Villa Rossi" — non entra in questa scala:
   non e' l'intestazione di niente, e scriverlo maiuscoletto lo trasformerebbe
   in un'etichetta. */
.dt-tendina--reparto > .dt-tendina__barra .dt-tendina__titolo {
  font-size: var(--dt-fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.dt-tendina__sotto {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--dt-fs-sm);
  color: var(--dt-text-3);
}
/* Il conto sta appiccicato al titolo e non in fondo alla riga, come gia' fa
   `.dt-piega`: e' il titolo che ne ha uno, e un numero dall'altra parte del
   riquadro — dopo i bollini, prima dei tastini, a un'ascissa diversa in ogni
   riga — non si capisce a che cosa si riferisca.
   Sulla riga del titolo e non in fondo al blocco di testo: sotto al nome c'e'
   l'indirizzo, che e' piu' lungo del nome, e un conto appoggiato al blocco
   intero finiva in fondo all'indirizzo — accanto a un numero di telefono, che
   e' l'ultimo posto in cui si vuole leggere un altro numero. */
.dt-tendina__capo {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-2);
  min-width: 0;
}
.dt-tendina__conto {
  flex: 0 0 auto;
  padding: 0 var(--dt-sp-3);
  border-radius: var(--dt-r-full);
  /* Un velo e non un grigio scritto: la pastiglia sta sul bianco di una riga e
     sulla fascia di una sezione, e un grigio fisso su una delle due sparisce.
     Cosi' e' sempre un gradino piu' scura di quello che ha sotto. */
  background: var(--dt-hover);
  color: var(--dt-text-2);
  font-size: var(--dt-fs-sm);
  font-weight: var(--dt-fw-medium);
  font-variant-numeric: tabular-nums;
  line-height: 18px;
}
/* I bollini stanno appoggiati ai comandi e non dietro al titolo: sono pochi e
   larghi quanto la parola che ci sta dentro, e attaccati al titolo ballavano
   da una riga all'altra. Da qui in poi la riga si legge da destra. */
.dt-tendina__segni {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-2);
  flex: 0 0 auto;
}
.dt-tendina__pancia {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dt-t-med);
}
.dt-tendina--aperta > .dt-tendina__pancia { grid-template-rows: 1fr; }
/* Nuda di proposito: e' la cella che si schiaccia, e con `border-box` un
   padding qui resterebbe aperto anche a tendina chiusa. */
.dt-tendina__dentro {
  overflow: hidden;
  min-height: 0;
}
/* Il rientro di un piano dell'albero. Il filo che lo reggeva se n'e' andato:
   adesso a reggerlo c'e' la costola della cartellina che l'ha aperto, che parte
   dalla sua testa e gli sta a fianco per tutta l'altezza. Due segni per la
   stessa cosa — un fianco e un filo, a due ascisse diverse — erano il motivo
   per cui non si capiva a che piano si stesse. */
.dt-tendina__corpo {
  position: relative;
  margin-left: var(--dt-passo);
  background: var(--dt-surface);
}

/* Una voce in fondo all'albero: il nome a sinistra, i dati misurati a destra.
   Non e' una tabella e non deve esserlo — le colonne che contano sono le
   ultime, e quelle restano incolonnate perche' hanno tutte la stessa misura in
   ogni riga dell'albero, dentro a qualunque ramo stiano.
   Le corsie di sinistra le tiene anche lei, vuote: una voce non si apre, ma se
   il suo nome cominciasse una corsia piu' a sinistra di quello della sezione
   che le sta accanto, i due nomi non starebbero in colonna — ed e' l'unica
   colonna che conta davvero, perche' e' quella che si legge. */
.dt-voce {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  /* Da destra si legge, e a destra restano: sulla prima riga il nome si prende
     lo spazio libero e questo non si vede, ma quando la riga va a capo — un
     telefono, due bollini larghi — la coda che scende sotto resta appoggiata al
     bordo destro invece di ricominciare da sinistra, dove sarebbe un riquadro
     sciolto all ascissa sbagliata. */
  justify-content: flex-end;
  /* Sei pixel fra una corsia e l'altra e fra la corsia e il nome, gli stessi
     della barra di una sezione: e' quella misura a tenere in colonna i nomi
     delle voci con quelli delle sezioni accanto. A quattro il segno di
     un'attivita' stava appiccicato alla sua etichetta. */
  gap: var(--dt-sp-2) var(--dt-sp-3);
  /* Il passo di tutte le righe di tutte le schede: vedi `--dt-riga-h`. Non e'
     un'altezza fissa perche' stretta la riga va a capo — i bollini scendono
     sotto ai comandi — e li' a essere cambiata e' la disposizione, non quanto
     si e' scritto dentro. */
  min-height: var(--dt-riga-h);
  padding: var(--dt-sp-2) var(--dt-riga-x);
}
/* Il filo si somma al passo, non se lo mangia. Le misure di questa pagina sono
   tutte `border-box`, quindi un bordo di un pixel viene contato *dentro*
   all'altezza minima: senza questa riga la prima voce di un elenco era alta un
   pixel piu' delle sue sorelle, che e' esattamente il genere di scarto per cui
   una fila di righe smette di sembrare una fila. Le sezioni non ne hanno
   bisogno: li' il filo sta sul contenitore (`.dt-tendina + .dt-tendina`), cioe'
   gia' fuori dalla barra. */
.dt-voce + .dt-voce {
  border-top: 1px solid var(--dt-border-soft);
  min-height: calc(var(--dt-riga-h) + 1px);
}
.dt-voce:hover { background-image: linear-gradient(var(--dt-hover), var(--dt-hover)); }
/* `flex-basis: 0` e non `auto`: in una riga che va a capo, a decidere se un
   pezzo ci sta e' la sua misura naturale — non quella a cui si e' disposto a
   stringersi. Il sottotitolo di una commessa naturale e' lungo mezza riga di
   testo, e con `auto` si portava a capo da solo trascinandosi dietro tutto il
   resto: la corsia restava sopra, sola, e il nome ricominciava dal bordo.
   Con base zero il nome si prende quello che avanza e si accorcia col
   puntolino, che e' quello che deve fare. */
.dt-voce__nome {
  flex: 1 1 0;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* **Il sottotitolo di una riga e' alto una riga, sempre.**
   Le due facce di un'attivita' — cosa si consegna, cosa torna indietro — sono
   due scritte e restano due: si leggono confrontandole, e appese di seguito
   sarebbero una fila sola di quattordici parole in cui non si vede dove
   finisce l'una. Ma stanno **in fila e non in colonna**, divise da un filo,
   come i due gruppi di una barra di comandi. In colonna erano la sola cosa che
   faceva l'elenco delle attivita' piu' alto di passo di tutti gli altri.
   Il filo, e non un punto o una barra battuta: un separatore scritto e' un
   carattere che si legge, e qui non c'e' niente da leggere fra le due — c'e'
   solo da vedere che sono due. */
.dt-voce__sotti {
  display: flex;
  align-items: baseline;
  min-width: 0;
  overflow: hidden;
}
.dt-voce__sotti > .dt-voce__sotto + .dt-voce__sotto {
  margin-left: var(--dt-sp-3);
  padding-left: var(--dt-sp-3);
  border-left: 1px solid var(--dt-border-soft);
}
.dt-voce__sotto {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--dt-fs-sm);
  color: var(--dt-text-3);
}
/* Chi cede per primo. La prima scritta e' quella che dice cos'e' quella riga —
   sulle attivita' e' la chiave piu' cosa si consegna — e le altre la
   completano: stringendo si accorciano tre volte piu' in fretta, cosi' a
   restare leggibile e' quella che si sta cercando. Con la stessa cedevolezza
   si riducevano a due monconi appaiati, che sono due cose non lette invece di
   una letta. */
.dt-voce__sotti > .dt-voce__sotto ~ .dt-voce__sotto { flex-shrink: 3; }

/* ===== Il nome e' il tasto =====
   Una regola sola, in tutte e sei le schede: **premere il nome apre quello che
   c'e' dentro**. Cosa ci sia dentro lo dice la corsia, che e' li' di fianco.
   Se c'e' la freccia, dentro c'e' un elenco, e il nome lo apre. Se c'e' la
   faccia — o se la corsia e' vuota — dentro c'e' la scheda, e il nome apre
   quella.

   Cosi' l'occhio se n'e' andato da cinque schede su sei. C'era, ed era il primo
   di quattro tastini in fondo alla riga: il gesto che si fa piu' spesso era il
   bersaglio piu' piccolo della riga, e stava dall'altra parte rispetto alla
   cosa che si voleva guardare. Resta solo dove il nome e' gia' preso — sui
   riferimenti, che si aprono *e* hanno una scheda.

   Niente aspetto da bottone: e' il nome di una riga, e incorniciarlo lo
   farebbe pesare piu' della riga che lo contiene. */
.dt-voce__apri {
  display: flex;
  flex-direction: column;
  justify-content: center;
  flex: 1 1 0;
  min-width: clamp(96px, 30%, 180px);
  align-self: stretch;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.dt-voce__apri--fermo { cursor: default; }
.dt-voce__apri:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--dt-accent-border);
  border-radius: var(--dt-r-sm);
}
.dt-voce__apri > .dt-voce__nome { flex: 0 1 auto; }

/* I bollini stanno appoggiati ai comandi, come sulla barra di una cartellina
   (`.dt-tendina__segni`): sono pochi, larghi quanto la parola che ci sta
   dentro, e attaccati al nome ballavano da una riga all'altra. Da qui in poi la
   riga si legge da destra, ed e' la stessa lettura in tutte e sei le schede. */
.dt-voce__bollini {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--dt-sp-2);
  /* Si stringe, e dentro i bollini vanno a capo fra loro. Con la base fissa
     erano loro a restare interi e a mandare a capo la barra dei comandi, che
     finiva su una riga sua in fondo a sinistra: un riquadro sciolto sotto alla
     riga, all'ascissa sbagliata. Due bollini larghi si impilano; la barra dei
     comandi resta dov'e' in tutte le altre righe. */
  flex: 0 1 auto;
  min-width: 0;
  margin-left: auto;
}
.dt-voce__bollini + .dt-comandi { margin-left: 0; }

/* Chi e' stato messo via si legge meno: c'e', e non e' quello che si sta
   cercando. La faccia no — quella resta piena, perche' e' come lo si
   riconosce. Vale su un account come su un articolo o un negozio: e' lo stesso
   interruttore, e non c'e' motivo che dica una cosa diversa a seconda della
   linguetta. */
.dt-voce--via .dt-voce__nome,
.dt-voce--via .dt-voce__dato,
.dt-voce--via .dt-voce__prezzo { color: var(--dt-text-3); }
/* Una tendina aperta e vuota deve dire perche' e cosa farci: lasciarla vuota
   fa sembrare che stia ancora caricando. */
.dt-vuoto-dentro {
  padding: var(--dt-sp-4) calc(var(--dt-riga-x) + var(--dt-corsia));
  font-size: var(--dt-fs-sm);
  color: var(--dt-text-3);
}
/* Il modello sta attaccato al nome ma non pesa come lui: e' quello che
   distingue due righe che si chiamano uguale, non quello che si cerca. */
.dt-voce__modello { color: var(--dt-text-3); }
/* Si stringono prima del nome: `min-width` sul nome fa cedere questi, e non il
   contrario. Un codice tagliato a meta' si legge lo stesso; un nome ridotto a
   "Tas…" non dice piu' niente, ed e' l'unica cosa per cui si sta guardando. */
.dt-voce__dato {
  flex: 0 1 clamp(48px, 9%, 72px);
  min-width: 0;
  overflow: hidden;
  /* Su una riga sola, sempre: un codice lungo che va a capo si porta dietro
     l'altezza della riga — quaranta righe di catalogo tutte da 48 pixel e in
     mezzo una da 96, che e' lo scarto per cui una fila smette di sembrare una
     fila. Tagliato col puntolino resta quello che si legge per primo, ed e'
     la stessa regola che il nome ha gia' qui sopra. */
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: var(--dt-fs-sm);
  color: var(--dt-text-3);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.dt-voce__nome { min-width: clamp(96px, 30%, 180px); }
.dt-voce__prezzo {
  flex: 0 0 clamp(72px, 12%, 96px);
  /* Stessa regola del dato qui sopra: una cifra grossa col simbolo appresso
     non si spezza fra il numero e l'euro. */
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: var(--dt-fs-sm);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
/* Stretti se ne vanno i dati misurati e resta il nome coi comandi: su un
   telefono l'unita' di misura e la posizione in elenco non sono quello per cui
   si e' aperto il catalogo. */
@media (max-width: 720px) {
  .dt-voce__dato { display: none; }
}
/* E sotto ai 560, dove i tastini passano al pollice e al testo restano due dita
   di riga, se ne va tutto quello che veniva dopo la prima scritta: due monconi
   di quattro lettere l'uno non sono due informazioni, sono nessuna. Resta la
   prima intera, che e' quella che dice di che riga si tratta — e la seconda
   faccia di un'attivita' si legge dov'e' scritta per esteso, cioe' nella sua
   scheda. Stessa regola dei dati misurati qui sopra, una soglia piu' giu'. */
@media (max-width: 560px) {
  .dt-voce__sotti > .dt-voce__sotto ~ .dt-voce__sotto { display: none; }
}

/* --------------------------------------------------------------------------
   La barra dei comandi di una riga
   --------------------------------------------------------------------------
   Un riquadro solo, non cinque tastini sciolti. Erano sciolti, tutti dello
   stesso grigio e della stessa forza del testo intorno, e su venti righe
   facevano una nuvola di segni lungo tutto il fianco destro dell'elenco: la
   cosa piu' rumorosa della schermata era il contorno. Qui sono un oggetto
   solo, uno per riga, sempre alla stessa ascissa: l'occhio ne conta venti
   uguali invece di cento sparsi, e chi cerca un comando sa gia' dov'e'.

   A riposo il riquadro e' un filo e i segni sono smorti; sulla riga sotto al
   dito il filo si fa vedere e i segni salgono di un tono. La forma non cambia
   mai — niente compare e niente sparisce — perche' un comando che si vede solo
   passandoci sopra col mouse su un tablet non esiste. */
.dt-comandi {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
  margin-left: auto;
  border: 1px solid var(--dt-border-soft);
  border-radius: var(--dt-r-md);
  background: transparent;
  color: var(--dt-text-3);
  transition: border-color var(--dt-t-fast), background var(--dt-t-fast),
    color var(--dt-t-fast);
}
.dt-voce:hover > .dt-comandi,
.dt-tendina__barra:hover > .dt-comandi,
.dt-comandi:focus-within {
  border-color: var(--dt-border);
  background: var(--dt-surface);
  color: var(--dt-text-2);
}
/* Dentro sono piatti: il riquadro ce l'ha gia' il gruppo, e un secondo bordo
   per tastino farebbe una scacchiera. Gli spigoli di testa e di coda seguono
   quelli del gruppo, meno il filo. */
.dt-comandi .dt-iconbtn {
  border: 0;
  border-radius: 0;
  color: inherit;
}
.dt-comandi > :first-child,
.dt-comandi > :first-child > .dt-iconbtn:first-child {
  border-top-left-radius: calc(var(--dt-r-md) - 1px);
  border-bottom-left-radius: calc(var(--dt-r-md) - 1px);
}
.dt-comandi > :last-child,
.dt-comandi > :last-child > .dt-iconbtn:last-child {
  border-top-right-radius: calc(var(--dt-r-md) - 1px);
  border-bottom-right-radius: calc(var(--dt-r-md) - 1px);
}
.dt-comandi .dt-iconbtn:hover { background: var(--dt-hover); color: var(--dt-text); }
/* Dentro a un elenco il rosso arriva quando ci si arriva sopra, non prima.
   Il cestino c'e' su ogni riga: venti cestini rossi in colonna sono la cosa piu'
   accesa della schermata, e quello che dicono — "qui si cancella" — lo dice gia'
   la forma del segno, su una riga sola come su venti. Reggerlo col colore a
   riposo vuol dire tingere di rosso l'unica colonna che non parla di lavoro.
   Vale anche per l'interruttore spento, e li' e' una correzione: "messo via" e'
   uno stato, non un gesto distruttivo, e a dirlo c'e' la crocetta al posto della
   spunta. */
.dt-comandi .dt-iconbtn--danger { color: inherit; }
.dt-comandi .dt-iconbtn--danger:hover:not(:disabled) {
  color: var(--dt-danger);
  background: var(--dt-danger-soft);
}
.dt-comandi .dt-iconbtn:disabled { color: var(--dt-text-3); }
/* Il filo che stacca la coda: quello che cancella non sta appiccicato a quello
   che apre. La coda e' `.dt-solo-largo`, cioe' proprio i gesti che sullo
   stretto se ne vanno — fondere e buttare — e il filo se ne va con loro senza
   che nessuno debba ricordarsene. E' un'ombra e non un bordo perche' il bordo
   sposterebbe i tastini di un pixel. */
.dt-comandi .dt-solo-largo > .dt-iconbtn:first-child {
  box-shadow: inset 1px 0 0 var(--dt-border-soft);
}

/* I due tastini di servizio, appoggiati sopra all'account in fondo alla barra.
   E' una barra di comandi come le altre — stesso riquadro, stessi tastini
   piatti, stesso filo a dividerli — e per questo si scrive addosso a
   `.dt-comandi` invece di rifarne una. Sta qui e non su nella barra laterale
   proprio per quello: le poche righe che seguono correggono quelle sopra, e
   scritte prima perderebbero.

   Il tratteggio e' l'unica cosa che cambia, e non e' un vezzo: e' un attrezzo
   di passaggio — serve a chi sta segnalando un problema, non a chi lavora — e
   il filo spezzato lo dice senza doverci scrivere sopra "debug".

   Il numero alto e' il punto della faccenda: quando c'e' una modale aperta il
   velo copre tutto, e quello e' esattamente il momento in cui serve
   fotografare. Sta sopra anche al suggerimento, che e' il piu' alto del
   programma. Funziona perche' ne' `.dt-app` ne' la barra aprono un contesto
   d'impilamento: il numero si confronta con quello del velo, non con quello di
   un antenato. */
.dt-debug {
  position: relative;
  z-index: calc(var(--dt-z-tooltip) + 100);
  align-self: flex-start;
  margin: 0 var(--dt-sp-5) var(--dt-sp-3);
  border-style: dashed;
  border-color: var(--dt-border-strong);
}
.dt-debug:hover,
.dt-debug:focus-within {
  background: var(--dt-surface);
  color: var(--dt-text-2);
}
.dt-debug .dt-iconbtn + .dt-iconbtn {
  box-shadow: inset 1px 0 0 var(--dt-border-strong);
}

/* Sullo stretto la barra non e' piu' una colonna ma una fascia a slot, e li'
   ogni slot e' una schermata da raggiungere col pollice. Un attrezzo di
   servizio non ne vale uno: si fotografa e si scrive del problema da dove si
   sta lavorando davvero, cioe' alla scrivania. */
@media (orientation: portrait), (max-width: 820px) {
  .dt-debug { display: none; }
}

/* --------------------------------------------------------------------------
   Il trascinamento: dove sta una riga si dice spostandola
   --------------------------------------------------------------------------
   Prima "dentro a quale sezione" e "in che posizione" erano due caselle in una
   maschera: una tendina coi percorsi scritti per esteso e un numero. Sono due
   traduzioni di una cosa che si ha gia' davanti, e per farle bisognava chiudere
   l'elenco, aprire una scheda, e tornare a guardare se era venuto come si
   voleva. Qui la risposta e' il gesto: si prende la riga e la si posa dove va.

   Tre segni, e ognuno risponde a una domanda diversa. La **maniglia** dice che
   quella riga si sposta e da dove si prende. Il **filo col nodo** dice fra
   quali due righe finirebbe — e a che piano, perche' comincia dal binario di
   quel piano invece che dal bordo della schermata. La **corsia accesa** dice
   dentro a quale sezione entrerebbe. Tutti e tre nel blu di `--dt-info`, che in
   questa interfaccia quasi tutta grigia e' l'unico colore che non vuol dire ne'
   allarme ne' conferma: vuol dire soltanto «qui». */

/* La maniglia si vede sempre, non solo passandoci sopra col mouse: su un
   telefono non c'e' nessun "passarci sopra", e una maniglia che compare solo
   col mouse e' una maniglia che sul telefono non esiste. Sottovoce pero' —
   sono tante quante le righe, e a piena forza sarebbero una colonna di
   puntini che grida piu' dei nomi. */
.dt-maniglia {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 var(--dt-corsia);
  /* Alta quanto la riga, e non un'altezza sua: si tira su da se' (`stretch`) e
     il pollice ce l'ha gia' dentro, perche' una riga non scende sotto a
     `--dt-riga-h`. Con un minimo suo era lei a decidere il passo delle righe
     che si trascinano — un pixel piu' alte delle altre — e le sei schede
     tornavano a due misure. */
  align-self: stretch;
  color: var(--dt-text-3);
  opacity: 0.45;
  cursor: grab;
  /* Da qui il gesto e' dell'applicazione e non del browser. Senza, il primo
     movimento del dito se lo prende lo scorrimento e la riga non parte mai —
     ed e' solo su questa corsia: il resto della riga deve continuare a
     scorrere, se no un elenco lungo non si sfoglia piu'. */
  touch-action: none;
  transition: opacity var(--dt-t-fast), color var(--dt-t-fast);
}
.dt-maniglia:hover {
  opacity: 1;
  color: var(--dt-text-2);
}
.dt-maniglia:active {
  cursor: grabbing;
}
/* I puntini di una riga che non si sposta: si vedono uguali a quelli di una
   che si sposta — e' tutto il punto, il bordo sinistro non si interrompe
   passando di scheda in scheda — ma non fanno niente e non promettono niente.
   Da fermi sono identici, ed e' cosi' che li si incontra scorrendo un elenco;
   avvicinandoci la mano non si accendono e non cambiano freccia, che e' dove
   la differenza si scopre e dove non costa niente saperla.
   `touch-action` torna quello di tutti: la maniglia vera si prende il gesto
   del dito perche' ci deve partire un trascinamento, e questa senza il ritorno
   sarebbe una striscia di ventidue pixel in cui un elenco non scorre. */
.dt-maniglia--finta,
.dt-maniglia--finta:hover {
  color: var(--dt-text-3);
  opacity: 0.45;
  cursor: inherit;
  touch-action: auto;
}

/* La riga che si ha in mano resta al suo posto e sbiadisce: toglierla di mezzo
   farebbe saltare in su tutto quello che ha sotto, e il posto in cui si sta
   mirando si sposterebbe da solo mentre ci si mira. Sbiadisce tutta insieme —
   `opacity` prende anche i figli, quindi non c'e' modo di tenerne acceso uno — e
   quello che si ha in mano lo dice l'etichetta attaccata al dito, che ha il blu
   sul fianco. */
.dt-presa {
  opacity: 0.45;
  background: var(--dt-surface-2);
}

/* Il filo: fra queste due righe, e a questo piano. Comincia dal binario del
   piano su cui cadrebbe — non dal bordo della schermata — perche' "in fondo a
   questa sezione" e "dopo questa sezione" sono due posti diversi che con un
   filo lungo tutta la riga si disegnavano uguali. Il nodo di testa e' il punto
   in cui si aggancia. */
.dt-cade {
  position: relative;
}
.dt-cade--prima::after,
.dt-cade--dopo::after {
  content: "";
  position: absolute;
  left: var(--dt-riga-x);
  right: var(--dt-riga-x);
  height: 2px;
  border-radius: 1px;
  background: var(--dt-info);
  pointer-events: none;
}
.dt-cade--prima::before,
.dt-cade--dopo::before {
  content: "";
  position: absolute;
  left: calc(var(--dt-riga-x) - 2px);
  width: 7px;
  height: 7px;
  border-radius: var(--dt-r-full);
  background: var(--dt-info);
  pointer-events: none;
}
.dt-cade--prima::after { top: -1px; }
.dt-cade--prima::before { top: -4px; }
.dt-cade--dopo::after { bottom: -1px; }
.dt-cade--dopo::before { bottom: -4px; }
/* Dentro: non un filo ma tutta la riga accesa e la corsia piena, perche' quello
   che si sta per fare non e' infilarsi fra due cose, e' entrare in una. Scritta
   dopo il `:hover` della barra e con la stessa forza, cosi' vince: passarci
   sopra col dito pieno non deve dire la stessa cosa che passarci sopra a mani
   vuote. */
.dt-voce.dt-cade--dentro,
.dt-tendina__barra.dt-cade--dentro {
  background: var(--dt-info-soft);
  box-shadow: inset 3px 0 0 var(--dt-info);
}

/* Quello che si ha in mano, attaccato al dito.
   Serve piu' dell'evidenziare la riga di partenza: dopo mezza schermata di
   scorrimento quella riga non si vede piu', e senza niente sotto al dito non si
   sa piu' cosa si sta posando. Non riceve tocchi: se li ricevesse sarebbe lei
   la cosa sotto al dito a ogni movimento, e non si troverebbe mai nient'altro. */
.dt-ombra {
  position: fixed;
  z-index: var(--dt-z-modal);
  display: flex;
  align-items: center;
  gap: var(--dt-sp-2);
  max-width: min(260px, 60vw);
  padding: var(--dt-sp-2) var(--dt-sp-3);
  /* Scostata dal dito, se no sta sotto al polpastrello e non si legge. */
  transform: translate(14px, 12px);
  border: 1px solid var(--dt-border);
  /* Lo stesso blu del filo e della corsia: e' la stessa cosa che si sta
     facendo, vista dall'altra parte. */
  border-left: 3px solid var(--dt-info);
  border-radius: var(--dt-r-md);
  background: var(--dt-surface);
  box-shadow: var(--dt-shadow-md);
  color: var(--dt-text);
  font-size: var(--dt-fs-sm);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
}
.dt-ombra > :first-child {
  flex: 0 0 auto;
  color: var(--dt-info);
}
.dt-ombra > span {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* La faccia di una cosa, in miniatura: la sua campitura col suo segno dentro.
   Ce l'hanno tutte e tre le anagrafiche del catalogo — attivita', articoli,
   tipi di tendaggio — perche' sono tre elenchi ma un solo paio d'occhi: chi in
   giornata riconosce il montaggio dall'ambra non ha motivo di dover leggere
   "Tassello SX 8x40" per trovare il tassello.
   Sull'attivita' era una colonna di tabella tinta per intero, larga un pollice
   e piu' forte di ogni altra cosa nella schermata. Ma quello che l'operatore
   avra' davanti non e' una fascia di colore: e' un segno dentro a una
   campitura, e questa e' quella campitura rimpicciolita — stesso fondo, stesso
   bordo, stesso segno.
   In elenco fa anche un secondo lavoro, ed e' quello che tiene in piedi
   l'albero: **chi ha la faccia e' una cosa, chi ha la freccia e' un posto in
   cui le cose stanno.** Le due occupano la stessa corsia, e non ci sono righe
   che hanno tutte e due.
   Tonalita' e carica arrivano dallo `style` inline, come per i blocchi e per la
   tavolozza: fin dove ogni tonalita' arriva lo sa chi ha scelto i colori, non
   il foglio di stile. */
.dt-tinta-segno {
  --dt-blocco-c: calc(var(--dt-blocco-croma, var(--dt-tinta-c)) * var(--dt-tinta-c-scala));
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: var(--dt-corsia);
  height: var(--dt-corsia);
  border-radius: var(--dt-r-sm);
  background: oklch(
    calc(var(--dt-tinta-l) + var(--dt-blocco-luce, 0%))
    var(--dt-blocco-c)
    var(--dt-blocco-tinta)
  );
  color: oklch(var(--dt-tinta-l-testo) var(--dt-tinta-c-testo) var(--dt-blocco-tinta));
}
/* Senza tinta non c'e' un colore da mostrare, ma la campitura resta: e' la
   forma a dire che quella riga e' una cosa da riconoscere, e una forma che
   sparisce nel caso normale — che nel listino e' quasi ogni riga — non dice
   piu' niente. Qui il fondo e' bianco, ed e' **il solo posto dove ci va un
   filo**: senza, un quadrato bianco sul bianco della scheda non e' un
   quadrato. Le campiture tinte il filo non ce l'hanno, che il colore si dice
   da se'. Stesso vestito del cerchietto di chi il colore non se l'e' visto
   scegliere. */
.dt-tinta-segno--nuda {
  background: var(--dt-surface);
  border: 1px solid var(--dt-border);
  color: var(--dt-text-3);
}
/* Una tinta che nella tavolozza non c'e' non ha campitura da mostrare: e' un
   dato da sistemare, non un colore da riconoscere, e si scrive. */
.dt-tinta-segno--rotta {
  background: var(--dt-warn-soft);
  color: var(--dt-warn);
}
/* L'iniziale di un negozio, al posto del simbolo di una cosa: stessa
   campitura, stessa misura, e dentro l'unica cosa che cambia. La misura viene
   dalla corsia e non da chi disegna, se no la stessa faccia esce di due
   grandezze in due elenchi che si somigliano. */
.dt-tinta-segno__lettera {
  font-size: calc(var(--dt-corsia) * 0.5);
  font-weight: var(--dt-fw-bold);
  line-height: 1;
  user-select: none;
}

/* Il tastino che apre una riga scritta a mano.
   Piatto e sottovoce: sta sotto alla tendina perche' e' quello che si fa DOPO
   aver guardato e non aver trovato, e un tasto pieno la' sotto sarebbe una
   scorciatoia per riscrivere roba che in catalogo c'e' gia'. */
.dt-fuori-catalogo {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-2);
  align-self: flex-start;
  padding: var(--dt-sp-2) var(--dt-sp-3);
  border: 0;
  border-radius: var(--dt-r-md);
  background: none;
  color: var(--dt-text-3);
  font: inherit;
  font-size: var(--dt-fs-sm);
  text-align: left;
  cursor: pointer;
  transition: color var(--dt-t-fast), background var(--dt-t-fast);
}
.dt-fuori-catalogo:hover { color: var(--dt-text); background: var(--dt-hover); }

/* Una riga di materiale scritta a mano: il listino qui non c'e', quindi nome,
   unita' e prezzo sono campi. Due piani e non uno — il nome si prende la riga
   sua perche' e' lungo quanto una frase, e sotto restano i tre numeri
   incolonnati. In una fila sola su un telefono il prezzo andava a capo da solo
   e il −/+ cambiava posto da una riga all'altra. */
.dt-riga-fuori {
  display: flex;
  flex-direction: column;
  gap: var(--dt-sp-2);
  /* I fianchi sono quelli di una riga d'elenco: sta in fila con le righe di
     listino, e un rientro suo la farebbe leggere come un'altra cosa. Il
     riquadro intorno ce l'ha gia' `.dt-presi`. */
  padding: var(--dt-sp-2) var(--dt-riga-x);
  background: var(--dt-surface);
}
.dt-riga-fuori__testa {
  display: flex;
  align-items: center;
  gap: var(--dt-sp-3);
  min-height: var(--dt-h-tocco);
}
/* Il nome mangia lo spazio che avanza; il bollino e la X no: sono loro che il
   dito deve trovare sempre nello stesso punto, riga dopo riga. */
.dt-riga-fuori__testa > .dt-input { flex: 1 1 auto; min-width: 0; }
/* Unita' e prezzo sono misurati e la quantita' si prende quello che avanza:
   sono tre campi al passo delle cifre che ci vanno dentro — due lettere, un
   prezzo, un numero col −/+ — e un prezzo largo mezza riga per cinque cifre
   spingerebbe il −/+ fuori dal pollice. E' la stessa scelta gia' fatta su
   `.dt-riga-ordine`, dove a misura sta la quantita'.

   Va a capo da se' invece che a una soglia: la scheda del blocco e' dentro a
   una maschera, e quanto e' larga la maschera non e' quanto e' larga la
   finestra. Una media query misurerebbe la cosa sbagliata e romperebbe la riga
   dove non serviva, o non la romperebbe dove serviva. */
.dt-riga-fuori__conti {
  display: flex;
  flex-wrap: wrap;
  gap: var(--dt-sp-2);
  align-items: center;
}
.dt-riga-fuori__conti > * { min-width: 0; }
/* L'unita' non si muove (due lettere e una freccia), il prezzo si prende quel
   che avanza, la quantita' resta larga quanto sulla riga di listino qui sopra:
   cosi' il −/+ cade sempre nella stessa colonna, riga dopo riga, ed e' quello
   che il pollice cerca senza guardare. Quando scende sotto, `margin-left:auto`
   la tiene lo stesso a destra invece di rimandarla a capo riga. */
.dt-riga-fuori__conti > :nth-child(1) { flex: 0 0 clamp(64px, 18%, 84px); }
.dt-riga-fuori__conti > :nth-child(2) { flex: 1 1 clamp(96px, 26%, 128px); }
.dt-riga-fuori__conti > :nth-child(3) {
  flex: 0 0 clamp(132px, 34%, 160px);
  margin-left: auto;
}
.dt-riga-fuori__nota {
  font-size: var(--dt-fs-xs);
  color: var(--dt-text-3);
}

@keyframes dt-sale { from { opacity: 0; transform: translateY(14px); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* --------------------------------------------------------------------------
   Il cerchietto di una persona
   --------------------------------------------------------------------------
   Gli account non hanno piu' una grafica loro: sono un elenco a corsie come i
   negozi, i riferimenti e il catalogo — vedi `.dt-albero` e `.dt-voce`. Quello
   che era il `.dt-ruolino`, con la sua riga-tasto e i suoi bollini, e' stato
   sciolto li' dentro: era l'ultima schermata dell'ufficio che si disegnava da
   se', e la sua idea buona — toccare il nome per leggere la scheda — e' passata
   a tutte le altre (`.dt-voce__apri`).

   Resta qui il cerchietto, che e' roba della faccia e non dell'elenco. */

/* Il cerchietto di chi il colore se l'e' visto scegliere: la campitura della
   tavolozza, la stessa dei blocchi e dei negozi, con sopra la scritta scura
   che quella campitura si porta dietro. */
.dt-avatar--tinta {
  background: oklch(
    calc(var(--dt-tinta-l) + var(--dt-blocco-luce, 0%))
    var(--dt-blocco-c, var(--dt-tinta-c))
    var(--dt-blocco-tinta)
  );
  color: oklch(var(--dt-tinta-l-testo) var(--dt-tinta-c-testo) var(--dt-blocco-tinta));
}
/* E il cerchietto di tutti gli altri: bianco, col filo intorno e l'iniziale
   smorta. Il bianco e' quello del tema — sul chiaro e' bianco, sullo scuro e'
   il bianco che ha lui — perche' un `#fff` scritto a mano sul tema scuro
   sarebbe l'unica macchia accesa della pagina.

   Prima qui usciva un pastello calcolato dal nome. Nessuno l'aveva scelto e
   nessuno poteva cambiarlo: due colleghi finivano per caso sulla stessa
   tonalita' senza rimedio, e sopratutto erano tinti *tutti*, cioe' nessuno.

   Il filo e' un `border` e non un'ombra: nelle file accavallate l'ombra e' gia'
   presa dall'anello che stacca una faccia dall'altra, e un secondo `box-shadow`
   la cancellerebbe — un cerchietto bianco con l'anello bianco, sul bianco, non
   e' piu' un cerchietto. Il bordo non tocca la misura, che le facce sono tutte
   `border-box`. */
.dt-avatar--senza {
  background: var(--dt-surface);
  border: 1px solid var(--dt-border);
  color: var(--dt-text-3);
  font-weight: var(--dt-fw-semibold);
}
.dt-avatar {
  --dt-blocco-c: calc(var(--dt-blocco-croma, var(--dt-tinta-c)) * var(--dt-tinta-c-scala));
}


/* Stampa: sul foglio deve restare il contenuto e nient'altro.
   Sparisce quel che serve solo a comandare l'applicazione (barra laterale,
   pulsanti, avvisi passeggeri) e i colori tornano nero su bianco, perche'
   il tema scuro in stampa e' illeggibile e svuota la cartuccia. */
@media print {
  :root, [data-tema] {
    --dt-bg: #fff;
    --dt-surface: #fff;
    --dt-surface-2: #fff;
    --dt-surface-inset: #fff;
    --dt-text: #000;
    --dt-text-2: #333;
    --dt-text-3: #555;
    --dt-border: #bbb;
    --dt-border-strong: #888;
  }

  .dt-app__side,
  .dt-toolbar,
  .dt-btn,
  .dt-iconbtn,
  .dt-toaster,
  .dt-modal__backdrop,
  .dt-segmented,
  .dt-tabs,
  .dt-td--actions,
  /* Il filo verticale separa dei comandi, e i comandi sulla carta non ci sono:
     restava una stanghetta in mezzo al niente, in cima al foglio. */
  .dt-divider--v,
  .dt-nostampa {
    display: none !important;
  }

  .dt-app,
  .dt-app__main,
  .dt-app__body {
    display: block;
    height: auto;
    overflow: visible;
  }

  .dt-card,
  .dt-kpi {
    border-color: #bbb;
    box-shadow: none;
    break-inside: avoid;
  }

  .dt-table { max-height: none; }
  .dt-table tr { break-inside: avoid; }
  .dt-table thead th { border-bottom: 1px solid #888; }

  /* Stampa di una sola giornata: chi la chiede marca il corpo e la scheda
     scelta, e tutto il resto dell'elenco esce di pagina. */
  body.dt-stampa-uno .dt-giornata:not(.dt-giornata--scelta) {
    display: none !important;
  }

  /* La data resta — e' l'intestazione del foglio — ma senza il segno del
     pannello: su carta non c'e' niente da aprire. Il riquadro che la stacca
     dal fondo dello schermo non serve piu': sulla carta il fondo e' bianco,
     e resterebbe un rettangolo intorno al titolo. */
  .dt-giorno__timone {
    position: static;
    max-width: none;
    height: auto;
    padding: 0;
    border: none;
    box-shadow: none;
    background: none;
  }
  .dt-giorno__data { background: none; height: auto; padding: 0; }
  .dt-giorno__data svg { display: none; }
  /* Su carta non c'e' niente da premere: restano la data e basta, senza il
     filo che la divideva da comandi che qui non ci sono. */
  .dt-giorno__comandi { display: none; }
}

/* ==========================================================================
   LA BARRA CHE SI TIRA
   ==========================================================================

   Il filo sta sopra al confine fra le due colonne e non dentro alla griglia:
   una terza colonna larga sei pixel avrebbe cambiato il disegno di tutte le
   schermate — e ognuna di loro avrebbe dovuto saperne qualcosa — mentre qui la
   griglia resta quella di prima e il filo ci si appoggia sopra.

   La larghezza la scrive il codice sul guscio (`--dt-sidebar-w` in linea) solo
   dopo che qualcuno l'ha tirata: finche' nessuno tocca niente vale il `clamp`
   dei token, che si muove con la finestra. */

.dt-app { position: relative; }

/* Larghezza e filo si spostano insieme e sugli stessi nodi: sono la stessa
   misura vista da due parti. Mentre si tira la transizione si spegne — con lei
   accesa la barra inseguirebbe il dito con due decimi di ritardo, che si legge
   come una barra che non sta dietro. */
.dt-app,
.dt-app__tira {
  transition: grid-template-columns var(--dt-t-slitta), left var(--dt-t-slitta);
}
.dt-app--barra-tirata,
.dt-app--barra-tirata .dt-app__tira {
  transition: none;
}

.dt-app__tira {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--dt-sidebar-w);
  width: 11px;
  /* Centrato sul confine: la presa cade sul filo, non di fianco. */
  transform: translateX(-5px);
  z-index: var(--dt-z-sticky);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: col-resize;
  /* Da qui il gesto e' dell'applicazione: senza, il primo movimento del dito
     se lo prende lo scorrimento e la barra non parte mai. */
  touch-action: none;
  background: transparent;
  transition: background var(--dt-t-fast);
}
.dt-app__tira:focus-visible { outline-offset: -2px; }
.dt-app__tira:hover,
.dt-app--barra-tirata .dt-app__tira {
  background: var(--dt-hover);
}

/* La presa: un segno corto in mezzo al filo. Da ferma non c'e' — il bordo
   della barra basta a dire dove finisce — e compare quando ci si avvicina, che
   e' l'unico momento in cui serve saperlo. */
.dt-app__tira__presa {
  width: 3px;
  height: 28px;
  border-radius: var(--dt-r-full);
  background: var(--dt-border-strong);
  opacity: 0;
  transition: opacity var(--dt-t-fast), background var(--dt-t-fast);
}
.dt-app__tira:hover .dt-app__tira__presa,
.dt-app__tira:focus-visible .dt-app__tira__presa,
.dt-app--barra-tirata .dt-app__tira__presa {
  opacity: 1;
}
.dt-app--barra-tirata .dt-app__tira__presa { background: var(--dt-accent); }

/* Barra chiusa. Il filo diventa una costola: si vede sempre, ha la presa
   accesa e la stessa faccia della barra che ha preso il posto di. E' la strada
   per tornare indietro, e sta esattamente dove stava quello che si e' chiuso.

   Solo dove le due cose sono affiancate: in verticale e sulle finestre strette
   la barra e' una fascia in fondo allo schermo, e li' non c'e' nessuna
   larghezza da chiudere — nascondere la fascia vorrebbe dire togliere la
   navigazione a chi tiene il tablet in piedi. */
@media (min-width: 821px) and (orientation: landscape) {
  .dt-app--barra-chiusa .dt-app__side {
    border-right: 0;
    /* Nascosta e non solo larga zero: larga zero resterebbe nella fila del
       tabulatore, e si finirebbe a girare dentro a una barra che non c'e'. */
    visibility: hidden;
  }
  /* La costola sta *dentro* alla colonna che la barra ha lasciato, non sopra
     al lavoro: la larghezza qui e quella scritta dal codice sono la stessa
     misura, e separate finirebbero per coprire le prime lettere di quello che
     c'e' scritto sotto. */
  .dt-app--barra-chiusa .dt-app__tira {
    left: 0;
    width: 14px;
    transform: none;
    /* Un grigio pieno e non il fondo della barra: chiusa, questa striscia deve
       leggersi come una cosa che c'e' e si puo' aprire, non come il bordo
       della finestra. */
    background: var(--dt-surface-3);
    border-right: 1px solid var(--dt-border);
    cursor: e-resize;
  }
  .dt-app--barra-chiusa .dt-app__tira:hover { background: var(--dt-selected); }
  /* La presa e' l'unico segno rimasto della barra: si vede sempre, e piu'
     lunga — su quattordici pixel di larghezza e' quella a dire che li' c'e'
     qualcosa da prendere. */
  .dt-app--barra-chiusa .dt-app__tira__presa {
    opacity: 1;
    width: 4px;
    height: 44px;
    background: var(--dt-border-strong);
  }
  .dt-app--barra-chiusa .dt-app__tira:hover .dt-app__tira__presa {
    background: var(--dt-accent);
  }
}

/* Il filo della barra laterale non esiste in verticale e sulle finestre
   strette: li' la barra e' una fascia in fondo allo schermo e non ha nessuna
   larghezza da decidere. Il codice non lo monta proprio; questa riga vale per
   l'istante in cui la finestra e' appena girata e il codice non lo sa ancora. */
@media (orientation: portrait), (max-width: 820px) {
  .dt-app__tira { display: none; }
}
