/* ═══════════════════════════════════════════════════════════════════
   Addit - 3D Print Quoting Web App
   Styles with responsive mobile support
   ═══════════════════════════════════════════════════════════════════

   FOGLIO DI STILE PRINCIPALE DELL'APPLICAZIONE ADDIT
   ───────────────────────────────────────────────────
   Questo file contiene tutti gli stili CSS per l'applicazione web
   Addit, un configuratore per preventivi di stampa 3D.

   L'interfaccia e' composta da:
   - Header con logo, navigazione e menu utente
   - Area viewer 3D (Three.js / Canvas2D) con pulsanti sovrapposti
   - Sidebar laterale con pannelli collassabili (analisi, pricing, parametri)
   - Zona drag-and-drop per caricamento file STL/STEP

   Supporto temi: tema scuro (default) e tema chiaro (classe body.light)
   Supporto responsive: layout adattivo per tablet (<768px) e smartphone (<480px)
   Supporto touch: ottimizzazioni per dispositivi touch (hover:none, pointer:coarse)

   Struttura del file:
   1. Reset e variabili CSS (temi scuro/chiaro)
   2. Layout principale (griglia a 2 colonne)
   3. Header e navigazione
   4. Menu utente con dropdown
   5. Area viewer 3D e zona drop
   6. Legenda debug raggi (analisi undercut)
   7. Sidebar e pannelli collassabili
   8. Pulsanti viewer (wireframe, heatmap, undercut, rotazione)
   9. Barra di progresso (conversione/analisi)
   10. Stati di caricamento analisi
   11. Pannello parametri STEP (tessellazione)
   12. Pulsanti toggle mobile
   13. Media queries responsive (<768px, <480px)
   14. Ottimizzazioni per dispositivi touch
   ═══════════════════════════════════════════════════════════════════ */

/* Reset globale: azzera margini, padding e imposta box-sizing border-box
   su tutti gli elementi per un calcolo coerente delle dimensioni */
* { margin: 0; padding: 0; box-sizing: border-box; }

/* ── Dark theme (default) ── */
/* Variabili CSS per il tema scuro (tema predefinito).
   Definisce tutti i colori dell'interfaccia: sfondo pagina, testo, header,
   viewer 3D, zona drop, sidebar, pannelli, righe proprieta', card,
   input, colore accent e colori griglia Three.js */
:root {
  --bg: #f0f2f5; --text: #1a1a2e;
  --header-bg: #ffffff; --header-text: #333;
  --viewer-bg: #1e1e32; --viewer-bg2: #252540;
  --drop-text: #8888aa; --drop-p: #aaa;
  --sidebar-bg: #fff; --sidebar-border: #e0e0e0;
  --panel-header-bg: #fafafa; --panel-header-text: #555;
  --row-border: #f5f5f5; --label-color: #777; --value-color: #333;
  --card-bg: #f8f9fb; --card-border: #eee; --card-name: #444; --card-cost: #666;
  --input-bg: #fff; --input-border: #ddd;
  --accent: #1a73e8;
  --viewer-info-bg: rgba(0,0,0,.5); --viewer-info-text: #99a;
  --grid-color1: 0x3a3a5a; --grid-color2: 0x2a2a44;
  --three-bg: 0x1e1e32;
}

/* ── Light theme ── */
/* Variabili CSS per il tema chiaro. Sovrascrive tutte le variabili
   quando la classe "light" e' presente sul body. Colori piu' luminosi
   per sfondo, sidebar e pannelli; testo piu' scuro per contrasto */
body.light {
  --bg: #ffffff; --text: #222;
  --header-bg: #ffffff; --header-text: #333;
  --viewer-bg: #d8dce6; --viewer-bg2: #c8ccd8;
  --drop-text: #6668; --drop-p: #555;
  --sidebar-bg: #f8f8fa; --sidebar-border: #ddd;
  --panel-header-bg: #eef0f4; --panel-header-text: #444;
  --row-border: #e8e8ec; --label-color: #666; --value-color: #222;
  --card-bg: #fff; --card-border: #ddd; --card-name: #333; --card-cost: #555;
  --input-bg: #fff; --input-border: #ccc;
  --accent: #2563eb;
  --viewer-info-bg: rgba(255,255,255,.7); --viewer-info-text: #556;
}

/* Stili base del body: font di sistema (San Francisco, Segoe UI, Roboto),
   colori dal tema corrente, transizione morbida per il cambio tema */
body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
  transition: background .3s, color .3s;
}

/* Layout principale dell'applicazione: griglia CSS a 2 colonne.
   Colonna sinistra (1fr) = area viewer 3D, colonna destra (380px) = sidebar.
   Due righe: header (auto) e contenuto (1fr). Occupa tutta l'altezza viewport */
.app {
  display: grid;
  grid-template-columns: 1fr 380px;
  grid-template-rows: auto 1fr;
  height: 100vh;
  gap: 0;
}

/* ── Header ── */
/* Barra superiore dell'applicazione: si estende su tutta la larghezza
   della griglia (grid-column: 1 / -1). Contiene logo, titolo, sottotitolo,
   pulsanti di navigazione, menu utente e toggle tema */
header {
  grid-column: 1 / -1;
  background: var(--header-bg);
  color: var(--header-text);
  padding: 5px 24px;
  display: flex;
  align-items: center;
  gap: 16px;
  border-bottom: 1px solid #e2e8f0;
}

/* Logo aziendale nell'header: altezza fissa 80px, larghezza proporzionale */
.header-logo {
  height: 80px;
  width: auto;
}

/* Contenitore titolo e sottotitolo nell'header: layout verticale,
   occupa tutto lo spazio disponibile (flex: 1) */
.header-titles {
  display: flex;
  flex-direction: column;
  flex: 1;
}

/* Titolo principale "Addit" nell'header */
header h1 {
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.3px;
}

/* Sottotitolo/descrizione sotto il titolo nell'header */
.header-titles span {
  font-size: 13px;
  color: #999;
}

/* Contenitore pulsanti di navigazione nell'header (es. Viewer, Shop, Admin) */
.header-nav {
  display: flex;
  gap: 8px;
}

/* Singolo pulsante di navigazione nell'header: stile pillola con bordo
   arrotondato, icona + testo affiancati, effetto hover con colore accent */
.nav-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  background: #f5f5f5;
  border: 1px solid #ddd;
  border-radius: 8px;
  color: #555;
  text-decoration: none;
  font-size: 13px;
  font-weight: 500;
  transition: all 0.15s;
  cursor: pointer;
}

/* Stato hover dei pulsanti di navigazione: sfondo azzurro chiaro e bordo blu */
.nav-btn:hover {
  background: #eff6ff;
  border-color: #4a7ccc;
  color: #4a7ccc;
}

/* ── User menu ── */
/* Menu utente nell'header: contenitore con posizionamento relativo
   per il dropdown che appare al click */
.user-menu {
  position: relative;
  display: flex;
}

/* Pulsante toggle del menu utente: mostra nome utente/icona,
   sfondo semi-trasparente, al click apre il dropdown sottostante */
.user-menu-toggle {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  background: rgba(0,0,0,.06);
  border: 1px solid rgba(0,0,0,.1);
  border-radius: 6px;
  color: var(--header-text);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
}

/* Dropdown del menu utente: nascosto di default, si posiziona sotto il
   pulsante toggle. Contiene voci come Profilo, Ordini, Logout.
   Ombra pronunciata e z-index alto per sovrapporsi al contenuto */
.user-dropdown {
  display: none;
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: 6px;
  background: #fff;
  border: 1px solid #ddd;
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.12);
  min-width: 180px;
  z-index: 200;
  padding: 6px;
}

/* Stato aperto del dropdown: reso visibile tramite classe "open" aggiunta via JS */
.user-dropdown.open {
  display: block;
}

/* Singola voce del dropdown utente: icona + testo, bordi arrotondati,
   hover con sfondo grigio chiaro */
.dropdown-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  color: #333;
  text-decoration: none;
  font-size: 13px;
  border-radius: 6px;
  transition: background 0.1s;
}

/* Hover generico sulle voci del dropdown */
.dropdown-item:hover {
  background: #f5f5f5;
}

/* Voce pericolosa del dropdown (es. Logout): hover rosso per evidenziare
   l'azione distruttiva */
.dropdown-danger:hover {
  background: #fee2e2;
  color: #dc2626;
}

/* Separatore orizzontale tra gruppi di voci nel dropdown */
.dropdown-divider {
  height: 1px;
  background: #e5e5e5;
  margin: 4px 0;
}

/* Pulsante toggle tema chiaro/scuro nell'header: icona sole/luna,
   dimensione minima 44px per accessibilita' touch */
#theme-btn {
  background: rgba(0,0,0,.06);
  border: 1px solid rgba(0,0,0,.1);
  color: var(--header-text);
  padding: 5px 12px;
  border-radius: 6px;
  font-size: 16px;
  cursor: pointer;
  transition: background .15s;
  min-width: 44px;
  min-height: 44px;
}

/* Hover sul pulsante tema: leggero scurimento dello sfondo */
#theme-btn:hover {
  background: rgba(0,0,0,.1);
}

/* ── Viewer Area ── */
/* Area principale del visualizzatore 3D: occupa la colonna sinistra della
   griglia. Contiene il canvas Three.js/Canvas2D, la zona drag-and-drop,
   i pulsanti sovrapposti e le info del viewer. Sfondo scuro dal tema */
.viewer-area {
  position: relative;
  background: var(--viewer-bg);
  overflow: hidden;
}

/* Zona drag-and-drop per il caricamento file: copre tutta l'area viewer
   con posizionamento assoluto. Mostra icona e testo invito al centro.
   Sfondo con gradiente verticale. Si nasconde dopo il caricamento del modello */
#drop-zone {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 10;
  background: linear-gradient(180deg, var(--viewer-bg) 0%, var(--viewer-bg2) 100%);
  color: var(--drop-text);
  cursor: pointer;
  transition: background .2s;
}

/* Feedback visivo quando un file viene trascinato sopra la zona drop:
   leggero aumento di luminosita' */
#drop-zone.drag-over {
  filter: brightness(1.1);
}

/* Zona drop nascosta: dopo il caricamento del modello 3D */
#drop-zone.hidden {
  display: none;
}

/* Icona grande nella zona drop: il disegno del pezzo con la quota
   (static/ico/drop-part.svg). ⚠️ Era l'emoji della scatola di cartone a 56px,
   con `grayscale(.5)` a spegnerla: sembrava una spedizione, non un'analisi. */
#drop-zone .icon {
  width: 108px;
  height: auto;
  margin-bottom: 20px;
  opacity: .85;
}

/* Testo descrittivo nella zona drop (es. "Trascina qui il tuo file 3D") */
#drop-zone p {
  font-size: 16px;
  color: var(--drop-p);
}

/* Testo secondario nella zona drop (formati supportati): piccolo e semi-trasparente */
#drop-zone small {
  font-size: 12px;
  margin-top: 8px;
  opacity: .45;
}

/* Selettore modalita' conversione STEP nella zona drop: permette di scegliere
   tra conversione server-side e client-side (WASM). Sfondo semi-trasparente */
.step-mode-selector {
  margin-top: 20px;
  padding: 10px 16px;
  background: rgba(255,255,255,0.1);
  border-radius: 8px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
}

/* Etichetta del selettore modalita' STEP */
.step-mode-selector label {
  color: var(--drop-p);
  white-space: nowrap;
}

/* Menu a tendina del selettore STEP: sfondo scuro semi-trasparente (tema scuro) */
.step-mode-selector select {
  padding: 6px 10px;
  border-radius: 6px;
  border: 1px solid rgba(255,255,255,0.2);
  background: rgba(0,0,0,0.3);
  color: #fff;
  font-size: 12px;
  cursor: pointer;
}

/* Selettore STEP in tema chiaro: sfondo grigio chiaro */
.light .step-mode-selector {
  background: rgba(0,0,0,0.05);
}

/* Menu a tendina STEP in tema chiaro: sfondo bianco, testo scuro */
.light .step-mode-selector select {
  background: #fff;
  color: #333;
  border-color: #ccc;
}

/* Input file nascosto: attivato dal click sulla zona drop tramite label */
#file-input {
  display: none;
}

/* Contenitore del canvas 3D (Three.js o Canvas2D): occupa tutta l'area viewer */
#viewer-container {
  width: 100%;
  height: 100%;
}

/* Canvas di rendering 3D: cursore "grab" per indicare la possibilita' di
   ruotare il modello. touch-action:none previene lo scroll su mobile
   durante l'interazione con il modello 3D */
#viewer-container canvas {
  display: block;
  width: 100%;
  height: 100%;
  cursor: grab;
  touch-action: none;
}

/* Canvas durante il trascinamento: cursore "grabbing" (mano chiusa) */
#viewer-container canvas:active {
  cursor: grabbing;
}

/* Etichetta informativa nel viewer (angolo in basso a sinistra): mostra
   istruzioni per mouse/touch (es. "Click sinistro: ruota"). Sfondo sfocato
   semi-trasparente, non intercetta eventi mouse (pointer-events: none) */
.viewer-info {
  position: absolute;
  bottom: 12px;
  left: 12px;
  background: var(--viewer-info-bg);
  color: var(--viewer-info-text);
  backdrop-filter: blur(4px);
  padding: 6px 14px;
  border-radius: 8px;
  font-size: 11px;
  pointer-events: none;
  z-index: 5;
}

/* Badge nel viewer (angolo in alto a destra): indica il tipo di rendering
   attivo (es. "WebGL" o "Canvas2D"). Piccolo e discreto */
.viewer-badge {
  position: absolute;
  top: 10px;
  right: 10px;
  background: var(--viewer-info-bg);
  color: var(--viewer-info-text);
  padding: 3px 10px;
  border-radius: 6px;
  font-size: 10px;
  pointer-events: none;
  z-index: 5;
}

/* ── Debug Rays Legend ── */
/* Legenda per la visualizzazione debug dei raggi di analisi undercut.
   Posizionata in basso a destra nel viewer. Mostra i colori dei diversi
   elementi di debug: origini (verde), hit UP (rosso), hit DOWN (blu),
   raggi (giallo), facce filtrate (grigio). Ogni voce ha un checkbox
   per attivare/disattivare la visualizzazione del singolo elemento */
/* ⚠️ In BASSO A SINISTRA, non a destra: a destra c'e' il cubo di navigazione e
   la legenda ci finiva sopra (segnalato da mp). */
.debug-legend {
  position: absolute;
  inset-block-end: var(--marca-space-2);
  inset-inline-start: var(--marca-space-2);
  background: var(--marca-surface-overlay);
  color: var(--marca-text-muted);
  border: var(--marca-border-width) solid var(--marca-border-control);
  border-radius: var(--marca-radius-control);
  padding: var(--marca-space-1);
  font-family: var(--marca-font-mono);
  font-size: var(--marca-type-mono-s-size);
  line-height: var(--marca-type-mono-s-lh);
  z-index: 10;
}

/* Titolo della legenda debug: maiuscolo, semi-trasparente */
.debug-legend-title {
  font-weight: var(--marca-weight-medium);
  text-transform: uppercase;
  letter-spacing: 0.3px;
  margin-block-end: var(--marca-space-1);
  color: var(--marca-text);
}

/* Singola voce della legenda debug: pallino colorato + testo descrittivo */
.debug-legend label {
  display: flex;
  align-items: center;
  gap: var(--marca-space-1);
  padding-block: 2px;
  cursor: pointer;
  color: inherit;
}

/* Hover sulle voci della legenda debug */
.debug-legend label:hover {
  opacity: .8;
}

/* Checkbox nascosti nella legenda: lo stato e' indicato visivamente
   dall'opacita' del pallino e del testo */
.debug-legend input[type="checkbox"] {
  display: none;
}

/* Pallino colorato nella legenda debug: cerchio 8x8px con bordo sottile */
.debug-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  display: inline-block;
  flex-shrink: 0;
  border: 1px solid rgba(255,255,255,.2);
}

/* Colori dei pallini debug: verde=origini ray, rosso=hit UP,
   blu=hit DOWN, giallo=percorso raggio, grigio=facce filtrate */
.debug-dot.green  { background: #4caf50; }
.debug-dot.red    { background: #f44336; }
.debug-dot.blue   { background: #2196f3; }
.debug-dot.yellow { background: #ffeb3b; }
.debug-dot.gray   { background: #9e9e9e; }

/* Pallino sbiadito quando il checkbox e' deselezionato: indica elemento
   debug non visibile nel viewer */
.debug-legend label input:not(:checked) ~ .debug-dot {
  opacity: .3;
}

/* Testo barrato e sbiadito per elementi debug disattivati */
.debug-legend label input:not(:checked) ~ span:last-child {
  opacity: .4;
  text-decoration: line-through;
}

/* Pulsante "Chiudi" della legenda debug: occupa tutta la larghezza,
   sfondo semi-trasparente con hover piu' opaco */
.debug-legend-close {
  display: block;
  width: 100%;
  margin-top: 6px;
  padding: 4px 8px;
  background: rgba(255,255,255,.1);
  color: inherit;
  border: 1px solid rgba(255,255,255,.15);
  border-radius: 4px;
  font-size: 10px;
  cursor: pointer;
  transition: background .15s;
}

/* Hover sul pulsante chiudi legenda (tema scuro) */
.debug-legend-close:hover {
  background: rgba(255,255,255,.2);
}

/* Adattamenti legenda debug per tema chiaro: bordi scuri anziche' chiari */
.light .debug-dot {
  border-color: rgba(0,0,0,.15);
}

/* Pulsante chiudi legenda in tema chiaro */
.light .debug-legend-close {
  background: rgba(0,0,0,.06);
  border-color: rgba(0,0,0,.12);
}

/* Hover pulsante chiudi legenda in tema chiaro */
.light .debug-legend-close:hover {
  background: rgba(0,0,0,.1);
}

/* ── Sidebar ── */
/* Barra laterale destra (380px): contiene i pannelli di analisi geometrica,
   pricing, parametri STEP e informazioni modello. Scroll verticale per
   contenuti lunghi, bordo sinistro come separatore dall'area viewer */
.sidebar {
  overflow-y: auto;
  background: var(--sidebar-bg);
  border-left: 1px solid var(--sidebar-border);
  transition: background .3s;
}

/* Singolo pannello nella sidebar: separato dagli altri con bordo inferiore */
.panel {
  border-bottom: 1px solid var(--card-border);
}

/* Intestazione del pannello: titolo in maiuscolo (es. "GEOMETRIA", "PRICING"),
   sfondo leggermente diverso per distinguerlo dal corpo. Flexbox per
   allineare titolo a sinistra e icona collapse a destra */
.panel-header {
  padding: 13px 16px;
  font-weight: 600;
  font-size: 13px;
  background: var(--panel-header-bg);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--panel-header-text);
  cursor: default;
  display: flex;
  justify-content: space-between;
  align-items: center;
  user-select: none;
}

/* Pannello collassabile: il cursore diventa puntatore per indicare
   che l'intestazione e' cliccabile per espandere/comprimere */
.panel-header.collapsible {
  cursor: pointer;
  transition: background 0.2s;
}

/* Hover sull'intestazione collassabile: leggero cambio sfondo */
.panel-header.collapsible:hover {
  background: var(--row-border);
}

/* Icona freccia per indicare lo stato del pannello (espanso/collassato):
   ruota di -90 gradi quando il pannello e' chiuso */
.collapse-icon {
  font-size: 10px;
  transition: transform 0.2s;
}

/* Icona ruotata quando il pannello e' collassato */
.panel-header.collapsed .collapse-icon {
  transform: rotate(-90deg);
}

/* Corpo del pannello: contiene le righe di proprieta'. Animazione
   fluida per espansione/compressione tramite max-height e opacity.
   max-height alto (2000px) per contenere qualsiasi contenuto */
.panel-body {
  padding: 10px 16px 14px;
  overflow: hidden;
  transition: max-height 0.3s ease, padding 0.3s ease, opacity 0.2s ease;
  max-height: 2000px;
  opacity: 1;
}

/* Corpo del pannello collassato: altezza zero, padding azzerato,
   completamente trasparente. L'overflow:hidden nasconde il contenuto */
.panel-body.collapsed {
  max-height: 0;
  padding-top: 0;
  padding-bottom: 0;
  opacity: 0;
}

/* Riga di proprieta' nel pannello: etichetta a sinistra, valore a destra.
   Usata per mostrare dimensioni, volume, superficie, spessore ecc. */
.prop-row {
  display: flex;
  justify-content: space-between;
  padding: 5px 0;
  font-size: 13px;
  border-bottom: 1px solid var(--row-border);
}

/* Ultima riga di proprieta': senza bordo inferiore */
.prop-row:last-child {
  border-bottom: none;
}

/* Etichetta della proprieta' (es. "Volume", "Superficie"): colore grigio */
.prop-label {
  color: var(--label-color);
}

/* Valore della proprieta' (es. "125.3 mm3"): grassetto, numeri tabulari
   per allineamento verticale coerente delle cifre */
.prop-value {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--value-color);
}

/* ── Barra strumenti del viewer ──────────────────────────────────────────────
   Un solo oggetto, non una manciata di pulsanti sparsi su un vetro smerigliato:
   i campi si toccano e si separano con un filo da 1px, come il controllo a
   gruppo del design system Marca (`.mg-segmented--s` in controls.css). I token
   arrivano da static/css/tokens.css, copiato dalla repo design_system.

   L'altezza chiude su 32 (4U) col FILO ASSORBITO: il pulsante misura
   32 − 2 fili, cosi' a chiudere sul ritmo e' la barra, non il pulsante. */
/* ⚠️ ATTACCATA all'angolo in alto a sinistra (richiesta di mp): niente margine,
   e la lastra perde i fili e gli spigoli sui due lati che toccano il bordo. */
.viewer-buttons {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 5;
  display: flex;
  flex-direction: column;
  gap: var(--marca-space-1);
  align-items: flex-start;
}

/* La barra: una lastra sola, senza spazi interni */
.btn-row {
  display: inline-flex;
  align-items: stretch;
  background: var(--marca-surface-overlay);
  border: var(--marca-border-width) solid var(--marca-border-control);
  border-block-start: 0;
  border-inline-start: 0;
  border-radius: 0 0 var(--marca-radius-control) 0;
  overflow: hidden;
}

.viewer-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--marca-space-1);
  block-size: calc(var(--marca-control-height-s) - 2 * var(--marca-border-width));
  padding-inline: var(--marca-space-1);
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--marca-text-muted);
  font-family: var(--marca-font-mono);
  font-size: var(--marca-type-mono-s-size);
  line-height: var(--marca-type-mono-s-lh);
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--marca-motion-state) var(--marca-ease-state),
              color var(--marca-motion-state) var(--marca-ease-state);
}

/* La giunzione fra due strumenti: un filo, mai uno spazio */
.viewer-btn + .viewer-btn {
  border-inline-start: var(--marca-border-width) solid var(--marca-border-control);
}

/* Separatore fra gruppi di strumenti: lo stesso filo, piu' marcato */
.tool-sep {
  inline-size: var(--marca-border-width);
  align-self: stretch;
  background: var(--marca-border-strong);
  flex: 0 0 auto;
}

.viewer-btn.icon-btn { display: inline-flex; }

/* Le icone sono <img>: seguono la condizione, non lo stato */
.btn-icon {
  width: 16px;
  height: 16px;
  opacity: .8;
  filter: invert(.82);
}
.light .btn-icon { filter: invert(.28); }
.viewer-btn:hover .btn-icon,
.viewer-btn.active .btn-icon { opacity: 1; }

.viewer-btn .bi { font-size: 15px; line-height: 1; }

/* Il passaggio cede allo stato con la guardia, non con l'ordine di scrittura */
.viewer-btn:hover:not(.active):not(.computing):not(.has-undercut):not(.no-undercut) {
  background: var(--marca-field-alt);
  color: var(--marca-text);
}

.viewer-btn:focus-visible {
  outline: var(--marca-focus-width) solid var(--marca-focus-ring);
  outline-offset: calc(-1 * var(--marca-focus-width));
}

/* ── Stati ──
   Ogni stato porta DUE segni: la superficie e la barra sotto. Il colore da solo
   non basta (e col solo colore, chi non lo distingue non vede niente). */
.viewer-btn.active,
.viewer-btn.computing,
.viewer-btn.has-undercut,
.viewer-btn.no-undercut {
  color: var(--marca-text);
  font-weight: var(--marca-weight-medium);
}

.viewer-btn.active::after,
.viewer-btn.computing::after,
.viewer-btn.has-undercut::after,
.viewer-btn.no-undercut::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  block-size: var(--marca-active-bar);
}

/* Strumento acceso (wireframe, spigoli, X-ray, heatmap...) */
.viewer-btn.active { background: var(--marca-identity-wash); }
.viewer-btn.active::after { background: var(--marca-mark); }

/* Calcolo in corso sul server */
.viewer-btn.computing { background: var(--marca-info-wash); }
.viewer-btn.computing::after { background: var(--marca-info); }

/* Esito: sottosquadra trovata / pezzo estraibile */
.viewer-btn.has-undercut { background: var(--marca-error-wash); }
.viewer-btn.has-undercut::after { background: var(--marca-error); }
.viewer-btn.no-undercut { background: var(--marca-success-wash); }
.viewer-btn.no-undercut::after { background: var(--marca-success); }

/* ── Rotazioni del modello (X/Y/Z) ──
   Stanno DENTRO la barra: lo span non fa scatola (`display: contents`), così i
   tre pulsanti si allineano agli altri invece di formare un gruppo a parte. */
#rotate-btns { display: contents; }

/* Niente filo sul primo: le rotazioni chiudono la barra e hanno gia' il
   separatore di gruppo davanti. */

/* Pulsanti di rotazione del modello 3D (90 gradi su X/Y/Z):
   stile simile ai pulsanti viewer, dimensione minima 44px
   per accessibilita' touch. Posizionati a destra nel viewer */
.rotate-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--marca-space-1);
  block-size: calc(var(--marca-control-height-s) - 2 * var(--marca-border-width));
  padding-inline: var(--marca-space-1);
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--marca-text-muted);
  font-family: var(--marca-font-mono);
  font-size: var(--marca-type-mono-s-size);
  line-height: var(--marca-type-mono-s-lh);
  cursor: pointer;
  transition: background-color var(--marca-motion-state) var(--marca-ease-state),
              color var(--marca-motion-state) var(--marca-ease-state);
}

.rotate-btn + .rotate-btn {
  border-inline-start: var(--marca-border-width) solid var(--marca-border-control);
}

.rotate-btn:hover {
  background: var(--marca-field-alt);
  color: var(--marca-text);
}

.rotate-btn:focus-visible {
  outline: var(--marca-focus-width) solid var(--marca-focus-ring);
  outline-offset: calc(-1 * var(--marca-focus-width));
}

/* Messaggio nella sidebar quando nessun file e' caricato:
   testo centrato grigio che invita a caricare un modello 3D */
.no-file {
  padding: 40px 16px;
  text-align: center;
  color: var(--label-color);
  font-size: 14px;
}

/* ── Progress Bar ── */
/* Barra di progresso sovrapposta al viewer: usata durante la conversione
   STEP, l'analisi spessore o l'analisi undercut. Centrata orizzontalmente
   nella parte bassa del viewer. Include etichetta testuale e barra animata */
.progress-container {
  position: absolute;
  bottom: 30%;
  left: 50%;
  transform: translateX(-50%);
  width: 80%;
  max-width: 400px;
  z-index: 15;
}

/* Etichetta sopra la barra di progresso: mostra il messaggio di stato
   (es. "Conversione STEP...", "Analisi spessore 45%") */
.progress-label {
  color: var(--drop-text);
  font-size: 13px;
  margin-bottom: 8px;
  text-align: center;
}

/* Sfondo della barra di progresso: traccia grigia semi-trasparente */
.progress-bar {
  width: 100%;
  height: 8px;
  background: rgba(255,255,255,0.1);
  border-radius: 4px;
  overflow: hidden;
}

/* Riempimento della barra di progresso: gradiente blu da accent a azzurro,
   la larghezza viene aggiornata via JS con transizione fluida */
.progress-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), #5cb3ff);
  border-radius: 4px;
  width: 0%;
  transition: width 0.2s ease-out;
}

/* Modalita' indeterminata: la barra scorre avanti e indietro quando
   la percentuale di completamento non e' nota */
.progress-fill.indeterminate {
  width: 30%;
  animation: indeterminate 1.5s ease-in-out infinite;
}

/* Animazione barra indeterminata: scorrimento da sinistra a destra */
@keyframes indeterminate {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(400%); }
}

/* ── Analysis Loading States ── */
/* Righe di risultati dell'analisi geometrica nella sidebar: simili
   a prop-row ma con supporto per stati di caricamento (spinner)
   e sezioni raggruppate per tipo di analisi */
.analysis-row {
  display: flex;
  justify-content: space-between;
  padding: 5px 0;
  font-size: 13px;
  border-bottom: 1px solid var(--row-border);
}

/* Ultima riga di analisi: senza bordo inferiore */
.analysis-row:last-child {
  border-bottom: none;
}

/* Valore numerico dell'analisi: grassetto con numeri tabulari */
.analysis-row .value {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--value-color);
}

/* Valore in stato di caricamento: testo corsivo grigio (es. "Calcolo...") */
.analysis-row .value.loading {
  color: var(--label-color);
  font-style: italic;
  font-weight: 400;
}

/* Spinner di caricamento dopo il testo: cerchietto rotante 12x12px
   che indica il calcolo in corso per un valore specifico */
.analysis-row .value.loading::after {
  content: '';
  display: inline-block;
  width: 12px;
  height: 12px;
  margin-left: 6px;
  border: 2px solid var(--label-color);
  border-top-color: transparent;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  vertical-align: middle;
}

/* Animazione di rotazione per lo spinner di caricamento */
@keyframes spin {
  to { transform: rotate(360deg); }
}

/* Sezione di analisi: gruppo di righe con separatore superiore
   (es. "Dimensioni", "Aree proiettate", "Spessore") */
.analysis-section {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--row-border);
}

/* Titolo della sotto-sezione analisi: piccolo, grassetto, semi-trasparente */
.analysis-section-title {
  font-size: 11px;
  font-weight: 600;
  margin-bottom: 6px;
  opacity: 0.7;
}

/* ── STEP Panel Inputs ── */
/* Campi di input nel pannello parametri STEP (tessellazione):
   permettono di regolare linearDeflection, angularDeflection e altri
   parametri che controllano la qualita' della tessellazione BREP */
.step-input {
  width: 70px;
  padding: 3px 6px;
  border: 1px solid var(--input-border);
  border-radius: 5px;
  font-size: 12px;
  text-align: right;
  background: var(--input-bg);
  color: var(--text);
}

/* Menu a tendina nel pannello STEP: larghezza automatica, testo a sinistra */
select.step-input {
  width: auto;
  text-align: left;
  cursor: pointer;
}

/* Pulsante "Ritessella" nel pannello STEP: applica i nuovi parametri
   di tessellazione e rigenera la mesh. Sfondo accent blu, 44px min
   per touch-friendly */
#step-reload-btn {
  margin-top: 8px;
  padding: 5px 14px;
  border-radius: 6px;
  border: 1px solid var(--input-border);
  background: var(--accent);
  color: #fff;
  font-size: 12px;
  cursor: pointer;
  min-height: 44px;
}

/* Hover sul pulsante Ritessella: leggera riduzione opacita' */
#step-reload-btn:hover {
  opacity: 0.9;
}

/* ═══════════════════════════════════════════════════════════════════
   Pulsanti Toggle Mobile
   ───────────────────────────────────────────────────────────────────
   Pulsanti circolari fissi (posizione fixed) visibili solo su mobile.
   Permettono di mostrare/nascondere i controlli del viewer e la sidebar
   su schermi piccoli dove lo spazio e' limitato. Nascosti su desktop.
   ═══════════════════════════════════════════════════════════════════ */

/* Pulsante toggle generico per mobile: cerchio 48px con icona,
   sfondo scuro con blur, ombra per distinguerlo dal contenuto.
   Nascosto su desktop (display:none), mostrato via media query */
.mobile-toggle-btn {
  display: none; /* Hidden on desktop by default */
  position: fixed; /* Fixed position so it doesn't move with layout */
  z-index: 100;
  background: rgba(0,0,0,.7);
  color: #fff;
  border: 1px solid rgba(255,255,255,.25);
  border-radius: 50%;
  width: 48px;
  height: 48px;
  font-size: 20px;
  cursor: pointer;
  backdrop-filter: blur(4px);
  transition: background .2s, transform .2s;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 8px rgba(0,0,0,.3);
}

/* Hover/active sui pulsanti toggle mobile: leggero ingrandimento (scala 1.05) */
.mobile-toggle-btn:hover,
.mobile-toggle-btn:active {
  background: rgba(60,60,100,.9);
  transform: scale(1.05);
}

/* Pulsanti toggle mobile in tema chiaro: sfondo bianco, ombra leggera */
.light .mobile-toggle-btn {
  background: rgba(255,255,255,.9);
  color: #444;
  border-color: rgba(0,0,0,.2);
  box-shadow: 0 2px 8px rgba(0,0,0,.15);
}

/* Hover toggle mobile in tema chiaro */
.light .mobile-toggle-btn:hover,
.light .mobile-toggle-btn:active {
  background: #fff;
}

/* Pulsante toggle strumenti viewer (mobile): posizionato sopra il toggle
   pannello, in basso a destra. Mostra/nasconde wireframe, heatmap ecc. */
#mobile-tools-toggle {
  bottom: 80px; /* Above the panel toggle */
  right: 16px;
}

/* Pulsante toggle sidebar/pannelli (mobile): in basso a destra,
   apre la sidebar come overlay a schermo intero */
#mobile-panel-toggle {
  bottom: 16px;
  right: 16px;
}

/* Pulsante "nuovo file" (mobile): in basso a sinistra, permette di
   caricare un nuovo modello 3D senza tornare alla zona drop */
#mobile-newfile-btn {
  bottom: 16px;
  left: 16px;
}

/* Nasconde il toggle strumenti quando nessun modello e' caricato:
   inutile mostrare wireframe/heatmap senza un modello */
#mobile-tools-toggle.hidden {
  display: none !important;
}

/* Maniglia di chiusura della sidebar su mobile: barra con testo
   "PANNELLO" e freccia, permette di collassare la sidebar overlay.
   Nascosta su desktop, mostrata su mobile via media query */
.sidebar-toggle-handle {
  display: none;
  width: 100%;
  padding: 14px 16px;
  background: var(--panel-header-bg);
  border: none;
  border-bottom: 1px solid var(--sidebar-border);
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  color: var(--panel-header-text);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  text-align: left;
}

/* Freccia nella maniglia: verso il basso quando la sidebar e' aperta */
.sidebar-toggle-handle::after {
  content: ' ▼';
  float: right;
  font-size: 10px;
}

/* Freccia verso l'alto quando la sidebar e' collassata */
.sidebar.collapsed .sidebar-toggle-handle::after {
  content: ' ▲';
}

/* ═══════════════════════════════════════════════════════════════════
   Responsive - PC basso (≤1100px)
   ───────────────────────────────────────────────────────────────────
   Sidebar ridotta a 320px per dare piu' spazio al viewer 3D.
   A 1024px: viewer 704px (era 644px con sidebar 380px).
   ═══════════════════════════════════════════════════════════════════ */

@media (max-width: 1100px) {
  .app {
    grid-template-columns: 1fr 320px;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   Responsive - PC 800px (≤860px)
   ───────────────────────────────────────────────────────────────────
   Sidebar 300px, header compatto, pulsanti viewer piu' piccoli.
   A 800px: viewer 500px (era 420px), header ~64px (era ~90px).
   ═══════════════════════════════════════════════════════════════════ */

@media (max-width: 860px) {
  .app {
    grid-template-columns: 1fr 300px;
  }

  header {
    padding: 4px 16px;
  }

  .header-logo {
    height: 56px;
  }

  header h1 {
    font-size: 20px;
  }

  .header-titles span {
    font-size: 11px;
  }

  .nav-btn {
    padding: 6px 10px;
    font-size: 12px;
  }

  .btn-row {
    flex-wrap: wrap;
  }

  .viewer-btn {
    padding-inline: var(--marca-space-1);
  }
}

/* ═══════════════════════════════════════════════════════════════════
   Responsive - Viewport corto (≤650px altezza)
   ───────────────────────────────────────────────────────────────────
   Per risoluzioni come 800x600: header ultra-compatto ~52px,
   sottotitolo nascosto per massimizzare l'area viewer.
   ═══════════════════════════════════════════════════════════════════ */

@media (max-height: 650px) {
  header {
    padding: 2px 16px;
  }

  .header-logo {
    height: 48px;
  }

  header h1 {
    font-size: 18px;
  }

  .header-titles span {
    display: none;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   Responsive - Mobile (<768px)
   ───────────────────────────────────────────────────────────────────
   Media query per tablet e smartphone: il layout passa da 2 colonne
   a colonna singola. L'area viewer occupa almeno 50vh, la sidebar
   diventa un overlay a schermo intero scorrevole dal basso.
   I pulsanti toggle mobile vengono mostrati, i controlli viewer
   nascosti di default per non ingombrare lo schermo piccolo.
   ═══════════════════════════════════════════════════════════════════ */

@media (max-width: 768px) {
  /* Griglia a colonna singola per schermi piccoli */
  .app {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
  }

  /* Header compatto su mobile: padding ridotto */
  header {
    padding: 10px 16px;
  }

  /* Logo piu' piccolo su mobile */
  .header-logo {
    height: 50px;
  }

  /* Titolo ridotto su mobile */
  header h1 {
    font-size: 16px;
  }

  /* Sottotitolo nascosto su mobile per risparmiare spazio */
  header span {
    display: none;
  }

  /* Area viewer: occupa almeno meta' dello schermo */
  .viewer-area {
    grid-row: 2;
    min-height: 50vh;
  }

  /* Mostra i pulsanti toggle circolari su mobile */
  .mobile-toggle-btn {
    display: flex;
  }

  /* Sidebar come overlay a schermo intero su mobile: copre tutto
     lo schermo con posizione fixed, scorre verticalmente.
     Si anima con translateY per entrare/uscire dal basso */
  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 200;
    overflow-y: auto;
    background: var(--sidebar-bg);
    transition: transform .3s ease-out;
    transform: translateY(0);
  }

  /* Mostra la maniglia di chiusura sidebar su mobile: sticky in alto
     per restare visibile durante lo scroll dei pannelli */
  .sidebar-toggle-handle {
    display: block;
    position: sticky;
    top: 0;
    z-index: 2;
  }

  /* Sidebar collassata: scorre fuori dallo schermo verso il basso,
     pointer-events disabilitati per non bloccare l'interazione col viewer */
  .sidebar.collapsed {
    transform: translateY(100%);
    pointer-events: none;
  }

  /* Pulsanti viewer nascosti di default su mobile: mostrati
     tramite il toggle #mobile-tools-toggle */
  .viewer-buttons {
    top: 0;
    left: 0;
    right: auto;
    bottom: auto;
    transition: opacity .2s, visibility .2s;
  }

  /* Sotto i 768 la legenda di diagnostica non ci sta: in basso a sinistra ci
     sono gia' i pulsanti di rotazione. E' uno strumento da scrivania. */
  .debug-legend { display: none; }

  /* Pulsanti viewer nascosti su mobile quando non richiesti */
  .viewer-buttons.mobile-hidden {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
  }

  /* Righe pulsanti: wrap per adattarsi a schermi stretti */
  .btn-row {
    flex-wrap: wrap;
  }

  /* Al tocco il controllo sale alla taglia piena del sistema (48 = 6U) */
  .viewer-btn {
    block-size: calc(var(--marca-control-height) - 2 * var(--marca-border-width));
    padding-inline: var(--marca-space-2);
  }

  /* Al tocco anche le rotazioni salgono alla taglia piena, come gli altri */
  .rotate-btn {
    block-size: calc(var(--marca-control-height) - 2 * var(--marca-border-width));
    padding-inline: var(--marca-space-2);
  }

  /* Info viewer su mobile: centrata orizzontalmente, spostata piu' in alto
     per non sovrapporsi ai pulsanti toggle in basso */
  .viewer-info {
    bottom: 60px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 10px;
    white-space: nowrap;
  }

  /* Badge viewer su mobile: centrato in alto */
  .viewer-badge {
    top: 8px;
    left: 50%;
    right: auto;
    transform: translateX(-50%);
  }

  /* Pannelli sidebar su mobile: padding ridotto per piu' contenuto */
  .panel-header {
    padding: 12px;
    font-size: 12px;
  }

  /* Corpo pannello su mobile: padding ridotto */
  .panel-body {
    padding: 8px 12px 12px;
  }

  /* Righe proprieta' su mobile: font piu' piccolo */
  .prop-row {
    font-size: 12px;
    padding: 4px 0;
  }

  /* Input STEP adattati per touch: altezza minima 44px (linee guida
     Apple/Google per target touch), font piu' grande */
  .step-input {
    min-height: 44px;
    font-size: 14px;
    padding: 8px 10px;
  }

  /* Pulsante Ritessella su mobile: larghezza piena, piu' grande */
  #step-reload-btn {
    width: 100%;
    padding: 12px;
    font-size: 14px;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   Schermi molto piccoli (<480px)
   ───────────────────────────────────────────────────────────────────
   Media query per smartphone in orientamento verticale: ulteriore
   riduzione delle dimensioni di header, pulsanti e testi.
   Le righe di proprieta' passano a layout verticale (etichetta sopra,
   valore sotto) per adattarsi alla larghezza ridotta.
   ═══════════════════════════════════════════════════════════════════ */

@media (max-width: 480px) {
  /* Header ancora piu' compatto su smartphone */
  header {
    padding: 8px 12px;
    gap: 8px;
  }

  /* Logo molto piccolo su smartphone */
  .header-logo {
    height: 40px;
  }

  /* Titolo ridotto ulteriormente */
  header h1 {
    font-size: 14px;
  }

  /* Pulsante tema piu' compatto su smartphone */
  #theme-btn {
    padding: 4px 10px;
    font-size: 14px;
  }

  /* Area viewer leggermente piu' alta su smartphone (55vh) */
  .viewer-area {
    min-height: 55vh;
  }

  /* Su smartphone si stringe il respiro, non si inventa un altro corpo */
  .viewer-btn {
    padding-inline: var(--marca-space-1);
  }

  /* Righe proprieta' in layout verticale su smartphone:
     etichetta e valore impilati per larghezze molto ridotte */
  .prop-row {
    flex-direction: column;
    gap: 2px;
  }

  /* Valore allineato a sinistra in layout verticale */
  .prop-value {
    text-align: left;
  }

  /* Pulsanti toggle mobile leggermente piu' piccoli (42px) su smartphone */
  .mobile-toggle-btn {
    width: 42px;
    height: 42px;
    font-size: 16px;
  }

  /* Posizionamento toggle strumenti su smartphone */
  #mobile-tools-toggle {
    bottom: 70px;
    right: 12px;
  }

  /* Posizionamento toggle pannello su smartphone */
  #mobile-panel-toggle {
    bottom: 12px;
    right: 12px;
  }

  /* Posizionamento pulsante nuovo file su smartphone */
  #mobile-newfile-btn {
    bottom: 12px;
    left: 12px;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   Ottimizzazioni per dispositivi touch
   ───────────────────────────────────────────────────────────────────
   Media query specifica per dispositivi senza hover e con puntatore
   grossolano (touch): nasconde le istruzioni mouse, rimuove l'evidenziazione
   tap di WebKit, e nasconde i controlli viewer di default (mostrati
   tramite pulsante toggle). Questo garantisce che il massimo spazio
   sia dedicato alla visualizzazione del modello 3D.
   ═══════════════════════════════════════════════════════════════════ */

@media (hover: none) and (pointer: coarse) {
  /* Nasconde le istruzioni mouse ("Click sinistro: ruota") su touch,
     perche' non applicabili */
  .viewer-info {
    display: none;
  }

  /* Rimuove l'evidenziazione blu/grigia al tap su WebKit/Safari */
  button {
    -webkit-tap-highlight-color: transparent;
  }

  /* Pulsanti viewer nascosti di default su touch: l'utente li mostra
     premendo il pulsante toggle circolare */
  .viewer-buttons {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
  }

  /* Pulsanti viewer resi visibili via JS quando l'utente preme il toggle */
  .viewer-buttons.mobile-visible {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
  }

}

/* ── Toast notifications ── */
/* Notifiche non bloccanti che appaiono in basso al centro dello schermo.
   Sostituiscono alert() per errori e avvisi nel viewer 3D.
   Tre varianti: error (rosso), warning (arancione), info (blu) */
.toast {
  position: fixed;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%) translateY(100px);
  padding: 12px 24px;
  border-radius: 8px;
  z-index: 10000;
  opacity: 0;
  transition: all 0.3s ease;
  font-size: 14px;
  max-width: 80vw;
  pointer-events: none;
  box-shadow: 0 4px 12px rgba(0,0,0,.25);
}
.toast.show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.toast-error { background: #d32f2f; color: #fff; }
.toast-warning { background: #f57c00; color: #fff; }
.toast-info { background: #1976d2; color: #fff; }

