// ViG Command Center — app shell, routing, topbar, export
const { useState: useStateApp, useEffect: useEffectApp } = React;

const NAV = [
  { section: 'Alliance Command', items: [
    { id: 'ai', label: 'AI Assistant', icon: 'sparkle' },
    { id: 'battlereport', label: 'Battle Report', icon: 'target' },
    { id: 'warsim', label: 'War Simulator', icon: 'scale' },
    { id: 'command', label: 'Command Center', icon: 'grid' },
    { id: 'analysis', label: 'Account Analysis', icon: 'target' },
    { id: 'guide', label: 'Guide & Learn', icon: 'book' },
    { id: 'roadmap', label: 'Growth Roadmap', icon: 'arrow' },
    { id: 'resourceplanner', label: 'Resource Planner', icon: 'layers' },
    { id: 'achievements', label: 'Achievements', icon: 'trophy' },
    { id: 'warroom', label: 'Alliance War Room', icon: 'trophy' },
    { id: 'diplomacy', label: 'Diplomacy Map', icon: 'link' },
    { id: 'rally', label: 'Rally Team Buffs', icon: 'layers' },
    { id: 'discord', label: 'Discord', icon: 'chat' },
    { id: 'events', label: 'Event Planner', icon: 'target' },
    { id: 'subs', label: 'Sub Cities', icon: 'star' },
    { id: 'users', label: 'User Management', icon: 'shield', admin: true },
  ] },
  { section: 'Generals HQ', items: [
    { id: 'generals', label: 'General Database', icon: 'database' },
    { id: 'compare', label: 'General Comparison', icon: 'scale' },
    { id: 'tierlist', label: 'Tier List Hub', icon: 'trophy' },
    { id: 'roster', label: 'Roster Analytics', icon: 'target' },
    { id: 'covenants', label: 'Covenant Center', icon: 'link' },
    { id: 'flexspec', label: 'Flexible Specialty', icon: 'star' },
    { id: 'dragons', label: 'Dragon Center', icon: 'flame' },
    { id: 'dragonmatrix', label: 'Dragon Matrix', icon: 'grid' },
  ] },
  { section: 'Buff Intelligence', items: [
    { id: 'tools', label: 'Calculator', icon: 'bolt', children: [
      { label: '🏹 Troop Training', sub: 'troop' },
      { label: '⚡ Speedups', sub: 'speedup' },
      { label: '📦 Resources', sub: 'resource' },
      { label: '🩸 Blood of Ares', sub: 'ares' },
      { label: '🏰 Buildings', sub: 'bcost' },
      { label: '⛏️ Gathering', sub: 'gather' },
      { label: '🏯 Keep', page: 'construction' },
      { label: '🚩 Rally Size', page: 'rallysize' },
      { label: '⚔️ March Size', page: 'march' },
      { label: '🛡️ Gear Calculator', page: 'gear' },
    ] },
    { id: 'champions', label: 'Champion Hall', icon: 'trophy' },
    { id: 'seal', label: 'Beast Seal', icon: 'shield' },
    { id: 'senate', label: 'Senete', icon: 'target' },
    { id: 'land', label: 'Ideal Land', icon: 'grid' },
    { id: 'academy', label: 'Academy', icon: 'shield' },
    { id: 'milacademy', label: 'Military Academy', icon: 'trophy' },
  ] },
];
const PAGE_TITLE = {
  command: ['Command Center', 'Live account intelligence, readiness & priorities'],
  ai: ['AI Assistant', 'Ask anything — grounded in your live account data'],
  warsim: ['War Simulator', 'Adjust alliance stats & simulate any event outcome'],
  battlereport: ['Battle Report', 'Paste a report — AI explains mistakes & buff gaps'],
  discord: ['Discord', 'Auto-post briefings, alerts & digests to your channel'],
  diplomacy: ['Diplomacy Map', 'Map your server\u2019s alliances, allies & enemies'],
  settings: ['Settings', 'Appearance, data, integrations & about'],
  events: ['Event Planner', 'Live countdowns & prep for every major event'],
  tierlist: ['Tier List Hub', 'Data-driven S/A/B/C rankings of every general'],
  roster: ['Roster Analytics', 'Ownership analytics, gaps & what to chase next'],
  roadmap: ['Growth Roadmap', 'A phased plan from your keep to your goal'],
  resourceplanner: ['Resource Planner', 'Plan your RSS needs across upgrades & training'],
  dragonmatrix: ['Dragon Matrix', 'Pairing matrix & value ranking for all 17 dragons'],
  achievements: ['Achievements', 'Your level, streak, badges & the power leaderboard'],
  guide: ['Guide & Learn', 'Master Evony — from keep basics to rally tactics'],
  users: ['User Management', 'Add members, assign roles & control access'],
  analysis: ['Account Analysis', 'Module-by-module health breakdown & weaknesses'],
  knowledge: ['Guide & Learn', 'ViG guides, checklists & strategic references'],
  tools: ['Calculator', 'Quick calculators — troops, speedups, resources, marches & buildings'],
  subs: ['Sub Cities', 'Server 428 sub-city tracker — live data feed'],
  dashboard: ['Command Center', 'Live account intelligence, readiness & priorities'],
  dashboard: ['Dashboard', 'Command overview of your roster and covenants'],
  generals: ['General Database', 'Search, filter, and track all 176 generals'],
  compare: ['General Comparison', 'Stack two generals head to head'],
  covenants: ['Covenant Center', 'Track completion across every set & rank what to unlock next'],
  optimizer: ['Covenant Center', 'Track completion across every set & rank what to unlock next'],
  dragons: ['Dragon Center', 'Assign dragons per troop type & browse the full codex'],
  march: ['March Size', 'Compose marches and size rally presets'],
  warroom: ['Alliance War Room', 'Live three-way standings, analytics & forecasting'],
  rally: ['Rally Team Buffs', 'Monthly in-rally buff heatmap for the ViG team'],
  land: ['Ideal Land', 'Plan decorations for prosperity, march size & coin cost'],
  gear: ['Gear Calculator', 'Compare two gear loadouts — buffs, set bonuses & debuffs'],
  flexspec: ['Flexible Specialty', 'Stats gained & runestone cost by level'],
  champions: ['Champion Hall', 'Buffs unlocked & EXP cost by level'],
  seal: ['Beast Seal', 'Sacred beast seal attributes & innate skills'],
  rallysize: ['Rally Size', 'Calculate your total rally capacity'],
  senate: ['Senete', 'Senate position buffs & leveling cost'],
  dragoncodex: ['Dragon Codex', 'Dragon unlocks, buffs, talents, stats & leveling cost'],
  construction: ['Keep', 'K40→K50 RSS planning, timelines & speed buffs'],
  academy: ['Academy', 'Academy 41–45 — research buffs, debuffs & costs per level'],
  milacademy: ['Military Academy', 'Gold, Tactics & Compendium costs per level 1–15'],
};

function exportCSV() {
  const own = LS.get('vig2_ownership', {});
  const rows = [['Name', 'Type', 'Rank', 'Power', 'AttackBuff', 'DefenseBuff', 'Owned']];
  window.VIG.generals.forEach(g => rows.push([g.name, g.type, g.rank, g.power, g.totAtk, g.totDef, own[g.name + '|' + g.type] ? 'Yes' : 'No']));
  const csv = rows.map(r => r.map(c => `"${String(c).replace(/"/g, '""')}"`).join(',')).join('\n');
  const blob = new Blob([csv], { type: 'text/csv' });
  const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = 'vig-roster.csv'; a.click();
}

function RoleMenu({ role, setRole }) {
  const [open, setOpen] = useStateApp(false);
  return (
    <div className="relative">
      <button onClick={() => setOpen(o => !o)} className="flex items-center gap-2 rounded-lg border border-zinc-200 bg-white px-2.5 py-1.5 text-[13px] dark:border-zinc-700 dark:bg-zinc-900">
        <span className={`h-1.5 w-1.5 rounded-full ${role === 'Guest' ? 'bg-zinc-400' : 'bg-emerald-500'}`}></span>
        <span className="font-medium text-zinc-700 dark:text-zinc-200">{role}</span>
        <Icon name="chevron" size={13} className={`text-zinc-300 transition-transform ${open ? 'rotate-90' : ''}`} />
      </button>
      {open && (
        <>
          <div className="fixed inset-0 z-20" onClick={() => setOpen(false)}></div>
          <div className="absolute right-0 z-30 mt-1.5 w-44 overflow-hidden rounded-xl border border-zinc-200 bg-white p-1 shadow-xl dark:border-zinc-700 dark:bg-zinc-900">
            {['Admin', 'Member', 'Guest'].map(r => (
              <button key={r} onClick={() => { setRole(r); setOpen(false); }} className="flex w-full items-center justify-between rounded-lg px-2.5 py-2 text-left text-[13px] hover:bg-zinc-50 dark:hover:bg-zinc-800">
                <div><div className="font-medium text-zinc-800 dark:text-zinc-100">{r}</div><div className="text-[11px] text-zinc-400">{r === 'Guest' ? 'Read-only' : 'Can edit ownership'}</div></div>
                {role === r && <Icon name="check" size={15} className="text-brand" />}
              </button>
            ))}
          </div>
        </>
      )}
    </div>
  );
}

function MarchHub() {
  return <MarchCenterPage />;
}

function CovenantHub({ go }) {
  const [sub, setSub] = useStateApp(() => LS.get('vig2_cov_sub', 'database'));
  useEffectApp(() => { LS.set('vig2_cov_sub', sub); }, [sub]);
  const TABS = [
    { id: 'database', label: 'Covenant Database', icon: 'link' },
    { id: 'optimizer', label: 'Optimizer', icon: 'target' },
  ];
  return (
    <div className="space-y-4">
      <div className="flex gap-1 border-b border-zinc-200 dark:border-zinc-800">
        {TABS.map(t => (
          <button key={t.id} onClick={() => setSub(t.id)}
            className={`relative flex items-center gap-1.5 px-3.5 pb-2.5 pt-1 text-[13.5px] font-medium transition-colors ${sub === t.id ? 'text-brand' : 'text-zinc-500 hover:text-zinc-800 dark:hover:text-zinc-200'}`}>
            <Icon name={t.icon} size={15} />{t.label}
            {sub === t.id && <span className="absolute inset-x-2 -bottom-px h-0.5 rounded-full bg-brand"></span>}
          </button>
        ))}
      </div>
      {sub === 'database' ? <CovenantPage /> : <OptimizerPage go={go} />}
    </div>
  );
}

function DragonHub({ initial }) {
  const [sub, setSub] = useStateApp(() => initial || LS.get('vig2_dragon_sub', 'manager'));
  useEffectApp(() => { LS.set('vig2_dragon_sub', sub); }, [sub]);
  const TABS = [
    { id: 'manager', label: 'Dragon Center', icon: 'flame' },
    { id: 'codex', label: 'Dragon Codex', icon: 'database' },
  ];
  return (
    <div className="space-y-4">
      <div className="flex gap-1 border-b border-zinc-200 dark:border-zinc-800">
        {TABS.map(t => (
          <button key={t.id} onClick={() => setSub(t.id)}
            className={`relative flex items-center gap-1.5 px-3.5 pb-2.5 pt-1 text-[13.5px] font-medium transition-colors ${sub === t.id ? 'text-brand' : 'text-zinc-500 hover:text-zinc-800 dark:hover:text-zinc-200'}`}>
            <Icon name={t.icon} size={15} />{t.label}
            {sub === t.id && <span className="absolute inset-x-2 -bottom-px h-0.5 rounded-full bg-brand"></span>}
          </button>
        ))}
      </div>
      {sub === 'manager' ? <DragonCenterPage /> : <DragonCodexPage />}
    </div>
  );
}

function HealthChip({ page, go }) {
  const score = React.useMemo(() => { try { return computeHealth().score; } catch (e) { return null; } }, [page]);
  if (score == null) return null;
  return (
    <button onClick={() => go('command')} title="Account Health — open Command Center" className="hidden items-center gap-2 rounded-lg border border-zinc-200 px-2.5 py-1.5 text-[13px] font-bold tabular-nums dark:border-zinc-700 sm:flex">
      <span className="h-2 w-2 rounded-full" style={{ background: scoreColor(score), boxShadow: `0 0 6px ${scoreColor(score)}` }}></span>
      <span className="text-zinc-800 dark:text-white">{score}</span>
      <span className="text-[10px] font-semibold uppercase tracking-wide text-zinc-400">HP</span>
    </button>
  );
}

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#E53935",
  "density": "standard",
  "atmosphere": "carbon"
}/*EDITMODE-END*/;

function hexToRgbStr(hex) {
  const m = /^#?([0-9a-f]{6})$/i.exec(hex || '');
  if (!m) return '229 57 53';
  const n = parseInt(m[1], 16);
  return `${(n >> 16) & 255} ${(n >> 8) & 255} ${n & 255}`;
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  React.useEffect(() => {
    const root = document.documentElement;
    root.style.setProperty('--brand-rgb', hexToRgbStr(t.accent));
    root.style.setProperty('--brand-hex', t.accent);
    root.dataset.density = t.density;
    root.dataset.atmosphere = t.atmosphere;
  }, [t.accent, t.density, t.atmosphere]);
  const [page, setPage] = useStateApp(() => location.hash.slice(1) || 'command');
  const [dark, setDark] = useStateApp(() => LS.get('vig2_dark', true));
  useEffectApp(() => { document.documentElement.classList.toggle('dark', dark); LS.set('vig2_dark', dark); }, [dark]);
  const [role, setRole] = useStateApp(() => LS.get('vig2_role', 'Admin'));
  const [session, setSession] = useStateApp(() => LS.get('vig2_session', null));
  const signIn = u => { LS.set('vig2_session', u); setSession(u); setRole(u.role); };
  const signOut = () => { try { localStorage.removeItem('vig2_session'); } catch (e) {} setSession(null); };
  // keep role in sync with the signed-in user's current roster role
  useEffectApp(() => {
    if (!session) return;
    const sync = () => { const list = LS.get('vig2_users', []); const me = list.find(x => x.id === session.id); if (me) { setSession(me); LS.set('vig2_session', me); setRole(me.role); } };
    window.addEventListener('vig-users', sync);
    return () => window.removeEventListener('vig-users', sync);
  }, [session && session.id]);
  const [navOpen, setNavOpen] = useStateApp(false);
  const [cmdk, setCmdk] = useStateApp(false);
  useEffectApp(() => {
    const h = e => { if ((e.metaKey || e.ctrlKey) && (e.key === 'k' || e.key === 'K')) { e.preventDefault(); setCmdk(o => !o); } };
    window.addEventListener('keydown', h);
    return () => window.removeEventListener('keydown', h);
  }, []);
  const cmdNavigate = (t) => {
    if (t.sub) { LS.set('vig2_tools_sub', t.sub); setPage('tools'); window.dispatchEvent(new CustomEvent('vig-tools-sub', { detail: t.sub })); }
    else setPage(t.page);
    if (t.search) { LS.set('vig2_db_search', t.search); setTimeout(() => window.dispatchEvent(new CustomEvent('vig-db-search', { detail: t.search })), 60); }
    setNavOpen(false);
  };
  const [tour, setTour] = useStateApp(false);
  useEffectApp(() => { if (session && !LS.get('vig2_onboarded', false)) setTour(true); }, [session && session.id]);
  const closeTour = () => { LS.set('vig2_onboarded', true); setTour(false); };
  useEffectApp(() => { const s = document.getElementById('vig-splash'); if (s) { s.style.opacity = '0'; setTimeout(() => s.remove(), 450); } }, []);
  useEffectApp(() => { if (session && window.dcAutoPost) { const t = setTimeout(() => window.dcAutoPost(), 3000); return () => clearTimeout(t); } }, [session && session.id]);
  useEffectApp(() => { LS.set('vig2_role', role); }, [role]);
  useEffectApp(() => { location.hash = page; setNavOpen(false); window.scrollTo(0, 0); }, [page]);
  const canEdit = ROLE_PERMS[role].edit;
  const gated = pg => !canAccessPage(pg, session) ? <TierGate page={pg} session={session} go={setPage} /> : null;
  const [title, subtitle] = PAGE_TITLE[page] || PAGE_TITLE.dashboard;

  const [calcOpen, setCalcOpen] = useStateApp(() => LS.get('vig2_nav_calc_open', false));
  useEffectApp(() => { LS.set('vig2_nav_calc_open', calcOpen); }, [calcOpen]);
  const openTool = (c) => {
    if (c.sub) { LS.set('vig2_tools_sub', c.sub); setPage('tools'); window.dispatchEvent(new CustomEvent('vig-tools-sub', { detail: c.sub })); }
    else setPage(c.page);
    setNavOpen(false);
  };

  const sidebar = (
    <div className="flex h-full flex-col">
      <div className="flex items-center gap-2.5 px-5 py-[18px]">
        <div className="glow-mark flex h-8 w-8 items-center justify-center"><VigCrest size={32} /></div>
        <div className="leading-tight"><div className="text-[14px] font-semibold text-zinc-900 dark:text-white">ViG Command</div><div className="text-[10px] uppercase tracking-wider text-zinc-400">Alliance Toolkit</div></div>
      </div>
      <nav className="flex-1 space-y-5 overflow-y-auto px-3 py-2">
        {NAV.map(grp => (
          <div key={grp.section}>
            <div className="px-2 pb-1.5 text-[10px] font-semibold uppercase tracking-wider text-zinc-300 dark:text-zinc-600">{grp.section}</div>
            <div className="space-y-0.5">
              {grp.items.filter(it => !it.admin || role === 'Admin').map(it => (
                <div key={it.id}>
                  <div className={`flex w-full items-center rounded-lg transition-colors ${page === it.id ? 'bg-brand/10 text-brand' : 'text-zinc-600 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800'}`}>
                    <button onClick={() => setPage(it.id)} className="flex flex-1 items-center gap-2.5 px-2.5 py-2 text-left text-[13.5px] font-medium">
                      <Icon name={it.icon} size={17} />{it.label}
                    </button>
                    {it.children && (
                      <button onClick={() => setCalcOpen(o => !o)} title={calcOpen ? 'Collapse' : 'Show all'}
                        className="mr-1.5 flex h-6 w-6 items-center justify-center rounded-md text-[15px] font-bold leading-none text-zinc-400 hover:bg-zinc-200/60 hover:text-zinc-700 dark:hover:bg-zinc-700 dark:hover:text-white">
                        {calcOpen ? '−' : '+'}
                      </button>
                    )}
                  </div>
                  {it.children && calcOpen && (
                    <div className="ml-4 mt-0.5 max-h-56 space-y-0.5 overflow-y-auto border-l border-zinc-200 pl-2 dark:border-zinc-800">
                      {it.children.map(c => (
                        <button key={c.label} onClick={() => openTool(c)}
                          className={`flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-[12.5px] transition-colors ${c.page && page === c.page ? 'bg-brand/10 font-medium text-brand' : 'text-zinc-500 hover:bg-zinc-100 hover:text-zinc-800 dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-zinc-100'}`}>
                          {c.label}
                        </button>
                      ))}
                    </div>
                  )}
                </div>
              ))}
            </div>
          </div>
        ))}
      </nav>
      <div className="border-t border-zinc-100 px-4 py-3 text-[11px] text-zinc-400 dark:border-zinc-800">176 generals · 75 covenants · 17 dragons</div>
    </div>
  );

  return (
    session ? <div className="flex min-h-screen bg-zinc-50 text-zinc-900 dark:bg-zinc-950 dark:text-zinc-100">
      <TweaksPanel>
        <TweakSection label="Identity" />
        <TweakColor label="Command accent" value={t.accent}
          options={['#E53935', '#FF6B00', '#2979FF', '#9C27B0']}
          onChange={v => setTweak('accent', v)} />
        <TweakSection label="Console feel" />
        <TweakRadio label="Atmosphere" value={t.atmosphere}
          options={['carbon', 'void']}
          onChange={v => setTweak('atmosphere', v)} />
        <TweakRadio label="Density" value={t.density}
          options={['standard', 'compact']}
          onChange={v => setTweak('density', v)} />
      </TweaksPanel>
      {/* desktop sidebar */}
      <aside className="sticky top-0 hidden h-screen w-60 shrink-0 border-r border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900 lg:block">{sidebar}</aside>
      {/* mobile drawer */}
      {navOpen && <div className="fixed inset-0 z-40 lg:hidden"><div className="absolute inset-0 bg-zinc-900/40" onClick={() => setNavOpen(false)}></div><div className="absolute left-0 top-0 h-full w-64 border-r border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900">{sidebar}</div></div>}

      <div className="flex min-w-0 flex-1 flex-col">
        <header className="sticky top-0 z-20 flex items-center gap-3 border-b border-zinc-200 bg-white/80 px-5 py-3 backdrop-blur dark:border-zinc-800 dark:bg-zinc-900/80">
          <button onClick={() => setNavOpen(true)} className="rounded-lg p-1.5 text-zinc-500 hover:bg-zinc-100 dark:hover:bg-zinc-800 lg:hidden"><Icon name="grid" size={18} /></button>
          <div className="min-w-0 flex-1">
            <h1 className="truncate text-[16px] font-semibold text-zinc-900 dark:text-white">{title}</h1>
            <p className="hidden truncate text-[12px] text-zinc-400 sm:block">{subtitle}</p>
          </div>
          <Btn variant="outline" size="sm" onClick={exportCSV} className="hidden sm:inline-flex"><Icon name="download" size={15} />Excel</Btn>
          <Btn variant="outline" size="sm" onClick={() => window.print()} className="hidden sm:inline-flex"><Icon name="download" size={15} />PDF</Btn>
          <button onClick={() => setCmdk(true)} title="Search (⌘K)" className="flex items-center gap-2 rounded-lg border border-zinc-200 px-2.5 py-1.5 text-[12.5px] text-zinc-400 transition-colors hover:border-zinc-300 hover:text-zinc-600 dark:border-zinc-700 dark:hover:border-zinc-600">
            <Icon name="search" size={14} /><span className="hidden md:inline">Search</span><kbd className="hidden rounded border border-zinc-200 px-1 text-[10px] font-semibold dark:border-zinc-700 md:inline">⌘K</kbd>
          </button>
          <HealthChip page={page} go={setPage} />
          <RoleMenu role={role} setRole={setRole} />
          <button onClick={() => setDark(d => !d)} title={dark ? 'Switch to Day mode' : 'Switch to Night mode'} className="rounded-lg p-1.5 text-zinc-400 transition-colors hover:bg-zinc-100 hover:text-zinc-700 dark:hover:bg-zinc-800"><Icon name={dark ? 'sun' : 'moon'} size={16} /></button>
          <button onClick={() => setTour(true)} title="Replay tour" className="rounded-lg p-1.5 text-zinc-400 transition-colors hover:bg-zinc-100 hover:text-zinc-700 dark:hover:bg-zinc-800"><Icon name="target" size={16} /></button>
          <button onClick={() => setPage('settings')} title="Settings" className="rounded-lg p-1.5 text-zinc-400 transition-colors hover:bg-zinc-100 hover:text-zinc-700 dark:hover:bg-zinc-800"><Icon name="reset" size={16} /></button>
          {session && <div className="flex items-center gap-2 border-l border-zinc-200 pl-3 dark:border-zinc-700">
            <div className="hidden text-right sm:block"><div className="text-[12px] font-semibold leading-tight text-zinc-700 dark:text-zinc-200">{session.name}</div><div className="text-[10.5px] leading-tight text-zinc-400">@{session.handle}</div></div>
            <button onClick={signOut} title="Sign out" className="rounded-lg p-1.5 text-zinc-400 transition-colors hover:bg-zinc-100 hover:text-zinc-700 dark:hover:bg-zinc-800"><Icon name="link" size={16} /></button>
          </div>}
        </header>

        <main className="w-full flex-1 p-5">
          <div key={page} className="page-swap">
          {(page === 'command' || page === 'dashboard') && <CommandPage go={setPage} />}
          {page === 'ai' && <AIAssistantPage />}
          {page === 'warsim' && <WarSimulatorPage />}
          {page === 'battlereport' && <BattleReportPage />}
          {page === 'discord' && <DiscordPage />}
          {page === 'diplomacy' && <DiplomacyPage />}
          {page === 'settings' && <SettingsPage go={setPage} dark={dark} setDark={setDark} role={role} />}
          {page === 'events' && <EventsPage />}
          {page === 'tierlist' && <TierListPage />}
          {page === 'roster' && <RosterAnalyticsPage go={setPage} />}
          {page === 'roadmap' && <GrowthRoadmapPage go={setPage} />}
          {page === 'resourceplanner' && <ResourcePlannerPage />}
          {page === 'dragonmatrix' && <DragonMatrixPage />}
          {page === 'achievements' && <AchievementsPage go={setPage} />}
          {page === 'guide' && <GuidePage go={setPage} />}
          {page === 'analysis' && <AnalysisPage go={setPage} />}
          {page === 'knowledge' && <KnowledgePage go={setPage} />}
          {page === 'tools' && <ToolsPage go={setPage} />}
          {page === 'generals' && <DatabasePage canEdit={canEdit} />}
          {page === 'compare' && <ComparePage />}
          {page === 'covenants' && <CovenantHub go={setPage} />}
          {page === 'optimizer' && <CovenantHub go={setPage} />}
          {page === 'dragons' && <DragonHub />}
          {page === 'dragoncodex' && <DragonHub initial="codex" />}
          {page === 'march' && <MarchHub />}
          {page === 'warroom' && (gated('warroom') || <WarRoomSection canEdit={canEdit} />)}
          {page === 'users' && (role === 'Admin' ? <UsersPage /> : <Card className="p-10 text-center"><Icon name="shield" size={28} className="mx-auto text-zinc-300" /><div className="mt-2 text-[15px] font-semibold text-zinc-700 dark:text-zinc-200">Admins only</div><div className="mt-1 text-[12.5px] text-zinc-400">Switch to the Admin role to manage users.</div></Card>)}
          {page === 'rally' && (gated('rally') || <RallyPage />)}
          {page === 'subs' && (gated('subs') || <SubsPage />)}
          {page === 'land' && <LandPage />}
          {page === 'gear' && <GearPage />}
          {page === 'flexspec' && <FlexSpecPage />}
          {page === 'champions' && <ChampionsPage />}
          {page === 'seal' && <SealPage />}
          {page === 'rallysize' && <RallySizePage />}
          {page === 'senate' && <SenatePage />}
          {page === 'construction' && <ConstructionPage />}
          {page === 'academy' && <AcademyPage />}
          {page === 'milacademy' && <MilAcademyPage />}
          </div>
        </main>
      </div>
      {tour && <OnboardingTour name={session.name} onGo={p => { setPage(p); setNavOpen(false); }} onClose={closeTour} />}
      <CommandPalette open={cmdk} onClose={() => setCmdk(false)} onNavigate={cmdNavigate} nav={NAV} />
    </div>
    : <LoginScreen onSignIn={signIn} />
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(
  <OwnershipProvider><AllianceProvider><App /></AllianceProvider></OwnershipProvider>
);
