// ────────────────── Shell: Sidebar + Topbar + shared atoms ──────────────────
// Convertito al Cupertino Enterprise Design System.
// Logica e comportamento invariati: cambiano solo classi/stili.

const { useState: useStateSH } = React;

const fmtEur = (n) => '€ ' + n.toLocaleString('it-IT', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
const fmtInt = (n) => n.toLocaleString('it-IT');
const fmtPct = (n) => (n >= 0 ? '+' : '') + n.toFixed(1) + '%';

// — Section card with optional title row
// DS: niente border 1px — la profondita' viene da shadow-md + hairline interna
//     gia' inclusa nel token. Radius card = --radius-2xl.
const Card = ({ title, action, children, className = '', padded = true }) => (
  <section className={`bg-surface rounded-2xl shadow-soft ${className}`}>
    {title && (
      <header className="flex items-center justify-between px-5 py-4 hairline">
        <h3 className="text-[15px] font-semibold tracking-tight text-ink">{title}</h3>
        {action}
      </header>
    )}
    <div className={padded ? 'p-5' : ''}>{children}</div>
  </section>
);

// — Button primitives
// DS: ogni variante copre default/hover/active/focus-visible/disabled.
//     transizioni su token --ease-standard / --dur-fast.
const Btn = ({ variant = 'ghost', size = 'md', children, leading, trailing, className = '', ...rest }) => {
  const sizes = {
    sm: 'h-9 px-3 text-[13px]',
    md: 'h-11 px-4 text-[14px]',
    lg: 'h-12 px-5 text-[15px]',
    xl: 'h-16 px-6 text-[17px]',
  };
  const variants = {
    // Primary — CTA "bubble": gradiente blu + ombra morbida colorata
    primary: 'btn-bubble btn-bubble-blue text-[var(--text-inverse)] hover:scale-[1.015] active:scale-[0.985] disabled:bg-[var(--gray-200)] disabled:text-[var(--gray-400)] disabled:scale-100 disabled:cursor-not-allowed',
    // Ink — azione neutra forte: stesso stile bubble blu
    ink:     'btn-bubble btn-bubble-blue text-[var(--text-inverse)] hover:scale-[1.015] active:scale-[0.985] disabled:opacity-50 disabled:scale-100',
    // Ghost — testo accent (secondario, piatto)
    ghost:   'bg-transparent text-[var(--accent-blue)] rounded-lg hover:bg-[var(--bg-selected)] active:bg-[var(--bg-pressed)] disabled:opacity-40',
    // Outline / Secondary — superficie sunken con hairline (secondario, piatto)
    outline: 'bg-sunken text-ink rounded-lg shadow-[inset_0_0_0_0.5px_var(--border-default)] hover:shadow-[inset_0_0_0_0.5px_var(--border-strong)] active:bg-[var(--bg-pressed)] disabled:opacity-50',
    // Danger — CTA "bubble" rossa
    danger:  'btn-bubble btn-bubble-red text-[var(--text-inverse)] hover:scale-[1.015] active:scale-[0.985] disabled:opacity-50 disabled:scale-100',
    // Success — CTA "bubble" verde
    success: 'btn-bubble btn-bubble-green text-[var(--text-inverse)] hover:scale-[1.015] active:scale-[0.985] disabled:opacity-50 disabled:scale-100',
  };
  return (
    <button
      className={`focus-ring inline-flex items-center justify-center gap-2 rounded-lg font-medium transition-[transform,box-shadow,filter] duration-fast ease-standard ${sizes[size]} ${variants[variant]} ${className}`}
      {...rest}
    >
      {leading}
      <span className="whitespace-nowrap">{children}</span>
      {trailing}
    </button>
  );
};

// — Pill / Badge
// DS §3.4: pill semantica con coppia background -50 / testo -700; dot colore -700.
//          variante neutral su --bg-sunken / --text-secondary.
const Pill = ({ tone = 'neutral', children, className = '' }) => {
  const tones = {
    neutral: 'bg-sunken text-[var(--text-secondary)]',
    pos:     'bg-[var(--success-50)] text-[var(--success-700)]',
    neg:     'bg-[var(--danger-50)] text-[var(--danger-700)]',
    info:    'bg-[var(--info-50)] text-[var(--info-700)]',
    warn:    'bg-[var(--warning-50)] text-[var(--warning-700)]',
    accent:  'bg-[var(--bg-selected)] text-[var(--accent-blue)]',
  };
  return (
    <span className={`inline-flex items-center gap-1 rounded-pill px-2.5 py-0.5 text-[11px] font-semibold tracking-tight ${tones[tone]} ${className}`}>
      {children}
    </span>
  );
};

// — Stat tile (used in dashboard)
// DS §4.5: label --text-h6, valore KPI grande, delta in success-700 / danger-700.
const Stat = ({ label, value, delta, subtle, mono = true }) => {
  const positive = delta >= 0;
  return (
    <div className="px-5 py-5 first:pl-6 last:pr-6 flex-1 min-w-0">
      <div className="text-[12px] uppercase tracking-[0.04em] text-muted font-semibold">{label}</div>
      <div className={`mt-2 text-[34px] leading-none text-ink ${mono ? 'num font-semibold' : 'font-semibold'}`}>{value}</div>
      <div className="mt-2 flex items-center gap-2">
        {typeof delta === 'number' && (
          <span className={`num text-[12.5px] font-semibold ${positive ? 'text-[var(--success-700)]' : 'text-[var(--danger-700)]'}`}>
            {positive ? '▲' : '▼'} {fmtPct(delta)}
          </span>
        )}
        {subtle && <span className="text-[12.5px] text-muted">{subtle}</span>}
      </div>
    </div>
  );
};

// Toni badge ruolo — mappa id-ruolo → tone Pill esistente
const ROLE_BADGE_TONE = {
  'Admin':         'accent',
  'Manager':       'accent',
  'Store Manager': 'info',
  'Cassiere':      'neutral',
  'Magazziniere':  'neutral',
};

// — Sidebar
const NAV = [
  { id: 'dashboard',    label: 'Dashboard',    icon: 'Dashboard' },
  { id: 'pos',          label: 'Cassa',        icon: 'Cash', hot: true },
  { id: 'catalogo',     label: 'Catalogo',     icon: 'Tag' },
  { id: 'magazzino',    label: 'Magazzino',    icon: 'Box' },
  { id: 'acquisti',     label: 'Acquisti',     icon: 'Truck' },
  { id: 'anagrafiche',  label: 'Anagrafiche',  icon: 'Users' },
  { id: 'timbrature',   label: 'Timbrature',   icon: 'Clock'    },
  { id: 'documenti',    label: 'Documenti',    icon: 'Doc'      },
  { id: 'scadenzario',  label: 'Scadenzario',  icon: 'Clock'    },
  // Le impostazioni aziendali sono nella rotella (pannello account), non più qui.
];

// DS §4.2: sidebar in materiale .glass-regular, larghezza 260px,
//          nav item con hover --bg-hover, attivo --bg-selected + accent.
const Sidebar = ({ section, onNav, onOpenTweaks, session, onLock, activeStoreId = STORE.id, onStoreChange, onOpenUserPanel }) => {
  const [storeOpen, setStoreOpen] = useStateSH(false);
  const activeStore = activeStoreId === 'all'
    ? { name: 'Tutti i negozi', id: 'all', short: 'ALL', city: '' }
    : STORES.find(s => s.id === activeStoreId) || STORE;
  const storeLocked = ROLES?.find(r => r.id === session?.op?.role)?.permissions?.storeSwitcher === 'locked';
  // Negozi visibili = scope del principal (Admin/Manager: tutti; Area Manager: la sua area; altrimenti il suo)
  const scope = session?.op?.scopeStores;
  const visibleStores = (!scope || scope === 'all') ? STORES : STORES.filter(s => scope.includes(s.id));
  const canSeeAll = (!scope || scope === 'all') ? true : visibleStores.length > 1; // "Tutti" ha senso solo con ≥2 negozi
  const rolePerms = ROLES?.find(r => r.id === session?.op?.role)?.permissions || {};
  const visibleNav = NAV.filter(item => {
    if (session?.op?.role === 'Magazziniere' && (item.id === 'dashboard' || item.id === 'pos')) return false;
    return true;
  });

  return (
  <aside className="w-[260px] shrink-0 glass-regular flex flex-col"
         style={{ borderRight: '0.5px solid var(--border-subtle)' }}>
    {/* brand */}
    <div className="px-5 pt-6 pb-5">
      <div className="flex items-center gap-2.5">
        <Logo size={32}/>
        <div>
          <div className="text-[14px] font-semibold tracking-tight text-ink">Easy2Sell</div>
          <div className="text-[11px] text-muted -mt-0.5">retail · fashion</div>
        </div>
      </div>
    </div>

    {/* store switcher */}
    <div className="mx-3 mb-3 relative">
      <button
        onClick={() => { if (!storeLocked) setStoreOpen(o => !o); }}
        className={`w-full px-3 py-2.5 rounded-md bg-surface text-left shadow-sm transition-shadow duration-fast ease-standard focus-ring ${storeLocked ? 'cursor-default opacity-80' : 'hover:shadow-md'}`}
      >
        <div className="flex items-center gap-2">
          <I.Store size={14} className="text-muted"/>
          <span className="text-[11px] uppercase tracking-[0.04em] text-muted font-semibold">Punto vendita</span>
        </div>
        <div className="mt-1 flex items-center justify-between">
          <span className="text-[13.5px] font-medium text-ink">{activeStore.name}</span>
          {storeLocked
            ? <I.Lock size={13} className="text-muted"/>
            : <I.ArrowD size={14} className="text-muted"/>
          }
        </div>
      </button>
      {!storeLocked && storeOpen && (
        <>
          <div className="fixed inset-0 z-40" onClick={() => setStoreOpen(false)}/>
          <div className="absolute left-0 right-0 top-full mt-1 z-50 bg-surface rounded-xl shadow-modal overflow-hidden">
            {canSeeAll && (
            <button
              onClick={() => { onStoreChange && onStoreChange('all'); setStoreOpen(false); }}
              className="w-full flex items-center justify-between px-4 py-3 text-[13.5px] text-left hover:bg-[var(--bg-hover)] transition-colors duration-fast ease-standard border-b border-line"
            >
              <div>
                <div className="font-medium text-ink">{(scope && scope !== 'all') ? 'Tutta la mia area' : 'Tutti i negozi'}</div>
                <div className="text-[11px] text-muted">Vista aggregata</div>
              </div>
              {activeStoreId === 'all' && <I.Check size={14} className="text-[var(--accent-blue)] shrink-0"/>}
            </button>
            )}
            {visibleStores.map(s => (
              <button
                key={s.id}
                onClick={() => { onStoreChange && onStoreChange(s.id); setStoreOpen(false); }}
                className="w-full flex items-center justify-between px-4 py-3 text-[13.5px] text-left hover:bg-[var(--bg-hover)] transition-colors duration-fast ease-standard"
              >
                <div>
                  <div className="font-medium text-ink">{s.name}</div>
                  <div className="text-[11px] text-muted">{s.city} · {s.short}</div>
                </div>
                {s.id === activeStoreId && <I.Check size={14} className="text-[var(--accent-blue)] shrink-0"/>}
              </button>
            ))}
          </div>
        </>
      )}
    </div>

    {/* nav */}
    <nav className="px-2 mt-1 flex-1">
      {visibleNav.map(n => {
        const Ico = I[n.icon];
        const active = section === n.id;
        return (
          <button
            key={n.id}
            data-active={active}
            onClick={() => onNav(n.id)}
            className="nav-item w-full flex items-center gap-3 px-3 h-11 rounded-md text-[14px] text-ink hover:bg-[var(--bg-hover)] focus-ring mb-0.5"
          >
            <span className="nav-dot w-1 h-1 rounded-full bg-transparent"></span>
            <Ico size={18} />
            <span className="font-medium">{n.label}</span>
            {n.hot && !active && (
              <span className="ml-auto num text-[10.5px] text-muted">F2</span>
            )}
          </button>
        );
      })}
    </nav>

    {/* footer: user + azioni */}
    <div className="px-3 pb-4 pt-3" style={{ borderTop: '0.5px solid var(--border-subtle)' }}>
      {/* Footer utente: profilo (sx) + impostazioni (dx) — due button fratelli */}
      <div className="flex items-center gap-1">
        <button
          onClick={onOpenUserPanel}
          className="flex-1 min-w-0 flex items-center gap-3 px-2 py-2 rounded-md text-left hover:bg-[var(--bg-hover)] active:bg-[var(--bg-pressed)] transition-colors duration-fast ease-standard focus-ring"
          title="Profilo e account"
        >
          <div className="w-8 h-8 rounded-lg text-[var(--text-inverse)] flex items-center justify-center text-[12px] font-semibold shrink-0"
            style={{ background: 'linear-gradient(140deg, var(--accent-blue), var(--accent-indigo))' }}>
            {session ? (session.op.kind === 'store' ? <I.Store size={16}/> : session.op.initials) : <I.Store size={16}/>}
          </div>
          <div className="min-w-0 flex-1">
            <div className="text-[13px] font-medium text-ink truncate">
              {session ? session.op.name : STORE.cashier}
            </div>
            <div className="mt-0.5 flex items-center gap-1.5 flex-wrap">
              {session
                ? <Pill tone={ROLE_BADGE_TONE[session.op.role] || 'neutral'}>{session.op.role}</Pill>
                : <span className="text-[11px] text-muted">Operatore</span>
              }
              <span className="text-[11px] text-muted">· turno {STORE.shiftStart}</span>
            </div>
          </div>
        </button>
        <button
          onClick={onOpenUserPanel}
          title="Account e sessione"
          className="focus-ring w-8 h-8 rounded-md hover:bg-[var(--bg-hover)] active:bg-[var(--bg-pressed)] flex items-center justify-center text-muted transition-colors duration-fast ease-standard shrink-0"
        >
          <I.Settings size={16}/>
        </button>
      </div>
      {onLock && (
        <button
          onClick={onLock}
          className="w-full h-11 flex items-center gap-2.5 px-2 rounded-md text-[13px] font-medium
                     text-muted hover:text-ink hover:bg-[var(--bg-hover)] active:bg-[var(--bg-pressed)]
                     transition-colors duration-fast ease-standard focus-ring"
        >
          <I.Lock size={15}/>
          <span>Blocca</span>
        </button>
      )}
    </div>
  </aside>
  );
};

// — Campanella notifiche: avvisi reali dal backend (/api/notifiche), badge non-letti,
//   pannello a tendina; clic su un avviso porta alla sezione. "Letti" persistiti in localStorage.
const NOTIF_META = {
  scorta:        { icon: 'Box',    fg: 'var(--warning-700)', bg: 'var(--warning-50)' },
  scadenza:      { icon: 'Clock',  fg: 'var(--danger-700)',  bg: 'var(--danger-50)' },
  richiesta:     { icon: 'Box',    fg: 'var(--accent-blue)', bg: 'rgba(0,122,255,0.12)' },
  trasferimento: { icon: 'Truck',  fg: 'var(--accent-blue)', bg: 'rgba(0,122,255,0.12)' },
  cassa:         { icon: 'Wallet', fg: 'var(--accent-blue)', bg: 'rgba(0,122,255,0.12)' },
  turno:         { icon: 'Clock',  fg: 'var(--warning-700)', bg: 'var(--warning-50)' },
};
const sevDot = (s) => s === 'danger' ? 'var(--danger-500)' : s === 'warning' ? 'var(--warning-500)' : 'var(--accent-blue)';

const NotificheBell = () => {
  const [open, setOpen] = useStateSH(false);
  const [items, setItems] = useStateSH([]);
  const [seen, setSeen] = useStateSH(() => {
    try { return new Set(JSON.parse(localStorage.getItem('e2s_notif_seen') || '[]')); } catch { return new Set(); }
  });
  const persistSeen = (set) => { try { localStorage.setItem('e2s_notif_seen', JSON.stringify([...set])); } catch (e) {} };

  const load = React.useCallback(async () => {
    if (window.__API__ && window.__API__.get) {
      const r = await window.__API__.get('/api/notifiche');
      if (r && r.ok) setItems(r.items || []);
    }
  }, []);
  React.useEffect(() => { load(); const t = setInterval(load, 120000); return () => clearInterval(t); }, [load]);

  const unread = items.filter(it => !seen.has(it.id)).length;
  const markAll = () => { const s = new Set(seen); items.forEach(it => s.add(it.id)); setSeen(s); persistSeen(s); };
  const go = (it) => {
    const s = new Set(seen); s.add(it.id); setSeen(s); persistSeen(s);
    setOpen(false);
    if (it.section && window.__nav) window.__nav(it.section);
  };

  return (
    <div className="relative">
      <button onClick={() => { setOpen(o => !o); if (!open) load(); }}
        className="focus-ring h-10 w-10 rounded-md hover:bg-[var(--bg-hover)] active:bg-[var(--bg-pressed)] flex items-center justify-center text-muted relative transition-colors duration-fast ease-standard" title="Notifiche">
        <I.Bell size={18} />
        {unread > 0 && (
          <span className="absolute -top-0.5 -right-0.5 min-w-[16px] h-4 px-1 rounded-full bg-[var(--danger-500)] text-[var(--text-inverse)] text-[10px] font-semibold flex items-center justify-center">{unread > 9 ? '9+' : unread}</span>
        )}
      </button>

      {open && (
        <>
          <div className="fixed inset-0 z-40" onClick={() => setOpen(false)}/>
          <div className="absolute right-0 top-full mt-2 z-50 w-[360px] max-w-[92vw] bg-surface rounded-xl shadow-modal overflow-hidden">
            <div className="flex items-center justify-between px-4 py-3 hairline">
              <span className="text-[14px] font-semibold text-ink">Notifiche {items.length > 0 && <span className="text-muted font-normal">· {items.length}</span>}</span>
              {items.length > 0 && unread > 0 && (
                <button onClick={markAll} className="focus-ring text-[12px] text-[var(--accent-blue)] hover:underline">Segna tutti come letti</button>
              )}
            </div>
            <div className="max-h-[60vh] overflow-auto">
              {items.length === 0 ? (
                <div className="py-12 flex flex-col items-center text-center gap-2 text-muted">
                  <span className="w-12 h-12 rounded-2xl bg-paper flex items-center justify-center"><I.Bell size={22}/></span>
                  <span className="text-[13px]">Nessuna notifica · tutto in ordine</span>
                </div>
              ) : items.map(it => {
                const m = NOTIF_META[it.type] || NOTIF_META.cassa;
                const Ico = I[m.icon] || I.Bell;
                const isNew = !seen.has(it.id);
                return (
                  <button key={it.id} onClick={() => go(it)}
                    className="w-full flex items-start gap-3 px-4 py-3 text-left hover:bg-[var(--bg-hover)] transition-colors border-b border-line2 last:border-0">
                    <span className="w-9 h-9 rounded-lg flex items-center justify-center shrink-0" style={{ background: m.bg, color: m.fg }}><Ico size={17}/></span>
                    <span className="min-w-0 flex-1">
                      <span className="flex items-center gap-2">
                        <span className="text-[13.5px] font-medium text-ink truncate">{it.title}</span>
                        {isNew && <span className="w-1.5 h-1.5 rounded-full shrink-0" style={{ background: sevDot(it.severity) }}/>}
                      </span>
                      <span className="block text-[12px] text-muted truncate">{it.detail}</span>
                    </span>
                  </button>
                );
              })}
            </div>
          </div>
        </>
      )}
    </div>
  );
};

// — Data e ora REALI (orologio del dispositivo), aggiornate ogni minuto.
const LiveClock = () => {
  const [now, setNow] = useStateSH(() => new Date());
  React.useEffect(() => {
    const t = setInterval(() => setNow(new Date()), 30000);
    return () => clearInterval(t);
  }, []);
  const data = now.toLocaleDateString('it-IT', { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' });
  const ora = now.toLocaleTimeString('it-IT', { hour: '2-digit', minute: '2-digit' });
  return (
    <div className="text-right leading-tight">
      <div className="text-[12px] text-muted capitalize">{data}</div>
      <div className="num text-[13.5px] font-medium text-ink">{ora}</div>
    </div>
  );
};

// — Top bar (per-section)
// DS §4.3: topbar in materiale .glass-thin, hairline inferiore, z-index sticky.
const Topbar = ({ title, eyebrow, right, dense = false }) => (
  <header className={`glass-thin sticky top-0 z-sticky ${dense ? 'py-3' : 'py-4'} px-7 flex items-center justify-between`}>
    <div className="min-w-0">
      {eyebrow && <div className="text-[11px] uppercase tracking-[0.04em] text-muted font-semibold">{eyebrow}</div>}
      <h1 className="text-[22px] font-semibold tracking-tight text-ink leading-tight">{title}</h1>
    </div>
    <div className="flex items-center gap-2">
      {right}
      <NotificheBell/>
      <div className="h-8 w-px mx-1" style={{ background: 'var(--border-default)' }}></div>
      <LiveClock/>
    </div>
  </header>
);

// — Overlay di blocco accesso con sblocco temporaneo via PIN supervisore.
// Chiama i figli blurrati+disabilitati quando l'accesso non è consentito.
// Stato locale: si azzera ogni volta che il componente smonta (= ogni cambio sezione).
const AccessGate = ({ allowed, section, children, onDismiss, operators: opList }) => {
  const [unlocked, setUnlocked] = useStateSH(false);
  const [gateView, setGateView] = useStateSH('blocked'); // 'blocked' | 'select' | 'pin'
  const [sup, setSup] = useStateSH(null);
  const [pin, setPin] = useStateSH('');
  const PIN_LEN = 4;

  // Tastiera fisica: quando il pannello PIN è attivo, digita coi numeri, Backspace cancella, Enter conferma.
  // NB: hook PRIMA del return anticipato (regole degli hook); usa aggiornamenti funzionali.
  React.useEffect(() => {
    if (gateView !== 'pin') return;
    const onKey = (e) => {
      if (e.key >= '0' && e.key <= '9') {
        e.preventDefault();
        setPin(prev => {
          if (prev.length >= PIN_LEN) return prev;
          const next = prev + e.key;
          if (next.length === PIN_LEN) setTimeout(() => setUnlocked(true), 180);
          return next;
        });
      } else if (e.key === 'Backspace') { e.preventDefault(); setPin(p => p.slice(0, -1)); }
      else if (e.key === 'Enter') { e.preventDefault(); setPin(p => { if (p.length === PIN_LEN) setUnlocked(true); return p; }); }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [gateView]);

  if (allowed || unlocked) return children;

  // Solo i ruoli alti (Admin / Area Manager) possono autorizzare le sezioni protette
  const supers = (opList || OPERATORS).filter(op =>
    ['Admin', 'Manager', 'Area Manager'].includes(op.role) && op.active !== false
  );
  const SEC_LABELS = { dashboard: 'Dashboard incassi', pos: 'Cassa (POS)', acquisti: 'Acquisti', impostazioni: 'Impostazioni' };
  const secLabel = SEC_LABELS[section] || section;

  const pressPin = (k) => {
    if (pin.length >= PIN_LEN) return;
    const next = pin + k;
    setPin(next);
    if (next.length === PIN_LEN) setTimeout(() => setUnlocked(true), 180);
  };

  const backSvg = (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <path d="M19 12H5M11 6l-6 6 6 6"/>
    </svg>
  );

  return (
    <>
      {/* Contenuto sfocato e non interattivo dietro il gate */}
      <div style={{ filter: 'blur(3px)', opacity: 0.3, pointerEvents: 'none', userSelect: 'none' }}>
        {children}
      </div>

      {/* Overlay fisso — il bg ha pointer-events:none così la sidebar resta cliccabile */}
      <div style={{ position: 'fixed', inset: 0, zIndex: 1040, pointerEvents: 'none', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        <div style={{ position: 'absolute', inset: 0, background: 'var(--bg-canvas)', opacity: 0.9 }}/>
        <div style={{ position: 'relative', pointerEvents: 'auto', width: '100%', maxWidth: '440px', padding: '0 24px' }}>

          {gateView === 'blocked' && (
            <div className="bg-surface rounded-2xl shadow-modal p-8 text-center relative">
              {onDismiss && (
                <button onClick={onDismiss}
                  className="absolute top-4 right-4 w-9 h-9 rounded-md hover:bg-[var(--bg-hover)] active:bg-[var(--bg-pressed)] flex items-center justify-center text-muted focus-ring transition-colors duration-fast ease-standard"
                  title="Torna alla sezione precedente">
                  <I.X size={18}/>
                </button>
              )}
              <div className="w-16 h-16 rounded-full bg-[var(--danger-50)] flex items-center justify-center mx-auto mb-5">
                <I.Lock size={26} className="text-[var(--danger-700)]"/>
              </div>
              <h2 className="text-[20px] font-semibold text-ink mb-2">Accesso non consentito</h2>
              <p className="text-[14px] text-muted leading-relaxed mb-6">
                Il tuo ruolo non consente l'accesso a <strong className="text-ink">{secLabel}</strong>.
                Un supervisore può sbloccare questa sezione temporaneamente.
              </p>
              <Btn variant="outline" size="lg" leading={<I.Lock size={16}/>} onClick={() => setGateView('select')}>
                Sblocca con PIN supervisore
              </Btn>
            </div>
          )}

          {gateView === 'select' && (
            <div className="bg-surface rounded-2xl shadow-modal p-6">
              <button onClick={() => setGateView('blocked')}
                className="flex items-center gap-1.5 text-[13px] text-muted hover:text-ink mb-5 focus-ring rounded-md px-2 py-1">
                {backSvg} Annulla
              </button>
              <h3 className="text-[17px] font-semibold text-ink mb-1">Seleziona supervisore</h3>
              <p className="text-[13px] text-muted mb-4">Accedi con il tuo account supervisore per sbloccare.</p>
              <div className="grid grid-cols-2 gap-3 mt-3">
                {supers.map(op => (
                  <button key={op.id} onClick={() => { setSup(op); setPin(''); setGateView('pin'); }}
                    className="flex flex-col items-center gap-2.5 p-4 bg-sunken rounded-xl hover:bg-[var(--bg-hover)] active:scale-[0.97] transition-all duration-fast ease-standard focus-ring">
                    <div className="w-12 h-12 rounded-full bg-[var(--accent-blue)] text-[var(--text-inverse)] flex items-center justify-center text-[15px] font-semibold">
                      {op.initials}
                    </div>
                    <div className="text-center">
                      <div className="text-[13px] font-semibold text-ink leading-tight">{op.name}</div>
                      <div className="text-[11px] text-muted mt-0.5">{op.role}</div>
                    </div>
                  </button>
                ))}
              </div>
            </div>
          )}

          {gateView === 'pin' && sup && (
            <div className="bg-surface rounded-2xl shadow-modal p-6 text-center">
              <button onClick={() => { setGateView('select'); setPin(''); }}
                className="flex items-center gap-1.5 text-[13px] text-muted hover:text-ink mb-5 focus-ring rounded-md px-2 py-1">
                {backSvg} Indietro
              </button>
              <div className="w-16 h-16 rounded-full bg-[var(--accent-blue)] text-[var(--text-inverse)] flex items-center justify-center text-[22px] font-semibold tracking-tight mx-auto mb-3 shadow-soft">
                {sup.initials}
              </div>
              <div className="text-[17px] font-semibold text-ink">{sup.name}</div>
              <div className="text-[12px] text-muted mb-6">{sup.role}</div>
              <div className="text-[11px] uppercase tracking-[0.06em] text-muted font-semibold mb-3">PIN di autorizzazione</div>
              <div className="flex justify-center gap-4 mb-7">
                {Array.from({ length: PIN_LEN }).map((_, i) => (
                  <div key={i} className={`w-3 h-3 rounded-full transition-all duration-fast ${i < pin.length ? 'bg-[var(--accent-blue)]' : 'bg-[var(--border-default)] scale-90'}`}/>
                ))}
              </div>
              <div className="max-w-[240px] mx-auto grid grid-cols-3 gap-2">
                {['1','2','3','4','5','6','7','8','9'].map(k => (
                  <button key={k} onClick={() => pressPin(k)}
                    className="h-14 bg-sunken rounded-lg text-[20px] font-medium text-ink hover:bg-[var(--bg-hover)] active:scale-[0.92] transition-all duration-fast ease-standard focus-ring">
                    {k}
                  </button>
                ))}
                <button onClick={() => setPin(p => p.slice(0, -1))} disabled={pin.length === 0}
                  className="h-14 rounded-lg text-[22px] text-muted hover:bg-[var(--bg-hover)] active:bg-[var(--bg-pressed)] active:scale-[0.92] disabled:opacity-20 transition-all duration-fast ease-standard focus-ring flex items-center justify-center">
                  ⌫
                </button>
                <button onClick={() => pressPin('0')}
                  className="h-14 bg-sunken rounded-lg text-[20px] font-medium text-ink hover:bg-[var(--bg-hover)] active:scale-[0.92] transition-all duration-fast ease-standard focus-ring">
                  0
                </button>
                <button onClick={() => { if (pin.length === PIN_LEN) setUnlocked(true); }}
                  disabled={pin.length < PIN_LEN}
                  className="h-14 bg-[var(--accent-blue)] text-[var(--text-inverse)] rounded-lg hover:bg-[var(--accent-blue-hover)] active:scale-[0.92] active:bg-[var(--accent-blue-active)] disabled:opacity-30 disabled:cursor-not-allowed transition-all duration-fast ease-standard focus-ring flex items-center justify-center">
                  <I.Check size={20}/>
                </button>
              </div>
            </div>
          )}

        </div>
      </div>
    </>
  );
};

Object.assign(window, { Card, Btn, Pill, Stat, Sidebar, Topbar, AccessGate, fmtEur, fmtInt, fmtPct, ROLE_BADGE_TONE, NAV });
