/* ══════════════════════════════════════════════════════════════
   VintedAgent — Design System 2026
   Inspired by Linear · Stripe · Vercel · Apple
══════════════════════════════════════════════════════════════ */
/* Font — Inter, auto-ospitata (2026-07-20, DC-63). Prima era caricata
   via @import da fonts.googleapis.com: l'@import in CSS è
   render-blocking e scopribile solo dopo il parsing di style.css,
   quindi il browser fa base→css2 endpoint→file woff2 in sequenza —
   tre round-trip prima che il font vero sia disponibile, da cui lo
   scatto visibile (FOUT) segnalato dal proprietario. Un file
   variabile locale (100-900, tutti i pesi già in uso nell'app) +
   preload in index.html elimina la catena di round-trip. Nessun
   cambio di font: Inter è già la scelta corretta per un prodotto
   premium (stesso riferimento Linear/Stripe/Mercury). */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: optional;
  font-optical-sizing: auto;
  src: url('/static/fonts/InterVariable.woff2') format('woff2');
}

:root {
  /* App sempre chiara (nessun toggle dark), nessun elemento nativo del
     browser (calendar-picker, scrollbar, ecc.) deve seguire la dark-mode
     del sistema operativo — altrimenti resta "nudo" perché le regole di
     skin qui sotto (es. input[type=date]::-webkit-calendar-picker-indicator)
     sono pensate solo per la resa chiara dei controlli nativi. */
  color-scheme: light;

  /* ── Palette — sophisticated, not generic ── */
  --bg:            #E4E7F0;   /* Clearly darker than white — creates depth */
  --surface:       #FFFFFF;
  --surface-2:     #F4F6FB;
  --surface-3:     #ECEEF6;
  --table-head:    #EFF1F9;   /* Table header distinct from row surface */

  --text:          #0D0F1A;
  --text-2:        #2A2F45;
  --muted:         #64748B;
  --subtle:        #9AA5B8;
  --faint:         #C8D0DF;

  --border:        rgba(0,0,0,0.055);
  --border-strong: rgba(0,0,0,0.10);
  --border-light:  rgba(255,255,255,0.80);

  /* ── Brand — Linear-grade deep purple ── */
  --indigo:        #6E56CF;
  --indigo-d:      #5B43B8;
  --indigo-light:  #8875E0;
  --indigo-soft:   rgba(110,86,207,0.08);
  --indigo-mid:    rgba(110,86,207,0.15);
  --violet:        #8B5CF6;
  --violet-soft:   rgba(139,92,246,0.08);
  --accent:        #6E56CF;
  --accent-soft:   rgba(110,86,207,0.08);
  --accent-glow:   rgba(110,86,207,0.30);

  /* ── Semantic ── */
  --green:         #10B981;
  --green-d:       #059669;
  --green-soft:    rgba(16,185,129,0.08);
  --green-text:    #065F46;
  --red:           #EF4444;
  --red-d:         #DC2626;
  --red-soft:      rgba(239,68,68,0.08);
  --red-text:      #991B1B;
  --amber:         #F59E0B;
  --amber-d:       #D97706;
  --amber-soft:    rgba(245,158,11,0.09);
  --amber-text:    #92400E;
  --teal:          #06B6D4;
  --teal-d:        #0891B2;
  --teal-soft:     rgba(6,182,212,0.08);
  --teal-text:     #164E63;
  --yellow-soft:   rgba(234,179,8,0.10);
  --yellow-text:   #713F12;

  /* ── Shadows — Stripe-quality, multi-layer ── */
  --shadow-xs:   0 1px 2px rgba(0,0,0,0.05);
  --shadow-sm:   0 0 0 1px rgba(0,0,0,0.04),
                 0 1px 3px rgba(0,0,0,0.06),
                 0 3px 8px rgba(0,0,0,0.04);
  --shadow-md:   0 0 0 1px rgba(0,0,0,0.04),
                 0 2px 4px rgba(0,0,0,0.04),
                 0 8px 20px rgba(0,0,0,0.06),
                 inset 0 1px 0 rgba(255,255,255,0.5);
  --shadow-card: 0 0 0 1px rgba(0,0,0,0.04),
                 0 1px 2px rgba(0,0,0,0.04),
                 0 4px 8px rgba(0,0,0,0.04),
                 0 16px 32px rgba(0,0,0,0.04),
                 inset 0 1px 0 rgba(255,255,255,0.7);
  --shadow-card-hover:
                 0 0 0 1px rgba(110,86,207,0.12),
                 0 4px 12px rgba(0,0,0,0.08),
                 0 16px 40px rgba(0,0,0,0.08),
                 inset 0 1px 0 rgba(255,255,255,0.9);
  --shadow-modal:0 0 0 1px rgba(0,0,0,0.07),
                 0 8px 24px rgba(0,0,0,0.12),
                 0 40px 80px rgba(0,0,0,0.16);
  --shadow-btn:  0 1px 2px rgba(0,0,0,0.06), 0 2px 6px rgba(0,0,0,0.08);

  /* ── Radius ── */
  --r-xs:   5px;
  --r-sm:   9px;
  --r-md:   12px;
  --r-lg:   16px;
  --r-xl:   20px;
  --r-2xl:  24px;
  --r-full: 9999px;

  /* ── Layout ──
     240px→180px (2026-09-12, richiesta esplicita del proprietario con
     screenshot annotato: la sidebar espansa in hover arrivava troppo
     oltre il testo delle voci, lasciando uno spazio vuoto a destra
     dell'etichetta più lunga — ridotta perché finisca circa dove
     indicato nello screenshot). */
  --sidebar-w: 180px;

  /* ── Breakpoint (2026-08-01, sistema mobile) ──
     Le media query non possono leggere custom property, quindi questi
     NON sono variabili funzionanti — sono la documentazione canonica dei
     due soli valori px da usare in tutte le @media dell'app, per non
     tornare a valori sparsi come prima di questa data (era 1280/900/720/
     560px senza alcun sistema). Ripetere il valore letterale nella query:
       @media (max-width: 900px) { ... }   ← soglia "tablet/nav"
       @media (max-width: 600px) { ... }   ← soglia "telefono"
     900px: la sidebar diventa una barra fissa in basso (icon-only, vedi
     sezione "Navigazione" più sotto), i layout multi-colonna passano a
     colonna singola.
     600px: rifiniture di spaziatura/type-scale, tabelle e modali più
     stretti ottimizzati (Inventario, lot-modal/decompose-modal).
     Vedi DESIGN_DECISIONS.md per la voce che introduce questo sistema. */

  /* ── Motion — Apple-grade easing ── */
  --ease-out:    cubic-bezier(0.16, 1, 0.3, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
  --dur-fast:    130ms;
  --dur:         200ms;
  --dur-slow:    320ms;
}

/* ══════════════════════════════════════════════════════════════
   PREMIUM LIGHT SYSTEM — token di base (2026-07-20)
   Sostituisce il tema dark come sistema principale dell'app (vedi
   DESIGN_DECISIONS.md, sezione "Sistema chiaro premium", che marca
   §1 come superata). Seme: pagina Tasse (DC-57/58), già nello
   spirito giusto — questi token ne formalizzano i valori reali
   (estratti, non reinventati) per riuso sulle altre pagine nelle
   fasi successive. Riferimenti: Stripe Dashboard, Linear (light
   mode), Mercury, Ramp — disciplina, non assenza di colore.

   FASE 1 — SOLO TOKEN. Additivi: non ridefiniscono i token base
   esistenti sopra (--surface, --border, --indigo, ecc.), quindi
   non alterano visivamente nessuna pagina finché non vengono
   adottati esplicitamente pagina per pagina. Uniche eccezioni,
   micro-fix su Tasse stessa per allinearla alle regole che se ne
   estraggono (vedi commenti puntuali in fondo al blocco TASSE).
══════════════════════════════════════════════════════════════ */
:root {
  /* ── 1. Scala sfondi ──────────────────────────────────────── */
  --bg-app:          #FAFAFA;  /* sfondo app — bianco caldo, mai piatto ovunque */
  --bg-sidebar:      #FAFAFA;  /* stesso tono del bg app: sidebar/topbar mai più scure del contenuto */
  --border-hairline: var(--border); /* alias esplicito — --border (rgba(0,0,0,.055) ≈ #EDEDED) è già il bordo tenue richiesto, nessun nuovo valore necessario */

  /* ── 2. Ombre a strati — scala di elevazione ─────────────────
     Card base restano quasi piatte (solo --border-hairline);
     l'ombra marcata è riservata a popover/modali. */
  --elev-0: none;
  --elev-1: 0 1px 1px rgba(16,24,40,0.03), 0 2px 6px rgba(16,24,40,0.02);    /* card a riposo, quasi impercettibile */
  --elev-2: 0 2px 4px rgba(16,24,40,0.05), 0 10px 24px rgba(16,24,40,0.03); /* hover / card sollevata */
  --elev-3: 0 4px 10px rgba(16,24,40,0.06), 0 20px 44px rgba(16,24,40,0.05);/* popover */
  --elev-4: 0 8px 20px rgba(16,24,40,0.08), 0 32px 64px rgba(16,24,40,0.08);/* modale */

  /* ── 3. Viola — con disciplina (azioni primarie, elemento
     protagonista di pagina, stati attivi/focus, wash dietro
     numeri hero). Ovunque altro: scale di grigio. ──────────── */
  --hero-wash:  radial-gradient(ellipse 70% 60% at 50% 0%, rgba(110,86,207,0.04) 0%, transparent 70%);
  --focus-ring: 0 0 0 3px rgba(110,86,207,0.15);
  --sidebar-active-bg:   rgba(110,86,207,0.08);
  --sidebar-active-text: var(--indigo);

  /* ── 4. Tipografia — valori reali già in uso in Tasse ────────
     (.tasse2-title / .tasse2-block-title, style.css:3454/3502) */
  --tracking-title: -0.02em; /* titoli pagina, numeri hero */
  --tracking-label:  0.05em; /* label maiuscole */

  /* ── 5. Colori semantici (stato) — pastello per sfondo chiaro:
     nessun nuovo token, riuso di quelli già definiti sopra
     (righe 38-55), già nella forma "sfondo pastello + testo
     saturo": --green-soft/--green-text, --amber-soft/--amber-text,
     --red-soft/--red-text, --teal-soft/--teal-text. Il rosso resta
     riservato a stati realmente critici (DC-11). */
}

/* Utility: cifre allineate — da applicare a ogni numero hero o
   tabellare della nuova UI chiara (requisito 4). */
.num-tabular { font-variant-numeric: tabular-nums; }

/* ══════════════════════════════════════════════════════════════
   RESET & BASE
══════════════════════════════════════════════════════════════ */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }

body {
  font-family: "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-feature-settings: "cv01" 1, "cv02" 1, "cv03" 1, "ss01" 1;
  background: var(--bg);
  background-image:
    radial-gradient(ellipse 80% 60% at -10% -10%, rgba(110,86,207,0.07) 0%, transparent 55%),
    radial-gradient(ellipse 50% 40% at 110% 110%, rgba(16,185,129,0.045) 0%, transparent 55%);
  background-attachment: fixed;
}

/* ══════════════════════════════════════════════════════════════
   LAYOUT
══════════════════════════════════════════════════════════════ */
.app-layout {
  display: flex;
  height: 100vh;
  overflow: hidden;
  position: relative;
}

/* ══════════════════════════════════════════════════════════════
   SIDEBAR
══════════════════════════════════════════════════════════════ */
.sidebar {
  width: var(--sidebar-w);
  flex-shrink: 0;
  background: #0E0F1A;
  /* Nessun bordo/linea statica di separazione dal contenuto (2026-09-12,
     richiesta esplicita del proprietario, riferimento Instagram: "non deve
     esserci una separazione visibile... la separazione deve vedersi solo
     con le card dell'hover") — il contrasto sidebar scura/contenuto chiaro
     basta da solo; la sola "separazione" resta lo sfondo evidenziato dei
     singoli .nav-item al passaggio del mouse. */
  display: flex;
  flex-direction: column;
  position: fixed;
  top: 0; left: 0; bottom: 0;
  z-index: 100;
}

/* Brand */
.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 22px 18px 18px;
  transition: gap 0.2s var(--ease-in-out), padding 0.2s var(--ease-in-out);
  background: none; border: none; cursor: pointer; width: 100%; text-align: left;
}
.brand-icon {
  width: 34px; height: 34px;
  background: linear-gradient(140deg, var(--indigo) 0%, var(--violet) 100%);
  border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  box-shadow: 0 2px 12px rgba(110,86,207,0.45), inset 0 1px 0 rgba(255,255,255,0.15);
  font-size: 15px; font-weight: 900; color: #fff;
  letter-spacing: -0.03em;
  transition: width 0.2s var(--ease-in-out), height 0.2s var(--ease-in-out), font-size 0.2s var(--ease-in-out);
}
/* Nav */
.sidebar-nav {
  padding: 12px 10px;
  flex: 1;
  display: flex;
  flex-direction: column;
  /* Centrato in verticale nello spazio fra logo e footer (2026-09-12,
     richiesta esplicita del proprietario, riferimento Instagram: "le icone
     devono essere al centro... solo il logo rimane in alto") — prima
     restavano ammassate subito sotto il logo, con un vuoto enorme sopra
     il footer. */
  justify-content: center;
  /* 1px→7px (2026-09-12, richiesta esplicita del proprietario: "distanziare
     di più le icone l'una dall'altra") — anche funzionale, non solo
     estetico: serve un minimo di margine perché l'icona ingrandita non
     tocchi quella sopra/sotto. */
  gap: 7px;
  /* overflow-y:auto RIMOSSO (2026-09-12): con le sole 7 voci attuali la
     lista non arriva mai a richiedere scroll (~390px, ampio margine anche
     su laptop da 700px di altezza) — e un overflow-y non-visible, per una
     regola poco nota della spec CSS, forza automaticamente anche
     overflow-x ad "auto" quando non è impostato esplicitamente,
     tagliando silenziosamente il fumetto .nav-label che deve invece
     sporgere FUORI dal rail a destra. Scoperto dal vivo: opacity/colori
     del fumetto risultavano corretti via getComputedStyle ma il fumetto
     non compariva mai a schermo — il container lo ritagliava. Se in
     futuro la lista crescerà abbastanza da eccedere l'altezza disponibile,
     va reintrodotto un meccanismo di scroll che non tagli l'asse
     orizzontale (es. su un wrapper interno dedicato), non semplicemente
     rimesso qui. */
}

/* Tooltip per singola icona (2026-09-12, sostituisce l'espansione
   dell'intera sidebar): la sidebar resta SEMPRE a rail stretto (64px,
   .sidebar-collapsed permanente, vedi app.js), non si allarga più al
   passaggio del mouse su un punto qualsiasi — richiesta esplicita del
   proprietario ("non si crea un intero background... voglio che si crei
   un'ombra limitata solo all'icona che punta il cursore"). .nav-label
   diventa quindi un fumetto flottante fuori dal rail, mostrato solo
   sull'hover del proprio .nav-item, invece di un testo che scorre inline
   dentro una sidebar che si allarga. */
.nav-label {
  position: absolute;
  left: calc(100% + 10px);
  top: 50%;
  transform: translateY(-50%) translateX(-4px);
  white-space: nowrap;
  background: var(--text);
  color: var(--surface);
  padding: 6px 11px;
  border-radius: var(--r-sm);
  font-size: 12px; font-weight: 600;
  box-shadow: var(--elev-3), 0 2px 6px rgba(0,0,0,0.25);
  opacity: 0;
  pointer-events: none;
  transition: opacity 130ms ease, transform 130ms ease;
  z-index: 20;
}
.nav-item:hover .nav-label {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
}

.nav-item {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  /* Padding fisso, mai sovrascritto da .sidebar-collapsed (la sidebar è
     ora SEMPRE collassata, vedi sopra) — l'icona ha una sola posizione
     possibile per costruzione, non serve più riconciliare due stati. */
  padding: 6px 3px;
  border: none;
  background: none;
  border-radius: var(--r-sm);
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  color: rgba(255,255,255,0.38);
  transition: background var(--dur) var(--ease-out),
              color var(--dur) var(--ease-out);
  text-align: left;
  width: 100%;
  font-family: inherit;
  letter-spacing: -0.015em;
  position: relative;
}
.nav-item:hover {
  background: rgba(255,255,255,0.055);
  color: rgba(255,255,255,0.72);
}
.nav-item.active {
  background: rgba(110,86,207,0.16);
  color: rgba(255,255,255,0.96);
  font-weight: 600;
}
.nav-item.active::after {
  content: "";
  position: absolute;
  left: 0; top: 6px; bottom: 6px;
  width: 2px;
  background: linear-gradient(180deg, var(--indigo-light), var(--violet));
  border-radius: 0 2px 2px 0;
  box-shadow: 0 0 8px rgba(110,86,207,0.7);
}

.nav-icon-wrap {
  width: 38px; height: 38px;
  border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  color: rgba(255,255,255,0.35);
  transition: background var(--dur) var(--ease-out),
              color var(--dur) var(--ease-out);
}
.nav-item:hover .nav-icon-wrap {
  color: rgba(255,255,255,0.70);
}
.nav-item.active .nav-icon-wrap {
  color: var(--indigo-light);
}
.nav-icon {
  width: 20px; height: 20px;
  stroke-width: 1.75;
}

/* Footer */
.sidebar-footer {
  padding: 14px 16px;
}
.sidebar-user { display: flex; align-items: center; gap: 9px; transition: gap 0.2s var(--ease-in-out); }
.sidebar-avatar {
  width: 32px; height: 32px;
  border-radius: var(--r-full);
  background: linear-gradient(135deg, var(--indigo), var(--violet));
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; color: #fff;
  flex-shrink: 0;
  box-shadow: 0 2px 8px rgba(110,86,207,0.40);
  transition: width 0.2s var(--ease-in-out), height 0.2s var(--ease-in-out), font-size 0.2s var(--ease-in-out);
}
/* ── Sidebar: rail stretto permanente su desktop, MAI più a scomparsa
   (2026-09-12, richiesta esplicita del proprietario: l'hover-expand di
   tutta la sidebar —introdotto in questa stessa sessione— creava "un
   intero background"; il proprietario lo ha rivisto e ora vuole solo un
   fumetto per la singola icona sotto il cursore, vedi .nav-label sopra —
   non più questo intero blocco). `#app-layout` porta `.sidebar-collapsed`
   in modo permanente (index.html), JS non la toglie/rimette più (rimosso
   initSidebarHoverExpand in app.js). Sotto i 900px un pattern del tutto
   diverso si applica invece — non più un drawer off-canvas ma una barra
   fissa in basso, vedi sezione "Navigazione" più sotto. */
@media (min-width: 901px) {
  .app-layout.sidebar-collapsed .sidebar { width: 64px; }
  /* Brand/footer non hanno più testo da nascondere (2026-09-12, richiesta
     esplicita del proprietario: "in parte al logo... togli le due scritte"/
     "la scritta in parte all'icona utente" — rimossi da index.html, non
     solo nascosti in CSS): logo e avatar restano semplicemente più piccoli
     da collassata, nessun div-wrapper di testo da centrare o nascondere. */
  .app-layout.sidebar-collapsed .sidebar-brand { justify-content: center; padding: 14px 0; }
  /* Logo e avatar allineati alla stessa dimensione delle icone di
     navigazione (2026-09-12, richiesta esplicita del proprietario: "rendi
     l'icona del logo e l'icona del profilo grandi quanto le altre icone")
     — 38px come .nav-icon-wrap, non più più piccoli (26px/24px). Radius
     del logo portato a 10px (stesso di .nav-icon-wrap); l'avatar resta
     circolare (var(--r-full)) — è una scelta di forma intenzionale per un
     'iniziale utente, non collegata alla dimensione richiesta qui. */
  .app-layout.sidebar-collapsed .brand-icon { width: 38px; height: 38px; font-size: 15px; border-radius: 10px; }
  .app-layout.sidebar-collapsed .sidebar-footer { justify-content: center; padding: 12px 0; }
  .app-layout.sidebar-collapsed .sidebar-user { justify-content: center; }
  .app-layout.sidebar-collapsed .sidebar-avatar { width: 38px; height: 38px; font-size: 14px; }
}
.sidebar { transition: width 0.2s var(--ease-in-out); }
.main-content { transition: margin-left 0.22s var(--ease-in-out); }

/* ══════════════════════════════════════════════════════════════
   MAIN CONTENT
══════════════════════════════════════════════════════════════ */
.main-content {
  /* 64px fisso, non var(--sidebar-w): la sidebar espansa in hover si
     sovrappone al contenuto (già position:fixed) invece di spostarlo — vedi
     nota sopra ".sidebar-collapsed". Su mobile vince comunque margin-left:0
     !important nella media query dedicata più sotto. */
  margin-left: 64px;
  flex: 1;
  min-width: 0;
  height: 100vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

.tab-panel        { display: none; }
.tab-panel.active {
  display: block; padding: 22px 28px 52px;
  animation: panel-fade-in 160ms var(--ease-out) both;
}
/* Respiro (DC-62): senza un max-width il contenuto si stira a piena
   larghezza su schermi ampi — Tasse "respira" già di suo con
   .tasse2-inner (760px). Stesso principio qui, un tetto per pagina
   coerente con la propria griglia: Dashboard più largo (griglia a
   5 colonne), Agente Acquisto medio (griglia di config a 2 colonne),
   Impostazioni stretto come Tasse (lista verticale di card). */
#tab-dashboard, #tab-buy, #tab-settings { margin-left: auto; margin-right: auto; }
/* Corretto 2026-07-20 (DC-63): il giro precedente aveva preso la
   "colonna di lettura" di Tasse (760px) come riferimento e l'aveva
   scalata troppo poco per Dashboard/Agente Acquisto — su un laptop
   reale (1440-1920px di viewport) il risultato era spazio vuoto ai
   lati e griglie compresse, l'opposto del "respiro" cercato. Questa
   è un'app da laptop/desktop, non mobile: il tetto serve solo a non
   stirare all'infinito su monitor ultra-wide (2560px+), non a creare
   una colonna stretta. Il "respiro" viene da padding/gap generosi
   dentro ogni card (già aumentati), non da meno larghezza totale. */
/* max-width rimosso dalla Dashboard (2026-09-11, richiesta esplicita del
   proprietario — supera DC-63: "spazio bianco ai lati, non serve"). DC-63
   aveva fissato un tetto apposta per non stirare all'infinito su monitor
   ultra-wide; il proprietario preferisce ora piena larghezza sempre,
   accettando lo stiramento su schermi molto ampi. Agente Acquisto e
   Impostazioni non toccati — richiesta specifica alla sola Dashboard.
   Margini auto ereditati dalla regola condivisa sopra ESCLUSI qui apposta:
   .main-content è un flex container (column) e un margin left/right:auto
   su un asse cross senza vincolo di larghezza impedisce lo stretch dello
   spec flexbox (l'item si dimensiona al contenuto invece di riempire lo
   spazio, anche con max-width:none) — scoperto dal vivo (#tab-dashboard
   restava largo 858px su un main-content di 1220px). */
#tab-dashboard { max-width: none; margin-left: 0; margin-right: 0; }
#tab-buy       { max-width: 1400px; }
/* Impostazioni estesa a piena larghezza (2026-09-11, richiesta esplicita del
   proprietario — supera la nota precedente "invariato: lista verticale di
   card come Tasse": stesso trattamento della Dashboard sopra, stessa causa
   flexbox (margin:auto non basta, serve margin:0 esplicito). Le singole
   card restano a larghezza limitata (688px→1100px inline in index.html,
   non rimosso) invece di diventare edge-to-edge: sono form a colonna
   singola (un input, un bottone), non una griglia — stirarle a piena
   larghezza avrebbe reso assurdamente lunghi i singoli campi, "respiro"
   qui viene da una card più ampia, non da un input di 1800px. */
#tab-settings  { max-width: none; margin-left: 0; margin-right: 0; }
@keyframes panel-fade-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ══════════════════════════════════════════════════════════════
   TOP BAR — rimossa dall'HTML (2026-09-12): ospitava solo l'hamburger
   mobile, ora sostituito dalla barra di navigazione fissa in basso (vedi
   sezione "Navigazione" più sotto). .topbar-search* sotto restano non
   referenziate da nessun elemento (già così prima di questa modifica,
   non toccate qui — fuori scope).
══════════════════════════════════════════════════════════════ */
.topbar-search { position: relative; flex: 1; max-width: 280px; }
.topbar-search input {
  width: 100%; padding: 6px 13px 6px 36px; padding-left: 36px !important;
  border: 1px solid var(--border); border-radius: var(--r-full);
  background: var(--surface); font-size: 12.5px; color: var(--text);
  outline: none; font-family: inherit;
  box-shadow: var(--shadow-xs);
  transition: border-color var(--dur), box-shadow var(--dur);
}
.topbar-search input:focus {
  border-color: var(--indigo);
  box-shadow: 0 0 0 3px rgba(110,86,207,0.10), var(--shadow-xs);
}
.topbar-search input::placeholder { color: var(--subtle); }
.topbar-search-icon {
  position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
  color: var(--subtle); pointer-events: none; width: 13px; height: 13px;
}

/* ── Notification badge (sull'icona in sidebar) ──────────────────────────────
   Spostata dalla topbar alla sidebar (richiesta esplicita del proprietario,
   riferimento Instagram: icona Notifiche nel rail invece che un campanello
   in topbar). Il bordo combacia con lo sfondo reale della sidebar
   (var(--surface), chiara — vedi §128, non più il presunto #0E0F1A scuro). */
.notif-badge {
  /* Centrato col flexbox invece di line-height (2026-09-12, il proprietario
     ha segnalato "il numero non è centrato nel pallino") — line-height
     dipendeva dai metrici del font, flex garantisce il centraggio a
     prescindere. Dimensioni ridotte ("sia il pallino che il numero devono
     essere ridotti"): 16→13px, font 9→7.5px. */
  position: absolute; top: -1px; right: -3px;
  min-width: 13px; height: 13px; border-radius: 7px;
  background: var(--indigo); color: #fff;
  font-size: 7.5px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
  padding: 0 2.5px;
  pointer-events: none;
  border: 1.5px solid var(--surface);
  animation: badge-pop 0.2s var(--ease-out) both;
}
@keyframes badge-pop {
  from { transform: scale(0.5); opacity: 0; }
  to   { transform: scale(1);   opacity: 1; }
}

/* ── Notification panel — ancorato alla sidebar, sfondo bianco ───────────────
   Prima un dropdown in alto a destra dalla topbar; poi (§126) un pannello
   scuro accanto al rail, riferimento Instagram. Sfondo tornato bianco
   (2026-09-12, richiesta esplicita del proprietario: "il sidemenu... deve
   avere sfondo bianco") — resta affiancato al rail (left:64px, piena
   altezza) e scivola da sinistra, cambia solo la palette (chiara invece di
   scura), stessi token già in uso ovunque altro nell'app. ── */
.notif-backdrop {
  display: none;
  position: fixed; inset: 0; z-index: 199;
}
.notif-backdrop.open { display: block; }

.notif-panel {
  position: fixed; top: 0; bottom: 0; left: 64px; z-index: 200;
  width: 360px;
  background: var(--surface);
  border-right: 1px solid var(--border-hairline);
  box-shadow: var(--elev-3);
  display: flex; flex-direction: column;
  transform: translateX(-16px);
  opacity: 0; pointer-events: none;
  transition: transform 0.2s var(--ease-in-out), opacity 0.16s ease;
}
.notif-panel.open {
  transform: translateX(0);
  opacity: 1; pointer-events: all;
}
.notif-panel-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 18px 14px;
  border-bottom: 1px solid var(--border-hairline);
  flex-shrink: 0;
}
.notif-panel-title {
  font-size: 15px; font-weight: 800; color: var(--text);
  letter-spacing: -0.03em;
}
.notif-header-right { display: flex; align-items: center; gap: 12px; }
.notif-mark-all {
  font-size: 11px; color: var(--indigo); font-weight: 600;
  background: none; border: none; cursor: pointer; padding: 0;
  font-family: inherit;
}
.notif-mark-all:hover { text-decoration: underline; }
/* Tasto chiudi (2026-09-12, richiesta esplicita: il pannello notifiche
   deve avere anche un tasto per chiuderlo in alto a destra) — stessa
   ricetta di .nd-close (style.css, drawer dettaglio Nexus), riusata
   invece di scriverne una nuova. */
.notif-close {
  width: 24px; height: 24px; border-radius: 6px; flex-shrink: 0;
  border: 1px solid var(--border); background: var(--surface);
  font-size: 15px; line-height: 1; color: var(--subtle); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: all var(--dur-fast);
}
.notif-close:hover { background: var(--surface-2); color: var(--text); }

.notif-list {
  overflow-y: auto; flex: 1;
  padding: 6px 0;
}
.notif-empty {
  padding: 28px 16px; text-align: center;
  font-size: 12px; color: var(--subtle);
}

/* Individual notification item — rifinito 2026-09-12 (richiesta esplicita
   del proprietario: "modo più pulito", la lista così com'era "davvero
   fastidiosa visivamente"). Causa reale: non il colore/tema (già chiaro,
   §130) ma la densità — 4 righe impilate per voce (agente / titolo /
   descrizione su 2 righe / orario), quasi identiche su decine di
   notifiche dello stesso agente, leggevano come un muro di testo
   ripetuto. Fix: agente+orario condivisi su una riga di metadato unica
   (vedi .notif-meta-row), descrizione troncata a una riga sola invece di
   due (il dettaglio completo resta un click), e un divisore sottile fra
   voci per leggerle come righe distinte invece che blocchi indifferenziati. */
.notif-item {
  display: flex; gap: 11px; align-items: flex-start;
  padding: 10px 18px;
  cursor: default;
  transition: background 60ms ease;
  border-left: 3px solid transparent;
}
.notif-item + .notif-item { border-top: 1px solid var(--border-hairline); }
.notif-item:hover { background: var(--surface-2); }
.notif-item.unread { border-left-color: var(--indigo); background: rgba(110,86,207,0.04); }
.notif-item.unread:hover { background: rgba(110,86,207,0.07); }

.notif-dot {
  width: 8px; height: 8px; border-radius: 50%;
  flex-shrink: 0; margin-top: 4px;
}
.notif-dot.buy_agent        { background: #6E56CF; }
.notif-dot.auto_purchased   { background: #10B981; }
.notif-dot.vinted_bot       { background: #3B82F6; }
.notif-dot.listing_agent    { background: #F59E0B; }
.notif-dot.sold_monitor     { background: #10B981; }
.notif-dot.system           { background: #6B7280; }
.notif-dot.error            { background: #EF4444; }

.notif-body { flex: 1; min-width: 0; }
.notif-meta-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; margin-bottom: 2px;
}
.notif-agent {
  font-size: 9.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .08em; color: var(--subtle);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.notif-time {
  font-size: 10px; color: var(--subtle); flex-shrink: 0;
}
.notif-title {
  font-size: 12.5px; font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.notif-desc {
  font-size: 11.5px; color: var(--text-2); margin-top: 1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ══════════════════════════════════════════════════════════════
   PAGE HEADER
══════════════════════════════════════════════════════════════ */
.page-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 20px; gap: 16px;
}
.page-title {
  font-size: 20px; font-weight: 800;
  color: var(--text); letter-spacing: var(--tracking-title); line-height: 1.1;
}
.page-sub {
  font-size: 12px; color: var(--muted); margin-top: 2px; font-weight: 400;
}
.header-actions { display: flex; gap: 8px; flex-shrink: 0; align-items: center; }

/* ══════════════════════════════════════════════════════════════
   DASHBOARD HEADER
══════════════════════════════════════════════════════════════ */
.dash-header {
  display: flex; align-items: flex-start; justify-content: space-between;
  margin-bottom: 24px; gap: 16px;
}
.dash-filters {
  display: flex; gap: 2px; align-items: center;
  background: var(--surface); padding: 3px; border-radius: var(--r-md);
  border: 1px solid var(--border); box-shadow: var(--shadow-sm);
}
.dash-filters select {
  padding: 5px 9px; border: none; border-radius: var(--r-sm);
  background: transparent; font-size: 12px; font-weight: 500;
  color: var(--text-2); cursor: pointer; outline: none;
  font-family: inherit; -webkit-appearance: none; appearance: none;
}
.dash-filters select:focus { background: var(--surface-2); }
.dash-filters select:disabled { opacity: .45; cursor: not-allowed; }

/* Filtro per intervallo di date — stesso componente .date-filter-panel già
   usato in Inventario (vedi quel blocco più sotto), qui riancorato via JS
   allo stesso modo (getBoundingClientRect del bottone) ma con logica di
   posizionamento più semplice: .dash-filters-wrap non vive dentro uno
   stacking context conteso come .inv-legacy, quindi non serve replicare
   tutti i casi limite (cmd-bar, bounds del foglio) di openDateFilterPanel(). */
.dash-filters-wrap { position: relative; }
.dash-filters-divider { width: 1px; height: 16px; background: var(--border); margin: 0 2px; }
.dash-date-btn {
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0; border: none; border-radius: var(--r-sm);
  background: transparent; color: var(--text-2); cursor: pointer;
  transition: all var(--dur-fast) var(--ease-out);
}
.dash-date-btn:hover { background: var(--surface-2); color: var(--text); }
.dash-date-btn.active { background: var(--indigo-soft, rgba(110,86,207,0.10)); color: var(--indigo); }

/* ══════════════════════════════════════════════════════════════
   KPI CARDS
══════════════════════════════════════════════════════════════ */
.kpi-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
  margin-bottom: 18px;
}
@media (max-width: 1280px) { .kpi-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 720px)  { .kpi-grid { grid-template-columns: 1fr; } }

.kpi-card {
  background: var(--surface);
  border: 1px solid rgba(0,0,0,0.055);
  border-radius: var(--r-xl);
  padding: 22px 22px 20px;
  box-shadow: var(--shadow-card);
  position: relative; overflow: hidden;
  transition: box-shadow var(--dur-slow) var(--ease-out),
              transform   var(--dur-slow) var(--ease-out);
}
.kpi-card:hover {
  box-shadow: var(--shadow-card-hover);
  transform: translateY(-2px);
}

/* Entrance stagger */
@keyframes kpi-in {
  from { opacity: 0; transform: translateY(14px) scale(0.99); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.kpi-card { animation: kpi-in 400ms var(--ease-out) both; }
.kpi-card:nth-child(1) { animation-delay:  0ms; }
.kpi-card:nth-child(2) { animation-delay: 45ms; }
.kpi-card:nth-child(3) { animation-delay: 90ms; }
.kpi-card:nth-child(4) { animation-delay:135ms; }
.kpi-card:nth-child(5) { animation-delay:180ms; }
.kpi-card:nth-child(6) { animation-delay:225ms; }
.kpi-card:nth-child(7) { animation-delay:270ms; }

/* Subtle colored top accent stripe — 1.5px, much more refined than 2.5px */
.kpi-card::before {
  content: "";
  position: absolute; top: 0; left: 0; right: 0; height: 1.5px;
  border-radius: var(--r-xl) var(--r-xl) 0 0;
}
.kpi-profit::before  { background: linear-gradient(90deg, #10B981, #34D399); }
.kpi-sales::before   { background: linear-gradient(90deg, #3B82F6, #60A5FA); }
.kpi-margin::before  { background: linear-gradient(90deg, #6E56CF, #8875E0); }
.kpi-stock::before   { background: linear-gradient(90deg, #F59E0B, #FCD34D); }
.kpi-shelf::before   { background: linear-gradient(90deg, #06B6D4, #22D3EE); }
.kpi-stalled::before   { background: linear-gradient(90deg, #EF4444, #F87171); }
.kpi-forecast::before  { background: linear-gradient(90deg, #8B5CF6, #A78BFA); }

.kpi-header {
  display: flex; align-items: flex-start; justify-content: space-between;
  margin-bottom: 14px;
}
.kpi-icon {
  width: 36px; height: 36px;
  border-radius: 10px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid rgba(0,0,0,0.06);
}
.kpi-icon svg { width: 17px; height: 17px; stroke-width: 2; }
.kpi-profit .kpi-icon { background: rgba(16,185,129,0.10); color: #059669; }
.kpi-margin .kpi-icon { background: rgba(110,86,207,0.10); color: var(--indigo); }
.kpi-stock  .kpi-icon { background: rgba(245,158,11,0.10); color: var(--amber-d); }
.kpi-shelf    .kpi-icon { background: rgba(6,182,212,0.10);  color: var(--teal-d); }
.kpi-forecast .kpi-icon { background: rgba(139,92,246,0.10); color: #7C3AED; }

.kpi-sparkline {
  width: 72px; height: 32px; flex-shrink: 0;
  opacity: .60; filter: drop-shadow(0 1px 2px rgba(0,0,0,0.06));
}

.kpi-label {
  font-size: 10px; font-weight: 700; color: var(--subtle);
  text-transform: uppercase; letter-spacing: .10em; margin-bottom: 6px;
}
.kpi-value {
  font-size: 38px; font-weight: 800; line-height: 1;
  margin-bottom: 10px; letter-spacing: -0.055em;
  font-variant-numeric: tabular-nums;
}
.kpi-profit .kpi-value { color: var(--text); }
.kpi-margin .kpi-value { color: var(--text); }
.kpi-stock  .kpi-value { color: var(--text); }
.kpi-shelf  .kpi-value { color: var(--text); }

.kpi-sub {
  font-size: 11.5px; color: var(--muted); font-weight: 500;
  display: flex; align-items: center; gap: 8px;
}
.kpi-sub span { font-weight: 600; color: var(--text-2); }

.kpi-trend {
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 10.5px; font-weight: 700;
  padding: 2px 7px; border-radius: var(--r-full); letter-spacing: -0.01em;
}
.kpi-trend.up   { background: var(--green-soft); color: var(--green-text); }
.kpi-trend.down { background: var(--red-soft);   color: var(--red-text); }
.kpi-trend.flat { background: rgba(0,0,0,0.04);  color: var(--muted); }

/* ══════════════════════════════════════════════════════════════
   MINI COUNTS
══════════════════════════════════════════════════════════════ */
.mini-counts {
  display: flex; gap: 7px; margin-bottom: 20px; flex-wrap: wrap;
}
.mini-count {
  display: flex; align-items: center; gap: 7px;
  font-size: 12px; font-weight: 500; color: var(--muted);
  background: var(--surface);
  border: 1px solid rgba(0,0,0,0.055);
  border-radius: var(--r-full);
  padding: 5px 13px 5px 10px;
  box-shadow: var(--shadow-xs);
  transition: box-shadow var(--dur), transform var(--dur-fast);
}
.mini-count:hover { box-shadow: var(--shadow-sm); transform: translateY(-1px); }
.mini-count span[id] { font-weight: 700; color: var(--text-2); }
.mini-dot {
  width: 6px; height: 6px;
  border-radius: var(--r-full); flex-shrink: 0;
}
.mini-dot.transit { background: #EAB308; box-shadow: 0 0 6px rgba(234,179,8,.5); }
.mini-dot.stock   { background: var(--indigo); box-shadow: 0 0 6px rgba(110,86,207,.45); }
.mini-dot.listed  { background: var(--amber);  box-shadow: 0 0 6px rgba(245,158,11,.45); }
.mini-dot.sold    { background: var(--green);  box-shadow: 0 0 6px rgba(16,185,129,.45); }

/* ══════════════════════════════════════════════════════════════
   CHARTS
══════════════════════════════════════════════════════════════ */
.chart-card {
  background: var(--surface);
  border: 1px solid rgba(0,0,0,0.055);
  border-radius: var(--r-xl);
  padding: 24px 24px 18px;
  box-shadow: var(--shadow-card);
}
.chart-title {
  font-size: 11px; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: .10em; margin-bottom: 20px;
}

/* ── Storico mensile — tabella (DESIGN_DECISIONS.md §109, screenshot di
   riferimento fornito dal proprietario: "il più simile possibile a questa,
   le uniche differenze devono essere di leggero design"). Stessa struttura
   dello screenshot — barra totali scura, intestazione colonne, righe
   mensili più recente in cima — ricolorata con i token della dashboard
   (var(--dk-surface), già usato per la striscia riepilogo scura in cima
   alla pagina, invece del navy dello screenshot; var(--indigo), il colore
   protagonista già usato altrove, invece del tan/marrone) anziché ricopiare
   la palette originale, che avrebbe introdotto due colori nuovi ed estranei
   al resto della dashboard. */
.storico-table-card { padding: 0 !important; overflow: hidden; }
.storico-table-wrap { overflow-x: auto; }
.storico-table { width: 100%; border-collapse: collapse; }
.storico-table th, .storico-table td {
  padding: 11px 16px; text-align: center;
  font-size: 13px; white-space: nowrap;
}
.storico-table th:not(:first-child), .storico-table td:not(:first-child) {
  border-left: 1px solid var(--border);
}
.storico-table-header th:not(:first-child) { border-left-color: var(--dk-border); }
.storico-table-totals td {
  background: transparent;
  color: var(--muted);
  font-weight: 500;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  padding-top: 6px; padding-bottom: 6px;
  border-top: 1px solid var(--border-hairline, var(--border));
}
.storico-avg-label {
  color: var(--muted); font-weight: 500; text-transform: uppercase;
  font-size: 9px; letter-spacing: .04em; margin-right: 5px;
}
.storico-table-header th {
  background: var(--dk-surface-2);
  color: var(--dk-text-2);
  font-weight: 700;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .05em;
  padding-top: 6px; padding-bottom: 6px;
}
.storico-table tbody td {
  color: var(--text);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  border-top: 1px solid var(--border-hairline, var(--border));
}
.storico-table tbody tr:first-child td { border-top: none; }

/* ══════════════════════════════════════════════════════════════
   GENERIC CARD
══════════════════════════════════════════════════════════════ */
.card {
  background: var(--surface);
  border: 1px solid var(--border-hairline);
  border-radius: var(--r-xl);
  padding: 24px;
  box-shadow: var(--elev-1);
}
.card + .card { margin-top: 18px; }
.section-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 18px;
}
.section-header h2 {
  font-size: 14px; font-weight: 700;
  color: var(--text); letter-spacing: -0.025em;
}

/* ── Righe elenco add/remove (Filtri Feed, Categorie prodotto — Impostazioni):
   mai avuto CSS dedicato, ricadevano sul flow a blocco di default (nome ed
   "Rimuovi" impilati verticalmente invece che affiancati, righe successive
   senza alcuna separazione). Un solo componente per entrambe le liste. */
.feed-filter-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 12px 0;
  border-top: 1px solid var(--border-hairline, var(--border));
}
.feed-filter-row:first-child { border-top: none; padding-top: 0; }
.feed-filter-details { min-width: 0; }
.feed-filter-name { font-size: 13.5px; font-weight: 600; color: var(--text); }
.feed-filter-url { font-size: 12px; color: var(--muted); margin-top: 2px; overflow-wrap: anywhere; }
.feed-filter-url a { color: var(--indigo); text-decoration: none; }
.feed-filter-url a:hover { text-decoration: underline; }
.feed-filter-row .btn { flex-shrink: 0; }

/* ══════════════════════════════════════════════════════════════
   INVENTORY TOOLBAR
══════════════════════════════════════════════════════════════ */
.inv-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 12px; flex-wrap: wrap;
}

.status-tabs {
  display: flex; gap: 2px;
  background: var(--surface);
  border: 1px solid rgba(0,0,0,0.06);
  border-radius: 10px; padding: 3px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.05), 0 0 0 1px rgba(0,0,0,0.03);
}
.status-tab {
  padding: 5px 12px; border: none; background: none;
  border-radius: 7px; cursor: pointer;
  font-size: 12px; font-weight: 500; color: var(--muted);
  transition: all var(--dur) var(--ease-out);
  white-space: nowrap; font-family: inherit; letter-spacing: -0.01em;
}
.status-tab:hover { color: var(--text-2); background: rgba(0,0,0,0.04); }
/* Linear-style: dark active tab, violet reserved for primary CTA only */
.status-tab.active {
  background: var(--text);
  color: #fff; font-weight: 600;
  box-shadow: 0 1px 3px rgba(0,0,0,0.20), 0 0 0 1px rgba(0,0,0,0.12);
}
.tab-count {
  display: inline-flex; align-items: center; justify-content: center;
  margin-left: 5px; font-size: 9.5px; font-weight: 700;
  border-radius: 5px; padding: 0 5px; line-height: 16px; min-width: 18px;
}
.status-tab.active .tab-count {
  background: rgba(255,255,255,0.14);
  color: rgba(255,255,255,0.80);
}
.status-tab:not(.active) .tab-count {
  background: rgba(0,0,0,0.06); color: var(--muted); font-weight: 600;
}

.inv-search { position: relative; }
.inv-search input {
  padding: 7px 13px 7px 36px; padding-left: 36px !important; border: 1px solid var(--border);
  border-radius: var(--r-full); background: var(--surface);
  font-size: 12.5px; width: 260px; outline: none;
  transition: border-color var(--dur), box-shadow var(--dur);
  font-family: inherit; color: var(--text); box-shadow: var(--shadow-xs);
}
.inv-search input:focus {
  border-color: var(--indigo);
  box-shadow: 0 0 0 3px rgba(110,86,207,0.10), var(--shadow-xs);
}
.inv-search input::placeholder { color: var(--subtle); }
.inv-search-icon {
  position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
  width: 13px; height: 13px; color: var(--subtle); pointer-events: none;
}

.cat-filter { display: flex; gap: 5px; flex-wrap: wrap; margin-bottom: 14px; }
.chip {
  padding: 4px 12px; border-radius: 7px;
  border: 1px solid rgba(0,0,0,0.07); background: var(--surface);
  font-size: 12px; font-weight: 500; cursor: pointer; color: var(--muted);
  transition: all var(--dur-fast) var(--ease-out); font-family: inherit;
  box-shadow: 0 1px 2px rgba(0,0,0,0.04);
}
.chip:hover { border-color: rgba(110,86,207,0.25); color: var(--text-2); background: var(--indigo-soft); }
.chip.active { background: var(--indigo-soft); border-color: rgba(110,86,207,0.28); color: var(--indigo); font-weight: 600; }

/* ══════════════════════════════════════════════════════════════
   INVENTORY TABLE
══════════════════════════════════════════════════════════════ */
.inv-table-container {
  overflow-x: auto;
  border-radius: var(--r-xl);
  border: 1px solid rgba(0,0,0,0.06);
  box-shadow: 0 0 0 1px rgba(0,0,0,0.04),
              0 2px 4px rgba(0,0,0,0.04),
              0 8px 24px rgba(0,0,0,0.06),
              0 24px 48px rgba(0,0,0,0.04);
  background: var(--surface);
  max-height: calc(100vh - 240px);
  overflow-y: auto;
  scroll-padding-bottom: 72px;
}
.inv-table {
  width: max-content; min-width: 100%;
  border-collapse: separate; border-spacing: 0;
  font-size: 12.5px; background: transparent;
}

.inv-table thead tr { position: sticky; top: 0; z-index: 10; }
.inv-table th {
  background: var(--table-head);
  color: var(--subtle); font-size: 9.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .09em;
  padding: 9px 14px; text-align: left;
  border-bottom: 1.5px solid rgba(0,0,0,0.08); white-space: nowrap; user-select: none;
}
.inv-table th.num { text-align: right; }

.inv-table td {
  padding: 10px 14px; border-bottom: 1px solid rgba(0,0,0,0.04);
  vertical-align: middle; white-space: nowrap;
  color: var(--text-2); transition: background 60ms ease; background: #fff;
}
.inv-table tr:last-child td { border-bottom: none; }
.inv-table tbody tr:nth-child(even) td { background: #F3F3F3; }

/* Status-tinted hover */
.inv-table tbody tr:hover td                   { background: #E8E8E8 !important; }
.inv-table tbody tr.sold:hover td              { background: #E2F5EC !important; }
.inv-table tbody tr.in_stock:hover td          { background: #EDEAFF !important; }
.inv-table tbody tr.in_transit:hover td        { background: #FDF8E1 !important; }
.inv-table tbody tr.listed:hover td            { background: #FDF5E1 !important; }

/* DC-2: no accent bars — status communicated by badge only */

/* Row number frozen column — la checkbox "seleziona tutto" (DC-48) vive
   nell'header di questa stessa colonna: non è più una colonna a sé (vedi
   DESIGN_DECISIONS.md, rimozione colonna checkbox ridondante). */
.inv-th-num input {
  cursor: pointer; width: 14px; height: 14px; margin: 0; vertical-align: middle;
}
.inv-th-num, .inv-row-num {
  position: sticky; left: 0; z-index: 5; width: 40px; min-width: 40px;
  text-align: center; background: var(--table-head);
}
.inv-row-num {
  background: #fff; font-size: 10.5px; color: var(--subtle);
  cursor: pointer; user-select: none; padding: 0 4px;
  border-right: 1px solid rgba(0,0,0,0.05);
}
.inv-row-num:hover { background: var(--indigo-soft); color: var(--indigo); }
.inv-table tbody tr:nth-child(even) td.inv-row-num { background: #F3F3F3; }
.inv-table thead th.inv-th-num { z-index: 12; background: var(--table-head); border-bottom: 1.5px solid rgba(0,0,0,0.08); }

/* Row selection */
.inv-table tbody tr.inv-row-selected td               { background: #E8EEFF !important; }
.inv-table tbody tr.inv-row-selected td.inv-row-num   { background: #C7D0FF !important; color: var(--indigo); font-weight: 700; }

.col-sticky { position: sticky; z-index: 5; }
/* col-sticky-1/2 left shifted right by the row-number column (40px).
   width/min-width/max-width tutti a 140px su col-sticky-1 (2026-09-12,
   fix regressione — vedi sotto): con `table-layout` auto (default,
   .inv-table non lo sovrascrive) un `min-width` da solo è solo un
   pavimento, non un tetto — il browser può comunque distribuire spazio
   extra alla colonna e renderla più larga (misurato dal vivo: 139.3px
   reali contro i 130px dichiarati). col-sticky-2 assumeva 130px esatti
   per il proprio `left` (40+130=170) — con la colonna reale più larga
   restava un varco di ~22px fra le due colonne sticky, dentro il quale
   si vedeva il contenuto sottostante scorrere (bug segnalato dal
   proprietario, "il problema dei testi dietro che si vedono quando
   scorro"). `max-width:140px` blocca la colonna alla larghezza
   dichiarata (contenuto reale 138px, ci sta comodamente, nessun clip). */
.col-sticky-1 { left: 40px; width: 140px; min-width: 140px; max-width: 140px; }
.col-sticky-2 {
  left: 180px; min-width: 340px;
  box-shadow: 4px 0 18px -3px rgba(0,0,0,0.10);
}
.col-notes { max-width: 220px; overflow: hidden; text-overflow: ellipsis; }
.inv-table thead .col-sticky { z-index: 12; }
.inv-table thead th.col-sticky-1,
.inv-table thead th.col-sticky-2 { background: var(--table-head); }

/* Sticky body cells MUST have solid backgrounds */
.inv-table tbody td.col-sticky,
.inv-table tbody td.inv-row-num                         { background: #ffffff; }
.inv-table tbody tr:nth-child(even) td.col-sticky,
.inv-table tbody tr:nth-child(even) td.inv-row-num      { background: #F3F3F3; }

/* Generic hover — neutral */
.inv-table tbody tr:hover td.col-sticky                 { background: #E8E8E8 !important; }
.inv-table tbody tr:hover td.inv-row-num                { background: var(--indigo-soft) !important; color: var(--indigo); }
/* Status-tinted overrides */
.inv-table tbody td.inv-status-cell,
.inv-table tbody td.inv-category-cell                   { cursor: pointer; }
body.inv-dragging, body.inv-dragging *                  { user-select: none !important; cursor: cell !important; }
.inv-table tbody tr.sold:hover td.col-sticky             { background: #E2F5EC !important; }
.inv-table tbody tr.in_stock:hover td.col-sticky         { background: #EDEAFF !important; }
.inv-table tbody tr.in_transit:hover td.col-sticky       { background: #FDF8E1 !important; }
.inv-table tbody tr.listed:hover td.col-sticky           { background: #FDF5E1 !important; }

/* Column hierarchy: primary → secondary → tertiary */
.inv-table td.col-name {
  font-weight: 600; color: var(--text); font-size: 13px;
  max-width: 420px; overflow: hidden; text-overflow: ellipsis;
}
.inv-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
/* Financial columns get strong weight — they are the reason this product exists */
.inv-table td.td-bold { font-weight: 700; color: var(--text); font-size: 13px; }
/* Tertiary — dates and metadata recede visually */
.inv-table td.td-date  { color: var(--subtle); font-size: 11.5px; font-weight: 400; }
.inv-table td.td-muted { color: var(--subtle); font-size: 12px; }
.cell-empty { color: var(--faint); }

.inv-table .actions-cell {
  display: flex; gap: 4px; justify-content: flex-end;
  opacity: 0; transition: opacity var(--dur-fast); min-width: 110px;
}
.inv-table tr:hover .actions-cell { opacity: 1; }


/* Spreadsheet-style inline editing — cells feel like direct text fields */
.cell-editable { cursor: default; }
.cell-editable:hover {
  outline: 1.5px solid rgba(0,0,0,0.18);
  outline-offset: -1px;
}
.cell-editable.editing {
  padding: 0 !important;
  outline: 2px solid var(--indigo) !important;
  outline-offset: -2px;
  background: #fff !important;
}
/* Empty editable cells: text cursor + subtle hover hint inviting input */
td.cell-editable[data-value=""] { cursor: text; }
td.cell-editable[data-value=""]:not(.editing):hover {
  background: #F8F8FC !important;
  outline: 1.5px solid rgba(0,0,0,0.10);
  outline-offset: -1px;
}
/* Status column is read-only — no hover cue */
.inv-table td.col-sticky-1 { cursor: default; }
.inv-table td.col-sticky-1:hover { outline: none !important; }

/* Bulk selection highlight */
.inv-table td.cell-selected {
  background: rgba(110,86,207,0.09) !important;
  outline: 1px solid rgba(110,86,207,0.22) !important;
  outline-offset: -1px;
}
.inv-table td.cell-selected.col-sticky-1,
.inv-table td.cell-selected.col-sticky-2 {
  background: #F2F0FB !important;
}
/* Active cell — like Google Sheets: thick indigo border */
.inv-table td.cell-active {
  outline: 2px solid var(--indigo) !important;
  outline-offset: -2px;
}

/* Bulk status bar — fixed at bottom like Google Sheets */
.bulk-bar {
  display: none;
  position: fixed; bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 90;
  align-items: center; justify-content: space-between;
  gap: 14px; padding: 7px 7px 7px 16px;
  background: #1C1D30;
  border: 1px solid rgba(255,255,255,0.07);
  border-radius: 999px;
  color: rgba(255,255,255,0.9);
  font-size: 12px;
  font-weight: 500;
  box-shadow: 0 8px 32px rgba(0,0,0,0.30), 0 2px 8px rgba(0,0,0,0.18);
  animation: panel-fade-in 120ms var(--ease-out) both;
  white-space: nowrap;
}
.bulk-bar.visible { display: flex; }
.bulk-bar-info { display: flex; align-items: center; gap: 10px; }
.bulk-count-badge {
  font-size: 11px; font-weight: 700; letter-spacing: 0.02em;
  background: rgba(255,255,255,0.10);
  border-radius: 999px; padding: 2px 9px;
  color: #fff;
}
.bulk-sep { opacity: 0.25; }
.bulk-calc { color: rgba(255,255,255,0.65); font-size: 11.5px; letter-spacing: 0.01em; }
.bulk-bar-actions { display: flex; align-items: center; gap: 4px; }
.bulk-btn {
  font-size: 11.5px; font-weight: 600; font-family: inherit;
  padding: 5px 12px; border-radius: 999px; cursor: pointer; border: none;
  background: rgba(255,255,255,0.10); color: #fff;
  transition: background var(--dur-fast);
}
.bulk-btn:hover { background: rgba(255,255,255,0.20); }
.bulk-btn-primary {
  background: var(--indigo); color: #fff;
  box-shadow: 0 1px 4px rgba(110,86,207,0.35);
}
.bulk-btn-primary:hover { background: #7C68D8; }
.bulk-btn-clear { background: transparent; color: rgba(255,255,255,0.45); padding: 5px 10px; }
.bulk-btn-clear:hover { background: rgba(255,255,255,0.08); color: #fff; }

.bulk-btn-apply {
  background: var(--indigo); color: #fff;
  border-radius: var(--r-sm) !important;
}
.bulk-btn-apply:hover { background: #7C68D8; }
.bulk-btn-clear-dark {
  background: transparent; color: var(--text-2); border: 1px solid var(--border);
  border-radius: var(--r-sm) !important; padding: 5px 12px !important;
}
.bulk-btn-clear-dark:hover { background: var(--bg); color: var(--text); }

/* Search highlight — like Google Sheets yellow */
mark.search-hl {
  background: #FDFF70;
  color: inherit;
  border-radius: 2px;
  padding: 0 1px;
  font-style: inherit;
  font-weight: inherit;
}

/* Input inherits the cell's own typography — looks like you're typing IN the cell */
.cell-input {
  width: 100%; height: 100%; min-height: 41px;
  padding: 10px 14px; border: none; outline: none;
  background: transparent;
  font: inherit; color: inherit;
  box-sizing: border-box; display: block;
}
.cell-input[type="number"] { text-align: right; }
.cell-input[type="date"]   { font-size: 11.5px; color: var(--subtle); }

/* ══════════════════════════════════════════════════════════════
   BADGES
══════════════════════════════════════════════════════════════ */
.badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 1.5px 7px; border-radius: 5px;
  font-size: 10px; font-weight: 600; white-space: nowrap;
  letter-spacing: 0.01em;
}
.badge::before { content: ""; width: 4.5px; height: 4.5px; border-radius: var(--r-full); flex-shrink: 0; }
.badge-in_transit { background: rgba(234,179,8,0.09); border: 1px solid rgba(234,179,8,0.20); color: var(--yellow-text); }
.badge-in_transit::before { background: #EAB308; box-shadow: 0 0 5px rgba(234,179,8,.55); }
.badge-in_stock { background: rgba(110,86,207,0.08); border: 1px solid rgba(110,86,207,0.18); color: var(--indigo-d); }
.badge-in_stock::before { background: var(--indigo); box-shadow: 0 0 5px rgba(110,86,207,.45); }
.badge-listed { background: rgba(245,158,11,0.08); border: 1px solid rgba(245,158,11,0.18); color: var(--amber-text); }
.badge-listed::before { background: var(--amber); box-shadow: 0 0 5px rgba(245,158,11,.45); }
.badge-sold { background: rgba(16,185,129,0.08); border: 1px solid rgba(16,185,129,0.18); color: var(--green-text); }
.badge-sold::before { background: var(--green); box-shadow: 0 0 5px rgba(16,185,129,.45); }
.badge-scomposto { background: rgba(107,114,128,0.08); border: 1px solid rgba(107,114,128,0.18); color: #6B7280; }
.badge-scomposto::before { background: #9CA3AF; }
.badge-clickable { cursor: pointer; }
.badge-clickable:hover { background: rgba(107,114,128,0.14); }

/* Badge lotto (DC-50) — sostituisce le righe raggruppate collassabili (ex DC-49).
   Pill compatto per riga con lot_id, stesso pattern visivo dei badge di stato/
   categoria sopra (dot + sfondo tenue + bordo + testo colorato). Colore assegnato
   ciclicamente (lot_id % 6) su una palette di 6 tinte scelte per restare mutuamente
   distinguibili E distinte dai colori semantici dell'app (verde=venduto, indigo/
   viola=brand/margine, teal=shelf life, ambra=in arrivo/warning, rosso=critico) —
   vedi DESIGN_DECISIONS.md §50. */
.lot-badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 1px 6px; border-radius: 999px;
  font-size: 9px; font-weight: 700; line-height: 1.5;
  vertical-align: middle; margin-right: 6px;
  border: none; cursor: pointer; font-family: inherit;
}
.lot-badge::before { content: ""; width: 4.5px; height: 4.5px; border-radius: 50%; flex-shrink: 0; }
.lot-badge:hover { filter: brightness(0.94); }

.lot-badge-0 { background: rgba(37,99,235,0.10);  border: 1px solid rgba(37,99,235,0.28);  color: #1D4ED8; }
.lot-badge-0::before { background: #3B82F6; }
.lot-badge-1 { background: rgba(101,163,13,0.12); border: 1px solid rgba(101,163,13,0.30); color: #3F6212; }
.lot-badge-1::before { background: #84CC16; }
.lot-badge-2 { background: rgba(192,38,211,0.10); border: 1px solid rgba(192,38,211,0.28); color: #86198F; }
.lot-badge-2::before { background: #D946EF; }
.lot-badge-3 { background: rgba(219,39,119,0.10); border: 1px solid rgba(219,39,119,0.28); color: #9D174D; }
.lot-badge-3::before { background: #EC4899; }
.lot-badge-4 { background: rgba(113,113,122,0.06); border: 1px solid rgba(113,113,122,0.22); color: #52525B; }
.lot-badge-4::before { background: #A1A1AA; }
.lot-badge-5 { background: rgba(28,25,23,0.16);    border: 1px solid rgba(28,25,23,0.42);    color: #1C1917; }
.lot-badge-5::before { background: #44403C; }

.lot-filter-badge {
  display: flex; align-items: center; gap: 6px;
  padding: 5px 10px; border-radius: var(--r-sm);
  background: var(--indigo); color: #fff; border: none;
  font-size: 12px; font-weight: 600; cursor: pointer;
  margin-left: 8px;
}
.lot-filter-badge:hover { filter: brightness(1.08); }

/* ══════════════════════════════════════════════════════════════
   FILTRO DATA (inventario) — pannello a livello body, posizionato via
   JS (getBoundingClientRect() del bottone "Data"), stesso pattern di
   status-picker/refund-popover. Vedi commento in index.html sul
   perché non può essere absolute dentro .page-header.
   Trattamento di elevazione allineato a .status-picker (dropdown
   leggero ancorato a un trigger), non a .refund-popover/--shadow-modal
   (pensata per una card centrata in basso, ombra profonda intenzionale
   lì — qui deve leggersi come un'estensione della toolbar, non un
   pannello isolato che galleggia sopra il resto). Radius ridotto a
   --r-md (12px, coerente con children-popover) invece di --r-lg (20px,
   troppo "card" per un dropdown di 2 campi.
══════════════════════════════════════════════════════════════ */
.date-filter-panel {
  display: none;
  position: fixed;
  /* 264px→320px (2026-09-12, bug segnalato dal proprietario con screenshot:
     il campo "Al" usciva dalla card). Causa: i due input[type=date] sono
     dentro .date-filter-field, flex:1 con min-width:auto di default — un
     input nativo ha una larghezza intrinseca (~145px, misurata dal vivo)
     che un figlio flex non può scendere sotto per costruzione, quindi a
     264px totali (116px disponibili per campo) l'input si rifiutava di
     restringersi e sporgeva fuori dal bordo destro della card invece di
     comprimersi. Stesso "flexbox blowout" già documentato altrove in
     questo file (topbar/tab-panel) — qui risolto sia allargando il
     pannello a sufficienza per il contenuto reale (145px×2+gap+padding),
     sia con min-width:0 su .date-filter-field sotto come rete di
     sicurezza strutturale, non solo un numero più grande a caso. */
  width: 320px; background: var(--surface); border: 1px solid rgba(0,0,0,0.10);
  border-radius: var(--r-md); box-shadow: 0 8px 24px rgba(0,0,0,0.12);
  padding: 12px; z-index: 92;
  animation: panel-fade-in 120ms var(--ease-out) both;
}
.date-filter-panel.visible { display: block; }

/* Popover account, apribile cliccando l'avatar in fondo alla sidebar:
   nome, email, ruolo e logout. Stesso trattamento visivo di .date-filter-panel
   (card chiara, ombra popover), posizionato via JS come i pannelli data. */
.sidebar-user {
  background: none; border: none; padding: 0; cursor: pointer;
  display: flex; align-items: center; gap: 9px; width: 100%;
  transition: gap 0.2s var(--ease-in-out);
}
.account-popover {
  display: none;
  position: fixed;
  width: 240px; background: var(--surface); border: 1px solid rgba(0,0,0,0.10);
  border-radius: var(--r-md); box-shadow: 0 8px 24px rgba(0,0,0,0.12);
  padding: 14px; z-index: 92;
  animation: panel-fade-in 120ms var(--ease-out) both;
}
.account-popover.visible { display: block; }
.account-popover-name { font-size: 13.5px; font-weight: 600; color: var(--text); }
.account-popover-email { font-size: 12px; color: var(--muted); margin-top: 2px; word-break: break-all; }
.account-popover-role { font-size: 11px; color: var(--subtle); margin-top: 6px; text-transform: uppercase; letter-spacing: 0.03em; }
.account-popover-logout {
  width: 100%; margin-top: 12px; padding: 8px 0;
  background: var(--bg); border: 1px solid rgba(0,0,0,0.08); border-radius: var(--r-sm);
  font-size: 13px; font-weight: 600; color: var(--text); cursor: pointer;
}
.account-popover-logout:hover { background: rgba(0,0,0,0.05); }

/* Segmented control leggero — stesso pattern di .buy-sort-toggle/.buy-sort-btn
   (toggle ordinamento Agente Acquisto), tradotto sui token light: track tenue,
   stato attivo = solo un lieve sfondo+ombra, mai un pulsante pieno colorato. */
.date-filter-type-row {
  display: flex; gap: 2px; margin-bottom: 10px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--r-sm); padding: 2px;
}
.date-filter-type-btn {
  flex: 1; padding: 5px 8px; border: none; border-radius: 7px;
  background: none; color: var(--muted); font-size: 11.5px; font-weight: 600;
  cursor: pointer; transition: all var(--dur-fast) var(--ease-out);
  font-family: inherit;
}
.date-filter-type-btn:hover:not(:disabled) { color: var(--text); }
.date-filter-type-btn.active { background: var(--surface); color: var(--text); box-shadow: var(--shadow-xs); }
.date-filter-type-btn:disabled { opacity: .4; cursor: not-allowed; }

.date-filter-range-row { display: flex; gap: 8px; margin-bottom: 8px; }
/* min-width:0 (2026-09-12): senza, un figlio flex non si restringe mai
   sotto la larghezza intrinseca del proprio contenuto (qui l'input date
   nativo, ~145px) — rete di sicurezza strutturale, non solo il pannello
   più largo sopra. Vedi il commento su .date-filter-panel per il bug. */
.date-filter-field { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.date-filter-field label {
  font-size: 10.5px; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: .07em;
}
/* Niente override di bordo/radius/padding qui: gli input date ereditano lo
   stesso stile generico usato in ogni altro form dell'app (input[type="date"]
   in style.css, usato da modale articolo/lotto/tasse) — stessa coerenza
   richiesta esplicitamente, non uno stile su misura solo per questo pannello. */

.date-filter-clear {
  display: block; width: 100%; margin-top: 2px; padding: 5px 8px;
  border: none; background: none; border-radius: var(--r-sm);
  color: var(--muted); font-size: 11.5px; font-weight: 600; text-align: center;
  cursor: pointer; font-family: inherit; transition: all var(--dur-fast) var(--ease-out);
}
.date-filter-clear:hover { color: var(--red-text); background: var(--red-soft); }

.badge-gioco      { background: rgba(16,185,129,0.07); border: 1px solid rgba(16,185,129,0.16); color: var(--green-text); }
.badge-gioco::before { background: #10B981; }
.badge-console    { background: rgba(139,92,246,0.07); border: 1px solid rgba(139,92,246,0.16); color: #5B21B6; }
.badge-console::before { background: #8B5CF6; }
.badge-accessorio { background: rgba(245,158,11,0.07); border: 1px solid rgba(245,158,11,0.16); color: var(--amber-text); }
.badge-accessorio::before { background: var(--amber); }
.badge-altro      { background: rgba(0,0,0,0.04); border: 1px solid rgba(0,0,0,0.07); color: var(--muted); }
.badge-altro::before { background: var(--subtle); }

.badge-buy      { background: var(--green-soft); border: 1px solid rgba(16,185,129,0.18); color: var(--green-text); font-size: 11.5px; padding: 3px 10px; }
.badge-buy::before      { background: var(--green); }
.badge-skip     { background: var(--red-soft); border: 1px solid rgba(239,68,68,0.18); color: var(--red-text); font-size: 11.5px; padding: 3px 10px; }
.badge-skip::before     { background: var(--red); }
.badge-approved { background: var(--green-soft); border: 1px solid rgba(16,185,129,0.18); color: var(--green-text); }
.badge-approved::before { background: var(--green); }
.badge-rejected { background: var(--red-soft); border: 1px solid rgba(239,68,68,0.18); color: var(--red-text); }
.badge-rejected::before { background: var(--red); }
.badge-pending  { background: rgba(0,0,0,0.04); border: 1px solid rgba(0,0,0,0.07); color: var(--muted); }
.badge-pending::before  { background: var(--subtle); }

/* ══════════════════════════════════════════════════════════════
   MARGIN PILL
══════════════════════════════════════════════════════════════ */
.margin-pill {
  padding: 2px 8px; border-radius: var(--r-full);
  font-size: 11px; font-weight: 700; display: inline-block;
  font-variant-numeric: tabular-nums; letter-spacing: -0.01em;
  white-space: nowrap;
}
.margin-pill.pos { background: var(--green-soft); border: 1px solid rgba(16,185,129,0.16); color: var(--green-text); }
.margin-pill.neg { background: var(--red-soft);   border: 1px solid rgba(239,68,68,0.16);  color: var(--red-text); }

/* Cella Profitto (Inventario) — testo semplice, non un badge (DC-66):
   la tabella è densa, una pillola colorata ripetuta su ogni riga era
   troppo pesante. Solo tipografia a fare la gerarchia: importo in
   evidenza, percentuale accessoria più piccola/tenue, nessuno sfondo/
   bordo. Classi dedicate, NON .margin-pill (quella resta invariata
   per il modale di scomposizione articolo).
   Rifinito 2026-09-12 (richiesta esplicita del proprietario — "modo più
   pulito/elegante"): la % non è più colorata verde/rosso come l'importo.
   Due numeri saturi vicini sulla stessa riga (es. "+13.50€ +90%", entrambi
   verdi) è quello che rendeva la colonna "fastidiosa" — non la mancanza di
   spazio. Un solo colore (quello dell'importo, il dato primario) più una %
   in grigio neutro fra parentesi (dato accessorio, stesso trattamento di
   un "vs mese precedente" altrove nell'app) crea una gerarchia più chiara
   con meno saturazione, non un layout diverso. */
.profit-amount {
  font-weight: 600; font-variant-numeric: tabular-nums; letter-spacing: -0.01em;
}
.profit-amount.pos { color: var(--green-text); }
.profit-amount.neg { color: var(--red-text); }
.profit-pct {
  margin-left: 5px; font-size: 11px; font-weight: 500; color: var(--subtle);
  font-variant-numeric: tabular-nums;
}

/* ══════════════════════════════════════════════════════════════
   GENERIC TABLES
══════════════════════════════════════════════════════════════ */
.table-wrap {
  overflow-x: auto; border-radius: var(--r-md);
  border: 1px solid var(--border); box-shadow: var(--shadow-xs);
}
table { width: 100%; border-collapse: collapse; background: var(--surface); }
th, td { text-align: left; padding: 10px 14px; border-bottom: 1px solid var(--border); font-size: 13px; }
th {
  font-size: 9.5px; font-weight: 700; color: var(--subtle);
  text-transform: uppercase; letter-spacing: .09em; background: var(--surface-2);
}
tr:last-child td { border-bottom: none; }
tbody tr:hover td { background: var(--indigo-soft); }

.empty-state { text-align: center; padding: 56px 20px; color: var(--muted); font-size: 14px; }
.empty-icon  { font-size: 32px; margin-bottom: 10px; }
.empty       { text-align: center; padding: 28px; color: var(--muted); font-size: 13px; }

/* ══════════════════════════════════════════════════════════════
   BUTTONS
══════════════════════════════════════════════════════════════ */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 16px; border-radius: var(--r-md);
  border: none; cursor: pointer; font-size: 13px; font-weight: 600;
  transition: all var(--dur) var(--ease-out);
  white-space: nowrap; font-family: inherit; letter-spacing: -0.015em;
  position: relative; overflow: hidden;
  text-decoration: none;
}
.btn:active { transform: scale(0.97); }
.btn:disabled { opacity: .38; cursor: not-allowed; transform: none !important; }

.btn-primary {
  background: var(--indigo);
  color: #fff;
  box-shadow: 0 1px 2px rgba(0,0,0,0.16), 0 1px 4px rgba(110,86,207,0.20),
              inset 0 1px 0 rgba(255,255,255,0.10);
}
.btn-primary:hover:not(:disabled) {
  background: var(--indigo-d);
  box-shadow: 0 2px 8px rgba(110,86,207,0.30), 0 1px 2px rgba(0,0,0,0.12),
              inset 0 1px 0 rgba(255,255,255,0.12);
  transform: translateY(-1px);
}
.btn-green {
  background: linear-gradient(135deg, var(--green), var(--green-d));
  color: #fff;
  box-shadow: 0 1px 2px rgba(16,185,129,0.35), 0 3px 8px rgba(16,185,129,0.18);
}
.btn-green:hover:not(:disabled) { transform: translateY(-1.5px); box-shadow: 0 3px 10px rgba(16,185,129,0.45); }
.btn-red {
  background: linear-gradient(135deg, var(--red), var(--red-d));
  color: #fff;
  box-shadow: 0 1px 2px rgba(239,68,68,0.30);
}
.btn-red:hover:not(:disabled) { transform: translateY(-1.5px); box-shadow: 0 3px 10px rgba(239,68,68,0.35); }
.btn-red-ghost {
  background: transparent;
  border: 1px solid rgba(248,113,113,0.45);
  color: var(--dk-red, #EF4444);
  box-shadow: none;
}
.btn-red-ghost:hover:not(:disabled) {
  background: linear-gradient(135deg, var(--red), var(--red-d));
  color: #fff;
  border-color: transparent;
  transform: translateY(-1.5px);
  box-shadow: 0 3px 10px rgba(239,68,68,0.35);
}
.btn-outline {
  background: var(--surface); border: 1px solid var(--border);
  color: var(--text-2); box-shadow: var(--shadow-xs);
}
.btn-outline:hover:not(:disabled) {
  border-color: var(--border-strong); box-shadow: var(--shadow-sm);
  transform: translateY(-1px);
}
.btn-ghost { background: none; border: 1px solid transparent; color: var(--muted); }
.btn-ghost:hover:not(:disabled) { background: var(--surface-2); color: var(--text-2); border-color: var(--border); }

.btn-sm { padding: 5px 11px; font-size: 12px; border-radius: var(--r-sm); }
.btn-xs { padding: 3px 8px; font-size: 11px; border-radius: var(--r-xs); }

/* ══════════════════════════════════════════════════════════════
   FORMS
══════════════════════════════════════════════════════════════ */
/* Access/Refresh token affiancati invece di due righe piene larghezza
   (DESIGN_DECISIONS.md §116) — su una card larga (1100px, §113) un singolo
   campo token pieno larghezza lasciava un vuoto enorme accanto al testo
   breve che contiene. */
.token-form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.token-form-grid > .form-group { min-width: 0; }
@media (max-width: 720px) { .token-form-grid { grid-template-columns: 1fr; } }
.form-group { margin-bottom: 16px; }
.form-group label {
  display: block; font-size: 10.5px; font-weight: 700;
  margin-bottom: 6px; color: var(--muted);
  text-transform: uppercase; letter-spacing: .07em;
}
input[type="text"],input[type="number"],input[type="date"],
input[type="url"],input[type="password"],select,textarea {
  width: 100%; padding: 9px 13px;
  border: 1px solid var(--border); border-radius: var(--r-md);
  font-size: 13px; font-family: "Inter", inherit;
  background: var(--surface); color: var(--text); outline: none;
  transition: border-color var(--dur), box-shadow var(--dur);
  -webkit-appearance: none; appearance: none; box-shadow: var(--shadow-xs);
}
input:focus,select:focus,textarea:focus {
  border-color: var(--indigo);
  box-shadow: 0 0 0 3px rgba(110,86,207,0.10), var(--shadow-xs);
}
input::placeholder,textarea::placeholder { color: var(--subtle); }
textarea { resize: vertical; min-height: 100px; }
select {
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%239AA5B8' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 11px center; padding-right: 30px;
}
.form-row   { display: grid; grid-template-columns: 1fr 1fr;     gap: 12px; margin-bottom: 0; }
.form-row-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; margin-bottom: 0; }
.form-row > .form-group, .form-row-3 > .form-group { margin-bottom: 0; }

/* Skin globale per date-picker e spinner numerico nativi (DC-73) — mai
   toccati prima in nessun punto dell'app. Vale per OGNI input[type=date/
   number] del sito (item-modal, lotto d'acquisto, filtri data inventario,
   pannello vendita), non solo dove introdotto: sono selettori sul tipo di
   input, non su una classe, quindi si applicano automaticamente ovunque. */
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none; margin: 0;
}
input[type="number"] { -moz-appearance: textfield; }

input[type="date"]::-webkit-calendar-picker-indicator {
  cursor: pointer; opacity: 0.5; transition: opacity var(--dur-fast);
}
input[type="date"]:hover::-webkit-calendar-picker-indicator,
input[type="date"]:focus::-webkit-calendar-picker-indicator { opacity: 0.85; }

.form-hint { font-size: 11px; color: var(--subtle); margin-top: 5px; }
.form-error-text { font-size: 11px; color: var(--red-text); margin-top: 5px; font-weight: 600; }
.form-error-text:empty { display: none; }

.buyer-shipping-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px 14px; margin-top: 4px;
}
.buyer-shipping-grid .form-group { margin-bottom: 0; }
.buyer-shipping-grid label { text-align: center; }
.buyer-shipping-grid input { text-align: center; }
@media (max-width: 560px) {
  .buyer-shipping-grid { grid-template-columns: repeat(2, 1fr); }
}

/* ══════════════════════════════════════════════════════════════
   NEXUS DETAIL DRAWER
══════════════════════════════════════════════════════════════ */
.nd-overlay {
  display: none; position: fixed; inset: 0; z-index: 298;
}
.nd-overlay.open { display: block; }

.nd-drawer {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 299;
  width: 420px; max-width: 95vw;
  background: var(--surface);
  border-left: 1px solid rgba(0,0,0,0.08);
  box-shadow: -12px 0 40px rgba(0,0,0,0.10);
  display: flex; flex-direction: column;
  transform: translateX(100%);
  transition: transform 240ms var(--ease-out);
}
.nd-drawer.open { transform: translateX(0); }

.nd-drawer-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 20px 14px;
  border-bottom: 1px solid rgba(0,0,0,0.06);
  flex-shrink: 0;
}
.nd-agent-tag {
  font-size: 10px; font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase; padding: 3px 8px;
  border-radius: 4px; color: #fff;
}
.nd-agent-tag.buy_agent     { background: #6E56CF; }
.nd-agent-tag.vinted_bot    { background: #3B82F6; }
.nd-agent-tag.listing_agent { background: #F59E0B; }
.nd-agent-tag.sold_monitor  { background: #10B981; }
.nd-agent-tag.system        { background: #6B7280; }
.nd-agent-tag.error         { background: #EF4444; }

.nd-close {
  width: 28px; height: 28px; border-radius: 6px;
  border: 1px solid var(--border); background: var(--surface);
  font-size: 16px; color: var(--subtle); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: all var(--dur-fast);
}
.nd-close:hover { background: var(--surface-2); color: var(--text); }

.nd-drawer-body {
  flex: 1; overflow-y: auto; padding: 20px;
}

/* Purchase detail */
.nd-photo {
  width: 100%; height: 180px; border-radius: var(--r-lg);
  object-fit: cover; background: var(--surface-2);
  margin-bottom: 16px; display: block;
}
.nd-photo-placeholder {
  width: 100%; height: 140px; border-radius: var(--r-lg);
  background: linear-gradient(135deg, rgba(110,86,207,0.08), rgba(110,86,207,0.04));
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 16px; border: 1px solid rgba(110,86,207,0.10);
}
.nd-title {
  font-size: 17px; font-weight: 800; color: var(--text);
  letter-spacing: -0.03em; line-height: 1.3; margin-bottom: 16px;
}
.nd-stats-row {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 10px; margin-bottom: 18px;
}
.nd-stat {
  background: var(--surface-2);
  border: 1px solid rgba(0,0,0,0.05);
  border-radius: var(--r-md); padding: 11px 12px;
}
.nd-stat-label {
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .08em; color: var(--subtle); margin-bottom: 4px;
}
.nd-stat-val {
  font-size: 16px; font-weight: 800; color: var(--text); letter-spacing: -0.02em;
}
.nd-stat-val.green { color: #10B981; }
.nd-stat-val.violet { color: var(--indigo); }

.nd-section-label {
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .08em; color: var(--subtle); margin-bottom: 8px;
}
.nd-reasoning {
  font-size: 13px; color: var(--text-2); line-height: 1.6;
  margin-bottom: 16px;
}
.nd-warnings {
  list-style: none; margin: 0 0 18px; padding: 0; display: flex; flex-direction: column; gap: 6px;
}
.nd-warning {
  font-size: 12px; color: #92400E;
  background: #FEF3C7; border: 1px solid #FDE68A;
  border-radius: var(--r-sm); padding: 7px 10px;
}

.nd-meta-row {
  display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 20px;
}
.nd-meta-chip {
  font-size: 11px; color: var(--text-2); background: var(--surface-2);
  border: 1px solid var(--border); border-radius: var(--r-full);
  padding: 3px 9px;
}

.nd-action-row {
  display: flex; gap: 10px; margin-top: 4px;
  position: sticky; bottom: 0;
  background: var(--surface); padding: 16px 0 4px;
  border-top: 1px solid rgba(0,0,0,0.06);
}
.nd-btn-approve {
  flex: 1; padding: 11px; border-radius: var(--r-md);
  background: #10B981; color: #fff; border: none;
  font-size: 13px; font-weight: 700; cursor: pointer;
  transition: all var(--dur-fast); font-family: inherit;
}
.nd-btn-approve:hover { background: #059669; transform: translateY(-1px); }
.nd-btn-reject {
  flex: 1; padding: 11px; border-radius: var(--r-md);
  background: var(--surface-2); color: var(--text-2);
  border: 1px solid var(--border); font-size: 13px; font-weight: 600;
  cursor: pointer; transition: all var(--dur-fast); font-family: inherit;
}
.nd-btn-reject:hover { background: #FEE2E2; color: #EF4444; border-color: #FECACA; }

.nd-result-msg {
  padding: 12px 14px; border-radius: var(--r-md);
  font-size: 13px; font-weight: 600; text-align: center;
}
.nd-result-msg.success { background: #D1FAE5; color: #065F46; }
.nd-result-msg.neutral { background: var(--surface-2); color: var(--subtle); }

/* Feedback panel after rejection */
.nd-feedback-panel {
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: 14px; margin-top: 4px;
}
.nd-feedback-label {
  font-size: 12px; font-weight: 600; color: var(--subtle);
  text-transform: uppercase; letter-spacing: .04em; margin-bottom: 10px;
}
.nd-feedback-btns { display: flex; gap: 8px; flex-wrap: wrap; }
.nd-fb-btn {
  flex: 1; min-width: 110px;
  padding: 8px 10px; border-radius: var(--r-sm);
  border: 1px solid var(--border); background: var(--surface);
  font-size: 12px; font-weight: 600; cursor: pointer;
  transition: background .15s, border-color .15s;
}
.nd-fb-btn:hover { border-color: var(--violet); color: var(--violet); }
.nd-fb-match:hover { border-color: #EF4444; color: #EF4444; }
.nd-fb-price:hover { border-color: #F59E0B; color: #F59E0B; }
.nd-fb-ok:hover    { border-color: #10B981; color: #10B981; }
.nd-fb-input {
  padding: 7px 10px; border-radius: var(--r-sm);
  border: 1px solid var(--border); background: var(--surface);
  font-size: 13px; color: var(--text); outline: none;
}
.nd-fb-input:focus { border-color: var(--violet); }
.nd-fb-confirm {
  padding: 7px 14px; border-radius: var(--r-sm);
  background: var(--violet); color: #fff; border: none;
  font-size: 12px; font-weight: 600; cursor: pointer;
}
.nd-fb-confirm:hover { background: var(--violet-dark, #5B21B6); }
.nd-fb-skip {
  padding: 7px 10px; border-radius: var(--r-sm);
  background: transparent; color: var(--subtle);
  border: 1px solid var(--border); font-size: 12px; cursor: pointer;
}
.nd-fb-done {
  font-size: 13px; color: var(--text-2);
  padding: 10px 0; text-align: center;
}
.nd-suggest-chip {
  padding: 4px 10px; border-radius: 99px;
  border: 1px solid var(--border); background: var(--surface);
  font-size: 12px; cursor: pointer; transition: background .15s;
}
.nd-suggest-chip:hover { border-color: var(--violet); }

/* Error detail */
.nd-error-block {
  background: #FEF2F2; border: 1px solid #FECACA;
  border-radius: var(--r-md); padding: 14px;
  font-size: 12.5px; color: #7F1D1D; font-family: monospace;
  line-height: 1.5; word-break: break-all;
}

/* Generic detail */
.nd-desc-block {
  font-size: 13.5px; color: var(--text-2); line-height: 1.7;
  padding: 16px; background: var(--surface-2);
  border-radius: var(--r-md); border: 1px solid var(--border);
}

/* ══════════════════════════════════════════════════════════════
   MODAL
══════════════════════════════════════════════════════════════ */
.modal-overlay {
  display: none; position: fixed; inset: 0;
  background: rgba(5,7,18,0.50); z-index: 300;
  align-items: center; justify-content: center;
  backdrop-filter: blur(10px);
}
.modal-overlay.visible { display: flex; }
.modal {
  background: var(--surface);
  border: 1px solid var(--border-hairline);
  border-radius: var(--r-xl);
  padding: 28px;
  width: 640px; max-width: 95vw; max-height: 90vh; overflow-y: auto;
  box-shadow: var(--elev-4);
  animation: modal-in 250ms var(--ease-out);
}
@keyframes modal-in {
  from { opacity: 0; transform: scale(.95) translateY(12px); }
}
.modal-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 22px; padding-bottom: 16px; border-bottom: 1px solid var(--border);
}
.modal-header h3 { font-size: 15px; font-weight: 700; letter-spacing: -0.03em; color: var(--text); }
.confirm-modal { width: 420px; }
.confirm-modal-text { font-size: 13.5px; color: var(--muted); line-height: 1.6; margin: 0; }
.modal-close {
  background: none; border: none; cursor: pointer;
  color: var(--subtle); font-size: 18px; line-height: 1;
  padding: 4px 7px; border-radius: var(--r-xs);
  transition: background var(--dur-fast), color var(--dur-fast);
}
.modal-close:hover { background: var(--surface-2); color: var(--text); }
.modal-footer {
  margin-top: 22px; padding-top: 16px;
  border-top: 1px solid var(--border);
  display: flex; gap: 8px; justify-content: flex-end;
}

/* ══════════════════════════════════════════════════════════════
   BUY AGENT
══════════════════════════════════════════════════════════════ */
.result-card { border-left: 3px solid var(--border); }
.result-card.buy  { border-left-color: var(--green); }
.result-card.skip { border-left-color: var(--red); }
.result-header { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.result-meta { display: flex; gap: 24px; flex-wrap: wrap; margin-bottom: 16px; }
.result-meta-item { display: flex; flex-direction: column; gap: 3px; }
.meta-label { font-size: 9.5px; font-weight: 700; color: var(--subtle); text-transform: uppercase; letter-spacing: .09em; }
.meta-value { font-size: 22px; font-weight: 800; letter-spacing: -0.04em; }
.reasoning { color: var(--text-2); line-height: 1.65; margin-bottom: 14px; font-size: 13px; }
.warnings { list-style: none; }
.warnings li {
  padding: 8px 12px; background: var(--amber-soft);
  border-radius: var(--r-sm); font-size: 12.5px; margin-bottom: 5px;
  color: #78350F; border-left: 2px solid var(--amber);
}
.decision-section { margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--border); }
.decision-buttons { display: flex; gap: 10px; margin-bottom: 14px; }
.feedback-section { display: none; }
.feedback-section.visible { display: block; }
.conf-alta  { color: var(--green);  font-weight: 700; }
.conf-media { color: var(--amber);  font-weight: 700; }
.conf-bassa { color: var(--red);    font-weight: 700; }

/* ══════════════════════════════════════════════════════════════
   MISC
══════════════════════════════════════════════════════════════ */
.spinner {
  display: none; width: 18px; height: 18px;
  border: 2px solid rgba(0,0,0,0.07); border-top-color: var(--indigo);
  border-radius: var(--r-full); animation: spin .6s linear infinite; flex-shrink: 0;
}
.spinner.visible { display: block; }
@keyframes spin { to { transform: rotate(360deg); } }

.notice {
  padding: 10px 13px; border-radius: var(--r-sm); font-size: 12.5px;
  margin-top: 10px; display: none; font-weight: 500; border-left: 2.5px solid;
}
.notice.visible  { display: block; }
.notice-success  { background: var(--green-soft); color: var(--green-text); border-color: var(--green); }
.notice-error    { background: var(--red-soft);   color: var(--red-text);   border-color: var(--red); }
.notice-warning  { background: var(--amber-soft); color: var(--amber-text); border-color: var(--amber); }

.filters { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 16px; }
.filters select { width: auto; }
.flex { display: flex; }
.gap-8 { gap: 8px; }
.items-center { align-items: center; }
.text-muted { color: var(--muted); }
.mt-16 { margin-top: 16px; }
:root { --transition-fast: all var(--dur-fast) ease; }

/* ══════════════════════════════════════════════════════════════
   FEED LIVE
══════════════════════════════════════════════════════════════ */
.live-pulse {
  display: inline-block; width: 8px; height: 8px;
  background: var(--green); border-radius: 50%; margin-left: 8px;
  box-shadow: 0 0 0 0 rgba(16,185,129,.6);
  animation: livePulse 1.8s ease-out infinite; vertical-align: middle;
}
@keyframes livePulse {
  0%   { box-shadow: 0 0 0 0 rgba(16,185,129,.55); }
  70%  { box-shadow: 0 0 0 7px rgba(16,185,129,0); }
  100% { box-shadow: 0 0 0 0 rgba(16,185,129,0); }
}
.feed-nav-badge {
  margin-left: auto; background: var(--dk-violet); color: #fff;
  font-size: 9.5px; font-weight: 700; line-height: 1;
  padding: 2px 5px; border-radius: 99px; min-width: 15px; text-align: center;
}
.feed-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
  gap: 12px; padding-bottom: 32px;
}
.feed-empty {
  grid-column: 1 / -1; text-align: center;
  color: var(--muted); font-size: 14px; padding: 56px 0;
}

/* Feed card — significantly more refined */
.feed-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden; display: flex; flex-direction: column;
  transition: transform var(--dur) var(--ease-out),
              box-shadow var(--dur) var(--ease-out),
              border-color var(--dur);
  animation: feedIn .22s var(--ease-out) both;
}
@keyframes feedIn {
  from { opacity: 0; transform: translateY(8px) scale(0.99); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.feed-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-card-hover);
  border-color: rgba(110,86,207,0.15);
}
.feed-card-new {
  border-color: var(--indigo);
  box-shadow: 0 0 0 2px rgba(110,86,207,0.14), var(--shadow-sm);
}
.feed-card-new::before {
  content: "NUOVO";
  display: block; background: var(--indigo); color: #fff;
  font-size: 8.5px; font-weight: 800; letter-spacing: .12em;
  padding: 3px 10px; text-align: center;
}
.feed-card-img {
  width: 100%; aspect-ratio: 16/11; background: var(--surface-3);
  overflow: hidden; display: flex; align-items: center; justify-content: center;
  cursor: pointer; text-decoration: none;
}
.feed-card-img img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform .32s var(--ease-out);
}
.feed-card:hover .feed-card-img img { transform: scale(1.05); }
.feed-no-img {
  width: 40px; height: 40px; opacity: 0.20;
  color: var(--subtle);
}
.feed-card-body { padding: 12px 14px 8px; flex: 1; }
.feed-search-tag {
  font-size: 9.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .09em; color: var(--indigo); margin-bottom: 4px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.feed-card-title {
  font-size: 13px; font-weight: 600; color: var(--text); line-height: 1.4;
  margin-bottom: 8px; display: -webkit-box;
  -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.feed-card-meta { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-bottom: 6px; }
.feed-price { font-size: 15px; font-weight: 800; color: var(--text); letter-spacing: -0.03em; }
.feed-cond {
  font-size: 10px; background: rgba(0,0,0,0.04);
  border: 1px solid rgba(0,0,0,0.06);
  color: var(--muted); border-radius: var(--r-full); padding: 1px 7px; font-weight: 600;
  letter-spacing: 0.01em;
}
.feed-flag { font-size: 13px; line-height: 1; }
.feed-card-time { font-size: 10.5px; color: var(--subtle); }
.feed-card-actions {
  display: flex; align-items: center; gap: 5px; padding: 8px 12px 10px;
  border-top: 1px solid rgba(0,0,0,0.042);
}
.btn-sm { padding: 5px 11px; font-size: 11.5px; height: auto; min-height: 0; border-radius: var(--r-sm); }
.feed-dismiss {
  margin-left: auto; width: 28px; height: 28px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--subtle); font-size: 16px; line-height: 1;
  border-radius: var(--r-sm); background: none; border: none;
  cursor: pointer; transition: background var(--dur-fast), color var(--dur-fast);
}
.feed-dismiss:hover { background: var(--red-soft); color: var(--red); }

/* ── Quick Sell backdrop (2026-09-13, richiesta esplicita del proprietario:
   nessun "menu" della pagina Inventario deve lasciare interagibile la
   tabella dietro di sé). Il pannello è ancorato in basso, non copre tutto
   lo schermo — senza questo velo dietro, la tabella sopra restava
   cliccabile/editabile mentre si compilava la vendita. z-index appena sotto
   il pannello (96): copre la tabella ma non il pannello stesso. ── */
.quick-sell-overlay {
  position: fixed; inset: 0; z-index: 95;
  background: rgba(5,7,18,0.35);
}

/* ── Quick Sell panel (fixed bottom overlay) ── */
.quick-sell-panel {
  /* left:64px non var(--sidebar-w) — stessa causa del bug mobile già
     corretto più sotto (§4144): deve combaciare con l'offset reale di
     .main-content, ora sempre 64px (sidebar a scomparsa, 2026-09-12), non
     con la larghezza "espansa" della sidebar che ormai è solo un hover
     temporaneo. */
  position: fixed; bottom: 0; left: 64px; right: 0; z-index: 96;
  background: #fff;
  border-top: 3px solid var(--green);
  box-shadow: 0 -2px 8px rgba(0,0,0,0.06), 0 -12px 40px rgba(0,0,0,0.10);
  padding: 10px 24px 14px;
  display: flex; flex-direction: column; gap: 9px;
  box-sizing: border-box;
  /* Vincolo di altezza (fix bug lotto, 2026-07-21): senza questo il
     pannello cresceva oltre il viewport quando si attivava la sezione
     lotto (ricerca + chip), spingendo il dropdown dei risultati fuori
     dallo schermo senza modo di raggiungerlo. Lascia sempre visibile
     un margine sopra il pannello; oltre quello scorre internamente. */
  max-height: calc(100vh - 80px);
  overflow-y: auto;
}

/* Header */
.qs-header {
  display: flex; align-items: center; gap: 12px;
  padding-bottom: 9px;
  border-bottom: 1px solid rgba(0,0,0,0.07);
}
.qs-header-meta { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.qs-title {
  font-size: 9px; font-weight: 800; color: var(--green-text);
  text-transform: uppercase; letter-spacing: .12em;
}
.qs-item-name {
  font-size: 15px; font-weight: 700; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  line-height: 1.2;
}
.qs-close {
  flex-shrink: 0; width: 28px; height: 28px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: none; border: none; cursor: pointer; color: var(--subtle);
  transition: background var(--dur-fast), color var(--dur-fast);
}
.qs-close:hover { background: var(--red-soft); color: var(--red-text); }

/* Fields row */
.qs-body { display: flex; gap: 10px; align-items: flex-end; }
.qs-group { display: flex; flex-direction: column; gap: 3px; flex-shrink: 0; }
.qs-group label {
  font-size: 9px; font-weight: 700; color: #94a3b8;
  text-transform: uppercase; letter-spacing: .08em; padding-left: 2px;
}
.qs-notes-group { flex: 1; min-width: 100px; flex-shrink: 1; }
.qs-fee-group { min-width: 200px; }

.qs-input {
  height: 32px; padding: 0 9px;
  border: 1.5px solid rgba(0,0,0,0.11);
  border-radius: 7px; background: #FAFBFF;
  font-size: 12.5px; font-family: inherit; color: var(--text);
  outline: none; width: 100%; box-sizing: border-box;
  transition: border-color 120ms, box-shadow 120ms, background 120ms;
}
.qs-input:focus {
  border-color: var(--indigo); background: #fff;
  box-shadow: 0 0 0 3px rgba(99,102,241,0.10);
}
.qs-notes-input { height: auto; padding: 7px 9px; resize: none; min-height: 32px; }

/* Toggle Vendita singola/lotto — prima decisione del pannello, subito
   sotto il titolo (DC-73). Stessa palette di .qs-input per coerenza
   interna al pannello, stato attivo indigo pieno come altri toggle
   dell'app (.refund-mode-btn.active, .qs-fee-btn.active). */
.qs-mode-toggle { display: flex; gap: 6px; margin-bottom: 2px; }
.qs-mode-btn {
  flex: 1; padding: 7px 10px; border-radius: 7px;
  border: 1.5px solid rgba(0,0,0,0.11); background: #FAFBFF;
  color: var(--muted); font-size: 12.5px; font-weight: 600;
  cursor: pointer; text-align: center;
  transition: all var(--dur-fast) var(--ease-out);
}
.qs-mode-btn:hover { color: var(--text); border-color: rgba(0,0,0,0.18); }
.qs-mode-btn.active { background: var(--indigo); border-color: var(--indigo); color: #fff; }

/* Riepilogo profitto — riga a sé stante, sempre subito sopra i bottoni
   azione finali (mai in mezzo al flusso, vedi DC-73). */
.qs-profit-preview { font-size: 13px; font-weight: 700; color: var(--muted); text-align: right; margin: 2px 0; }
.qs-fee-hint { font-size: 11px; font-weight: 500; color: var(--muted); margin-top: 2px; }
.qs-pos { color: var(--green-text); }
.qs-neg { color: var(--red-text); }

/* Bottoni finali — SEMPRE l'ultimo blocco del pannello, mai fissi a metà:
   se la modalità lotto aggiunge contenuto (ricerca, chip, ripartizione),
   quel contenuto sta prima nel markup e li spinge più in basso (DC-73). */
.qs-actions-row {
  display: flex; align-items: center; justify-content: flex-end; gap: 8px;
  padding-top: 8px; border-top: 1px solid rgba(0,0,0,0.07);
}

/* Fee buttons (kept for any legacy fee UI) */
.qs-fee-btns { display: flex; gap: 4px; flex-wrap: wrap; margin-bottom: 4px; }
.qs-fee-btn {
  background: var(--surface-3); border: 1px solid var(--border);
  border-radius: 6px; padding: 3px 7px; font-size: 10.5px; font-weight: 600;
  cursor: pointer; color: var(--muted); transition: all 0.12s;
}
.qs-fee-btn:hover { background: var(--indigo-soft); border-color: var(--indigo); color: var(--indigo); }
.qs-fee-btn.active { background: var(--indigo); color: #fff; border-color: var(--indigo); }
.qs-lot-section { display: flex; flex-direction: column; gap: 8px; padding: 8px 0 2px; }
.qs-lot-search-wrap { position: relative; }
.qs-lot-search { width: 100%; box-sizing: border-box; }
.qs-lot-search-results {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 200;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 8px; box-shadow: 0 4px 16px rgba(0,0,0,0.10);
  max-height: 200px; overflow-y: auto; margin-top: 3px;
}
.lot-search-row {
  display: flex; justify-content: space-between; align-items: center;
  padding: 7px 10px; cursor: pointer; font-size: 12.5px;
  border-bottom: 1px solid var(--border);
}
.lot-search-row:last-child { border-bottom: none; }
.lot-search-row:hover { background: var(--indigo-soft); }
.lot-search-row small { color: var(--muted); font-size: 11px; }
.lot-search-empty { padding: 10px; text-align: center; color: var(--faint); font-size: 12px; }
.qs-lot-items { display: flex; flex-wrap: wrap; gap: 5px; }
.lot-sell-chip {
  display: flex; align-items: center; gap: 5px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 20px; padding: 3px 10px; font-size: 11.5px; color: var(--text);
}
.lot-sell-chip-main { background: var(--indigo-soft); border-color: var(--indigo); color: var(--indigo); font-weight: 600; }
.lot-sell-chip small { color: var(--muted); }
.lot-sell-chip button { background: none; border: none; cursor: pointer; color: var(--muted); font-size: 10px; padding: 0 0 0 2px; }

/* Ripartizione lotto (Equa/Proporzionale) — stesso stile toggle e stessa
   struttura di anteprima per-articolo di Rimborso su lotto (.refund-mode-btn,
   .refund-preview-row), riproposti qui con classi dedicate (DC-73). Mostrata
   solo quando c'è almeno un articolo aggiunto oltre al principale. */
.qs-split-section { margin-top: 4px; padding-top: 10px; border-top: 1px dashed rgba(0,0,0,0.08); }
.qs-split-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; gap: 8px; }
.qs-split-title { font-size: 10px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .07em; }
.qs-split-toggle { display: flex; gap: 6px; }
.qs-split-btn {
  padding: 5px 9px; border-radius: var(--r-sm);
  border: 1px solid var(--border); background: var(--surface-2);
  color: var(--muted); font-size: 11px; font-weight: 600;
  cursor: pointer; transition: all var(--dur-fast) var(--ease-out);
}
.qs-split-btn:hover { color: var(--text); }
.qs-split-btn.active { background: var(--indigo); border-color: var(--indigo); color: #fff; }
.qs-split-preview { display: flex; flex-direction: column; gap: 4px; }
.qs-split-row { display: flex; justify-content: space-between; align-items: center; font-size: 11.5px; color: var(--text-2); gap: 8px; }
.qs-split-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1; color: var(--muted); }
.qs-split-val { flex-shrink: 0; font-variant-numeric: tabular-nums; }
.qs-split-val strong { color: var(--text); }

/* ── Lot modal ── */
.lot-modal { max-width: 980px; width: 95vw; max-height: 90vh; display: flex; flex-direction: column; overflow: hidden; }
.lot-meta { display: flex; gap: 12px; flex-wrap: wrap; padding-bottom: 12px; border-bottom: 1px solid var(--border); }
.lot-meta .form-group { flex: 1; min-width: 140px; margin-bottom: 0; }
.lot-items-header { display: flex; align-items: center; gap: 10px; padding: 10px 0 6px; font-size: 12.5px; font-weight: 700; color: var(--text); }
.lot-summary { flex: 1; font-size: 12px; color: var(--muted); }
.lot-items-table-wrap { overflow-y: auto; flex: 1; min-height: 0; border: 1px solid var(--border); border-radius: 8px; }
.lot-items-table { width: 100%; border-collapse: collapse; font-size: 12.5px; table-layout: fixed; }
.lot-items-table th:nth-child(1),
.lot-items-table td:nth-child(1) { width: 38%; }
.lot-items-table th:nth-child(2),
.lot-items-table td:nth-child(2) { width: 15%; }
.lot-items-table th:nth-child(3),
.lot-items-table td:nth-child(3) { width: 14%; }
.lot-items-table th:nth-child(4),
.lot-items-table td:nth-child(4) { width: 13%; }
.lot-items-table th:nth-child(5),
.lot-items-table td:nth-child(5) { width: 17%; }
.lot-items-table th:nth-child(6),
.lot-items-table td:nth-child(6) { width: 3%; text-align: center; padding: 0; }

/* decompose-modal ha una 7ª colonna (Margine previsto) che lot-modal non ha:
   le percentuali sopra sono pensate per 6 colonne e sommano già al 100%, quindi
   sotto table-layout:fixed la 7ª restava senza spazio e il .margin-pill dentro
   andava a capo su più righe (bug estetico). Percentuali dedicate a 7 colonne,
   dopo le regole di lot-modal per vincere a parità di specificità. */
.decompose-table th:nth-child(1), .decompose-table td:nth-child(1) { width: 27%; }
.decompose-table th:nth-child(2), .decompose-table td:nth-child(2) { width: 12%; }
.decompose-table th:nth-child(3), .decompose-table td:nth-child(3) { width: 9%; }
.decompose-table th:nth-child(4), .decompose-table td:nth-child(4) { width: 11%; }
.decompose-table th:nth-child(5), .decompose-table td:nth-child(5) { width: 16%; }
.decompose-table th:nth-child(6), .decompose-table td:nth-child(6) { width: 22%; text-align: right; }
.decompose-table th:nth-child(7), .decompose-table td:nth-child(7) { width: 3%; text-align: center; padding: 0; }

.lot-items-table th { background: var(--table-head); padding: 7px 10px; text-align: left; font-size: 11px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; border-bottom: 1px solid var(--border); position: sticky; top: 0; }
.lot-items-table td { padding: 5px 8px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.lot-items-table tr:last-child td { border-bottom: none; }
.lot-items-table .num { text-align: right; }
.lot-input { border: 1.5px solid var(--border-strong); border-radius: 6px; padding: 5px 8px; font-size: 12.5px; font-family: inherit; color: var(--text); background: #fff; outline: none; width: 100%; box-sizing: border-box; }
.lot-input:focus { border-color: var(--indigo); box-shadow: 0 0 0 3px var(--indigo-soft); }
.lot-price-input { max-width: 110px; text-align: right; }
.lot-calc-col { min-width: 110px; font-weight: 700; color: var(--indigo); font-size: 12.5px; }
.lot-remove-btn { background: none; border: none; cursor: pointer; color: var(--muted); font-size: 13px; padding: 4px 7px; border-radius: 5px; display: block; margin: 0 auto; }
.lot-remove-btn:hover { background: var(--red-soft); color: var(--red-text); }
.lot-notes-input { min-width: 140px; color: var(--text-2); }
.lot-notes-input::placeholder { color: var(--subtle); }

/* Autocomplete suggestion shown as a light selection on the name input */
.lot-name-input::selection { background: rgba(110,86,207,0.18); color: var(--text); }
.lot-footer { display: flex; align-items: center; gap: 12px; padding-top: 10px; border-top: 1px solid var(--border); margin-top: 4px; }
.lot-total-preview { flex: 1; font-size: 12.5px; color: var(--muted); }
.lot-total-preview strong { color: var(--text); }

/* ── Status picker ── */
.status-picker {
  position: absolute; z-index: 9999;
  display: flex; flex-direction: column; gap: 4px;
  padding: 7px; background: var(--surface);
  border: 1px solid rgba(0,0,0,0.10); border-radius: 11px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.12); min-width: 140px;
}
.status-pick-btn {
  cursor: pointer; font-size: 11.5px; font-weight: 600;
  padding: 5px 12px; border-radius: 18px; border: none;
  text-align: center; transition: opacity 0.13s, transform 0.1s; width: 100%;
}
.status-pick-btn:hover { opacity: 0.85; transform: scale(1.02); }
.status-pick-btn.current { outline: 2px solid var(--text); outline-offset: 2px; }

/* ══════════════════════════════════════════════════════════════
   BUY OPPORTUNITIES
══════════════════════════════════════════════════════════════ */
.opp-header { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.opp-title { font-size: 14px; font-weight: 700; color: var(--text); letter-spacing: -0.02em; }
.opp-badge {
  background: var(--accent); color: #fff;
  font-size: 10.5px; font-weight: 800; padding: 2px 8px;
  border-radius: var(--r-full);
  box-shadow: 0 2px 6px rgba(110,86,207,0.30);
}
.opp-ignore-all {
  margin-left: auto;
  background: none; border: none; cursor: pointer;
  font-size: 12px; font-weight: 600; color: var(--muted);
  padding: 4px 2px;
  transition: color var(--dur-fast);
}
.opp-ignore-all:hover { color: var(--text-2); text-decoration: underline; }
.opp-list { display: flex; flex-direction: column; gap: 10px; }
.opp-card {
  position: relative;
  display: flex; gap: 14px; align-items: flex-start;
  background: var(--surface);
  border: 1px solid rgba(110,86,207,0.18);
  border-radius: var(--r-lg); padding: 16px;
  padding-right: 40px;
  box-shadow: 0 0 0 1px rgba(110,86,207,0.06),
              0 2px 8px rgba(0,0,0,0.05),
              0 8px 24px rgba(110,86,207,0.06);
  transition: box-shadow var(--dur), border-color var(--dur), opacity 220ms ease, transform 220ms ease;
}
.opp-card:hover {
  border-color: rgba(110,86,207,0.30);
  box-shadow: 0 0 0 1px rgba(110,86,207,0.12),
              0 4px 16px rgba(0,0,0,0.07),
              0 12px 32px rgba(110,86,207,0.10);
}
.opp-card.opp-dismissing { opacity: 0; transform: translateX(10px); }
.opp-dismiss {
  position: absolute; top: 10px; right: 10px;
  width: 22px; height: 22px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  background: none; border: none; border-radius: var(--r-sm);
  color: rgba(0,0,0,0.32); cursor: pointer;
  transition: color var(--dur-fast), background var(--dur-fast);
}
.opp-dismiss:hover { color: rgba(0,0,0,0.75); background: rgba(0,0,0,0.06); }
.opp-img { width: 68px; height: 68px; object-fit: cover; border-radius: var(--r-md); flex-shrink: 0; }
.opp-body { flex: 1; min-width: 0; }
.opp-name { font-size: 13.5px; font-weight: 700; margin-bottom: 7px; letter-spacing: -0.02em; }
.opp-meta { display: flex; flex-wrap: wrap; gap: 10px; font-size: 11.5px; color: var(--muted); margin-bottom: 7px; }
.opp-meta strong { color: var(--text); font-weight: 700; }
.opp-meta .opp-margin strong { color: inherit; }
.opp-reason { font-size: 12px; color: var(--muted); line-height: 1.55; }
.opp-warns { margin-top: 7px; display: flex; flex-wrap: wrap; gap: 5px; }
.opp-warn { font-size: 10.5px; background: rgba(245,158,11,0.09); color: var(--amber-text); border: 1px solid rgba(245,158,11,0.18); padding: 2px 8px; border-radius: var(--r-sm); }
.opp-actions { display: flex; flex-direction: column; gap: 5px; flex-shrink: 0; }

/* ── Inline feedback ── */
.opp-feedback-wrap { padding: 12px 4px; width: 100%; }
.opp-feedback-label { font-size: 13px; font-weight: 600; margin-bottom: 11px; color: var(--text); letter-spacing: -0.02em; }
.opp-feedback-btns  { display: flex; gap: 7px; margin-bottom: 10px; }
.fb-btn {
  padding: 6px 14px; border-radius: var(--r-full);
  border: 1px solid var(--border); background: var(--surface-2);
  cursor: pointer; font-size: 13px; font-weight: 500;
  transition: all var(--dur-fast);
}
.fb-btn:hover { border-color: var(--accent); color: var(--accent); }
.fb-btn.fb-selected { background: var(--accent); color: #fff; border-color: var(--accent); box-shadow: 0 2px 8px rgba(110,86,207,0.30); }
.opp-feedback-input {
  width: 100%; box-sizing: border-box; padding: 8px 12px;
  border: 1px solid var(--border); border-radius: var(--r-md);
  font-size: 13px; background: var(--surface-2); margin-bottom: 8px;
  transition: border-color var(--dur);
}
.opp-feedback-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(110,86,207,0.09); }
.opp-feedback-footer { display: flex; justify-content: flex-end; }

/* ── "Da rivedere" — tag di motivo per skip sbagliati (chip, no testo libero) ── */
.review-tags { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; max-width: 220px; }
.review-tag-btn {
  padding: 5px 11px; border-radius: var(--r-full);
  border: 1px solid var(--border); background: var(--surface-2);
  cursor: pointer; font-size: 11.5px; font-weight: 500; color: var(--text);
  transition: all var(--dur-fast);
}
.review-tag-btn:hover { border-color: var(--red); color: var(--red-text, var(--red)); background: rgba(239,68,68,0.06); }
.review-resale-input { display: flex; flex-direction: column; gap: 6px; align-items: flex-end; }
.review-resale-reasons { display: flex; flex-wrap: wrap; gap: 5px; justify-content: flex-end; max-width: 220px; }
.review-resale-reason.active {
  border-color: var(--accent); color: var(--accent); background: rgba(110,86,207,0.08);
}
.review-resale-label { font-size: 10.5px; color: var(--muted); text-transform: uppercase; letter-spacing: .02em; }
.review-resale-error { font-size: 11px; color: var(--red-text, var(--red)); min-height: 14px; }
.review-resale-field {
  width: 210px; box-sizing: border-box; padding: 6px 10px;
  border: 1px solid var(--border); border-radius: var(--r-md);
  font-size: 12.5px; background: var(--surface-2);
}
.review-resale-field:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(110,86,207,0.09); }
.review-resale-btns { display: flex; gap: 6px; }

/* ── Feed alert card ── */
.feed-card-alert {
  display: flex; align-items: center; gap: 12px;
  border: 1.5px solid rgba(245,158,11,0.30);
  background: rgba(254,251,235,0.8);
  border-radius: var(--r-lg); padding: 14px 16px;
}
.feed-card-alert-icon { font-size: 24px; flex-shrink: 0; line-height: 1; }
.feed-card-sold { border-left: 2.5px solid var(--green); opacity: 0.82; }

/* ══════════════════════════════════════════════════════════════
   AGENTE ACQUISTO — chiaro (DC-61, 2026-07-20). Era l'unica pagina
   dark-nativa senza layer chiaro sotto (DC-1.2 storico) — riscritta
   qui con i token del sistema chiaro premium (DC-58), stesso
   vocabolario già in uso altrove (dash-filters, badge-idle, ecc.).
══════════════════════════════════════════════════════════════ */
.buy-status-card {
  display: flex; align-items: center; gap: 28px; flex-wrap: wrap;
  padding: 18px 22px;
}
.buy-status-id { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.buy-status-dot {
  width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0;
  background: var(--faint);
  transition: background var(--dur), box-shadow var(--dur);
}
.buy-status-dot.running {
  background: var(--green);
  box-shadow: 0 0 0 3px rgba(16,185,129,0.18), 0 0 10px rgba(16,185,129,0.5);
  animation: livePulse 1.8s ease-out infinite;
}
/* Respiro discreto da fermo (DC-62) — non un grigio piatto/spento, ma
   nemmeno il pulse acceso di .running: un ciclo lento e sottile che
   comunica "in attesa", non "assente". */
.buy-status-dot.stopped { background: var(--faint); box-shadow: none; animation: dotBreathe 3.2s ease-in-out infinite; }
@keyframes dotBreathe {
  0%, 100% { opacity: 0.55; transform: scale(0.88); }
  50%      { opacity: 1;    transform: scale(1); }
}
.buy-status-label { font-size: 10px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--subtle); margin-bottom: 2px; }
.buy-status-value { font-size: 15px; font-weight: 700; color: var(--text); letter-spacing: -0.01em; }
.buy-status-stats { flex: 1; min-width: 280px; }
.buy-status-card .btn { flex-shrink: 0; }

.buy-opp-section { margin-top: 20px; }
.buy-opp-header {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-bottom: 14px;
}
.buy-opp-tabs {
  display: flex; gap: 2px; background: var(--surface-2);
  border: 1px solid var(--border); border-radius: 10px; padding: 3px;
}
.buy-opp-tab {
  padding: 6px 13px; border: none; background: none; border-radius: 7px;
  cursor: pointer; font-size: 12px; font-weight: 600; color: var(--muted);
  transition: all var(--dur) var(--ease-out); white-space: nowrap;
  font-family: inherit; letter-spacing: -0.01em;
  display: flex; align-items: center; gap: 6px;
}
.buy-opp-tab:hover { color: var(--text); background: rgba(0,0,0,0.03); }
.buy-opp-tab.active {
  background: var(--surface); color: var(--indigo);
  box-shadow: var(--shadow-xs);
}
.buy-opp-tab .tab-count {
  background: rgba(0,0,0,0.06); color: var(--muted);
  font-size: 9.5px; font-weight: 700; border-radius: 5px; padding: 0 5px;
  line-height: 16px; min-width: 17px; text-align: center;
}
.buy-opp-tab.active .tab-count { background: var(--indigo-soft); color: var(--indigo); }
.buy-opp-tools { display: flex; align-items: center; gap: 12px; margin-left: auto; }
.buy-sort-toggle { display: flex; gap: 2px; background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px; padding: 2px; }
.buy-sort-btn {
  padding: 4px 10px; border: none; background: none; border-radius: 6px;
  cursor: pointer; font-size: 11.5px; font-weight: 600; color: var(--muted);
  transition: all var(--dur-fast); font-family: inherit;
}
.buy-sort-btn:hover { color: var(--text); }
.buy-sort-btn.active { background: var(--surface); color: var(--text); box-shadow: var(--shadow-xs); }
.opp-see-all {
  margin-left: auto; font-size: 12px; font-weight: 700; color: var(--indigo) !important;
  text-decoration: none; transition: color var(--dur-fast);
}
.opp-see-all:hover { color: var(--indigo-d) !important; text-decoration: underline; }

.buy-opp-empty {
  text-align: center; padding: 48px 20px; color: var(--muted);
  font-size: 13.5px; background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--r-lg);
}
.buy-opp-empty .empty-icon { font-size: 28px; margin-bottom: 8px; opacity: 0.7; }

/* History cards (Ignorate/Approvate/Rifiutate) — stessa forma della opp-card
   ma non azionabili: badge esito al posto dei bottoni Approva/Rifiuta. */
.opp-card.opp-history { padding-right: 16px; }
.opp-history-badge {
  font-size: 9.5px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase;
  padding: 2px 8px; border-radius: var(--r-full); flex-shrink: 0; align-self: flex-start;
}
.opp-history-badge.approved { background: var(--green-soft); color: var(--green-text); border: 1px solid rgba(16,185,129,0.18); }
.opp-history-badge.rejected,
.opp-history-badge.dismissed { background: rgba(0,0,0,0.045); color: var(--muted); border: 1px solid var(--border); }
.opp-history-feedback { margin-top: 6px; font-size: 11.5px; color: var(--subtle); font-style: italic; }

.buy-config-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 20px;
}
.buy-config-desc { font-size: 13px; color: var(--muted); line-height: 1.6; margin: 0 0 14px; }
.buy-config-desc code { font-size: 12px; background: var(--surface-2); padding: 1px 5px; border-radius: 4px; }
.buy-mode-toggle { display: flex; gap: 10px; flex-wrap: wrap; }
.buy-config-note { font-size: 11.5px; color: var(--subtle); margin-top: 10px; line-height: 1.5; }
.buy-param-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 20px; }
.buy-param-label { font-size: 9.5px; color: var(--subtle); text-transform: uppercase; letter-spacing: 0.07em; font-weight: 600; margin-bottom: 3px; }
.buy-param-val { font-size: 17px; font-weight: 700; color: var(--text); letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.buy-shipping-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.buy-shipping-chip {
  font-size: 11.5px; font-weight: 600; color: var(--muted);
  background: var(--surface-2); border: 1px solid var(--border);
  padding: 3px 10px; border-radius: var(--r-full);
}
.buy-shipping-chip strong { color: var(--text); }
@media (max-width: 900px) {
  .buy-config-grid { grid-template-columns: 1fr; }
}

/* ══════════════════════════════════════════════════════════════
   SETTINGS
══════════════════════════════════════════════════════════════ */
.monitor-status-badge {
  font-size: 10.5px; font-weight: 700; padding: 3px 10px;
  border-radius: var(--r-full); letter-spacing: 0.05em; text-transform: uppercase;
}
.badge-active  { background: rgba(16,185,129,0.09); color: var(--green-text); border: 1px solid rgba(16,185,129,0.18); }
.badge-stopped { background: rgba(239,68,68,0.09);  color: var(--red-text);   border: 1px solid rgba(239,68,68,0.18); }
.badge-idle    { background: rgba(245,158,11,0.09); color: var(--amber-text); border: 1px solid rgba(245,158,11,0.18); }

.settings-stat-row { display: flex; gap: 28px; flex-wrap: wrap; margin-top: 4px; }
.settings-stat { display: flex; flex-direction: column; gap: 4px; }
.settings-stat-label { font-size: 9.5px; color: var(--subtle); text-transform: uppercase; letter-spacing: 0.09em; font-weight: 600; }
.settings-stat-val   { font-size: 22px; font-weight: 800; color: var(--text); letter-spacing: -0.04em; font-variant-numeric: tabular-nums; }

.shortcuts-steps { display: flex; flex-direction: column; gap: 9px; margin: 4px 0; }
.shortcut-step {
  display: flex; align-items: flex-start; gap: 12px;
  font-size: 13px; color: var(--text); line-height: 1.5;
}
.step-n {
  flex-shrink: 0; width: 21px; height: 21px; border-radius: 50%;
  background: var(--accent); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 10.5px; font-weight: 700; margin-top: 1px;
  box-shadow: 0 2px 6px rgba(110,86,207,0.28);
}

/* ── Platform buttons ── */
.post-platforms { display: flex; flex-wrap: wrap; gap: 9px; align-items: center; }
.btn-platform {
  display: flex; align-items: center; gap: 8px;
  font-size: 12.5px; font-weight: 600; padding: 9px 16px;
  border-radius: var(--r-md); border: none; cursor: pointer;
  transition: opacity 0.15s, transform 0.1s, box-shadow 0.15s;
}
.btn-platform:hover  { opacity: 0.88; transform: translateY(-1.5px); }
.btn-platform:active { transform: scale(0.97); }
.btn-platform:disabled { opacity: 0.35; cursor: not-allowed; transform: none; }
.btn-platform span {
  width: 20px; height: 20px; border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 800; background: rgba(0,0,0,0.13);
}
.btn-vinted   { background: #09B1BA; color: #fff; box-shadow: 0 2px 8px rgba(9,177,186,0.28); }
.btn-subito   { background: #E85C0D; color: #fff; box-shadow: 0 2px 8px rgba(232,92,13,0.28); }
.btn-wallapop { background: #13C0A2; color: #fff; box-shadow: 0 2px 8px rgba(19,192,162,0.28); }

/* ── Photo grid ── */
.photos-grid { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 8px; }
.photo-thumb {
  position: relative; cursor: pointer; border-radius: var(--r-md);
  overflow: hidden; border: 2px solid transparent;
  width: 86px; height: 86px; flex-shrink: 0;
  transition: border-color 0.15s, opacity 0.15s, transform 0.15s;
  opacity: 0.5;
}
.photo-thumb:hover { opacity: 0.75; transform: scale(1.02); }
.photo-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-thumb .photo-check {
  position: absolute; top: 4px; right: 4px;
  background: var(--accent); color: #fff;
  border-radius: 50%; width: 18px; height: 18px;
  font-size: 10px; font-weight: 700;
  display: none; align-items: center; justify-content: center;
  box-shadow: 0 1px 4px rgba(0,0,0,0.20);
}
.photo-thumb.selected { border-color: var(--accent); opacity: 1; }
.photo-thumb.selected .photo-check { display: flex; }

/* ══════════════════════════════════════════════════════════════
   TOAST — Raycast-style
══════════════════════════════════════════════════════════════ */
.app-toast {
  position: fixed; bottom: 24px; left: 50%;
  transform: translateX(-50%) translateY(10px);
  background: #0E0F1A; color: rgba(255,255,255,0.92);
  border: 1px solid rgba(255,255,255,0.09);
  border-radius: 12px;
  padding: 10px 18px; font-size: 12.5px; font-weight: 600;
  opacity: 0; transition: opacity 0.18s, transform 0.22s var(--ease-out);
  pointer-events: none; z-index: 9999; white-space: nowrap;
  box-shadow: 0 4px 16px rgba(0,0,0,0.22), 0 1px 0 rgba(255,255,255,0.04) inset;
  letter-spacing: -0.01em;
  display: flex; align-items: center; gap: 14px;
}
.app-toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.app-toast.has-action { pointer-events: auto; }
.app-toast.error {
  border-left: 3px solid var(--dk-red);
  padding-left: 15px;
  white-space: normal;
  max-width: min(520px, 90vw);
  text-align: left;
}
.app-toast-icon { flex-shrink: 0; display: flex; align-items: center; }
.app-toast-action {
  background: transparent; border: none; padding: 0; cursor: pointer;
  color: var(--dk-violet); font-weight: 700; font-size: 12.5px;
  letter-spacing: -0.01em;
}
.app-toast-action:hover { color: var(--dk-violet-2); text-decoration: underline; }

/* ══════════════════════════════════════════════════════════════
   UI POLISH — solo layer visivo, nessuna funzionalità modificata
══════════════════════════════════════════════════════════════ */

/* ── 1. Rimuovi striping alternato (effetto Excel) ── */
.inv-table tbody tr:nth-child(even) td           { background: #ffffff; }
.inv-table tbody tr:nth-child(even) td.col-sticky { background: #ffffff; }

/* ── 2. Hover riga più percettibile ── */
.inv-table tbody tr td                      { transition: background 70ms ease; }
.inv-table tbody tr:hover td                { background: rgba(0,0,0,0.028) !important; }
.inv-table tbody tr.sold:hover td           { background: rgba(16,185,129,0.055) !important; }
.inv-table tbody tr.in_stock:hover td       { background: rgba(110,86,207,0.055) !important; }
.inv-table tbody tr.in_transit:hover td     { background: rgba(234,179,8,0.055) !important; }
.inv-table tbody tr.listed:hover td         { background: rgba(245,158,11,0.055) !important; }
.inv-table tbody tr:hover td.col-sticky             { background: #F4F5F8 !important; }
.inv-table tbody tr.sold:hover td.col-sticky        { background: #EDF8F4 !important; }
.inv-table tbody tr.in_stock:hover td.col-sticky    { background: #F2F0FF !important; }
.inv-table tbody tr.in_transit:hover td.col-sticky  { background: #FDFCEE !important; }
.inv-table tbody tr.listed:hover td.col-sticky      { background: #FDFAED !important; }

/* ── 3. Separatori riga più sottili — meno rumore verticale ── */
.inv-table td { border-bottom: 1px solid rgba(0,0,0,0.032); }
.inv-table tr:last-child td { border-bottom: none; }

/* ── 4. Header tabella: più distinto, meno piatto ── */
.inv-table th {
  background: #ECEEF8;
  padding: 7px 14px;
  font-size: 8.5px;
  letter-spacing: 0.13em;
  border-bottom: 1px solid rgba(0,0,0,0.09);
  color: #7B87A0;
}
.inv-table thead .col-sticky,
.inv-table thead th.col-sticky-1,
.inv-table thead th.col-sticky-2 { background: #ECEEF8; }

/* ── 5. Status badge — più compatti, meno peso visivo ── */
.badge {
  padding: 1px 6px;
  font-size: 9px;
  letter-spacing: 0.025em;
  border-radius: 4px;
}
.badge::before { width: 4px; height: 4px; }

/* ── 6. Celle vuote (trattini) — quasi invisibili ── */
.cell-empty { color: #D5DCE8; }

/* ── 7. Gerarchia colonne: dati secondari più recessi ── */
.inv-table td.td-muted { color: #B0BAC9; font-size: 11.5px; }
.inv-table td.td-date  { color: #B8C2D0; font-size: 11px; }

/* ── 8. Dati finanziari: più peso — sono il motivo del prodotto ── */
.inv-table td.td-bold  { font-weight: 700; color: var(--text); }

/* ── 9. DC-2: no accent bars — status communicated by badge only ── */

/* ── 10. Shadow col-sticky-2 — meno invadente ── */
.col-sticky-2 { box-shadow: 2px 0 10px -3px rgba(0,0,0,0.07); }

/* ── 11. Tab count badge → pill perfetta ── */
.tab-count {
  border-radius: 99px;
  min-width: 18px;
  height: 15px;
  line-height: 15px;
  font-size: 9px;
  padding: 0 5px;
}

/* ── 12. Toolbar: meno margine, ritmo più stretto ── */
.inv-toolbar { margin-bottom: 8px; }
.cat-filter  { margin-bottom: 10px; gap: 4px; }
.chip        { padding: 3px 10px; font-size: 11.5px; border-radius: 6px; }

/* ── 13. Page header — verticalmente più compatto ── */
.page-header   { margin-bottom: 16px; }
.page-title    { font-size: 18px; letter-spacing: -0.04em; }
.page-sub      { font-size: 11px; margin-top: 1px; }

/* ── 14. Sidebar active: leggermente meno saturo ── */
.nav-item.active { background: rgba(110,86,207,0.10); }

/* ── 15. Table container: radius più coerente col sistema ── */
.inv-table-container { border-radius: var(--r-lg); }

/* ── 16. Campo picker (field popover) — item pills più leggibili ── */
.status-pick-btn {
  font-size: 12px;
  font-weight: 500;
  padding: 6px 14px;
  text-align: left;
  border-radius: 7px;
}
.status-pick-btn.current { outline: 1.5px solid rgba(0,0,0,0.22); outline-offset: 1px; }

/* ── 17. Profitto: margin-pill — più spazio, più leggibile ── */
.margin-pill { padding: 2px 9px; font-size: 11.5px; }

/* ── 19. Publish toggle button inside status cell ──
   (la regola `.col-sticky-2 { left: 202px !important; }` che stava qui è
   stata rimossa il 2026-09-12: un duplicato residuo dal layout pre-rimozione
   colonna checkbox, mai aggiornato quando col-sticky-2 è passata a
   left:180px sopra — vinceva comunque per `!important`, causando un varco
   fra le colonne sticky con testo sottostante visibile durante lo scroll.
   Vedi DESIGN_DECISIONS.md per il dettaglio del bug.) */

.status-wrap {
  display: flex; align-items: center; gap: 5px;
}
.v-pub-btn {
  flex-shrink: 0;
  width: 16px; height: 16px;
  border: none; padding: 0; cursor: pointer; border-radius: 3px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent;
  transition: opacity 120ms, background 120ms;
}
.v-pub-on {
  color: #09B1BA;
  opacity: 1;
}
.v-pub-on:hover { background: rgba(9,177,186,0.12); }
.v-pub-off {
  color: #B0B8C8;
  opacity: 0;
}
tr:hover .v-pub-off { opacity: 1; }
.v-pub-off:hover { color: #09B1BA; background: rgba(9,177,186,0.10); }

/* cell-selected must win over row-hover even on sticky cols (hover uses !important) */
.inv-table tbody tr:hover td.cell-selected.col-sticky-1,
.inv-table tbody tr:hover td.cell-selected.col-sticky-2 {
  background: #F2F0FB !important;
}

/* ══════════════════════════════════════════════════════════════
   INVENTORY — estetica affinata
══════════════════════════════════════════════════════════════ */

/* 1. Colonna numero riga: fondo bianco */
.inv-table td.inv-row-num,
.inv-table tr:nth-child(even) td.inv-row-num,
.inv-table tr:hover td.inv-row-num,
.inv-table tr.inv-row-selected td.inv-row-num { background: #fff !important; color: #9AA5B8; border-right: 1px solid rgba(0,0,0,0.09) !important; }
.inv-table tr.inv-row-selected td.inv-row-num { color: var(--indigo) !important; font-weight: 700 !important; }
.inv-table thead th.inv-th-num { background: #fff !important; border-right: 1px solid rgba(0,0,0,0.09) !important; }

/* 2. Header: fondo bianco, meno urlato */
.inv-table th {
  background: #fff !important;
  font-size: 9px !important;
  letter-spacing: 0.07em !important;
  color: #7B87A0 !important;
  padding: 7px 12px !important;
}
.inv-table thead .col-sticky,
.inv-table thead th.col-sticky-1,
.inv-table thead th.col-sticky-2 { background: #fff !important; }

/* 3. Righe più compatte */
.inv-table td { padding: 7px 12px !important; }
.inv-table td.inv-row-num { padding: 0 4px !important; }

/* 4. Colonne secondarie quasi invisibili, note più leggibili */
.inv-table td.td-muted { color: #B8C2D0 !important; font-size: 11px !important; }
.inv-table td.td-date  { color: #C0CAD6 !important; font-size: 11px !important; }
.inv-table td.col-notes { color: #6B7280 !important; font-size: 12px !important; }

/* 5. DC-2: no accent bars — status communicated by badge only */

/* 6. Azioni sempre presenti ma discrete */
.inv-table .actions-cell { opacity: 0.22; }
.inv-table tr:hover .actions-cell { opacity: 1; }

/* ══════════════════════════════════════════════════════════════
   INVENTORY — grid lines (Google Sheets style)
══════════════════════════════════════════════════════════════ */
.inv-table th,
.inv-table td {
  /* 0.07→0.14 (2026-09-14, richiesta esplicita del proprietario: "evidenzia
     di più le righe di separazione delle celle") — griglia stile Google
     Sheets più marcata, stessa tinta (grigio neutro), solo più visibile. */
  border-right: 1px solid rgba(0,0,0,0.14);
  border-bottom: 1px solid rgba(0,0,0,0.14);
}
.inv-table th:last-child,
.inv-table td:last-child { border-right: none; }

/* ══════════════════════════════════════════════════════════════
   INVENTORY — intestazione colonne: colore chiaro coerente con l'Inventario
   stesso, non più scuro (2026-09-14, richiesta esplicita del proprietario —
   terzo giro sullo stesso elemento nella stessa sessione: prima "nero come
   la tabella nella dashboard", poi "un colore che si abbina di più al resto
   della schermata" — ancora un nero, solo diverso, non bastava — infine
   "trova proprio un colore diverso che si abbina al resto dell'inventario").
   Interpretato alla lettera: il resto della TABELLA Inventario (non solo
   "dello schermo" in astratto) è chiaro — righe bianche/grigio chiarissimo
   alternate, testo scuro, badge pastello. Un'intestazione scura, qualunque
   nero si scegliesse, restava sempre un corpo estraneo lì. Sostituita con
   `var(--table-head)` (#EFF1F9), il token che esiste apposta per questo
   ("Table header — distinct from row surface", definito in cima al file) —
   mai usato qui perché nel frattempo l'header era stato spostato al bianco
   puro poi al nero, ma è letteralmente il colore pensato per un'intestazione
   di tabella chiara in questo design system. Testo tornato a `--muted`,
   bordi a un grigio scuro leggero coerente con le altre righe della
   tabella (non più i token --dk-* pensati per sfondi scuri). !important
   necessario per vincere sulle regole precedenti ("Header: fondo bianco,
   meno urlato" e le varianti sticky, tutte a loro volta !important). Le
   colonne "congelate" (Stato/Nome oggetto) e la colonna numero riga
   condividono la stessa riga di intestazione: devono cambiare colore
   insieme, altrimenti l'intestazione risulterebbe a chiazze. Testo del
   titolo anche leggermente ingrandito nello stesso giro (richiesta
   esplicita, "rendi le scritte dei titoli leggermente più grosse"):
   9px→10px. ── */
.inv-table th {
  /* Quarto giro sullo stesso elemento nella stessa sessione (2026-09-14):
     chiaro (#EFF1F9) → più scuro ma ancora chiaro (#D8DCEA) → di nuovo nero
     come la tabella Storico della Dashboard, richiesta esplicita e diretta
     del proprietario ("cambia il colore in nero come quello della
     dashboard e le scritte in bianco") dopo aver verificato dal vivo il
     grigio chiaro di §148. Stessi token di §146 (--dk-surface-2), ma testo
     stavolta `--dk-text` (bianco al 92%, "bianco" richiesto alla lettera)
     invece di `--dk-text-2` (bianco al 55%, troppo tenue) usato in §146. */
  background: var(--dk-surface-2) !important;
  color: var(--dk-text) !important;
  font-size: 10px !important;
  border-bottom-color: var(--dk-border) !important;
  border-right-color: var(--dk-border) !important;
}
.inv-table thead .col-sticky,
.inv-table thead th.col-sticky-1,
.inv-table thead th.col-sticky-2,
.inv-table thead th.inv-th-num {
  background: var(--dk-surface-2) !important;
  border-right-color: var(--dk-border) !important;
}
/* "Dislivello" fra le celle nere Stato/Nome oggetto (2026-09-14, segnalato
   dal proprietario con screenshot ravvicinato, confermato riproducibile con
   uno zoom estremo — non un bug di layout: `getBoundingClientRect()` dà
   bordi identici al pixel per entrambe le celle). Causa reale: sono entrambe
   `position:sticky` (restano ferme nello scroll orizzontale) e su schermi
   ad alta densità (devicePixelRatio 2, confermato) Chrome le disegna su due
   livelli grafici separati che a volte non si allineano al pixel fisico
   esatto — lascia passare una fessura larga meno di un pixel, invisibile
   prima con l'intestazione chiara, molto visibile ora col nero. Fix:
   un'ombra piena (nessuna sfumatura) estende il nero di col-sticky-1 di 1px
   oltre il proprio bordo destro, ricoprendo l'eventuale fessura con lo
   stesso colore della cella adiacente — innocuo perché entrambe le celle
   sono comunque nere identiche, non introduce un bordo/ombra visibile. */
.inv-table thead th.col-sticky-1 {
  box-shadow: 1px 0 0 0 var(--dk-surface-2) !important;
}
/* Colonna numero riga esclusa dal nero dell'intestazione (2026-09-14,
   richiesta esplicita del proprietario: "la prima colonna deve essere
   tutta dello stesso colore, anche la cella del titolo con il quadrato,
   quindi quella escludila dalla colorazione nera") — le sue celle nel
   corpo sono bianche fin da DC-129 (mai cambiate in questa sessione), ma
   la cella di intestazione (checkbox "seleziona tutto") seguiva ancora la
   regola generale sopra e diventava nera come il resto della riga,
   spezzando l'unico colore dell'intera colonna. Dichiarata DOPO le regole
   nere per vincere sull'ordine di sorgente, oltre che per specificità. */
.inv-table thead th.inv-th-num {
  background: #fff !important;
  color: #9AA5B8 !important;
  border-right-color: rgba(0,0,0,0.14) !important;
}

/* Testo delle colonne secondarie (Categoria/Data acq./Fonte acq./Data vend.)
   più marcato (2026-09-14, richiesta esplicita del proprietario, con
   screenshot di riferimento: "rendi anche le scritte dentro alla tabella
   più marcate... mi riferisco a queste e quelle con questo stile"). Erano
   state deliberatamente sbiadite (#B8C2D0/#C0CAD6, "colonne secondarie
   quasi invisibili" — un'altra sessione, altro obiettivo) fino a diventare
   poco leggibili. --muted (stesso grigio già usato per le etichette
   dell'intestazione qui sopra) è più scuro ma resta comunque secondario
   rispetto al testo principale nero/bold delle altre colonne — non
   promosso al primo piano, solo reso leggibile. Peso font portato a 500
   (era 400/normale) per lo stesso motivo, "marcate" inteso anche come
   spessore non solo come colore. */
.inv-table td.td-muted,
.inv-table td.td-date {
  color: var(--muted) !important;
  font-weight: 500 !important;
}

/* ══════════════════════════════════════════════════════════════
   REFUND POPOVER
══════════════════════════════════════════════════════════════ */
.refund-popover {
  position: fixed; bottom: 72px; left: 50%;
  transform: translateX(-50%);
  width: 360px; max-width: 95vw;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-modal);
  padding: 16px;
  z-index: 92;
  animation: panel-fade-in 120ms var(--ease-out) both;
}
.refund-header {
  font-size: 12px; font-weight: 700; color: var(--text);
  margin-bottom: 12px; letter-spacing: -0.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.refund-input-row {
  display: flex; align-items: center; gap: 8px; margin-bottom: 12px;
}
.refund-input-row label {
  font-size: 11px; font-weight: 600; color: var(--muted);
  text-transform: uppercase; letter-spacing: .06em; flex-shrink: 0;
}
.refund-input-row input {
  flex: 1; padding: 7px 10px;
  border: 1.5px solid var(--indigo); border-radius: var(--r-sm);
  font-size: 14px; font-weight: 700; font-family: inherit;
  color: var(--text); outline: none; background: var(--surface);
  box-shadow: 0 0 0 3px rgba(110,86,207,0.10);
  text-align: right; width: 0;
}
.refund-currency { font-size: 13px; font-weight: 600; color: var(--muted); flex-shrink: 0; }

.refund-mode-row { display: flex; gap: 6px; margin-bottom: 12px; }
.refund-mode-btn {
  flex: 1; padding: 6px 8px; border-radius: var(--r-sm);
  border: 1px solid var(--border); background: var(--surface-2);
  color: var(--muted); font-size: 11.5px; font-weight: 600;
  cursor: pointer; transition: all var(--dur-fast) var(--ease-out);
}
.refund-mode-btn:hover { color: var(--text); }
.refund-mode-btn.active {
  background: var(--indigo); border-color: var(--indigo); color: #fff;
}

#refund-preview { margin-bottom: 12px; display: flex; flex-direction: column; gap: 5px; }
.refund-preview-row {
  display: flex; justify-content: space-between; align-items: center;
  font-size: 11.5px; color: var(--text-2); gap: 8px;
}
.refund-preview-name {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1;
  color: var(--muted);
}
.refund-preview-val { flex-shrink: 0; font-variant-numeric: tabular-nums; }
.refund-preview-val strong { color: var(--text); }

.refund-footer {
  display: flex; gap: 8px; justify-content: flex-end;
  padding-top: 10px; border-top: 1px solid var(--border);
}

.children-popover {
  position: fixed; display: none;
  width: 260px; max-width: 90vw; max-height: 280px; overflow-y: auto;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); box-shadow: var(--shadow-modal);
  padding: 8px; z-index: 95;
  animation: panel-fade-in 120ms var(--ease-out) both;
}
.children-popover-header {
  font-size: 10.5px; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: .05em;
  padding: 4px 6px 8px;
}
.children-popover-row {
  display: flex; align-items: center; gap: 8px;
  padding: 6px; border-radius: var(--r-sm);
  cursor: pointer; transition: background var(--dur-fast) var(--ease-out);
}
.children-popover-row:hover { background: var(--surface-2); }
.children-popover-name {
  flex: 1; font-size: 12px; font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.children-popover-cost {
  font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; flex-shrink: 0;
}

/* ══════════════════════════════════════════════════════════════
   MISSING PRICES MODAL (Google-Sheets style editor)
══════════════════════════════════════════════════════════════ */
.mp-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.mp-table thead tr { position: sticky; top: 0; z-index: 2; }
.mp-table th {
  background: var(--table-head); color: var(--subtle);
  font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .09em;
  padding: 8px 10px; border-bottom: 1.5px solid rgba(0,0,0,0.08);
  white-space: nowrap; user-select: none; text-align: left;
}
.mp-th-num  { width: 38px; text-align: center; color: var(--subtle); }
.mp-th-cb   { width: 32px; text-align: center; }
.mp-th-price { width: 150px; }
.mp-table td {
  padding: 0; border-bottom: 1px solid rgba(0,0,0,0.05);
  vertical-align: middle; background: #fff;
}
.mp-table tr:nth-child(even) td { background: #F3F3F3; }
.mp-table tr.mp-selected td { background: #E8EEFF !important; }
.mp-table tr.mp-selected td.mp-num { color: var(--indigo); font-weight: 700; }

.mp-num {
  text-align: center; font-size: 11px; color: var(--subtle);
  padding: 9px 6px; user-select: none; cursor: pointer;
  border-right: 1px solid rgba(0,0,0,0.05);
}
.mp-cb-cell { text-align: center; padding: 9px 6px; }
.mp-cell { padding: 9px 10px; }
.mp-cell-price {
  text-align: right; padding: 2px 4px;
  cursor: cell; position: relative;
}
.mp-cell-price:hover { background: rgba(110,86,207,0.06) !important; }
.mp-cell-price.mp-editing {
  padding: 0;
  outline: 2px solid var(--indigo);
  outline-offset: -1px;
  background: #fff !important;
  z-index: 1;
}
.mp-price-display { padding: 7px 10px; font-weight: 600; color: var(--text); text-align: right; }
.mp-price-display.empty { color: var(--subtle); font-weight: 400; }
.mp-price-input {
  width: 100%; padding: 7px 10px; border: none; outline: none;
  background: transparent; font-size: 12.5px; font-family: inherit;
  font-weight: 600; color: var(--text); text-align: right;
}
.mp-bulk-input {
  padding: 6px 12px; border: 1px solid var(--border); border-radius: var(--r-full);
  font-size: 12.5px; font-family: inherit; outline: none; width: 220px;
}
.mp-bulk-input:focus { border-color: var(--indigo); box-shadow: 0 0 0 3px rgba(110,86,207,0.10); }

/* ══════════════════════════════════════════════════════════════
   KPI REDESIGN — meno rumore visivo, gerarchia più chiara
   Principio: il colore vale solo quando è raro.
══════════════════════════════════════════════════════════════ */

/* 1. Unifica accent stripe: da 7 colori a 1 (brand viola) */
.kpi-profit::before,
.kpi-sales::before,
.kpi-margin::before,
.kpi-stock::before,
.kpi-shelf::before,
.kpi-stalled::before,
.kpi-forecast::before {
  background: linear-gradient(90deg, var(--indigo), var(--violet));
  height: 2px;
}

/* 2. Icon box: niente background né bordo — silhouette neutra */
.kpi-icon {
  width: 26px;
  height: 26px;
  background: none !important;
  border: none !important;
  color: var(--faint) !important;
  border-radius: 0;
}
.kpi-icon svg { width: 18px; height: 18px; stroke-width: 1.75; }

/* 3. Valore compatto e leggibile */
.kpi-value {
  font-size: 28px;
  letter-spacing: -0.03em;
  font-weight: 700;
  margin-bottom: 6px;
}

/* 4. Label +1px per leggibilità */
.kpi-label {
  font-size: 11px;
  letter-spacing: 0.08em;
  margin-bottom: 8px;
}

/* 5. Trend: solo testo, niente pill colorata */
.kpi-trend {
  background: none !important;
  padding: 0 !important;
  border-radius: 0 !important;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0;
}
.kpi-trend.up   { color: var(--green); }
.kpi-trend.down { color: var(--red); }
.kpi-trend.flat { color: var(--muted); }

/* 6. Sparkline meno invadente */
.kpi-sparkline { opacity: 0.35; }

/* 7. Spaziatura griglia */
.kpi-grid { gap: 16px; margin-bottom: 28px; }
.kpi-card { padding: 24px 24px 20px; }
.kpi-header { margin-bottom: 12px; }

/* ── Dashboard charts: altezza ridotta, meno spazio sprecato ── */
.chart-card { padding: 20px 20px 14px; }
.chart-title {
  font-size: 10px;
  letter-spacing: 0.12em;
  margin-bottom: 14px;
  color: var(--subtle);
}

/* ── Mini counts: ritmo più stretto ── */
.mini-counts { margin-bottom: 16px; gap: 6px; }
.mini-count { font-size: 11.5px; padding: 4px 11px 4px 9px; }

/* ── Dash header: meno margine ── */
.dash-header { margin-bottom: 20px; }

/* ══════════════════════════════════════════════════════════════
   INVENTORY — colore alternato su tutta la riga (sticky incluse)
══════════════════════════════════════════════════════════════ */

/* Ripristina striping su celle normali */
.inv-table tbody tr:nth-child(even) td           { background: #F3F3F3; }

/* Sticky cells seguono lo stesso colore alternato */
.inv-table tbody td.col-sticky,
.inv-table tbody td.inv-row-num                  { background: #ffffff; }
.inv-table tbody tr:nth-child(even) td.col-sticky,
.inv-table tbody tr:nth-child(even) td.inv-row-num { background: #F3F3F3; }

/* Hover neutro su tutta la riga */
.inv-table tbody tr:hover td                     { background: #E8E8E8 !important; }
.inv-table tbody tr:hover td.col-sticky,
.inv-table tbody tr:hover td.inv-row-num         { background: #E0E0E0 !important; }

/* Selezione riga */
.inv-table tbody tr.inv-row-selected td              { background: #E8EEFF !important; }
.inv-table tbody tr.inv-row-selected td.inv-row-num  { background: #C7D0FF !important; color: var(--indigo); font-weight: 700; }
.inv-table tbody tr.inv-row-selected td.col-sticky   { background: #EEF0FF !important; }

/* Search clear button */
.search-clear-btn {
  position: absolute; right: 9px; top: 50%; transform: translateY(-50%);
  background: none; border: none; cursor: pointer; padding: 0;
  width: 15px; height: 15px; border-radius: 50%;
  font-size: 13px; line-height: 1;
  color: #B0B8C8;
  display: none; align-items: center; justify-content: center;
  transition: color 0.15s;
}
.search-clear-btn:hover { color: var(--dk-text); }
.search-clear-btn.visible { display: flex; }
.topbar-search input:not(:placeholder-shown),
.inv-search input:not(:placeholder-shown) { padding-right: 28px !important; }

/* ══════════════════════════════════════════════════════════════
   RESTYLING 2026 — overrides
══════════════════════════════════════════════════════════════ */

/* ── 1. SIDEBAR LIGHT ───────────────────────────────────────── */
/* border-right rimosso (2026-09-12): era questa la vera fonte della linea
   verticale ancora visibile dopo §127 — quella correzione aveva tolto il
   border-right dalla regola base di .sidebar (style.css riga ~232), ma
   questa seconda dichiarazione, con !important e più in basso nel file,
   restava comunque attiva e vinceva. "Non deve esserci una separazione
   visibile" (richiesta esplicita del proprietario) vale anche qui. */
.sidebar {
  background: #FAFAFA !important;
}
.nav-item {
  color: #6B7280 !important;
}
.nav-item:hover {
  background: #F3F4F6 !important;
  color: var(--text) !important;
}
.nav-item.active {
  background: rgba(110,86,207,0.10) !important;
  color: var(--indigo) !important;
  font-weight: 600 !important;
}
.nav-item.active::after {
  background: var(--indigo) !important;
  box-shadow: none !important;
}
.nav-icon-wrap {
  color: #9CA3AF !important;
}
.nav-item:hover .nav-icon-wrap {
  color: #374151 !important;
}
.nav-item.active .nav-icon-wrap {
  color: var(--indigo) !important;
}
/* ── 2. KPI CARD — pulizia ──────────────────────────────────── */
.kpi-card::before { display: none !important; }
.kpi-card {
  border: 1px solid var(--border-hairline) !important;
  border-radius: 10px !important;
  box-shadow: var(--elev-1) !important;
  transition: box-shadow 180ms ease, transform 180ms ease !important;
}
.kpi-card:hover {
  box-shadow: var(--elev-2) !important;
  transform: translateY(-1px) !important;
}
.kpi-sparkline { display: none !important; }

/* ── 3. GRIGLIA KPI — secondarie compatte (i due hero non sono più
   in griglia: ognuno da solo nella propria riga, vedi DC-64) ─── */
.kpi-grid { display: block !important; }

.kpi-grid-secondary {
  display: grid !important;
  grid-template-columns: repeat(5, 1fr) !important;
  gap: 14px !important;
  margin-bottom: 24px !important;
}
.kpi-grid-secondary .kpi-card {
  padding: 18px 18px 16px !important;
}
.kpi-grid-secondary .kpi-value {
  font-size: 22px !important;
  font-weight: 700 !important;
  letter-spacing: -0.03em !important;
  margin-bottom: 4px !important;
  line-height: 1.1 !important;
}
.kpi-grid-secondary .kpi-label {
  font-size: 10px !important;
  letter-spacing: 0.04em !important;
  margin-bottom: 4px !important;
  text-transform: none !important;
  font-weight: 600 !important;
  color: #9CA3AF !important;
}
.kpi-grid-secondary .kpi-sub {
  font-size: 11px !important;
}

/* Override general kpi-value from the previous redesign block */
.kpi-value {
  font-size: 28px !important;
  letter-spacing: -0.03em !important;
  font-weight: 700 !important;
  margin-bottom: 6px !important;
}

/* ── 4. TREND BADGE — grigio neutro per down ────────────────── */
.kpi-trend.down {
  background: none !important;
  color: #6B7280 !important;
  padding: 0 !important;
  border-radius: 0 !important;
}
.kpi-trend.up {
  background: none !important;
  padding: 0 !important;
  border-radius: 0 !important;
}
.kpi-trend.flat {
  background: none !important;
  padding: 0 !important;
  border-radius: 0 !important;
}
/* Rosso solo per stalled DAVVERO critico — SOLO se stalled_count > 0
   (classe .is-critical aggiunta via JS in loadDashboard(), DC-64),
   mai di default: prima era incondizionato sulla sola classe
   .kpi-stalled, quindi rosso anche a "0 articoli fermi". */
.kpi-stalled.is-critical .kpi-value { color: #DC2626; }
.kpi-stalled.is-critical { border-color: rgba(239,68,68,0.30) !important; }

/* ── 4b. Badge "mese in corso" ──────────────────────────────── */
.badge-in-corso {
  display: inline-block;
  background: rgba(110,86,207,0.10);
  color: var(--indigo);
  font-size: 10px;
  font-weight: 600;
  padding: 1px 7px;
  border-radius: 999px;
  letter-spacing: 0.02em;
  vertical-align: middle;
  margin-left: 6px;
}

/* ── 6. CHARTS — palette unificata ─────────────────────────── */
.chart-card {
  border: 1px solid var(--border-hairline) !important;
  border-radius: 10px !important;
  box-shadow: var(--elev-1) !important;
}
.chart-title {
  font-size: 11px !important;
  letter-spacing: 0.04em !important;
  text-transform: none !important;
  font-weight: 600 !important;
  color: #6B7280 !important;
  margin-bottom: 16px !important;
}

/* ── 7. TIPOGRAFIA — letter-spacing ridotto ─────────────────── */
.kpi-label {
  letter-spacing: 0.04em !important;
  text-transform: none !important;
  font-weight: 600 !important;
}

@media (max-width: 1280px) {
  .kpi-grid-secondary { grid-template-columns: repeat(3, 1fr) !important; }
}
@media (max-width: 900px) {
  .kpi-grid-secondary { grid-template-columns: repeat(2, 1fr) !important; }
}

/* ══════════════════════════════════════════════════════════════
   DARK PREMIUM THEME — overrides everything above
══════════════════════════════════════════════════════════════ */

/* ── Token ridefinition ─────────────────────────────────────── */
:root {
  --dk-bg:         #0B0B12;
  --dk-surface:    #14141F;
  --dk-surface-2:  #1C1C2A;
  --dk-border:     rgba(255,255,255,0.06);
  --dk-border-act: rgba(139,124,246,0.35);
  --dk-violet:     #8B7CF6;
  --dk-violet-2:   #A78BFA;
  --dk-glow:       rgba(139,124,246,0.15);
  --dk-glow-str:   rgba(139,124,246,0.28);
  --dk-text:       rgba(255,255,255,0.92);
  --dk-text-2:     rgba(255,255,255,0.55);
  --dk-label:      rgba(255,255,255,0.38);
  /* Variante AA per label a font-size <18px (badge, KPI label, sidebar):
     --dk-label a 0.38 scende sotto 4.5:1 su testo piccolo (~3.5:1). Non tocca
     --dk-label (valore di design DC-15/16 usato altrove) — vedi DESIGN_DECISIONS §15/16. */
  --dk-label-strong: rgba(255,255,255,0.48);
  --dk-green:      #34D399;
  --dk-amber:      #FBBF24;
  --dk-blue:       #60A5FA;
  --dk-red:        #F87171;
  --dk-teal:       #2DD4BF;
}

/* ── 1. Sfondo app — chiaro (sistema premium, DC-59, 2026-07-20) ─
   Sostituisce lo sfondo dark globale: sidebar/topbar/canvas passano
   al sistema chiaro. Le pagine non ancora migrate (Dashboard,
   Inventario, Agente Acquisto, Impostazioni) restano scure di per
   sé — le loro card (.card/.kpi-card/.chart-card, sotto) hanno
   sfondo/bordo dark propri e ora galleggiano su un canvas chiaro
   invece che dark: stesso pattern transitorio già accettato per
   Tasse nella direzione opposta (isola chiara in canvas scuro),
   fino alla migrazione di ciascuna pagina. */
body {
  background: var(--bg-app) !important;
  background-image: none !important;
  color: var(--text) !important;
}

/* ── 2. Sidebar — nessuna regola qui: il layer "RESTYLING 2026 —
   SIDEBAR LIGHT" (style.css:2730) è già il sidebar chiaro corretto
   per il nuovo sistema (stesso #FAFAFA, stesso principio di stato
   attivo viola tenue) e non viene più sovrascritto da qui. */

/* ── 3. Topbar — rimossa dall'HTML (2026-09-12), vedi nota più sopra
   nella sezione base "TOP BAR". ── */

/* ── 4. Card base ───────────────────────────────────────────── */
/* .card rimossa da qui 2026-07-20 (DC-61): con Agente Acquisto/
   Impostazioni/Feed Live/Annunci migrate in questo stesso passo,
   nessuna pagina ha più bisogno di .card scura — torna al proprio
   sfondo chiaro (var(--surface), style.css:752). */
.dash-empty-state {
  background: var(--surface) !important;
  border-color: var(--border) !important;
  color: var(--text-2) !important;
  padding: 64px 20px !important;
}
.dash-empty-state p { margin: 0 0 18px; font-size: 14px; }
/* .kpi-card:hover rimosso 2026-07-20 (DC-60): ridondante, la versione
   chiara corretta è già in style.css:2789 (RESTYLING 2026). */

/* Card hero — chiara (DC-60): sostituisce il glassmorphism scuro con
   la scala di elevazione + il wash viola tenue di DC-58 dietro il
   numero, reinterpretazione chiara del glow dark. */
.kpi-hero {
  box-shadow: var(--elev-1) !important;
}
/* Velo d'angolo dinamico (richiesta esplicita del proprietario, 2026-09-11):
   prende il colore del badge "vs mese prec." (verde se positivo, rosso se
   negativo) invece dell'identità statica viola/teal di ciascuna card —
   supera DC-22b/DC-58 su questo punto specifico. --trend-wash è impostata
   via JS in setBadge() (app.js); il fallback (nessun trend calcolabile,
   es. mese di riferimento assente) resta il wash originale della card, non
   un colore neutro. Posizione unificata in alto a destra per entrambe (era
   centrata per Profitto, in angolo per Fondi immobilizzati). */
.kpi-profit.kpi-hero {
  background-image: radial-gradient(ellipse 70% 60% at 100% 0%, var(--trend-wash, rgba(110,86,207,0.04)) 0%, transparent 70%) !important;
  background-repeat: no-repeat !important;
  border-color: rgba(110,86,207,0.22) !important;
  box-shadow: var(--elev-2) !important;
}
.kpi-profit.kpi-hero:hover {
  box-shadow: var(--elev-3) !important;
}

/* Card Fondi immobilizzati: comprimaria, declinata sul teal — mai intercambiabile con
   la card Profitto (vedi audit/DESIGN_DECISIONS.md §35). Bordo/wash più
   tenue del viola della card protagonista, coerente col principio
   "un solo elemento domina" anche nella versione chiara. */
.kpi-stock.kpi-hero {
  background-image: radial-gradient(ellipse 70% 60% at 100% 0%, var(--trend-wash, rgba(6,182,212,0.05)) 0%, transparent 70%) !important;
  background-repeat: no-repeat !important;
  border-color: rgba(6,182,212,0.18) !important;
  box-shadow: var(--elev-1) !important;
}
.kpi-stock.kpi-hero:hover {
  box-shadow: var(--elev-2) !important;
}

/* ── 5. Testi ───────────────────────────────────────────────── */
/* .page-title/.page-sub/h1 rimossi da qui 2026-07-20 (DC-59): sono
   sempre in testa pagina, direttamente sul canvas — ora chiaro
   globalmente — mai dentro una card dark, quindi tornano al colore
   base (var(--text)/var(--muted), style.css:569-575), leggibile sul
   nuovo sfondo chiaro. h2 resta gestito da `.section-header h2` qui
   sotto: è sempre dentro una card (ancora dark finché non migrata),
   quindi mantiene il proprio override. */
/* .kpi-label/.kpi-sub rimossi da qui 2026-07-20 (DC-60): ridondanti,
   le versioni chiare corrette sono già in style.css:675/689. */
/* .kpi-stock-count rimosso 2026-09-11: la pillola "N articoli" nell'header
   di Fondi immobilizzati è stata sostituita dal badge di variazione %
   vs mese precedente (stesso .kpi-trend di Profitto/Vendite/Margine),
   richiesta esplicita del proprietario — nessun riferimento rimasto. */

/* Label + dot teal della card Fondi immobilizzati — identità distinta dal Profitto */
.kpi-stock .kpi-label {
  color: var(--teal-text) !important;
  display: flex;
  align-items: center;
  gap: 6px;
}
.kpi-teal-dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--teal);
  box-shadow: 0 0 6px rgba(6,182,212,0.5);
  flex-shrink: 0;
}

/* Label + dot viola della card Profitto — speculare al trattamento teal,
   la protagonista deve restare riconoscibile quanto la comprimaria
   (vedi audit/DESIGN_DECISIONS.md §22b). */
.kpi-profit .kpi-label {
  color: var(--indigo) !important;
  display: flex;
  align-items: center;
  gap: 6px;
}
.kpi-violet-dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--indigo);
  box-shadow: 0 0 6px rgba(110,86,207,0.5);
  flex-shrink: 0;
}

/* ── Numeri hero — chiari (DC-60), niente più gradiente metallico:
   sul bianco il numero grande e scuro è già protagonista di suo,
   il wash viola/teal dietro la card fa il resto. ─────────────── */
.kpi-hero .kpi-value {
  color: var(--text) !important;
  font-size: 40px !important;
  font-weight: 800 !important;
  letter-spacing: -0.045em !important;
}
/* Numero critico: rosso — vedi .kpi-stalled.is-critical .kpi-value,
   style.css:~2895 (DC-64), condizionale via JS, non più incondizionato. */

/* ── Layout hero card interno ──────────────────────────────── */
.kpi-hero-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 6px;
}
/* ── Profitto e Fondi immobilizzati — affiancati, stesso livello
   (DESIGN_DECISIONS.md §96, richiesta esplicita del proprietario: supera
   DC-22b/DC-64, che volevano il Profitto sempre da solo e leggermente
   dominante. Qui le due card sono deliberatamente intercambiabili per
   struttura e dimensione — solo colore/etichetta le distinguono. ── */
.dash-hero-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-bottom: 28px;
  /* align-items:start (non lo stretch di default) — due card di altezza
     naturale molto diversa (es. tabella Storico §109 accanto al grafico
     Categorie §108) non devono stirarsi a vicenda: lo stretch lascerebbe
     la card più corta con vuoto morto sotto, stesso bug già visto in
     DESIGN_DECISIONS.md §103. Innocuo per Profitto/Fondi immobilizzati,
     già della stessa altezza per costruzione. */
  align-items: start;
}
.kpi-hero-split {
  padding: 28px 28px 4px 28px !important;
  display: flex;
  flex-direction: column;
}
/* Ancora sotto il margine di base (6px) di .kpi-hero-top — 4px qui, ultimo
   di una serie di tentativi (20/16/10/8/6px) verificati dal proprietario su
   screenshot reali annotati. Vedi DESIGN_DECISIONS.md §97-98 per il perché
   i calcoli teorici su chartArea/ink del canvas erano fuorvianti. */
.kpi-hero-split .kpi-hero-top { margin-bottom: 3px; }
.kpi-hero-split .kpi-value {
  font-size: 32px !important;
  letter-spacing: -0.03em !important;
  font-variant-numeric: tabular-nums !important;
  margin-bottom: 8px !important;
}
.kpi-hero-split .kpi-sparkline-hero { height: 300px !important; }
@media (max-width: 1024px) {
  .dash-hero-row { grid-template-columns: 1fr; }
}
/* Badge "vs mese prec." di Profitto/Fondi immobilizzati — rosso per il calo,
   non il grigio neutro globale di DC-11 (style.css:3054, resta invariato
   ovunque altro, es. Vendite/Margine in "Come sto andando"): richiesta
   esplicita del proprietario di uniformare questi due badge allo stesso
   schema rosso/verde già usato nella striscia riepilogo sopra (DC-94).
   Scoped a .kpi-hero-split per non toccare le altre card. */
.kpi-hero-split .kpi-trend.down { color: var(--red) !important; }
.kpi-hero-split .kpi-trend.up   { color: var(--green) !important; }

/* ── 0. Riepilogo numeri principali — striscia sopra la card Profitto
   (DESIGN_DECISIONS.md §90-92). Una card unica con celle separate da un
   sottile bordo verticale (non 7 .kpi-card individuali, versione provata e
   poi scartata dal proprietario — tornati a questa). Griglia responsive
   invece di una riga rigida: con valori in € che possono crescere molto su
   filtri "tutti i mesi/anni", forzare 7 colonne su schermi laptop standard
   rischierebbe di ammassare il contenuto — meglio andare a capo su 4/3/2
   colonne che tagliare o rimpicciolire i numeri fino a renderli
   illeggibili. ── */
.dash-summary-section { margin-top: 0; margin-bottom: 20px; }
/* Sfondo scuro deliberato (richiesta esplicita del proprietario, DC-93) —
   unica eccezione "dark chrome" della Dashboard chiara insieme al toast
   (DC-24, style.css:~2454): stessi token --dk-* già usati lì, non un nuovo
   colore inventato, per restare "elegante" perché coerente con l'unico
   altro elemento scuro già presente nell'app, non un'aggiunta isolata. */
.dash-summary-strip {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 20px;
  padding: 20px 24px !important;
  background: var(--dk-surface);
  border: 1px solid var(--dk-border);
  box-shadow: 0 4px 20px rgba(0,0,0,0.20), 0 1px 0 rgba(255,255,255,0.04) inset;
}
.dash-summary-strip .kpi-label { color: var(--dk-text-2) !important; }
.dash-summary-cell {
  min-width: 0;
  padding-left: 18px;
  border-left: 1px solid var(--dk-border);
}
.dash-summary-cell:first-child { border-left: none; padding-left: 0; }
.dash-summary-value {
  font-size: 21px; font-weight: 800; letter-spacing: -0.02em;
  color: var(--dk-text); margin-top: 4px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Riga di confronto "+x% • mese anno" — una sola riga (non più due
   impilate), costruita interamente in JS (renderSummaryStrip()) perché mix
   di span colorato (percentuale) + testo neutro (mese). Vuota quando manca
   lo storico (es. Fatturato Previsto, DESIGN_DECISIONS.md §94) non lascia
   un buco visivo grazie a :empty. */
.dash-summary-sub {
  font-size: 11.5px; font-weight: 600; color: var(--dk-label);
  margin-top: 6px;
  font-variant-numeric: tabular-nums;
}
.dash-summary-sub:empty { display: none; }
.dash-summary-sub .dash-summary-delta { font-weight: 700; }
.dash-summary-sub .dash-summary-delta.pos { color: var(--green); }
.dash-summary-sub .dash-summary-delta.neg { color: var(--red); }
.dash-summary-sub .dash-summary-delta.flat { color: var(--dk-text-2); }
@media (max-width: 1400px) {
  .dash-summary-strip { grid-template-columns: repeat(4, 1fr); row-gap: 18px; }
  .dash-summary-cell { border-left: none; padding-left: 0; }
}
@media (max-width: 720px) {
  .dash-summary-strip { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 480px) {
  .dash-summary-strip { grid-template-columns: repeat(2, 1fr); }
}

/* 3-4. "Come sto andando" / "Richiede attenzione": riusano lo stesso
   trattamento card di .kpi-grid-secondary (padding/valore/label già
   corretti, style.css:~2820), solo il numero di colonne cambia —
   nessun nuovo sistema di card, un raggruppamento tematico dello
   stesso livello di dettaglio. Vedi DESIGN_DECISIONS.md DC-64 per il
   perché "attenzione" è separata da "performance" (non solo visivo). */
.dash-section { margin-top: 32px; }
.dash-section-title {
  font-size: 12px; font-weight: 700; letter-spacing: var(--tracking-label);
  text-transform: uppercase; color: var(--subtle); margin-bottom: 14px;
}
/* Spostata dentro .dash-hero-row (DESIGN_DECISIONS.md §111) — una colonna
   sola, le due card impilate in verticale invece che affiancate (era
   repeat(2,1fr) quando questa sezione era a piena larghezza sotto). */
.dash-attention-col .dash-section-title { margin-bottom: 14px; }
.kpi-grid-secondary.dash-group-attention   { grid-template-columns: 1fr !important; }
#buy-opportunities { margin-top: 32px; }

/* ── 5b. Sparkline hero — base 72px, sovrascritta a 300px da
   .kpi-hero-split (Profitto/Fondi immobilizzati, DESIGN_DECISIONS.md §96).
   Nessun'altra card usa più questa classe alla dimensione base. ── */
.kpi-sparkline-hero {
  display: block !important;
  width: 100% !important;
  height: 72px !important;
  margin-top: auto;
  opacity: 1 !important;
}

/* .kpi-trend (6.), .badge-in-corso (7.), .chart-card/.chart-title (9.)
   e .dash-filters (10.) rimossi da qui 2026-07-20 (DC-60): tutti
   ridondanti, le versioni chiare corrette esistono già — trend in
   style.css:2854 (RESTYLING 2026, già coerente con DC-11: down =
   grigio neutro, non rosso), badge-in-corso in style.css:2874, chart
   in style.css:737/744, dash-filters in style.css:585. */

/* Sezioni 11-14 rimosse da qui 2026-07-20 (DC-61): notif panel
   (Nexus), opp-card, badge status e label sezione settings avevano
   già una versione chiara completa (style.css:476/1963/2169) — con
   Agente Acquisto/Impostazioni migrate in questo stesso passo,
   nessuna pagina ha più bisogno delle versioni dark qui sopra. */

/* ── 15. Scroll bar sottile — chiara (DC-61, 2026-07-20): il thumb
   bianco era pensato per canvas dark, ormai invisibile sulla quasi
   totalità dell'app chiara. Stesso principio già in uso per
   .inv-sheet (style.css:3326). */
::-webkit-scrollbar { width: 5px; height: 5px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.15); border-radius: 99px; }
::-webkit-scrollbar-thumb:hover { background: rgba(110,86,207,0.4); }

/* ══════════════════════════════════════════════════════════════
   DARK THEME REFINEMENTS — fix mirati
══════════════════════════════════════════════════════════════ */

/* Fix 1 — clip sparkline dentro la card hero */
.kpi-hero {
  overflow: hidden !important;
}

/* Fix 5 — rimosso 2026-07-20: ridipingeva un glow radiale scuro
   su `body`, in conflitto diretto col nuovo sfondo chiaro globale
   (DC-59, style.css:~102/2947). Il glow "atmosfera" resta un
   pattern valido per pagine ancora dark (Dashboard) ma va scoped
   alla pagina stessa quando verrà migrata, non più su `body`. */

/* Fix 8 — card secondarie stessa altezza */
.kpi-grid-secondary {
  align-items: stretch !important;
}
.kpi-grid-secondary .kpi-card {
  display: flex !important;
  flex-direction: column !important;
}
.kpi-grid-secondary .kpi-value {
  flex: 1 !important;
  display: flex !important;
  align-items: center !important;
}

/* Fix 7 — badge mese più largo (testo esteso) */
.badge-in-corso {
  white-space: nowrap !important;
  font-size: 10px !important;
  padding: 2px 8px !important;
}

/* Fix 9 — asse X non tagliato: padding chart bottom */
.chart-card canvas {
  padding-bottom: 2px !important;
}


/* ============================================================
   INVENTORY SHEET — foglio elevato sul dark
   ============================================================ */

/* Atmosphere radial glow */
#tab-inventory {
  position: relative;
  /* padding-bottom 52px→16px (2026-09-12, bug segnalato dal proprietario:
     "non so perché hai attivato lo scroll... non mi riferisco allo scroll
     dentro l'inventario ma fuori"). Causa: il calcolo di .inv-table-container
     (max-height: calc(100vh - 224px), vedi sotto) presumeva già un respiro
     finale di 16px invece dei 52px standard di .tab-panel.active — ma
     quel padding-bottom da 52px restava comunque applicato QUI, per
     intero, DOPO il foglio: i due valori si sommavano invece di
     sostituirsi, spingendo l'altezza totale della pagina oltre il
     viewport e attivando lo scroll esterno su .main-content (mai
     voluto — la pagina non deve scrollare, solo la tabella al suo
     interno). Portato a 16px per combaciare con l'intento reale. */
  padding-bottom: 16px;
}
#tab-inventory::before {
  content: "";
  position: absolute;
  top: -40px;
  left: 50%;
  transform: translateX(-50%);
  /* 800px fisso → min(800px,100%) (2026-09-14, bug segnalato dal
     proprietario con screenshot da telefono reale: "grosso spazio bianco
     inutile quando si scorre a destra fuori dalla tabella"). Causa: questa
     macchia decorativa (quasi invisibile, solo un velo viola all'8% di
     opacità) è larga 800px fissi indipendentemente dal contenitore — su
     un telefono (#tab-inventory ben sotto gli 800px) sporgeva ai lati per
     (800-larghezza)/2 px, e siccome nulla la clippa fra #tab-inventory e
     .main-content (che ha già il proprio overflow-x:auto implicito, stessa
     regola CSS per cui un solo asse "auto" forza anche l'altro, vedi §131),
     quello sporgere diventava scroll orizzontale reale sulla pagina, oltre
     al legittimo scroll interno della tabella — bianco perché la macchia è
     quasi invisibile. Riprodotto e confermato SOLO in un iframe a
     larghezza reale (386px, non con le classiche regole @media forzate a
     runtime su una finestra larga: lo strumento di resize disponibile in
     queste sessioni non riduce il viewport reale, quindi serviva un
     viewport genuinamente stretto per farlo comparire) — .main-content
     aveva scrollWidth 591px contro clientWidth 381px, 210px di troppo,
     quasi esattamente (800-381)/2. min(800px,100%) non supera mai la
     larghezza di #tab-inventory: stesso effetto su desktop (dove 100% è
     comunque oltre 800px), nessuno sporgere su schermi più stretti. */
  width: min(800px, 100%);
  height: 500px;
  background: radial-gradient(ellipse at center, rgba(139,124,246,0.08) 0%, transparent 65%);
  pointer-events: none;
  z-index: 0;
}
#tab-inventory > * {
  position: relative;
  z-index: 1;
}

/* The Sheet card */
.inv-sheet {
  background: #FFFFFF;
  border-radius: 16px;
  border: 1px solid rgba(255,255,255,0.08);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  /* Ombra ripristinata (2026-09-12, richiesta esplicita del proprietario:
     "rimetti l'ombra dietro l'inventario") — era stata tolta in §129
     nella stessa sessione ("un'ombra scura e pronunciata dietro l'intero
     foglio tabella"), il proprietario l'ha rivista e la rivuole. Stesso
     valore di allora, non reinventato. */
  box-shadow: 0 20px 60px -15px rgba(0,0,0,0.6), 0 0 40px rgba(139,124,246,0.06);
}

/* Sheet header — light bg, tabs + chips inside */
.inv-sheet-header {
  background: #F9FAFB;
  border-bottom: 1px solid #E5E7EB;
  padding: 12px 16px 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* Riga tab di stato + filtri (ricerca/data/lotto), spostati qui dal
   page-header (2026-09-12): .inv-toolbar è già flex/space-between/wrap,
   riusata com'era invece di scriverne una nuova; azzerato solo il suo
   margin-bottom di base (12px) perché il gap verticale lo dà già
   .inv-sheet-header (10px), altrimenti si sommavano. */
.inv-sheet-header .inv-toolbar { margin-bottom: 0; }
.inv-search-filters { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* Override tab styles for light context */
.inv-sheet-header .status-tabs {
  background: #FFFFFF;
  border: 1px solid #E5E7EB;
  box-shadow: 0 1px 2px rgba(0,0,0,0.04);
}
.inv-sheet-header .status-tab {
  color: #6B7280;
}
.inv-sheet-header .status-tab:hover {
  background: #F3F4F6;
  color: #374151;
}
.inv-sheet-header .status-tab.active {
  background: rgba(124,93,250,0.10);
  color: #5B21B6;
  box-shadow: none;
  font-weight: 600;
}
.inv-sheet-header .status-tab.active .tab-count {
  background: rgba(124,93,250,0.15);
  color: #6D28D9;
}
.inv-sheet-header .status-tab:not(.active) .tab-count {
  background: #F3F4F6;
  color: #9CA3AF;
}

/* Override chip styles for light context */
.inv-sheet-header .cat-filter {
  margin-bottom: 12px;
}
.inv-sheet-header .chip {
  background: #FFFFFF;
  border-color: #E5E7EB;
  color: #6B7280;
}
.inv-sheet-header .chip:hover {
  background: #F9FAFB;
  border-color: #D1D5DB;
  color: #374151;
}
.inv-sheet-header .chip.active {
  background: rgba(124,93,250,0.08);
  border-color: rgba(124,93,250,0.25);
  color: #5B21B6;
}

/* Table container inside sheet: reset card styling */
.inv-sheet .inv-table-container {
  border-radius: 0 !important;
  border: none !important;
  box-shadow: none !important;
  overflow-x: auto;
  overflow-y: auto;
  /* 340px→290px→260px→224px→229px (2026-09-12, stessa sessione): la riga
     comandi (.inv-cmd-bar) sopra il foglio è stata rimossa (i suoi
     bottoni sono ora nel page-header, i filtri dentro il foglio) — una
     riga in meno sopra la tabella. Il proprietario ha poi chiesto di
     estendere ULTERIORMENTE l'Inventario (densità di righe sul respiro
     estetico, essendo una pagina di utilità) — ma a 224px il
     padding-bottom di #tab-inventory (52px standard, invariato allora)
     si sommava al respiro già preventivato qui, spingendo l'altezza
     totale della pagina oltre il viewport e attivando uno scroll
     ESTERNO su .main-content mai voluto (bug segnalato dal proprietario:
     "non so perché hai attivato lo scroll... non mi riferisco allo
     scroll dentro l'inventario ma fuori"). Fix in due parti: (1)
     #tab-inventory.padding-bottom portato a 16px (sopra), non più 52,
     così il respiro finale è uno solo, non due sommati; (2) questa
     costante ricalibrata a 229px misurando dal vivo l'overhead reale
     (172.8px sopra + ~40px footer + 16px respiro ≈ 229, non 224 —
     lo scarto di 4-5px veniva da una stima imprecisa, non da un
     cambiamento voluto). Overflow di .main-content verificato a 0px
     dopo il fix, non solo "quasi zero". */
  max-height: calc(100vh - 229px);
  scrollbar-width: thin;
  scrollbar-color: rgba(0,0,0,0.2) transparent;
}
.inv-sheet .inv-table-container::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}
.inv-sheet .inv-table-container::-webkit-scrollbar-track {
  background: transparent;
}
.inv-sheet .inv-table-container::-webkit-scrollbar-thumb {
  background: rgba(0,0,0,0.18);
  border-radius: 99px;
}
.inv-sheet .inv-table-container::-webkit-scrollbar-thumb:hover {
  background: rgba(0,0,0,0.30);
}

/* Sheet footer */
.inv-sheet-footer {
  background: #F9FAFB;
  border-top: 1px solid #E5E7EB;
  padding: 10px 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
}
.inv-footer-count {
  font-size: 12px;
  color: #9CA3AF;
  font-weight: 500;
}

/* DC-1: per-view column visibility */
#inv-table.view-purchase .col-sell-date,
#inv-table.view-purchase .col-sell-price,
#inv-table.view-purchase .col-sell-platform,
#inv-table.view-purchase .col-destination,
#inv-table.view-purchase .col-shipper,
#inv-table.view-purchase .col-shipping-cost,
#inv-table.view-purchase .col-fee,
#inv-table.view-purchase .col-profit { display: none !important; }

#inv-table.view-listed .col-sell-date,
#inv-table.view-listed .col-sell-price,
#inv-table.view-listed .col-destination,
#inv-table.view-listed .col-shipper,
#inv-table.view-listed .col-shipping-cost,
#inv-table.view-listed .col-fee,
#inv-table.view-listed .col-profit { display: none !important; }

/* "In possesso" (in_transit+in_stock+listed): stesso set colonne di "listed" */
#inv-table.view-possesso .col-sell-date,
#inv-table.view-possesso .col-sell-price,
#inv-table.view-possesso .col-destination,
#inv-table.view-possesso .col-shipper,
#inv-table.view-possesso .col-shipping-cost,
#inv-table.view-possesso .col-fee,
#inv-table.view-possesso .col-profit { display: none !important; }

#inv-table.view-sold .col-purchase-date,
#inv-table.view-sold .col-purchase-source { display: none !important; }

/* Tbody micro-fade on filter change */
#inv-tbody {
  transition: opacity 150ms ease;
}
#inv-tbody.fading {
  opacity: 0;
}

/* ══════════════════════════════════════════════════════════════
   TASSE — pagina interamente chiara (redesign "wow = sollievo,
   intuitivo = sequenza di domande reali", vedi DESIGN_DECISIONS.md).
   Sostituisce il pattern "foglio su chrome scuro" (DC-54): qui il
   contenuto è chiaro end-to-end, solo sidebar/topbar restano scure
   (resto dell'app invariato). Riusa i token chiari di base definiti
   a inizio file (--text/--muted/--indigo/--surface/--border...),
   la palette "originale" dell'app oggi coperta ovunque dal tema
   dark globale — NON nuovi token, NON i token --dk-*.
══════════════════════════════════════════════════════════════ */

/* .main-content normalmente è trasparente (mostra il body scuro).
   Quando Tasse è la tab attiva, body porta la classe .tasse-light
   (impostata in app.js sul cambio tab) e l'intera area contenuto
   diventa chiara — non solo il riquadro del pannello, altrimenti
   resterebbe un bordo scuro visibile sotto contenuti corti. */
/* Micro-fix 2026-07-20: sfondo pagina su --bg-app (bianco caldo) invece
   di --surface (bianco piatto) — Tasse era rimasta bianco puro end-to-end
   per DC-57, in contrasto con la regola "mai bianco piatto ovunque" del
   nuovo sistema chiaro premium. Le superfici con bordo (.tasse2-empty-state,
   .tasse2-simple-card) restano su --surface-2, quindi il contrasto pagina/
   card è invariato — cambia solo il bianco di sfondo generico. */
body.tasse-light .main-content { background: var(--bg-app) !important; }
#tab-tasse { background: var(--bg-app) !important; }

/* 760px → 1100px (2026-09-12, richiesta esplicita del proprietario: "allarga
   anche... tasse a tutto schermo come abbiamo fatto con impostazioni e
   dashboard") — stesso tetto usato per le card di Impostazioni (§113),
   non "none": Tasse resta una colonna di lettura sequenziale (anello STATO
   + timeline + blocchi di testo), non una griglia — edge-to-edge avrebbe
   reso righe di testo e timeline assurdamente lunghe, non "più respiro". */
.tasse2-inner { max-width: 1100px; margin: 0 auto; }

/* ── Header ── */
.tasse2-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 4px; }
.tasse2-title { font-size: 22px; font-weight: 800; color: var(--text) !important; letter-spacing: var(--tracking-title); }
.tasse2-header-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; margin-top: 2px; }
.tasse2-select {
  font-size: 12.5px; font-weight: 600; color: var(--text-2); background: var(--surface);
  border: 1px solid var(--border-strong); border-radius: 8px; padding: 6px 10px; cursor: pointer;
}
.tasse2-icon-link {
  width: 32px; height: 32px; border-radius: 8px; display: flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid var(--border-strong); color: var(--muted); cursor: pointer; flex-shrink: 0;
}
.tasse2-icon-link:hover { background: var(--surface-2); color: var(--text-2); }

/* ── Empty state / regime non disponibile — varianti chiare ── */
.tasse2-empty-state, .tasse2-simple-card {
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 16px;
  padding: 44px 24px; text-align: center; margin-top: 24px;
}
.tasse2-simple-card { text-align: left; padding: 24px; }
.tasse2-empty-icon { color: var(--subtle); margin-bottom: 14px; display: flex; justify-content: center; }
.tasse2-empty-state p { font-size: 13.5px; color: var(--muted); margin-bottom: 16px; }
.tasse2-muted-note { font-size: 12.5px; color: var(--muted); margin-top: 10px; }

/* ── 1. STATO — elemento singolo e dominante ── */
.tasse2-status {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  padding: 44px 20px 38px;
}
.tasse2-ring-wrap { position: relative; width: 176px; height: 176px; margin-bottom: 26px; }
.tasse2-ring { transform: rotate(-90deg); }
.tasse2-ring-track { fill: none; stroke: var(--surface-3); stroke-width: 14; }
.tasse2-ring-progress {
  fill: none; stroke: url(#tasse2RingGrad); stroke-width: 14; stroke-linecap: round;
  transition: stroke-dashoffset .6s cubic-bezier(.4,0,.2,1);
}
.tasse2-ring-progress.overdue { stroke: var(--red); }
.tasse2-ring-center { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.tasse2-ring-pct { font-size: 34px; font-weight: 800; color: var(--text); letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
.tasse2-ring-caption { font-size: 11px; color: var(--subtle); font-weight: 700; text-transform: uppercase; letter-spacing: .06em; margin-top: 3px; }

.tasse2-status-dot-row { display: flex; align-items: flex-start; gap: 9px; max-width: 560px; }
.tasse2-status-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--green); flex-shrink: 0; margin-top: 7px; }
.tasse2-status-dot.warning { background: var(--red); }
.tasse2-status-headline { font-size: 16px; font-weight: 700; color: var(--text); line-height: 1.4; text-align: left; }
.tasse2-status-sub { font-size: 13.5px; color: var(--muted); margin-top: 10px; max-width: 520px; line-height: 1.55; }

/* ── STATO + Prossimi passi affiancati sulla stessa riga (2026-09-12,
   richiesta esplicita del proprietario) — anello ridimensionato più
   piccolo a sinistra, invece che impilati a piena larghezza uno sopra
   l'altro. ── */
.tasse2-status-row { display: flex; align-items: flex-start; gap: 40px; margin-top: 36px; }
.tasse2-status-row .tasse2-status { flex: 0 0 320px; padding: 28px 24px; }
.tasse2-status-row .tasse2-block--paired { flex: 1; min-width: 0; margin-top: 4px; }
.tasse2-status--compact .tasse2-ring-wrap { width: 150px; height: 150px; margin-bottom: 22px; }
.tasse2-status--compact .tasse2-ring { width: 150px; height: 150px; }
.tasse2-status--compact .tasse2-ring-pct { font-size: 28px; }
@media (max-width: 760px) {
  .tasse2-status-row { flex-direction: column; }
  .tasse2-status-row .tasse2-status { flex: none; width: 100%; }
}

/* ── Blocco generico (Prossimi passi, Accantonamenti) ── */
.tasse2-block { margin-top: 36px; }
.tasse2-block-title { font-size: 12px; font-weight: 700; letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--subtle); margin-bottom: 16px; }
.tasse2-block-title-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.tasse2-block-title-row .tasse2-block-title { margin-bottom: 0; }
.tasse2-link-btn { font-size: 12.5px; font-weight: 600; color: var(--indigo); background: none; border: none; cursor: pointer; padding: 0; }
.tasse2-link-btn:hover { text-decoration: underline; }

/* Corrispettivi da dichiarare — unico blocco "hero" della pagina Tasse,
   stesso trattamento della card "Profitto" in Dashboard (.kpi-profit.kpi-hero,
   style.css:3131): wash viola tenue (--hero-wash) + bordo tinto + elevazione,
   non il bordo/sfondo piatto usato altrove sulla pagina — è la card che deve
   colpire per prima l'occhio, coerente con la sua priorità (DESIGN_DECISIONS.md). */
.tasse2-block-highlight {
  background: var(--surface);
  /* Stesso velo d'angolo (non centrato) e stessa opacità della card
     Profitto in Dashboard — non var(--hero-wash) generico, che è centrato
     in alto: qui vogliamo il trattamento esatto della card hero, non solo
     "un" wash viola (2026-09-12, richiesta esplicita del proprietario). */
  background-image: radial-gradient(ellipse 70% 60% at 100% 0%, rgba(110,86,207,0.04) 0%, transparent 70%);
  background-repeat: no-repeat;
  border: 1px solid rgba(110,86,207,0.22);
  border-radius: var(--r-xl);
  padding: 22px 22px 20px;
  box-shadow: var(--elev-2);
}
/* Stesso ritmo verticale label→valore della card Profitto (.kpi-hero-top,
   margin-bottom 6px) — qui il generico .tasse2-block-title-row (16px,
   pensato per blocchi con solo un titolo) lasciava troppo spazio prima del
   valore, diverso da come appare in Dashboard. Scoped a .tasse2-block-highlight
   per non toccare le altre righe titolo+azione della pagina. */
.tasse2-block-highlight .tasse2-block-title-row { margin-bottom: 6px; }
/* Valore alla stessa dimensione della card Profitto (.kpi-hero .kpi-value,
   40px/-0.045em) — non i 34px condivisi con la percentuale dentro l'anello
   (quella resta piccola apposta, deve stare dentro un cerchio di 150px). */
.tasse2-block-highlight .tasse2-ring-pct { font-size: 40px; letter-spacing: -0.045em; }

/* Mini-riepilogo vendite normali vs Scambio a mano, dentro la card
   Corrispettivi — non un giudizio (nessun rosso/verde), solo "dentro" vs
   "fuori" dal conteggio: indigo per ciò che è conteggiato, grigio neutro
   per ciò che è escluso. */
.tasse2-corr-breakdown {
  margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 9px;
}
.tasse2-corr-row { display: flex; align-items: center; gap: 9px; font-size: 12.5px; }
.tasse2-corr-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.tasse2-corr-dot.normal { background: var(--indigo); }
.tasse2-corr-dot.excluded { background: var(--subtle); }
.tasse2-corr-row-label { flex: 1; color: var(--text-2); font-weight: 600; }
.tasse2-corr-row-note { color: var(--subtle); font-weight: 500; margin-left: 4px; }
.tasse2-corr-row-count { color: var(--muted); font-variant-numeric: tabular-nums; }
.tasse2-corr-row-amount {
  font-weight: 700; color: var(--text); min-width: 76px; text-align: right;
  font-variant-numeric: tabular-nums;
}
.tasse2-corr-row-clickable {
  cursor: pointer; margin: -4px -8px; padding: 4px 8px; border-radius: 6px;
  transition: background-color .12s ease;
}
.tasse2-corr-row-clickable:hover { background: var(--surface-2); }

/* Vendite Italia / estero UE: stesse righe del blocco Corrispettivi, più
   una barra verso la soglia UE. Neutra finché lontana, ambra dall'80%,
   rossa oltre: unico punto della card che usa colore semantico. */
.tasse2-ue-breakdown { margin-top: 0; padding-top: 0; border-top: none; }
.tasse2-ue-dot-missing { background: var(--amber); }
/* Vendite recuperate: pallino distinto (teal tenue) per non confonderle
   a colpo d'occhio con quelle da inventario (indigo). */
.tasse2-corr-dot.recovered { background: var(--teal); }
#recuperate-toggle { padding-left: 0; }
.tasse2-recuperate-summary {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  margin-top: 12px; font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums;
}
.tasse2-recuperate-total { font-size: 20px; font-weight: 700; color: var(--text); letter-spacing: -0.02em; }
.tasse2-ue-threshold { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border); }
.tasse2-ue-threshold-head {
  display: flex; justify-content: space-between; gap: 12px; font-size: 12.5px;
  font-weight: 600; color: var(--text-2); margin-bottom: 8px; font-variant-numeric: tabular-nums;
}
.tasse2-ue-bar { height: 6px; border-radius: 999px; background: var(--surface-2); overflow: hidden; }
.tasse2-ue-fill { height: 100%; width: 0; border-radius: inherit; background: var(--muted); transition: width .5s ease; }
.tasse2-ue-fill.warning { background: var(--amber); }
.tasse2-ue-fill.over { background: var(--red); }
.tasse2-ue-msg { margin-top: 10px; font-size: 12.5px; line-height: 1.5; color: var(--muted); }
.tasse2-ue-msg.warning { color: var(--amber-text); }
.tasse2-ue-msg.over { color: var(--red-text); }

/* ── 2. Timeline verticale — non tabella ── */
.tasse2-timeline-row { position: relative; display: flex; gap: 16px; padding-bottom: 22px; }
.tasse2-timeline-row:last-child { padding-bottom: 0; }
.tasse2-timeline-row::before {
  content: ""; position: absolute; left: 5px; top: 15px; bottom: -7px; width: 1px; background: var(--border-strong);
}
.tasse2-timeline-row:last-child::before { display: none; }
.tasse2-timeline-dot {
  width: 11px; height: 11px; border-radius: 50%; background: var(--subtle); flex-shrink: 0; margin-top: 4px;
  position: relative; z-index: 1; box-shadow: 0 0 0 3px var(--surface);
}
.tasse2-timeline-dot.brand { background: var(--indigo); }
.tasse2-timeline-dot.overdue { background: var(--red); }
.tasse2-timeline-main { flex: 1; min-width: 0; }
.tasse2-timeline-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.tasse2-timeline-title { font-size: 14.5px; font-weight: 600; color: var(--text); }
.tasse2-timeline-row.highlighted .tasse2-timeline-title { font-weight: 700; }
.tasse2-timeline-amount { font-size: 15px; font-weight: 700; color: var(--text); white-space: nowrap; font-variant-numeric: tabular-nums; }
.tasse2-timeline-meta { font-size: 12.5px; color: var(--muted); margin-top: 4px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.tasse2-timeline-tag { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; padding: 2px 8px; border-radius: 99px; }
.tasse2-timeline-tag.overdue { background: var(--red-soft); color: var(--red-text); }
.tasse2-timeline-check { display: flex; align-items: center; gap: 6px; cursor: pointer; }
.tasse2-timeline-check input { width: auto; }
.tasse2-timeline-empty { font-size: 13px; color: var(--subtle); padding: 4px 0 0 27px; }

.tasse2-paid-toggle { font-size: 12px; font-weight: 600; color: var(--muted); background: none; border: none; cursor: pointer; padding: 12px 0 0 27px; text-align: left; }
.tasse2-paid-toggle:hover { color: var(--text-2); }
.tasse2-timeline-paid { margin-top: 12px; padding-top: 14px; border-top: 1px dashed var(--border); }

/* ── 3. Il calcolo — collassato di default, header a link, non a
   pulsante pieno: intenzionalmente basso rilievo ── */
.tasse2-collapsible { margin-top: 36px; border-top: 1px solid var(--border); padding-top: 20px; }
.tasse2-collapsible-header {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 8px;
  background: none; border: none; cursor: pointer; padding: 0;
  font-size: 13px; font-weight: 600; color: var(--indigo);
}
.tasse2-chevron { transition: transform .18s ease; flex-shrink: 0; }
.tasse2-collapsible.open .tasse2-chevron { transform: rotate(180deg); }
.tasse2-collapsible-body { display: none; margin-top: 18px; }
.tasse2-collapsible.open .tasse2-collapsible-body { display: block; }

.tasse2-list-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 13px 0; border-bottom: 1px solid var(--border); }
.tasse2-list-row:last-of-type { border-bottom: none; }
.tasse2-list-title { font-size: 13.5px; font-weight: 600; color: var(--text); }
.tasse2-list-sub { font-size: 12px; color: var(--muted); margin-top: 2px; }
.tasse2-list-amount { font-size: 14px; font-weight: 700; color: var(--text-2); white-space: nowrap; font-variant-numeric: tabular-nums; }

.tasse2-detail-steps { margin-top: 6px; }
.tasse2-detail-steps .tax-detail-step { padding: 12px 0; border-bottom: 1px solid var(--border); font-size: 12.5px; line-height: 1.65; color: var(--text-2); }
.tasse2-detail-steps .tax-detail-step:last-child { border-bottom: none; }
.tasse2-detail-steps .tax-detail-step strong { color: var(--text); }

/* ── Disclaimer — nota a piè di pagina, discreta ma sempre visibile ── */
.tasse2-footnote { font-size: 11.5px; color: var(--subtle); line-height: 1.6; margin-top: 48px; padding-top: 18px; border-top: 1px solid var(--border); }
.tasse2-footnote strong { color: var(--muted); }

/* ══════════════════════════════════════════════════════════════
   MOBILE — SISTEMA RESPONSIVE (2026-08-01)
   Attua le due soglie documentate accanto a --sidebar-w in cima al
   file: 900px (nav/tablet) e 600px (telefono). Vedi DESIGN_DECISIONS.md
   per la voce che rende questo lavoro vincolante e supera
   l'inquadramento "non uno strumento mobile-first" di DC-63 e i
   finding F4-01/03/04/05 di audit/REPORT.md (postposti al 2026-07-06,
   ora ripresi su richiesta esplicita del proprietario).
══════════════════════════════════════════════════════════════ */

/* ── 0. Argine anti-overflow (aggiunto dopo verifica su telefono reale,
   2026-08-01) — qualunque riga flessibile senza flex-wrap che ecceda la
   larghezza dello schermo forza Safari iOS a renderizzare l'INTERA pagina
   più larga del viewport invece di limitare l'overflow a quella riga (non
   un semplice "scrollbar orizzontale" come su desktop): risultato,
   l'intera app appare rimpicciolita, tablet-like, anche dove le regole
   sotto già collassano correttamente a colonna singola. Regola permanente
   (non solo sotto media query — su desktop nessun elemento fa mai
   affidamento su uno scroll orizzontale del body, tutte le tabelle larghe
   hanno già un proprio contenitore overflow-x:auto), più tre righe
   specifiche individuate come le vere cause radice: intestazione pagina
   (titolo + controlli), ricerca Inventario (larghezza fissa 260px) e tab
   di stato (6 voci, mai andate a capo). ── */
html, body { overflow-x: hidden; }

@media (max-width: 900px) {
  .page-header { flex-wrap: wrap; }
  .kpi-hero-top { flex-wrap: wrap; }
  /* La causa radice vera, trovata dopo due giri di correzioni parziali:
     .main-content è display:flex;flex-direction:column, quindi ogni
     .tab-panel è un FIGLIO FLEX — e un figlio flex per default ha
     min-width:auto, cioè si rifiuta di restringersi sotto la larghezza
     "naturale" del proprio contenuto (il classico "flexbox blowout"),
     indipendentemente da qualunque flex-wrap/grid-template-columns messo
     nei livelli più interni. Risultato osservato: aggiungere prima
     overflow-x:hidden qui NASCONDEVA il sintomo invece di risolverlo —
     il contenuto restava più largo dello schermo, semplicemente non lo si
     vedeva più scrollando (peggio: prima almeno si poteva raggiungere
     scorrendo). Il fix corretto è min-width:0, che permette al pannello di
     restringersi davvero fino alla larghezza disponibile — dopo di che il
     contenuto interno (già wrappato/collassato dalle regole sopra e da
     .kpi-grid/.cat-filter) si dispone per intero senza bisogno di
     nascondere nulla. */
  .tab-panel.active { min-width: 0; }
}
@media (max-width: 600px) {
  .inv-header-controls { flex-wrap: wrap; row-gap: 8px; }
  .inv-search, .inv-search input { width: 100%; max-width: none; }
  .inv-sheet-header .status-tabs {
    overflow-x: auto; flex-wrap: nowrap; max-width: 100%;
    -webkit-overflow-scrolling: touch;
  }
}

/* ── 1. Navigazione: barra fissa in basso, icon-only, stile Instagram
   (2026-09-12, richiesta esplicita del proprietario — sostituisce
   l'hamburger+drawer off-canvas usato fino a questa stessa sessione:
   "nella versione mobile il menu sta in basso", confermato col preview
   di una barra icone fissa in fondo). Nessun toggle/backdrop più
   necessario: la barra è sempre visibile, non un pannello a comparsa. ── */
@media (max-width: 900px) {
  .sidebar {
    top: auto; bottom: 0; left: 0; right: 0;
    width: 100%; height: 64px;
    flex-direction: row;
    box-shadow: 0 -4px 16px rgba(0,0,0,0.10);
    /* Barra della gesture home su iPhone: senza questo l'ultima voce
       (Impostazioni) cadrebbe sotto l'area cliccabile del sistema. */
    padding-bottom: env(safe-area-inset-bottom, 0);
    box-sizing: content-box;
  }
  /* Logo e avatar non hanno senso in una barra icone stile Instagram —
     l'avatar duplicherebbe comunque la voce Impostazioni. */
  .sidebar-brand, .sidebar-footer { display: none; }
  .sidebar-nav {
    flex: none; width: 100%; height: 100%;
    flex-direction: row;
    justify-content: space-around;
    padding: 0 4px;
    gap: 0;
    overflow: visible;
  }
  /* Fumetto al hover (desktop) sostituito da nessuna etichetta: il touch
     non ha hover, e 7 etichette sempre visibili affollerebbero una barra
     orizzontale — barra icon-only pura, come il riferimento Instagram. */
  .nav-label { display: none; }
  /* Barretta accento a sinistra (.nav-item.active::after) pensata per un
     rail verticale — su una colonna stretta di una barra orizzontale
     sembra una riga verticale isolata, non un accento. Il pallino/pill
     viola sull'icona attiva basta da solo a comunicare lo stato. */
  .nav-item.active::after { display: none; }

  .main-content {
    margin-left: 0 !important;
    padding-bottom: calc(64px + env(safe-area-inset-bottom, 0));
  }

  /* ── 2. Layout multi-colonna → colonna singola sotto i 900px ── */
  .kpi-grid, .kpi-grid-secondary, .buy-config-grid, .buyer-shipping-grid { grid-template-columns: 1fr !important; }
  /* Stesso "blowout" del punto sopra ma per i figli grid invece che flex —
     un figlio di traccia 1fr per default non si restringe sotto il
     min-content del proprio contenuto. Senza questo, .kpi-card poteva
     restare più largo della colonna anche a grid-template-columns:1fr. */
  .kpi-grid > *, .kpi-grid-secondary > *, .buy-config-grid > *, .buyer-shipping-grid > * { min-width: 0; }
}

/* ── 3. Azioni legate solo a :hover — invisibili/irraggiungibili al tocco.
   (hover:none) intercetta i dispositivi touch reali indipendentemente
   dalla larghezza viewport; il max-width 900px copre anche chi ridimensiona
   la finestra con mouse per verifica. ── */
@media (hover: none), (max-width: 900px) {
  .inv-table .actions-cell { opacity: 1 !important; }
  .v-pub-off { opacity: 1 !important; }
}

/* ── 4. Pannello notifiche — su mobile non c'è più un rail a sinistra a
   cui agganciarsi (la sidebar è una barra in basso, §"Navigazione" sopra):
   left:0, niente più left:64px (F4-04, aggiornato 2026-09-12 insieme allo
   spostamento del pannello dalla topbar alla sidebar, e di nuovo quando la
   sidebar mobile è passata da drawer laterale a barra in basso). Larghezza
   min() per non eccedere lo schermo sotto i ~376px, innocuo su schermi più
   larghi dove resta comunque il width:360px preferito. ── */
.notif-panel { left: 0; width: min(360px, calc(100vw - 32px)); }

/* ── 5. Inventario — resta tabella con scroll orizzontale (decisione
   esplicita, non diventa lista di card). Sotto i 600px le colonne
   "congelate" (numero riga/stato/nome, fino a left:510px)
   eccedono da sole la larghezza dello schermo — la sovrapposizione
   risultante rompeva i tap target (bug F4-03). Fix: sotto quella soglia
   nessuna colonna resta fissa, tutta la tabella scorre come un unico
   blocco orizzontale — prevedibile, niente più sovrapposizioni. ── */
@media (max-width: 600px) {
  .inv-table-container { overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch; }
  .inv-th-num, .inv-row-num,
  .col-sticky, .col-sticky-1, .col-sticky-2 {
    position: static !important;
    left: auto !important;
    box-shadow: none !important;
  }
}

/* ── 5c. Inventario su telefono (≤600px) — la tabella si estende per la
   propria altezza intera e scorre con tutta la pagina, non più dentro un
   riquadro con altezza fissa (2026-09-13, richiesta esplicita del
   proprietario: "voglio che la tabella si estenda per intero e sia io a
   dover scrollare per vederla tutta, non che venga tagliata alle
   proporzioni dello schermo e debba scrollare dentro"). Supera
   esplicitamente il commento adiacente su #tab-inventory ("la pagina non
   deve scrollare, solo la tabella al suo interno", §138) — quella era la
   scelta voluta per desktop/tablet, qui viene rovesciata solo sotto i
   600px. #inv-legacy ha flex:1 inline e .inv-sheet ha overflow:hidden,
   entrambi pensati per contenere .inv-table-container a scroll interno
   (calc(100vh - 229px)) — vanno neutralizzati perché il foglio possa
   crescere con tutto il proprio contenuto invece di restare tagliato.
   .main-content ha già il proprio overflow-y:auto (mai rimosso): con
   questi override diventa lui a scrollare davvero, invece di restare
   "innocuo" perché il contenuto combaciava sempre col viewport.
   !important solo su #inv-legacy: flex:1 è uno style inline in index.html,
   più specifico di una regola in foglio di stile senza !important. ── */
@media (max-width: 600px) {
  #inv-legacy { flex: none !important; min-height: 0 !important; }
  .inv-sheet .inv-table-container { max-height: none; }
  /* Angoli/ombra/bordo tolti e foglio esteso a filo schermo (compensando i
     28px di padding laterale di .tab-panel.active con un margine negativo
     uguale e contrario): "il più a schermo intero possibile" — un bordo
     arrotondato staccato dai margini dello schermo avrebbe solo sottratto
     spazio utile alla tabella. .inv-sheet-header conserva il proprio
     padding interno (16px), quindi ricerca/filtri restano staccati dal
     vero bordo schermo anche così. */
  .inv-sheet {
    overflow: visible;
    border-radius: 0; border: none; box-shadow: none;
    margin: 0 -28px;
  }
}

/* ── 5b. Pannello "Segna come Venduto" (quick-sell-panel, creato da JS in
   showQuickSellPanel(), non è nel markup statico di index.html) — bug
   reale trovato durante la verifica su telefono: `left: var(--sidebar-w)`
   (240px) è pensato per stare accanto alla sidebar fissa desktop, ma
   sotto i 900px la sidebar è off-canvas — il pannello restava comunque
   ancorato a 240px dal bordo, schiacciato in una striscia larga ~150px su
   un telefono da 390px, inutilizzabile. Le singole card (.qs-group,
   larghezze in px inline nell'HTML generato da app.js — 96-140px l'una,
   6 in fila) non andavano mai a capo, aggravando il problema. ── */
@media (max-width: 900px) {
  .quick-sell-panel { left: 0 !important; }
  /* Bug reale (2026-09-20, screenshot dal telefono del proprietario): sotto
     i 900px la sidebar diventa la barra di navigazione fissa in basso
     (z-index:100, 64px), mentre il pannello è ancorato a bottom:0 con
     z-index:96 — la barra lo copriva esattamente dove stanno i bottoni
     Conferma/Annulla, rendendo impossibile confermare una vendita da
     telefono. Il pannello (e il suo velo) passano SOPRA la barra: è un
     foglio modale, la navigazione dietro non deve restare cliccabile.
     Padding inferiore per la barra gesture di iPhone, altezza massima su
     100dvh (100vh su mobile include la barra URL del browser e taglierebbe
     il fondo del pannello). */
  .quick-sell-overlay { z-index: 210; }
  .quick-sell-panel {
    z-index: 211;
    padding-bottom: calc(14px + env(safe-area-inset-bottom, 0px));
    max-height: calc(100vh - 80px);
    max-height: calc(100dvh - 80px);
  }
}
@media (max-width: 600px) {
  .qs-body { flex-wrap: wrap; }
  /* !important necessario: le larghezze fisse sono style inline nell'HTML
     generato da app.js (style="width:128px" ecc.), più specifiche di una
     regola in foglio di stile senza !important. */
  .qs-group { width: calc(50% - 5px) !important; box-sizing: border-box; }
  .qs-notes-group { width: 100% !important; }
}

/* ── 6. Tabelle dentro lot-modal/decompose-modal — il contenitore esterno
   del modale è già fluido (95vw), ma .lot-items-table-wrap non aveva
   overflow-x: con table-layout:fixed a colonne percentuali, sotto i
   600px le celle si schiacciavano in modo imprevedibile (input troncati,
   colonne che si accavallano). Fix: sotto quella soglia il wrapper scorre
   e la tabella passa ad auto-layout — le colonne si dimensionano sul
   contenuto invece che sulle percentuali pensate per una viewport larga.
   Risolve anche la 7ª colonna di decompose-modal (Margine previsto), mai
   dichiarata nelle regole nth-child pensate per le 6 colonne di lot-modal:
   con auto-layout ottiene comunque uno spazio coerente, senza bisogno di
   duplicare le regole di larghezza per un'unica colonna in più. ── */
@media (max-width: 600px) {
  .lot-items-table-wrap { overflow-x: auto; }
  .lot-items-table { table-layout: auto; min-width: 560px; }
}

/* ── Modalità "Seleziona" su telefono + barra di selezione sopra la nav
   (2026-09-21, richiesta del proprietario: "come faccio a fare un rimborso
   selezionando più celle da telefono"). Due parti:
   1) Bug reale: sotto i 900px la nav fissa in basso ha z-index:100 e 64px
      di altezza, mentre .bulk-bar stava a bottom:20px con z-index:90 —
      la barra "N righe · Rimborso" finiva DIETRO la nav e sul telefono non
      si vedeva mai. Ora sta sopra la nav; il popover Rimborso sopra la barra.
   2) Bottone "Seleziona" (nascosto su desktop): con la modalità attiva un
      tap su tutta la riga la seleziona (logica in app.js, toggleInvSelectMode). ── */
#inv-select-mode-btn { display: none; }
@media (max-width: 600px) {
  #inv-select-mode-btn { display: inline-flex; align-items: center; gap: 4px; }
  #inv-select-mode-btn.active {
    background: var(--indigo); border-color: var(--indigo); color: #fff;
  }
  body.inv-select-mode .inv-table tbody tr { cursor: pointer; -webkit-tap-highlight-color: transparent; }
  body.inv-select-mode .inv-table tbody td { user-select: none; -webkit-user-select: none; }
}
@media (max-width: 900px) {
  /* Centratura senza transform: l'animazione panel-fade-in (fill both) termina
     con transform:translateY(0) e sovrascrive il translateX(-50%) con cui
     .bulk-bar/.refund-popover si centrano — la barra partiva da metà schermo e
     sbordava a destra (tagliata su telefono). Con left/right:0 + margin auto
     non dipende più dal transform. Su desktop non toccato (fuori scope). */
  .bulk-bar {
    left: 0; right: 0; margin: 0 auto; transform: none;
    width: max-content;
    bottom: calc(64px + env(safe-area-inset-bottom, 0px) + 12px);
    max-width: calc(100vw - 24px);
  }
  .refund-popover {
    left: 0; right: 0; margin: 0 auto; transform: none;
    bottom: calc(64px + env(safe-area-inset-bottom, 0px) + 12px + 52px);
    max-height: calc(100dvh - 64px - 12px - 52px - 24px - env(safe-area-inset-bottom, 0px));
    overflow-y: auto;
  }
}

/* ══ Tasse v3 (2026-10-12, DESIGN_DECISIONS §157) ══════════════════════════
   Pagina come sequenza di domande numerate. Ogni sezione dichiara il proprio
   periodo (pill) perché il selettore anno vale solo per alcune. Numeri delle
   domande in grigio neutro: il viola resta per il numero protagonista
   (Restano da dichiarare / anello) e per l'azione primaria. */
.tasse3-nav {
  display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 22px;
}
.tasse3-nav button {
  font-size: 12.5px; font-weight: 600; color: var(--text-2);
  background: var(--surface); border: 1px solid var(--border); border-radius: 999px;
  padding: 6px 12px; cursor: pointer; transition: background-color .12s ease, border-color .12s ease;
}
.tasse3-nav button:hover { background: var(--surface-2); border-color: var(--border-strong); }

.tasse3-section { margin-top: 44px; scroll-margin-top: 16px; }
.tasse3-section:first-of-type { margin-top: 0; }

.tasse3-q-head { display: flex; align-items: flex-start; gap: 12px; margin-bottom: 16px; }
.tasse2-block-highlight .tasse3-q-head { margin-bottom: 14px; }
.tasse3-q-num {
  flex-shrink: 0; width: 26px; height: 26px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12.5px; font-weight: 700; color: var(--text-2);
  background: var(--surface-2); border: 1px solid var(--border);
}
.tasse3-q-num-plain { visibility: hidden; }
.tasse3-q-titles { flex: 1; min-width: 0; }
.tasse3-q-title { font-size: 17px; font-weight: 700; color: var(--text); letter-spacing: -0.01em; margin: 2px 0 0; }
.tasse3-q-help { font-size: 12.5px; color: var(--muted); line-height: 1.5; margin-top: 3px; }
.tasse3-scope {
  flex-shrink: 0; font-size: 11.5px; font-weight: 600; color: var(--muted);
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 999px;
  padding: 3px 10px; white-space: nowrap; margin-top: 2px;
}

/* Equazione del blocco 1: + inventario + recuperate = incassato − già
   dichiarato = restano. Il segno in colonna rende esplicito come nasce il
   numero grande, senza dover leggere il sottotitolo. */
.tasse3-op { width: 12px; flex-shrink: 0; text-align: center; color: var(--subtle); font-weight: 700; font-variant-numeric: tabular-nums; }
.tasse3-eq-subtotal, .tasse3-eq-total { padding-top: 9px; border-top: 1px dashed var(--border); }
.tasse3-eq-subtotal .tasse2-corr-row-label, .tasse3-eq-total .tasse2-corr-row-label { color: var(--text); }
.tasse3-eq-total .tasse2-corr-row-amount { color: var(--indigo-d, var(--indigo)); font-size: 14px; }
.tasse3-eq-excluded { margin-top: 6px !important; opacity: .85; }

.tasse3-actions { display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end; margin-top: 18px; }
.tasse3-sub-title {
  font-size: 11.5px; font-weight: 700; letter-spacing: var(--tracking-label); text-transform: uppercase;
  color: var(--subtle); margin: 22px 0 6px;
}
.tasse3-form-help { font-size: 12.5px; color: var(--muted); line-height: 1.5; margin-bottom: 10px; }
.tasse3-inner-block { margin-top: 20px; }

/* Importi giorno per giorno */
.tasse3-giorni { margin-top: 16px; border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; background: var(--surface); }
.tasse3-giorni-help { font-size: 12.5px; color: var(--muted); line-height: 1.5; margin-bottom: 10px; }
.tasse3-giorni-head, .tasse3-giorni-row, .tasse3-giorni-foot {
  display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; align-items: center;
  font-size: 12.5px; font-variant-numeric: tabular-nums;
}
.tasse3-giorni-head span:last-child, .tasse3-giorni-row span:last-child, .tasse3-giorni-foot span:last-child { text-align: right; }
.tasse3-giorni-head { font-size: 11px; font-weight: 700; letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--subtle); padding-bottom: 6px; border-bottom: 1px solid var(--border); }
#corr-giorni-list { max-height: 360px; overflow-y: auto; }
.tasse3-giorni-row { padding: 7px 0; border-bottom: 1px solid var(--border); color: var(--text-2); }
.tasse3-giorni-row span:last-child { font-weight: 700; color: var(--text); }
.tasse3-giorni-row.zero span:last-child { font-weight: 500; color: var(--subtle); }
.tasse3-giorni-rec { font-size: 11px; font-weight: 600; color: var(--muted); margin-left: 4px; }
.tasse3-giorni-foot { padding-top: 9px; font-weight: 700; color: var(--text); }

@media (max-width: 600px) {
  .tasse3-q-head { flex-wrap: wrap; row-gap: 8px; }
  .tasse3-q-titles { flex: 1 1 calc(100% - 38px); }
  .tasse3-scope { order: 3; margin-left: 38px; white-space: normal; }
  .tasse3-actions { justify-content: stretch; }
  .tasse3-actions .btn { flex: 1; }
}
.tasse3-section .tasse2-status-row { margin-top: 0; }
.tasse3-giorni-acc { grid-column: 1 / -1; font-size: 11.5px; color: var(--muted); line-height: 1.45; margin-top: -2px; }
.tasse3-giorni-row .tasse3-giorni-acc { font-weight: 500; text-align: left; }

/* ── iPhone: niente zoom automatico sui campi + lot-modal scorrevole
   (2026-10-14, §160, richiesta del proprietario: "su iphone quando si clicca
   sul campo di testo per aggiungere un articolo si zooma e non si capisce
   cosa stai scrivendo").
   1) Safari iOS zooma la pagina su qualunque input/select/textarea con
      font-size < 16px (es. .lot-input 12.5px). Sui dispositivi touch tutti
      i campi passano a 16px; !important necessario per battere le molte
      regole più specifiche e gli style inline generati da app.js. Desktop
      (mouse) invariato. Non si usa maximum-scale=1 nel viewport: su Android
      bloccherebbe anche lo zoom manuale (accessibilità).
   2) Sul telefono la tabella "Articoli del lotto" era flex:1 dentro un modale
      a overflow:hidden: i campi sopra si prendevano tutto lo spazio e la riga
      di input restava schiacciata a pochi pixel. Sotto i 600px scorre l'intero
      modale e la tabella prende l'altezza del suo contenuto. ── */
@media (hover: none) and (pointer: coarse) {
  input, select, textarea { font-size: 16px !important; }
}
@media (max-width: 600px) {
  .lot-modal { overflow-y: auto; max-height: 90dvh; }
  .lot-items-table-wrap { flex: none; overflow-y: visible; }
  .lot-items-header { flex-wrap: wrap; }
  /* Con auto-layout la colonna Nome restava ~40px: si scriveva alla cieca. */
  .lot-items-table td:nth-child(1) .lot-input { min-width: 180px; }
  .lot-items-table td:nth-child(2) .lot-input { min-width: 120px; }
  .lot-items-table .lot-price-input { min-width: 90px; }
}
