// ---------- Admin shell (sidebar, topbar, layout) ----------

function AdminShell({ currentRole, onExit, sessionEmployeeId, onLogout }) {
  const { t, lang } = useT();
  const [page, setPage] = React.useState('dashboard');
  const [collapsed, setCollapsed] = React.useState(false);
  const [mobileSidebar, setMobileSidebar] = React.useState(false);
  const [notifOpen, setNotifOpen] = React.useState(false);

  const features = window.ROLE_FEATURES[currentRole] || {};
  const isBoss = currentRole === 'boss';
  const [empTick, setEmpTick] = React.useState(0);
  React.useEffect(() => {
    const h = () => setEmpTick((x) => x + 1);
    window.addEventListener('gh-admin-data', h);
    return () => window.removeEventListener('gh-admin-data', h);
  }, []);
  const userObj = React.useMemo(() => {
    const list = window.EMPLOYEES || [];
    if (sessionEmployeeId) {
      const u = list.find((e) => e.id === sessionEmployeeId);
      if (u) return u;
    }
    return list.find((e) => e.role === currentRole) || list[0];
  }, [sessionEmployeeId, currentRole, empTick]);

  const [, setTweakRev] = React.useState(0);
  React.useEffect(() => {
    const h = () => setTweakRev((x) => x + 1);
    window.addEventListener('tweak-change', h);
    return () => window.removeEventListener('tweak-change', h);
  }, []);

  const navGroups = [
    { label: t('admin.overview'), items: [
      { key:'dashboard', label:t('admin.dashboard'), icon:Icon.LayoutDashboard },
      { key:'production', label:t('admin.production'), icon:Icon.IceCream, badge: 2, feature:'view_production' },
      { key:'inventory',  label:t('admin.inventory'),  icon:Icon.Box,      feature:'view_inventory' },
    ]},
    { label: t('admin.people'), items: [
      { key:'employees', label:t('admin.employees'), icon:Icon.Users, feature:'view_employees' },
      { key:'attendance', label:'Attendance', icon:Icon.Clock, badge: (window.__attendanceLateTodayCount ?? 0) || undefined, feature:'view_employees' },
      { key:'hr',        label:t('admin.hr'),        icon:Icon.Briefcase, badge: 2, feature:'hr_management' },
    ]},
    { label: t('admin.finance'), items: [
      { key:'expenses',  label:t('admin.expenses'),  icon:Icon.CreditCard, feature:'view_expenses' },
      { key:'deposits',  label:t('admin.deposits'),  icon:Icon.Landmark, feature:'view_deposits' },
      { key:'analytics', label:t('admin.analytics'), icon:Icon.TrendingUp, feature:'view_analytics' },
    ]},
    { label: t('admin.system'), items: [
      { key:'users',    label:t('admin.users'),    icon:Icon.ShieldCheck, bossOnly:true, badge:3 },
      { key:'audit',    label:t('admin.audit'),    icon:Icon.History,    bossOnly:true },
      { key:'settings', label:t('admin.settings'), icon:Icon.Settings },
    ]},
  ];

  // Filter locked items for non-boss? Keep visible but lock inside (per spec FeatureGuard)
  const pages = {
    dashboard: <Dashboard setPage={setPage} userObj={userObj} role={currentRole}/>,
    production: <FeatureGuard ok={features.view_production}><Production role={currentRole}/></FeatureGuard>,
    inventory:  <FeatureGuard ok={features.view_inventory}><Inventory role={currentRole}/></FeatureGuard>,
    employees:  <FeatureGuard ok={features.view_employees || isBoss}><Employees role={currentRole}/></FeatureGuard>,
    attendance: <FeatureGuard ok={features.view_employees || isBoss}><Attendance role={currentRole}/></FeatureGuard>,
    hr:         <FeatureGuard ok={features.hr_management || isBoss}><HRLeave role={currentRole} userObj={userObj}/></FeatureGuard>,
    expenses:   <FeatureGuard ok={features.view_expenses}><ExpensesOutlet role={currentRole}/></FeatureGuard>,
    deposits:   <FeatureGuard ok={features.view_deposits}><Deposits role={currentRole}/></FeatureGuard>,
    analytics:  <FeatureGuard ok={features.view_analytics}><Analytics role={currentRole}/></FeatureGuard>,
    users:      <FeatureGuard ok={isBoss}><UserManagement role={currentRole}/></FeatureGuard>,
    audit:      <FeatureGuard ok={isBoss}><AuditLog role={currentRole}/></FeatureGuard>,
    settings:   <Settings role={currentRole} userObj={userObj} theme={window.__tweaks?.theme||'dark'} setTheme={(t)=>{ if (window.__applyGhTheme) window.__applyGhTheme(t); }} accent={window.__tweaks?.accent||'terracotta'} setAccent={(a)=>{window.__setAccent&&window.__setAccent(a);}} fontSizeName={(window.__tweaks&&window.__tweaks.fontSize)||document.documentElement.getAttribute('data-font-size')||'lg'} setFontSizeName={(n)=>{window.__setTextSize&&window.__setTextSize(n);}} lang={window.__lang||'en'} setLang={(l)=>{window.setLang&&window.setLang(l);}}/>,
  };

  const pageTitles = {
    dashboard:  [t('admin.dashboard'), t('admin.welcome_sub')],
    production: [t('admin.production'), 'Log batches, track flavor output'],
    inventory:  [t('admin.inventory'), 'Stock levels across all ingredients'],
    employees:  [t('admin.employees'), 'Team directory and profiles'],
    attendance: ['Attendance', 'Clock-ins, overrides, and device status'],
    hr:         [t('admin.hr'), 'Leave requests and warnings'],
    expenses:   [t('admin.expenses'), t('admin.expenses_sub')],
    deposits:   [t('admin.deposits'), 'Bank deposit records and receipts'],
    analytics:  [t('admin.analytics'), 'Revenue, flavors, production, stock'],
    users:      [t('admin.users'), 'Approve accounts and manage permissions'],
    audit:      [t('admin.audit'), 'Every change, every user'],
    settings:   [t('admin.settings'), 'Preferences, profile, appearance'],
  };

  const sidebarW = collapsed ? 'var(--sidebar-collapsed-w)' : 'var(--sidebar-w)';

  return (
    <div style={{display:'flex',minHeight:'100vh',background:'var(--bg)'}}>
      {/* Sidebar */}
      <aside className="hide-md" style={{
        width: sidebarW, flexShrink:0,
        background:'var(--surface)',
        borderRight:'1px solid var(--border)',
        display:'flex',flexDirection:'column',
        transition:'width .3s ease',
        position:'sticky', top:0, height:'100vh',
        overflow:'hidden',
      }}>
        <SidebarInner
          collapsed={collapsed} setCollapsed={setCollapsed}
          navGroups={navGroups} page={page} setPage={setPage}
          isBoss={isBoss} currentRole={currentRole} userObj={userObj}
          onExit={onExit}
          onLogout={onLogout}
        />
      </aside>

      {/* Mobile drawer sidebar */}
      {mobileSidebar && (
        <div style={{position:'fixed',inset:0,zIndex:200,background:'rgba(0,0,0,0.55)'}} onClick={()=>setMobileSidebar(false)}>
          <aside onClick={e=>e.stopPropagation()} style={{width:260,height:'100%',background:'var(--surface)',borderRight:'1px solid var(--border)',display:'flex',flexDirection:'column'}}>
            <SidebarInner
              collapsed={false} setCollapsed={()=>{}}
              navGroups={navGroups} page={page} setPage={(p)=>{setPage(p);setMobileSidebar(false);}}
              isBoss={isBoss} currentRole={currentRole} userObj={userObj}
              onExit={onExit}
              onLogout={onLogout}
            />
          </aside>
        </div>
      )}

      {/* Main */}
      <div style={{flex:1,minWidth:0,display:'flex',flexDirection:'column'}}>
        <Topbar
          title={pageTitles[page][0]} subtitle={pageTitles[page][1]}
          onToggleNotif={()=>setNotifOpen(v=>!v)}
          onMenu={()=>setMobileSidebar(true)}
          currentRole={currentRole} userObj={userObj}
          onLogout={onLogout}
        />
        <main style={{padding:'28px 36px 120px',flex:1,overflow:'auto'}} className="admin-main">
          <div className="fade-in" key={page}>
            {pages[page] || <div>Page not found</div>}
          </div>
        </main>
        <MobileBottomNav page={page} setPage={setPage} onMenu={()=>setMobileSidebar(true)}/>
      </div>

      {/* Notification panel */}
      {notifOpen && <NotificationPanel onClose={()=>setNotifOpen(false)} role={currentRole}/>}

      <style>{`
        @media (max-width: 900px) {
          .admin-main { padding: 20px 18px 100px !important; }
        }
      `}</style>
    </div>
  );
}

function SidebarInner({ collapsed, setCollapsed, navGroups, page, setPage, isBoss, currentRole, userObj, onExit, onLogout }) {
  const { t } = useT();
  return (
    <>
      {/* Logo */}
      <div style={{padding: collapsed ? '20px 0' : '22px 22px',display:'flex',alignItems:'center',gap:10,borderBottom:'1px solid var(--border)',justifyContent: collapsed ? 'center' : 'flex-start'}}>
        <div style={{width:32,height:32,borderRadius:10,background:'linear-gradient(135deg, var(--accent), var(--accent-light))',display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0}}>
          <Icon.IceCream size={18} style={{color:'white'}}/>
        </div>
        {!collapsed && (
          <div>
            <div style={{fontFamily:'Cormorant Garamond',fontSize:20,fontWeight:500,lineHeight:1}}>
              Gelato <span style={{fontStyle:'italic',color:'var(--accent)'}}>House</span>
            </div>
            <div style={{fontSize:10,letterSpacing:'0.15em',textTransform:'uppercase',color:'var(--text-dim)',marginTop:3,fontFamily:'JetBrains Mono'}}>Admin Portal</div>
          </div>
        )}
      </div>

      {/* User card */}
      {!collapsed && (
        <div style={{padding:'18px 18px',display:'flex',gap:12,alignItems:'center',margin:'16px',background:'var(--card)',borderRadius:'var(--radius-md)',border:'1px solid var(--border)'}}>
          <div style={{ position: 'relative', flexShrink: 0 }}>
            <TopbarAvatar userObj={userObj} size={40} />
            <div style={{position:'absolute',bottom:-2,right:-2,width:12,height:12,borderRadius:'50%',background:'var(--green)',border:'2px solid var(--surface)',animation:'pulseDot 2s infinite'}}/>
          </div>
          <div style={{minWidth:0}}>
            <div style={{fontSize:13,fontWeight:500,whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis'}}>{userObj.full_name}</div>
            <div style={{fontSize:11,color:'var(--text-dim)',textTransform:'capitalize'}}>{currentRole.replace('_',' ')}</div>
          </div>
        </div>
      )}

      {/* Nav */}
      <nav className="sidebar-scroll" style={{flex:1,overflow:'auto',padding: collapsed ? '8px 6px' : '0 12px'}}>
        {navGroups.map((g, gi) => (
          <div key={gi} style={{marginBottom:18}}>
            {!collapsed && <div style={{fontSize:10,letterSpacing:'0.18em',textTransform:'uppercase',color:'var(--text-dimmer)',padding:'8px 10px',fontFamily:'JetBrains Mono'}}>{g.label}</div>}
            {g.items.map(item => {
              if (item.bossOnly && !isBoss) return null;
              const Ico = item.icon;
              const active = page === item.key;
              return (
                <button key={item.key} onClick={()=>setPage(item.key)}
                  title={collapsed ? item.label : undefined}
                  style={{
                    width:'100%', display:'flex', alignItems:'center', gap:12,
                    padding: collapsed ? '11px 0' : '10px 12px',
                    justifyContent: collapsed ? 'center' : 'flex-start',
                    borderRadius: 'var(--radius-sm)',
                    fontSize: 13, fontWeight: 500,
                    color: active ? 'var(--accent)' : 'var(--text)',
                    background: active ? 'var(--accent-dim)' : 'transparent',
                    borderLeft: active && !collapsed ? '2px solid var(--accent)' : '2px solid transparent',
                    marginBottom: 2,
                    transition:'all .15s ease',
                  }}
                  onMouseEnter={e=>{ if(!active) e.currentTarget.style.background='var(--card)'; }}
                  onMouseLeave={e=>{ if(!active) e.currentTarget.style.background='transparent'; }}
                >
                  <Ico size={17} stroke={active?1.8:1.6}/>
                  {!collapsed && <span style={{flex:1,textAlign:'start'}}>{item.label}</span>}
                  {!collapsed && item.badge && (
                    <span style={{background:'var(--accent)',color:'white',fontSize:10,padding:'1px 7px',borderRadius:999,fontWeight:600}}>{item.badge}</span>
                  )}
                </button>
              );
            })}
          </div>
        ))}
      </nav>

      {isBoss && !collapsed && (
        <details style={{
          margin: '8px 12px',
          padding: '10px 12px',
          background: 'var(--card)',
          border: '1px solid var(--border2)',
          borderRadius: 10,
          fontSize: 12,
        }}>
          <summary style={{ cursor: 'pointer', fontWeight: 600, color: 'var(--accent)', listStyle: 'none' }}>{t('admin.boss_panel')}</summary>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 6, marginTop: 10 }}>
            <button type="button" className="btn btn-ghost btn-sm" style={{ justifyContent: 'flex-start' }} onClick={() => setPage('users')}><Icon.ShieldCheck size={14}/> {t('admin.users')}</button>
            <button type="button" className="btn btn-ghost btn-sm" style={{ justifyContent: 'flex-start' }} onClick={() => setPage('hr')}><Icon.Briefcase size={14}/> {t('admin.hr')}</button>
            <button type="button" className="btn btn-ghost btn-sm" style={{ justifyContent: 'flex-start' }} onClick={() => setPage('audit')}><Icon.History size={14}/> {t('admin.audit')}</button>
            <button type="button" className="btn btn-ghost btn-sm" style={{ justifyContent: 'flex-start' }} onClick={() => setPage('settings')}><Icon.Settings size={14}/> {t('admin.settings')}</button>
          </div>
        </details>
      )}

      {/* Collapse / exit */}
      <div style={{padding:12,borderTop:'1px solid var(--border)',display:'flex',flexDirection:'column',gap:6}}>
        {typeof onLogout === 'function' && (
          <button onClick={() => onLogout()} style={{display:'flex',alignItems:'center',gap:10,padding:'10px 12px',fontSize:12,color:'var(--gold)',justifyContent: collapsed?'center':'flex-start'}}>
            <Icon.LogOut size={15}/> {!collapsed && <span>{t('admin.logout')}</span>}
          </button>
        )}
        <button onClick={onExit} style={{display:'flex',alignItems:'center',gap:10,padding:'10px 12px',fontSize:12,color:'var(--text-dim)',justifyContent: collapsed?'center':'flex-start'}}>
          <Icon.Globe size={15}/> {!collapsed && <span>{t('admin.public_site')}</span>}
        </button>
        <button onClick={()=>setCollapsed(v=>!v)} style={{display:'flex',alignItems:'center',gap:10,padding:'10px 12px',fontSize:12,color:'var(--text-dim)',justifyContent:collapsed?'center':'flex-start'}}>
          {collapsed ? <Icon.ChevronRight size={15}/> : <><Icon.ChevronLeft size={15}/><span>Collapse</span></>}
        </button>
      </div>
    </>
  );
}

function TopbarAvatar({ userObj, size }) {
  const [bad, setBad] = React.useState(false);
  const s = size || 36;
  if (!userObj.avatar_url || bad) {
    return (
      <div style={{ width: s, height: s, borderRadius: '50%', background: 'var(--accent-dim)', color: 'var(--accent)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontWeight: 600, border: '1px solid var(--accent-border)', fontSize: s > 32 ? 13 : 11, flexShrink: 0 }}>
        {userObj.initials}
      </div>
    );
  }
  return <img alt="" src={userObj.avatar_url} width={s} height={s} style={{ borderRadius: '50%', objectFit: 'cover', border: '1px solid var(--accent-border)', flexShrink: 0 }} onError={() => setBad(true)} />;
}

function Topbar({ title, subtitle, onToggleNotif, onMenu, currentRole, userObj, onLogout }) {
  const { t, lang } = useT();
  const unread = (NOTIFICATIONS_BY_ROLE[currentRole] || []).filter(n=>!n.read).length;
  return (
    <header style={{
      height:'var(--topbar-h)', padding:'0 28px',
      display:'flex', alignItems:'center', justifyContent:'space-between',
      borderBottom:'1px solid var(--border)',
      background:'var(--bg)',
      position:'sticky', top:0, zIndex:50,
      gap:20,
      flexWrap:'nowrap',
    }} className="admin-topbar">
      <div style={{display:'flex',alignItems:'center',gap:16,minWidth:0}}>
        <button className="show-md" onClick={onMenu}><Icon.Menu size={22}/></button>
        <div style={{minWidth:0}}>
          <h1 style={{fontSize:22,fontWeight:400,letterSpacing:'-0.01em',lineHeight:1.1,whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis'}}>
            {title}
          </h1>
          <div className="hide-md" style={{fontSize:12,color:'var(--text-dim)',marginTop:2}}>{subtitle}</div>
        </div>
      </div>
      <div style={{display:'flex',alignItems:'center',gap:10}}>
        <FontSizeButtons/>
        <button className="tip hide-md" data-tip="Search" style={{padding:8,color:'var(--text-dim)'}}>
          <Icon.Search size={18}/>
        </button>
        <button onClick={onToggleNotif} style={{padding:8,color:'var(--text-dim)',position:'relative'}}>
          <Icon.Bell size={18}/>
          {unread > 0 && (
            <span style={{position:'absolute',top:3,right:3,background:'var(--accent)',color:'white',fontSize:9,padding:'1px 5px',borderRadius:999,fontWeight:700}}>{unread}</span>
          )}
        </button>
        <ThemeToggleButton/>
        <div className="hide-md"><LangSwitch/></div>
        <div title={userObj.full_name}><TopbarAvatar userObj={userObj} size={36} /></div>
        {typeof onLogout === 'function' && (
          <button type="button" className="hide-md btn btn-ghost btn-sm" onClick={()=>onLogout()} style={{flexShrink:0}}>{t('admin.logout')}</button>
        )}
      </div>
    </header>
  );
}

const _ADMIN_TEXT_SIZES = ['sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl'];

function FontSizeButtons() {
  const { t } = useT();
  const [cur, setCur] = React.useState(() => document.documentElement.getAttribute('data-font-size') || 'lg');
  React.useEffect(() => {
    const h = () => setCur(document.documentElement.getAttribute('data-font-size') || 'lg');
    window.addEventListener('tweak-change', h);
    return () => window.removeEventListener('tweak-change', h);
  }, []);
  const idx = _ADMIN_TEXT_SIZES.indexOf(cur);
  const step = (d) => {
    const n = idx + d;
    if (n < 0 || n >= _ADMIN_TEXT_SIZES.length) return;
    if (window.__setTextSize) window.__setTextSize(_ADMIN_TEXT_SIZES[n]);
  };
  const short = cur === '2xl' ? '2×' : cur === '3xl' ? '3×' : cur === '4xl' ? 'max' : cur.toUpperCase();
  return (
    <div className="hide-md" style={{ display: 'flex', alignItems: 'center', gap: 4, padding: '3px 6px', border: '1px solid var(--border)', borderRadius: 999 }} title={t('nav.size')}>
      <button type="button" aria-label={t('a11y.size_minus')} onClick={() => step(-1)} disabled={idx <= 0} style={{ padding: '4px 10px', borderRadius: 999, border: 'none', background: 'transparent', color: 'var(--text)', cursor: idx <= 0 ? 'not-allowed' : 'pointer', opacity: idx <= 0 ? 0.35 : 1, fontWeight: 700, fontSize: 13, letterSpacing: '-0.02em' }}>A−</button>
      <button type="button" aria-label={t('a11y.size_plus')} onClick={() => step(1)} disabled={idx >= _ADMIN_TEXT_SIZES.length - 1} style={{ padding: '4px 10px', borderRadius: 999, border: 'none', background: 'transparent', color: 'var(--accent)', cursor: idx >= _ADMIN_TEXT_SIZES.length - 1 ? 'not-allowed' : 'pointer', opacity: idx >= _ADMIN_TEXT_SIZES.length - 1 ? 0.35 : 1, fontWeight: 700, fontSize: 13, letterSpacing: '-0.02em' }}>A+</button>
    </div>
  );
}

function ThemeToggleButton() {
  const { t } = useT();
  const readTheme = () => {
    if (document.body.classList.contains('theme-light')) return 'light';
    if (document.body.classList.contains('theme-sand')) return 'sand';
    return 'dark';
  };
  const [theme, setTheme] = React.useState(readTheme);
  const toggle = () => {
    const cur = readTheme();
    const next = cur === 'light' ? 'dark' : 'light';
    if (window.__applyGhTheme) window.__applyGhTheme(next);
  };
  React.useEffect(() => {
    const h = () => setTheme(readTheme());
    window.addEventListener('tweak-change', h);
    return () => window.removeEventListener('tweak-change', h);
  }, []);
  const isLight = theme === 'light';
  return (
    <button
      type="button"
      onClick={toggle}
      title={isLight ? t('nav.theme_toggle_dark') : t('nav.theme_toggle_light')}
      aria-label={isLight ? t('nav.theme_toggle_dark') : t('nav.theme_toggle_light')}
      style={{ padding: 8, color: 'var(--text-dim)' }}
    >
      {isLight ? <Icon.Sun size={18}/> : <Icon.Moon size={18}/>}
    </button>
  );
}

function FeatureGuard({ ok, children }) {
  const { t } = useT();
  if (ok) return children;
  return (
    <div style={{display:'flex',flexDirection:'column',alignItems:'center',justifyContent:'center',height:'60vh',gap:16,textAlign:'center',padding:30}}>
      <div style={{width:72,height:72,borderRadius:'50%',background:'var(--card2)',border:'1px solid var(--border)',display:'flex',alignItems:'center',justifyContent:'center',color:'var(--text-dim)'}}>
        <Icon.Lock size={28}/>
      </div>
      <h3 style={{fontFamily:'Cormorant Garamond',fontSize:30,fontWeight:400}}>{t('access.denied_title')}</h3>
      <p style={{color:'var(--text-dim)',maxWidth:420,lineHeight:1.6,fontSize:14}}>{t('access.denied_message')}</p>
      <div className="chip" style={{marginTop:8,fontFamily:'JetBrains Mono',fontSize:10,letterSpacing:'0.15em',textTransform:'uppercase'}}>
        Try the Tweaks panel → change role to <span style={{color:'var(--accent)',marginLeft:4}}>boss</span>
      </div>
    </div>
  );
}

function NotificationPanel({ onClose, role }) {
  const { t } = useT();
  const [items, setItems] = React.useState(NOTIFICATIONS_BY_ROLE[role] || []);
  const markAll = () => setItems(items.map(i => ({...i, read:true})));
  const typeIcon = { info: Icon.Info, warning: Icon.AlertTriangle, success: Icon.Check, error: Icon.X };
  const typeColor = { info:'var(--blue)', warning:'var(--gold)', success:'var(--green)', error:'var(--red)' };
  return (
    <>
      <div onClick={onClose} style={{position:'fixed',inset:0,background:'rgba(0,0,0,0.4)',zIndex:180}}/>
      <aside style={{position:'fixed',right:0,top:0,bottom:0,width:380,maxWidth:'95vw',background:'var(--surface)',borderLeft:'1px solid var(--border)',zIndex:190,display:'flex',flexDirection:'column',animation:'fadeUp .3s ease'}}>
        <div style={{padding:'20px 22px',borderBottom:'1px solid var(--border)',display:'flex',justifyContent:'space-between',alignItems:'center'}}>
          <h3 style={{fontSize:20,fontWeight:400}}>{t('notifications.title')}</h3>
          <button onClick={onClose} style={{padding:6,color:'var(--text-dim)'}}><Icon.X size={18}/></button>
        </div>
        <div style={{padding:'10px 22px',borderBottom:'1px solid var(--border)',display:'flex',justifyContent:'space-between',alignItems:'center',fontSize:12}}>
          <span style={{color:'var(--text-dim)'}}>{items.filter(i=>!i.read).length} unread</span>
          <button onClick={markAll} style={{color:'var(--accent)',fontSize:12,fontWeight:500}}>{t('notifications.mark_all_read')}</button>
        </div>
        <div style={{flex:1,overflow:'auto'}}>
          {items.length === 0 ? (
            <div style={{padding:40,textAlign:'center',color:'var(--text-dim)'}}>{t('notifications.empty')}</div>
          ) : items.map(n => {
            const Ic = typeIcon[n.type] || Icon.Info;
            return (
              <div key={n.id} style={{padding:'16px 22px',borderBottom:'1px solid var(--border)',display:'flex',gap:12,background: n.read ? 'transparent' : 'var(--accent-dim)'}}>
                <div style={{width:32,height:32,borderRadius:'50%',background:'var(--card)',border:'1px solid var(--border)',display:'flex',alignItems:'center',justifyContent:'center',color:typeColor[n.type],flexShrink:0}}>
                  <Ic size={15}/>
                </div>
                <div style={{flex:1,minWidth:0}}>
                  <div style={{fontSize:13,fontWeight:500,marginBottom:4}}>{n.title}</div>
                  <div style={{fontSize:12,color:'var(--text-dim)',lineHeight:1.5}}>{n.message}</div>
                  <div style={{fontSize:10,color:'var(--text-dimmer)',marginTop:6,fontFamily:'JetBrains Mono'}}>{fmtDateTime(n.created_at)}</div>
                </div>
                {!n.read && <div style={{width:6,height:6,borderRadius:'50%',background:'var(--accent)',marginTop:8,flexShrink:0}}/>}
              </div>
            );
          })}
        </div>
      </aside>
    </>
  );
}

function MobileBottomNav({ page, setPage, onMenu }) {
  const items = [
    { k:'dashboard', l:'Home', Ic:Icon.LayoutDashboard },
    { k:'inventory', l:'Stock', Ic:Icon.Box },
    { k:'production', l:'Produce', Ic:Icon.IceCream },
    { k:'analytics', l:'Data', Ic:Icon.TrendingUp },
  ];
  return (
    <nav className="show-md" style={{
      position:'fixed',bottom:0,left:0,right:0,zIndex:60,
      background:'var(--surface)',borderTop:'1px solid var(--border)',
      display:'flex',justifyContent:'space-around',padding:'10px 4px 14px',
    }}>
      {items.map(i => {
        const active = page === i.k;
        return (
          <button key={i.k} onClick={()=>setPage(i.k)} style={{display:'flex',flexDirection:'column',alignItems:'center',gap:2,padding:'6px 12px',color: active ? 'var(--accent)' : 'var(--text-dim)',fontSize:10,letterSpacing:'0.05em'}}>
            <i.Ic size={22} stroke={active?1.8:1.5}/>
            <span>{i.l}</span>
          </button>
        );
      })}
      <button onClick={onMenu} style={{display:'flex',flexDirection:'column',alignItems:'center',gap:2,padding:'6px 12px',color:'var(--text-dim)',fontSize:10}}>
        <Icon.Menu size={22}/><span>More</span>
      </button>
    </nav>
  );
}

// ---------- Shared UI helpers ----------

function KPI({ label, value, delta, icon: Ic, color='var(--accent)', spark }) {
  const positive = delta >= 0;
  return (
    <div className="card" style={{padding:22,position:'relative',overflow:'hidden'}}>
      <div style={{display:'flex',justifyContent:'space-between',marginBottom:14}}>
        <div style={{width:36,height:36,borderRadius:10,background:`color-mix(in oklch, ${color} 15%, transparent)`,display:'flex',alignItems:'center',justifyContent:'center',color}}>
          {Ic && <Ic size={17}/>}
        </div>
        {typeof delta === 'number' && (
          <div style={{fontSize:11,fontWeight:500,color: positive ? 'var(--green)' : 'var(--red)',display:'flex',alignItems:'center',gap:3}}>
            <span style={{transform: positive ? 'rotate(-45deg)' : 'rotate(45deg)'}}>→</span>
            {positive?'+':''}{delta}%
          </div>
        )}
      </div>
      <div style={{fontSize:11,letterSpacing:'0.15em',textTransform:'uppercase',color:'var(--text-dim)',fontFamily:'JetBrains Mono',marginBottom:6}}>{label}</div>
      <div style={{fontFamily:'Cormorant Garamond',fontSize:34,fontWeight:400,lineHeight:1,letterSpacing:'-0.01em'}}>{value}</div>
      {spark && (
        <svg className="spark" style={{position:'absolute',bottom:0,right:0,width:'100%',height:40,opacity:0.25,pointerEvents:'none'}} viewBox="0 0 100 40" preserveAspectRatio="none">
          <path d={spark} stroke={color}/>
        </svg>
      )}
    </div>
  );
}

function StatusBadge({ status }) {
  const map = {
    ok: ['Ok','badge-green'],
    low: ['Low stock','badge-gold'],
    critical: ['Critical','badge-red'],
    active: ['Active','badge-green'],
    waitlist: ['Waitlist','badge-gold'],
    suspended: ['Suspended','badge-red'],
    pending: ['Pending','badge-gold'],
    approved: ['Approved','badge-green'],
    denied: ['Denied','badge-red'],
    completed: ['Completed','badge-green'],
    in_progress: ['In progress','badge-gold'],
    planned: ['Planned','badge-blue'],
    minor: ['Minor','badge-blue'],
    major: ['Major','badge-gold'],
    final: ['Final','badge-red'],
  };
  const [label, cls] = map[status] || [status, 'badge-muted'];
  return <span className={'badge '+cls}><span className="badge-dot" style={{background:'currentColor'}}/>{label}</span>;
}

function TablePanel({ title, right, children }) {
  return (
    <div className="card" style={{padding:0,overflow:'hidden'}}>
      {title && (
        <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',padding:'18px 22px',borderBottom:'1px solid var(--border)',gap:12,flexWrap:'wrap'}}>
          <h3 style={{fontSize:18,fontWeight:400}}>{title}</h3>
          {right}
        </div>
      )}
      <div style={{overflow:'auto'}}>{children}</div>
    </div>
  );
}

function Th({ children, w, align }) {
  return <th style={{padding:'12px 16px',fontSize:11,letterSpacing:'0.12em',textTransform:'uppercase',color:'var(--text-dim)',textAlign:align||'start',fontWeight:500,borderBottom:'1px solid var(--border)',whiteSpace:'nowrap',width:w,fontFamily:'JetBrains Mono'}}>{children}</th>;
}
function Td({ children, align, w, style }) {
  return <td style={{padding:'14px 16px',fontSize:13,borderBottom:'1px solid var(--border)',textAlign:align||'start',verticalAlign:'middle',width:w,...style}}>{children}</td>;
}

Object.assign(window, { AdminShell, KPI, StatusBadge, TablePanel, Th, Td, FeatureGuard });
