/* ⭐ IL LOOK DEL BINARIO GRAFICO ( `graphic-editor.html` ). I pezzi sono quelli di dp7 — `desktop-panel`, la testata
   `.next-content-activator`, le righe `.input-property` —, la veste e' ridotta all'osso: niente rilievi, niente tinte, un filo dove
   serve a dividere e il resto lo fa lo spazio.

   ⛔ NON sostituisce `xos.css`: gli sta sopra e va caricato DOPO. Quel che cambia passa, dove si puo', dalle VARIABILI del tema —
   cosi' una regola di XOS che non abbiamo riscritto prende comunque il colore giusto. Le regole sono ancorate a `.sidebar` e
   `.graphic-tools`: cosi' restano di questa pagina e non toccano l'app. */


/* ⭐ I COLORI, PER TUTTI E DUE I TEMI. Le stesse variabili scritte due volte: `.dark_theme` e `.light_theme` sono classi su `<html>`
   ( la convenzione di XOS ), e tutto il resto di questo file legge solo variabili — un colore nuovo va aggiunto a TUTTI E DUE, mai
   scritto in chiaro in una regola.

   ⭐ La veste e' quella di un editor tecnico: fondo a griglia, superfici piatte, filo sottile, testo MONOSPAZIATO e piccolo. Le uniche
   tinte sono l'accento ( cio' che e' in mano ) e l'arancione dell'anteprima ( dove una cosa andra' a finire ).

   ⚠️ Il monospaziato e' quello di SISTEMA: i font di questo progetto li serviamo noi ( `res/css/fonts.css` ), e un `@import` da Google
   sarebbe l'IP del visitatore che se ne va prima ancora di aver disegnato qualcosa. Volendo JetBrains Mono, si scarica e si aggiunge
   li'. */
:root.dark_theme
{
    --page-background: #0a0e14;

    --surface: #0d131b;
    --hairline: rgba(255, 255, 255, .08);

    --ink: #d7dee8;
    --ink-soft: #94a4ba;
    --ink-faint: #616b7b;

    --bar-surface: #10161f;
    --bar-shadow: 0 1px 2px rgba(0, 0, 0, .35), 0 12px 32px -16px rgba(0, 0, 0, .70);
    --bar-hover: rgba(255, 255, 255, .06);
    --bar-active: rgba(255, 255, 255, .10);

    /* lo stesso accento nei due temi, e sopra ci va il BIANCO */
    --accent: #05b5e1;
    --error: #e5484d;
    --keyframe-current: #ffa51f;
    --tween-span: #f5c400;
    --tween-motion: #05b5e1;
    --tween-color: #d0479b;
    --tween-opacity: #8a6cf0;
    --tween-size: #2fb67a;
    --tween-property: #8a99ab;
    --on-accent: #ffffff;

    /* ⭐ LA STANZA ATTORNO AI FOGLI: il `<canvas>` e' trasparente e questo e' il suo sfondo CSS; le pagine si dipingono bianche sopra
       ( `GraphicPage.PAGE_COLOR` ). Anche il velo di « dentro un oggetto » la legge da qui ( `GraphicEditor.CONTEXT_VEIL_ALPHA` ).
       ⚠️ Un disegno FUORI da una pagina sta su questo grigio: l'inchiostro nero di un DXF o di un PDF li' si legge poco.
       ⛔ Senza griglia: sotto un disegno tecnico sarebbe una seconda quadrettatura che nessuno ha chiesto. */
    --canvas-background: #444852;
    --canvas-ink: #1f2933;

    /* l'icona su fondo d'accento: nera, che su un ciano chiaro e' quel che si legge */
    --svg-on-accent-filter: brightness(0) invert(1);
}

:root.light_theme
{
    --page-background: #f5f7fa;

    --surface: #f8fafc;
    --hairline: rgba(20, 30, 50, .11);

    --ink: #1f2933;
    --ink-soft: #5a6b7d;
    --ink-faint: #8a99ab;

    --bar-surface: #ffffff;
    --bar-shadow: 0 1px 2px rgba(20, 30, 50, .06), 0 12px 32px -18px rgba(20, 30, 50, .28);
    --bar-hover: rgba(20, 30, 50, .05);
    --bar-active: rgba(20, 30, 50, .09);

    --accent: #05b5e1;
    --error: #e5484d;
    --keyframe-current: #ffa51f;
    --tween-span: #f5c400;
    --tween-motion: #05b5e1;
    --tween-color: #d0479b;
    --tween-opacity: #8a6cf0;
    --tween-size: #2fb67a;
    --tween-property: #8a99ab;
    --on-accent: #ffffff;

    /* la stessa carta del tema scuro: la tela non cambia colore, cambia la stanza intorno */
    --canvas-background: #e8e8e8;
    --canvas-ink: #1f2933;

    --svg-on-accent-filter: brightness(0) invert(1);
}

/* ⭐ Quel che vale per tutti e due: le variabili di XOS, che questo file ridefinisce perche' anche le regole che non abbiamo riscritto
   prendano il colore giusto. */
:root.dark_theme ,
:root.light_theme
{
    --mono: 'JetBrains Mono', ui-monospace, 'SF Mono', SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace;

    --body-text-color: var(--ink);
    --border-color: var(--hairline);
    --input-background-color: var(--bar-hover);

    /* ⭐ IL FONDO DEL PANNELLO STACCATO. In colonna un pannello non ha fondo proprio — `xos.css` non gliene da' uno, e la superficie
       e' quella della colonna —, ma staccato galleggia sopra la tela e il fondo se lo deve portare: e' `.panel.dragged` a chiedere
       questa variabile. Percio' non va messa a `transparent`, o il disegno si vedrebbe attraverso il pannello. */
    --panel-background-color: var(--bar-surface);

    /* quel che sta sopra: il filo lo tiene leggibile sul foglio bianco di un PDF, l'ombra dice la distanza senza fare rilievo */
    --elevation-shadow: 0 0 0 1px var(--hairline), 0 14px 34px -18px rgba(0, 0, 0, .45);

    /* ⛔ il titolo di un pannello aperto vira all'azzurro e ingrassa ( `.next-content-activator.checked .name` ): qui i titoli sono
       tutti uguali, e a dire che il pannello e' aperto ci pensa la freccia. */
    --panel-title-color: var(--ink-faint);

    /* ⭐ L'ACCENTO E' UNO SOLO, e dice cosa e' IN MANO. ⛔ `xos.css` lo usa anche per tingere icone e glifi sotto il puntatore
       ( `.tool-bar .button:hover svg` ): quello no, un'icona che cambia colore al passaggio e' rumore. */
    --accent-color: var(--accent);
    --svg-accent-color-filter: none;
}

/* ⭐ IL LAYOUT: la tela prende quel che resta, la colonna ha la sua misura. Il `ResizeObserver` del player rimisura la tela da se'.
   ⛔ LA PAGINA NON SCORRE: quel che si sposta e' la VISTA del disegno ( `GraphicPlayer.pan` ), e una pagina che scivola sotto la rotella
   sposterebbe la tela invece del disegno. `overscroll-behavior` ferma anche il rimbalzo del trackpad. */
html, body { height: 100%; margin: 0; overflow: hidden; overscroll-behavior: none; }

/* ⭐ DUE RIGHE: sopra la tela e la colonna, sotto il footer a tutta larghezza ( `graphic-dock` ), che chiuso non occupa niente */
body
{
    display: grid;
    grid-template-columns: minmax( 0 , 1fr ) auto;
    grid-template-rows: minmax( 0 , 1fr ) auto;
    font-family: var(--mono);
    font-size: 12px;
    color: var(--ink);
    background: var(--page-background);
}

/* ⭐ IL FONDO DELLA TELA E' IL `background` DEL CANVAS, non una pittura: il player pulisce e non dipinge niente sotto il disegno
   ( `paintBackground` e' vuoto apposta ), quindi quel che il CSS mette qui si vede attraverso, a costo zero e senza un colore in piu'
   da tenere nel codice.
   ⚠️ E anche il `color`: e' da li' che il player prende `currentColor` per chi lo chiede, e su carta chiara l'inchiostro va scuro. */
#graphic-editor
{
    display: block;
    grid-row: 1;
    grid-column: 1;
    min-width: 0;
    width: 100%;
    height: 100%;
    touch-action: none;
    color: var(--canvas-ink);
    background: var(--canvas-background);
}






/* ⭐ LA COLONNA: non una superficie con dei pannelli dentro, ma delle CARD sul fondo a griglia — la griglia passa fra l'una e l'altra,
   e ogni pannello si legge come un pezzo a se'. E' la veste dell'editor di riferimento. */
.sidebar
{
    grid-row: 1;
    grid-column: 2;
    min-height: 0;
    height: 100%;
    display: flex;
    flex-flow: row nowrap;
    font-size: 12px;
    color: var(--ink);

    /* ⭐ IL FILO SULLA TELA, IL FIANCO E LO SPAZIO FRA LE COLONNE SONO DEL CONTENITORE ( 2026-09-28 ): una colonna spenta ( `hidden` ) non
       prende posto ne' spazio, e il bordo della sidebar resta lo stesso con o senza la colonna Document. Fra le colonne 10 px, un
       poco meno del fianco sinistro. */
    box-sizing: border-box;
    gap: 10px;
    padding: 0 14px;
    border-left: 1px solid var(--hairline);
}

/* ⭐ LE COLONNE, una accanto all'altra: il documento, poi gli inspector, poi la barra. Ognuna scorre per conto suo. Di fianco niente: il
   rientro e lo spazio fra loro li mette la sidebar.
   ⚠️ `border-box`: col conto di serie l'altezza era il 100% PIU' il rientro, e il fondo della colonna finiva 28 px sotto lo schermo —
   invisibile finche' la colonna scorreva, non con l'albero che la riempie. */
.sidebar > .column
{
    flex: 0 0 275px;
    box-sizing: border-box;
    height: 100%;
    overflow: auto;
    padding: 14px 0;
    display: flex;
    flex-flow: column nowrap;

    /* ⚠️ LE CARD SI TOCCANO ( chiesto da Riccardo il 2026-09-20 ): il distacco di 14 px era aria in piu' in una colonna che
       ne ha gia' dentro ogni card. Restano i loro fili a dividerle. */
    gap: 0;
}

/* ⭐ GLI INSPECTOR SCORRONO NEL LORO CONTENITORE, la barra delle risorse resta sotto, fuori ( chiesto da Riccardo il 2026-09-27: i pannelli
   non devono passarle sopra ). La colonna non scorre piu': ci pensa `.column-scroll`. Fra un pannello e l'altro un filo d'aria ( chiesto lo
   stesso giorno ); gli staccati sono `fixed` e non ne prendono. */
.sidebar > .inspector-column { overflow: hidden; }

/* l'albero un po' piu' stretto degli inspector, come prima */
.sidebar > .document-column { flex-basis: 268px; }

/* ⭐ LE RISORSE AL POSTO DI DOCUMENT ( prova del 2026-09-28, `GraphicResourceColumn` ): accese, Document non si vede — la sua `hidden` resta sua, e
   spente le risorse torna com'era. In testa un bottone per tipo, sotto i pannelli accesi uno sotto l'altro: scorrono loro, le schede restano. */
.sidebar:has( > resource-column:not( .hidden ) ) > .document-column ,
.sidebar > .column.hidden
{
    /* ⭐ UNA COLONNA SPENTA ESCE DAL FLUSSO MA C'E' ( chiesto da Riccardo il 2026-09-28 ): i suoi pannelli staccati restano sulla tela. Niente
       posto ne' spazio fra le colonne ( `absolute`, larga zero ), e invisibile — tranne chi e' staccato. */
    display: flex !important;
    position: absolute;
    width: 0;
    height: 0;
    padding: 0;
    overflow: visible;
    visibility: hidden;
}

.sidebar .panel.dragged { visibility: visible; }
.sidebar > .resource-column { flex-basis: 268px; }
.resource-column > .resource-tabs { margin: 0 0 6px; }
.resource-column > .resource-tabs > .column-button { border-right: none; margin-right: 0; padding-right: 0; border-radius: 6px; }
.resource-column > .resource-stack { flex: 1 1 auto; min-height: 0; overflow: auto; display: flex; flex-flow: column nowrap; gap: 6px; }
.resource-column > .resource-stack > .panel { flex: 0 0 auto; }

/* ⭐ LA COLONNA FONT: in testa le fonti, in una card come le schede delle risorse; sotto il pannello, alto quanto resta, e scorre l'elenco */
.font-column > .column-header { flex: 0 0 auto; margin: 0 0 6px; padding: 4px; gap: 2px; background: var(--bar-surface); border: 1px solid var(--hairline); border-radius: 10px; }
.font-column > .column-header > .button { height: 28px; border-radius: 6px; cursor: pointer; }
.font-column > .column-header > .button:hover { background: var(--bar-hover); }
.font-column > .column-header > .button.selected { background: var(--bar-active); }
.font-column > font-panel:not( .dragged ) { flex: 1 1 auto; min-height: 0; }
.font-column > font-panel > .content { flex: 1 1 auto; min-height: 0; overflow: auto; }

.sidebar > .inspector-column > .column-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; display: flex; flex-flow: column nowrap; gap: 6px; }

/* gli inspector del nodo scelto stanno nel loro `showable-children`: lo stesso filo d'aria anche fra loro */
.sidebar > .inspector-column > .column-scroll > .showable-children { flex: 0 0 auto; display: flex; flex-flow: column nowrap; gap: 6px; }

/* ⭐ IL DOCUMENTO PRENDE L'ALTEZZA DELLA COLONNA, e a scorrere e' l'albero: la testata resta ferma. Chiuso l'accordion torna una card
   alta quanto la sua testata. */
.sidebar > .document-column > document-panel:has( > .next-content-activator.checked ) { flex: 1 1 auto; min-height: 0; }

.sidebar > .document-column > document-panel > .content { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 6px 4px; }

/* ⭐ UN PANNELLO E' UNA CARD: fondo pieno, filo sottile, angoli. In colonna l'altezza la fa il contenuto. */
.sidebar .panel
{
    max-height: none;
    background: var(--bar-surface);
    border: 1px solid var(--hairline);
    border-radius: 10px;
    overflow: hidden;
}

.sidebar .panel + .panel { margin-top: 0; }

/* ⚠️ la testata e' una riga a se', col suo filo sotto: e' quella che da' il nome alla card */
.sidebar .panel > .header
{
    height: auto;
    padding: 10px 12px;
    gap: 2px;
    background: var(--bar-surface);
    border-bottom: 1px solid var(--hairline);
}

/* ⛔ chiuso l'accordion il filo della testata non separa piu' niente: se ne va con il contenuto */
.sidebar .panel > .next-content-activator:not( .checked ) { border-bottom: none; }

.sidebar .next-content-activator .name ,
.sidebar .next-content-activator.checked .name
{
    margin: 0 4px;
    padding: 0;
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--ink-faint);
}

.sidebar .next-content-activator .button.activator { font-size: 16px; color: var(--ink-faint); }

/* ⭐ anche nei pannelli degli strumenti ( blob, pennelli, aggancio ): staccati mostrano la stessa crocetta della colonna ( Riccardo, 2026-10-01 ) */
:is( .sidebar , tool-options ) .next-content-activator .button.close { font-size: 16px; color: var(--ink-faint); }

/* ⭐ I COMANDI NELLA TESTATA ( lo specchio di Geometry ): a destra, dopo il nome che prende tutto lo spazio, con l'inchiostro e la
   misura delle icone della colonna. */
.sidebar .next-content-activator .button.header-command
{
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 20px;
    border-radius: 3px;
}

.sidebar .next-content-activator .button.header-command:hover { background: var( --bar-active ); }

.sidebar .next-content-activator .button.header-command > .icon.material-symbols-outlined { font-size: 20px; color: var( --ink-soft ); }

.sidebar .next-content-activator .button.header-command:hover > .icon.material-symbols-outlined { color: var( --ink ); }

.sidebar .panel > .content { padding: 10px 12px; max-height: none; }

/* ⭐ IL PANNELLO STACCATO: il fondo glielo da' `--panel-background-color` e il contorno `--elevation-shadow`, tutti e due ridefiniti
   in testa. Qui resta la forma: lo stesso angolo della barra degli strumenti ( `xos.css` ne da' 16 ), e una testata che deve fare
   posto alla chiusura, che compare solo da staccato. */
.sidebar .panel.dragged { border-radius: 12px; }

.sidebar .panel.dragged > .header { padding: 11px 10px 11px 14px; }

/* ⭐ LA RIGA: etichetta a sinistra, valore a destra. `.input-property` da sola impila ( e' `flex-direction: column` ), e a metterla in
   riga e' `flex-row` accanto a lei — la coppia del markup di dp7.
   ⚠️ Queste regole erano scritte DUE VOLTE, con due `font-size` diversi ( 11 e 12 ): vinceva la seconda, e le due meta' della colonna
   parlavano con due corpi. Una volta sola, a **11px**, che e' il corpo dei pannelli che scrivono. */
.input-property > .label
{
    flex: 1;
    min-width: 0;
    text-align: left;
    opacity: 1;
    font-size: 11px;
    color: var(--ink-soft);
}

/* ⚠️ le cifre incolonnate ( `tabular-nums` ): un valore che cambia a ogni giro di rotella non deve far ballare la riga */
.read-only-value
{
    width: auto;
    padding: 0;
    opacity: 1;
    text-align: right;
    font-size: 11px;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
}



/* ⭐ LE OPZIONI DELLO STRUMENTO: una scatola sotto la barra, aperta passando sopra un bottone. Dentro ci sta una barra ( che porta
   `.floating-bar`, ed e' quindi identica a quella sopra ) o un pannello di dp7. */
tool-options
{
    position: fixed;
    z-index: 30;
    display: block;
}

/* ⛔ senza figli mostrati la scatola non c'e': l'ombra e la punta di un contenitore vuoto resterebbero sopra il disegno */
tool-options:not( :has( > .showed ) ) { display: none; }

/* ⛔ I FIGLI NON SONO POSIZIONATI: staccandolo, il trascinamento scrive `left`/`top` sull'elemento ( `DragManager.dragElement` ), e su
   un elemento `relative` quei due numeri continuano a valere anche dopo — rimesso a posto, il pannello restava spostato della stessa
   misura. Da `static` non contano, e chiuderlo lo riporta dov'era, come in colonna. */
tool-options > * { position: static; }

/* un pannello dentro la scatola: in colonna la larghezza la detta la colonna, qui se la deve portare */
tool-options > .panel
{
    width: 198px;
    max-height: none;
    font-size: 12px;
    color: var(--ink);
    background: var(--bar-surface);
    border: 1px solid var(--hairline);
    border-radius: 10px;
    box-shadow: var(--bar-shadow);
    overflow: hidden;
}

tool-options > .panel > .header
{
    height: auto;
    padding: 10px 12px;
    gap: 2px;
    border-bottom: 1px solid var(--hairline);
}

tool-options > .panel > .next-content-activator:not( .checked ) { border-bottom: none; }

tool-options > .panel > .content { padding: 8px 10px; max-height: none; }

tool-options .next-content-activator .name,
tool-options .next-content-activator.checked .name
{
    margin: 0 4px;
    padding: 0;
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--ink-faint);
}

tool-options .next-content-activator .button.activator { font-size: 16px; color: var(--ink-faint); }



/* ⭐ LA LISTA DEI PENNELLI, dentro il suo pannello: nomi, uno per riga, e quello scelto si accende. */
tool-options > .panel .content { padding: 4px 8px 10px; }

.brush-list { display: flex; flex-flow: column nowrap; gap: 2px; width: 170px; max-height: 44vh; overflow: auto; }

.brush-item
{
    padding: 2px 4px;
    border-radius: 6px;
    cursor: pointer;
}

/* ⚠️ il tratto si guarda, non si preme: i gesti sono della voce, o passando sopra il disegno il pennello non si sceglierebbe */
.brush-thumb { display: block; width: 100%; height: auto; color: var(--ink); opacity: .85; pointer-events: none; }

.brush-item:hover .brush-thumb ,
.brush-item.selected .brush-thumb { opacity: 1; }

.brush-item:hover { background: var(--bar-hover); color: var(--ink); }

/* il pennello scelto e' una scelta dentro uno strumento, non uno strumento: fondo grigio, come i modi */
.brush-item.selected { background: var(--bar-active); }

.brush-item.selected .brush-thumb { opacity: 1; }



/* ⭐ I CAMPI: quelli di `xos.css` vestiti come il resto — monospaziati, piccoli, piatti. Valgono ovunque nella pagina, perche' un campo
   in una barra e un campo in un pannello sono lo stesso campo. */
input , select , textarea
{
    font-family: var(--mono);
    font-size: 11.5px;
    color: var(--ink);
    background: var(--bar-hover);
    border: 1px solid transparent;
    border-radius: 6px;
    padding: 4px 6px;
    transition: border-color .12s ease, background-color .12s ease;
}

input:hover { background: var(--bar-active); }

/* ⚠️ il fuoco si vede: un bordo d'accento, non l'anello di sistema che salta fuori dal raggio del campo */
input:focus , select:focus
{
    outline: none;
    border-color: var(--accent);
    background: var(--bar-hover);
}

/* ⭐ LO SLIDER: un filo con una pallina d'accento. ⚠️ Il bordo della pallina e' del colore del FONDO, non trasparente: e' quello che la
   stacca dalla riga su cui scorre.
   ⛔ E VALE ANCHE NEI MENU ( `.menu` ): quelli stanno FUORI dalla colonna, e senza il loro nome qui dentro prendevano lo slider
   di serie del browser — traccia spessa e pallina grossa, un secondo stile nella stessa pagina ( visto da Riccardo ).
   ⚠️ Il selettore di colore fa eccezione apposta e si riscrive il suo piu' avanti: li' la traccia E' il comando. */
input[type="range"]
{
    -webkit-appearance: none;
    appearance: none;
    height: 3px;
    padding: 0;
    background: var(--hairline);
    border: none;
    border-radius: 2px;
}

input[type="range"]::-webkit-slider-thumb
{
    -webkit-appearance: none;
    width: 13px;
    height: 13px;
    border-radius: 50%;
    background: var(--accent);
    border: 2px solid var(--bar-surface);
    cursor: pointer;
}

input[type="range"]::-moz-range-thumb
{
    width: 11px;
    height: 11px;
    border-radius: 50%;
    background: var(--accent);
    border: 2px solid var(--bar-surface);
    cursor: pointer;
}

/* il colore: il campo E' il campione, senza cornice di sistema */
input[type="color"]
{
    width: 100%;
    height: 22px;
    padding: 2px;
    background: transparent;
    border: 1px solid var(--hairline);
    border-radius: 5px;
    cursor: pointer;
}

/* la casella di spunta prende l'accento invece del blu di sistema */
input[type="checkbox"] { accent-color: var(--accent); }


/* ══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
   ⭐ QUEL CHE SERVE DA XOS, E NIENT'ALTRO.

   ⛔ Questa pagina NON carica `xos.css`. Non e' una rottura con il framework: il JS di XOS resta tutto — `DesktopPanel`, `DragManager`,
   `Node.prototype.applyClass` —, e sono loro a mettere e togliere le classi qui sotto. E' il FOGLIO che non serviva intero: portava
   dialoghi, menu, alberi, barre di scorrimento e due temi che questa pagina non usa, e le sue regole sui bottoni ( `.radio-bar
   .button.selected`, `.tool-bar .button:hover svg` ) andavano battute una per una a colpi di specificita'. Ogni volta che se ne
   ridisegnava una, la successiva saltava fuori.

   Le regole che seguono sono quelle che il MARKUP di questa pagina chiede davvero, copiate da `xos.css` con la stessa semantica e il
   riferimento a dove stanno di casa. Se una parte nuova ne vuole un'altra, la si porta qui — non si torna a caricare il foglio intero.
   ══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════ */

/* il gruppo che mostra un figlio alla volta, e il nascondere per tutti */
.showable-children > *:not( .showed ) { display: none !important; }

.hidden { display: none !important; }

/* ⭐ I DIALOGHI ( `app-dialogs` + `modal-dialog` di `xos.css` ): il velo a tutto schermo, e il dialogo come un pannello staccato — fondo, contorno
   e raggio dei pannelli. Le righe sono quelle degli inspector, con le etichette larghe come nel pannello Project. */
app-dialogs { position: fixed; inset: 0; z-index: 100; background: rgba( 0 , 0 , 0 , .18 ); }

.dialog { position: absolute; left: 50%; top: 22%; width: 300px; margin-left: -150px; border-radius: 16px; background: var( --panel-background-color ); box-shadow: var( --elevation-shadow ); }
.dialog > .header { align-items: center; gap: 8px; padding: 12px 12px 6px 16px; }
.dialog > .header > .title { flex: 1; font-size: 14px; }
.dialog > .header > .close { cursor: pointer; color: var( --ink-soft ); }
.dialog > .content { padding: 4px 16px 16px 16px; }
.dialog .input-property > .label { flex-basis: 96px; }

/* ⭐ il dialogo di un valore e' piccolo ( chiesto da Riccardo il 2026-09-25 ): 200 px, centrato come gli altri */
#value-dialog { width: 200px; margin-left: -100px; }

/* il numero dei punti di un tracciato, a destra come gli altri valori del pannello Shape */
shape-properties [name="pointCount"] { margin-left: auto; }

#value-dialog .input-property > .label { flex-basis: auto; }

#value-dialog .input-property > input { flex: 1; min-width: 0; }
.dialog .input-property.flex-row > input[type="number"] { width: 56px; margin-left: auto; }
.dialog .input-property.flex-row > input[type="checkbox"] { margin-left: auto; }
.dialog .input-property.flex-row > select { max-width: 150px; }
.dialog .input-property > .note { margin-left: auto; font-size: 11px; color: var( --ink-soft ); white-space: nowrap; }
.dialog .input-property > .note + input[type="checkbox"] { margin-left: 8px; }
.dialog .buttons { justify-content: flex-end; gap: 8px; padding-top: 14px; }
.dialog .buttons > button { font: inherit; padding: 5px 14px; border-radius: 8px; border: 1px solid var( --hairline ); background: transparent; color: var( --ink ); cursor: pointer; }
.dialog .buttons > button:last-child { background: var( --accent ); border-color: var( --accent ); color: var( --on-accent ); }
/* il login: il bottone di Google centrato, e sotto l'errore di chi non e' entrato */
#login-dialog .google-button { display: flex; justify-content: center; padding-top: 14px; min-height: 44px; }
#login-dialog .intro { color: var( --ink-soft ); text-wrap: balance; text-align: center; }
#login-dialog .error { padding-top: 8px; font-size: 11px; color: var( --error ); text-align: center; }
#login-dialog .error:empty { display: none; }
#login-dialog .legal { padding-top: 12px; text-align: center; font-size: 11px; }
#login-dialog .legal > a { color: var( --ink-soft ); }

/* ⭐ IL BANNER DEI COOKIE ( `CookieConsent` ): la fascia in fondo del sito ( `janvas.com/themes/janvas/css/style.css` ), sopra anche il velo dei dialoghi.
   ⚠️ i due bottoni sono IDENTICI: un « Refuse » meno visibile non e' una scelta libera */
cookie-consent:not([hidden]) { position: fixed; left: 0; right: 0; bottom: 0; z-index: 1000; display: flex; align-items: center; justify-content: space-between;
                               gap: 20px; padding: 12px 16px; background: var( --bar-surface ); box-shadow: var( --bar-shadow ); color: var( --ink ); font-size: 12px; }
.cookie-consent-text a { color: var( --ink ); text-decoration: underline; margin-left: 4px; }
.cookie-consent-buttons { display: flex; gap: 10px; flex: 0 0 auto; }
.cookie-consent-buttons button { font: inherit; color: var( --ink ); background: none; border: 1px solid var( --ink ); border-radius: 8px; padding: 5px 16px; cursor: pointer; }
.cookie-consent-buttons button:hover { background: var( --ink ); color: var( --bar-surface ); }
@media ( max-width: 760px )
{
    cookie-consent:not([hidden]) { flex-direction: column; align-items: stretch; }
    .cookie-consent-buttons button { flex: 1; }
}

/* ⭐ IL BOTTONE DI UN COMANDO DENTRO UN PANNELLO ( il Trace di Trace image ): la veste del bottone principale dei dialoghi, a destra */
.panel .trace-row { justify-content: flex-end; }
.panel .command-button { font: inherit; padding: 5px 14px; border-radius: 8px; border: 1px solid var( --accent ); background: var( --accent ); color: var( --on-accent ); cursor: pointer; }
.panel .command-button:disabled { opacity: .5; cursor: default; }
.panel .trace-hint { color: var( --ink-faint ); }

/* spento: si vede che c'e', non si tocca */
.disabled { opacity: .4; pointer-events: none; }

/* ⚠️ `.input-property` DA SOLA IMPILA, e sta PRIMA di `.flex-row`: e' l'ordine che ha in `xos.css`, e non e' cosmetico — chi vuole una
   riga porta tutte e due le classi, e la seconda deve poter vincere sulla prima. Invertendole, ogni riga di una property andava a capo. */
.input-property { display: flex; flex-direction: column; margin-top: 0; padding: 3px 0; align-items: baseline; }

.flex-row { display: flex; flex-direction: row; align-items: center; gap: 5px; }

.button { cursor: pointer; }

/* ⭐ L'ACCORDION E' PURA CSS: la testata non spegne niente, nasconde l'elemento CHE LE VIENE DOPO. La freccia gira di 90°. */
.next-content-activator { display: flex; align-items: center; }

/* ⛔ CHIUDERE L'ACCORDION VUOL DIRE NASCONDERE, e vince su qualunque `display` dichiarato dal contenuto: senza `!important`
   una regola piu' specifica — `.content.geometry-grid { display: grid }` — teneva aperto il pannello della geometria, che
   con la freccia non si chiudeva ( visto da Riccardo il 2026-09-20 ). E' la stessa scelta di `.hidden`. */
.next-content-activator:not( .checked ) + * { display: none !important; }

.next-content-activator .button.activator { display: inline-flex; transition: transform .2s ease; font-size: 18px; }

.next-content-activator.checked .button.activator { transform: rotate( 90deg ); }

.next-content-activator .name { flex-grow: 1; margin: 0 10px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }

/* ⚠️ il nome e' la PRESA per staccare il pannello: il cursore lo dice */
.panel .next-content-activator .name { cursor: move; }

.panel { display: flex; flex-direction: column; box-sizing: border-box; color: var(--body-text-color); user-select: none; }

.column { display: flex; flex-direction: column; min-width: 50px; overflow: auto; }

/* ⭐ IL PANNELLO STACCATO: fuori dal flusso, sopra tutto, e con la misura che gli ha dato la presa — scritta in due VARIABILI, non in
   `width`/`height`, cosi' rimettendolo a posto la regola smette di valere da sola e non c'e' niente da ripulire. */
.panel.dragged
{
    position: fixed;
    z-index: 20;
    min-width: 220px;
    width: var(--panel-width, auto);
    max-width: var(--panel-width, min-content);
    height: auto;
    max-height: var(--panel-height, 60vh);
    box-shadow: var(--elevation-shadow);
}

.panel.dragged:has( > .next-content-activator.checked ) { height: var(--panel-height, auto); min-height: 120px; }

/* ⭐ STACCATO, L'ALTEZZA LA DETTA IL CONTENUTO ( chiesto da Riccardo ): `dragElement` congela la misura che il pannello aveva
   IN COLONNA — che e' la misura della colonna, non una scelta — e da li' una riga che compare non ci sta piu'.
   ⛔ L'`!important` E' NECESSARIO E HA UN PREZZO: quella misura `dragElement` la scrive INLINE, e una dichiarazione inline
   batte il foglio — senza, il pannello restava alto com'era e il contenuto scorreva ( misurato: 159 px e la riga di
   « ognuno » fuori ). Col `!important` vince il foglio, ma perde anche la PRESA in basso a destra, che scrive li' dentro: da
   qui in poi l'altezza di un pannello staccato la decide il suo contenuto e basta ( la larghezza no, quella resta della presa ).
   ⚠️ E il tetto va dichiarato qui: `max-height: var( --panel-height , 60vh )` con `auto` non e' un valore valido, quindi
   quella riga cade e senza un tetto un pannello lungo uscirebbe dallo schermo. */
.sidebar .panel.dragged { --panel-height: auto !important; max-height: 60vh; }


/* ⚠️ l'altezza in piu' la prende il CONTENUTO, che e' l'unica parte che ha senso allungare.
   ⛔ E SE NON BASTA, SCORRE: staccando un pannello la sua altezza si FISSA a quella che aveva in quel momento
   ( `dragElement` scrive `--panel-height` ), e da li' in poi il contenuto puo' crescere — la riga di « ognuno » compare
   scegliendo un secondo oggetto — e usciva dalla scatola, oltre gli angoli arrotondati ( misurato con Riccardo il 2026-09-20:
   contenuto 133 px in una scatola da 118 ). */
.panel.dragged > .content { flex: 1; min-height: 0; max-height: none; overflow: auto; }

/* ⭐ La presa e la chiusura ci sono solo sul pannello staccato: in colonna la misura la detta la colonna, e non c'e' niente da chiudere. */
.panel > .resize-grip { display: none; }

.panel.dragged:has( > .next-content-activator.checked ) > .resize-grip
{
    display: block;
    position: absolute;
    right: 0;
    bottom: 0;
    width: 18px;
    height: 18px;
    cursor: nwse-resize;
    z-index: 1;
}

.panel .button.close { display: none; }

.panel.dragged > .next-content-activator .button.close { display: block; }

/* ⛔ durante un trascinamento nessuno prende eventi, iframe compresi: il gesto e' di chi l'ha cominciato */
body.is-dragging * { pointer-events: none !important; }

/* ⭐ LE ICONE DELLO SPRITE SONO `currentColor`: prendono l'inchiostro del tema come i glifi Material — `--ink-soft` a riposo, `--ink`
   sotto il puntatore e accese. Il `fill` serve alle forme dello sprite senza colore, che altrimenti restano nere.
   ⛔ Non piu' nero con un'opacita' ne' invertito nel tema scuro: il nero schiarito e' un grigio neutro, e accanto al grigio-blu dei
   glifi si vedeva la differenza. */
svg.icon { width: 26px; height: 26px; color: var(--ink-soft); fill: currentColor; }

.button:hover svg.icon , .button.selected svg.icon , .icon-button:hover svg.icon { color: var(--ink); }



/* ══ I COMPONENTI — UNA VOLTA SOLA, SENZA CONTENITORE ════════════════════════════════════════════════════════════════════════
   ⭐ Riga, etichetta, casella, tendina, slider, interruttore, barra di alternative: da qui in giù sono scritti per quello che
   SONO, non per dove stanno. Una riga in un pannello e la stessa riga dentro un menu sono la stessa riga, e si vedono uguali
   perché è la stessa regola a disegnarle ( chiesto da Riccardo il 2026-09-20: « usa un css generale » ).

   ⛔ PRIMA ERANO ANCORATE ALLA COLONNA ( `.sidebar .panel .content …` , 41 regole ) e ogni menu se le riscriveva per conto suo
   con numeri un po' diversi — 48px di etichetta invece di 54, la casella a 42 invece che a 36, la tendina copiata per intero.
   Il foglio è sceso di 100 righe e le differenze fra un menu e un pannello sono sparite con loro.

   Le tipologie sono DUE, e questa è la prima. L'altra sono le barre sopra la tela, in fondo al foglio. Tutto il resto — la
   larghezza di UN menu, l'altezza di QUEI quattro bottoni — è una differenza di un pezzo solo e sta INLINE nel markup, dove si
   legge accanto alla cosa che la porta ( come il `--flip` dei quattro angoli ).
   ══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════ */

/* ⭐ `.radio-bar` sono ALTERNATIVE ( se ne accende una e le altre si spengono, `applyClass` in modo 'unique' ); `.button-bar` sono
   INTERRUTTORI indipendenti, e per questo hanno un `gap`: due fondi accento adiacenti si leggerebbero come un blocco solo. Nei
   pannelli prendono la veste di `.radio-bar`, gap compreso ( piu' sotto ). */
.radio-bar , .button-bar
{
    display: flex;
    /* i bottoni stanno su UNA riga: andando a capo la fila si alzerebbe e la pillola con lei */
    flex-wrap: nowrap;
    width: 100%;
    justify-content: space-evenly;
    text-align: center;
    gap: 0;
}

.button-bar { gap: 5px; }

.radio-bar > * , .button-bar > * { display: flex; align-items: center; justify-content: center; width: 100%; font-size: inherit; }

/* ⛔ IL BOTTONE ACCESO NON CAMBIA FORMA: qui `xos.css` rimetteva il raggio da pillola ( 8px ) e in una barra di tre bottoni da
   3px quello scelto si leggeva come un pezzo d'altra veste ( visto da Riccardo il 2026-09-20 ). Cambia il FONDO, non la sagoma.
   Le barre sopra la tela il loro 8px se lo dichiarano in fondo al foglio, dove i bottoni sono grandi il doppio. */
.radio-bar .button.selected , .button-bar .button.selected { background-color: var( --bar-active ); }

.radio-bar .button.selected svg , .button-bar .button.selected svg { opacity: 1; }

/* ⚠️ `flex: 1` e non `width: 100%`: dove comanda `flex` il 100% e' di troppo, e in Safari faceva sforare la riga.
   ⛔ LA COPPIA SLIDER + CASELLA sta scritta una volta sola, piu' avanti fra i componenti: qui c'era la stessa regola con un
   altro numero ( 54px invece di 36 ), e vinceva questa perche' piu' specifica — lo slider restava corto. */
.flex-row input[type="text"] { flex: 1; }

/* ⭐ LA RIGA DI UN INSPECTOR E' LA STESSA RIGA DEI PANNELLI DI LETTURA: etichetta a sinistra a misura FISSA, comando a destra che si
   prende quel che avanza. E' l'unica regola che tiene insieme una colonna di pannelli — senza, ogni pannello portato si porta
   dietro il ritmo del markup da cui viene, e la colonna diventa un collage ( guardato con Riccardo il 2026-09-20 ).
   ⚠️ **54px e 12 di divario, non 62 e 14** ( 2026-09-20, Riccardo: « lo slider non mi sembra piu' lungo » ): misurate una per
   una, le etichette vogliono da 27 ( `Fill` ) a 47 px ( `Opacity` ), e 54 le tiene tutte. L'unica piu' lunga e' `Non scaling`
   ( 73 px ), che SBORDA nella sua riga — e li' il comando e' un interruttore all'estremita' opposta, quindi non tocca niente.
   Dimensionare la colonna sul caso unico teneva 16 px sottratti a OGNI riga. */
.input-property.flex-row { gap: 12px; align-items: center; min-height: 22px; }

.input-property > .label { flex: 0 0 54px; font-size: 11px; color: var( --ink-soft ); white-space: nowrap; }

/* ⭐ IL PANNELLO PROJECT HA ETICHETTE PIU' LUNGHE ( `Rotation step` 86 px, `Arrow step` 66, `Scale 1 :` 59 ): sborderebbero sotto la
   casella ( segnalato da Riccardo il 2026-09-22 ). La colonna si allarga solo qui, per tutte le sue righe: dentro il pannello restano
   allineate, e gli inspector tengono i loro 54. Cosi' anche il pannello Text, da quando ha etichette scritte e slider ( `Letter spacing` ). */
project-properties .input-property > .label , text-properties .input-property > .label , table-properties .input-property > .label { flex-basis: 88px; }

/* il titolo di una sezione di un pannello ( la scala dello scheletro ): un'etichetta sola, nell'inchiostro pieno */
.input-property.section-title > .label { color: var( --ink ); }

/* ⭐ LA CASELLA NON HA CORNICE A RIPOSO: a riposo si legge un NUMERO, e la scatola comparirebbe undici volte per pannello senza
   dire niente. La si vede quando serve — passandoci sopra e scrivendoci —, che e' quando il campo va mirato ( provato con
   Riccardo il 2026-09-20: prima c'era un filo sotto, sempre acceso ).
   ⚠️ Il bordo c'e' SEMPRE, trasparente: se comparisse solo al passaggio la riga si allargherebbe di due pixel sotto il puntatore. */
input[type="text"]
{
    flex: 1;
    min-width: 0;
    box-sizing: border-box;
    width: 100%;
    padding: 2px 5px;
    border: 1px solid transparent;
    border-radius: 4px;
    background: transparent;
    color: var( --ink );
    font-size: 11px;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

input[type="text"]:hover { border-color: var( --hairline ); }

input[type="text"]:focus { outline: none; border-color: var( --accent ); background: var( --bar-active ); }

/* ⛔ LA CASELLA ACCANTO A UNO SLIDER E' A MISURA FISSA, o lo slider non avrebbe piu' spazio.
   ⚠️ **36px, e non 42 ne' i 54 di partenza**: quattro cifre ci stanno lo stesso ( `0.04` , `12.5` , `100` ) stringendo il
   rientro a 3 px, e tutto quel che si toglie va allo slider ( visto da Riccardo: casella lunga e slider corto ).
   ⛔ Sotto i 35 px il quarto carattere si taglia, misurato — e a CINQUE ( `0.125` ) ci vorrebbero 41 px, cioe' la casella di
   prima: un valore cosi' si legge tutto solo mettendoci il fuoco.
   ⚠️ **Il margine NEGATIVO e' il divario della riga ripreso**: fra un'etichetta e il suo comando ci vogliono 14 px, fra uno
   slider e la casella che ne mostra il valore no — sono la stessa cosa detta due volte, e 7 px bastano a tenerle distinte.
   ⚠️ `min-width: 0` non e' di troppo: la misura minima automatica di un `input` e' la sua larghezza INTRINSECA ( 145px misurati ),
   e `flex-basis` non la tocca. */
input[type="range"] + input[type="text"] { flex: 0 0 36px; padding: 2px 3px; margin-left: -7px; }

/* ⭐ UN NUMERO NON SI PRENDE TUTTA LA RIGA ( segnalato da Riccardo il 2026-09-24, « come al solito i campi e i menu prendono troppa lunghezza » ):
   la casella di un valore numerico ( `property-type` int, float, real, angle ) ha una misura fissa e sta a destra, dove si legge il numero. I campi
   di testo ( un nome ) restano lunghi, e la casella di uno slider tiene la sua regola qui sopra. */
.input-property.flex-row > input[type="text"]:is([property-type="int"],[property-type="float"],[property-type="real"],[property-type="angle"]):not([type="range"] + input)
{
    flex: 0 0 64px;
    margin-left: auto;
}

/* ⭐ E UN MENU E' LARGO QUANTO LA SUA VOCE PIU' LUNGA ( e' cosi' un `select` ), fino a 120 px, a destra come i numeri */
.input-property.flex-row > select { flex: 0 1 auto; width: auto; max-width: 120px; margin-left: auto; text-overflow: ellipsis; }

/* lo slider: un filo di fondo e un pallino d'accento, niente di piu' */
input[type="range"] { flex: 1; min-width: 0; height: 2px; }

/* ⭐ LA BARRA DI ALTERNATIVE, piatta: un filo attorno, i bottoni uguali, e quello acceso si riconosce dal FONDO, non da una pillola
   d'accento — in una colonna di undici pannelli sarebbe un semaforo. Nei pannelli la stessa veste la portano gli interruttori
   ( B I U S accanto agli allineamenti, chiesto da Riccardo il 2026-09-24 ): le due barre di una riga si leggono uguali. */
.radio-bar ,
.button-bar:not( .floating-bar )
{
    flex: 1;
    gap: 1px;
    padding: 1px;
    border: 1px solid var( --hairline );
    border-radius: 5px;
    background: transparent;
}

.radio-bar .button , .button-bar:not( .floating-bar ) .button { height: 20px; border-radius: 3px; }

.radio-bar .button svg.icon { width: 16px; height: 16px; }

.radio-bar .button:hover , .button-bar:not( .floating-bar ) .button:hover { background: var( --bar-active ); }

.radio-bar .button.selected { background: var( --bar-active ); }


/* l'anteprima del tratteggio: una riga, al posto del valore */
.dash-preview { flex: 1; min-width: 0; color: var( --ink-soft ); }

/* ⭐ IL CAMPIONE DI COLORE: un quadratino DIPINTO che apre il selettore di casa. Non e' piu' un `input[type="color"]` del
   sistema ( 2026-09-20 ): quello non sapeva dire l'opacita' e apriva una finestra sua, fuori dalla pagina. Il fondo lo scrive
   `showSwatch`, colore sopra scacchiera. */
.swatch
{
    flex: 0 0 auto;
    width: 22px;
    height: 16px;
    border: 1px solid var( --hairline );
    border-radius: 4px;
    background-clip: padding-box !important;
    cursor: pointer;
}

/* ⚠️ IL FILO SI RITAGLIA SUL PADDING: il fondo di un elemento passa ANCHE SOTTO il bordo, quindi un filo traslucido steso
   sopra un gradiente ne prendeva il colore e di grigio non aveva niente ( visto da Riccardo ). Con `padding-box` il fondo si
   ferma prima e il filo resta quello dei campi.
   ⚠️ E l'`!important` NON e' un vezzo: la vernice la scrive il pannello con `element.style.background = ...`, che e' una
   SCORCIATOIA e rimette `background-clip` al suo valore di partenza a ogni giro. Una dichiarazione importante del foglio vince su
   una inline normale, ed e' l'unico modo di tenere il ritaglio senza toccare ogni punto in cui si dipinge. */
/* ⭐ L'ANTEPRIMA DELLA VERNICE: un quadratino che porta la vernice VERA — un colore, un gradiente, la scacchiera di una trama. E' il
   solo posto del pannello dove si legge « com'e' » senza leggere un valore.
   ⚠️ La scacchiera sotto serve ai colori trasparenti: senza, un `rgba( ... , .2 )` si vedrebbe come un grigio qualunque. */
.paint-preview
{
    position: relative;
    flex: 0 0 auto;
    width: 22px;
    height: 16px;
    border: 1px solid var( --hairline );
    border-radius: 4px;
    background-color: transparent;
    background-clip: padding-box !important;
}

/* ⚠️ LA SCACCHIERA STA SOTTO, in uno strato a parte: la vernice la scrive il pannello con la SCORCIATOIA `style.background`,
   che spazzerebbe via qualunque fondo dichiarato qui. Senza, un gradiente che sfuma nel nulla sembrerebbe sfumare nel bianco. */
.paint-preview::before
{
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: 3px;
    background: repeating-conic-gradient( var( --hairline ) 0% 25% , transparent 0% 50% ) 0 / 8px 8px;
}

/* ⭐ LA STRISCIA DELLE FERMATE ( quella di Illustrator ): la vernice distesa, e sopra un segno per fermata. La scacchiera sotto fa
   vedere le fermate trasparenti — senza, un gradiente che sfuma nel nulla sembrerebbe sfumare nel bianco. */
.gradient-bar
{
    position: relative;
    flex: 1;
    min-width: 0;
    height: 16px;
    border: 1px solid var( --hairline );
    border-radius: 4px;
    background-clip: padding-box !important;
    cursor: pointer;
}

/* ⚠️ la scacchiera sta SOTTO: il gradiente e' il fondo dell'elemento, e questo e' uno strato dietro */
.gradient-bar::before
{
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: 3px;
    background: repeating-conic-gradient( var( --hairline ) 0% 25% , transparent 0% 50% ) 0 / 8px 8px;
}

/* ⭐ IL SEGNO DI UNA FERMATA: un quadratino col suo colore dentro, centrato sul punto in cui sta. Quello SCELTO ha il filo
   d'accento — non un colore diverso, che sarebbe un secondo colore in una striscia che di colori ne ha gia' tanti. */
.gradient-bar .stop
{
    position: absolute;
    top: 50%;
    width: 9px;
    height: 9px;
    margin: -5px 0 0 -5px;
    border: 1px solid var( --bar-surface );
    border-radius: 2px;
    background: var( --stop-color , #000 );
    box-shadow: 0 0 0 1px var( --ink-faint );
}

.gradient-bar .stop.chosen { box-shadow: 0 0 0 2px var( --accent ); }

/* ⚠️ una fermata che sta uscendo dalla striscia si sbiadisce: dice che lasciandola li' se ne va */
.gradient-bar .stop.leaving { opacity: .35; }

/* il bottone dell'inclinazione, in fondo alla striscia */
/* ⚠️ LA STESSA ICONA DELLE PREFERENZE degli altri due menu ( chiesta da Riccardo ): il bottone non apre piu' « l'inclinazione »
   ma la GEOMETRIA del gradiente — verso per un lineare, centro per un radiale — e una freccia curva diceva solo la prima. */
.angle-button { color: var( --ink-soft ); }

/* e quello dello stile del filo, in fondo alla riga dello spessore: l'icona delle preferenze, piccola come tutto il resto */
.icon-button { flex: 0 0 auto; display: flex; align-items: center; }

.icon-button svg.icon { width: 15px; height: 15px; }


/* ⭐ UN BOTTONE A ICONA CHE E' UN INTERRUTTORE SI VEDE ACCESO ( chiesto da Riccardo per il vincolo delle proporzioni ): la
   classe `selected` c'era gia' e non la disegnava nessuno, quindi il modo era attivo senza che si vedesse.
   ⚠️ Fondo d'accento e icona rovesciata, come il bottone acceso della barra degli strumenti: le icone dello sprite sono
   sagome, e tingerle di accento vorrebbe dire inventarsi un filtro per ogni colore. */
.icon-button.selected
{
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: 4px;
    background: var( --accent );
}

.icon-button.selected svg.icon { filter: var( --svg-on-accent-filter ); }

/* ⭐ IL MENU DEL TRATTEGGIO: gli stili uno sotto l'altro, poi i numeri. Le righe le disegnano le stesse regole del menu del filo,
   qui sotto: due menu che mostrano le righe di un pannello hanno la stessa veste. */
/* ⚠️ LARGHEZZA FISSA: le anteprime sono <svg> senza misura intrinseca e il menu, che si dimensiona
   al contenuto, arrivava a 696px. 230 è la larghezza del pannello meno i suoi margini. */

.dash-styles { display: flex; flex-direction: column; gap: 1px; }

/* ⚠️ `box-sizing` e nessun rientro laterale: col conto di serie il 100% era la larghezza PIU' i due fianchi, e le anteprime
   sbordavano dal padding del menu. Senza rientro si incolonnano con le etichette delle righe sotto e col filo. */
.dash-style { display: block; box-sizing: border-box; width: 100%; padding: 3px 0; border-radius: 4px; color: var( --ink ); cursor: pointer; }

.dash-style:hover { background: var( --bar-active ); }



/* ⭐ I QUATTRO ANGOLI, disposti come gli angoli che governano: quattro caselle in due righe, e in mezzo l'aria del rettangolo
   che rappresentano. E' l'interfaccia piu' corta che si possa dare a quattro numeri che hanno un posto nello spazio. */

/* ⚠️ QUATTRO RIGHE UNA SOTTO L'ALTRA ( chiesto da Riccardo ), come ogni altra riga della pagina: slider e casella di fianco.
   ⭐ A dire QUALE angolo e' un quadratino col suo spigolo acceso: quattro parole ( « alto sinistra »... ) sarebbero quattro
   righe di testo per una cosa che si vede. */
/* ⭐ UNA SOLA ICONA, RIBALTATA ( suggerito da Riccardo ): `rounded_corner` disegna l'angolo in ALTO A DESTRA, e gli altri tre
   sono lo stesso segno specchiato — come le quattro direzioni del gradiente sono la stessa freccia girata.
   ⚠️ `rounded_corner` e' nel sottoinsieme del font ( c'e' da 2026-09-07 ): un nome nuovo mostrerebbe la PAROLA. */
/* ⚠️ COME SI RIBALTA LO DICE IL MARKUP ( `--flip` , inline ), come le quattro direzioni del gradiente dicono la loro
   rotazione: qui resta una regola sola, e chi legge la riga vede subito quale angolo e' — senza rincorrere un selettore. */
.corner-mark { flex: 0 0 auto; font-size: 16px; color: var( --ink-soft ); transform: var( --flip , none ); }

/* ⭐ IL SELETTORE DI COLORE ( `graphic-color-picker` ), portato da `xos.css` e rivestito come questa pagina: il riquadro e i due
   cursori restano quelli, la scatola e le misure sono quelle dei menu qui accanto.
   ⚠️ Il riquadro e' UNA tinta con due sfumature sopra — bianco da sinistra, nero dal basso — e la tinta la scrive il JS in
   `--hue`: sono tre fondi sovrapposti, non tre elementi. */

graphic-color-picker { display: flex; flex-direction: column; gap: 8px; width: 180px; }

.sb-panel
{
    position: relative;
    height: 132px;
    border-radius: 6px;
    background: linear-gradient( to top , #000 , rgba( 0 , 0 , 0 , 0 ) ) ,
                linear-gradient( to right , #fff , rgba( 255 , 255 , 255 , 0 ) ) ,
                var( --hue , #f00 );
    cursor: crosshair;
}

/* ⚠️ la maniglia porta IL COLORE SCELTO dentro, con un anello bianco: su un fondo che cambia sotto, un pallino pieno di un
   colore solo sparisce appena ci passa sopra */
.sb-selector
{
    position: absolute;
    width: 12px;
    height: 12px;
    margin: -6px 0 0 -6px;
    border: 2px solid #fff;
    border-radius: 50%;
    box-shadow: 0 0 0 1px rgba( 0 , 0 , 0 , .4 );
    pointer-events: none;
}

/* i due cursori: piu' alti di quelli del pannello, perche' qui il fondo E' il comando — si mira un colore, non un valore */
.picker-menu input[type="range"]
{
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: 10px;
    margin: 0;
    padding: 0;
    border: 1px solid var( --hairline );
    border-radius: 5px;
    background-clip: padding-box !important;
    cursor: pointer;
}

.picker-menu .hue-slider
{
    background: linear-gradient( 90deg , #f00 , #ff0 , #0f0 , #0ff , #00f , #f0f , #f00 );
}

/* l'opacita': il colore scelto che sfuma nel nulla, e sotto la scacchiera che dice cos'e' « niente » */
.picker-menu .alpha-slider
{
    background: var( --paint , linear-gradient( 90deg , transparent , #000 ) ) ,
                repeating-conic-gradient( var( --ink-faint ) 0% 25% , transparent 0% 50% ) 0 / 8px 8px;
}

.picker-menu input[type="range"]::-webkit-slider-thumb
{
    -webkit-appearance: none;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    border: 2px solid #fff;
    box-shadow: 0 0 0 1px rgba( 0 , 0 , 0 , .4 );
    background: transparent;
    cursor: pointer;
}

.picker-menu input[type="range"]::-moz-range-thumb
{
    width: 12px;
    height: 12px;
    border-radius: 50%;
    border: 2px solid #fff;
    box-shadow: 0 0 0 1px rgba( 0 , 0 , 0 , .4 );
    background: transparent;
    cursor: pointer;
}

/* la casella dell'esadecimale: la veste delle altre caselle, centrata perche' qui il valore e' tutto quel che c'e' */
.picker-menu .hex-input
{
    box-sizing: border-box;
    width: 100%;
    padding: 3px 5px;
    border: 1px solid var( --hairline );
    border-radius: 4px;
    background: transparent;
    color: var( --ink );
    font: inherit;
    font-size: 11px;
    text-align: center;
    text-transform: uppercase;
    font-variant-numeric: tabular-nums;
}

.picker-menu .hex-input:focus { outline: none; border-color: var( --accent ); background: var( --bar-active ); }

/* ⭐ LA ROTELLA DELL'INCLINAZIONE, dentro il menu: un cerchio, un raggio e un pallino che si trascina. Le due variabili le scrive
   il pannello ( `showDial` ), che e' l'unico a sapere dove punta il gradiente. */

.angle-dial
{
    position: relative;
    width: 84px;
    height: 84px;

    /* ⭐ un po' d'aria sotto la rotella, prima delle direzioni: sono due comandi diversi e non devono sembrare una cosa sola */
    margin-bottom: 5px;
    border: 1px solid var( --hairline );
    border-radius: 50%;
    background: var( --bar-active );
    background-clip: padding-box !important;
    cursor: grab;
}

/* ⭐ LA FACCIA DEL RADIALE: un RIQUADRO, non un cerchio ( chiesto da Riccardo ). E' il riquadro dell'oggetto visto da vicino, e
   il pallino sta dove sta il centro del gradiente — quindi lo si porta dove si vuole, anche in un angolo. Niente raggio disegnato:
   li' non c'e' niente da girare. */
.angle-dial.radial { border-radius: 6px; cursor: crosshair; }

.angle-dial.radial::before { display: none; }

/* il raggio: dal centro al pallino */
.angle-dial::before
{
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 50%;
    height: 1px;
    background: var( --ink-faint );
    transform-origin: 0 50%;
    rotate: var( --dot-angle , 0deg );
}

/* ⚠️ la maniglia sta SUL bordo, quindi sborda di mezzo pallino: il menu ha il suo padding e non la taglia */
.angle-dial > i
{
    position: absolute;
    left: var( --dot-x , 100% );
    top: var( --dot-y , 50% );
    width: 11px;
    height: 11px;
    margin: -6px 0 0 -6px;
    border-radius: 50%;
    background: var( --accent );
    box-shadow: 0 0 0 2px var( --bar-surface );
}

/* ⭐ LE QUATTRO DIREZIONI SONO QUATTRO CAMPIONI del gradiente che si sta girando ( chiesto da Riccardo ): il fondo lo scrive
   `showDial`. ⚠️ Percio' la scelta NON si puo' dire col fondo del bottone, che ora e' il campione: la dice un anello
   d'accento attorno, cioe' il padding del bottone che si colora. */

.angle-menu .radio-bar .button:hover { background: var( --bar-active ); }

.angle-menu .radio-bar .button.selected { background: var( --accent ); }

.angle-sample { display: block; box-sizing: border-box; width: 100%; height: 100%; border: 1px solid var( --hairline ); border-radius: 3px; background-clip: padding-box !important; }

/* ⭐ LA CROCETTA DEL PERNO: un riquadro con nove punti, quello acceso e' il punto che resta fermo. ⚠️ Il riquadro dentro
   GIRA come l'oggetto ( lo scrive `updateProperties` ), cosi' si sceglie su quel che si vede e non su uno schema. */
.pivot-display { flex: 0 0 auto; width: 40px; display: flex; align-items: center; justify-content: center; }

.pivot-box
{
    position: relative;
    width: 30px;
    height: 30px;
    border: 1px solid var( --hairline );
    border-radius: 2px;
}

.pivot-box > i
{
    position: absolute;
    width: 9px;
    height: 9px;
    margin: -4.5px 0 0 -4.5px;
    border-radius: 50%;
    cursor: pointer;
}

/* ⚠️ I NOVE PUNTI SI VEDONO, ma appena: invisibili non direbbero che li' si sceglie qualcosa, pieni sarebbero una macchia in
   20 px di lato. Il perno scelto e' l'unico con un colore. */
.pivot-box > i::after { content: ""; position: absolute; inset: 2.5px; border-radius: 50%; background: var( --ink-faint ); opacity: .45; }

.pivot-box > i:hover::after { opacity: .75; }

.pivot-box > i.selected::after { opacity: 1; background: var( --accent ); }

.pivot-box > [data-pivot="nw"] { left: 0; top: 0; }
.pivot-box > [data-pivot="n"] { left: 50%; top: 0; }
.pivot-box > [data-pivot="ne"] { left: 100%; top: 0; }
.pivot-box > [data-pivot="w"] { left: 0; top: 50%; }
.pivot-box > [data-pivot="center"] { left: 50%; top: 50%; }
.pivot-box > [data-pivot="e"] { left: 100%; top: 50%; }
.pivot-box > [data-pivot="sw"] { left: 0; top: 100%; }
.pivot-box > [data-pivot="s"] { left: 50%; top: 100%; }
.pivot-box > [data-pivot="se"] { left: 100%; top: 100%; }

/* ⭐ LA GEOMETRIA E' UNA GRIGLIA SOLA: etichetta, il posto del vincolo, e DUE colonne di numeri. A flex ogni riga si distribuiva
   per conto suo, e una riga con un numero solo ( la scala, la rotazione ) non si incolonnava con quelle che ne hanno due ( visto
   da Riccardo ). ⚠️ La colonna del vincolo c'e' in TUTTE le righe, vuota dove non serve: e' quella che tiene i numeri
   allineati.
   ⚠️ E le righe ci si SCIOLGONO dentro ( `display: contents` ) invece di essere ognuna la sua griglia: e' l'unico modo perche'
   un elemento — la crocetta del perno — possa prendersi la colonna di destra per DUE righe. */
.content.geometry-grid
{
    display: grid;
    grid-template-columns: 54px 16px 1fr 1fr;
    align-items: center;
    column-gap: 12px;
    row-gap: 4px;

    /* ⛔ LE RIGHE NON SI STIRANO: una griglia distribuisce l'altezza che avanza fra le sue righe, e ridimensionando il pannello
       le righe si spaziavano ( visto da Riccardo ). `align-content: start` le tiene alla loro misura, impilate in alto — che e'
       quel che fanno le righe flex di ogni altro pannello. */
    align-content: start;

    /* ⚠️ TUTTE LE RIGHE ALTE UGUALE, dichiarato: altrimenti ognuna prende l'altezza di quel che porta — una casella e'
       22 px, un interruttore 16 — e l'ultima riga cadeva piu' vicina alla penultima ( visto da Riccardo ).
       ⚠️ L'ALTEZZA invece e' AUTOMATICA ( chiesto da Riccardo ): il pannello e' alto quanto le righe che ha davvero, e con un
       oggetto solo — dove la riga di « ognuno » non c'e' — non resta un vuoto in fondo. A tenere le righe alla loro misura
       quando il pannello viene tirato in basso e' `align-content: start`, non una misura scritta. */
    grid-auto-rows: 22px;
}

.content.geometry-grid > .input-property.row { display: contents; }

/* ⚠️ OGNI CELLA DICHIARA LA SUA COLONNA: con le righe sciolte, la disposizione automatica riempirebbe i buchi lasciati dalla
   crocetta e le righe si sfalserebbero. */
.content.geometry-grid > .row > :nth-child( 1 ) { grid-column: 1; }
.content.geometry-grid > .row > :nth-child( 2 ) { grid-column: 2; }
.content.geometry-grid > .row > :nth-child( 3 ) { grid-column: 3; }
.content.geometry-grid > .row > :nth-child( 4 ) { grid-column: 4; }

.content.geometry-grid input[type="text"] { width: 100%; min-width: 0; min-height: 22px; text-align: right; }

.content.geometry-grid .slot { width: 16px; height: 16px; }

.content.geometry-grid input[type="checkbox"] { justify-self: end; }

/* ⭐ IL TIPO DEL PUNTO ( pannello Point ): una parola, sulle due colonne dei numeri */
point-properties .content.geometry-grid > .row > .point-kind { grid-column: 3 / 5; justify-self: end; color: var( --ink-soft ); }

/* ⭐ LA CROCETTA DEI CAPI: tre punti su una riga, girata come l'oggetto. ⚠️ Stessa scatola di quella del riquadro — la stessa
   colonna, le stesse due righe — perche' e' la stessa domanda: quale punto resta fermo. */
.pivot-line
{
    position: relative;
    width: 30px;
    height: 1px;
    background: var( --hairline );
}

.pivot-line > i
{
    position: absolute;
    top: 50%;
    width: 9px;
    height: 9px;
    margin: -4.5px 0 0 -4.5px;
    border-radius: 50%;
    cursor: pointer;
}

.pivot-line > i::after { content: ""; position: absolute; inset: 2.5px; border-radius: 50%; background: var( --ink-faint ); opacity: .45; }

.pivot-line > i:hover::after { opacity: .75; }

.pivot-line > i.selected::after { opacity: 1; background: var( --accent ); }

.pivot-line > [data-pivot="start"] { left: 0; }
.pivot-line > [data-pivot="center"] { left: 50%; }
.pivot-line > [data-pivot="end"] { left: 100%; }

/* ⭐ LA CROCETTA prende la colonna di destra per le due righe di rotazione e scala: e' il perno di tutte e due.
   ⚠️ L'ARIA A DESTRA NON E' COSMETICA ( chiesta da Riccardo ): il riquadro GIRA come l'oggetto, e un quadrato girato sporge
   dal suo ingombro dritto — fino a mezza diagonale meno mezzo lato, che su 30 px fa circa 6 — quindi a 45° gli angoli
   arrivavano addosso al bordo del pannello. */
.content.geometry-grid > .pivot-display
{
    grid-column: 4;
    justify-self: end;
    align-self: center;
    margin-right: 10px;
}

/* ⚠️ QUALI DUE RIGHE lo dice il pannello: nel riquadro il perno e' di rotazione e scala ( la terza e la quarta ), nei capi di
   lunghezza e rotazione ( la seconda e la terza ). La scatola e la colonna restano le stesse. */
rectangular-properties .content.geometry-grid > .pivot-display { grid-row: 3 / span 2; }

linear-properties .content.geometry-grid > .pivot-display { grid-row: 2 / span 2; }

/* ⚠️ IL FILO CHE DIVIDE I BLOCCHI, non la cornice del browser: quello di serie e' una riga a rilievo e si vedeva piu' dei comandi
   che separa ( visto da Riccardo ). E' lo stesso `--hairline` di ogni altra divisione della pagina. */
hr { margin: 8px 0; border: 0; border-top: 1px solid var( --hairline ); }

/* la riga di dettaglio: rientrata sotto la sua, e senza etichetta */
.detail > .label { flex: 0 0 54px; }

/* ⭐ ...salvo le righe del GRADIENTE, che vanno da bordo a bordo: la striscia e' il disegno della vernice, e un disegno schiacciato
   in un terzo di riga non si legge ( chiesto da Riccardo il 2026-09-20 ). */
.detail.wide { gap: 6px; }

/* tre cifre: posizione, trasparenza, inclinazione */
input.tiny { flex: 1 1 0; min-width: 0; text-align: center; }

/* ⭐ LA TENDINA: la stessa riga degli altri comandi, senza la veste di sistema. La freccia la disegna un fondo, che e' il modo di
   `xos.css` — azzerando `appearance` sparisce anche quella. */
select
{
    appearance: none;
    flex: 1;
    min-width: 0;
    box-sizing: border-box;
    padding: 2px 18px 2px 5px;
    border: 1px solid transparent;
    border-radius: 4px;
    background: transparent;
    background-image: linear-gradient( 45deg , transparent 50% , currentColor 50% ) , linear-gradient( 135deg , currentColor 50% , transparent 50% );
    background-position: right 8px center , right 4px center;
    background-size: 4px 4px , 4px 4px;
    background-repeat: no-repeat;
    color: var( --ink );
    font: inherit;
    font-size: 11px;
    text-align: right;
    cursor: pointer;
}

select:hover { border-color: var( --hairline ); }

select:focus { outline: none; border-color: var( --accent ); }

/* ⭐ I FONT SONO UN ELENCO, non una griglia: la cella e' una riga larga quanto il pannello, col NOME della famiglia scritto con la famiglia
   stessa. Un nome lungo si taglia con i puntini. */
font-panel.panel > .resource-grid { grid-template-columns: 1fr; gap: 4px; }

/* la barra delle fonti ( Google, Local, Document ): la testata della colonna Font */
.font-sources > .button { font-size: 11px; color: var( --ink-soft ); }
.font-sources > .button.selected { color: var( --ink ); }

font-panel .resource-cell { aspect-ratio: auto; justify-content: flex-start; padding: 4px 8px; }

/* ⭐ I WIDGET: anteprime quadrate da 66 px, il doppio dei colori ( chiesto da Riccardo il 2026-10-01 ), quante ne stanno; si trascinano */
widget-panel.panel > .resource-grid { grid-template-columns: repeat( auto-fill , 66px ); gap: 8px; }

widget-panel .resource-cell { cursor: grab; }

.resource-cell > .font-sample
{
    display: flex;
    align-items: center;
    font-size: 18px;
    color: #111111;
    line-height: 1.5;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ⭐ LA ZONA DOVE SI LASCIA UNA RISORSA ( pannelli Use e Markers ): il suo id in una casella tratteggiata, accesa quando ci passa sopra una
   risorsa del tipo giusto trascinata dal suo pannello. */
.resource-drop { box-sizing: border-box; width: 100%; padding: 2px 5px; border: 1px dashed var( --hairline ); border-radius: 4px;
               color: var( --ink ); font-size: 11px; text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.resource-drop.drag-over { border-style: solid; border-color: var( --accent ); background: var( --bar-active ); }

/* la × che toglie la risorsa, accanto alla zona */
.resource-drop + .button { flex: none; margin-left: 2px; cursor: pointer; }

/* i parametri del filtro ( `GraphicNodeFilter.updateParameters` ): una testata per primitiva, poi le sue righe */
.filter-parameters .filter-name { margin-top: 8px; padding-top: 6px; border-top: 1px solid var( --hairline ); font-weight: 600; cursor: grab; }
.filter-parameters .filter-name:first-child { margin-top: 0; padding-top: 0; border-top: none; }
.filter-parameters .filter-name .label { flex: 1; color: var( --ink ); }
.filter-parameters .filter-name .button { cursor: pointer; }
.filter-parameters .filter-name .button.activator { font-size: 16px; color: var( --ink-faint ); margin-right: 2px; }
/* la × di un filtro ha la misura di quella della testata del pannello ( `.button.close` ), che qui non si puo' usare: in colonna e' nascosta */
.filter-parameters .filter-name .button.remove { font-size: 16px; color: var( --ink-faint ); }
/* dove cade la testata trascinata: un filo d'accento sopra o sotto */
.filter-parameters .filter-name.drop-before { box-shadow: inset 0 2px 0 var( --accent ); }
.filter-parameters .filter-name.drop-after { box-shadow: inset 0 -2px 0 var( --accent ); }

/* ⭐ IL DRAG DELLE RIGHE DEL DOCUMENTO: le regole di xos.css, che l'editor non carica — dove cade la riga ( sopra, sotto, dentro ) */
.tree-view li.dragging > .node-info { opacity: 0.4; }
.tree-view li.drop-before > .node-info { box-shadow: 0 -2px 0 var( --accent ); }
.tree-view li.drop-after > .node-info { box-shadow: 0 2px 0 var( --accent ); }
.tree-view .node-info.drop-center { outline: 1px solid var( --accent ); outline-offset: -1px; }
.filter-parameters .filter-primitive { margin: 10px 0 2px; font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var( --ink-soft ); }
.filter-parameters:empty { display: none; }

/* il canale di un `feComponentTransfer` ( « RGB », « A » ) sopra i suoi campi; e un'etichetta che non ci sta finisce coi puntini ( il testo
   intero nel `title` ), invece di uscire sotto il campo */
.filter-parameters .filter-channel { margin: 6px 0 0; font-size: 10px; font-weight: 600; color: var( --ink-soft ); }
/* ⚠️ 68 px e non i 54 degli altri pannelli ( come Project ha i suoi 88 ): « Saturation » ne misura 66, « Intercept » e « Amplitude » 60 */
.filter-parameters .input-property > .label { flex-basis: 68px; overflow: hidden; text-overflow: ellipsis; }

/* ⭐ L'INTERRUTTORE, quello dei telefoni ( chiesto da Riccardo il 2026-09-20 ): e' la stessa `input[type="checkbox"]` del markup —
   il controller, la spunta e la tastiera non cambiano — con la veste rifatta da zero ( `appearance: none` ) e il pallino che scorre.
   ⚠️ Le misure discendono dall'ALTEZZA: raggio a meta', pallino due pixel piu' piccolo per lato, corsa = larghezza − altezza.
   Cambiando `--switch-h` si rifa' tutto da se'. */
input[type="checkbox"]
{
    --switch-h: 14px;
    --switch-w: 26px;

    appearance: none;
    flex: 0 0 auto;
    margin: 0 0 0 auto;
    position: relative;
    width: var( --switch-w );
    height: var( --switch-h );
    border-radius: calc( var( --switch-h ) / 2 );
    background: var( --bar-active );
    border: 1px solid var( --hairline );
    box-sizing: border-box;
    cursor: pointer;
    transition: background-color .15s ease , border-color .15s ease;
}

input[type="checkbox"]::after
{
    content: "";
    position: absolute;
    top: 1px;
    left: 1px;
    width: calc( var( --switch-h ) - 4px );
    height: calc( var( --switch-h ) - 4px );
    border-radius: 50%;
    background: var( --bar-surface );
    box-shadow: 0 1px 2px rgba( 0 , 0 , 0 , .30 );
    transition: transform .15s ease;
}

input[type="checkbox"]:checked { background: var( --accent ); border-color: transparent; }

/* la corsa: la larghezza meno l'altezza, cioe' il pallino che va da un capo all'altro */
input[type="checkbox"]:checked::after { transform: translateX( calc( var( --switch-w ) - var( --switch-h ) ) ); background: var( --on-accent ); }

input[type="checkbox"]:hover { border-color: var( --ink-faint ); }

/* ⚠️ il fuoco si vede: e' un comando che si prende anche col tasto di tabulazione */
input[type="checkbox"]:focus-visible { outline: 2px solid var( --accent ); outline-offset: 2px; }



/* ══ IL MENU DEL TASTO DESTRO ═══════════════════════════════════════════════════════════════════════════════════════════════════
   I pezzi sono quelli di XOS ( `popup-menu`, `menu-item`, e il `::after` che disegna la scorciatoia secondo la piattaforma ), la
   veste e' quella di questa pagina: piccolo, piatto, monospaziato, un filo a dividere. ⛔ Le misure di `xos.css` — 13px, padding 20,
   raggio 16, voci alte 24 — qui sarebbero un menu di sistema in mezzo a una barra di strumenti da 11px. */

graphic-menus
{
    position: fixed;
    inset: 0;
    display: none;
    z-index: 300;
}

.menu
{
    position: absolute;
    display: flex;
    flex-direction: column;
    gap: 1px;

    padding: 5px;
    min-width: 188px;

    background: var(--bar-surface);
    border: 1px solid var(--hairline);
    border-radius: 10px;
    box-shadow: var(--bar-shadow);

    font-family: var(--mono);
    font-size: 11px;
    color: var(--ink);
}

.menu.scrollable { top: 8px; bottom: 8px; overflow-y: auto; }

/* ⛔ SI VEDE SOLO IL MENU APERTO: `PopupMenu.open()` accende `showed` su di se' e mostra il CONTENITORE ( il velo ), quindi senza
   questa riga aprendo un menu comparivano anche gli altri — il menu del tasto destro spuntava in alto a sinistra insieme alla
   rotella ( visto il 2026-09-20 ). In `xos.css` la regola c'e'; qui il foglio e' nostro, e va portata. */
graphic-menus > *:not( .showed ) { display: none !important; }

.menu hr
{
    margin: 4px 6px;
    border: 0;
    border-top: 1px solid var(--hairline);
}

menu-item
{
    display: flex;
    align-items: center;
    gap: 14px;

    padding: 4px 8px;
    min-height: 20px;
    border-radius: 6px;

    cursor: default;
    white-space: nowrap;
}

/* l'etichetta prende lo spazio, la scorciatoia resta a destra incolonnata */
menu-item > div { flex: 1; }

/* ⭐ LA FRECCIA DI UN SOTTOMENU: sta in fondo alla voce e non si allarga come l'etichetta, e la voce accesa la porta con sé */
menu-item > .submenu-arrow { flex: 0 0 auto; margin-right: -4px; font-size: 16px; opacity: .55; }

menu-item:hover > .submenu-arrow { opacity: 1; }

/* ⚠️ una voce che apre un sottomenu resta accesa finché il sottomenu è aperto: `PopupMenu.open` le mette `highlighted` */
menu-item.highlighted { background: var(--accent); color: var(--on-accent); }

menu-item.highlighted > .submenu-arrow { opacity: 1; }

menu-item:hover { background: var(--accent); color: var(--on-accent); }

/* ⭐ LA SCORCIATOIA LA DISEGNA IL CSS DAGLI ATTRIBUTI, e secondo la PIATTAFORMA: `data-platform` lo scrive `xos-dom.js` su <html>,
   e non si aggiunge nessuno sniffing dello user agent. Sono le righe di `xos.css`, con il nostro grigio. */
menu-item::after
{
    content: attr(data-shortcut-key);
    color: var(--ink-faint);
    font-size: 10.5px;
    letter-spacing: .02em;
}

menu-item:hover::after { color: var(--on-accent); opacity: .8; }

html[data-platform="MacIntel"] .menu [data-shortcut-modifiers~="cmd"]::after           { content: "⌘" attr(data-shortcut-key); }
html[data-platform="MacIntel"] .menu [data-shortcut-modifiers~="cmd-shift"]::after     { content: "⌘⇧" attr(data-shortcut-key); }
html[data-platform="MacIntel"] .menu [data-shortcut-modifiers~="cmd-alt"]::after       { content: "⌘⌥" attr(data-shortcut-key); }
html[data-platform="MacIntel"] .menu [data-shortcut-modifiers~="cmd-alt-shift"]::after { content: "⌘⌥⇧" attr(data-shortcut-key); }

html:not([data-platform="MacIntel"]) .menu [data-shortcut-modifiers~="cmd"]::after           { content: "Ctrl+" attr(data-shortcut-key); }
html:not([data-platform="MacIntel"]) .menu [data-shortcut-modifiers~="cmd-shift"]::after     { content: "Ctrl+Shift+" attr(data-shortcut-key); }
html:not([data-platform="MacIntel"]) .menu [data-shortcut-modifiers~="cmd-alt"]::after       { content: "Ctrl+Alt+" attr(data-shortcut-key); }
html:not([data-platform="MacIntel"]) .menu [data-shortcut-modifiers~="cmd-alt-shift"]::after { content: "Ctrl+Alt+Shift+" attr(data-shortcut-key); }

/* ⚠️ Il tasto di cancellazione si chiama in due modi: `⌫` sul Mac, `Del` altrove. E il simbolo NON sta nel nostro font — il
   sottoinsieme e' latino — ma sul Mac il ripiego di sistema ce l'ha; su Windows non serve, perche' li' si legge `Del`. */
html[data-platform="MacIntel"] .menu [data-command="delete"]::after { content: "⌫"; font-size: 12px; }


/* ⭐ IL CAMPO IN CUI SI SCRIVE UNA CELLA DI TABELLA ( `GraphicTableCellPointer` ): sopra la cella, nel suo riferimento ( `transform`, dall'angolo in alto a
   sinistra ), trasparente — si vedono la griglia e le fasce —, senza bordi ne' margini: il testo cade dove lo dipinge la vista. */
.graphic-cell-input
{
    display: none;
    position: fixed;
    left: 0;
    top: 0;
    z-index: 5;

    transform-origin: 0 0;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    outline: none;
    background: transparent;
    resize: none;
    overflow: hidden;
    white-space: pre-wrap;
    overflow-wrap: normal;
    word-break: normal;
}

/* ⭐ LA CASELLA CHE TIENE QUEL CHE SI SCRIVE ( `GraphicDrawTextPointer` ): sta fuori dallo schermo, non si vede e non si puo' toccare,
   ma PUO' PRENDERE IL FUOCO — con `display: none` non arriverebbe nessun tasto, e con `visibility: hidden` nemmeno. ⚠️ Un pixel e non
   zero: una casella senza area, in qualche browser, il fuoco non lo prende. */
.graphic-text-input
{
    position: fixed;
    left: -9999px;
    top: 0;

    width: 1px;
    height: 1px;

    opacity: 0;
    border: 0;
    padding: 0;
    resize: none;
}



/* ══ LE BARRE SOPRA LA TELA — LA SECONDA ( E ULTIMA ) TIPOLOGIA ══════════════════════════════════════════════════════════════
   ⭐ Tutto il resto della pagina — riga, etichetta, casella, tendina, slider, barra di alternative — è scritto UNA volta sola e
   senza contenitore: un campo in un pannello e lo stesso campo in un menu sono lo stesso campo. Qui c'è l'unica cosa che la
   veste generale NON descrive: le barre che stanno sopra la tela, dove i bottoni sono grandi da centrare col puntatore e le
   caselle hanno la loro scatola, perché galleggiano sul disegno invece di stare in una riga.

   ⛔ E STA IN FONDO AL FOGLIO APPOSTA: quasi tutte queste regole pesano quanto quelle generali ( `.floating-bar .button` vale
   (0,2,0) come `.radio-bar .button` ), quindi a decidere è L'ORDINE. Spostandola più su, i bottoni delle barre tornano alti
   20px come quelli di un pannello — misurato il 2026-09-20, e non si vede finché non si apre la sotto-barra di uno strumento.
   ══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════ */

/* ⭐ UNA BARRA E' UNA BARRA, sopra o sotto che sia: la veste e' scritta UNA volta per `.floating-bar`, e la portano sia la barra degli
   strumenti sia le barre che compaiono sotto di lei ( `tool-options` ). ⛔ Se la si duplica, la seconda copia diverge alla prima
   modifica — ed e' successo: le due barre erano gia' due elenchi di regole uguali.

   Gli strumenti sono quelli della pianta ( `res/ui/ui-tools.php` ): stesse icone dello sprite, stessi titoli, stesso ordine, ma in
   riga. Pareti e pavimenti non ci sono — sono fuori dal binario grafico — e pan e zoom neanche: la vista si sposta col tasto destro o
   la barra spaziatrice e si ingrandisce con la rotella. Gli strumenti che l'editor non ha ancora sono spenti e si accendono quando
   arrivano: la barra dice fin dall'inizio cosa ci sara', e dove. */
.floating-bar
{
    display: flex;
    flex-flow: row nowrap;
    align-items: center;
    gap: 2px;
    padding: 5px;
    border-radius: 12px;
    background: var(--bar-surface);
    border: 1px solid var(--hairline);
    box-shadow: var(--bar-shadow);
}

/* la barra degli strumenti e' una barra che sta sopra la tela, in alto a sinistra */
.graphic-tools
{
    position: fixed;
    top: 30px;
    left: 30px;
}

/* ⭐ I RIGHELLI ( `GraphicRuler` ): strisce di 16 px sopra il bordo alto e il sinistro della tela, nella sua cella della griglia — non la
   stringono, e le coordinate della tela restano quelle della pagina. Il `color` e' l'inchiostro di tacche e numeri: il righello lo legge
   quando si ridisegna, e il filo verso la tela lo disegna lui ( un bordo CSS stringerebbe il canvas di un pixel ). La barra degli strumenti scende di 16 px per lasciarli liberi. */
graphic-ruler , .ruler-corner
{
    grid-row: 1;
    grid-column: 1;
    z-index: 5;
    box-sizing: border-box;
    background: var(--bar-surface);
    color: var(--ink-faint);
}

graphic-ruler > canvas { display: block; width: 100%; height: 100%; }

graphic-ruler.horizontal { align-self: start; height: 16px; margin-left: 16px; }

graphic-ruler.vertical { justify-self: start; width: 16px; margin-top: 16px; }

/* ⭐ l'angolo e' la presa dell'origine della pagina ( `GraphicPageOriginPointer` ) */
.ruler-corner { align-self: start; justify-self: start; width: 16px; height: 16px; border-right: 1px solid var(--hairline); border-bottom: 1px solid var(--hairline); cursor: crosshair; }

/* ⭐ L'USCITA DAL CONTENITORE: una parola col contorno dell'accento, larga quanto lei ( chiesto da Riccardo il 2026-09-22 ). Deve
   vedersi: dice che si e' dentro qualcosa e che il resto del disegno e' nascosto per questo. */
.floating-bar .button.exit-button
{
    width: auto;
    padding: 0 10px;
    box-sizing: border-box;
    border: 1.5px solid var( --accent );
    color: var( --accent );
    font-size: 12px;
    font-weight: 600;
}

/* ⚠️ un'icona inline lascia sotto di se' lo spazio della riga: il bottone era alto 35 px per 28 di icona, e l'icona stava 3,5 px sopra
   il centro della barra. Da flex, il bottone e' alto quanto l'icona. */
.floating-bar .button
{
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    border-radius: 8px;
    opacity: 1;
    transition: background-color .12s ease;
}

.floating-bar .button:hover { background: var(--bar-hover); }

/* ⭐ L'ACCENTO E' DELLO STRUMENTO IN MANO, e di lui soltanto: quello si vede da lontano, perche' governa cosa fa il prossimo gesto.
   ⛔ Un'opzione accesa — un modo, un interruttore — NON e' uno strumento: resta sul fondo grigio, o il colore direbbe due cose diverse
   nello stesso momento. A distinguerli e' `data-pointer`, che ce l'ha solo chi e' uno strumento. */
.floating-bar .button.selected { background: var(--bar-active); }

.floating-bar .button[data-pointer].selected { background: var(--accent-color); }

/* l'icona a riposo e' la stessa, in `--ink-soft` ( regola di `svg.icon` ): uno strumento che non e' in mano si riconosce comunque */
.floating-bar .button svg.icon { width: 20px; height: 20px; }


.floating-bar .button[data-pointer].selected svg.icon { filter: var(--svg-on-accent-filter); }

/* ⚠️ `xos.css` spegne un bottone portandolo a opacita' .2, e su questo fondo chiaro sparisce: qui si legge che c'e' e che non
   risponde. Il peso lo porta l'icona, non il bottone. */
.floating-bar .button.disabled { opacity: 1; }
.floating-bar .button.disabled svg.icon { opacity: .22; }

/* ⚠️ anche il glifo Material: senza, un bottone spento col glifo si leggeva acceso. ⛔ Annulla e ripeti non si spengono mai. */
.floating-bar .button.disabled > .icon.material-symbols-outlined { opacity: .22; }

/* i gruppi separati da un filo verticale */
.floating-bar hr { width: 0; height: 18px; margin: 0 5px; border-top: none; border-left: 1px solid var(--hairline); }

/* il nome del progetto in testa alla barra: una riga sola, tagliata se e' lungo */
.floating-bar .project-name
{
    max-width: 180px;
    padding: 0 8px 0 6px;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    font-size: 12px;
    font-weight: 600;
    color: var(--ink);
}

/* ⭐ SALVATO: il nome lampeggia tre volte nell'accento ( `flashProjectName` ), al posto di un dialogo da chiudere; in rosso se il
   salvataggio e' fallito */
.floating-bar .project-name.saved { animation: project-saved .5s ease-in-out 3; }
.floating-bar .project-name.save-failed { animation: project-save-failed .5s ease-in-out 3; }

@keyframes project-saved { 50% { color: var( --accent ); } }
@keyframes project-save-failed { 50% { color: var( --error ); } }

/* il glifo Material nella stessa scatola delle icone dello sprite */
.floating-bar .button > .icon.material-symbols-outlined
{
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    font-size: 20px;
    line-height: 1;
    color: var(--ink-soft);
}

.floating-bar .button:hover > .icon.material-symbols-outlined { color: var(--ink); }

.floating-bar .button.selected > .icon.material-symbols-outlined { color: var(--ink); }

.floating-bar .button[data-pointer].selected > .icon.material-symbols-outlined { color: var(--on-accent); }

/* ⚠️ `undo` e `redo` hanno l'inchiostro mezzo pixel SOTTO il centro della scatola ( 10px sopra, 9 sotto; gli altri glifi della barra
   sono centrati — misurato con `measureText` ). Si alzano di un pixel: mezzo per centrarli, e mezzo OTTICO ( chiesto da Riccardo ),
   perche' la curva, che pesa di piu', sta in basso e la punta in alto. */
.floating-bar .button[data-command="undo"] > .icon.material-symbols-outlined ,
.floating-bar .button[data-command="redo"] > .icon.material-symbols-outlined { translate: 0 -1px; }

/* ⚠️ `radio-bar` di `xos.css` porta un fondo, un raggio e i suoi spazi, e ARROTONDA il primo e l'ultimo bottone per farne un blocco
   unico: qui la veste e' quella della barra e i bottoni sono tutti uguali. Di `radio-bar` resta il significato — accendendone una si
   spengono le altre. */
/* ⛔ E LA BARRA SI MISURA SUL SUO CONTENUTO, non sul contenitore: `.radio-bar` generale porta `width: 100%`, e una sotto-barra
   che la indossa restava larga quanto la scatola di `tool-options` ( 195px ) schiacciando i bottoni a 20px — la barra della
   matita aveva i bottoni piu' stretti di quelli della barra principale ( visto da Riccardo il 2026-09-20 ). */
.floating-bar.radio-bar { flex: 0 1 auto; width: auto; padding: 5px; border: 1px solid var(--hairline); border-radius: 12px; background: var(--bar-surface); }

.floating-bar .radio-bar ,
.floating-bar .button-bar { flex: 0 1 auto; padding: 0; border: none; background: transparent; }

.floating-bar .radio-bar .button ,
.floating-bar .button-bar .button { width: 30px; height: 30px; border-radius: 8px; }

.floating-bar .radio-bar .button svg.icon ,
.floating-bar .button-bar .button svg.icon { width: 20px; height: 20px; }

/* ⚠️ Le tre regole di `radio-bar` sul bottone ACCESO hanno specificita' (0,3,0) e (0,3,1) — fondo d'accento, raggio da pillola, testo
   bianco, icona invertita —, quindi non basta arrivare dopo: bisogna scrivere piu' stretto. Il bottone acceso di una barra e' lo stesso
   dappertutto. */
.floating-bar.radio-bar > * ,
.floating-bar.radio-bar .button.selected { border-radius: 8px; }

.floating-bar.radio-bar .button.selected ,
.floating-bar.button-bar .button.selected
{
    background-color: var(--bar-active);
    color: var(--ink);
}

.floating-bar.radio-bar .button.selected svg ,
.floating-bar.button-bar .button.selected svg { filter: none; opacity: 1; }

/* ⚠️ `button-bar` di `xos.css` porta un `gap` suo: qui le misure sono quelle della barra, e l'aria fra due interruttori la si tiene */
.floating-bar.button-bar { gap: 5px; }

.floating-bar.button-bar > * { border-radius: 8px; }

/* ⭐ LA SOTTO-BARRA DEGLI ALLINEAMENTI ha le misure della barra principale: lo stesso passo fra i bottoni ( sono comandi, non
   interruttori da tenere distanti ) e lo stesso INCHIOSTRO. ⚠️ I glifi `align_*` e `*_distribute` a 20px disegnano 16x16, le icone
   dello sprite della barra 8-13px e `undo` 12x11 ( misurato con `measureText` e `getBBox` ): a 15px fanno 12, come le altre. */
.floating-bar.button-bar[data-for="arrange-options"] { gap: 2px; }

arrange-bar.floating-bar .button > .icon.material-symbols-outlined ,
.floating-bar .button[data-options="arrange-options"] > .icon.material-symbols-outlined { font-size: 15px; }

/* ⭐ UNA MISURA DENTRO UNA BARRA: etichetta e casella in riga, senza la colonna fissa che la riga generale mette. Da qui in
   giu' la barra dichiara quello che NON condivide con pannelli e menu — e' la seconda ( e ultima ) tipologia della pagina. */
.floating-bar .input-property.flex-row ,
.floating-bar .input-property
{
    flex-flow: row nowrap;
    align-items: center;
    gap: 6px;
    margin: 0 4px 0 6px;
    padding: 0;
}

.floating-bar .input-property > .label
{
    flex: 0 0 auto;
    min-width: 0;
    opacity: 1;
    font-size: 11px;
    color: var(--ink-soft);
    white-space: nowrap;
}

/* ⚠️ LA LARGHEZZA DI UNA CASELLA LA DICE `size` NEL MARKUP, non questo foglio: un `<input>` e' un elemento con una larghezza
   INTRINSECA ( venti caratteri, se non si dice altro ) e come figlio flex non scende sotto di quella — `flex-basis` da solo non lo
   stringe. In dp7 il `min-width: 0` che lo avrebbe permesso e' stato tolto apposta: un campo non deve scendere sotto il proprio
   contenuto. Qui si scrive quante cifre ci vanno, e la casella viene di conseguenza. */
.floating-bar .input-property input[type="text"]
{
    flex: 0 0 auto;
    width: auto;
    padding: 4px 6px;
    border-radius: 6px;
    background: var(--bar-hover);
    font-size: 11.5px;
    text-align: right;
}


/* ⭐ LA STAMPA ( `graphic-print` ): a schermo non c'e', in stampa c'e' solo lui — ogni foglio sulla sua pagina ( `@page` nominato, scritto
   da `GraphicPrint` ), della sua misura in mm. ⚠️ L'altezza e lo scorrimento della pagina dell'editor ( `height: 100%`, `overflow:
   hidden` ) in stampa taglierebbero i fogli dopo il primo. */
graphic-print { display: none; }

@media print
{
    html, body { height: auto; overflow: visible; background: none; }

    /* ⛔ IN STAMPA IL `body` NON E' FLEX: a schermo mette in riga tela e colonna, e in stampa faceva di `graphic-print` un elemento
       flex — un foglio piu' largo del primo ( A3 orizzontale dopo una copertina A4 ) usciva ristretto a 2/3, con la carta vuota a
       destra e sotto ( segnalato da Riccardo il 2026-09-22, misurato stampando in PDF con Chrome headless ). */
    body { display: block; }

    body > *:not( graphic-print ) { display: none !important; }

    graphic-print { display: block; }

    graphic-print .print-sheet { overflow: hidden; break-after: page; }

    graphic-print .print-sheet:last-child { break-after: auto; }

    graphic-print .print-sheet > svg { display: block; width: 100%; height: 100%; }
}



/* ══ L'ALBERO DEL DOCUMENTO ( `document-tree-view` ) ═════════════════════════════════════════════════════════════════════════
   Le regole di `.tree-view` di `xos.css`, con l'inchiostro e l'accento di qui. Una riga e' alta quanto una voce di menu. */
.tree-view { outline: none; position: relative; }

.tree-view > svg.background { display: none; }

.tree-view ul.tree ,
.tree-view ul.tree ul { list-style: none; margin: 0; padding: 0; }

.tree-view ul.tree ul { display: none; margin-left: 13px; padding-left: 4px; border-left: 1px solid var(--hairline); }

.tree-view li.open > ul { display: block; }

.tree-view .node-info
{
    display: flex;
    align-items: center;
    gap: 4px;
    height: 24px;
    padding: 0 6px 0 2px;
    border-radius: 5px;
    cursor: default;
    white-space: nowrap;
    color: var(--ink-soft);
}

/* ⭐ LE RIGHE FUORI VISTA NON SI IMPAGINANO ( `content-visibility` ), con l'altezza che avranno: un ramo da 1.202 righe appena aperto
   costava 81 ms di layout per portare in vista quella scelta, 29 cosi' ( `GIRLS.svg` ) */
.tree-view .node-info { content-visibility: auto; contain-intrinsic-size: auto 24px; }

.tree-view .node-info:hover { background: var(--bar-hover); color: var(--ink); }

.tree-view li.selected > .node-info { background: var(--accent); color: var(--on-accent); }

/* la pagina attiva ( `GraphicEditor.goToPage` ): non scelta, ma si legge */
.tree-view li.active-page:not( .selected ) > .node-info { box-shadow: inset 3px 0 0 var(--accent); font-weight: 600; }

.tree-view .arrow { flex: 0 0 12px; font-size: 8px; text-align: center; color: var(--ink-faint); transition: transform .15s; }

.tree-view li.open > .node-info > .arrow { transform: rotate( 90deg ); }

.tree-view .arrow.leaf { visibility: hidden; }

.tree-view li.selected > .node-info > .arrow { color: var(--on-accent); }

/* ⚠️ le icone dello sprite sono `currentColor`: accesa la riga, prendono il colore del testo */
.tree-view .node-info > svg.icon { flex: 0 0 20px; width: 20px; height: 20px; min-width: 20px; color: inherit; }

.tree-view .node-info > .label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* ⭐ IL LUCCHETTO E L'OCCHIO in fondo alla riga: accesi si vedono sempre, spenti solo passandoci sopra ( `GraphicDocTreeview.showFlags` ). Nascosto, il nome
   si legge sbiadito */
.tree-view .node-info > .row-flag { flex: 0 0 18px; font-size: 15px; line-height: 18px; text-align: center; color: var( --ink-faint ); cursor: pointer; visibility: hidden; }

.tree-view .node-info:hover > .row-flag , .tree-view .node-info > .row-flag.on { visibility: visible; }

.tree-view .node-info > .row-flag:hover { color: var( --ink ); }

.tree-view li.selected > .node-info > .row-flag { color: var( --on-accent ); }

.tree-view .node-info:has( > .row-flag[data-flag="hidden"].on ) > .label { opacity: .5; }



/* ⭐ UNA VOCE DI MENU CHE MOSTRA UNO STATO ( `checked`, lo dice il comando ): la spunta sta dove starebbe la scorciatoia.
   ⚠️ Il segno non e' nel nostro font: lo prende il ripiego di sistema, come il `⌫` di Delete. */
menu-item.checked::after { content: "✓"; font-size: 12px; color: var(--ink); }

menu-item.checked:hover::after { color: var(--on-accent); }



/* ══ LE RISORSE ( `graphic-resources.js` ) ═══════════════════════════════════════════════════════════════════════════════════
   ⭐ IL FOOTER DELLA COLONNA DEGLI INSPECTOR: una card bassa coi bottoni dei tipi. ⚠️ Non in quella del documento: quella si spegne. Acceso il bottone del pannello aperto. */
.resource-bar
{
    flex: 0 0 auto;
    display: flex;
    gap: 2px;

    /* ⭐ IN FONDO ALLA COLONNA E FERMA LI' ( chiesto da Riccardo il 2026-09-22 ): la tiene giu' `.column-scroll`, che prende l'altezza che
       resta e scorre lui */
    margin-top: 6px;
    padding: 4px;
    background: var(--bar-surface);
    border: 1px solid var(--hairline);
    border-radius: 10px;
}

/* ⚠️ i bottoni si dividono la larghezza: otto da 32 px non ci stavano nella colonna */
.resource-bar > .button
{
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 1 1 0;
    min-width: 0;
    height: 28px;
    border-radius: 6px;
    cursor: pointer;
}

/* ⭐ I BOTTONI DELLE COLONNE ( Document, Risorse, Font ) stanno in testa, e l'ultimo li stacca dagli altri con un filo */
.inspector-column > .resource-bar > .column-button:not( :has( + .column-button ) ) { border-right: 1px solid var(--hairline); margin-right: 4px; padding-right: 6px; border-radius: 6px 0 0 6px; }

.resource-bar > .button:hover { background: var(--bar-hover); }

.resource-bar > .button.selected { background: var(--bar-active); }

/* ⭐ L'ACCOUNT, ultimo della barra e staccato dai pannelli con un filo; nascosto finche' non si e' entrati */
.account-button.hidden { display: none; }
#account-menu > .account-email { padding: 6px 12px 4px 12px; font-size: 11px; color: var( --ink-soft ); }
#account-menu > .account-saves { padding: 0 12px 6px 12px; font-size: 12px; }

/* ⭐ LA GRIGLIA: celle quadrate da 40 px ( chiesto da Riccardo il 2026-09-28 ), quante ne stanno nella larghezza del pannello; lo spazio e' quello
   dei colori. */
.panel > .resource-grid
{
    display: grid;
    grid-template-columns: repeat( auto-fill , 40px );

    /* ⛔ LE RIGHE ALTE QUANTO LE CELLE: la griglia e' il contenuto che scorre, con un'altezza data dal pannello, e con le righe `auto` le
       celle quadrate ( `aspect-ratio` ) si sovrapponevano — misurato: celle da 66 px, righe a 14 px di distanza. */
    grid-auto-rows: max-content;
    align-content: start;

    /* ⚠️ a 6 px le anteprime si toccavano ( Riccardo, 2026-09-22 ) */
    gap: 8px;
    padding: 12px;
}

/* ⭐ I COLORI A META': un colore si riconosce anche piccolo, e cosi' se ne vedono di piu' ( chiesto da Riccardo il 2026-09-22 ). Il lato e' la
   meta' della cella delle altre risorse ( 66 → 33 ), e lo spazio fra le celle scende con lei. */
color-panel.panel > .resource-grid { grid-template-columns: repeat( auto-fill , 33px ); gap: 8px; }

/* ⭐ E COME I COLORI gradienti, trame e marcatori ( chiesto da Riccardo il 2026-09-28 ): si riconoscono anche piccoli. I simboli restano a 40. */
resource-panel.panel:is( [data-resource="gradients"] , [data-resource="patterns"] , [data-resource="markers"] ) > .resource-grid { grid-template-columns: repeat( auto-fill , 33px ); }

.panel > .resource-grid:empty::after { content: "none"; grid-column: 1 / -1; color: var(--ink-faint); }

.resource-cell
{
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 1;
    border: 1px solid var(--hairline);
    border-radius: 6px;
    cursor: pointer;
}

.resource-cell:hover { border-color: var(--ink-faint); }

.resource-cell.selected { outline: 2px solid var(--accent); outline-offset: -1px; }

.resource-cell > svg.icon { pointer-events: none; }

/* ⭐ L'ANTEPRIMA RIEMPIE LA CELLA. ⚠️ Il fondo e' la CARTA, bianca in tutti e due i temi come il foglio: un simbolo nero sul fondo scuro
   della colonna non si vedrebbe */
.resource-cell { background: #ffffff; overflow: hidden; }

.resource-cell > .resource-preview { display: block; width: 100%; height: 100%; pointer-events: none; }

/* ⭐ IL FOOTER DEL PANNELLO: il nome della risorsa scelta, e li' si cambia */
.resource-footer { flex: 0 0 auto; padding: 8px 12px; border-top: 1px solid var(--hairline); }

.resource-footer > input { width: 100%; box-sizing: border-box; }



/* ⭐ IL FOOTER DELLA PAGINA ( `graphic-dock` ): a tutta larghezza sotto tela e colonna, alto `--dock-height` ( si tira dal bordo di sopra ).
   Un pannello per volta; chiuso non c'e'. */
graphic-dock.dock
{
    grid-row: 2;
    grid-column: 1 / -1;
    position: relative;
    height: var( --dock-height , 190px );
    display: flex;
    flex-flow: column nowrap;
    border-top: 1px solid var( --hairline );
    background: var( --page-background );
    color: var( --ink );
}

graphic-dock.dock.hidden , graphic-dock .dock-panel.hidden { display: none; }

graphic-dock .dock-grip { position: absolute; left: 0; right: 0; top: -3px; height: 6px; cursor: ns-resize; z-index: 1; }

graphic-dock .dock-panel { flex: 1 1 auto; min-height: 0; display: flex; flex-flow: column nowrap; }

/* ⭐ TABLES, nella colonna delle risorse: una riga per tabella di dati su due linee — il nome ( si scrive li' ), e sotto fonte · righe x colonne · lettura —; scelta, accesa */
tables-panel > .content { display: flex; flex-direction: column; gap: 2px; padding: 6px 8px 10px 8px; overflow-y: auto; }
tables-panel .data-tables { display: flex; flex-direction: column; gap: 2px; }
tables-panel .data-table-row { display: flex; align-items: center; gap: 8px; padding: 4px 6px; border-radius: 6px; cursor: default; }
tables-panel .data-table-icon { flex: 0 0 auto; font-size: 22px; color: var( --ink-soft ); cursor: default; }
tables-panel .data-table-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
tables-panel .data-table-row:hover { background: var( --bar-hover ); }
tables-panel .data-table-row.selected { background: color-mix( in srgb , var( --accent ) 16% , transparent ); }
tables-panel .data-table-name { background: transparent; color: var( --ink ); text-align: left; padding: 2px 0; }
tables-panel .data-table-info { font-size: 10.5px; color: var( --ink-faint ); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
tables-panel .data-tables-empty { padding: 6px 4px; font-size: 11px; color: var( --ink-faint ); }
tables-panel .header > .button.disabled { opacity: .35; pointer-events: none; }

graphic-dock .dock-header
{
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 8px 4px 14px;
    border-bottom: 1px solid var( --hairline );
}

graphic-dock .dock-header > .name { font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var( --ink-soft ); }

graphic-dock .dock-header > .count { flex: 0 0 auto; color: var( --ink-faint ); }

/* ⭐ TRE PARTI: a sinistra nome e conteggio, al centro lo spazio che resta ( per ora vuoto ), a destra i controlli */
graphic-dock .dock-header > .dock-header-center { flex: 1 1 auto; min-width: 0; }

graphic-dock .dock-header > .button { display: flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: 4px; cursor: pointer; color: var( --ink-soft ); }

graphic-dock .dock-header > .button:hover { background: var( --bar-active ); color: var( --ink ); }

graphic-dock .dock-header > .button > .icon.material-symbols-outlined , graphic-dock .dock-header > .button.close { font-size: 18px; }

/* uno strumento nella testata ( `data-pointer`, lo strumento pagina in Pages ): l'icona della barra, e acceso quando e' in mano */
graphic-dock .dock-header > .button > svg.icon { width: 20px; height: 20px; }

graphic-dock .dock-header > .button.selected { background: var( --bar-active ); color: var( --ink ); }

/* ⭐ LE BARRE DELLA TESTATA ( Pages, Masters ): al centro i comandi ( `button-bar` ), a destra le fonti ( `radio-bar` ), coi bottoni della testata. Larghe quanto i
   loro bottoni: la regola di tutte le barre ( `width: 100%` ) le stendeva */
graphic-dock .dock-header > .dock-header-center { display: flex; justify-content: center; }

graphic-dock .dock-header :is( .button-bar , .radio-bar ) { flex: 0 0 auto; width: auto; }

graphic-dock .dock-header :is( .button-bar , .radio-bar ) > .button { flex: 0 0 auto; width: 24px; min-width: 24px; height: 24px; border-radius: 4px; cursor: pointer; color: var( --ink-soft ); }

graphic-dock .dock-header :is( .button-bar , .radio-bar ) > .button:hover { background: var( --bar-active ); color: var( --ink ); }

graphic-dock .dock-header :is( .button-bar , .radio-bar ) > .button > .icon.material-symbols-outlined { font-size: 18px; }

graphic-dock .dock-header :is( .button-bar , .radio-bar ) > .button > svg.icon { width: 20px; height: 20px; min-width: 20px; }

/* un comando che non vale sulla pagina attiva, o una fonte che non c'e' ancora */
graphic-dock .dock-header :is( .button-bar , .radio-bar ) > .button.disabled { opacity: 0.35; pointer-events: none; }

/* ⭐ IL CORPO: le immagini in fila a sinistra, il dettaglio dell'immagine scelta a destra */
graphic-dock .dock-body { flex: 1 1 auto; min-height: 0; display: flex; flex-flow: row nowrap; }

images-panel .photo-detail
{
    flex: 0 0 260px;
    box-sizing: border-box;
    padding: 10px 14px;
    border-left: 1px solid var( --hairline );
    overflow-y: auto;
    display: flex;
    flex-flow: column nowrap;
    gap: 6px;
}

images-panel .photo-detail.hidden { display: none; }

images-panel .photo-detail .detail-name { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

images-panel .photo-detail .detail-line { color: var( --ink-faint ); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* l'originale che manca si vede */
images-panel .photo-detail .detail-line.source[ data-status="missing" ] { color: #d9534f; }

images-panel .photo-detail .input-property { display: flex; align-items: center; gap: 8px; }

/* ⭐ IL BOTTONE DEI DATI della tabella: come i bottoni dei dialoghi */
table-properties .data-button { margin-left: auto; font: inherit; font-size: 11.5px; padding: 3px 12px; border-radius: 8px; border: 1px solid var( --hairline ); background: transparent; color: var( --ink ); cursor: pointer; }

/* ⭐ IL PANNELLO DEI DATI ( `GraphicTableDataPanel` ): staccato come gli altri; la presa lo allunga anche in altezza ( `--data-height`: nella colonna l'altezza
   di un pannello staccato la detta il contenuto, con `--panel-height` forzata ). La griglia prende lo spazio e scorre, con le testate ferme. */
/* ⚠️ `!important`: `.panel.dragged:has( > .next-content-activator.checked )` e' piu' specifica e rimetteva l'altezza del contenuto ( misurato: la presa allargava
   e non allungava, 259 → 259 ) */
.sidebar table-data-panel.panel.dragged { height: var( --data-height , auto ) !important; max-height: 90vh; min-height: 200px; }
table-data-panel .header > .panel-icon { font-size: 18px; color: var( --ink-soft ); margin-right: 6px; }
table-data-panel > .content { display: flex; flex-direction: column; padding: 0 12px 12px 12px; }
table-data-panel .grid-scroll { flex: 1 1 auto; min-height: 60px; max-height: 60vh; overflow: auto; border: 1px solid var( --hairline ); border-radius: 6px; }
/* allungato dalla presa, la griglia non ha piu' tetto: la misura la da' il pannello */
table-data-panel[style*="--data-height"] .grid-scroll { max-height: none; }
table-data-panel .data-buttons { justify-content: flex-end; gap: 8px; padding-top: 10px; }
/* ⭐ IL BOTTONE DEL FOGLIO in basso a sinistra ( acceso se la tabella e' collegata ), e il suo dialogo: il link largo, lo stato sotto i campi, rosso se non si legge */
table-data-panel .data-buttons > .sheet-button { margin-right: auto; }
table-data-panel .data-buttons > .sheet-button.linked { border-color: var( --accent ); color: var( --accent ); }
.dialog.sheet-dialog { width: 420px; margin-left: -210px; }
.sheet-dialog .input-property > input[type="text"] { flex: 1 1 auto; min-width: 0; text-align: left; }
.sheet-dialog .sheet-status { min-height: 14px; padding-top: 8px; font-size: 10.5px; color: var( --ink-faint ); }
.sheet-dialog .sheet-status.error { color: #d93025; }
table-data-panel .data-grid.linked td { color: var( --ink-soft ); cursor: default; }
table-data-panel .data-buttons > button { font: inherit; font-size: 11.5px; padding: 4px 14px; border-radius: 8px; border: 1px solid var( --hairline ); background: transparent; color: var( --ink ); cursor: pointer; }
table-data-panel .data-buttons > button.apply { background: var( --accent ); border-color: var( --accent ); color: var( --on-accent ); }
table-data-panel .data-grid { border-collapse: collapse; font-size: 12px; user-select: text; }
table-data-panel .data-grid th { position: sticky; top: 0; background: linear-gradient( var( --bar-hover ) , var( --bar-hover ) ) , var( --panel-background-color ); color: var( --ink-soft ); font-weight: normal; font-size: 10.5px; padding: 3px 6px; border: 1px solid var( --hairline ); z-index: 1; }
table-data-panel .data-grid tr > th:first-child { position: sticky; left: 0; text-align: right; z-index: 2; }
/* ⭐ CHI STA SOPRA, scorrendo: la riga delle lettere sopra i numeri ( che salendo ci passavano sopra, segnalato da Riccardo ), e l'angolo sopra tutto */
table-data-panel .data-grid tr:first-child > th { z-index: 3; }
table-data-panel .data-grid tr:first-child > th:first-child { z-index: 4; }
table-data-panel .data-grid th > .type { display: block; font-size: 9px; color: var( --accent ); }
table-data-panel .data-grid td { min-width: 90px; max-width: 260px; padding: 4px 6px; border: 1px solid var( --hairline ); white-space: pre-wrap; vertical-align: top; outline: none; color: var( --ink ); }
table-data-panel .data-grid td.numeric { text-align: right; }
table-data-panel .data-grid td:focus { box-shadow: inset 0 0 0 2px var( --accent ); }
/* ⭐ LA SCELTA: le celle velate dell'accento, le testate che tocca accese; trascinando niente testo scelto ne' cursore */
table-data-panel .data-grid { outline: none; }
table-data-panel .data-grid td.selected { background: color-mix( in srgb , var( --accent ) 16% , transparent ); }
/* ⚠️ le testate sono OPACHE: ferme mentre la griglia scorre, con un fondo trasparente le righe ci passavano sotto e si leggevano insieme ( segnalato da Riccardo ) */
table-data-panel .data-grid th.selected { background: color-mix( in srgb , var( --accent ) 30% , var( --panel-background-color ) ); color: var( --ink ); }
table-data-panel .data-grid th { cursor: default; }
table-data-panel .data-grid.selecting td { user-select: none; caret-color: transparent; }
/* ⭐ DOVE CADRANNO righe o colonne trascinate dalla testata: una linea dell'accento sul bordo ( `GraphicTableDataPanel.startMove` ) */
table-data-panel .data-grid th[data-column].drop-before { box-shadow: inset 3px 0 0 var( --accent ); }
table-data-panel .data-grid th[data-column].drop-after { box-shadow: inset -3px 0 0 var( --accent ); }
table-data-panel .data-grid th[data-row].drop-before { box-shadow: inset 0 3px 0 var( --accent ); }
table-data-panel .data-grid th[data-row].drop-after { box-shadow: inset 0 -3px 0 var( --accent ); }
table-data-panel .data-grid th.selected { cursor: grab; }

images-panel .photo-detail .input-property > .label { flex: 0 0 64px; color: var( --ink-soft ); }

images-panel .photo-detail .input-property > input[type="range"] { flex: 1 1 auto; min-width: 0; }

images-panel .photo-detail .input-property > input[type="text"] { flex: 0 0 40px; width: 40px; text-align: right; }

images-panel .photo-detail .input-property > select { flex: 1 1 auto; }

/* ⚠️ larga quanto la sua voce: la regola di tutti i `select` ( `flex: 1` ) la stendeva per tutta la testata */
graphic-dock .dock-header > select { flex: 0 0 auto; width: auto; font-size: 11px; }

/* ⭐ LE IMMAGINI IN FILA, che scorrono in orizzontale: ogni cella alta quanto il pannello, l'immagine intera sopra la sua data */
images-panel .photo-strip
{
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-flow: row nowrap;
    gap: 10px;
    padding: 10px 14px;
    overflow-x: auto;
    overflow-y: hidden;
}

images-panel .photo-strip:empty::after { content: "drop photos here, or +"; align-self: center; color: var( --ink-faint ); }

images-panel .photo-cell
{
    flex: 0 0 auto;
    height: 100%;
    display: flex;
    flex-flow: column nowrap;
    align-items: center;
    gap: 4px;
    cursor: grab;
    border-radius: 4px;
    outline-offset: 2px;
}

/* ⚠️ UN'ALTEZZA DEFINITA, non quella del flex: solo cosi' `aspect-ratio` ( scritto dalla cella ) fa la larghezza — col flex le celle uscivano
   tutte larghe uguali. Si toglie la riga della data ( 14 px ) e lo spazio ( 4 ). */
images-panel .photo-cell > img { flex: 0 0 auto; height: calc( 100% - 18px ); width: auto; object-fit: cover; border-radius: 3px; background: var( --hairline ); }

images-panel .photo-cell > .photo-date { flex: 0 0 14px; line-height: 14px; font-size: 10px; color: var( --ink-faint ); white-space: nowrap; text-align: center; }

images-panel .photo-cell.selected { outline: 2px solid var( --accent ); }

/* ⭐ GIA' IN UNA GRIGLIA: velata, col segno in un angolo — si vede cosa resta da mettere */
images-panel .photo-cell { position: relative; }

images-panel .photo-cell.used > img { opacity: 0.45; }

/* quante volte e' usata, se piu' d'una */
images-panel .photo-cell > .photo-badge:not( :empty )
{
    position: absolute;
    top: 4px;
    left: 4px;
    padding: 0 4px;
    border-radius: 3px;
    font-size: 10px;
    background: var( --accent );
    color: white;
}

/* ⭐ LE CATEGORIE: la preferita col bordo, l'archiviata velata */
images-panel .photo-cell[ data-category="preferred" ] > img { box-shadow: 0 0 0 2px #f2b705; }

images-panel .photo-cell[ data-category="archived" ] > img { filter: grayscale( 1 ); opacity: 0.35; }

images-panel .photo-cell.used::after
{
    content: "check_circle";
    font-family: 'Material Symbols Outlined';
    position: absolute;
    top: 4px;
    right: 4px;
    font-size: 18px;
    color: var( --accent );
}


/* ⭐ LA TIMELINE DELLE PAGINE ( `pages-panel`, e i mastri in `masters-panel` ): in fila, ognuna nelle sue proporzioni, col numero e il nome sotto; accesa la pagina attiva */
:is( pages-panel , masters-panel , templates-panel ) .page-strip
{
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-flow: row nowrap;
    align-items: flex-start;
    gap: 14px;
    padding: 10px 14px;
    overflow-x: auto;
    overflow-y: hidden;
}

:is( pages-panel , masters-panel , templates-panel ) .page-cell { flex: 0 0 auto; display: flex; flex-flow: column nowrap; align-items: center; gap: 4px; cursor: pointer; position: relative; }

/* la miniatura alta come `GraphicPagesPanel.THUMB_HEIGHT`, larga quanto la pagina vuole */
:is( pages-panel , masters-panel , templates-panel ) .page-cell > canvas { height: 110px; width: auto; background: #ffffff; box-shadow: 0 1px 3px rgba( 0 , 0 , 0 , 0.25 ); }

/* ⭐ I TEMPLATE VANNO A CAPO e scorrono in verticale, come le griglie delle librerie; la miniatura e' alta quanto dice il pannello ( `--thumb-height`,
   `GraphicTemplatesPanel.onResize` ). La timeline delle pagine resta una fila. */
templates-panel .page-strip { flex-flow: row wrap; align-content: flex-start; overflow-x: hidden; overflow-y: auto; row-gap: 12px; }

templates-panel .page-cell > canvas { height: var( --thumb-height , 110px ); }

:is( pages-panel , masters-panel , templates-panel ) .page-cell > .page-label { font-size: 10px; color: var( --ink-faint ); white-space: nowrap; max-width: 140px; overflow: hidden; text-overflow: ellipsis; }

:is( pages-panel , masters-panel , templates-panel ) .page-cell.selected > canvas { outline: 2px solid var( --accent ); outline-offset: 2px; }

:is( pages-panel , masters-panel , templates-panel ) .page-cell.selected > .page-label { color: var( --ink ); }

/* dove cadra' la pagina trascinata */
:is( pages-panel , masters-panel , templates-panel ) .page-cell.drop-before::before , :is( pages-panel , masters-panel , templates-panel ) .page-cell.drop-after::after
{
    content: "";
    position: absolute;
    top: 0;
    height: 110px;
    width: 3px;
    background: var( --accent );
}

:is( pages-panel , masters-panel , templates-panel ) .page-cell.drop-before::before { left: -9px; }

:is( pages-panel , masters-panel , templates-panel ) .page-cell.drop-after::after { right: -9px; }


/* ⭐ LA TIMELINE DELLA PAGINA ( `timeline-panel` ): righello fermo in alto, etichette ferme a sinistra, la testina sopra tutto */
.resource-bar > .button > .icon.material-symbols-outlined { font-size: 18px; }

/* i comandi al centro della testata ( chiesto da Riccardo il 2026-09-23 ), come i bottoni della testata */
timeline-panel .dock-header { position: relative; }

/* al centro della testata intera, non dello spazio che resta fra nome e tempo */
timeline-panel .timeline-controls { position: absolute; left: 50%; transform: translateX( -50% ); display: flex; gap: 2px; }

/* il tempo a sinistra dei comandi ( chiesto da Riccardo ), la chiusura in fondo a destra */
/* lo zoom e la chiusura in fondo a destra */
timeline-panel .dock-header > .timeline-zoom { flex: 0 0 110px; width: 110px; margin-left: auto; }

timeline-panel .timeline-controls > .button { display: flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: 4px; cursor: pointer; color: var( --ink-soft ); }

timeline-panel .timeline-controls > .button:hover { background: var( --bar-active ); color: var( --ink ); }

timeline-panel .timeline-controls > .button > .icon.material-symbols-outlined { font-size: 18px; }

timeline-panel .timeline-time { flex: 0 0 auto; min-width: 56px; margin-right: 6px; align-self: center; text-align: right; font-variant-numeric: tabular-nums; color: var( --ink-soft ); }

timeline-panel .play-button > .stop , timeline-panel.playing .play-button > .play { display: none; }

timeline-panel.playing .play-button > .stop { display: inline; }

timeline-panel .timeline-scroll { flex: 1 1 auto; min-width: 0; overflow: auto; }

timeline-panel .timeline-content { position: relative; width: max-content; min-width: 100%; min-height: 100%; }

timeline-panel .timeline-line { display: flex; height: 24px; border-bottom: 1px solid var( --hairline ); }

timeline-panel .timeline-label
{
    flex: 0 0 140px;
    box-sizing: border-box;
    position: sticky;
    left: 0;
    z-index: 2;
    padding: 0 8px 0 14px;
    line-height: 24px;
    font-size: 11px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var( --ink-soft );
    background: var( --page-background );
    border-right: 1px solid var( --hairline );
    cursor: pointer;
}

/* le piste: un filo a ogni secondo e uno piu' leggero a ogni quarto */
timeline-panel .timeline-track
{
    flex: 0 0 auto;
    position: relative;
    cursor: text;
    background-image: linear-gradient( to right , var( --hairline ) 1px , transparent 1px );
    background-size: var( --ruler-step , 100px ) 100%;
    background-position: 10px 0;  /* `GraphicTimelinePanel.INSET` */
}

timeline-panel .timeline-ruler { position: sticky; top: 0; z-index: 3; background: var( --page-background ); }

timeline-panel .timeline-ruler > .timeline-label { cursor: default; }

timeline-panel .timeline-ruler > .timeline-track
{
    background-image: linear-gradient( to right , var( --ink-faint ) 1px , transparent 1px ) , linear-gradient( to right , var( --hairline ) 1px , transparent 1px );
    background-size: var( --ruler-step , 100px ) 100% , var( --ruler-minor , 25px ) 30%;
    background-repeat: repeat-x;
    background-position: 10px 0 , 10px 100%;
}

timeline-panel .timeline-ruler span { position: absolute; top: 4px; padding-left: 3px; font-size: 10px; color: var( --ink-faint ); pointer-events: none; }

/* ⭐ I TWEEN DI UN OGGETTO: barre in fila sulla sua riga, un rombo a ogni capo ( i keyframe ); accesa quella del tween scelto */
timeline-panel .timeline-row.selected > .timeline-label { color: var( --ink ); box-shadow: inset 2px 0 0 var( --accent ); }

timeline-panel .tween-bar { position: absolute; top: 5px; height: 14px; box-sizing: border-box; border-radius: 2px; background: var( --bar-active ); border: 1px solid var( --ink-faint ); cursor: grab; }

timeline-panel .tween-bar > .keyframe { position: absolute; top: 1px; width: 9px; height: 9px; margin: 0 0 0 -5px; transform: rotate( 45deg ); background: var( --ink-soft ); cursor: ew-resize; }

timeline-panel .tween-bar > .keyframe[data-edge="end"] { left: 100%; }

/* ⭐ IL COLORE DELLA BARRA DICE IL TIPO: la famiglia della prima property del delta ( `GraphicTween.familyOf` ); scelta, piu' piena */
timeline-panel .tween-bar { --tween : var( --tween-property ); background: color-mix( in srgb , var( --tween ) 30% , transparent ); border-color: var( --tween ); }

timeline-panel .tween-bar[data-kind="motion"] { --tween : var( --tween-motion ); }
timeline-panel .tween-bar[data-kind="color"] { --tween : var( --tween-color ); }
timeline-panel .tween-bar[data-kind="opacity"] { --tween : var( --tween-opacity ); }
timeline-panel .tween-bar[data-kind="size"] { --tween : var( --tween-size ); }

timeline-panel .tween-bar.selected { background: color-mix( in srgb , var( --tween ) 60% , transparent ); border-color: var( --ink ); }

timeline-panel .tween-bar > .keyframe , timeline-panel .tween-bar.selected > .keyframe { background: var( --tween ); }

/* il nome della property, dentro la barra */
timeline-panel .tween-bar > .tween-label { position: absolute; left: 8px; right: 8px; top: 0; font-size: 9px; line-height: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var( --ink ); pointer-events: none; }

/* il keyframe sotto la testina: un altro colore, sopra lo stato della barra */
timeline-panel .tween-bar > .keyframe.current { background: var( --keyframe-current ); }

/* la copia che si trascina con alt */
timeline-panel .tween-bar.ghost { opacity: .6; pointer-events: none; }

/* dove finisce la durata: oltre, niente tempo */
timeline-panel .timeline-end { position: absolute; top: 0; bottom: 0; width: 1px; background: var( --ink-faint ); pointer-events: none; }

/* la maniglia della fine, sul righello: trascinandola si allunga l'animazione */
timeline-panel .timeline-end-grip { position: absolute; top: 4px; width: 8px; height: 16px; margin-left: -4px; border-radius: 2px; background: var( --ink-faint ); cursor: ew-resize; z-index: 5; }

timeline-panel .timeline-end-grip:hover { background: var( --accent ); }

/* durante un trascinamento il cursore e' quello dell'elemento premuto, ovunque nel pannello ( `holdCursor` ) */
timeline-panel.dragging , timeline-panel.dragging * { cursor: var( --drag-cursor ) !important; }

/* ⭐ IL CICLO, come in GarageBand: la fascia gialla nella meta' alta del righello; spento resta grigio. Le etichette dei secondi restano sopra */
timeline-panel .timeline-cycle { position: absolute; top: 1px; height: 10px; box-sizing: border-box; border-radius: 2px; background: color-mix( in srgb , var( --tween-span ) 45% , transparent ); border: 1px solid var( --tween-span ); cursor: grab; }

timeline-panel .timeline-cycle.off { background: color-mix( in srgb , var( --ink-faint ) 25% , transparent ); border-color: var( --ink-faint ); }

timeline-panel .timeline-cycle > .cycle-grip { position: absolute; top: -1px; bottom: -1px; width: 6px; margin-left: -3px; cursor: ew-resize; }

timeline-panel .timeline-cycle > .cycle-grip[data-edge="end"] { left: 100%; }

timeline-panel .timeline-ruler span { z-index: 1; }

/* ⭐ LA SELEZIONE SUL RIGHELLO: la barra gialla dal primo inizio all'ultima fine dei tween scelti; si sposta, e le maniglie la scalano */
timeline-panel .timeline-span { position: absolute; bottom: 2px; height: 6px; border-radius: 3px; background: var( --tween-span ); cursor: grab; z-index: 6; }  /* sopra la maniglia della fine ( 5 ), che resta presa dall'alto */

timeline-panel .timeline-span > .span-grip { position: absolute; top: -4px; width: 8px; height: 14px; margin-left: -4px; border-radius: 2px; background: var( --tween-span ); border: 1px solid var( --page-background ); box-sizing: border-box; cursor: ew-resize; }

timeline-panel .timeline-span > .span-grip[data-edge="end"] { left: 100%; }

timeline-panel .timeline-head { position: absolute; top: 0; bottom: 0; width: 1px; background: var( --accent ); z-index: 4; pointer-events: none; }


/* ⭐ I PANNELLI DEL BLOB E DEI PENNELLI ( `GraphicToolPanel` ): a pagine, scelte dalla barra in testata. Larghi 240 ( Riccardo, 2026-10-01 ), una colonna sola */
tool-options > :is( blob-options , brush-options ).panel { width: 240px; }

tool-options > :is( blob-options , brush-options ).panel > .content { padding: 10px; }

/* ⭐ LE PAGINE: una alla volta, e il pannello e' alto quanto quella che si vede ( « l'altezza dovrebbe essere auto », Riccardo 2026-10-01 ) */
.tool-panes > [data-pane].pane-hidden { display: none; }

/* la barra delle pagine in testata, prima della crocetta: stretta, a destra del nome */
/* ⚠️ le barre sono larghe 100%, coi bottoni: qui stretta, bottoni da 32 e icone da 20 come i comandi in testata ( `.header-command` ) */
:is( blob-options , brush-options ) .header > [name="paneBar"] { flex: 0 0 auto; width: auto; margin-left: auto; margin-right: 4px; }

:is( blob-options , brush-options ) .header > [name="paneBar"] > .button { width: 32px; }

/* ⭐ IL COLORE DELLE ICONE DELL'APP ( « non sono un po' troppo scure? », Riccardo 2026-10-01 ): `--ink-soft`, e `--ink` solo scelta o sotto il mouse */
:is( blob-options , brush-options ) .header > [name="paneBar"] .icon.material-symbols-outlined { font-size: 20px; color: var( --ink-soft ); }

:is( blob-options , brush-options ) .header > [name="paneBar"] .button:is( .selected , :hover ) .icon.material-symbols-outlined { color: var( --ink ); }

/* l'icona del pennello ( la stessa del suo strumento, dallo sprite: Riccardo 2026-10-01 ), grande come le altre della testata; il colore e' quello di `svg.icon` */
:is( blob-options , brush-options ) .header > [name="paneBar"] svg.icon { width: 20px; height: 20px; }

/* ⭐ LA PAGINA DELLA PUNTA: nel blob forma, spessori e modo; nei pennelli la lista e gli spessori. In colonna, a tutta larghezza */
:is( .blob-tip-column , .brush-tip ) { display: flex; flex-direction: column; gap: 8px; }

/* le barre a tutta larghezza, i bottoni divisi in parti uguali */
blob-options .blob-tip-column > .radio-bar .button { flex: 1 1 0; }

/* ⚠️ le barre restano alte una riga: col `flex: 1` di serie in una colonna crescerebbero in altezza */
blob-options .blob-tip-column > .radio-bar { flex: 0 0 auto; }

blob-options .blob-tip-column > .radio-bar .icon { fill: currentColor; }

/* la lista dei pennelli a tutta larghezza, col suo tetto */
brush-options .brush-tip > .brush-list { width: auto; }

/* gli spessori: la stessa griglia nel blob e nei pennelli ( `BrushOptions.renderSizes` ), 6 colonne × 2 righe */
.size-grid { display: grid; grid-template-columns: repeat( 6 , 1fr ); gap: 4px; }

.size-tip { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 46px; border-radius: 6px; cursor: pointer; color: var( --ink-soft ); }

.size-tip:hover { background: var( --bar-active ); color: var( --ink ); }

.size-tip.selected { background: var( --accent ); color: var( --on-accent ); }

.size-tip > svg { width: 28px; height: 28px; fill: currentColor; }

.size-tip > span { font-size: 9px; line-height: 1; }

/* ⭐ LA PAGINA DELLE OPZIONI: le righe come quelle degli inspector ( Riccardo, 2026-10-01 ): etichetta, slider e valore con le loro regole ( `.input-property >
   .label` 54 px, il campo del valore ); solo le etichette lunghe delle righe con l'interruttore vanno a capo, o finirebbero sotto l'interruttore */
:is( .blob-properties , .brush-pressure ) { min-width: 0; }

:is( .blob-properties , .brush-pressure ) .input-property:has( > input[type="checkbox"] ) > .label { flex: 1 1 auto; white-space: normal; line-height: 1.2; }
