/* Layout applicazione ------------------------------------------------------ */

/* Il pannello e' a tutta pagina: senza un'altezza esplicita sulla catena
   html/body la percentuale non si risolveva, la pagina scrollava e l'SVG
   veniva misurato a zero all'avvio. */
html {
    height: 100%;
}

/* overflow:hidden deve restare confinato alla pagina dell'applicazione.
   Stando su html, che non e' qualificato da nessuna classe, bloccava lo
   scorrimento anche di documentation.html e samples.html, che caricano lo
   stesso foglio di stile. Su body l'overflow viene propagato al viewport,
   quindi per l'editor l'effetto e' identico. */
body.sad-app {
    height: 100%;
    margin: 0;
    overflow: hidden;
}

/* La barra dei comandi resta sopra i pannelli laterali (offcanvas: 1045),
   altrimenti a pannello aperto i suoi pulsanti diventano irraggiungibili. */
#designNavbar {
    z-index: 1046;
}

/* Barre delle modalita': sopra il pannello, sotto gli offcanvas. */
#labellerBar,
#wallaceBar,
#walkerBar,
#walkerPanel,
#flowerBar,
#flowerPanel,
#floorMap {
    z-index: 1040;
}

/* Colori standard del riempimento in Wallace: 10 colonne, una famiglia
   ciascuna, dalla tinta scura in alto alla chiara in basso. */
.wall-palette {
    display: grid;
    grid-template-columns: repeat(10, 1.5rem);
    grid-auto-rows: 1.5rem;
    gap: 4px;
}

.wall-swatch {
    border: 1px solid rgba(0, 0, 0, 0.2);
    border-radius: 0;
    padding: 0;
}

.wall-swatch:hover,
.wall-swatch:focus-visible {
    outline: 2px solid #212529;
    outline-offset: 1px;
}

/* Il colore del muro selezionato. */
.wall-swatch.active {
    outline: 2px solid #ffc107;
    outline-offset: 1px;
}

/* Una scheda di Scada Machines non ha piani: la minimappa non direbbe niente. */
body[data-mode="Machines"] #floorMap {
    display: none;
}

/* Piani --------------------------------------------------------------------- */

/* La minimappa sta in basso a sinistra, sopra alla barra dei comandi: il piano
   e' un controllo della vista come lo zoom, quindi resta li' in ogni
   modalita'. */
#floorMap {
    bottom: 3.5rem;
    width: 3.5rem;
    padding: 0.25rem;
}

.floor-title {
    font-size: 0.6rem;
    font-weight: bold;
    text-align: center;
    text-transform: uppercase;
    color: #ffc107;
    margin-bottom: 0.25rem;
}

/* L'elenco puo' crescere: si limita a meta' schermo e poi scorre. */
#floor-list {
    max-height: 70vh;
    overflow-y: auto;
}

.floor-btn,
.floor-step {
    display: block;
    width: 100%;
    padding: 0.1rem 0;
    margin-bottom: 0.15rem;
    border: 1px solid #495057;
    background: none;
    color: inherit;
    font-size: 0.75rem;
    line-height: 1.4;
}

/* Un piano con qualcosa sopra si distingue da uno vuoto senza doverci andare:
   e' tutto quel che la minimappa deve dire. */
.floor-btn.filled {
    background: #495057;
}

.floor-btn.active {
    border-color: #ffc107;
    color: #ffc107;
    font-weight: bold;
}

/* Il Default sta in fondo, staccato: non e' un piano da aggiungere o togliere
   ma la corsia di chi un piano non ce l'ha. La parola intera non sta nella
   colonna al corpo degli altri pulsanti. */
.floor-default {
    margin-top: 0.35rem;
    border-top-width: 2px;
    font-size: 0.55rem;
    letter-spacing: -0.02em;
}

/* Muri ---------------------------------------------------------------------- */

/* Il muro selezionato viene alonato invece di cambiare colore: il colore e'
   una sua proprieta' e deve restare quello che l'utente ha scelto. */
.sad-wall.selected {
    filter: drop-shadow(0px 0px 0px #F7D100) drop-shadow(5px 5px 0px #F7D100);
}

.sad-wall { cursor: pointer; }

/* Angoli del muro selezionato. Il cursore dice che si prendono: senza, sono
   indistinguibili da una decorazione. */
.wall-handle { cursor: grab; }
#wall-handles.dragging .wall-handle { cursor: grabbing; }

/* Flowpath ------------------------------------------------------------------ */

/* Come per i muri: l'alone invece del cambio di colore, cosi' il binario resta
   riconoscibile anche da selezionato. */
.sad-flowpath.selected {
    filter: drop-shadow(0px 0px 0px #F7D100) drop-shadow(5px 5px 0px #F7D100);
}

.sad-flowpath { cursor: pointer; }

/* Elenchi laterali (Walker, Flower) ------------------------------------------ */

/* Gli elenchi sono sempre visibili: stanno a lato, incassati fra la barra della
   modalita' e quella dei comandi, che non devono coprire. */
#walkerPanel,
#flowerPanel {
    top: 3rem;
    bottom: 3.5rem;
    width: 19rem;
}

.walk-row,
.flow-row {
    border: 1px solid #495057;
    padding: 0.35rem;
    margin-bottom: 0.4rem;
}

.walk-row.active,
.flow-row.active {
    border-color: #ffc107;
    background: rgba(255, 193, 7, 0.12);
}

/* Il cambio di riga e' la riga stessa: e' il bersaglio piu' grande e non
   obbliga a centrare un'icona. */
.walk-pick,
.flow-pick {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex: 1 1 auto;
    min-width: 0;
    background: none;
    border: 0;
    color: inherit;
    text-align: left;
    padding: 0.15rem 0.25rem;
}

.walk-dot {
    flex: 0 0 auto;
    width: 0.8rem;
    height: 0.8rem;
    border-radius: 50%;
}

/* Un nome lungo viene tagliato: la riga non deve allargare il pannello. */
.walk-name,
.flow-name {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.85rem;
}

.walk-count,
.flow-count {
    flex: 0 0 auto;
    background: #495057;
    padding: 0 0.35rem;
    font-size: 0.7rem;
}

.walk-action,
.flow-action {
    --bs-btn-padding-x: 0.4rem;
    --bs-btn-padding-y: 0.05rem;
}

/* Macchina che non c'e' piu': resta nell'elenco del binario, perche' e' un
   legame scritto, ma la sua linea non finisce nell'export. */
.flow-name .missing {
    text-decoration: line-through;
    color: #ff6b6b;
}

/* Binario senza macchine: e' disegnato, ma l'export non saprebbe di chi e'. */
.flow-name.unassigned {
    color: #ffc107;
    font-style: italic;
}

.flow-machines {
    flex: 1 1 auto;
    min-width: 0;
    font-family: var(--bs-font-monospace, monospace);
    font-size: 0.75rem;
}

/* Punti del binario scelto in Flower: si prendono come gli angoli dei muri. */
.flow-handle { cursor: grab; }
#flow-handles.dragging .flow-handle { cursor: grabbing; }

/* L'etichetta del raggio dice a che cosa si applica: puo' essere lunga, e si
   taglia invece di spingere il campo fuori dalla riga. */
.flow-radius-label {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.75rem;
}

.flow-radius input {
    flex: 0 0 5.5rem;
}

/* La larghezza sta accanto alle macchine: un numero di due cifre non chiede
   di piu', e il campo delle macchine si prende il resto della riga. */
.flow-width {
    flex: 0 0 5.5rem;
    width: 5.5rem;
}

/* Sequenza degli item della walk attiva: e' il risultato del disegno, quindi
   va letta, ma non deve far crescere il pannello oltre la sua altezza. */
.walk-items {
    max-height: 9rem;
    margin: 0.35rem 0 0;
    padding: 0.25rem;
    overflow-y: auto;
    list-style: decimal inside;
    background: rgba(0, 0, 0, 0.25);
    font-family: var(--bs-font-monospace, monospace);
    font-size: 0.72rem;
}

.walk-items li {
    white-space: nowrap;
}

/* Id rimasto senza item: resta scritto, perche' fa parte della sequenza
   disegnata, ma Update lo salta. */
.walk-items li.missing {
    color: #ff8a80;
    text-decoration: line-through;
}

/* Item attraversato ma non un passo (id senza ASI completo, o uno scaffale
   rimasto da un file vecchio): resta scritto, ma Update e i collegamenti lo
   saltano. */
.walk-items li.ignored {
    color: rgba(255, 255, 255, 0.4);
    font-style: italic;
}

/* I controlli propri di una modalita' vengono nascosti con l'attributo hidden.
   La regola serve perche' le utility display di Bootstrap (d-flex, btn-group)
   avrebbero altrimenti la precedenza sul display:none del browser. */
[hidden] {
    display: none !important;
}

/* ...e i pannelli lasciano scoperta la barra in fondo. */
.offcanvas-body {
    padding-bottom: 5rem;
}

/* Prototipi che non si posano dalla galleria: restano visibili, per sapere che
   esistono, ma non si scelgono. */
.item-locked .itemBox {
    opacity: 0.55;
    cursor: not-allowed;
    user-select: none;
}

.item-locked .itemBox:hover {
    box-shadow: none;
}

/* Campi in sola lettura del pannello Details: Bootstrap colora lo sfondo dei
   soli campi disabilitati, e un readonly sembrerebbe modificabile. */
#itemDetailsBody [readonly] {
    background-color: var(--bs-secondary-bg, #e9ecef);
}

/* Guida ai comandi (SadHelp) ----------------------------------------------- */

/* Le modalita': vanno a capo invece di allargare la finestra. */
.help-modes {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    margin-bottom: 1rem;
}

.help-modes .btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}

.help-tab-count {
    min-width: 1.4em;
    padding: 0 0.35em;
    border-radius: 1em;
    background: rgba(0, 0, 0, 0.08);
    font-size: 0.72em;
    line-height: 1.5;
}

/* Le pagine stanno in fila e la fila scorre: la pagina e' larga quanto la
   finestra su cui si guarda, quindi -100% e' una pagina esatta. */
.help-stage {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.help-viewport {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
}

.help-track {
    display: flex;
    transition: transform 0.35s ease;
}

.help-track.no-slide {
    transition: none;
}

.help-page {
    flex: 0 0 100%;
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.75rem;
    align-content: start;
    /* Lo spazio per l'ombra e il sollevamento della card sotto al puntatore,
       che la finestra altrimenti taglierebbe. */
    padding: 0.35rem 0.25rem 0.6rem;
}

@media (max-width: 991.98px) {
    .help-page {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.help-arrow {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 2.5rem;
    height: 2.5rem;
    border: 1px solid #dee2e6;
    border-radius: 50%;
    background: #ffffff;
    color: #212529;
    transition: background-color 0.15s, border-color 0.15s, opacity 0.15s;
}

.help-arrow:hover:not(:disabled),
.help-arrow:focus-visible {
    background: #ffc107;
    border-color: #ffc107;
}

.help-arrow:disabled {
    opacity: 0.3;
}

.help-dots {
    display: flex;
    justify-content: center;
    gap: 0.4rem;
    min-height: 0.6rem;
    margin-top: 0.5rem;
}

.help-dot {
    width: 0.6rem;
    height: 0.6rem;
    padding: 0;
    border: 0;
    border-radius: 0.3rem;
    background: #ced4da;
    transition: width 0.2s, background-color 0.2s;
}

.help-dot:hover {
    background: #adb5bd;
}

.help-dot.active {
    width: 1.6rem;
    background: #ffc107;
}

.help-card {
    display: flex;
    flex-direction: column;
    padding: 0;
    border: 1px solid #dee2e6;
    background: #ffffff;
    color: inherit;
    text-align: left;
    transition: border-color 0.15s, box-shadow 0.15s, transform 0.15s;
}

.help-card:hover,
.help-card:focus-visible {
    border-color: #ffc107;
    box-shadow: 0 0.4rem 1rem rgba(0, 0, 0, 0.12);
    transform: translateY(-2px);
    outline: none;
}

.help-card-title {
    padding: 0.45rem 0.65rem;
    border-top: 1px solid #f1f3f5;
    font-size: 0.85rem;
    font-weight: 600;
}

/* Il disegno di una card, e lo stesso in grande: la tela e' 16 x 10. */
.help-art {
    position: relative;
    display: block;
    aspect-ratio: 16 / 10;
    background: #ffffff;
}

.help-art > svg {
    display: block;
    width: 100%;
    height: 100%;
}

.help-art-large {
    border: 1px solid #dee2e6;
}

/* Il comando nell'angolo: le misure sono in em, quindi basta il corpo per
   farlo grande nella vista grande. */
.help-corner {
    position: absolute;
    right: 0.35rem;
    bottom: 0.35rem;
    padding: 0.25em 0.4em;
    border-radius: 0.4em;
    background: rgba(255, 255, 255, 0.92);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
    font-size: 0.6rem;
    pointer-events: none;
}

.help-corner:empty {
    display: none;
}

.help-art-large .help-corner {
    right: 0.75rem;
    bottom: 0.75rem;
    font-size: 1.05rem;
}

.help-input {
    display: inline-flex;
    align-items: center;
    gap: 0.3em;
    white-space: nowrap;
}

.help-sep {
    color: #6c757d;
    font-weight: 600;
}

/* Un tasto: piu' alto davanti che dietro, come quelli veri. Vince sul kbd di
   Bootstrap, scuro e piatto. */
.help-key {
    display: inline-grid;
    place-items: center;
    min-width: 2em;
    height: 2em;
    padding: 0 0.5em;
    border: 1px solid #adb5bd;
    border-bottom-width: 3px;
    border-radius: 0.35em;
    background: linear-gradient(#ffffff, #f1f3f5);
    color: #212529;
    font: 600 1em/1 var(--bs-body-font-family);
    box-shadow: none;
}

.help-arrows {
    display: inline-grid;
    grid-template-columns: repeat(3, auto);
    grid-template-areas: ". up ." "left down right";
    gap: 0.12em;
}

.help-arrows .help-key {
    min-width: 1.7em;
    height: 1.35em;
    padding: 0;
    font-size: 0.8em;
}

.help-arrows .up { grid-area: up; }
.help-arrows .left { grid-area: left; }
.help-arrows .down { grid-area: down; }
.help-arrows .right { grid-area: right; }

.help-nav-keys {
    display: inline-grid;
    grid-template-columns: auto auto;
    gap: 0.12em;
}

.help-nav-keys .help-key {
    height: 1.5em;
    font-size: 0.72em;
}

.help-mouse-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.15em;
}

.help-mouse {
    width: 1.5em;
    height: 2.25em;
}

.help-mouse-chip .bi {
    color: #212529;
    font-size: 1.1em;
}

/* Un pulsante della barra, giallo come li'. */
.help-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35em;
    height: 2em;
    padding: 0 0.6em;
    background: #ffc107;
    color: #000000;
    font-weight: 500;
}

.help-btn.dark {
    background: #212529;
    color: #ffffff;
}

.help-btn.light {
    border: 1px solid #6c757d;
    background: #ffffff;
}

.help-btn .help-menu {
    font-size: 0.7em;
    opacity: 0.7;
}

.help-info {
    justify-content: center;
    width: 2em;
    padding: 0;
    border-radius: 50%;
    background: #0d6efd;
    color: #ffffff;
}

/* Vista grande. Prende il fuoco quando si apre una card (SadHelp._keepFocus),
   ma non e' un controllo: niente bordo. */
#help-detail:focus {
    outline: none;
}

.help-detail-head {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 0.75rem;
}

.help-count {
    color: #6c757d;
    font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
}

.help-overline {
    color: #6c757d;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.help-title {
    margin: 0.25rem 0 1rem;
    font-weight: 700;
}

.help-combos {
    margin: 0 0 1rem;
    padding: 0;
    list-style: none;
}

.help-combos li {
    padding: 0.65rem 0;
    border-top: 1px solid #e9ecef;
}

.help-combo-keys {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.85rem;
}

.help-combos p {
    margin: 0.45rem 0 0;
    font-size: 0.9rem;
}

.help-where {
    color: #6c757d;
    font-size: 0.8rem;
}

.help-text {
    color: #495057;
    font-size: 0.9rem;
}

.help-fade {
    animation: help-fade 0.25s ease;
}

@keyframes help-fade {
    from { opacity: 0; transform: translateY(4px); }
    to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .help-track,
    .help-card,
    .help-dot {
        transition: none;
    }

    .help-fade {
        animation: none;
    }
}

.sad-canvas {
    position: absolute;
    inset: 0;
}

.sad-canvas > #panel {
    display: block;
    width: 100%;
    height: 100%;
    background: #fff;
    /* Il tasto centrale non deve attivare lo scorrimento automatico. */
    touch-action: none;
}

/* Triggerable -------------------------------------------------------------- */

.triggerable { transition: opacity 0.3s ease; }

/* Rotazioni e ribaltamenti -------------------------------------------------- */

.rotate, .flip {
    transform-box: fill-box;
    transform-origin: center;
}

/* Quando rotazione e flip convivono, SadObject emette una singola transform
   inline: le classi qui sotto si sovrascriverebbero a vicenda. */
.transform-inline {
    transform-box: fill-box;
    transform-origin: center;
}

.rotating-slow { animation: rotate-animation 5s infinite ease-in-out; }
.rotating { animation: rotate-animation 3s infinite ease-in-out; }
.rotating-fast { animation: rotate-animation 1s infinite ease-in-out; }

.rotate-45 { transform: rotate(45deg); }
.rotate-90 { transform: rotate(90deg); }
.rotate-135 { transform: rotate(135deg); }
.rotate-180 { transform: rotate(180deg); }
.rotate-225 { transform: rotate(225deg); }
.rotate-270 { transform: rotate(270deg); }
.rotate-315 { transform: rotate(315deg); }

.flip-x { transform: scaleX(-1); }
.flip-y { transform: scaleY(-1); }
.flip-all { transform: scale(-1, -1); }

/* Hoverable ---------------------------------------------------------------- */

.hoverable { opacity: 0; transition-duration: 0.3s; }
.hoverable:hover { opacity: 1; }

/* L'ingombro degli statici (SadObject._buildHit): ferma il mouse dove il click
   destro li sceglie, cioe' nell'editor e nelle schede. Nelle altre modalita' il
   click li attraversa, e deve farlo anche l'hover. */
.static-hit { pointer-events: none; }
body[data-mode="Editor"] .static-hit,
body[data-mode="Machines"] .static-hit { pointer-events: all; }

/* Le frecce di flusso stanno fuori dall'hoverable, per essere disegnate sopra a
   motori e sensori, ma si scoprono insieme a esso: sono un fratello successivo
   dentro lo stesso gruppo dell'item. Non ricevono eventi perche' opacity non li
   disattiva: da invisibili intercetterebbero il click sul sensore sottostante. */
.flows-hover { opacity: 0; transition-duration: 0.3s; pointer-events: none; }
.hoverable:hover ~ .flows-hover { opacity: 1; }

/* Evidenza di sensori e motori: la classe e' quella dello Scada 2.0
   (Components.svg), scritta nei modelli. Qui la scopre il passaggio sull'icona
   e non sull'evidenza, che e' piu' grande della cella: ricevendo eventi,
   invisibile, toglierebbe all'item sotto l'evidenziazione e l'etichetta. */
.hoverGroup { opacity: 0; transition-duration: 0.3s; pointer-events: none; }
svg[data-sensor]:hover > .hoverGroup,
svg[data-engine]:hover > .hoverGroup { opacity: 1; }

/* Pulse -------------------------------------------------------------------- */

.pulse-small, .pulse-small-alert, .pulse {
    transform-box: fill-box;
    transform-origin: center;
}

.pulse { animation: pulse-animation 1s infinite; }
.pulse-small { animation: pulse-small-animation 1s infinite; }
.pulse-small-alert { animation: pulse-small-alert-animation 1s infinite; }

/* Hidden ------------------------------------------------------------------- */

.hidden { opacity: 0.25; }

/* Galleria dei prototipi --------------------------------------------------- */

.itemBox { cursor: pointer; }

.card-body { height: 150px; align-items: center; }

/* Solo l'svg esterno dell'anteprima: con ".itemImg svg" la regola arrivava
   anche agli svg annidati - il modello dentro l'anteprima, le fasce dello
   switcher - e li stirava tutti sull'icona intera. */
.itemImg > svg {
    width: 100%;
    height: 100%;
    display: block;
}

/* Rispetto delle preferenze di sistema ------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    .rotating, .rotating-slow, .rotating-fast,
    .pulse, .pulse-small, .pulse-small-alert {
        animation: none;
    }
}
